summaryrefslogtreecommitdiff
path: root/src/VBox/Additions/WINNT/Graphics
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Additions/WINNT/Graphics')
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Makefile.kmk6
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/Makefile.kmk4
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/common/VBoxVideoLog.h26
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/common/VBoxVideoTools.h2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/common/wddm/VBoxMPIf.h30
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/common/xpdm/VBoxVideoIOCTL.h9
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/common/xpdm/VBoxVideoPortAPI.h2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/Makefile.kmk9
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxCrHgsmi.cpp6
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.cpp210
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.h19
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispCm.cpp22
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.cpp838
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.def3
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.h12
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D64.def21
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DBase.h46
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DCmn.h30
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.cpp130
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.h22
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.cpp73
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.h24
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.cpp52
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.h15
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.cpp5
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.h5
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMpInternal.h2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMpTst.cpp204
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispProfile.h43
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxScreen.cpp23
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.cpp34
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.h36
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.cpp135
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.h4
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.cpp217
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.h8
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dbg/DumpD3DCaps9.cpp475
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dbg/tstMvWnd.cpp2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDisp.h4
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDDraw.cpp7
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDriver.cpp10
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMini.cpp21
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMini.h1
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVRDP.cpp36
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpBmp.cpp303
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpBmp.h16
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpTxt.cpp2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/Makefile.kmk16
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPCommon.cpp2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPCommon.h11
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPDevExt.h67
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPHGSMI.cpp2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPHGSMI.h2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPUtils.cpp6
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPUtils.h10
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPVidModes.cpp636
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCm.cpp245
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCm.h8
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp678
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.h212
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCrUtil.cpp5
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.cpp1088
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.h53
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPShgsmi.cpp2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPShgsmi.h11
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPTypes.h36
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.cpp1121
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.h178
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.cpp1257
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.h47
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVhwa.cpp2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVhwa.h2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVidPn.cpp158
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVidPn.h7
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp3320
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.h114
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.rc2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxVideoWddm.inf2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPDriver.cpp46
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPIOCTL.cpp46
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPInternal.cpp5
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPInternal.h1
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/Makefile.kmk3
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/d3d9/d3d9wddm.def2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/d3d9/device.c28
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/switcher/d3d8_main.c2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/switcher/d3d9_main.c2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/switcher/sw_common.c37
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/switcher/switcher.h2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/vbox/VBoxDbgGl.c2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/vbox/VBoxDbgGl.h2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/vbox/VBoxWineEx.h12
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/vbox/libWineStub/include/wine/debug.h8
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/vbox/libWineStub/include/wine/wined3d.h8
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/wined3d/buffer.c2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c62
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/wined3d/directx.c44
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/wined3d/glsl_shader.c5
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/wined3d/surface.c2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain.c9
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxext.c2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxext.h2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxsharedrc.h2
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_gl.h38
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_main.c28
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_private.h162
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/Makefile.kmk395
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/Makefile.kup0
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/buffer.c620
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/d3d8.def7
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/d3d8_main.c149
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/d3d8_private.h311
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/device.c3163
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/directx.c428
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/shader.c179
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/surface.c377
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/swapchain.c208
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/texture.c1308
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/version.rc35
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/vertexdeclaration.c400
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/volume.c312
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/Makefile.kup0
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/buffer.c619
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/d3d9_main.c179
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/d3d9_private.h361
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/d3d9wddm.def27
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/d3d9xpdm.def13
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/device.c3964
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/directx.c664
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/query.c193
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/shader.c320
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/stateblock.c172
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/surface.c490
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/swapchain.c327
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/texture.c1462
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/vboxport.asm47
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/version.rc35
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/vertexdeclaration.c445
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/volume.c323
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/Makefile.kup0
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/d3d8.rc64
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/d3d8_main.c104
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/d3d9.rc64
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/d3d9_main.c195
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/sw_common.c134
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/sw_d3d8.def6
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/sw_d3d9.def12
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/sw_d3d9xpdm.def12
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/switcher.h54
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/Makefile.kup0
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/VBoxDbgGl.c389
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/VBoxDbgGl.h43
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/VBoxWineEx.h159
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/Makefile.kup0
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/debug.c498
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/config.h1275
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/d3d8.h1153
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/d3d9.h2063
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/debug.h322
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/list.h243
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/port.h489
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/rbtree.h351
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/unicode.h320
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/wgl.h5081
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/wgl_driver.h2862
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/wglext.h943
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/wined3d.h2499
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/Makefile.kup0
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/arb_program_shader.c7523
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/ati_fragment_shader.c1228
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/buffer.c1557
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/context.c2987
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/device.c5835
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/directx.c5503
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/drawprim.c827
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/gl_compat.c552
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/glsl_shader.c7350
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/nvidia_texture_shader.c921
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/palette.c226
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/query.c653
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/resource.c377
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/sampler.c85
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/shader.c2615
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/shader_sm1.c781
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/shader_sm4.c815
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/state.c6097
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/stateblock.c1494
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/surface.c7832
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/swapchain.c1559
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/texture.c1791
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/utils.c3718
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/vboxext.c860
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/vboxext.h313
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/vboxsharedrc.h49
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/version.rc36
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/vertexdeclaration.c429
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/view.c97
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/volume.c474
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d.def255
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d.spec288
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d_gl.h634
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d_main.c584
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d_private.h3187
-rw-r--r--src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3dwddm.def263
204 files changed, 114970 insertions, 4761 deletions
diff --git a/src/VBox/Additions/WINNT/Graphics/Makefile.kmk b/src/VBox/Additions/WINNT/Graphics/Makefile.kmk
index 74f75868..c20e17b6 100644
--- a/src/VBox/Additions/WINNT/Graphics/Makefile.kmk
+++ b/src/VBox/Additions/WINNT/Graphics/Makefile.kmk
@@ -21,7 +21,11 @@ include $(KBUILD_PATH)/subheader.kmk
# Include sub-makefiles.
include $(PATH_SUB_CURRENT)/Video/Makefile.kmk
ifdef VBOX_WITH_CROGL
- include $(PATH_SUB_CURRENT)/Wine/Makefile.kmk
+ if !defined(VBOX_WITH_NEW_WINE)
+ include $(PATH_SUB_CURRENT)/Wine/Makefile.kmk
+ else
+ include $(PATH_SUB_CURRENT)/Wine_new/Makefile.kmk
+ endif
endif
include $(FILE_KBUILD_SUB_FOOTER)
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/Makefile.kmk b/src/VBox/Additions/WINNT/Graphics/Video/Makefile.kmk
index 94da6019..6e6887b4 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/Makefile.kmk
+++ b/src/VBox/Additions/WINNT/Graphics/Video/Makefile.kmk
@@ -220,13 +220,13 @@ ifdef VBOX_WITH_WDDM
$(PATH_TARGET)/VBoxVideoWddmCat.dir/VBoxOGLpassthroughspu-x86.dll, ), )
$(call MSG_TOOL,Inf2Cat,VBoxVideoWddm-inf,$@,$<)
$(call VBOX_MAKE_CAT_FN, $(@D),$@)
-
+
ifdef VBOX_WITH_WDDM_W8
VBOXWDDMW8_WITH_DISPD3D = 1
ifdef VBOX_WITH_CROGL
VBOXWDDMW8_WITH_GL = 1
endif
-
+
INSTALLS += VBoxVideoW8-inf
VBoxVideoW8-inf_INST = $(INST_ADDITIONS)
VBoxVideoW8-inf_MODE = a+r,u+w
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/common/VBoxVideoLog.h b/src/VBox/Additions/WINNT/Graphics/Video/common/VBoxVideoLog.h
index e6e60205..b928bd67 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/common/VBoxVideoLog.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/common/VBoxVideoLog.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -96,19 +96,41 @@
# define _WARN_LOGGER VBOX_VIDEO_LOG_LOGGER
#endif
-#define WARN_NOBP(_a) _LOGMSG(VBOX_VIDEO_LOG_LOGGER, "WARNING! :", _a)
+#define WARN_NOBP(_a) _LOGMSG(_WARN_LOGGER, "WARNING! :", _a)
#define WARN(_a) \
do \
{ \
WARN_NOBP(_a); \
BP_WARN(); \
} while (0)
+
#define ASSERT_WARN(_a, _w) do {\
if(!(_a)) { \
WARN(_w); \
}\
} while (0)
+#define STOP_FATAL() do { \
+ AssertReleaseFailed(); \
+ } while (0)
+#define ERR(_a) do { \
+ _LOGMSG(VBOX_VIDEO_LOGREL_LOGGER, "FATAL! :", _a); \
+ STOP_FATAL(); \
+ } while (0)
+
+#define _DBGOP_N_TIMES(_count, _op) do { \
+ static int fDoWarnCount = (_count); \
+ if (fDoWarnCount) { \
+ --fDoWarnCount; \
+ _op; \
+ } \
+ } while (0)
+
+#define WARN_ONCE(_a) do { \
+ _DBGOP_N_TIMES(1, WARN(_a)); \
+ } while (0)
+
+
#define LOG(_a) _LOGMSG(VBOX_VIDEO_LOG_LOGGER, "", _a)
#define LOGREL(_a) _LOGMSG(VBOX_VIDEO_LOGREL_LOGGER, "", _a)
#define LOGF(_a) _LOGMSG(VBOX_VIDEO_LOGFLOW_LOGGER, "", _a)
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/common/VBoxVideoTools.h b/src/VBox/Additions/WINNT/Graphics/Video/common/VBoxVideoTools.h
index d4b9cf6a..a1f7ec91 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/common/VBoxVideoTools.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/common/VBoxVideoTools.h
@@ -347,7 +347,7 @@ DECLINLINE(void) vboxWddmDirtyRegionAddRect(PVBOXWDDM_DIRTYREGION pInfo, const R
}
}
-DECLINLINE(void) vboxWddmDirtyRegionUnite(PVBOXWDDM_DIRTYREGION pInfo, const PVBOXWDDM_DIRTYREGION pInfo2)
+DECLINLINE(void) vboxWddmDirtyRegionUnite(PVBOXWDDM_DIRTYREGION pInfo, const VBOXWDDM_DIRTYREGION *pInfo2)
{
if (pInfo2->fFlags & VBOXWDDM_DIRTYREGION_F_VALID)
{
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/common/wddm/VBoxMPIf.h b/src/VBox/Additions/WINNT/Graphics/Video/common/wddm/VBoxMPIf.h
index 32c90041..bd2776d9 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/common/wddm/VBoxMPIf.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/common/wddm/VBoxMPIf.h
@@ -13,7 +13,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -34,7 +34,7 @@
#include <VBox/VBoxGuest2.h>
/* One would increase this whenever definitions in this file are changed */
-#define VBOXVIDEOIF_VERSION 13
+#define VBOXVIDEOIF_VERSION 20
#define VBOXWDDM_NODE_ID_SYSTEM 0
#define VBOXWDDM_NODE_ID_3D (VBOXWDDM_NODE_ID_SYSTEM)
@@ -91,6 +91,7 @@ typedef struct VBOXWDDM_SURFACE_DESC
UINT pitch;
UINT depth;
UINT slicePitch;
+ UINT d3dWidth;
UINT cbSize;
D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId;
D3DDDI_RATIONAL RefreshRate;
@@ -104,6 +105,8 @@ typedef struct VBOXWDDM_ALLOCINFO
struct
{
D3DDDI_RESOURCEFLAGS fFlags;
+ /* id used to identify the allocation on the host */
+ uint32_t hostID;
uint64_t hSharedHandle;
VBOXWDDM_SURFACE_DESC SurfDesc;
};
@@ -111,7 +114,6 @@ typedef struct VBOXWDDM_ALLOCINFO
struct
{
uint32_t cbBuffer;
- uint64_t hSynch;
VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType;
};
};
@@ -179,7 +181,6 @@ typedef struct VBOXWDDM_DMA_PRIVATEDATA_BASEHDR
typedef struct VBOXWDDM_UHGSMI_BUFFER_UI_SUBMIT_INFO
{
- uint32_t bDoNotSignalCompletion;
uint32_t offData;
uint32_t cbData;
} VBOXWDDM_UHGSMI_BUFFER_UI_SUBMIT_INFO, *PVBOXWDDM_UHGSMI_BUFFER_UI_SUBMIT_INFO;
@@ -190,6 +191,7 @@ typedef struct VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD
VBOXWDDM_UHGSMI_BUFFER_UI_SUBMIT_INFO aBufInfos[1];
} VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, *PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD;
+
#define VBOXVHWA_F_ENABLED 0x00000001
#define VBOXVHWA_F_CKEY_DST 0x00000002
#define VBOXVHWA_F_CKEY_SRC 0x00000004
@@ -248,7 +250,11 @@ typedef enum
VBOXWDDM_CONTEXT_TYPE_CUSTOM_UHGSMI_3D,
VBOXWDDM_CONTEXT_TYPE_CUSTOM_UHGSMI_GL,
/* context created by the kernel->user communication mechanism for visible rects reporting, etc. */
- VBOXWDDM_CONTEXT_TYPE_CUSTOM_SESSION
+ VBOXWDDM_CONTEXT_TYPE_CUSTOM_SESSION,
+ /* context created by VBoxTray to handle resize operations */
+ VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_RESIZE,
+ /* context created by VBoxTray to handle seamless operations */
+ VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_SEAMLESS
} VBOXWDDM_CONTEXT_TYPE;
typedef struct VBOXWDDM_CREATECONTEXT_INFO
@@ -420,6 +426,7 @@ typedef struct VBOXSWAPCHAININFO
{
VBOXDISP_KMHANDLE hSwapchainKm; /* in, NULL if new is being created */
VBOXDISP_UMHANDLE hSwapchainUm; /* in, UMD private data */
+ int32_t winHostID;
RECT Rect;
UINT u32Reserved;
UINT cAllocs;
@@ -470,6 +477,15 @@ typedef struct VBOXDISPIFESCAPE_SHRC_REF
uint64_t hAlloc;
} VBOXDISPIFESCAPE_SHRC_REF, *PVBOXDISPIFESCAPE_SHRC_REF;
+typedef struct VBOXDISPIFESCAPE_SETALLOCHOSTID
+{
+ VBOXDISPIFESCAPE EscapeHdr;
+ int32_t rc;
+ uint32_t hostID;
+ uint64_t hAlloc;
+
+} VBOXDISPIFESCAPE_SETALLOCHOSTID, *PVBOXDISPIFESCAPE_SETALLOCHOSTID;
+
typedef struct VBOXDISPIFESCAPE_CRHGSMICTLCON_CALL
{
VBOXDISPIFESCAPE EscapeHdr;
@@ -480,6 +496,7 @@ typedef struct VBOXDISPIFESCAPE_CRHGSMICTLCON_CALL
typedef struct VBOXWDDM_QI
{
uint32_t u32Version;
+ uint32_t u32VBox3DCaps;
uint32_t cInfos;
VBOXVHWA_INFO aInfos[VBOX_VIDEO_MAX_SCREENS];
} VBOXWDDM_QI;
@@ -530,6 +547,7 @@ DECLINLINE(UINT) vboxWddmCalcBitsPerPixel(D3DDDIFORMAT enmFormat)
case D3DDDIFMT_A2R10G10B10:
return 32;
case D3DDDIFMT_A16B16G16R16:
+ case D3DDDIFMT_A16B16G16R16F:
return 64;
case D3DDDIFMT_A8P8:
return 16;
@@ -577,6 +595,8 @@ DECLINLINE(UINT) vboxWddmCalcBitsPerPixel(D3DDDIFORMAT enmFormat)
return 8;
case D3DDDIFMT_R32F:
return 32;
+ case D3DDDIFMT_R16F:
+ return 16;
default:
AssertBreakpoint();
return 0;
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/common/xpdm/VBoxVideoIOCTL.h b/src/VBox/Additions/WINNT/Graphics/Video/common/xpdm/VBoxVideoIOCTL.h
index 6a759628..5fb97ac8 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/common/xpdm/VBoxVideoIOCTL.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/common/xpdm/VBoxVideoIOCTL.h
@@ -58,6 +58,10 @@
#define IOCTL_VIDEO_VHWA_QUERY_INFO \
CTL_CODE(FILE_DEVICE_VIDEO, 0x435, METHOD_BUFFERED, FILE_ANY_ACCESS)
+/* Called to get adapter's generic information */
+#define IOCTL_VIDEO_QUERY_VBOXVIDEO_INFO \
+ CTL_CODE(FILE_DEVICE_VIDEO, 0x436, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
/* ==================== Data structures used by Virtual Box VRPS's ==================== */
typedef void* HVBOXVIDEOHGSMI;
@@ -146,4 +150,9 @@ typedef struct _VHWAQUERYINFO
#endif
#pragma pack()
+/* IOCTL_VIDEO_QUERY_INFO */
+#define VBOXVIDEO_INFO_LEVEL_REGISTRY_FLAGS 1
+
+#define VBOXVIDEO_REGISTRY_FLAGS_DISABLE_BITMAP_CACHE 0x00000001
+
#endif /*VBOXVIDEOIOCTL_H*/
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/common/xpdm/VBoxVideoPortAPI.h b/src/VBox/Additions/WINNT/Graphics/Video/common/xpdm/VBoxVideoPortAPI.h
index a49641f7..01147a58 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/common/xpdm/VBoxVideoPortAPI.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/common/xpdm/VBoxVideoPortAPI.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/Makefile.kmk b/src/VBox/Additions/WINNT/Graphics/Video/disp/Makefile.kmk
index 53a32b0a..e11768aa 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/Makefile.kmk
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/Makefile.kmk
@@ -104,6 +104,9 @@ endif
ifdef VBOX_WITH_CROGL
VBoxDispD3D_DEFS += VBOX_WITH_CROGL
endif
+ifdef VBOX_WITH_NEW_WINE
+ VBoxDispD3D_DEFS += VBOX_WITH_NEW_WINE
+endif
VBoxDispD3D_INCS = \
../../../include \
.. \
@@ -112,9 +115,7 @@ VBoxDispD3D_SOURCES = \
wddm/VBoxDispD3D.cpp \
wddm/VBoxDispD3DIf.cpp \
wddm/VBoxDispCm.cpp \
- wddm/VBoxDispMp.cpp \
wddm/VBoxScreen.cpp \
- wddm/VBoxDispMpTst.cpp \
wddm/VBoxDispKmt.cpp \
wddm/VBoxDispDbg.cpp \
wddm/VBoxD3DIf.cpp \
@@ -208,7 +209,7 @@ tstMvWnd_TEMPLATE = VBOXR3EXE
tstMvWnd_DEFS = UNICODE _UNICODE
tstMvWnd_SOURCES = \
wddm/dbg/tstMvWnd.cpp
-tstMvWnd_LIBS = $(LIB_RUNTIME)
+tstMvWnd_LIBS = $(VBOX_LIB_IPRT_GUEST_R3)
tstMvWnd_LDFLAGS.win = /SUBSYSTEM:windows
PROGRAMS += DumpD3DCaps9
@@ -217,7 +218,7 @@ DumpD3DCaps9_SDKS = ReorderCompilerIncs $(VBOX_WINDDK_GST_WLH)
DumpD3DCaps9_DEFS = UNICODE _UNICODE
DumpD3DCaps9_SOURCES = \
wddm/dbg/DumpD3DCaps9.cpp
-DumpD3DCaps9_LIBS = $(LIB_RUNTIME)
+DumpD3DCaps9_LIBS = $(VBOX_LIB_IPRT_GUEST_R3) d3d9.lib
DumpD3DCaps9_LDFLAGS.win = /SUBSYSTEM:CONSOLE
endif #VBOXVIDEOWINDBG
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxCrHgsmi.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxCrHgsmi.cpp
index f6aadbf0..e86375f7 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxCrHgsmi.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxCrHgsmi.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -61,11 +61,7 @@ VBOXCRHGSMI_DECL(PVBOXUHGSMI) VBoxCrHgsmiCreate()
PVBOXUHGSMI_PRIVATE_KMT pHgsmiGL = (PVBOXUHGSMI_PRIVATE_KMT)RTMemAllocZ(sizeof (*pHgsmiGL));
if (pHgsmiGL)
{
-#if 0
HRESULT hr = vboxUhgsmiKmtCreate(pHgsmiGL, TRUE /* bD3D tmp for injection thread*/);
-#else
- HRESULT hr = vboxUhgsmiKmtEscCreate(pHgsmiGL, TRUE /* bD3D tmp for injection thread*/);
-#endif
Log(("CrHgsmi: faled to create KmtEsc VBOXUHGSMI instance, hr (0x%x)\n", hr));
if (hr == S_OK)
{
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.cpp
index d8e0bf67..bf8d2259 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.cpp
@@ -482,7 +482,7 @@ HRESULT VBoxD3DIfCreateForRc(struct VBOXWDDMDISP_RESOURCE *pRc)
else
{
hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9CreateCubeTexture((IDirect3DDevice9Ex *)pDevice9If,
- pAllocation->D3DWidth,
+ pAllocation->SurfDesc.d3dWidth,
VBOXDISP_CUBEMAP_LEVELS_COUNT(pRc),
vboxDDI2D3DUsage(pRc->RcDesc.fFlags),
vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
@@ -502,7 +502,7 @@ HRESULT VBoxD3DIfCreateForRc(struct VBOXWDDMDISP_RESOURCE *pRc)
else if (pRc->RcDesc.fFlags.Volume)
{
hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9CreateVolumeTexture((IDirect3DDevice9Ex *)pDevice9If,
- pAllocation->D3DWidth,
+ pAllocation->SurfDesc.d3dWidth,
pAllocation->SurfDesc.height,
pAllocation->SurfDesc.depth,
pRc->cAllocations,
@@ -523,7 +523,7 @@ HRESULT VBoxD3DIfCreateForRc(struct VBOXWDDMDISP_RESOURCE *pRc)
else
{
hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9CreateTexture((IDirect3DDevice9Ex *)pDevice9If,
- pAllocation->D3DWidth,
+ pAllocation->SurfDesc.d3dWidth,
pAllocation->SurfDesc.height,
pRc->cAllocations,
vboxDDI2D3DUsage(pRc->RcDesc.fFlags),
@@ -570,28 +570,26 @@ HRESULT VBoxD3DIfCreateForRc(struct VBOXWDDMDISP_RESOURCE *pRc)
PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
HANDLE hSharedHandle = pAllocation->hSharedHandle;
IDirect3DSurface9* pD3D9Surf;
- switch (pAllocation->enmType)
+ if ((pDevice->pAdapter->u32VBox3DCaps & CR_VBOX_CAP_TEX_PRESENT) || pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC)
{
- case VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC:
- {
- hr = pDevice9If->CreateRenderTarget(pAllocation->SurfDesc.width,
- pAllocation->SurfDesc.height,
- vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
- vboxDDI2D3DMultiSampleType(pRc->RcDesc.enmMultisampleType),
- pRc->RcDesc.MultisampleQuality,
- !pRc->RcDesc.fFlags.NotLockable /* BOOL Lockable */,
- &pD3D9Surf,
+ hr = pDevice9If->CreateRenderTarget(pAllocation->SurfDesc.width,
+ pAllocation->SurfDesc.height,
+ vboxDDI2D3DFormat(pRc->RcDesc.enmFormat),
+ vboxDDI2D3DMultiSampleType(pRc->RcDesc.enmMultisampleType),
+ pRc->RcDesc.MultisampleQuality,
+ !pRc->RcDesc.fFlags.NotLockable /* BOOL Lockable */,
+ &pD3D9Surf,
#ifdef VBOXWDDMDISP_DEBUG_NOSHARED
- NULL
+ NULL
#else
- pRc->RcDesc.fFlags.SharedResource ? &hSharedHandle : NULL
+ pRc->RcDesc.fFlags.SharedResource ? &hSharedHandle : NULL
#endif
- );
- Assert(hr == S_OK);
- break;
- }
- case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE:
- {
+ );
+ Assert(hr == S_OK);
+ }
+ else if (pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE)
+ {
+ do {
BOOL bNeedPresent;
if (pRc->cAllocations != 1)
{
@@ -622,13 +620,12 @@ HRESULT VBoxD3DIfCreateForRc(struct VBOXWDDMDISP_RESOURCE *pRc)
Assert(pAllocation->pD3DIf);
pD3D9Surf = (IDirect3DSurface9*)pAllocation->pD3DIf;
break;
- }
- default:
- {
- WARN(("unexpected alloc type %d", pAllocation->enmType));
- hr = E_FAIL;
- break;
- }
+ } while (0);
+ }
+ else
+ {
+ WARN(("unexpected alloc type %d", pAllocation->enmType));
+ hr = E_FAIL;
}
if (SUCCEEDED(hr))
@@ -709,7 +706,11 @@ HRESULT VBoxD3DIfCreateForRc(struct VBOXWDDMDISP_RESOURCE *pRc)
PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
IDirect3DVertexBuffer9 *pD3D9VBuf;
hr = pDevice9If->CreateVertexBuffer(pAllocation->SurfDesc.width,
- vboxDDI2D3DUsage(pRc->RcDesc.fFlags),
+ vboxDDI2D3DUsage(pRc->RcDesc.fFlags)
+#ifdef VBOX_WITH_NEW_WINE
+ & (~D3DUSAGE_DYNAMIC) /* <- avoid using dynamic to ensure wine does not switch do user buffer */
+#endif
+ ,
pRc->RcDesc.Fvf,
vboxDDI2D3DPool(pRc->RcDesc.enmPool),
&pD3D9VBuf,
@@ -829,13 +830,156 @@ HRESULT VBoxD3DIfDeviceCreateDummy(PVBOXWDDMDISP_DEVICE pDevice)
IDirect3DDevice9 * pDevice9If = NULL;
HRESULT hr = pAdapter->D3D.pD3D9If->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, fFlags, &Params.Base, &pDevice9If);
- if (!SUCCEEDED(hr))
+ if (SUCCEEDED(hr))
{
+ int32_t hostId = 0;
+ hr = pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9GetHostId((IDirect3DDevice9Ex*)pDevice9If, &hostId);
+ if (SUCCEEDED(hr))
+ {
+ Assert(hostId);
+
+ VBOXDISPIFESCAPE Data;
+ Data.escapeCode = VBOXESC_SETCTXHOSTID;
+ Data.u32CmdSpecific = (uint32_t)hostId;
+ D3DDDICB_ESCAPE DdiEscape = {0};
+ DdiEscape.hContext = pDevice->DefaultContext.ContextInfo.hContext;
+ DdiEscape.hDevice = pDevice->hDevice;
+ // DdiEscape.Flags.Value = 0;
+ DdiEscape.pPrivateDriverData = &Data;
+ DdiEscape.PrivateDriverDataSize = sizeof (Data);
+ hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
+ if (SUCCEEDED(hr))
+ {
+ pDevice->pDevice9If = pDevice9If;
+ return S_OK;
+ }
+ else
+ WARN(("pfnEscapeCb VBOXESC_SETCTXHOSTID failed hr 0x%x", hr));
+ }
+ else
+ WARN(("pfnVBoxWineExD3DDev9GetHostId failed hr 0x%x", hr));
+
+ pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9Term((IDirect3DDevice9Ex *)pDevice9If);
+ }
+ else
WARN(("CreateDevice failed hr 0x%x", hr));
- return hr;
+
+ return hr;
+}
+
+int vboxD3DIfSetHostId(PVBOXWDDMDISP_ALLOCATION pAlloc, uint32_t hostID, uint32_t *pHostID)
+{
+ struct VBOXWDDMDISP_RESOURCE *pRc = pAlloc->pRc;
+ PVBOXWDDMDISP_DEVICE pDevice = pRc->pDevice;
+
+ VBOXDISPIFESCAPE_SETALLOCHOSTID SetHostID = {0};
+ SetHostID.EscapeHdr.escapeCode = VBOXESC_SETALLOCHOSTID;
+ SetHostID.hostID = hostID;
+ SetHostID.hAlloc = pAlloc->hAllocation;
+
+ D3DDDICB_ESCAPE DdiEscape = {0};
+ DdiEscape.hContext = pDevice->DefaultContext.ContextInfo.hContext;
+ DdiEscape.hDevice = pDevice->hDevice;
+// DdiEscape.Flags.Value = 0;
+ DdiEscape.pPrivateDriverData = &SetHostID;
+ DdiEscape.PrivateDriverDataSize = sizeof (SetHostID);
+ HRESULT hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
+ if (SUCCEEDED(hr))
+ {
+ if (pHostID)
+ *pHostID = SetHostID.EscapeHdr.u32CmdSpecific;
+
+ return SetHostID.rc;
}
+ else
+ WARN(("pfnEscapeCb VBOXESC_SETALLOCHOSTID failed hr 0x%x", hr));
- pDevice->pDevice9If = pDevice9If;
- return S_OK;
+ return VERR_GENERAL_FAILURE;
}
+IUnknown* vboxD3DIfCreateSharedPrimary(PVBOXWDDMDISP_ALLOCATION pAlloc)
+{
+ IDirect3DSurface9 *pSurfIf;
+ struct VBOXWDDMDISP_RESOURCE *pRc = pAlloc->pRc;
+ PVBOXWDDMDISP_DEVICE pDevice = pRc->pDevice;
+
+ HRESULT hr = VBoxD3DIfCreateForRc(pRc);
+ if (!SUCCEEDED(hr))
+ {
+ WARN(("VBoxD3DIfCreateForRc failed, hr 0x%x", hr));
+ return NULL;
+ }
+
+ Assert(pAlloc->pD3DIf);
+ Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
+ Assert(pAlloc->pRc->RcDesc.fFlags.SharedResource);
+
+ hr = VBoxD3DIfSurfGet(pRc, pAlloc->iAlloc, &pSurfIf);
+ if (!SUCCEEDED(hr))
+ {
+ WARN(("VBoxD3DIfSurfGet failed hr %#x", hr));
+ return NULL;
+ }
+
+ uint32_t hostID, usedHostId;
+ hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DSurf9GetHostId(pSurfIf, &hostID);
+ if (SUCCEEDED(hr))
+ {
+ Assert(hostID);
+ int rc = vboxD3DIfSetHostId(pAlloc, hostID, &usedHostId);
+ if (!RT_SUCCESS(rc))
+ {
+ if (rc == VERR_NOT_EQUAL)
+ {
+ WARN(("another hostId % is in use, using it instead", usedHostId));
+ Assert(hostID != usedHostId);
+ Assert(usedHostId);
+ pSurfIf->Release();
+ pSurfIf = NULL;
+ for (UINT i = 0; i < pRc->cAllocations; ++i)
+ {
+ PVBOXWDDMDISP_ALLOCATION pCurAlloc = &pRc->aAllocations[i];
+ if (pCurAlloc->pD3DIf)
+ {
+ pCurAlloc->pD3DIf->Release();
+ pCurAlloc->pD3DIf = NULL;
+ }
+ }
+
+ pAlloc->hSharedHandle = (HANDLE)usedHostId;
+
+ hr = VBoxD3DIfCreateForRc(pRc);
+ if (!SUCCEEDED(hr))
+ {
+ WARN(("VBoxD3DIfCreateForRc failed, hr 0x%x", hr));
+ return NULL;
+ }
+
+ hr = VBoxD3DIfSurfGet(pRc, pAlloc->iAlloc, &pSurfIf);
+ if (!SUCCEEDED(hr))
+ {
+ WARN(("VBoxD3DIfSurfGet failed hr %#x", hr));
+ return NULL;
+ }
+ }
+ else
+ {
+ WARN(("vboxD3DIfSetHostId failed %#x, ignoring", hr));
+ hr = S_OK;
+ hostID = 0;
+ usedHostId = 0;
+ }
+ }
+ else
+ {
+ Assert(hostID == usedHostId);
+ }
+ }
+ else
+ WARN(("pfnVBoxWineExD3DSurf9GetHostId failed, hr 0x%x", hr));
+
+ pSurfIf->Release();
+ pSurfIf = NULL;
+
+ return pAlloc->pD3DIf;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.h
index 31e39082..43520b65 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxD3DIf.h
@@ -40,8 +40,11 @@ HRESULT VBoxD3DIfLockRect(struct VBOXWDDMDISP_RESOURCE *pRc, UINT iAlloc,
HRESULT VBoxD3DIfUnlockRect(struct VBOXWDDMDISP_RESOURCE *pRc, UINT iAlloc);
void VBoxD3DIfLockUnlockMemSynch(struct VBOXWDDMDISP_ALLOCATION *pAlloc, D3DLOCKED_RECT *pLockInfo, RECT *pRect, bool bToLockInfo);
+IUnknown* vboxD3DIfCreateSharedPrimary(PVBOXWDDMDISP_ALLOCATION pAlloc);
+
+
/* NOTE: does NOT increment a ref counter! NO Release needed!! */
-DECLINLINE(IUnknown*) VBoxD3DIfGet(PVBOXWDDMDISP_ALLOCATION pAlloc)
+DECLINLINE(IUnknown*) vboxD3DIfGet(PVBOXWDDMDISP_ALLOCATION pAlloc)
{
if (pAlloc->pD3DIf)
return pAlloc->pD3DIf;
@@ -52,17 +55,7 @@ DECLINLINE(IUnknown*) VBoxD3DIfGet(PVBOXWDDMDISP_ALLOCATION pAlloc)
return NULL;
}
- HRESULT hr = VBoxD3DIfCreateForRc(pAlloc->pRc);
- if (!SUCCEEDED(hr))
- {
- WARN(("VBoxD3DIfCreateForRc failed, hr 0x%x", hr));
- return NULL;
- }
-
- Assert(pAlloc->pD3DIf);
- Assert(pAlloc->enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE);
-
- return pAlloc->pD3DIf;
+ return vboxD3DIfCreateSharedPrimary(pAlloc);
}
/* on success increments the surface ref counter,
@@ -72,7 +65,7 @@ DECLINLINE(HRESULT) VBoxD3DIfSurfGet(PVBOXWDDMDISP_RESOURCE pRc, UINT iAlloc, ID
HRESULT hr = S_OK;
Assert(pRc->cAllocations > iAlloc);
*ppSurf = NULL;
- IUnknown* pD3DIf = VBoxD3DIfGet(&pRc->aAllocations[iAlloc]);
+ IUnknown* pD3DIf = vboxD3DIfGet(&pRc->aAllocations[iAlloc]);
switch (pRc->aAllocations[0].enmD3DIfType)
{
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispCm.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispCm.cpp
index f4c6c528..39c465f5 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispCm.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispCm.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -164,7 +164,12 @@ HRESULT vboxDispCmCtxCreate(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_CONTEXT
vboxDispCmSessionCtxAdd(&g_pVBoxCmMgr.Session, pContext);
pContext->pDevice = pDevice;
if (fIsCrContext)
- vboxUhgsmiD3DEscInit(&pDevice->Uhgsmi, pDevice);
+ {
+ if (pDevice->pAdapter->u32VBox3DCaps & CR_VBOX_CAP_CMDVBVA)
+ vboxUhgsmiD3DInit(&pDevice->Uhgsmi, pDevice);
+ else
+ vboxUhgsmiD3DEscInit(&pDevice->Uhgsmi, pDevice);
+ }
}
else
{
@@ -206,10 +211,21 @@ static HRESULT vboxDispCmSessionCmdQueryData(PVBOXDISPCM_SESSION pSession, PVBOX
DdiEscape.PrivateDriverDataSize = cbCmd;
pCmd->EscapeHdr.escapeCode = VBOXESC_GETVBOXVIDEOCMCMD;
+
+ PVBOXWDDMDISP_CONTEXT pContext = NULL, pCurCtx;
+
/* lock to ensure the context is not destroyed */
EnterCriticalSection(&pSession->CritSect);
/* use any context for identifying the kernel CmSession. We're using the first one */
- PVBOXWDDMDISP_CONTEXT pContext = RTListGetFirst(&pSession->CtxList, VBOXWDDMDISP_CONTEXT, ListNode);
+ RTListForEach(&pSession->CtxList, pCurCtx, VBOXWDDMDISP_CONTEXT, ListNode)
+ {
+ PVBOXWDDMDISP_DEVICE pDevice = pCurCtx->pDevice;
+ if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
+ {
+ pContext = pCurCtx;
+ break;
+ }
+ }
if (pContext)
{
PVBOXWDDMDISP_DEVICE pDevice = pContext->pDevice;
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.cpp
index 6311a93d..d3946060 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -37,6 +37,9 @@
volatile uint32_t g_u32VBoxDispProfileFunctionLoggerIndex = 0;
+/* the number of frames to collect data before doing dump/reset */
+#define VBOXDISPPROFILE_DDI_DUMP_FRAME_COUNT 0x20
+
struct VBOXDISPPROFILE_GLOBAL {
VBoxDispProfileFpsCounter ProfileDdiFps;
VBoxDispProfileSet ProfileDdiFunc;
@@ -50,10 +53,25 @@ struct VBOXDISPPROFILE_GLOBAL {
# ifdef VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_ENABLE
-extern volatile uint32_t g_u322VBoxDispProfileFunctionLoggerIndex = 0;
+class VBoxDispProfileDevicePostProcess
+{
+public:
+ VBoxDispProfileDevicePostProcess(PVBOXWDDMDISP_DEVICE pDevice) :
+ m_pDevice(pDevice)
+ {}
+
+ void postProcess()
+ {
+ if (m_pDevice->pDevice9If)
+ m_pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9Finish((IDirect3DDevice9Ex *)m_pDevice->pDevice9If);
+ }
+private:
+ PVBOXWDDMDISP_DEVICE m_pDevice;
+};
//static VBoxDispProfileSet g_VBoxDispProfileDDI("D3D_DDI");
-# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE(_pObj) VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE((_pObj)->ProfileDdiFunc)
+# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE_DEV(_pObj) VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE((_pObj)->ProfileDdiFunc, VBoxDispProfileDevicePostProcess, VBoxDispProfileDevicePostProcess(_pObj))
+# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE_BASE(_pObj) VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE((_pObj)->ProfileDdiFunc, VBoxDispProfileDummyPostProcess, VBoxDispProfileDummyPostProcess())
# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_DUMP(_pObj) do {\
(_pObj)->ProfileDdiFunc.dump(_pObj); \
} while (0)
@@ -67,14 +85,15 @@ extern volatile uint32_t g_u322VBoxDispProfileFunctionLoggerIndex = 0;
# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_LOG_AND_DISABLE_CURRENT() VBOXDISPPROFILE_FUNCTION_LOGGER_LOG_AND_DISABLE_CURRENT()
# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_REPORT_FRAME(_pObj) do { \
- if (!((_pObj)->ProfileDdiFunc.reportIteration() % 31) && !VBOXVDBG_IS_DWM()) {\
+ if (!((_pObj)->ProfileDdiFunc.reportIteration() % VBOXDISPPROFILE_DDI_DUMP_FRAME_COUNT) /*&& !VBOXVDBG_IS_DWM()*/) {\
VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_DUMP(_pObj); \
VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_RESET(_pObj); \
} \
} while (0)
# else
-# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE(_pObj) do {} while(0)
+# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE_DEV(_pObj) do {} while(0)
+# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE_BASE(_pObj) do {} while(0)
# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_DUMP(_pObj) do {} while(0)
# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_RESET(_pObj) do {} while(0)
# define VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_DISABLE_CURRENT() do {} while (0)
@@ -84,7 +103,7 @@ extern volatile uint32_t g_u322VBoxDispProfileFunctionLoggerIndex = 0;
# ifdef VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_ENABLE
//static VBoxDispProfileFpsCounter g_VBoxDispFpsDDI(64);
-# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_PROLOGUE(_pObj) VBOXDISPPROFILE_STATISTIC_LOGGER_DEFINE(&(_pObj)->ProfileDdiFps)
+# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_PROLOGUE(_pObj) VBOXDISPPROFILE_STATISTIC_LOGGER_DEFINE(&(_pObj)->ProfileDdiFps, VBoxDispProfileDummyPostProcess, VBoxDispProfileDummyPostProcess())
# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_DISABLE_CURRENT() do {\
VBOXDISPPROFILE_STATISTIC_LOGGER_DISABLE_CURRENT();\
} while (0)
@@ -98,7 +117,7 @@ extern volatile uint32_t g_u322VBoxDispProfileFunctionLoggerIndex = 0;
# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_REPORT_FRAME(_pObj) do { \
(_pObj)->ProfileDdiFps.ReportFrame(); \
- if(!((_pObj)->ProfileDdiFps.GetNumFrames() % 31)) \
+ if(!((_pObj)->ProfileDdiFps.GetNumFrames() % VBOXDISPPROFILE_DDI_DUMP_FRAME_COUNT)) \
{ \
VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_DUMP(_pObj); \
} \
@@ -113,8 +132,12 @@ extern volatile uint32_t g_u322VBoxDispProfileFunctionLoggerIndex = 0;
# define VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_DUMP(_pObj) do {} while (0)
# endif
-# define VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE(_pObj) \
- VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE(_pObj); \
+# define VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE_DEV(_pObj) \
+ VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE_DEV(_pObj); \
+ VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_PROLOGUE(_pObj);
+
+# define VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE_BASE(_pObj) \
+ VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_PROLOGUE_BASE(_pObj); \
VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_PROLOGUE(_pObj);
# define VBOXDISPPROFILE_DDI_LOG_AND_DISABLE_CURRENT() \
@@ -127,11 +150,15 @@ extern volatile uint32_t g_u322VBoxDispProfileFunctionLoggerIndex = 0;
VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_REPORT_FRAME(_pDev); \
} while (0)
+#if 0
# define VBOXDISPPROFILE_DDI_REPORT_FLUSH(_pDev) do {\
VBOXDISPPROFILE_DDI_LOG_AND_DISABLE_CURRENT(); \
VBOXDISPPROFILE_DDI_STATISTIC_LOGGER_REPORT_FRAME(_pDev); \
VBOXDISPPROFILE_DDI_FUNCTION_LOGGER_REPORT_FRAME(_pDev); \
} while (0)
+#else
+# define VBOXDISPPROFILE_DDI_REPORT_FLUSH(_pDev) do {} while (0)
+#endif
# define VBOXDISPPROFILE_DDI_INIT_CMN(_pObj, _name, _cEntries) do { \
(_pObj)->ProfileDdiFps = VBoxDispProfileFpsCounter(); \
@@ -156,7 +183,8 @@ extern volatile uint32_t g_u322VBoxDispProfileFunctionLoggerIndex = 0;
# define VBOXDISPPROFILE_DDI_INIT_ADP(_pAdp) VBOXDISPPROFILE_DDI_INIT_CMN(_pAdp, "DDI_Adp", 64)
# define VBOXDISPPROFILE_DDI_INIT_DEV(_pDev) VBOXDISPPROFILE_DDI_INIT_CMN(_pDev, "DDI_Dev", 64)
#else
-# define VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE(_pObj) do {} while (0)
+# define VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE_DEV(_pObj) do {} while (0)
+# define VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE_BASE(_pObj) do {} while (0)
# define VBOXDISPPROFILE_DDI_REPORT_FRAME(_pDev) do {} while (0)
# define VBOXDISPPROFILE_DDI_REPORT_FLUSH(_pDev) do {} while (0)
# define VBOXDISPPROFILE_DDI_INIT_GLBL() do {} while (0)
@@ -174,15 +202,15 @@ extern volatile uint32_t g_u322VBoxDispProfileFunctionLoggerIndex = 0;
#define VBOXDISP_DDI_PROLOGUE_DEV(_hDevice) \
VBOXDISP_DDI_PROLOGUE_CMN(); \
- VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE((PVBOXWDDMDISP_DEVICE)(_hDevice));
+ VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE_DEV((PVBOXWDDMDISP_DEVICE)(_hDevice));
#define VBOXDISP_DDI_PROLOGUE_ADP(_hAdapter) \
VBOXDISP_DDI_PROLOGUE_CMN(); \
- VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE((PVBOXWDDMDISP_ADAPTER)(_hAdapter));
+ VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE_BASE((PVBOXWDDMDISP_ADAPTER)(_hAdapter));
#define VBOXDISP_DDI_PROLOGUE_GLBL() \
VBOXDISP_DDI_PROLOGUE_CMN(); \
- VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE(&g_VBoxDispProfile);
+ VBOXDISPPROFILE_FUNCTION_DDI_PROLOGUE_BASE(&g_VBoxDispProfile);
#ifdef VBOXDISPMP_TEST
HRESULT vboxDispMpTstStart();
@@ -238,7 +266,8 @@ typedef struct VBOXWDDMDISP_NSCADD
static HRESULT vboxWddmNSCAddAlloc(PVBOXWDDMDISP_NSCADD pData, PVBOXWDDMDISP_ALLOCATION pAlloc)
{
HRESULT hr = S_OK;
- if (pData->cAllocationList && pData->cPatchLocationList && pData->cbCommandBuffer > 4)
+ Assert(pAlloc->fEverWritten || pAlloc->pRc->RcDesc.fFlags.SharedResource);
+ if (pData->cAllocationList && pData->cPatchLocationList && pData->cbCommandBuffer >= 4)
{
memset(pData->pAllocationList, 0, sizeof (D3DDDI_ALLOCATIONLIST));
pData->pAllocationList[0].hAllocation = pAlloc->hAllocation;
@@ -265,24 +294,28 @@ static HRESULT vboxWddmNSCAddAlloc(PVBOXWDDMDISP_NSCADD pData, PVBOXWDDMDISP_ALL
return hr;
}
-static BOOLEAN vboxWddmDalCheckRemove(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc)
+static VOID vboxWddmDalRemove(PVBOXWDDMDISP_ALLOCATION pAlloc)
{
- BOOLEAN fRemoved = FALSE;
-
- if (pAlloc->DirtyAllocListEntry.pNext)
- {
- RTListNodeRemove(&pAlloc->DirtyAllocListEntry);
- pAlloc->fDirtyWrite = FALSE;
- fRemoved = TRUE;
- }
-
- return fRemoved;
+ RTListNodeRemove(&pAlloc->DirtyAllocListEntry);
+ pAlloc->fDirtyWrite = FALSE;
}
+#ifdef DEBUG_misha
+typedef struct VBOXWDDM_DBG_ALLOC
+{
+ BOOLEAN fWrite;
+ PVBOXWDDMDISP_ALLOCATION pAlloc;
+} VBOXWDDM_DBG_ALLOC;
+#endif
+
static HRESULT vboxWddmDalNotifyChange(PVBOXWDDMDISP_DEVICE pDevice)
{
VBOXWDDMDISP_NSCADD NscAdd;
BOOL bReinitRenderData = TRUE;
+#ifdef DEBUG_misha
+ uint32_t cDbgAllocs = 0;
+ VBOXWDDM_DBG_ALLOC aDbgAllocs[128];
+#endif
do
{
@@ -304,16 +337,38 @@ static HRESULT vboxWddmDalNotifyChange(PVBOXWDDMDISP_DEVICE pDevice)
NscAdd.pvCommandBuffer = (VOID*)(((uint8_t*)NscAdd.pvCommandBuffer) + sizeof (*pHdr));
NscAdd.cbCommandBuffer -= sizeof (*pHdr);
bReinitRenderData = FALSE;
+
+#ifdef DEBUG_misha
+ {
+ memset(aDbgAllocs, 0, sizeof (aDbgAllocs));
+ PVBOXWDDMDISP_ALLOCATION pAlloc;
+ uint32_t cAllocs = 0;
+ RTListForEach(&pDevice->DirtyAllocList, pAlloc, VBOXWDDMDISP_ALLOCATION, DirtyAllocListEntry)
+ {
+ Assert(pAlloc->fEverWritten || pAlloc->pRc->RcDesc.fFlags.SharedResource);
+ if (cAllocs < RT_ELEMENTS(aDbgAllocs))
+ {
+ aDbgAllocs[cAllocs].pAlloc = pAlloc;
+ aDbgAllocs[cAllocs].fWrite = pAlloc->fDirtyWrite;
+ ++cDbgAllocs;
+ }
+ ++cAllocs;
+ }
+ }
+#endif
}
PVBOXWDDMDISP_ALLOCATION pAlloc = RTListGetFirst(&pDevice->DirtyAllocList, VBOXWDDMDISP_ALLOCATION, DirtyAllocListEntry);
if (pAlloc)
{
HRESULT tmpHr = vboxWddmNSCAddAlloc(&NscAdd, pAlloc);
+#ifdef DEBUG_misha
+ Assert(tmpHr == S_OK);
+#endif
Assert(tmpHr == S_OK || tmpHr == S_FALSE);
if (tmpHr == S_OK)
{
- vboxWddmDalCheckRemove(pDevice, pAlloc);
+ vboxWddmDalRemove(pAlloc);
continue;
}
}
@@ -356,31 +411,122 @@ static HRESULT vboxWddmDalNotifyChange(PVBOXWDDMDISP_DEVICE pDevice)
return S_OK;
}
-//#define VBOX_WDDM_SHRC_WO_NOTIFY
+#ifdef VBOXWDDMDISP_DAL_CHECK_LOCK
+static HRESULT vboxWddmDalCheckUnlock(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc)
+{
+ if (!pAlloc->fAllocLocked || pAlloc->LockInfo.cLocks)
+ return S_OK;
+
+ Assert(pAlloc->hAllocation);
+
+ D3DDDICB_UNLOCK Unlock;
+
+ Unlock.NumAllocations = 1;
+ Unlock.phAllocations = &pAlloc->hAllocation;
+
+ HRESULT hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &Unlock);
+ if(hr != S_OK)
+ {
+ WARN(("pfnUnlockCb failed, hr %#x", hr));
+ }
+
+ return hr;
+}
+
+static HRESULT vboxWddmDalCheckLock(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc, D3DDDI_LOCKFLAGS Flags)
+{
+ if (!pAlloc->hAllocation || pAlloc->fAllocLocked)
+ return S_OK;
+
+ HRESULT hr;
+
+ if (pAlloc->fDirtyWrite)
+ {
+ Assert(pAlloc->DirtyAllocListEntry.pNext);
+ hr = vboxWddmDalNotifyChange(pDevice);
+ if (hr == S_OK)
+ {
+ Assert(!pAlloc->DirtyAllocListEntry.pNext);
+ }
+ else
+ {
+ WARN(("vboxWddmDalNotifyChange failed %#x, ignoring", hr));
+ }
+ }
+
+ D3DDDICB_LOCK LockData;
+ LockData.hAllocation = pAlloc->hAllocation;
+ LockData.PrivateDriverData = 0;
+ LockData.NumPages = 0;
+ LockData.pPages = NULL;
+ LockData.pData = NULL; /* out */
+ LockData.Flags.Value = 0;
+ LockData.Flags.Discard = Flags.Discard;
+ LockData.Flags.DonotWait = Flags.DoNotWait;
+
+ hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &LockData);
+ if (hr == S_OK)
+ {
+ if (!Flags.ReadOnly)
+ pAlloc->fEverWritten = TRUE;
+ pAlloc->fAllocLocked = TRUE;
+ return S_OK;
+ }
+
+ WARN(("pfnLockCb failed %#x, Flags %#x", hr, Flags.Value));
+
+ return hr;
+}
+#endif
+
+static BOOLEAN vboxWddmDalCheckNotifyRemove(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc)
+{
+ if (pAlloc->DirtyAllocListEntry.pNext)
+ {
+ HRESULT hr = vboxWddmDalNotifyChange(pDevice);
+ if (hr == S_OK)
+ {
+ Assert(!pAlloc->DirtyAllocListEntry.pNext);
+ }
+ else
+ {
+ WARN(("vboxWddmDalNotifyChange failed %#x", hr));
+ if (pAlloc->DirtyAllocListEntry.pNext)
+ vboxWddmDalRemove(pAlloc);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static BOOLEAN vboxWddmDalCheckAdd(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_ALLOCATION pAlloc, BOOLEAN fWrite)
{
if (!pAlloc->hAllocation /* only shared resources matter */
-#ifdef VBOX_WDDM_SHRC_WO_NOTIFY
- || !fWrite /* only write op matter */
-#endif
+ || (/*!fWrite &&*/ !pAlloc->hSharedHandle)
)
{
-#ifdef VBOX_WDDM_SHRC_WO_NOTIFY
- Assert(!pAlloc->DirtyAllocListEntry.pNext || (!fWrite && pAlloc->hSharedHandle && pAlloc->fDirtyWrite));
-#else
- Assert(!pAlloc->DirtyAllocListEntry.pNext);
-#endif
+ Assert(!pAlloc->DirtyAllocListEntry.pNext || pAlloc->hSharedHandle /*|| pAlloc->fDirtyWrite*/);
+
Assert(!pAlloc->hSharedHandle);
return FALSE;
}
+ Assert(fWrite || pAlloc->fEverWritten || pAlloc->pRc->RcDesc.fFlags.SharedResource);
+
if (!pAlloc->DirtyAllocListEntry.pNext)
{
Assert(!pAlloc->fDirtyWrite);
RTListAppend(&pDevice->DirtyAllocList, &pAlloc->DirtyAllocListEntry);
}
+ else
+ {
+ Assert(pAlloc->fDirtyWrite == fWrite);
+ }
pAlloc->fDirtyWrite |= fWrite;
+ pAlloc->fEverWritten |= fWrite;
return TRUE;
}
@@ -396,7 +542,13 @@ static DECLINLINE(BOOLEAN) vboxWddmDalCheckAddRc(PVBOXWDDMDISP_DEVICE pDevice, P
return fChanged;
}
-static VOID vboxWddmDalCheckAddRtsSamplers(PVBOXWDDMDISP_DEVICE pDevice)
+static VOID vboxWddmDalCheckAddDepthStencil(PVBOXWDDMDISP_DEVICE pDevice)
+{
+ if (pDevice->pDepthStencilRc)
+ vboxWddmDalCheckAddRc(pDevice, pDevice->pDepthStencilRc, TRUE);
+}
+
+static VOID vboxWddmDalCheckAddRTs(PVBOXWDDMDISP_DEVICE pDevice)
{
for (UINT i = 0; i < pDevice->cRTs; ++i)
{
@@ -405,7 +557,10 @@ static VOID vboxWddmDalCheckAddRtsSamplers(PVBOXWDDMDISP_DEVICE pDevice)
vboxWddmDalCheckAdd(pDevice, pDevice->apRTs[i], TRUE);
}
}
+}
+static VOID vboxWddmDalCheckAddSamplers(PVBOXWDDMDISP_DEVICE pDevice)
+{
for (UINT i = 0, iSampler = 0; iSampler < pDevice->cSamplerTextures; ++i)
{
Assert(i < RT_ELEMENTS(pDevice->aSamplerTextures));
@@ -415,6 +570,20 @@ static VOID vboxWddmDalCheckAddRtsSamplers(PVBOXWDDMDISP_DEVICE pDevice)
}
}
+static VOID vboxWddmDalCheckAddOnDraw(PVBOXWDDMDISP_DEVICE pDevice)
+{
+ vboxWddmDalCheckAddRTs(pDevice);
+
+ vboxWddmDalCheckAddDepthStencil(pDevice);
+
+ vboxWddmDalCheckAddSamplers(pDevice);
+}
+
+static BOOLEAN vboxWddmDalIsEmpty(PVBOXWDDMDISP_DEVICE pDevice)
+{
+ return RTListIsEmpty(&pDevice->DirtyAllocList);
+}
+
#ifdef VBOX_WITH_VIDEOHWACCEL
static bool vboxVhwaIsEnabled(PVBOXWDDMDISP_ADAPTER pAdapter)
@@ -569,6 +738,13 @@ static HRESULT vboxWddmSwapchainKmSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMD
Buf.SwapchainInfo.EscapeHdr.escapeCode = VBOXESC_SWAPCHAININFO;
Buf.SwapchainInfo.SwapchainInfo.hSwapchainKm = pSwapchain->hSwapchainKm;
Buf.SwapchainInfo.SwapchainInfo.hSwapchainUm = (VBOXDISP_UMHANDLE)pSwapchain;
+ HRESULT hr = pDevice->pAdapter->D3D.D3D.pfnVBoxWineExD3DSwapchain9GetHostWinID(pSwapchain->pSwapChainIf, &Buf.SwapchainInfo.SwapchainInfo.winHostID);
+ if (FAILED(hr))
+ {
+ WARN(("pfnVBoxWineExD3DSwapchain9GetHostWinID failed, hr 0x%x", hr));
+ return hr;
+ }
+ Assert(Buf.SwapchainInfo.SwapchainInfo.winHostID);
// Buf.SwapchainInfo.SwapchainInfo.Rect;
// Buf.SwapchainInfo.SwapchainInfo.u32Reserved;
Buf.SwapchainInfo.SwapchainInfo.cAllocs = pSwapchain->cRTs;
@@ -582,7 +758,6 @@ static HRESULT vboxWddmSwapchainKmSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMD
}
Assert(cAllocsKm == Buf.SwapchainInfo.SwapchainInfo.cAllocs || !cAllocsKm);
- HRESULT hr = S_OK;
if (cAllocsKm == Buf.SwapchainInfo.SwapchainInfo.cAllocs)
{
D3DDDICB_ESCAPE DdiEscape = {0};
@@ -651,7 +826,6 @@ DECLINLINE(VOID) vboxWddmSwapchainClear(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMD
/* first do a Km destroy to ensure all km->um region submissions are completed */
vboxWddmSwapchainKmDestroy(pDevice, pSwapchain);
- vboxDispMpInternalCancel(&pDevice->DefaultContext, pSwapchain);
vboxWddmSwapchainDestroyIf(pDevice, pSwapchain);
vboxWddmSwapchainInit(pSwapchain);
}
@@ -1029,7 +1203,7 @@ static HRESULT vboxWddmSwapchainRtSynch(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMD
}
else
{
- WARN(("GetFrontBufferData failed, hr (0x%x)", hr));
+ WARN(("GetFrontBufferData failed, hr (0x%x)", tmpHr));
}
}
#endif
@@ -1771,7 +1945,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstance,
#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
vboxVDbgVEHandlerRegister();
#endif
- int rc = RTR3InitDll(0);
+ int rc = RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE);
AssertRC(rc);
if (RT_SUCCESS(rc))
{
@@ -1783,14 +1957,9 @@ BOOL WINAPI DllMain(HINSTANCE hInstance,
Assert(hr == S_OK);
if (hr == S_OK)
{
- hr = vboxDispMpInternalInit();
- Assert(hr == S_OK);
- if (hr == S_OK)
- {
- VBoxDispD3DGlobalInit();
- vboxVDbgPrint(("VBoxDispD3D: DLL loaded OK\n"));
- return TRUE;
- }
+ VBoxDispD3DGlobalInit();
+ vboxVDbgPrint(("VBoxDispD3D: DLL loaded OK\n"));
+ return TRUE;
}
// VbglR3Term();
}
@@ -1807,19 +1976,14 @@ BOOL WINAPI DllMain(HINSTANCE hInstance,
#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
vboxVDbgVEHandlerUnregister();
#endif
- HRESULT hr = vboxDispMpInternalTerm();
+ HRESULT hr = vboxDispCmTerm();
Assert(hr == S_OK);
if (hr == S_OK)
{
- hr = vboxDispCmTerm();
- Assert(hr == S_OK);
- if (hr == S_OK)
- {
// VbglR3Term();
- /// @todo RTR3Term();
- VBoxDispD3DGlobalTerm();
- return TRUE;
- }
+ /// @todo RTR3Term();
+ VBoxDispD3DGlobalTerm();
+ return TRUE;
}
break;
@@ -1833,7 +1997,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstance,
static HRESULT APIENTRY vboxWddmDispGetCaps (HANDLE hAdapter, CONST D3DDDIARG_GETCAPS* pData)
{
- VBOXDISP_DDI_PROLOGUE_ADP(hAdapter);
+ VBOXDISP_DDI_PROLOGUE_ADP(hAdapter);
vboxVDbgPrint(("==> "__FUNCTION__", hAdapter(0x%p), caps type(%d)\n", hAdapter, pData->Type));
@@ -2417,34 +2581,47 @@ static HRESULT APIENTRY vboxWddmDDevDrawPrimitive(HANDLE hDevice, CONST D3DDDIAR
VBOXVDBG_DUMP_DRAWPRIM_ENTER(pDevice);
- if (!pDevice->cStreamSources)
+ if (pDevice->cStreamSourcesUm)
{
- if (pDevice->aStreamSourceUm[0].pvBuffer)
- {
#ifdef DEBUG
- for (UINT i = 1; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
+ uint32_t cStreams = 0;
+ for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
+ {
+ if(pDevice->aStreamSourceUm[i].pvBuffer)
{
- Assert(!pDevice->aStreamSourceUm[i].pvBuffer);
+ ++cStreams;
}
-#endif
- hr = pDevice9If->DrawPrimitiveUP(pData->PrimitiveType,
- pData->PrimitiveCount,
- ((uint8_t*)pDevice->aStreamSourceUm[0].pvBuffer) + pData->VStart * pDevice->aStreamSourceUm[0].cbStride,
- pDevice->aStreamSourceUm[0].cbStride);
- Assert(hr == S_OK);
+ }
-// vboxVDbgMpPrintF((pDevice, __FUNCTION__": DrawPrimitiveUP\n"));
+ Assert(cStreams);
+ Assert(cStreams == pDevice->cStreamSourcesUm);
+#endif
+ if (pDevice->cStreamSourcesUm == 1)
+ {
+ for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
+ {
+ if(pDevice->aStreamSourceUm[i].pvBuffer)
+ {
+ hr = pDevice9If->DrawPrimitiveUP(pData->PrimitiveType,
+ pData->PrimitiveCount,
+ ((uint8_t*)pDevice->aStreamSourceUm[i].pvBuffer) + pData->VStart * pDevice->aStreamSourceUm[i].cbStride,
+ pDevice->aStreamSourceUm[i].cbStride);
+ Assert(hr == S_OK);
+ break;
+ }
+ }
}
else
{
/* todo: impl */
- Assert(0);
+ WARN(("multiple user stream sources (%d) not implemented!!", pDevice->cStreamSourcesUm));
}
}
else
{
#ifdef DEBUG
+ Assert(!pDevice->cStreamSourcesUm);
for (UINT i = 0; i < RT_ELEMENTS(pDevice->aStreamSourceUm); ++i)
{
Assert(!pDevice->aStreamSourceUm[i].pvBuffer);
@@ -2471,7 +2648,7 @@ static HRESULT APIENTRY vboxWddmDDevDrawPrimitive(HANDLE hDevice, CONST D3DDDIAR
// vboxVDbgMpPrintF((pDevice, __FUNCTION__": DrawPrimitive\n"));
}
- vboxWddmDalCheckAddRtsSamplers(pDevice);
+ vboxWddmDalCheckAddOnDraw(pDevice);
VBOXVDBG_DUMP_DRAWPRIM_LEAVE(pDevice);
@@ -2602,7 +2779,7 @@ static HRESULT APIENTRY vboxWddmDDevDrawIndexedPrimitive(HANDLE hDevice, CONST D
}
}
- vboxWddmDalCheckAddRtsSamplers(pDevice);
+ vboxWddmDalCheckAddOnDraw(pDevice);
VBOXVDBG_DUMP_DRAWPRIM_LEAVE(pDevice);
@@ -2618,7 +2795,7 @@ static HRESULT APIENTRY vboxWddmDDevDrawRectPatch(HANDLE hDevice, CONST D3DDDIAR
Assert(pDevice);
VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
Assert(0);
- vboxWddmDalCheckAddRtsSamplers(pDevice);
+ vboxWddmDalCheckAddOnDraw(pDevice);
vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
return E_FAIL;
}
@@ -2631,7 +2808,7 @@ static HRESULT APIENTRY vboxWddmDDevDrawTriPatch(HANDLE hDevice, CONST D3DDDIARG
Assert(pDevice);
VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
Assert(0);
- vboxWddmDalCheckAddRtsSamplers(pDevice);
+ vboxWddmDalCheckAddOnDraw(pDevice);
vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
return E_FAIL;
}
@@ -2724,7 +2901,7 @@ static HRESULT APIENTRY vboxWddmDDevDrawPrimitive2(HANDLE hDevice, CONST D3DDDIA
#endif
#endif
- vboxWddmDalCheckAddRtsSamplers(pDevice);
+ vboxWddmDalCheckAddOnDraw(pDevice);
VBOXVDBG_DUMP_DRAWPRIM_LEAVE(pDevice);
@@ -2808,7 +2985,7 @@ static HRESULT APIENTRY vboxWddmDDevDrawIndexedPrimitive2(HANDLE hDevice, CONST
}
}
- vboxWddmDalCheckAddRtsSamplers(pDevice);
+ vboxWddmDalCheckAddOnDraw(pDevice);
vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
return hr;
}
@@ -2895,7 +3072,7 @@ static HRESULT APIENTRY vboxWddmDDevTexBlt(HANDLE hDevice, CONST D3DDDIARG_TEXBL
VBOXVDBG_CHECK_SMSYNC(pDstRc);
VBOXVDBG_CHECK_SMSYNC(pSrcRc);
- if (pSrcRc->aAllocations[0].D3DWidth == pDstRc->aAllocations[0].D3DWidth
+ if (pSrcRc->aAllocations[0].SurfDesc.d3dWidth == pDstRc->aAllocations[0].SurfDesc.d3dWidth
&& pSrcRc->aAllocations[0].SurfDesc.height == pDstRc->aAllocations[0].SurfDesc.height
&& pSrcRc->RcDesc.enmFormat == pDstRc->RcDesc.enmFormat
&&pData->DstPoint.x == 0 && pData->DstPoint.y == 0
@@ -2998,7 +3175,17 @@ static HRESULT APIENTRY vboxWddmDDevClear(HANDLE hDevice, CONST D3DDDIARG_CLEAR*
pData->FillColor,
pData->FillDepth,
pData->FillStencil);
- Assert(hr == S_OK);
+ if (SUCCEEDED(hr))
+ {
+ if (pData->Flags & D3DCLEAR_TARGET)
+ vboxWddmDalCheckAddRTs(pDevice);
+ if ((pData->Flags & D3DCLEAR_STENCIL)
+ || (pData->Flags & D3DCLEAR_ZBUFFER))
+ vboxWddmDalCheckAddDepthStencil(pDevice);
+ }
+ else
+ WARN(("Clear failed %#x", hr));
+
vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
return hr;
}
@@ -3213,15 +3400,24 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData)
Assert(pDevice);
VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hResource;
- Assert(pData->SubResourceIndex < pRc->cAllocations);
if (pData->SubResourceIndex >= pRc->cAllocations)
return E_INVALIDARG;
+ PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
+ Assert(pData->SubResourceIndex < pRc->cAllocations);
HRESULT hr = S_OK;
if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
{
// Assert(pRc != pScreen->pRenderTargetRc || pScreen->iRenderTargetFrontBuf != pData->SubResourceIndex);
+#ifdef VBOXWDDMDISP_DAL_CHECK_LOCK
+ hr = vboxWddmDalCheckLock(pDevice, pAlloc, pData->Flags);
+ if (!SUCCEEDED(hr))
+ {
+ WARN(("vboxWddmDalCheckLock failed %#x", hr));
+ return hr;
+ }
+#endif
if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE
|| pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_CUBE_TEXTURE
@@ -3229,7 +3425,6 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData)
{
PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0];
Assert(pData->SubResourceIndex < pRc->cAllocations);
- PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex];
IDirect3DTexture9 *pD3DIfTex = (IDirect3DTexture9*)pTexAlloc->pD3DIf;
IDirect3DCubeTexture9 *pD3DIfCubeTex = (IDirect3DCubeTexture9*)pTexAlloc->pD3DIf;
IDirect3DSurface9 *pD3DIfSurface = (IDirect3DSurface9*)pTexAlloc->pD3DIf;
@@ -3245,20 +3440,20 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData)
/* else - we lock the entire texture, pRect == NULL */
- if (pLockAlloc->LockInfo.cLocks)
+ if (pAlloc->LockInfo.cLocks)
{
- Assert(pLockAlloc->LockInfo.fFlags.AreaValid == pData->Flags.AreaValid);
- if (pLockAlloc->LockInfo.fFlags.AreaValid && pData->Flags.AreaValid)
+ Assert(pAlloc->LockInfo.fFlags.AreaValid == pData->Flags.AreaValid);
+ if (pAlloc->LockInfo.fFlags.AreaValid && pData->Flags.AreaValid)
{
- Assert(pLockAlloc->LockInfo.Area.left == pData->Area.left);
- Assert(pLockAlloc->LockInfo.Area.top == pData->Area.top);
- Assert(pLockAlloc->LockInfo.Area.right == pData->Area.right);
- Assert(pLockAlloc->LockInfo.Area.bottom == pData->Area.bottom);
+ Assert(pAlloc->LockInfo.Area.left == pData->Area.left);
+ Assert(pAlloc->LockInfo.Area.top == pData->Area.top);
+ Assert(pAlloc->LockInfo.Area.right == pData->Area.right);
+ Assert(pAlloc->LockInfo.Area.bottom == pData->Area.bottom);
}
- Assert(pLockAlloc->LockInfo.LockedRect.pBits);
- Assert((pLockAlloc->LockInfo.fFlags.Value & ~1) == (pData->Flags.Value & ~1)); /* <- 1 is "ReadOnly" flag */
+ Assert(pAlloc->LockInfo.LockedRect.pBits);
+ Assert((pAlloc->LockInfo.fFlags.Value & ~1) == (pData->Flags.Value & ~1)); /* <- 1 is "ReadOnly" flag */
- if (pLockAlloc->LockInfo.fFlags.ReadOnly && !pData->Flags.ReadOnly)
+ if (pAlloc->LockInfo.fFlags.ReadOnly && !pData->Flags.ReadOnly)
{
switch (pTexAlloc->enmD3DIfType)
{
@@ -3288,34 +3483,34 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData)
{
VBOXVDBG_CHECK_SMSYNC(pRc);
- pLockAlloc->LockInfo.fFlags = pData->Flags;
+ pAlloc->LockInfo.fFlags = pData->Flags;
if (pRect)
{
- pLockAlloc->LockInfo.Area = *pRect;
- Assert(pLockAlloc->LockInfo.fFlags.AreaValid == 1);
+ pAlloc->LockInfo.Area = *pRect;
+ Assert(pAlloc->LockInfo.fFlags.AreaValid == 1);
}
else
{
- Assert(pLockAlloc->LockInfo.fFlags.AreaValid == 0);
+ Assert(pAlloc->LockInfo.fFlags.AreaValid == 0);
}
switch (pTexAlloc->enmD3DIfType)
{
case VBOXDISP_D3DIFTYPE_TEXTURE:
hr = pD3DIfTex->LockRect(pData->SubResourceIndex,
- &pLockAlloc->LockInfo.LockedRect,
+ &pAlloc->LockInfo.LockedRect,
pRect,
vboxDDI2D3DLockFlags(pData->Flags));
break;
case VBOXDISP_D3DIFTYPE_CUBE_TEXTURE:
hr = pD3DIfCubeTex->LockRect(VBOXDISP_CUBEMAP_INDEX_TO_FACE(pRc, pData->SubResourceIndex),
VBOXDISP_CUBEMAP_INDEX_TO_LEVEL(pRc, pData->SubResourceIndex),
- &pLockAlloc->LockInfo.LockedRect,
+ &pAlloc->LockInfo.LockedRect,
pRect,
vboxDDI2D3DLockFlags(pData->Flags));
break;
case VBOXDISP_D3DIFTYPE_SURFACE:
- hr = pD3DIfSurface->LockRect(&pLockAlloc->LockInfo.LockedRect,
+ hr = pD3DIfSurface->LockRect(&pAlloc->LockInfo.LockedRect,
pRect,
vboxDDI2D3DLockFlags(pData->Flags));
break;
@@ -3332,19 +3527,19 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData)
if (SUCCEEDED(hr))
{
- ++pLockAlloc->LockInfo.cLocks;
+ ++pAlloc->LockInfo.cLocks;
if (!pData->Flags.NotifyOnly)
{
- pData->pSurfData = pLockAlloc->LockInfo.LockedRect.pBits;
- pData->Pitch = pLockAlloc->LockInfo.LockedRect.Pitch;
+ pData->pSurfData = pAlloc->LockInfo.LockedRect.pBits;
+ pData->Pitch = pAlloc->LockInfo.LockedRect.Pitch;
pData->SlicePitch = 0;
- Assert(pLockAlloc->SurfDesc.slicePitch == 0);
- Assert(!pLockAlloc->pvMem);
+ Assert(pAlloc->SurfDesc.slicePitch == 0);
+ Assert(!pAlloc->pvMem);
}
else
{
- Assert(pLockAlloc->pvMem);
+ Assert(pAlloc->pvMem);
Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
}
@@ -3357,7 +3552,6 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData)
{
PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0];
Assert(pData->SubResourceIndex < pRc->cAllocations);
- PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex];
IDirect3DVolumeTexture9 *pD3DIfTex = (IDirect3DVolumeTexture9*)pTexAlloc->pD3DIf;
Assert(pTexAlloc->pD3DIf);
D3DDDIBOX *pBox = NULL;
@@ -3371,22 +3565,22 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData)
/* else - we lock the entire texture, pBox == NULL */
- if (pLockAlloc->LockInfo.cLocks)
+ if (pAlloc->LockInfo.cLocks)
{
- Assert(pLockAlloc->LockInfo.fFlags.BoxValid == pData->Flags.BoxValid);
- if (pLockAlloc->LockInfo.fFlags.BoxValid && pData->Flags.BoxValid)
+ Assert(pAlloc->LockInfo.fFlags.BoxValid == pData->Flags.BoxValid);
+ if (pAlloc->LockInfo.fFlags.BoxValid && pData->Flags.BoxValid)
{
- Assert(pLockAlloc->LockInfo.Box.Left == pData->Box.Left);
- Assert(pLockAlloc->LockInfo.Box.Top == pData->Box.Top);
- Assert(pLockAlloc->LockInfo.Box.Right == pData->Box.Right);
- Assert(pLockAlloc->LockInfo.Box.Bottom == pData->Box.Bottom);
- Assert(pLockAlloc->LockInfo.Box.Front == pData->Box.Front);
- Assert(pLockAlloc->LockInfo.Box.Back == pData->Box.Back);
+ Assert(pAlloc->LockInfo.Box.Left == pData->Box.Left);
+ Assert(pAlloc->LockInfo.Box.Top == pData->Box.Top);
+ Assert(pAlloc->LockInfo.Box.Right == pData->Box.Right);
+ Assert(pAlloc->LockInfo.Box.Bottom == pData->Box.Bottom);
+ Assert(pAlloc->LockInfo.Box.Front == pData->Box.Front);
+ Assert(pAlloc->LockInfo.Box.Back == pData->Box.Back);
}
- Assert(pLockAlloc->LockInfo.LockedBox.pBits);
- Assert((pLockAlloc->LockInfo.fFlags.Value & ~1) == (pData->Flags.Value & ~1)); /* <- 1 is "ReadOnly" flag */
+ Assert(pAlloc->LockInfo.LockedBox.pBits);
+ Assert((pAlloc->LockInfo.fFlags.Value & ~1) == (pData->Flags.Value & ~1)); /* <- 1 is "ReadOnly" flag */
- if (pLockAlloc->LockInfo.fFlags.ReadOnly && !pData->Flags.ReadOnly)
+ if (pAlloc->LockInfo.fFlags.ReadOnly && !pData->Flags.ReadOnly)
{
hr = pD3DIfTex->UnlockBox(pData->SubResourceIndex);
Assert(hr == S_OK);
@@ -3401,19 +3595,19 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData)
{
VBOXVDBG_CHECK_SMSYNC(pRc);
- pLockAlloc->LockInfo.fFlags = pData->Flags;
+ pAlloc->LockInfo.fFlags = pData->Flags;
if (pBox)
{
- pLockAlloc->LockInfo.Box = *pBox;
- Assert(pLockAlloc->LockInfo.fFlags.BoxValid == 1);
+ pAlloc->LockInfo.Box = *pBox;
+ Assert(pAlloc->LockInfo.fFlags.BoxValid == 1);
}
else
{
- Assert(pLockAlloc->LockInfo.fFlags.BoxValid == 0);
+ Assert(pAlloc->LockInfo.fFlags.BoxValid == 0);
}
hr = pD3DIfTex->LockBox(pData->SubResourceIndex,
- &pLockAlloc->LockInfo.LockedBox,
+ &pAlloc->LockInfo.LockedBox,
(D3DBOX*)pBox,
vboxDDI2D3DLockFlags(pData->Flags));
if (FAILED(hr))
@@ -3424,18 +3618,18 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData)
if (SUCCEEDED(hr))
{
- ++pLockAlloc->LockInfo.cLocks;
+ ++pAlloc->LockInfo.cLocks;
if (!pData->Flags.NotifyOnly)
{
- pData->pSurfData = pLockAlloc->LockInfo.LockedBox.pBits;
- pData->Pitch = pLockAlloc->LockInfo.LockedBox.RowPitch;
- pData->SlicePitch = pLockAlloc->LockInfo.LockedBox.SlicePitch;
- Assert(!pLockAlloc->pvMem);
+ pData->pSurfData = pAlloc->LockInfo.LockedBox.pBits;
+ pData->Pitch = pAlloc->LockInfo.LockedBox.RowPitch;
+ pData->SlicePitch = pAlloc->LockInfo.LockedBox.SlicePitch;
+ Assert(!pAlloc->pvMem);
}
else
{
- Assert(pLockAlloc->pvMem);
+ Assert(pAlloc->pvMem);
Assert(pRc->RcDesc.enmPool == D3DDDIPOOL_SYSTEMMEM);
}
@@ -3447,7 +3641,6 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData)
else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VERTEXBUFFER)
{
Assert(pData->SubResourceIndex < pRc->cAllocations);
- PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
IDirect3DVertexBuffer9 *pD3D9VBuf = (IDirect3DVertexBuffer9*)pAlloc->pD3DIf;
BOOL bLocked = false;
Assert(pD3D9VBuf);
@@ -3478,7 +3671,7 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData)
{
Assert(pAlloc->SurfDesc.pitch == pAlloc->SurfDesc.width);
pAlloc->LockInfo.LockedRect.Pitch = pAlloc->SurfDesc.pitch;
-// Assert(pLockAlloc->LockInfo.fFlags.Value == 0);
+// Assert(pAlloc->LockInfo.fFlags.Value == 0);
pAlloc->LockInfo.fFlags = pData->Flags;
if (pRange)
{
@@ -3541,7 +3734,6 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData)
else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_INDEXBUFFER)
{
Assert(pData->SubResourceIndex < pRc->cAllocations);
- PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
IDirect3DIndexBuffer9 *pD3D9IBuf = (IDirect3DIndexBuffer9*)pAlloc->pD3DIf;
BOOL bLocked = false;
Assert(pD3D9IBuf);
@@ -3572,7 +3764,7 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData)
{
Assert(pAlloc->SurfDesc.pitch == pAlloc->SurfDesc.width);
pAlloc->LockInfo.LockedRect.Pitch = pAlloc->SurfDesc.pitch;
-// Assert(pLockAlloc->LockInfo.fFlags.Value == 0);
+// Assert(pAlloc->LockInfo.fFlags.Value == 0);
pAlloc->LockInfo.fFlags = pData->Flags;
if (pRange)
{
@@ -3634,12 +3826,19 @@ static HRESULT APIENTRY vboxWddmDDevLock(HANDLE hDevice, D3DDDIARG_LOCK* pData)
}
else
{
- Assert(0);
+ WARN(("not implemented %d", pRc->aAllocations[0].enmD3DIfType));
}
+
+#ifdef VBOXWDDMDISP_DAL_CHECK_LOCK
+ if (!SUCCEEDED(hr))
+ {
+ WARN(("lock failed %#x", hr));
+ vboxWddmDalCheckUnlock(pDevice, pAlloc);
+ }
+#endif
}
else /* if !VBOXDISPMODE_IS_3D(pDevice->pAdapter) */
{
- PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
if (pAlloc->hAllocation)
{
if (pRc->RcDesc.enmPool != D3DDDIPOOL_SYSTEMMEM)
@@ -3736,6 +3935,8 @@ static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOC
if (pData->SubResourceIndex >= pRc->cAllocations)
return E_INVALIDARG;
+ PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
+
if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
{
if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_TEXTURE
@@ -3743,13 +3944,12 @@ static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOC
|| pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_SURFACE)
{
Assert(pData->SubResourceIndex < pRc->cAllocations);
- PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex];
VBOXVDBG_DUMP_UNLOCK_ST(pData);
- --pLockAlloc->LockInfo.cLocks;
- Assert(pLockAlloc->LockInfo.cLocks < UINT32_MAX);
- if (!pLockAlloc->LockInfo.cLocks)
+ --pAlloc->LockInfo.cLocks;
+ Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
+ if (!pAlloc->LockInfo.cLocks)
{
PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0];
Assert(pTexAlloc->pD3DIf);
@@ -3786,13 +3986,12 @@ static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOC
else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VOLUME_TEXTURE)
{
Assert(pData->SubResourceIndex < pRc->cAllocations);
- PVBOXWDDMDISP_ALLOCATION pLockAlloc = &pRc->aAllocations[pData->SubResourceIndex];
VBOXVDBG_DUMP_UNLOCK_ST(pData);
- --pLockAlloc->LockInfo.cLocks;
- Assert(pLockAlloc->LockInfo.cLocks < UINT32_MAX);
- if (!pLockAlloc->LockInfo.cLocks)
+ --pAlloc->LockInfo.cLocks;
+ Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
+ if (!pAlloc->LockInfo.cLocks)
{
PVBOXWDDMDISP_ALLOCATION pTexAlloc = &pRc->aAllocations[0];
Assert(pTexAlloc->pD3DIf);
@@ -3806,7 +4005,6 @@ static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOC
else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_VERTEXBUFFER)
{
Assert(pData->SubResourceIndex < pRc->cAllocations);
- PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
--pAlloc->LockInfo.cLocks;
Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
@@ -3847,7 +4045,6 @@ static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOC
else if (pRc->aAllocations[0].enmD3DIfType == VBOXDISP_D3DIFTYPE_INDEXBUFFER)
{
Assert(pData->SubResourceIndex < pRc->cAllocations);
- PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
--pAlloc->LockInfo.cLocks;
Assert(pAlloc->LockInfo.cLocks < UINT32_MAX);
@@ -3887,13 +4084,22 @@ static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOC
}
else
{
- Assert(0);
+ WARN(("Unlock unsupported %d", pRc->aAllocations[0].enmD3DIfType));
+ }
+
+#ifdef VBOXWDDMDISP_DAL_CHECK_LOCK
+ if (SUCCEEDED(hr))
+ {
+ hr = vboxWddmDalCheckUnlock(pDevice, pAlloc);
+ if (!SUCCEEDED(hr))
+ WARN(("vboxWddmDalCheckUnlock failed %#x", hr));
}
+ else
+ WARN(("unlock failed %#x", hr));
+#endif
}
else
{
- PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
-
if (pAlloc->hAllocation)
{
BOOL fDoUnlock = FALSE;
@@ -3938,18 +4144,12 @@ static HRESULT APIENTRY vboxWddmDDevUnlock(HANDLE hDevice, CONST D3DDDIARG_UNLOC
if (fDoUnlock)
{
- struct
- {
- D3DDDICB_UNLOCK Unlock;
- D3DKMT_HANDLE hAllocation;
- } UnlockData;
+ D3DDDICB_UNLOCK Unlock;
+ Unlock.NumAllocations = 1;
+ Unlock.phAllocations = &pAlloc->hAllocation;
- UnlockData.Unlock.NumAllocations = 1;
- UnlockData.Unlock.phAllocations = &UnlockData.hAllocation;
- UnlockData.hAllocation = pAlloc->hAllocation;
-
- hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &UnlockData.Unlock);
+ hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &Unlock);
if(hr != S_OK)
{
WARN(("pfnUnlockCb failed, hr 0x%x", hr));
@@ -4062,6 +4262,7 @@ static HRESULT APIENTRY vboxWddmDDevCreateResource(HANDLE hDevice, D3DDDIARG_CRE
}
bool bIssueCreateResource = false;
bool bCreateKMResource = false;
+ bool bSetHostID = false;
pRc->hResource = pResource->hResource;
pRc->hKMResource = NULL;
@@ -4087,7 +4288,7 @@ static HRESULT APIENTRY vboxWddmDDevCreateResource(HANDLE hDevice, D3DDDIARG_CRE
pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
pAllocation->iAlloc = i;
pAllocation->pRc = pRc;
- pAllocation->D3DWidth = pSurf->Width;
+ pAllocation->SurfDesc.d3dWidth = pSurf->Width;
pAllocation->pvMem = (void*)pSurf->pSysMem;
pAllocation->SurfDesc.slicePitch = pSurf->SysMemSlicePitch;
pAllocation->SurfDesc.depth = pSurf->Depth;
@@ -4119,14 +4320,14 @@ static HRESULT APIENTRY vboxWddmDDevCreateResource(HANDLE hDevice, D3DDDIARG_CRE
if (pAllocation->SurfDesc.pitch != minPitch)
{
Assert(pAllocation->SurfDesc.pitch > minPitch);
- pAllocation->D3DWidth = vboxWddmCalcWidthForPitch(pAllocation->SurfDesc.pitch, pAllocation->SurfDesc.format);
+ pAllocation->SurfDesc.d3dWidth = vboxWddmCalcWidthForPitch(pAllocation->SurfDesc.pitch, pAllocation->SurfDesc.format);
Assert(VBOXWDDMDISP_IS_TEXTURE(pRc->RcDesc.fFlags) && !pRc->RcDesc.fFlags.CubeMap); /* <- tested for textures only! */
}
- Assert(pAllocation->D3DWidth >= pAllocation->SurfDesc.width);
+ Assert(pAllocation->SurfDesc.d3dWidth >= pAllocation->SurfDesc.width);
}
else
{
- Assert(pAllocation->D3DWidth == pAllocation->SurfDesc.width);
+ Assert(pAllocation->SurfDesc.d3dWidth == pAllocation->SurfDesc.width);
}
}
@@ -4140,9 +4341,10 @@ static HRESULT APIENTRY vboxWddmDDevCreateResource(HANDLE hDevice, D3DDDIARG_CRE
bCreateKMResource = true;
}
- if (pRc->RcDesc.fFlags.RenderTarget)
+ if (pRc->RcDesc.fFlags.RenderTarget || pRc->RcDesc.fFlags.Primary)
{
bIssueCreateResource = true;
+ bSetHostID = true;
}
hr = VBoxD3DIfCreateForRc(pRc);
@@ -4194,92 +4396,121 @@ static HRESULT APIENTRY vboxWddmDDevCreateResource(HANDLE hDevice, D3DDDIARG_CRE
pAllocInfo->fFlags = pResource->Flags;
pAllocInfo->hSharedHandle = (uint64_t)pAllocation->hSharedHandle;
pAllocInfo->SurfDesc = pAllocation->SurfDesc;
+ if (bSetHostID)
+ {
+ IDirect3DSurface9 *pSurfIf = NULL;
+ hr = VBoxD3DIfSurfGet(pRc, i, &pSurfIf);
+ if (SUCCEEDED(hr))
+ {
+ hr = pAdapter->D3D.D3D.pfnVBoxWineExD3DSurf9GetHostId(pSurfIf, &pAllocInfo->hostID);
+ if (SUCCEEDED(hr))
+ {
+ Assert(pAllocInfo->hostID);
+ }
+ else
+ {
+ WARN(("pfnVBoxWineExD3DSurf9GetHostId failed, hr 0x%x", hr));
+ break;
+ }
+ pSurfIf->Release();
+ }
+ else
+ {
+ WARN(("VBoxD3DIfSurfGet failed, hr 0x%x", hr));
+ break;
+ }
+ }
+ else
+ pAllocInfo->hostID = 0;
}
Assert(!pRc->fFlags.Opened);
// Assert(!pRc->fFlags.KmResource);
Assert(pRc->fFlags.Generic);
- if (bCreateKMResource)
- {
- Assert(pRc->fFlags.KmResource);
-
- hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pDdiAllocate);
- Assert(hr == S_OK);
- Assert(pDdiAllocate->hKMResource
- || pResource->Flags.SharedResource /* for some reason shared resources
- * are created with zero km resource handle on Win7+ */
- );
- }
- else
+ if (SUCCEEDED(hr))
{
- Assert(!pRc->fFlags.KmResource);
-
- pDdiAllocate->hResource = NULL;
- pDdiAllocate->NumAllocations = 1;
- pDdiAllocate->PrivateDriverDataSize = 0;
- pDdiAllocate->pPrivateDriverData = NULL;
- D3DDDI_ALLOCATIONINFO *pDdiAllocIBase = pDdiAllocate->pAllocationInfo;
-
- for (UINT i = 0; i < pResource->SurfCount; ++i)
+ if (bCreateKMResource)
{
- pDdiAllocate->pAllocationInfo = &pDdiAllocIBase[i];
+ Assert(pRc->fFlags.KmResource);
+
hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pDdiAllocate);
Assert(hr == S_OK);
- Assert(!pDdiAllocate->hKMResource);
- if (SUCCEEDED(hr))
- {
- Assert(pDdiAllocate->pAllocationInfo->hAllocation);
- }
- else
+ Assert(pDdiAllocate->hKMResource
+ || pResource->Flags.SharedResource /* for some reason shared resources
+ * are created with zero km resource handle on Win7+ */
+ );
+ }
+ else
+ {
+ Assert(!pRc->fFlags.KmResource);
+
+ pDdiAllocate->hResource = NULL;
+ pDdiAllocate->NumAllocations = 1;
+ pDdiAllocate->PrivateDriverDataSize = 0;
+ pDdiAllocate->pPrivateDriverData = NULL;
+ D3DDDI_ALLOCATIONINFO *pDdiAllocIBase = pDdiAllocate->pAllocationInfo;
+
+ for (UINT i = 0; i < pResource->SurfCount; ++i)
{
- for (UINT j = 0; i < j; ++j)
+ pDdiAllocate->pAllocationInfo = &pDdiAllocIBase[i];
+ hr = pDevice->RtCallbacks.pfnAllocateCb(pDevice->hDevice, pDdiAllocate);
+ Assert(hr == S_OK);
+ Assert(!pDdiAllocate->hKMResource);
+ if (SUCCEEDED(hr))
{
- D3DDDI_ALLOCATIONINFO * pCur = &pDdiAllocIBase[i];
- D3DDDICB_DEALLOCATE Dealloc;
- Dealloc.hResource = 0;
- Dealloc.NumAllocations = 1;
- Dealloc.HandleList = &pCur->hAllocation;
- HRESULT tmpHr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
- Assert(tmpHr == S_OK);
+ Assert(pDdiAllocate->pAllocationInfo->hAllocation);
+ }
+ else
+ {
+ for (UINT j = 0; i < j; ++j)
+ {
+ D3DDDI_ALLOCATIONINFO * pCur = &pDdiAllocIBase[i];
+ D3DDDICB_DEALLOCATE Dealloc;
+ Dealloc.hResource = 0;
+ Dealloc.NumAllocations = 1;
+ Dealloc.HandleList = &pCur->hAllocation;
+ HRESULT tmpHr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &Dealloc);
+ Assert(tmpHr == S_OK);
+ }
+ break;
}
- break;
}
- }
-
- pDdiAllocate->pAllocationInfo = pDdiAllocIBase;
- }
- if (SUCCEEDED(hr))
- {
- pRc->hKMResource = pDdiAllocate->hKMResource;
+ pDdiAllocate->pAllocationInfo = pDdiAllocIBase;
+ }
- for (UINT i = 0; i < pResource->SurfCount; ++i)
+ if (SUCCEEDED(hr))
{
- PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
- D3DDDI_ALLOCATIONINFO *pDdiAllocI = &pDdiAllocate->pAllocationInfo[i];
- PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocI->pPrivateDriverData;
- CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
- pAllocation->hAllocation = pDdiAllocI->hAllocation;
- pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
- pAllocation->pvMem = (void*)pSurf->pSysMem;
- pAllocation->SurfDesc = pAllocInfo->SurfDesc;
-
- if (pResource->Flags.SharedResource)
+ pRc->hKMResource = pDdiAllocate->hKMResource;
+
+ for (UINT i = 0; i < pResource->SurfCount; ++i)
{
+ PVBOXWDDMDISP_ALLOCATION pAllocation = &pRc->aAllocations[i];
+ D3DDDI_ALLOCATIONINFO *pDdiAllocI = &pDdiAllocate->pAllocationInfo[i];
+ PVBOXWDDM_ALLOCINFO pAllocInfo = (PVBOXWDDM_ALLOCINFO)pDdiAllocI->pPrivateDriverData;
+ CONST D3DDDI_SURFACEINFO* pSurf = &pResource->pSurfList[i];
+ pAllocation->hAllocation = pDdiAllocI->hAllocation;
+ pAllocation->enmType = VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC;
+ pAllocation->pvMem = (void*)pSurf->pSysMem;
+ pAllocation->SurfDesc = pAllocInfo->SurfDesc;
+
+ if (pResource->Flags.SharedResource)
+ {
#ifdef VBOXWDDMDISP_DEBUG_PRINT_SHARED_CREATE
- Assert(VBOXWDDMDISP_IS_TEXTURE(pResource->Flags));
- vboxVDbgPrint(("\n\n********\n(0x%x:0n%d)Shared CREATED pAlloc(0x%p), hRc(0x%p), hAl(0x%p), "
- "Handle(0x%x), (0n%d) \n***********\n\n",
- GetCurrentProcessId(), GetCurrentProcessId(),
- pAllocation, pRc->hKMResource, pAllocation->hAllocation,
- pAllocation->hSharedHandle, pAllocation->hSharedHandle
- ));
+ Assert(VBOXWDDMDISP_IS_TEXTURE(pResource->Flags));
+ vboxVDbgPrint(("\n\n********\n(0x%x:0n%d)Shared CREATED pAlloc(0x%p), hRc(0x%p), hAl(0x%p), "
+ "Handle(0x%x), (0n%d) \n***********\n\n",
+ GetCurrentProcessId(), GetCurrentProcessId(),
+ pAllocation, pRc->hKMResource, pAllocation->hAllocation,
+ pAllocation->hSharedHandle, pAllocation->hSharedHandle
+ ));
#endif
+ }
}
- }
- VBOXVDBG_CREATE_CHECK_SWAPCHAIN();
+ VBOXVDBG_CREATE_CHECK_SWAPCHAIN();
+ }
}
vboxWddmRequestAllocFree(pDdiAllocate);
@@ -4349,7 +4580,7 @@ static HRESULT APIENTRY vboxWddmDDevDestroyResource(HANDLE hDevice, HANDLE hReso
vboxWddmSwapchainDestroy(pDevice, pSwapchain);
}
- vboxWddmDalCheckRemove(pDevice, pAlloc);
+ vboxWddmDalCheckNotifyRemove(pDevice, pAlloc);
}
}
@@ -4426,7 +4657,29 @@ static HRESULT APIENTRY vboxWddmDDevPresent(HANDLE hDevice, CONST D3DDDIARG_PRES
Assert(pDevice);
VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
HRESULT hr = S_OK;
- if (VBOXDISPMODE_IS_3D(pDevice->pAdapter))
+ PVBOXWDDMDISP_ADAPTER pAdapter = pDevice->pAdapter;
+ PVBOXWDDMDISP_RESOURCE pSrcRc = NULL, pDstRc = NULL;
+ PVBOXWDDMDISP_ALLOCATION pSrcAlloc = NULL, pDstAlloc = NULL;
+
+ Assert(vboxWddmDalIsEmpty(pDevice));
+
+ if (pData->hSrcResource)
+ {
+ pSrcRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
+ Assert(pSrcRc->cAllocations > pData->SrcSubResourceIndex);
+ pSrcAlloc = &pSrcRc->aAllocations[pData->SrcSubResourceIndex];
+ Assert(pSrcAlloc->hAllocation);
+ }
+
+ if (pData->hDstResource)
+ {
+ pDstRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
+ Assert(pDstRc->cAllocations > pData->DstSubResourceIndex);
+ pDstAlloc = &pDstRc->aAllocations[pData->DstSubResourceIndex];
+ Assert(pDstAlloc->hAllocation);
+ }
+
+ if (VBOXDISPMODE_IS_3D(pAdapter))
{
#ifdef VBOXWDDM_TEST_UHGSMI
{
@@ -4437,55 +4690,65 @@ static HRESULT APIENTRY vboxWddmDDevPresent(HANDLE hDevice, CONST D3DDDIARG_PRES
uint32_t cCPS = (((uint64_t)cCals) * 1000ULL)/TimeMs;
}
#endif
- PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
- Assert(pRc);
- Assert(pRc->cAllocations > pData->SrcSubResourceIndex);
- PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
- hr = vboxWddmSwapchainPresent(pDevice, pAlloc);
- Assert(hr == S_OK);
- }
+ if (pAdapter->u32VBox3DCaps & CR_VBOX_CAP_TEX_PRESENT)
+ {
+ IDirect3DSurface9 *pSrcSurfIf = NULL;
+ hr = VBoxD3DIfSurfGet(pSrcRc, pData->DstSubResourceIndex, &pSrcSurfIf);
+ if (SUCCEEDED(hr))
+ {
+ pAdapter->D3D.D3D.pfnVBoxWineExD3DSurf9SyncToHost(pSrcSurfIf);
+ pSrcSurfIf->Release();
+ }
+ else
+ {
+ WARN(("VBoxD3DIfSurfGet failed, hr = 0x%x", hr));
+ return hr;
+ }
- {
- D3DDDICB_PRESENT DdiPresent = {0};
- if (pData->hSrcResource)
+ pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9FlushToHost((IDirect3DDevice9Ex*)pDevice->pDevice9If);
+ }
+ else
{
+ pAdapter->D3D.D3D.pfnVBoxWineExD3DDev9FlushToHost((IDirect3DDevice9Ex*)pDevice->pDevice9If);
PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hSrcResource;
+ Assert(pRc);
Assert(pRc->cAllocations > pData->SrcSubResourceIndex);
PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SrcSubResourceIndex];
- Assert(pAlloc->hAllocation);
- DdiPresent.hSrcAllocation = pAlloc->hAllocation;
- }
- if (pData->hDstResource)
- {
- PVBOXWDDMDISP_RESOURCE pRc = (PVBOXWDDMDISP_RESOURCE)pData->hDstResource;
- Assert(pRc->cAllocations > pData->DstSubResourceIndex);
- PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->DstSubResourceIndex];
- Assert(pAlloc->hAllocation);
- DdiPresent.hDstAllocation = pAlloc->hAllocation;
+ hr = vboxWddmSwapchainPresent(pDevice, pAlloc);
+ Assert(hr == S_OK);
}
- DdiPresent.hContext = pDevice->DefaultContext.ContextInfo.hContext;
+ }
+
+ D3DDDICB_PRESENT DdiPresent = {0};
+ if (pSrcAlloc)
+ DdiPresent.hSrcAllocation = pSrcAlloc->hAllocation;
+
+ if (pDstAlloc)
+ DdiPresent.hDstAllocation = pDstAlloc->hAllocation;
+
+ DdiPresent.hContext = pDevice->DefaultContext.ContextInfo.hContext;
#if 0 //def VBOX_WDDMDISP_WITH_PROFILE
- VBoxDispProfileScopeLogger<VBoxDispProfileEntry> profilePresentCbLogger(pDevice->ProfileDdiPresentCb.alloc("pfnPresentCb"));
+ VBoxDispProfileScopeLogger<VBoxDispProfileEntry> profilePresentCbLogger(pDevice->ProfileDdiPresentCb.alloc("pfnPresentCb"));
#endif
+
#ifdef VBOXWDDMDISP_DEBUG_TIMER
- HANDLE hTimer = NULL;
- vboxVDbgTimerStart(pDevice->hTimerQueue, &hTimer, 1000);
+ HANDLE hTimer = NULL;
+ vboxVDbgTimerStart(pDevice->hTimerQueue, &hTimer, 1000);
#endif
- hr = pDevice->RtCallbacks.pfnPresentCb(pDevice->hDevice, &DdiPresent);
+ hr = pDevice->RtCallbacks.pfnPresentCb(pDevice->hDevice, &DdiPresent);
#ifdef VBOXWDDMDISP_DEBUG_TIMER
- vboxVDbgTimerStop(pDevice->hTimerQueue, hTimer);
+ vboxVDbgTimerStop(pDevice->hTimerQueue, hTimer);
#endif
#if 0 //def VBOX_WDDMDISP_WITH_PROFILE
- profilePresentCbLogger.logAndDisable();
- if (pDevice->ProfileDdiPresentCb.getNumEntries() == 64)
- {
- pDevice->ProfileDdiPresentCb.dump(pDevice);
- pDevice->ProfileDdiPresentCb.reset();
- }
-#endif
- Assert(hr == S_OK);
+ profilePresentCbLogger.logAndDisable();
+ if (pDevice->ProfileDdiPresentCb.getNumEntries() == 64)
+ {
+ pDevice->ProfileDdiPresentCb.dump(pDevice);
+ pDevice->ProfileDdiPresentCb.reset();
}
+#endif
+ Assert(hr == S_OK);
vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p), hr(0x%x)\n", hDevice, hr));
@@ -4749,13 +5012,23 @@ static HRESULT APIENTRY vboxWddmDDevSetStreamSource(HANDLE hDevice, CONST D3DDDI
static HRESULT APIENTRY vboxWddmDDevSetStreamSourceFreq(HANDLE hDevice, CONST D3DDDIARG_SETSTREAMSOURCEFREQ* pData)
{
VBOXDISP_DDI_PROLOGUE_DEV(hDevice);
- vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
+ vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
PVBOXWDDMDISP_DEVICE pDevice = (PVBOXWDDMDISP_DEVICE)hDevice;
Assert(pDevice);
VBOXDISPCRHGSMI_SCOPE_SET_DEV(pDevice);
+ IDirect3DDevice9 * pDevice9If = VBOXDISP_D3DEV(pDevice);
+ HRESULT hr = pDevice9If->SetStreamSourceFreq(pData->Stream, pData->Divider);
+ if (SUCCEEDED(hr))
+ hr = S_OK;
+ else
+ WARN(("SetStreamSourceFreq failed hr 0x%x", hr));
+
+#ifdef DEBUG_misha
+ /* test it more */
Assert(0);
- vboxVDbgPrintF(("==> "__FUNCTION__", hDevice(0x%p)\n", hDevice));
- return E_FAIL;
+#endif
+ vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
+ return hr;
}
static HRESULT APIENTRY vboxWddmDDevSetConvolutionKernelMono(HANDLE hDevice, CONST D3DDDIARG_SETCONVOLUTIONKERNELMONO* pData)
{
@@ -5045,7 +5318,10 @@ static HRESULT APIENTRY vboxWddmDDevSetDepthStencil(HANDLE hDevice, CONST D3DDDI
{
hr = pDevice9If->SetDepthStencilSurface(pD3D9Surf);
if (SUCCEEDED(hr))
+ {
+ pDevice->pDepthStencilRc = pRc;
hr = S_OK;
+ }
else
WARN(("VBoxD3DIfSurfGet failed, hr (0x%x)",hr));
@@ -5353,7 +5629,11 @@ static HRESULT APIENTRY vboxWddmDDevDestroyDevice(IN HANDLE hDevice)
HRESULT hr = vboxDispCmCtxDestroy(pDevice, &pDevice->DefaultContext);
Assert(hr == S_OK);
if (hr == S_OK)
+ {
+ if (pDevice->hHgsmiTransportModule)
+ FreeLibrary(pDevice->hHgsmiTransportModule);
RTMemFree(pDevice);
+ }
vboxVDbgPrintF(("<== "__FUNCTION__", hDevice(0x%p)\n", hDevice));
return hr;
}
@@ -5638,7 +5918,8 @@ static HRESULT APIENTRY vboxWddmDDevOpenResource(HANDLE hDevice, D3DDDIARG_OPENR
pRc->RcDesc.enmMultisampleType = D3DDDIMULTISAMPLE_NONE;
pRc->RcDesc.MultisampleQuality = 0;
pRc->RcDesc.MipLevels = 0;
- pRc->RcDesc.Fvf;
+ /*pRc->RcDesc.Fvf;*/
+ pRc->RcDesc.fFlags.SharedResource = 1;
if (pData->NumAllocations != 1)
{
@@ -5903,7 +6184,7 @@ static HRESULT APIENTRY vboxWddmDispCreateDevice (IN HANDLE hAdapter, IN D3DDDIA
Assert(hr == S_OK);
if (hr == S_OK)
{
- #ifdef VBOXDISP_EARLYCREATEDEVICE
+#ifdef VBOXDISP_EARLYCREATEDEVICE
PVBOXWDDMDISP_RESOURCE pRc = vboxResourceAlloc(2);
Assert(pRc);
if (pRc)
@@ -5939,13 +6220,13 @@ static HRESULT APIENTRY vboxWddmDispCreateDevice (IN HANDLE hAdapter, IN D3DDDIA
{
hr = E_OUTOFMEMORY;
}
- #else
+#else
//# define VBOXDISP_TEST_SWAPCHAIN
# ifdef VBOXDISP_TEST_SWAPCHAIN
VBOXDISP_D3DEV(pDevice);
# endif
break;
- #endif
+#endif
HRESULT tmpHr = vboxDispCmCtxDestroy(pDevice, &pDevice->DefaultContext);
Assert(tmpHr == S_OK);
@@ -5969,6 +6250,22 @@ static HRESULT APIENTRY vboxWddmDispCreateDevice (IN HANDLE hAdapter, IN D3DDDIA
hr = E_OUTOFMEMORY;
}
+ if (SUCCEEDED(hr))
+ {
+ if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+ (LPCWSTR)pDevice->RtCallbacks.pfnAllocateCb,
+ &pDevice->hHgsmiTransportModule))
+ {
+ Assert(pDevice->hHgsmiTransportModule);
+ }
+ else
+ {
+ DWORD winEr = GetLastError();
+ WARN(("GetModuleHandleEx failed winEr %d, ignoring", winEr));
+ pDevice->hHgsmiTransportModule = 0;
+ }
+ }
+
vboxVDbgPrint(("<== "__FUNCTION__", hAdapter(0x%p)\n", hAdapter));
return hr;
@@ -6102,8 +6399,9 @@ HRESULT APIENTRY OpenAdapter(__inout D3DDDIARG_OPENADAPTER* pOpenData)
pAdapter->uRtVersion= pOpenData->Version;
pAdapter->RtCallbacks = *pOpenData->pAdapterCallbacks;
- pAdapter->cHeads = Query.cInfos;
+ pAdapter->u32VBox3DCaps = Query.u32VBox3DCaps;
+ pAdapter->cHeads = Query.cInfos;
pOpenData->hAdapter = pAdapter;
pOpenData->pAdapterFuncs->pfnGetCaps = vboxWddmDispGetCaps;
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.def b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.def
index d4884561..2c69c887 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.def
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.def
@@ -3,7 +3,7 @@
;
; VBoxDispD3D
;
-; Copyright (C) 2011 Oracle Corporation
+; Copyright (C) 2011-2012 Oracle Corporation
;
; This file is part of VirtualBox Open Source Edition (OSE), as
; available from http://www.virtualbox.org. This file is free software;
@@ -16,4 +16,3 @@
EXPORTS
OpenAdapter
- VBoxDispMpGetCallbacks
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.h
index 8b8a4bfe..4b614e7e 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -20,7 +20,7 @@
#define ___VBoxDispD3D_h___
#include "VBoxDispD3DIf.h"
-#include "common/wddm/VBoxMPIf.h"
+#include "../../common/wddm/VBoxMPIf.h"
#ifdef VBOX_WITH_CRHGSMI
#include "VBoxUhgsmiDisp.h"
#endif
@@ -78,6 +78,7 @@ typedef struct VBOXWDDMDISP_ADAPTER
D3DDDI_ADAPTERCALLBACKS RtCallbacks;
VBOXWDDMDISP_D3D D3D;
VBOXWDDMDISP_FORMATS Formats;
+ uint32_t u32VBox3DCaps;
#ifdef VBOX_WDDMDISP_WITH_PROFILE
VBoxDispProfileFpsCounter ProfileDdiFps;
VBoxDispProfileSet ProfileDdiFunc;
@@ -210,6 +211,10 @@ typedef struct VBOXWDDMDISP_DEVICE
UINT cSamplerTextures;
struct VBOXWDDMDISP_RESOURCE *aSamplerTextures[VBOXWDDMDISP_TOTAL_SAMPLERS];
+ struct VBOXWDDMDISP_RESOURCE *pDepthStencilRc;
+
+ HMODULE hHgsmiTransportModule;
+
#ifdef VBOX_WDDMDISP_WITH_PROFILE
VBoxDispProfileFpsCounter ProfileDdiFps;
VBoxDispProfileSet ProfileDdiFunc;
@@ -261,13 +266,14 @@ typedef struct VBOXWDDMDISP_ALLOCATION
UINT iAlloc;
struct VBOXWDDMDISP_RESOURCE *pRc;
void* pvMem;
- UINT D3DWidth;
/* object type is defined by enmD3DIfType enum */
IUnknown *pD3DIf;
VBOXDISP_D3DIFTYPE enmD3DIfType;
/* list entry used to add allocation to the dirty alloc list */
RTLISTNODE DirtyAllocListEntry;
+ BOOLEAN fEverWritten;
BOOLEAN fDirtyWrite;
+ BOOLEAN fAllocLocked;
HANDLE hSharedHandle;
VBOXWDDMDISP_LOCKINFO LockInfo;
VBOXWDDM_DIRTYREGION DirtyRegion; /* <- dirty region to notify host about */
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D64.def b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D64.def
deleted file mode 100644
index ad901dc8..00000000
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D64.def
+++ /dev/null
@@ -1,21 +0,0 @@
-; $Id: VBoxDispD3D64.def $
-; @file
-;
-; VBoxDispD3D 64bit
-;
-; Copyright (C) 2011 Oracle Corporation
-;
-; This file is part of VirtualBox Open Source Edition (OSE), as
-; available from http://www.virtualbox.org. This file is free software;
-; you can redistribute it and/or modify it under the terms of the GNU
-; General Public License (GPL) as published by the Free Software
-; Foundation, in version 2 as it comes in the "COPYING" file of the
-; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
-; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
-;
-
-LIBRARY VBoxDispD3D64
-
-EXPORTS
- OpenAdapter
- VBoxDispMpGetCallbacks
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DBase.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DBase.h
new file mode 100644
index 00000000..8599f75b
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DBase.h
@@ -0,0 +1,46 @@
+/* $Id: VBoxDispD3DBase.h $ */
+/** @file
+ * VBoxVideo Display D3D Base Include
+ */
+
+/*
+ * Copyright (C) 2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+#ifndef __VBoxDispD3DBase_h_
+#define __VBoxDispD3DBase_h_
+
+# define _InterlockedExchange _InterlockedExchange_StupidDDKVsCompilerCrap
+# define _InterlockedExchangeAdd _InterlockedExchangeAdd_StupidDDKVsCompilerCrap
+# define _InterlockedCompareExchange _InterlockedCompareExchange_StupidDDKVsCompilerCrap
+# define _InterlockedAddLargeStatistic _InterlockedAddLargeStatistic_StupidDDKVsCompilerCrap
+# define _interlockedbittestandset _interlockedbittestandset_StupidDDKVsCompilerCrap
+# define _interlockedbittestandreset _interlockedbittestandreset_StupidDDKVsCompilerCrap
+# define _interlockedbittestandset64 _interlockedbittestandset64_StupidDDKVsCompilerCrap
+# define _interlockedbittestandreset64 _interlockedbittestandreset64_StupidDDKVsCompilerCrap
+# pragma warning(disable : 4163)
+#include <windows.h>
+# pragma warning(default : 4163)
+# undef _InterlockedExchange
+# undef _InterlockedExchangeAdd
+# undef _InterlockedCompareExchange
+# undef _InterlockedAddLargeStatistic
+# undef _interlockedbittestandset
+# undef _interlockedbittestandreset
+# undef _interlockedbittestandset64
+# undef _interlockedbittestandreset64
+
+#include <d3d9types.h>
+//#include <d3dtypes.h>
+#include <D3dumddi.h>
+#include <d3dhal.h>
+
+
+#endif /* #ifndef __VBoxDispD3DBase_h_ */
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DCmn.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DCmn.h
index 38609367..a71a108a 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DCmn.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DCmn.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -18,30 +18,7 @@
#ifndef ___VBoxDispD3DCmn_h___
#define ___VBoxDispD3DCmn_h___
-# define _InterlockedExchange _InterlockedExchange_StupidDDKVsCompilerCrap
-# define _InterlockedExchangeAdd _InterlockedExchangeAdd_StupidDDKVsCompilerCrap
-# define _InterlockedCompareExchange _InterlockedCompareExchange_StupidDDKVsCompilerCrap
-# define _InterlockedAddLargeStatistic _InterlockedAddLargeStatistic_StupidDDKVsCompilerCrap
-# define _interlockedbittestandset _interlockedbittestandset_StupidDDKVsCompilerCrap
-# define _interlockedbittestandreset _interlockedbittestandreset_StupidDDKVsCompilerCrap
-# define _interlockedbittestandset64 _interlockedbittestandset64_StupidDDKVsCompilerCrap
-# define _interlockedbittestandreset64 _interlockedbittestandreset64_StupidDDKVsCompilerCrap
-# pragma warning(disable : 4163)
-#include <windows.h>
-# pragma warning(default : 4163)
-# undef _InterlockedExchange
-# undef _InterlockedExchangeAdd
-# undef _InterlockedCompareExchange
-# undef _InterlockedAddLargeStatistic
-# undef _interlockedbittestandset
-# undef _interlockedbittestandreset
-# undef _interlockedbittestandset64
-# undef _interlockedbittestandreset64
-
-#include <d3d9types.h>
-//#include <d3dtypes.h>
-#include <D3dumddi.h>
-#include <d3dhal.h>
+#include "VBoxDispD3DBase.h"
#include <iprt/initterm.h>
#include <iprt/log.h>
@@ -53,7 +30,7 @@
#include "VBoxDispDbg.h"
#include "VBoxDispD3DIf.h"
-#include "common/wddm/VBoxMPIf.h"
+#include "../../common/wddm/VBoxMPIf.h"
#include "VBoxDispCm.h"
#include "VBoxDispMpInternal.h"
#include "VBoxDispKmt.h"
@@ -66,6 +43,7 @@
#ifndef IN_VBOXCRHGSMI
#include "VBoxD3DIf.h"
#endif
+#include <cr_protocol.h>
# ifdef VBOXWDDMDISP
# define VBOXWDDMDISP_DECL(_type) DECLEXPORT(_type)
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.cpp
index 8ad6e5cb..a50780ca 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -27,18 +27,38 @@ void VBoxDispD3DClose(VBOXDISPD3D *pD3D)
pD3D->hD3DLib = NULL;
}
+/**
+ * Loads a system DLL.
+ *
+ * @returns Module handle or NULL
+ * @param pszName The DLL name.
+ */
+static HMODULE loadSystemDll(const char *pszName)
+{
+ char szPath[MAX_PATH];
+ UINT cchPath = GetSystemDirectoryA(szPath, sizeof(szPath));
+ size_t cbName = strlen(pszName) + 1;
+ if (cchPath + 1 + cbName > sizeof(szPath))
+ {
+ SetLastError(ERROR_FILENAME_EXCED_RANGE);
+ return NULL;
+ }
+ szPath[cchPath] = '\\';
+ memcpy(&szPath[cchPath + 1], pszName, cbName);
+ return LoadLibraryA(szPath);
+}
HRESULT VBoxDispD3DOpen(VBOXDISPD3D *pD3D)
{
#ifdef VBOX_WDDM_WOW64
- pD3D->hD3DLib = LoadLibraryW(L"VBoxD3D9wddm-x86.dll");
+ pD3D->hD3DLib = loadSystemDll("VBoxD3D9wddm-x86.dll");
#else
- pD3D->hD3DLib = LoadLibraryW(L"VBoxD3D9wddm.dll");
+ pD3D->hD3DLib = loadSystemDll("VBoxD3D9wddm.dll");
#endif
if (!pD3D->hD3DLib)
{
DWORD winErr = GetLastError();
- WARN((__FUNCTION__": LoadLibraryW failed, winErr = (%d)", winErr));
+ WARN((__FUNCTION__": LoadLibrary failed, winErr = (%d)", winErr));
return E_FAIL;
}
@@ -79,6 +99,20 @@ HRESULT VBoxDispD3DOpen(VBOXDISPD3D *pD3D)
break;
}
+ pD3D->pfnVBoxWineExD3DDev9FlushToHost = (PFNVBOXWINEEXD3DDEV9_FLUSHTOHOST)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9FlushToHost");
+ if (!pD3D->pfnVBoxWineExD3DDev9FlushToHost)
+ {
+ WARN(("no VBoxWineExD3DDev9FlushToHost"));
+ break;
+ }
+
+ pD3D->pfnVBoxWineExD3DDev9Finish = (PFNVBOXWINEEXD3DDEV9_FINISH)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9Finish");
+ if (!pD3D->pfnVBoxWineExD3DDev9Finish)
+ {
+ WARN(("no VBoxWineExD3DDev9Finish"));
+ break;
+ }
+
pD3D->pfnVBoxWineExD3DDev9VolBlt = (PFNVBOXWINEEXD3DDEV9_VOLBLT)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9VolBlt");
if (!pD3D->pfnVBoxWineExD3DDev9VolBlt)
{
@@ -93,31 +127,45 @@ HRESULT VBoxDispD3DOpen(VBOXDISPD3D *pD3D)
break;
}
- pD3D->pfnVBoxWineExD3DDev9Update = (PFNVBOXWINEEXD3DDEV9_UPDATE)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9Update");
- if (!pD3D->pfnVBoxWineExD3DDev9Update)
+ pD3D->pfnVBoxWineExD3DDev9Term = (PFNVBOXWINEEXD3DDEV9_TERM)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9Term");
+ if (!pD3D->pfnVBoxWineExD3DDev9Term)
{
- WARN(("no VBoxWineExD3DDev9Update"));
+ WARN(("no VBoxWineExD3DDev9Term"));
break;
}
- pD3D->pfnVBoxWineExD3DDev9Term = (PFNVBOXWINEEXD3DDEV9_TERM)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9Term");
- if (!pD3D->pfnVBoxWineExD3DDev9Term)
+ pD3D->pfnVBoxWineExD3DSwapchain9Present = (PFNVBOXWINEEXD3DSWAPCHAIN9_PRESENT)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DSwapchain9Present");
+ if (!pD3D->pfnVBoxWineExD3DSwapchain9Present)
{
- WARN(("no VBoxWineExD3DDev9Term"));
+ WARN(("no VBoxWineExD3DSwapchain9Present"));
break;
}
- pD3D->pfnVBoxWineExD3DRc9SetShRcState = (PFNVBOXWINEEXD3DRC9_SETSHRCSTATE)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DRc9SetShRcState");
- if (!pD3D->pfnVBoxWineExD3DRc9SetShRcState)
+ pD3D->pfnVBoxWineExD3DSurf9GetHostId = (PFNVBOXWINEEXD3DSURF9_GETHOSTID)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DSurf9GetHostId");
+ if (!pD3D->pfnVBoxWineExD3DSurf9GetHostId)
{
- WARN(("no VBoxWineExD3DRc9SetShRcState"));
+ WARN(("no VBoxWineExD3DSurf9GetHostId"));
break;
}
- pD3D->pfnVBoxWineExD3DSwapchain9Present = (PFNVBOXWINEEXD3DSWAPCHAIN9_PRESENT)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DSwapchain9Present");
- if (!pD3D->pfnVBoxWineExD3DSwapchain9Present)
+ pD3D->pfnVBoxWineExD3DSurf9SyncToHost = (PFNVBOXWINEEXD3DSURF9_SYNCTOHOST)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DSurf9SyncToHost");
+ if (!pD3D->pfnVBoxWineExD3DSurf9SyncToHost)
{
- WARN(("no VBoxWineExD3DSwapchain9Present"));
+ WARN(("no VBoxWineExD3DSurf9SyncToHost"));
+ break;
+ }
+
+ pD3D->pfnVBoxWineExD3DSwapchain9GetHostWinID = (PFNVBOXWINEEXD3DSWAPCHAIN9_GETHOSTWINID)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DSwapchain9GetHostWinID");
+ if (!pD3D->pfnVBoxWineExD3DSwapchain9GetHostWinID)
+ {
+ WARN(("no VBoxWineExD3DSwapchain9GetHostWinID"));
+ break;
+ }
+
+ pD3D->pfnVBoxWineExD3DDev9GetHostId = (PFNVBOXWINEEXD3DDEV9_GETHOSTID)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9GetHostId");
+ if (!pD3D->pfnVBoxWineExD3DDev9GetHostId)
+ {
+ WARN(("no VBoxWineExD3DDev9GetHostId"));
break;
}
@@ -943,6 +991,56 @@ static HRESULT vboxWddmGetD3D9Caps(PVBOXWDDMDISP_D3D pD3D, D3DCAPS9 *pCaps)
return hr;
}
+ /* needed for Windows Media Player to work properly */
+ pCaps->Caps |= D3DCAPS_READ_SCANLINE;
+ pCaps->Caps2 |= 0x00080000 /*D3DCAPS2_CANRENDERWINDOWED*/;
+ pCaps->Caps2 |= D3DCAPS2_CANSHARERESOURCE;
+ pCaps->DevCaps |= D3DDEVCAPS_FLOATTLVERTEX /* <- must be set according to the docs */
+ /*| D3DDEVCAPS_HWVERTEXBUFFER | D3DDEVCAPS_HWINDEXBUFFER | D3DDEVCAPS_SUBVOLUMELOCK */;
+ pCaps->PrimitiveMiscCaps |= D3DPMISCCAPS_INDEPENDENTWRITEMASKS
+ | D3DPMISCCAPS_FOGINFVF
+ | D3DPMISCCAPS_SEPARATEALPHABLEND | D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS;
+ pCaps->RasterCaps |= D3DPRASTERCAPS_SUBPIXEL | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_COLORPERSPECTIVE /* keep */;
+ pCaps->TextureCaps |= D3DPTEXTURECAPS_TRANSPARENCY | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE;
+ pCaps->TextureAddressCaps |= D3DPTADDRESSCAPS_MIRRORONCE;
+ pCaps->VolumeTextureAddressCaps |= D3DPTADDRESSCAPS_MIRRORONCE;
+ pCaps->StencilCaps |= D3DSTENCILCAPS_TWOSIDED;
+ pCaps->DeclTypes |= D3DDTCAPS_FLOAT16_2 | D3DDTCAPS_FLOAT16_4;
+ pCaps->VertexTextureFilterCaps |= D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MAGFPOINT;
+ pCaps->GuardBandLeft = -8192.;
+ pCaps->GuardBandTop = -8192.;
+ pCaps->GuardBandRight = 8192.;
+ pCaps->GuardBandBottom = 8192.;
+ pCaps->VS20Caps.DynamicFlowControlDepth = 24;
+ pCaps->VS20Caps.NumTemps = D3DVS20_MAX_NUMTEMPS;
+ pCaps->PS20Caps.DynamicFlowControlDepth = 24;
+ pCaps->PS20Caps.NumTemps = D3DVS20_MAX_NUMTEMPS;
+
+ /* workaround for wine not returning InstructionSlots correctly for shaders v3.0 */
+ if ((pCaps->VertexShaderVersion & 0xff00) == 0x0300)
+ {
+ pCaps->MaxVertexShader30InstructionSlots = RT_MIN(32768, pCaps->MaxVertexShader30InstructionSlots);
+ pCaps->MaxPixelShader30InstructionSlots = RT_MIN(32768, pCaps->MaxPixelShader30InstructionSlots);
+ }
+#if defined(DEBUG)
+ if ((pCaps->VertexShaderVersion & 0xff00) == 0x0300)
+ {
+ Assert(pCaps->MaxVertexShader30InstructionSlots >= 512);
+ Assert(pCaps->MaxVertexShader30InstructionSlots <= 32768);
+ Assert(pCaps->MaxPixelShader30InstructionSlots >= 512);
+ Assert(pCaps->MaxPixelShader30InstructionSlots <= 32768);
+ }
+ else if ((pCaps->VertexShaderVersion & 0xff00) == 0x0200)
+ {
+ Assert(pCaps->MaxVertexShader30InstructionSlots == 0);
+ Assert(pCaps->MaxPixelShader30InstructionSlots == 0);
+ }
+ else
+ {
+ WARN(("incorect shader caps!"));
+ }
+#endif
+
vboxDispDumpD3DCAPS9(pCaps);
return S_OK;
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.h
index 9d534050..c112b26c 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3DIf.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -43,7 +43,11 @@
# undef _interlockedbittestandset64
# undef _interlockedbittestandreset64
+#ifdef VBOX_WITH_NEW_WINE
+#include "../../../Wine_new/vbox/VBoxWineEx.h"
+#else
#include "../../../Wine/vbox/VBoxWineEx.h"
+#endif
/* D3D functionality the VBOXDISPD3D provides */
typedef HRESULT WINAPI FNVBOXDISPD3DCREATE9EX(UINT SDKVersion, IDirect3D9Ex **ppD3D);
@@ -66,14 +70,22 @@ typedef struct VBOXDISPD3D
PFNVBOXWINEEXD3DDEV9_VOLTEXBLT pfnVBoxWineExD3DDev9VolTexBlt;
- PFNVBOXWINEEXD3DDEV9_UPDATE pfnVBoxWineExD3DDev9Update;
-
PFNVBOXWINEEXD3DDEV9_TERM pfnVBoxWineExD3DDev9Term;
- PFNVBOXWINEEXD3DRC9_SETSHRCSTATE pfnVBoxWineExD3DRc9SetShRcState;
-
PFNVBOXWINEEXD3DSWAPCHAIN9_PRESENT pfnVBoxWineExD3DSwapchain9Present;
+ PFNVBOXWINEEXD3DDEV9_FLUSHTOHOST pfnVBoxWineExD3DDev9FlushToHost;
+
+ PFNVBOXWINEEXD3DDEV9_FINISH pfnVBoxWineExD3DDev9Finish;
+
+ PFNVBOXWINEEXD3DSURF9_GETHOSTID pfnVBoxWineExD3DSurf9GetHostId;
+
+ PFNVBOXWINEEXD3DSURF9_SYNCTOHOST pfnVBoxWineExD3DSurf9SyncToHost;
+
+ PFNVBOXWINEEXD3DSWAPCHAIN9_GETHOSTWINID pfnVBoxWineExD3DSwapchain9GetHostWinID;
+
+ PFNVBOXWINEEXD3DDEV9_GETHOSTID pfnVBoxWineExD3DDev9GetHostId;
+
/* module handle */
HMODULE hD3DLib;
} VBOXDISPD3D;
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.cpp
index ad5fdf3f..da7af03c 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -84,14 +84,19 @@ static void vboxDispLogDbgFormatStringV(char * szBuffer, uint32_t cbBuffer, cons
LONG g_VBoxVDbgFIsDwm = -1;
DWORD g_VBoxVDbgPid = 0;
-#endif
-
-#ifdef VBOXWDDMDISP_DEBUG
DWORD g_VBoxVDbgFLogRel = 1;
+# if !defined(VBOXWDDMDISP_DEBUG)
+DWORD g_VBoxVDbgFLog = 0;
+# else
DWORD g_VBoxVDbgFLog = 1;
+# endif
DWORD g_VBoxVDbgFLogFlow = 0;
+#endif
+
+#ifdef VBOXWDDMDISP_DEBUG
+
# ifndef IN_VBOXCRHGSMI
#define VBOXWDDMDISP_DEBUG_DUMP_DEFAULT 0
DWORD g_VBoxVDbgFDumpSetTexture = VBOXWDDMDISP_DEBUG_DUMP_DEFAULT;
@@ -156,9 +161,9 @@ VOID vboxVDbgDoPrintLopLastCmd(const char* pszDesc)
typedef struct VBOXVDBG_DUMP_INFO
{
DWORD fFlags;
- PVBOXWDDMDISP_ALLOCATION pAlloc;
+ const VBOXWDDMDISP_ALLOCATION *pAlloc;
IDirect3DResource9 *pD3DRc;
- RECT *pRect;
+ const RECT *pRect;
} VBOXVDBG_DUMP_INFO, *PVBOXVDBG_DUMP_INFO;
typedef DECLCALLBACK(void) FNVBOXVDBG_CONTENTS_DUMPER(PVBOXVDBG_DUMP_INFO pInfo, BOOLEAN fBreak, void *pvDumper);
@@ -166,7 +171,7 @@ typedef FNVBOXVDBG_CONTENTS_DUMPER *PFNVBOXVDBG_CONTENTS_DUMPER;
static VOID vboxVDbgDoDumpSummary(const char * pPrefix, PVBOXVDBG_DUMP_INFO pInfo, const char * pSuffix)
{
- PVBOXWDDMDISP_ALLOCATION pAlloc = pInfo->pAlloc;
+ const VBOXWDDMDISP_ALLOCATION *pAlloc = pInfo->pAlloc;
IDirect3DResource9 *pD3DRc = pInfo->pD3DRc;
char rectBuf[24];
if (pInfo->pRect)
@@ -219,7 +224,7 @@ VOID vboxVDbgDoDumpPerform(const char * pPrefix, PVBOXVDBG_DUMP_INFO pInfo, cons
static DECLCALLBACK(void) vboxVDbgAllocRectContentsDumperCb(PVBOXVDBG_DUMP_INFO pInfo, BOOLEAN fBreak, void *pvDumper)
{
- PVBOXWDDMDISP_ALLOCATION pAlloc = pInfo->pAlloc;
+ const VBOXWDDMDISP_ALLOCATION *pAlloc = pInfo->pAlloc;
const RECT *pRect = pInfo->pRect;
Assert(pAlloc->hAllocation);
@@ -241,7 +246,7 @@ static DECLCALLBACK(void) vboxVDbgAllocRectContentsDumperCb(PVBOXVDBG_DUMP_INFO
if (hr == S_OK)
{
UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
- vboxVDbgDoPrintDumpCmd("Surf Info", LockData.pData, pAlloc->D3DWidth, pAlloc->SurfDesc.height, bpp, pAlloc->SurfDesc.pitch);
+ vboxVDbgDoPrintDumpCmd("Surf Info", LockData.pData, pAlloc->SurfDesc.d3dWidth, pAlloc->SurfDesc.height, bpp, pAlloc->SurfDesc.pitch);
if (pRect)
{
Assert(pRect->right > pRect->left);
@@ -274,7 +279,7 @@ VOID vboxVDbgDoDumpAllocRect(const char * pPrefix, PVBOXWDDMDISP_ALLOCATION pAll
static DECLCALLBACK(void) vboxVDbgRcRectContentsDumperCb(PVBOXVDBG_DUMP_INFO pInfo, BOOLEAN fBreak, void *pvDumper)
{
- PVBOXWDDMDISP_ALLOCATION pAlloc = pInfo->pAlloc;
+ const VBOXWDDMDISP_ALLOCATION *pAlloc = pInfo->pAlloc;
IDirect3DResource9 *pD3DRc = pInfo->pD3DRc;
const RECT *pRect = pInfo->pRect;
IDirect3DSurface9 *pSurf;
@@ -314,6 +319,8 @@ static DECLCALLBACK(void) vboxVDbgRcRectContentsDumperCb(PVBOXVDBG_DUMP_INFO pIn
Assert(hr == S_OK);
}
}
+
+ pSurf->Release();
}
VOID vboxVDbgDoDumpRcRect(const char * pPrefix, PVBOXWDDMDISP_ALLOCATION pAlloc,
@@ -417,8 +424,8 @@ VOID vboxVDbgDoDumpSamplers(const char * pPrefix, PVBOXWDDMDISP_DEVICE pDevice,
static DECLCALLBACK(void) vboxVDbgLockUnlockSurfTexContentsDumperCb(PVBOXVDBG_DUMP_INFO pInfo, BOOLEAN fBreak, void *pvDumper)
{
- PVBOXWDDMDISP_ALLOCATION pAlloc = pInfo->pAlloc;
- PRECT pRect = pInfo->pRect;
+ const VBOXWDDMDISP_ALLOCATION *pAlloc = pInfo->pAlloc;
+ const RECT *pRect = pInfo->pRect;
UINT bpp = vboxWddmCalcBitsPerPixel(pAlloc->SurfDesc.format);
uint32_t width, height, pitch;
void *pvData;
@@ -451,11 +458,12 @@ static DECLCALLBACK(void) vboxVDbgLockUnlockSurfTexContentsDumperCb(PVBOXVDBG_DU
}
}
-VOID vboxVDbgDoDumpLockUnlockSurfTex(const char * pPrefix, const PVBOXWDDMDISP_ALLOCATION pAlloc, const char * pSuffix, DWORD fFlags)
+VOID vboxVDbgDoDumpLockUnlockSurfTex(const char * pPrefix, const VBOXWDDMDISP_ALLOCATION *pAlloc, const char * pSuffix, DWORD fFlags)
{
Assert(!pAlloc->hSharedHandle);
- RECT Rect, *pRect;
+ RECT Rect;
+ const RECT *pRect;
Assert(!pAlloc->LockInfo.fFlags.RangeValid);
Assert(!pAlloc->LockInfo.fFlags.BoxValid);
if (pAlloc->LockInfo.fFlags.AreaValid)
@@ -481,16 +489,19 @@ VOID vboxVDbgDoDumpLockUnlockSurfTex(const char * pPrefix, const PVBOXWDDMDISP_A
VOID vboxVDbgDoDumpLockSurfTex(const char * pPrefix, const D3DDDIARG_LOCK* pData, const char * pSuffix, DWORD fFlags)
{
- const PVBOXWDDMDISP_RESOURCE pRc = (const PVBOXWDDMDISP_RESOURCE)pData->hResource;
- const PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
- pAlloc->LockInfo.pvData = pData->pSurfData;
+ const VBOXWDDMDISP_RESOURCE *pRc = (const VBOXWDDMDISP_RESOURCE*)pData->hResource;
+ const VBOXWDDMDISP_ALLOCATION *pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
+#ifdef VBOXWDDMDISP_DEBUG
+ VBOXWDDMDISP_ALLOCATION *pUnconstpAlloc = (VBOXWDDMDISP_ALLOCATION *)pAlloc;
+ pUnconstpAlloc->LockInfo.pvData = pData->pSurfData;
+#endif
vboxVDbgDoDumpLockUnlockSurfTex(pPrefix, pAlloc, pSuffix, fFlags);
}
VOID vboxVDbgDoDumpUnlockSurfTex(const char * pPrefix, const D3DDDIARG_UNLOCK* pData, const char * pSuffix, DWORD fFlags)
{
- const PVBOXWDDMDISP_RESOURCE pRc = (const PVBOXWDDMDISP_RESOURCE)pData->hResource;
- const PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
+ const VBOXWDDMDISP_RESOURCE *pRc = (const VBOXWDDMDISP_RESOURCE*)pData->hResource;
+ const VBOXWDDMDISP_ALLOCATION *pAlloc = &pRc->aAllocations[pData->SubResourceIndex];
vboxVDbgDoDumpLockUnlockSurfTex(pPrefix, pAlloc, pSuffix, fFlags);
}
@@ -528,8 +539,8 @@ BOOL vboxVDbgDoCheckLRects(D3DLOCKED_RECT *pDstLRect, const RECT *pDstRect, D3DL
return fMatch;
}
-BOOL vboxVDbgDoCheckRectsMatch(const PVBOXWDDMDISP_RESOURCE pDstRc, uint32_t iDstAlloc,
- const PVBOXWDDMDISP_RESOURCE pSrcRc, uint32_t iSrcAlloc,
+BOOL vboxVDbgDoCheckRectsMatch(const VBOXWDDMDISP_RESOURCE *pDstRc, uint32_t iDstAlloc,
+ const VBOXWDDMDISP_RESOURCE *pSrcRc, uint32_t iSrcAlloc,
const RECT *pDstRect,
const RECT *pSrcRect,
BOOL fBreakOnMismatch)
@@ -592,46 +603,46 @@ BOOL vboxVDbgDoCheckRectsMatch(const PVBOXWDDMDISP_RESOURCE pDstRc, uint32_t iDs
}
D3DLOCKED_RECT SrcLRect, DstLRect;
- HRESULT hr = VBoxD3DIfLockRect(pDstRc, iDstAlloc, &DstLRect, pDstRect, D3DLOCK_READONLY);
+ HRESULT hr = VBoxD3DIfLockRect((VBOXWDDMDISP_RESOURCE *)pDstRc, iDstAlloc, &DstLRect, pDstRect, D3DLOCK_READONLY);
if (FAILED(hr))
{
WARN(("VBoxD3DIfLockRect failed, hr(0x%x)", hr));
return FALSE;
}
- hr = VBoxD3DIfLockRect(pSrcRc, iSrcAlloc, &SrcLRect, pSrcRect, D3DLOCK_READONLY);
+ hr = VBoxD3DIfLockRect((VBOXWDDMDISP_RESOURCE *)pSrcRc, iSrcAlloc, &SrcLRect, pSrcRect, D3DLOCK_READONLY);
if (FAILED(hr))
{
WARN(("VBoxD3DIfLockRect failed, hr(0x%x)", hr));
- hr = VBoxD3DIfUnlockRect(pDstRc, iDstAlloc);
+ hr = VBoxD3DIfUnlockRect((VBOXWDDMDISP_RESOURCE *)pDstRc, iDstAlloc);
return FALSE;
}
fMatch = vboxVDbgDoCheckLRects(&DstLRect, pDstRect, &SrcLRect, pSrcRect, bpp, fBreakOnMismatch);
- hr = VBoxD3DIfUnlockRect(pDstRc, iDstAlloc);
+ hr = VBoxD3DIfUnlockRect((VBOXWDDMDISP_RESOURCE *)pDstRc, iDstAlloc);
Assert(hr == S_OK);
- hr = VBoxD3DIfUnlockRect(pSrcRc, iSrcAlloc);
+ hr = VBoxD3DIfUnlockRect((VBOXWDDMDISP_RESOURCE *)pSrcRc, iSrcAlloc);
Assert(hr == S_OK);
return fMatch;
}
-void vboxVDbgDoPrintAlloc(const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const char * pSuffix)
+void vboxVDbgDoPrintAlloc(const char * pPrefix, const VBOXWDDMDISP_RESOURCE *pRc, uint32_t iAlloc, const char * pSuffix)
{
Assert(pRc->cAllocations > iAlloc);
- const PVBOXWDDMDISP_ALLOCATION pAlloc = &pRc->aAllocations[iAlloc];
+ const VBOXWDDMDISP_ALLOCATION *pAlloc = &pRc->aAllocations[iAlloc];
BOOL bPrimary = pRc->RcDesc.fFlags.Primary;
BOOL bFrontBuf = FALSE;
if (bPrimary)
{
- PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc(pAlloc);
+ PVBOXWDDMDISP_SWAPCHAIN pSwapchain = vboxWddmSwapchainForAlloc((VBOXWDDMDISP_ALLOCATION *)pAlloc);
Assert(pSwapchain);
bFrontBuf = (vboxWddmSwapchainGetFb(pSwapchain)->pAlloc == pAlloc);
}
- vboxVDbgPrint(("%s D3DWidth(%d), width(%d), height(%d), format(%d), usage(%s), %s", pPrefix,
- pAlloc->D3DWidth, pAlloc->SurfDesc.width, pAlloc->SurfDesc.height, pAlloc->SurfDesc.format,
+ vboxVDbgPrint(("%s d3dWidth(%d), width(%d), height(%d), format(%d), usage(%s), %s", pPrefix,
+ pAlloc->SurfDesc.d3dWidth, pAlloc->SurfDesc.width, pAlloc->SurfDesc.height, pAlloc->SurfDesc.format,
bPrimary ?
(bFrontBuf ? "Front Buffer" : "Back Buffer")
: "?Everage? Alloc",
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.h
index 9c5798b4..df5a14bb 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispDbg.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -49,11 +49,6 @@
//# define VBOXWDDMDISP_DEBUG_TIMER
# endif
-/* log enable flags */
-extern DWORD g_VBoxVDbgFLogRel;
-extern DWORD g_VBoxVDbgFLog;
-extern DWORD g_VBoxVDbgFLogFlow;
-
# ifndef IN_VBOXCRHGSMI
/* debug config vars */
extern DWORD g_VBoxVDbgFDumpSetTexture;
@@ -90,6 +85,13 @@ extern DWORD g_VBoxVDbgCfgCreateSwapchainOnDdiOnce;
# endif /* #ifndef IN_VBOXCRHGSMI */
#endif
+#if defined(VBOXWDDMDISP_DEBUG) || defined(VBOX_WDDMDISP_WITH_PROFILE)
+/* log enable flags */
+extern DWORD g_VBoxVDbgFLogRel;
+extern DWORD g_VBoxVDbgFLog;
+extern DWORD g_VBoxVDbgFLogFlow;
+#endif
+
#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
void vboxVDbgVEHandlerRegister();
void vboxVDbgVEHandlerUnregister();
@@ -115,7 +117,7 @@ void vboxVDbgVEHandlerUnregister();
# define DbgPrintUsrFlow(_m) do { } while (0)
#endif
-#ifdef VBOXWDDMDISP_DEBUG
+#if defined(VBOXWDDMDISP_DEBUG) || defined(VBOX_WDDMDISP_WITH_PROFILE)
#define vboxVDbgInternalLog(_p) if (g_VBoxVDbgFLog) { _p }
#define vboxVDbgInternalLogFlow(_p) if (g_VBoxVDbgFLogFlow) { _p }
#define vboxVDbgInternalLogRel(_p) if (g_VBoxVDbgFLogRel) { _p }
@@ -233,20 +235,20 @@ typedef struct VBOXWDDMDISP_RESOURCE *PVBOXWDDMDISP_RESOURCE;
VOID vboxVDbgDoDumpAllocRect(const char * pPrefix, PVBOXWDDMDISP_ALLOCATION pAlloc, RECT *pRect, const char* pSuffix, DWORD fFlags);
VOID vboxVDbgDoDumpRcRect(const char * pPrefix, PVBOXWDDMDISP_ALLOCATION pAlloc, IDirect3DResource9 *pD3DRc, RECT *pRect, const char * pSuffix, DWORD fFlags);
-VOID vboxVDbgDoDumpLockUnlockSurfTex(const char * pPrefix, const PVBOXWDDMDISP_ALLOCATION pAlloc, const char * pSuffix, DWORD fFlags);
+VOID vboxVDbgDoDumpLockUnlockSurfTex(const char * pPrefix, const VBOXWDDMDISP_ALLOCATION *pAlloc, const char * pSuffix, DWORD fFlags);
VOID vboxVDbgDoDumpRt(const char * pPrefix, struct VBOXWDDMDISP_DEVICE *pDevice, const char * pSuffix, DWORD fFlags);
VOID vboxVDbgDoDumpBb(const char * pPrefix, IDirect3DSwapChain9 *pSwapchainIf, const char * pSuffix, DWORD fFlags);
VOID vboxVDbgDoDumpFb(const char * pPrefix, IDirect3DSwapChain9 *pSwapchainIf, const char * pSuffix, DWORD fFlags);
VOID vboxVDbgDoDumpSamplers(const char * pPrefix, struct VBOXWDDMDISP_DEVICE *pDevice, const char * pSuffix, DWORD fFlags);
void vboxVDbgDoPrintRect(const char * pPrefix, const RECT *pRect, const char * pSuffix);
-void vboxVDbgDoPrintAlloc(const char * pPrefix, const PVBOXWDDMDISP_RESOURCE pRc, uint32_t iAlloc, const char * pSuffix);
+void vboxVDbgDoPrintAlloc(const char * pPrefix, const VBOXWDDMDISP_RESOURCE *pRc, uint32_t iAlloc, const char * pSuffix);
VOID vboxVDbgDoDumpLockSurfTex(const char * pPrefix, const D3DDDIARG_LOCK* pData, const char * pSuffix, DWORD fFlags);
VOID vboxVDbgDoDumpUnlockSurfTex(const char * pPrefix, const D3DDDIARG_UNLOCK* pData, const char * pSuffix, DWORD fFlags);
-BOOL vboxVDbgDoCheckRectsMatch(const PVBOXWDDMDISP_RESOURCE pDstRc, uint32_t iDstAlloc,
- const PVBOXWDDMDISP_RESOURCE pSrcRc, uint32_t iSrcAlloc,
+BOOL vboxVDbgDoCheckRectsMatch(const VBOXWDDMDISP_RESOURCE *pDstRc, uint32_t iDstAlloc,
+ const VBOXWDDMDISP_RESOURCE *pSrcRc, uint32_t iSrcAlloc,
const RECT *pDstRect,
const RECT *pSrcRect,
BOOL fBreakOnMismatch);
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.cpp
index 081088a4..200fa44c 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -16,19 +16,41 @@
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-#include "VBoxDispD3DCmn.h"
+#include "VBoxDispD3DBase.h"
+#include "VBoxDispKmt.h"
+
+#include <iprt/assert.h>
+#include <iprt/log.h>
#ifndef NT_SUCCESS
# define NT_SUCCESS(_Status) ((_Status) >= 0)
#endif
+/**
+ * Loads a system DLL.
+ *
+ * @returns Module handle or NULL
+ * @param pszName The DLL name.
+ */
+static HMODULE loadSystemDll(const char *pszName)
+{
+ char szPath[MAX_PATH];
+ UINT cchPath = GetSystemDirectoryA(szPath, sizeof(szPath));
+ size_t cbName = strlen(pszName) + 1;
+ if (cchPath + 1 + cbName > sizeof(szPath))
+ return NULL;
+ szPath[cchPath] = '\\';
+ memcpy(&szPath[cchPath + 1], pszName, cbName);
+ return LoadLibraryA(szPath);
+}
+
HRESULT vboxDispKmtCallbacksInit(PVBOXDISPKMT_CALLBACKS pCallbacks)
{
HRESULT hr = S_OK;
memset(pCallbacks, 0, sizeof (*pCallbacks));
- pCallbacks->hGdi32 = LoadLibraryW(L"gdi32.dll");
+ pCallbacks->hGdi32 = loadSystemDll("gdi32.dll");
if (pCallbacks->hGdi32 != NULL)
{
bool bSupported = true;
@@ -49,7 +71,11 @@ HRESULT vboxDispKmtCallbacksInit(PVBOXDISPKMT_CALLBACKS pCallbacks)
Log((__FUNCTION__": pfnD3DKMTEscape = %p\n", pCallbacks->pfnD3DKMTEscape));
bSupported &= !!(pCallbacks->pfnD3DKMTEscape);
- pCallbacks->pfnD3DKMTCreateDevice = (PFND3DKMT_CREATEDEVICE)GetProcAddress(pCallbacks->hGdi32, "D3DKMTCreateDevice");
+ pCallbacks->pfnD3DKMTQueryAdapterInfo = (PFND3DKMT_QUERYADAPTERINFO)GetProcAddress(pCallbacks->hGdi32, "D3DKMTQueryAdapterInfo");
+ Log((__FUNCTION__": pfnD3DKMTQueryAdapterInfo = %p\n", pCallbacks->pfnD3DKMTQueryAdapterInfo));
+ bSupported &= !!(pCallbacks->pfnD3DKMTQueryAdapterInfo);
+
+ pCallbacks->pfnD3DKMTCreateDevice = (PFND3DKMT_CREATEDEVICE)GetProcAddress(pCallbacks->hGdi32, "D3DKMTCreateDevice");
Log((__FUNCTION__": pfnD3DKMTCreateDevice = %p\n", pCallbacks->pfnD3DKMTCreateDevice));
bSupported &= !!(pCallbacks->pfnD3DKMTCreateDevice);
@@ -85,6 +111,14 @@ HRESULT vboxDispKmtCallbacksInit(PVBOXDISPKMT_CALLBACKS pCallbacks)
Log((__FUNCTION__": pfnD3DKMTUnlock = %p\n", pCallbacks->pfnD3DKMTUnlock));
bSupported &= !!(pCallbacks->pfnD3DKMTUnlock);
+ pCallbacks->pfnD3DKMTInvalidateActiveVidPn = (PFND3DKMT_INVALIDATEACTIVEVIDPN)GetProcAddress(pCallbacks->hGdi32, "D3DKMTInvalidateActiveVidPn");
+ Log((__FUNCTION__": pfnD3DKMTInvalidateActiveVidPn = %p\n", pCallbacks->pfnD3DKMTInvalidateActiveVidPn));
+ bSupported &= !!(pCallbacks->pfnD3DKMTInvalidateActiveVidPn);
+
+ pCallbacks->pfnD3DKMTPollDisplayChildren = (PFND3DKMT_POLLDISPLAYCHILDREN)GetProcAddress(pCallbacks->hGdi32, "D3DKMTPollDisplayChildren");
+ Log((__FUNCTION__": pfnD3DKMTPollDisplayChildren = %p\n", pCallbacks->pfnD3DKMTPollDisplayChildren));
+ bSupported &= !!(pCallbacks->pfnD3DKMTPollDisplayChildren);
+
pCallbacks->pfnD3DKMTEnumAdapters = (PFND3DKMT_ENUMADAPTERS)GetProcAddress(pCallbacks->hGdi32, "D3DKMTEnumAdapters");
Log((__FUNCTION__": pfnD3DKMTEnumAdapters = %p\n", pCallbacks->pfnD3DKMTEnumAdapters));
/* this present starting win8 release preview only, so keep going if it is not available,
@@ -185,7 +219,7 @@ HRESULT vboxDispKmtAdpHdcCreate(HDC *phDc)
return hr;
}
-static HRESULT vboxDispKmtOpenAdapterViaHdc(PVBOXDISPKMT_CALLBACKS pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter)
+static HRESULT vboxDispKmtOpenAdapterViaHdc(const VBOXDISPKMT_CALLBACKS *pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter)
{
D3DKMT_OPENADAPTERFROMHDC OpenAdapterData = {0};
HRESULT hr = vboxDispKmtAdpHdcCreate(&OpenAdapterData.hDc);
@@ -194,10 +228,6 @@ static HRESULT vboxDispKmtOpenAdapterViaHdc(PVBOXDISPKMT_CALLBACKS pCallbacks, P
Assert(OpenAdapterData.hDc);
NTSTATUS Status = pCallbacks->pfnD3DKMTOpenAdapterFromHdc(&OpenAdapterData);
-#ifdef DEBUG_misha
- /* may fail with xpdm driver */
- Assert(NT_SUCCESS(Status));
-#endif
if (NT_SUCCESS(Status))
{
pAdapter->hAdapter = OpenAdapterData.hAdapter;
@@ -217,7 +247,7 @@ static HRESULT vboxDispKmtOpenAdapterViaHdc(PVBOXDISPKMT_CALLBACKS pCallbacks, P
return hr;
}
-static HRESULT vboxDispKmtOpenAdapterViaLuid(PVBOXDISPKMT_CALLBACKS pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter)
+static HRESULT vboxDispKmtOpenAdapterViaLuid(const VBOXDISPKMT_CALLBACKS *pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter)
{
if (pCallbacks->enmVersion < VBOXDISPKMT_CALLBACKS_VERSION_WIN8)
return E_NOTIMPL;
@@ -266,7 +296,7 @@ static HRESULT vboxDispKmtOpenAdapterViaLuid(PVBOXDISPKMT_CALLBACKS pCallbacks,
return E_FAIL;
}
-HRESULT vboxDispKmtOpenAdapter(PVBOXDISPKMT_CALLBACKS pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter)
+HRESULT vboxDispKmtOpenAdapter(const VBOXDISPKMT_CALLBACKS *pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter)
{
HRESULT hr = vboxDispKmtOpenAdapterViaHdc(pCallbacks, pAdapter);
if (SUCCEEDED(hr))
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.h
index 54fe974b..6c481a72 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -21,6 +21,8 @@
#include <D3dkmthk.h>
+#include "../../common/wddm/VBoxMPIf.h"
+
/* win8 release preview-specific stuff */
typedef struct _D3DKMT_ADAPTERINFO
{
@@ -68,6 +70,8 @@ typedef struct VBOXDISPKMT_CALLBACKS
/* escape */
PFND3DKMT_ESCAPE pfnD3DKMTEscape;
+ PFND3DKMT_QUERYADAPTERINFO pfnD3DKMTQueryAdapterInfo;
+
PFND3DKMT_CREATEDEVICE pfnD3DKMTCreateDevice;
PFND3DKMT_DESTROYDEVICE pfnD3DKMTDestroyDevice;
PFND3DKMT_CREATECONTEXT pfnD3DKMTCreateContext;
@@ -81,6 +85,11 @@ typedef struct VBOXDISPKMT_CALLBACKS
PFND3DKMT_LOCK pfnD3DKMTLock;
PFND3DKMT_UNLOCK pfnD3DKMTUnlock;
+ /* auto resize support */
+ PFND3DKMT_INVALIDATEACTIVEVIDPN pfnD3DKMTInvalidateActiveVidPn;
+ PFND3DKMT_POLLDISPLAYCHILDREN pfnD3DKMTPollDisplayChildren;
+
+ /* win8 specifics */
PFND3DKMT_ENUMADAPTERS pfnD3DKMTEnumAdapters;
PFND3DKMT_OPENADAPTERFROMLUID pfnD3DKMTOpenAdapterFromLuid;
} VBOXDISPKMT_CALLBACKS, *PVBOXDISPKMT_CALLBACKS;
@@ -90,7 +99,7 @@ typedef struct VBOXDISPKMT_ADAPTER
D3DKMT_HANDLE hAdapter;
HDC hDc;
LUID Luid;
- PVBOXDISPKMT_CALLBACKS pCallbacks;
+ const VBOXDISPKMT_CALLBACKS *pCallbacks;
}VBOXDISPKMT_ADAPTER, *PVBOXDISPKMT_ADAPTER;
typedef struct VBOXDISPKMT_DEVICE
@@ -120,7 +129,7 @@ typedef struct VBOXDISPKMT_CONTEXT
HRESULT vboxDispKmtCallbacksInit(PVBOXDISPKMT_CALLBACKS pCallbacks);
HRESULT vboxDispKmtCallbacksTerm(PVBOXDISPKMT_CALLBACKS pCallbacks);
-HRESULT vboxDispKmtOpenAdapter(PVBOXDISPKMT_CALLBACKS pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter);
+HRESULT vboxDispKmtOpenAdapter(const VBOXDISPKMT_CALLBACKS *pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter);
HRESULT vboxDispKmtCloseAdapter(PVBOXDISPKMT_ADAPTER pAdapter);
HRESULT vboxDispKmtCreateDevice(PVBOXDISPKMT_ADAPTER pAdapter, PVBOXDISPKMT_DEVICE pDevice);
HRESULT vboxDispKmtDestroyDevice(PVBOXDISPKMT_DEVICE pDevice);
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.cpp
index 182354e2..e7e06e93 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -18,7 +18,7 @@
#include "VBoxDispD3DCmn.h"
#include "VBoxDispMp.h"
-
+#if 0
#include <iprt/assert.h>
typedef struct VBOXVIDEOCM_ITERATOR
@@ -293,3 +293,4 @@ HRESULT vboxDispMpInternalCancel(VBOXWDDMDISP_CONTEXT *pContext, PVBOXWDDMDISP_S
LeaveCriticalSection(&g_VBoxDispMp.CritSect);
return hr;
}
+#endif /* 0 */
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.h
index c91db2a2..c643f713 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2010 Oracle Corporation
+ * Copyright (C) 2010-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -25,6 +25,7 @@
#include <d3dhal.h>
#include "../../common/wddm/VBoxMPIf.h"
+#if 0
typedef struct VBOXDISPMP_REGIONS
{
HWND hWnd;
@@ -80,5 +81,5 @@ typedef struct VBOXDISPMP_CALLBACKS
*/
typedef VBOXDISPMP_DECL(HRESULT) FNVBOXDISPMP_GETCALLBACKS(uint32_t u32Version, PVBOXDISPMP_CALLBACKS pCallbacks);
typedef FNVBOXDISPMP_GETCALLBACKS *PFNVBOXDISPMP_GETCALLBACKS;
-
+#endif /* 0 */
#endif /* #ifndef ___VBoxDispMp_h___ */
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMpInternal.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMpInternal.h
index 0f159634..b0bd9718 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMpInternal.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMpInternal.h
@@ -21,8 +21,10 @@
#include <windows.h>
+#if 0
HRESULT vboxDispMpInternalInit();
HRESULT vboxDispMpInternalTerm();
HRESULT vboxDispMpInternalCancel(struct VBOXWDDMDISP_CONTEXT *pContext, struct VBOXWDDMDISP_SWAPCHAIN *pSwapchain);
+#endif
#endif /* #ifndef ___VBoxDispMpInternal_h__ */
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMpTst.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMpTst.cpp
deleted file mode 100644
index 679dc91e..00000000
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMpTst.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-/* $Id: VBoxDispMpTst.cpp $ */
-
-/** @file
- * VBoxVideo Display D3D User mode dll
- */
-
-/*
- * Copyright (C) 2011 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-#include "VBoxDispD3DCmn.h"
-#include "VBoxDispMp.h"
-
-#include <iprt/thread.h>
-#include <iprt/err.h>
-
-#ifdef VBOXWDDM_TEST_UHGSMI
-#include "VBoxDispProfile.h"
-#endif
-
-static RTTHREAD g_VBoxDispMpTstThread;
-static VBOXDISPMP_CALLBACKS g_VBoxDispMpTstCallbacks;
-static HMODULE g_hVBoxDispMpModule;
-static PFNVBOXDISPMP_GETCALLBACKS g_pfnVBoxDispMpGetCallbacks;
-
-
-static void vboxDispMpTstLogRect(const char * pPrefix, RECT *pRect, const char * pSuffix)
-{
- vboxVDbgPrint(("%s left(%d), top(%d), right(%d), bottom(%d) %s", pPrefix, pRect->left, pRect->top, pRect->right, pRect->bottom, pSuffix));
-}
-
-static DECLCALLBACK(int) vboxDispMpTstThreadProc(RTTHREAD ThreadSelf, void *pvUser)
-{
- VBOXDISPMP_REGIONS Regions;
-
- HRESULT hr = g_VBoxDispMpTstCallbacks.pfnEnableEvents();
- Assert(hr == S_OK);
- if (hr != S_OK)
- return VERR_GENERAL_FAILURE;
-
- do
- {
- hr = g_VBoxDispMpTstCallbacks.pfnGetRegions(&Regions, INFINITE);
- Assert(hr == S_OK);
- if (hr == S_OK)
- {
- vboxVDbgPrint(("\n>>>\n"));
- HWND hWnd = Regions.hWnd;
- if (Regions.pRegions->fFlags.bAddVisibleRects)
- {
- uint32_t iVisibleRects = 0;
- uint32_t cVisibleRects = Regions.pRegions->RectsInfo.cRects;
- if (Regions.pRegions->fFlags.bSetViewRect)
- {
- iVisibleRects = 1;
-
- vboxVDbgPrint(("hWnd (0x%p), position and/or size changed: ", hWnd));
- vboxDispMpTstLogRect("", Regions.pRegions->RectsInfo.aRects, "\n");
- }
-
- vboxVDbgPrint(("hWnd (0x%p), visibleRects: \n", hWnd));
- for (uint32_t i = iVisibleRects; i < cVisibleRects; ++i)
- {
- vboxDispMpTstLogRect("", &Regions.pRegions->RectsInfo.aRects[i], "");
- }
- }
- else if (Regions.pRegions->fFlags.bAddHiddenRects)
- {
- vboxVDbgPrint(("hWnd (0x%p), hiddenRects: \n", hWnd));
- for (uint32_t i = 0; i < Regions.pRegions->RectsInfo.cRects; ++i)
- {
- vboxDispMpTstLogRect("", &Regions.pRegions->RectsInfo.aRects[i], "");
- }
- }
-
- vboxVDbgPrint(("\n<<<\n"));
- }
- } while (1);
-
- hr = g_VBoxDispMpTstCallbacks.pfnDisableEvents();
- Assert(hr == S_OK);
-
- return VINF_SUCCESS;
-}
-
-HRESULT vboxDispMpTstStart()
-{
- HRESULT hr = E_FAIL;
- g_hVBoxDispMpModule = GetModuleHandleW(L"VBoxDispD3D.dll");
- Assert(g_hVBoxDispMpModule);
-
- if (g_hVBoxDispMpModule)
- {
- g_pfnVBoxDispMpGetCallbacks = (PFNVBOXDISPMP_GETCALLBACKS)GetProcAddress(g_hVBoxDispMpModule, "VBoxDispMpGetCallbacks");
- Assert(g_pfnVBoxDispMpGetCallbacks);
- if (g_pfnVBoxDispMpGetCallbacks)
- {
- hr = g_pfnVBoxDispMpGetCallbacks(VBOXDISPMP_VERSION, &g_VBoxDispMpTstCallbacks);
- Assert(hr == S_OK);
- if (hr == S_OK)
- {
- int rc = RTThreadCreate(&g_VBoxDispMpTstThread, vboxDispMpTstThreadProc, NULL, 0,
- RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "VBoxDispMpTst");
- AssertRC(rc);
- if (RT_SUCCESS(rc))
- return S_OK;
-
- hr = E_FAIL;
- }
- }
- FreeLibrary(g_hVBoxDispMpModule);
- }
-
- return hr;
-}
-
-HRESULT vboxDispMpTstStop()
-{
- HRESULT hr = g_VBoxDispMpTstCallbacks.pfnDisableEvents();
- Assert(hr == S_OK);
-#if 0
- if (hr == S_OK)
- {
- int rc = RTThreadWaitNoResume(g_VBoxDispMpTstThread, RT_INDEFINITE_WAIT, NULL);
- AssertRC(rc);
- if (RT_SUCCESS(rc))
- {
- BOOL bResult = FreeLibrary(g_hVBoxDispMpModule);
- Assert(bResult);
-#ifdef DEBUG
- if (!bResult)
- {
- DWORD winEr = GetLastError();
- hr = HRESULT_FROM_WIN32(winEr);
- }
-#endif
- }
- else
- hr = E_FAIL;
- }
-#endif
- return hr;
-}
-
-#ifdef VBOXWDDM_TEST_UHGSMI
-int vboxUhgsmiTst(PVBOXUHGSMI pUhgsmi, uint32_t cbBuf, uint32_t cNumCals, uint64_t * pTimeMs)
-{
- PVBOXUHGSMI_BUFFER pBuf;
- int rc = pUhgsmi->pfnBufferCreate(pUhgsmi, cbBuf, VBOXUHGSMI_SYNCHOBJECT_TYPE_EVENT, NULL, &pBuf);
- AssertRC(rc);
- if (RT_SUCCESS(rc))
- {
- uint64_t TimeMs = VBOXDISPPROFILE_GET_TIME_MILLI();
- do
- {
- VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags;
- fFlags.Value = 0;
- fFlags.bLockEntire = 1;
- fFlags.bDiscard = 1;
-
- void *pvLock;
- rc = pBuf->pfnLock(pBuf, 0, cbBuf, fFlags, &pvLock);
- AssertRC(rc);
- if (!RT_SUCCESS(rc))
- break;
-
- rc = pBuf->pfnUnlock(pBuf);
- AssertRC(rc);
- if (!RT_SUCCESS(rc))
- break;
-
- VBOXUHGSMI_BUFFER_SUBMIT SubmitData;
- SubmitData.pBuf = pBuf;
- SubmitData.fFlags.Value = 0;
- SubmitData.fFlags.bDoNotRetire = 1;
- SubmitData.fFlags.bEntireBuffer = 1;
-
- rc = pUhgsmi->pfnBufferSubmitAsynch(pUhgsmi, &SubmitData, 1);
- AssertRC(rc);
- if (!RT_SUCCESS(rc))
- break;
-
- DWORD dw = WaitForSingleObject(pBuf->hSynch, INFINITE);
- Assert(dw == WAIT_OBJECT_0);
- if (dw)
- break;
- } while (--cNumCals);
-
- TimeMs = VBOXDISPPROFILE_GET_TIME_MILLI() - TimeMs;
- *pTimeMs = TimeMs;
-
- pBuf->pfnDestroy(pBuf);
- }
- return rc;
-}
-#endif
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispProfile.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispProfile.h
index a732762e..4e62c621 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispProfile.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispProfile.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -77,11 +77,19 @@ public:
// VBOXDISPPROFILE_DUMP((pDevice, "Entry '%s': calls(%d), time: nanos(%I64u), micros(%I64u), millis(%I64u)\n",
// m_pName, m_cCalls,
// m_cTime, m_cTime/1000, m_cTime/1000000));
- VBOXDISPPROFILE_DUMP(("'%s' [0x%p]: \t%d\t%u\t%u\t%u\t%u\t%u", m_pName, pvObj,
+
+// VBOXDISPPROFILE_DUMP(("'%s' [0x%p]: \t%d\t%u\t%u\t%u\t%f\t%f", m_pName, pvObj,
+// m_cCalls,
+// (uint32_t)m_cTime, (uint32_t)(m_cTime/1000), (uint32_t)(m_cTime/1000000),
+// (((double)m_cTime)/cTotalEntriesTime),
+// (((double)m_cTime)/cTotalTime)));
+
+ VBOXDISPPROFILE_DUMP(("'%s' [0x%p]: \t%d\t%u\t%f\t%f", m_pName, pvObj,
m_cCalls,
- (uint32_t)m_cTime, (uint32_t)(m_cTime/1000), (uint32_t)(m_cTime/1000000),
- (uint32_t)(((double)m_cTime)/cTotalEntriesTime),
- (uint32_t)(((double)m_cTime)/cTotalTime)));
+ (uint32_t)(m_cTime/1000000),
+ (((double)m_cTime)/cTotalEntriesTime),
+ (((double)m_cTime)/cTotalTime)));
+
}
private:
uint32_t m_cCalls;
@@ -193,11 +201,18 @@ private:
const char * m_pName;
};
-template<typename T> class VBoxDispProfileScopeLogger
+class VBoxDispProfileDummyPostProcess
+{
+public:
+ void postProcess(){}
+};
+
+template<typename T, typename P> class VBoxDispProfileScopeLogger
{
public:
- VBoxDispProfileScopeLogger(T *pEntry) :
+ VBoxDispProfileScopeLogger(T *pEntry, P PostProcess) :
m_pEntry(pEntry),
+ m_PostProcess(PostProcess),
m_bDisable(FALSE)
{
m_cTime = VBOXDISPPROFILE_GET_TIME_NANO();
@@ -225,10 +240,12 @@ public:
private:
void logStep()
{
+ m_PostProcess.postProcess();
uint64_t cNewTime = VBOXDISPPROFILE_GET_TIME_NANO();
m_pEntry->step(cNewTime - m_cTime);
}
T *m_pEntry;
+ P m_PostProcess;
uint64_t m_cTime;
BOOL m_bDisable;
};
@@ -372,18 +389,18 @@ private:
} while (0)
#ifdef VBOXDISPPROFILE_FUNCTION_LOGGER_GLOBAL_PROFILE
-# define VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE(_p) \
+# define VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE(_p, _T, _v) \
static VBoxDispProfileEntry * __pVBoxDispProfileEntry = NULL; \
if (!__pVBoxDispProfileEntry) { __pVBoxDispProfileEntry = _p.alloc(__FUNCTION__); } \
- VBoxDispProfileScopeLogger<VBoxDispProfileEntry> __vboxDispProfileFunctionLogger(__pVBoxDispProfileEntry);
+ VBoxDispProfileScopeLogger<VBoxDispProfileEntry, _T> __vboxDispProfileFunctionLogger(__pVBoxDispProfileEntry, _v);
#else
# ifndef VBOXDISPPROFILE_FUNCTION_LOGGER_INDEX_GEN
# error "VBOXDISPPROFILE_FUNCTION_LOGGER_INDEX_GEN should be fedined!"
# endif
-# define VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE(_p) \
+# define VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE(_p, _T, _v) \
static uint32_t __u32VBoxDispProfileIndex = VBOXDISPPROFILE_FUNCTION_LOGGER_INDEX_GEN(); \
VBoxDispProfileEntry * __pVBoxDispProfileEntry = _p.get(__u32VBoxDispProfileIndex, __FUNCTION__); \
- VBoxDispProfileScopeLogger<VBoxDispProfileEntry> __vboxDispProfileFunctionLogger(__pVBoxDispProfileEntry);
+ VBoxDispProfileScopeLogger<VBoxDispProfileEntry, _T> __vboxDispProfileFunctionLogger(__pVBoxDispProfileEntry, _v);
#endif
#define VBOXDISPPROFILE_STATISTIC_LOGGER_DISABLE_CURRENT() do { \
@@ -395,8 +412,8 @@ private:
} while (0)
-#define VBOXDISPPROFILE_STATISTIC_LOGGER_DEFINE(_p) \
- VBoxDispProfileScopeLogger<VBoxDispProfileFpsCounter> __vboxDispProfileStatisticLogger(_p);
+#define VBOXDISPPROFILE_STATISTIC_LOGGER_DEFINE(_p, _T, _v) \
+ VBoxDispProfileScopeLogger<VBoxDispProfileFpsCounter, _T> __vboxDispProfileStatisticLogger(_p, _v);
//#define VBOXDISPPROFILE_FUNCTION_PROLOGUE(_p) \
// VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE(_p)
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxScreen.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxScreen.cpp
index 0345bbc9..d225e339 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxScreen.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxScreen.cpp
@@ -1,11 +1,10 @@
/* $Id: VBoxScreen.cpp $ */
-
/** @file
* VBoxVideo Display D3D User mode dll
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -340,6 +339,24 @@ static HRESULT vboxScreenMonWndDestroy(HWND hWnd)
return HRESULT_FROM_WIN32(winErr);
}
+/**
+ * Loads a system DLL.
+ *
+ * @returns Module handle or NULL
+ * @param pszName The DLL name.
+ */
+static HMODULE loadSystemDll(const char *pszName)
+{
+ char szPath[MAX_PATH];
+ UINT cchPath = GetSystemDirectoryA(szPath, sizeof(szPath));
+ size_t cbName = strlen(pszName) + 1;
+ if (cchPath + 1 + cbName > sizeof(szPath))
+ return NULL;
+ szPath[cchPath] = '\\';
+ memcpy(&szPath[cchPath + 1], pszName, cbName);
+ return LoadLibraryA(szPath);
+}
+
//HRESULT vboxScreenMonInit(PVBOXSCREENMON pMon)
HRESULT vboxScreenMonInit()
{
@@ -350,7 +367,7 @@ HRESULT vboxScreenMonInit()
pMon->LoData.ScreenLayout.EscapeHdr.escapeCode = VBOXESC_SCREENLAYOUT;
- pMon->hGdi32 = LoadLibraryW(L"gdi32.dll");
+ pMon->hGdi32 = loadSystemDll("gdi32.dll");
if (pMon->hGdi32 != NULL)
{
bool bSupported = true;
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.cpp
index 939cba60..6ac9d7e7 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.cpp
@@ -32,7 +32,7 @@ DECLCALLBACK(int) vboxUhgsmiBaseEscBufferUnlock(PVBOXUHGSMI_BUFFER pBuf)
int vboxUhgsmiBaseBufferTerm(PVBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE pBuffer)
{
- PVBOXUHGSMI_PRIVATE_BASE pPrivate = VBOXUHGSMIBASE_GET(pBuffer->PrivateBase.pHgsmi);
+ PVBOXUHGSMI_PRIVATE_BASE pPrivate = VBOXUHGSMIBASE_GET(pBuffer->BasePrivate.pHgsmi);
VBOXDISPIFESCAPE_UHGSMI_DEALLOCATE DeallocInfo = {0};
DeallocInfo.EscapeHdr.escapeCode = VBOXESC_UHGSMI_DEALLOCATE;
DeallocInfo.hAlloc = pBuffer->Alloc.hAlloc;
@@ -97,12 +97,12 @@ int vboxUhgsmiKmtEscBufferInit(PVBOXUHGSMI_PRIVATE_BASE pPrivate, PVBOXUHGSMI_BU
pBuffer->Alloc = AllocInfo.Alloc;
Assert(pBuffer->Alloc.pvData);
- pBuffer->PrivateBase.pHgsmi = pPrivate;
- pBuffer->PrivateBase.Base.pfnLock = vboxUhgsmiBaseEscBufferLock;
- pBuffer->PrivateBase.Base.pfnUnlock = vboxUhgsmiBaseEscBufferUnlock;
- pBuffer->PrivateBase.Base.pfnDestroy = pfnDestroy;
- pBuffer->PrivateBase.Base.fType = fUhgsmiType;
- pBuffer->PrivateBase.Base.cbBuffer = AllocInfo.Alloc.cbData;
+ pBuffer->BasePrivate.pHgsmi = pPrivate;
+ pBuffer->BasePrivate.Base.pfnLock = vboxUhgsmiBaseEscBufferLock;
+ pBuffer->BasePrivate.Base.pfnUnlock = vboxUhgsmiBaseEscBufferUnlock;
+ pBuffer->BasePrivate.Base.pfnDestroy = pfnDestroy;
+ pBuffer->BasePrivate.Base.fType = fUhgsmiType;
+ pBuffer->BasePrivate.Base.cbBuffer = AllocInfo.Alloc.cbData;
pBuffer->hSynch = hSynch;
return VINF_SUCCESS;
}
@@ -136,7 +136,7 @@ DECLCALLBACK(int) vboxUhgsmiBaseEscBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbB
int rc = vboxUhgsmiKmtEscBufferInit(pPrivate, pBuffer, cbBuf, fUhgsmiType, vboxUhgsmiBaseEscBufferDestroy);
if (RT_SUCCESS(rc))
{
- *ppBuf = &pBuffer->PrivateBase.Base;
+ *ppBuf = &pBuffer->BasePrivate.Base;
return VINF_SUCCESS;
}
@@ -177,11 +177,10 @@ DECLCALLBACK(int) vboxUhgsmiBaseEscBufferSubmit(PVBOXUHGSMI pHgsmi, PVBOXUHGSMI_
PVBOXUHGSMI_BUFFER_SUBMIT pBufInfo = &aBuffers[i];
PVBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE pBuf = VBOXUHGSMIESCBASE_GET_BUFFER(pBufInfo->pBuf);
pSubmInfo->hAlloc = pBuf->Alloc.hAlloc;
- pSubmInfo->Info.bDoNotSignalCompletion = 0;
if (pBufInfo->fFlags.bEntireBuffer)
{
pSubmInfo->Info.offData = 0;
- pSubmInfo->Info.cbData = pBuf->PrivateBase.Base.cbBuffer;
+ pSubmInfo->Info.cbData = pBuf->BasePrivate.Base.cbBuffer;
}
else
{
@@ -233,19 +232,24 @@ int vboxCrHgsmiPrivateCtlConCall(struct VBOXUHGSMI_PRIVATE_BASE *pHgsmi, struct
}
pBuf->CallHdr.EscapeHdr.escapeCode = VBOXESC_CRHGSMICTLCON_CALL;
- pBuf->CallHdr.EscapeHdr.u32CmdSpecific = 0;
+ pBuf->CallHdr.EscapeHdr.u32CmdSpecific = (uint32_t)VERR_GENERAL_FAILURE;
memcpy(&pBuf->CallHdr.CallInfo, pCallInfo, cbCallInfo);
int rc = vboxCrHgsmiPrivateEscape(pHgsmi, pBuf, cbBuffer, FALSE);
if (RT_SUCCESS(rc))
{
- memcpy(pCallInfo, &pBuf->CallHdr.CallInfo, cbCallInfo);
- rc = VINF_SUCCESS;
+ rc = (int)pBuf->CallHdr.EscapeHdr.u32CmdSpecific;
+ if (RT_SUCCESS(rc))
+ {
+ memcpy(pCallInfo, &pBuf->CallHdr.CallInfo, cbCallInfo);
+ rc = VINF_SUCCESS;
+ }
+ else
+ WARN(("vboxCrHgsmiPrivateEscape u32CmdSpecific failed, rc (%d)", rc));
}
else
- {
WARN(("vboxCrHgsmiPrivateEscape failed, rc (%d)", rc));
- }
+
/* cleanup */
if (pBuf != &Buf)
RTMemFree(pBuf);
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.h
index 07a09d8e..9aaafa0c 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiBase.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -67,14 +67,14 @@ typedef struct VBOXUHGSMI_BUFFER_PRIVATE_BASE
typedef struct VBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE
{
- VBOXUHGSMI_BUFFER_PRIVATE_BASE PrivateBase;
+ VBOXUHGSMI_BUFFER_PRIVATE_BASE BasePrivate;
VBOXVIDEOCM_UM_ALLOC Alloc;
HANDLE hSynch;
} VBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE, *PVBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE;
typedef struct VBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE
{
- VBOXUHGSMI_BUFFER_PRIVATE_BASE PrivateBase;
+ VBOXUHGSMI_BUFFER_PRIVATE_BASE BasePrivate;
D3DKMT_HANDLE hAllocation;
UINT aLockPageIndices[1];
} VBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE, *PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE;
@@ -83,13 +83,14 @@ typedef struct VBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE
#define VBOXUHGSMIBASE_GET(_p) VBOXUHGSMIBASE_GET_PRIVATE(_p, VBOXUHGSMI_PRIVATE_BASE)
#define VBOXUHGSMIBASE_GET_BUFFER(_p) VBOXUHGSMIBASE_GET_PRIVATE(_p, VBOXUHGSMI_BUFFER_PRIVATE_BASE)
-#define VBOXUHGSMIPRIVATEBASE_GET_PRIVATE(_p, _t) ((_t*)(((uint8_t*)_p) - RT_OFFSETOF(_t, PrivateBase.Base)))
+#define VBOXUHGSMIPRIVATEBASE_GET_PRIVATE(_p, _t) ((_t*)(((uint8_t*)_p) - RT_OFFSETOF(_t, BasePrivate.Base)))
#define VBOXUHGSMIESCBASE_GET_BUFFER(_p) VBOXUHGSMIPRIVATEBASE_GET_PRIVATE(_p, VBOXUHGSMI_BUFFER_PRIVATE_ESC_BASE)
#define VBOXUHGSMDXALLOCBASE_GET_BUFFER(_p) VBOXUHGSMIPRIVATEBASE_GET_PRIVATE(_p, VBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE)
-DECLINLINE(int) vboxUhgsmiBaseLockData(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock, uint32_t cbLock, VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags,
- D3DDDICB_LOCKFLAGS *pfFlags, UINT *pNumPages, UINT* pPages)
+DECLINLINE(int) vboxUhgsmiBaseDxLockData(PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pPrivate, uint32_t offLock, uint32_t cbLock, VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags,
+ D3DDDICB_LOCKFLAGS *pfFlags, UINT *pNumPages)
{
+ PVBOXUHGSMI_BUFFER pBuf = &pPrivate->BasePrivate.Base;
D3DDDICB_LOCKFLAGS fLockFlags;
fLockFlags.Value = 0;
if (fFlags.bLockEntire)
@@ -126,7 +127,7 @@ DECLINLINE(int) vboxUhgsmiBaseLockData(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock
*pNumPages = cPages;
for (UINT i = 0, j = iFirstPage; i < cPages; ++i, ++j)
{
- pPages[i] = j;
+ pPrivate->aLockPageIndices[i] = j;
}
}
@@ -140,8 +141,17 @@ DECLINLINE(int) vboxUhgsmiBaseLockData(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock
return VINF_SUCCESS;
}
-#if 0
-DECLINLINE(int) vboxUhgsmiBaseDmaFill(PVBOXUHGSMI_BUFFER_SUBMIT aBuffers, uint32_t cBuffers,
+DECLINLINE(void) vboxUhgsmiBaseDxAllocInfoFill(D3DDDI_ALLOCATIONINFO *pDdiAllocInfo, VBOXWDDM_ALLOCINFO *pAllocInfo, uint32_t cbBuffer, VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType)
+{
+ pDdiAllocInfo->pPrivateDriverData = pAllocInfo;
+ pDdiAllocInfo->PrivateDriverDataSize = sizeof (*pAllocInfo);
+ pAllocInfo->enmType = VBOXWDDM_ALLOC_TYPE_UMD_HGSMI_BUFFER;
+ pAllocInfo->cbBuffer = cbBuffer;
+ pAllocInfo->fUhgsmiType = fUhgsmiType;
+
+}
+
+DECLINLINE(int) vboxUhgsmiBaseDxDmaFill(PVBOXUHGSMI_BUFFER_SUBMIT aBuffers, uint32_t cBuffers,
VOID* pCommandBuffer, UINT *pCommandBufferSize,
D3DDDI_ALLOCATIONLIST *pAllocationList, UINT AllocationListSize,
D3DDDI_PATCHLOCATIONLIST *pPatchLocationList, UINT PatchLocationListSize)
@@ -162,25 +172,24 @@ DECLINLINE(int) vboxUhgsmiBaseDmaFill(PVBOXUHGSMI_BUFFER_SUBMIT aBuffers, uint32
PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD pHdr = (PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD)pCommandBuffer;
pHdr->Base.enmCmd = VBOXVDMACMD_TYPE_CHROMIUM_CMD;
- pHdr->Base.u32CmdReserved = cBuffers;
+ pHdr->Base.u32CmdReserved = 0;
PVBOXWDDM_UHGSMI_BUFFER_UI_SUBMIT_INFO pBufSubmInfo = pHdr->aBufInfos;
for (uint32_t i = 0; i < cBuffers; ++i)
{
PVBOXUHGSMI_BUFFER_SUBMIT pBufInfo = &aBuffers[i];
- PVBOXUHGSMI_BUFFER_PRIVATE_BASE pBuffer = VBOXUHGSMIBASE_GET_BUFFER(pBufInfo->pBuf);
+ PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuffer = VBOXUHGSMDXALLOCBASE_GET_BUFFER(pBufInfo->pBuf);
memset(pAllocationList, 0, sizeof (D3DDDI_ALLOCATIONLIST));
pAllocationList->hAllocation = pBuffer->hAllocation;
pAllocationList->Value = 0;
pAllocationList->WriteOperation = !pBufInfo->fFlags.bHostReadOnly;
pAllocationList->DoNotRetireInstance = pBufInfo->fFlags.bDoNotRetire;
- pBufSubmInfo->bDoNotSignalCompletion = 0;
if (pBufInfo->fFlags.bEntireBuffer)
{
pBufSubmInfo->offData = 0;
- pBufSubmInfo->cbData = pBuffer->Base.cbBuffer;
+ pBufSubmInfo->cbData = pBuffer->BasePrivate.Base.cbBuffer;
}
else
{
@@ -194,7 +203,6 @@ DECLINLINE(int) vboxUhgsmiBaseDmaFill(PVBOXUHGSMI_BUFFER_SUBMIT aBuffers, uint32
return VINF_SUCCESS;
}
-#endif
DECLCALLBACK(int) vboxUhgsmiBaseEscBufferLock(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock, uint32_t cbLock, VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags, void**pvLock);
DECLCALLBACK(int) vboxUhgsmiBaseEscBufferUnlock(PVBOXUHGSMI_BUFFER pBuf);
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.cpp
index 12e26c12..c3fe710b 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -21,91 +21,83 @@
#define VBOXUHGSMID3D_GET_PRIVATE(_p, _t) ((_t*)(((uint8_t*)_p) - RT_OFFSETOF(_t, BasePrivate.Base)))
#define VBOXUHGSMID3D_GET(_p) VBOXUHGSMID3D_GET_PRIVATE(_p, VBOXUHGSMI_PRIVATE_D3D)
-#if 0
-#define VBOXUHGSMID3D_GET_BUFFER(_p) VBOXUHGSMID3D_GET_PRIVATE(_p, VBOXUHGSMI_BUFFER_PRIVATE_D3D)
-
#include <iprt/mem.h>
#include <iprt/err.h>
-typedef struct VBOXUHGSMI_BUFFER_PRIVATE_D3D
-{
- VBOXUHGSMI_BUFFER_PRIVATE_BASE BasePrivate;
- PVBOXWDDMDISP_DEVICE pDevice;
- UINT aLockPageIndices[1];
-} VBOXUHGSMI_BUFFER_PRIVATE_D3D, *PVBOXUHGSMI_BUFFER_PRIVATE_D3D;
-
-
-
DECLCALLBACK(int) vboxUhgsmiD3DBufferDestroy(PVBOXUHGSMI_BUFFER pBuf)
{
- PVBOXUHGSMI_BUFFER_PRIVATE_D3D pBuffer = VBOXUHGSMID3D_GET_BUFFER(pBuf);
+ PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuffer = VBOXUHGSMDXALLOCBASE_GET_BUFFER(pBuf);
+ struct VBOXWDDMDISP_DEVICE *pDevice = VBOXUHGSMID3D_GET(pBuffer->BasePrivate.pHgsmi)->pDevice;
D3DDDICB_DEALLOCATE DdiDealloc;
DdiDealloc.hResource = 0;
DdiDealloc.NumAllocations = 1;
- DdiDealloc.HandleList = &pBuffer->BasePrivate.hAllocation;
- HRESULT hr = pBuffer->pDevice->RtCallbacks.pfnDeallocateCb(pBuffer->pDevice->hDevice, &DdiDealloc);
- Assert(hr == S_OK);
+ DdiDealloc.HandleList = &pBuffer->hAllocation;
+ HRESULT hr = pDevice->RtCallbacks.pfnDeallocateCb(pDevice->hDevice, &DdiDealloc);
if (hr == S_OK)
{
- if (pBuffer->BasePrivate.hSynch)
- CloseHandle(pBuffer->BasePrivate.hSynch);
RTMemFree(pBuffer);
return VINF_SUCCESS;
}
+
+ WARN(("pfnDeallocateCb failed, hr %#x", hr));
return VERR_GENERAL_FAILURE;
}
+/* typedef DECLCALLBACK(int) FNVBOXUHGSMI_BUFFER_LOCK(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock, uint32_t cbLock, VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags, void**pvLock); */
DECLCALLBACK(int) vboxUhgsmiD3DBufferLock(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock, uint32_t cbLock, VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags, void**pvLock)
{
- PVBOXUHGSMI_BUFFER_PRIVATE_D3D pBuffer = VBOXUHGSMID3D_GET_BUFFER(pBuf);
+ PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuffer = VBOXUHGSMDXALLOCBASE_GET_BUFFER(pBuf);
+ struct VBOXWDDMDISP_DEVICE *pDevice = VBOXUHGSMID3D_GET(pBuffer->BasePrivate.pHgsmi)->pDevice;
D3DDDICB_LOCK DdiLock = {0};
- DdiLock.hAllocation = pBuffer->BasePrivate.hAllocation;
+ DdiLock.hAllocation = pBuffer->hAllocation;
DdiLock.PrivateDriverData = 0;
- int rc = vboxUhgsmiBaseLockData(pBuf, offLock, cbLock, fFlags,
- &DdiLock.Flags, &DdiLock.NumPages, pBuffer->aLockPageIndices);
- AssertRC(rc);
- if (RT_FAILURE(rc))
+ int rc = vboxUhgsmiBaseDxLockData(pBuffer, offLock, cbLock, fFlags,
+ &DdiLock.Flags, &DdiLock.NumPages);
+ if (!RT_SUCCESS(rc))
+ {
+ WARN(("vboxUhgsmiBaseDxLockData failed rc %d", rc));
return rc;
+ }
if (DdiLock.NumPages)
DdiLock.pPages = pBuffer->aLockPageIndices;
else
DdiLock.pPages = NULL;
- HRESULT hr = pBuffer->pDevice->RtCallbacks.pfnLockCb(pBuffer->pDevice->hDevice, &DdiLock);
- Assert(hr == S_OK);
+ HRESULT hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &DdiLock);
if (hr == S_OK)
{
*pvLock = (void*)(((uint8_t*)DdiLock.pData) + (offLock & 0xfff));
return VINF_SUCCESS;
}
+
+ WARN(("pfnLockCb failed, hr %#x", hr));
return VERR_GENERAL_FAILURE;
}
DECLCALLBACK(int) vboxUhgsmiD3DBufferUnlock(PVBOXUHGSMI_BUFFER pBuf)
{
- PVBOXUHGSMI_BUFFER_PRIVATE_D3D pBuffer = VBOXUHGSMID3D_GET_BUFFER(pBuf);
+ PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuffer = VBOXUHGSMDXALLOCBASE_GET_BUFFER(pBuf);
+ struct VBOXWDDMDISP_DEVICE *pDevice = VBOXUHGSMID3D_GET(pBuffer->BasePrivate.pHgsmi)->pDevice;
D3DDDICB_UNLOCK DdiUnlock;
DdiUnlock.NumAllocations = 1;
- DdiUnlock.phAllocations = &pBuffer->BasePrivate.hAllocation;
- HRESULT hr = pBuffer->pDevice->RtCallbacks.pfnUnlockCb(pBuffer->pDevice->hDevice, &DdiUnlock);
- Assert(hr == S_OK);
+ DdiUnlock.phAllocations = &pBuffer->hAllocation;
+ HRESULT hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &DdiUnlock);
if (hr == S_OK)
return VINF_SUCCESS;
+
+ WARN(("pfnUnlockCb failed, hr %#x", hr));
return VERR_GENERAL_FAILURE;
}
-DECLCALLBACK(int) vboxUhgsmiD3DBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType, PVBOXUHGSMI_BUFFER* ppBuf)
+/*typedef DECLCALLBACK(int) FNVBOXUHGSMI_BUFFER_CREATE(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fType, PVBOXUHGSMI_BUFFER* ppBuf);*/
+DECLCALLBACK(int) vboxUhgsmiD3DBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fType, PVBOXUHGSMI_BUFFER* ppBuf)
{
- HANDLE hSynch = NULL;
if (!cbBuf)
return VERR_INVALID_PARAMETER;
- int rc = vboxUhgsmiBaseEventChkCreate(fUhgsmiType, &hSynch);
- AssertRC(rc);
- if (RT_FAILURE(rc))
- return rc;
+ int rc = VINF_SUCCESS;
cbBuf = VBOXWDDM_ROUNDBOUND(cbBuf, 0x1000);
Assert(cbBuf);
@@ -113,72 +105,69 @@ DECLCALLBACK(int) vboxUhgsmiD3DBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf,
Assert(cPages);
PVBOXUHGSMI_PRIVATE_D3D pPrivate = VBOXUHGSMID3D_GET(pHgsmi);
- PVBOXUHGSMI_BUFFER_PRIVATE_D3D pBuf = (PVBOXUHGSMI_BUFFER_PRIVATE_D3D)RTMemAllocZ(RT_OFFSETOF(VBOXUHGSMI_BUFFER_PRIVATE_D3D, aLockPageIndices[cPages]));
- Assert(pBuf);
+ PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuf = (PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE)RTMemAllocZ(RT_OFFSETOF(VBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE, aLockPageIndices[cPages]));
if (pBuf)
{
- struct
- {
- D3DDDICB_ALLOCATE DdiAlloc;
- D3DDDI_ALLOCATIONINFO DdiAllocInfo;
- VBOXWDDM_ALLOCINFO AllocInfo;
- } Buf;
- memset(&Buf, 0, sizeof (Buf));
- Buf.DdiAlloc.hResource = NULL;
- Buf.DdiAlloc.hKMResource = NULL;
- Buf.DdiAlloc.NumAllocations = 1;
- Buf.DdiAlloc.pAllocationInfo = &Buf.DdiAllocInfo;
- Buf.DdiAllocInfo.pPrivateDriverData = &Buf.AllocInfo;
- Buf.DdiAllocInfo.PrivateDriverDataSize = sizeof (Buf.AllocInfo);
- Buf.AllocInfo.enmType = VBOXWDDM_ALLOC_TYPE_UMD_HGSMI_BUFFER;
- Buf.AllocInfo.cbBuffer = cbBuf;
- Buf.AllocInfo.hSynch = hSynch;
- Buf.AllocInfo.fUhgsmiType = fUhgsmiType;
-
- HRESULT hr = pPrivate->pDevice->RtCallbacks.pfnAllocateCb(pPrivate->pDevice->hDevice, &Buf.DdiAlloc);
- Assert(hr == S_OK);
+ D3DDDICB_ALLOCATE DdiAlloc;
+ D3DDDI_ALLOCATIONINFO DdiAllocInfo;
+ VBOXWDDM_ALLOCINFO AllocInfo;
+
+ memset(&DdiAlloc, 0, sizeof (DdiAlloc));
+ DdiAlloc.hResource = NULL;
+ DdiAlloc.hKMResource = NULL;
+ DdiAlloc.NumAllocations = 1;
+ DdiAlloc.pAllocationInfo = &DdiAllocInfo;
+ vboxUhgsmiBaseDxAllocInfoFill(&DdiAllocInfo, &AllocInfo, cbBuf, fType);
+
+ HRESULT hr = pPrivate->pDevice->RtCallbacks.pfnAllocateCb(pPrivate->pDevice->hDevice, &DdiAlloc);
if (hr == S_OK)
{
- Assert(Buf.DdiAllocInfo.hAllocation);
+ Assert(DdiAllocInfo.hAllocation);
pBuf->BasePrivate.Base.pfnLock = vboxUhgsmiD3DBufferLock;
pBuf->BasePrivate.Base.pfnUnlock = vboxUhgsmiD3DBufferUnlock;
-// pBuf->Base.pfnAdjustValidDataRange = vboxUhgsmiD3DBufferAdjustValidDataRange;
pBuf->BasePrivate.Base.pfnDestroy = vboxUhgsmiD3DBufferDestroy;
- pBuf->BasePrivate.Base.fType = fUhgsmiType;
+ pBuf->BasePrivate.Base.fType = fType;
pBuf->BasePrivate.Base.cbBuffer = cbBuf;
- pBuf->pDevice = pPrivate->pDevice;
- pBuf->BasePrivate.hAllocation = Buf.DdiAllocInfo.hAllocation;
+ pBuf->hAllocation = DdiAllocInfo.hAllocation;
*ppBuf = &pBuf->BasePrivate.Base;
return VINF_SUCCESS;
}
+ else
+ {
+ WARN(("pfnAllocateCb failed hr %#x"));
+ rc = VERR_GENERAL_FAILURE;
+ }
RTMemFree(pBuf);
}
else
+ {
+ WARN(("RTMemAllocZ failed"));
rc = VERR_NO_MEMORY;
-
- if (hSynch)
- CloseHandle(hSynch);
+ }
return rc;
}
+/* typedef DECLCALLBACK(int) FNVBOXUHGSMI_BUFFER_SUBMIT(PVBOXUHGSMI pHgsmi, PVBOXUHGSMI_BUFFER_SUBMIT aBuffers, uint32_t cBuffers); */
DECLCALLBACK(int) vboxUhgsmiD3DBufferSubmit(PVBOXUHGSMI pHgsmi, PVBOXUHGSMI_BUFFER_SUBMIT aBuffers, uint32_t cBuffers)
{
PVBOXUHGSMI_PRIVATE_D3D pHg = VBOXUHGSMID3D_GET(pHgsmi);
PVBOXWDDMDISP_DEVICE pDevice = pHg->pDevice;
UINT cbDmaCmd = pDevice->DefaultContext.ContextInfo.CommandBufferSize;
- int rc = vboxUhgsmiBaseDmaFill(aBuffers, cBuffers,
+ int rc = vboxUhgsmiBaseDxDmaFill(aBuffers, cBuffers,
pDevice->DefaultContext.ContextInfo.pCommandBuffer, &cbDmaCmd,
pDevice->DefaultContext.ContextInfo.pAllocationList, pDevice->DefaultContext.ContextInfo.AllocationListSize,
pDevice->DefaultContext.ContextInfo.pPatchLocationList, pDevice->DefaultContext.ContextInfo.PatchLocationListSize);
- AssertRC(rc);
if (RT_FAILURE(rc))
+ {
+ WARN(("vboxUhgsmiBaseDxDmaFill failed, rc %d", rc));
return rc;
+ }
D3DDDICB_RENDER DdiRender = {0};
DdiRender.CommandLength = cbDmaCmd;
@@ -193,7 +182,6 @@ DECLCALLBACK(int) vboxUhgsmiD3DBufferSubmit(PVBOXUHGSMI pHgsmi, PVBOXUHGSMI_BUFF
DdiRender.hContext = pDevice->DefaultContext.ContextInfo.hContext;
HRESULT hr = pDevice->RtCallbacks.pfnRenderCb(pDevice->hDevice, &DdiRender);
- Assert(hr == S_OK);
if (hr == S_OK)
{
pDevice->DefaultContext.ContextInfo.CommandBufferSize = DdiRender.NewCommandBufferSize;
@@ -206,17 +194,18 @@ DECLCALLBACK(int) vboxUhgsmiD3DBufferSubmit(PVBOXUHGSMI pHgsmi, PVBOXUHGSMI_BUFF
return VINF_SUCCESS;
}
+ WARN(("pfnRenderCb failed, hr %#x", hr));
return VERR_GENERAL_FAILURE;
}
-HRESULT vboxUhgsmiD3DInit(PVBOXUHGSMI_PRIVATE_D3D pHgsmi, PVBOXWDDMDISP_DEVICE pDevice)
+void vboxUhgsmiD3DInit(PVBOXUHGSMI_PRIVATE_D3D pHgsmi, PVBOXWDDMDISP_DEVICE pDevice)
{
pHgsmi->BasePrivate.Base.pfnBufferCreate = vboxUhgsmiD3DBufferCreate;
pHgsmi->BasePrivate.Base.pfnBufferSubmit = vboxUhgsmiD3DBufferSubmit;
+ /* no escapes (for now) */
+ pHgsmi->BasePrivate.pfnEscape = NULL;
pHgsmi->pDevice = pDevice;
- return S_OK;
}
-#endif
static DECLCALLBACK(int) vboxCrHhgsmiDispEscape(struct VBOXUHGSMI_PRIVATE_BASE *pHgsmi, void *pvData, uint32_t cbData, BOOL fHwAccess)
{
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.h
index f85b0e0d..1c2e981f 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiDisp.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -28,9 +28,7 @@ typedef struct VBOXUHGSMI_PRIVATE_D3D
struct VBOXWDDMDISP_DEVICE *pDevice;
} VBOXUHGSMI_PRIVATE_D3D, *PVBOXUHGSMI_PRIVATE_D3D;
-#if 0
void vboxUhgsmiD3DInit(PVBOXUHGSMI_PRIVATE_D3D pHgsmi, struct VBOXWDDMDISP_DEVICE *pDevice);
-#endif
void vboxUhgsmiD3DEscInit(PVBOXUHGSMI_PRIVATE_D3D pHgsmi, struct VBOXWDDMDISP_DEVICE *pDevice);
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.cpp
index 53325c6b..25573e21 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -27,29 +27,20 @@
# define NT_SUCCESS(_Status) (((NTSTATUS)(_Status)) >= 0)
#endif
-#if 0
-typedef struct VBOXUHGSMI_BUFFER_PRIVATE_KMT
-{
- VBOXUHGSMI_BUFFER_PRIVATE_BASE BasePrivate;
- CRITICAL_SECTION CritSect;
-} VBOXUHGSMI_BUFFER_PRIVATE_KMT, *PVBOXUHGSMI_BUFFER_PRIVATE_KMT;
-
-
-#define VBOXUHGSMIKMT_GET_BUFFER(_p) VBOXUHGSMIKMT_GET_PRIVATE(_p, VBOXUHGSMI_BUFFER_PRIVATE_KMT)
DECLCALLBACK(int) vboxUhgsmiKmtBufferDestroy(PVBOXUHGSMI_BUFFER pBuf)
{
- PVBOXUHGSMI_BUFFER_PRIVATE_KMT pBuffer = VBOXUHGSMIKMT_GET_BUFFER(pBuf);
+ PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuffer = VBOXUHGSMDXALLOCBASE_GET_BUFFER(pBuf);
+ PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pBuffer->BasePrivate.pHgsmi);
+
D3DKMT_DESTROYALLOCATION DdiDealloc;
- DdiDealloc.hDevice = pBuffer->pHgsmi->Device.hDevice;
+ DdiDealloc.hDevice = pPrivate->Device.hDevice;
DdiDealloc.hResource = NULL;
- DdiDealloc.phAllocationList = &pBuffer->BasePrivate.hAllocation;
+ DdiDealloc.phAllocationList = &pBuffer->hAllocation;
DdiDealloc.AllocationCount = 1;
- NTSTATUS Status = pBuffer->pHgsmi->Callbacks.pfnD3DKMTDestroyAllocation(&DdiDealloc);
+ NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTDestroyAllocation(&DdiDealloc);
if (NT_SUCCESS(Status))
{
- if (pBuffer->BasePrivate.hSynch)
- CloseHandle(pBuffer->BasePrivate.hSynch);
RTMemFree(pBuffer);
return VINF_SUCCESS;
}
@@ -62,27 +53,28 @@ DECLCALLBACK(int) vboxUhgsmiKmtBufferDestroy(PVBOXUHGSMI_BUFFER pBuf)
DECLCALLBACK(int) vboxUhgsmiKmtBufferLock(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock, uint32_t cbLock, VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags, void**pvLock)
{
- PVBOXUHGSMI_BUFFER_PRIVATE_KMT pBuffer = VBOXUHGSMIKMT_GET_BUFFER(pBuf);
+ PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuffer = VBOXUHGSMDXALLOCBASE_GET_BUFFER(pBuf);
+ PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pBuffer->BasePrivate.pHgsmi);
D3DKMT_LOCK DdiLock = {0};
- DdiLock.hDevice = pBuffer->pHgsmi->Device.hDevice;
- DdiLock.hAllocation = pBuffer->BasePrivate.hAllocation;
+ DdiLock.hDevice = pPrivate->Device.hDevice;
+ DdiLock.hAllocation = pBuffer->hAllocation;
DdiLock.PrivateDriverData = NULL;
- EnterCriticalSection(&pBuffer->CritSect);
-
- int rc = vboxUhgsmiBaseLockData(pBuf, offLock, cbLock, fFlags,
- &DdiLock.Flags, &DdiLock.NumPages, pBuffer->aLockPageIndices);
- AssertRC(rc);
- if (RT_FAILURE(rc))
+ int rc = vboxUhgsmiBaseDxLockData(pBuffer, offLock, cbLock, fFlags,
+ &DdiLock.Flags, &DdiLock.NumPages);
+ if (!RT_SUCCESS(rc))
+ {
+ WARN(("vboxUhgsmiBaseDxLockData failed rc %d", rc));
return rc;
+ }
+
if (DdiLock.NumPages)
DdiLock.pPages = pBuffer->aLockPageIndices;
else
DdiLock.pPages = NULL;
- NTSTATUS Status = pBuffer->pHgsmi->Callbacks.pfnD3DKMTLock(&DdiLock);
- LeaveCriticalSection(&pBuffer->CritSect);
+ NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTLock(&DdiLock);
if (NT_SUCCESS(Status))
{
*pvLock = (void*)(((uint8_t*)DdiLock.pData) + (offLock & 0xfff));
@@ -98,13 +90,14 @@ DECLCALLBACK(int) vboxUhgsmiKmtBufferLock(PVBOXUHGSMI_BUFFER pBuf, uint32_t offL
DECLCALLBACK(int) vboxUhgsmiKmtBufferUnlock(PVBOXUHGSMI_BUFFER pBuf)
{
- PVBOXUHGSMI_BUFFER_PRIVATE_KMT pBuffer = VBOXUHGSMIKMT_GET_BUFFER(pBuf);
+ PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuffer = VBOXUHGSMDXALLOCBASE_GET_BUFFER(pBuf);
D3DKMT_UNLOCK DdiUnlock;
- DdiUnlock.hDevice = pBuffer->pHgsmi->Device.hDevice;
+ PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pBuffer->BasePrivate.pHgsmi);
+ DdiUnlock.hDevice = pPrivate->Device.hDevice;
DdiUnlock.NumAllocations = 1;
- DdiUnlock.phAllocations = &pBuffer->BasePrivate.hAllocation;
- NTSTATUS Status = pBuffer->pHgsmi->Callbacks.pfnD3DKMTUnlock(&DdiUnlock);
+ DdiUnlock.phAllocations = &pBuffer->hAllocation;
+ NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTUnlock(&DdiUnlock);
if (NT_SUCCESS(Status))
return VINF_SUCCESS;
else
@@ -113,16 +106,12 @@ DECLCALLBACK(int) vboxUhgsmiKmtBufferUnlock(PVBOXUHGSMI_BUFFER pBuf)
return VERR_GENERAL_FAILURE;
}
-DECLCALLBACK(int) vboxUhgsmiKmtBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType, PVBOXUHGSMI_BUFFER* ppBuf)
+DECLCALLBACK(int) vboxUhgsmiKmtBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fType, PVBOXUHGSMI_BUFFER* ppBuf)
{
- HANDLE hSynch = NULL;
if (!cbBuf)
return VERR_INVALID_PARAMETER;
- int rc = vboxUhgsmiBaseEventChkCreate(fUhgsmiType, &hSynch);
- AssertRC(rc);
- if (RT_FAILURE(rc))
- return rc;
+ int rc = VINF_SUCCESS;
cbBuf = VBOXWDDM_ROUNDBOUND(cbBuf, 0x1000);
Assert(cbBuf);
@@ -130,61 +119,48 @@ DECLCALLBACK(int) vboxUhgsmiKmtBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf,
Assert(cPages);
PVBOXUHGSMI_PRIVATE_KMT pPrivate = VBOXUHGSMIKMT_GET(pHgsmi);
- PVBOXUHGSMI_BUFFER_PRIVATE_KMT pBuf = (PVBOXUHGSMI_BUFFER_PRIVATE_KMT)RTMemAllocZ(RT_OFFSETOF(VBOXUHGSMI_BUFFER_PRIVATE_KMT, aLockPageIndices[cPages]));
- Assert(pBuf);
- if (pBuf)
+ PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE pBuf = (PVBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE)RTMemAllocZ(RT_OFFSETOF(VBOXUHGSMI_BUFFER_PRIVATE_DX_ALLOC_BASE, aLockPageIndices[cPages]));
+ if (!pBuf)
{
- struct
- {
- D3DKMT_CREATEALLOCATION DdiAlloc;
- D3DDDI_ALLOCATIONINFO DdiAllocInfo;
- VBOXWDDM_ALLOCINFO AllocInfo;
- } Buf;
- memset(&Buf, 0, sizeof (Buf));
- Buf.DdiAlloc.hDevice = pPrivate->Device.hDevice;
- Buf.DdiAlloc.NumAllocations = 1;
- Buf.DdiAlloc.pAllocationInfo = &Buf.DdiAllocInfo;
- Buf.DdiAllocInfo.pPrivateDriverData = &Buf.AllocInfo;
- Buf.DdiAllocInfo.PrivateDriverDataSize = sizeof (Buf.AllocInfo);
- Buf.AllocInfo.enmType = VBOXWDDM_ALLOC_TYPE_UMD_HGSMI_BUFFER;
- Buf.AllocInfo.cbBuffer = cbBuf;
- Buf.AllocInfo.hSynch = (uint64_t)hSynch;
- Buf.AllocInfo.fUhgsmiType = fUhgsmiType;
-
- NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTCreateAllocation(&Buf.DdiAlloc);
- if (NT_SUCCESS(Status))
- {
- InitializeCriticalSection(&pBuf->CritSect);
+ WARN(("RTMemAllocZ failed"));
+ return VERR_NO_MEMORY;
+ }
- Assert(Buf.DdiAllocInfo.hAllocation);
- pBuf->BasePrivate.Base.pfnLock = vboxUhgsmiKmtBufferLock;
- pBuf->BasePrivate.Base.pfnUnlock = vboxUhgsmiKmtBufferUnlock;
-// pBuf->Base.pfnAdjustValidDataRange = vboxUhgsmiKmtBufferAdjustValidDataRange;
- pBuf->BasePrivate.Base.pfnDestroy = vboxUhgsmiKmtBufferDestroy;
+ D3DKMT_CREATEALLOCATION DdiAlloc;
+ D3DDDI_ALLOCATIONINFO DdiAllocInfo;
+ VBOXWDDM_ALLOCINFO AllocInfo;
- pBuf->BasePrivate.Base.fType = fUhgsmiType;
- pBuf->BasePrivate.Base.cbBuffer = cbBuf;
+ memset(&DdiAlloc, 0, sizeof (DdiAlloc));
+ DdiAlloc.hDevice = pPrivate->Device.hDevice;
+ DdiAlloc.NumAllocations = 1;
+ DdiAlloc.pAllocationInfo = &DdiAllocInfo;
- pBuf->pHgsmi = pPrivate;
- pBuf->BasePrivate.hAllocation = Buf.DdiAllocInfo.hAllocation;
+ vboxUhgsmiBaseDxAllocInfoFill(&DdiAllocInfo, &AllocInfo, cbBuf, fType);
- *ppBuf = &pBuf->BasePrivate.Base;
+ NTSTATUS Status = pPrivate->Callbacks.pfnD3DKMTCreateAllocation(&DdiAlloc);
+ if (NT_SUCCESS(Status))
+ {
+ Assert(DdiAllocInfo.hAllocation);
+ pBuf->BasePrivate.Base.pfnLock = vboxUhgsmiKmtBufferLock;
+ pBuf->BasePrivate.Base.pfnUnlock = vboxUhgsmiKmtBufferUnlock;
+ pBuf->BasePrivate.Base.pfnDestroy = vboxUhgsmiKmtBufferDestroy;
- return VINF_SUCCESS;
- }
- else
- {
- WARN(("pfnD3DKMTCreateAllocation failes, Status(0x%x)", Status));
- rc = VERR_OUT_OF_RESOURCES;
- }
+ pBuf->BasePrivate.Base.fType = fType;
+ pBuf->BasePrivate.Base.cbBuffer = cbBuf;
+
+ pBuf->hAllocation = DdiAllocInfo.hAllocation;
- RTMemFree(pBuf);
+ *ppBuf = &pBuf->BasePrivate.Base;
+
+ return VINF_SUCCESS;
}
else
- rc = VERR_NO_MEMORY;
+ {
+ WARN(("pfnD3DKMTCreateAllocation failes, Status(0x%x)", Status));
+ rc = VERR_OUT_OF_RESOURCES;
+ }
- if (hSynch)
- CloseHandle(hSynch);
+ RTMemFree(pBuf);
return rc;
}
@@ -193,13 +169,15 @@ DECLCALLBACK(int) vboxUhgsmiKmtBufferSubmit(PVBOXUHGSMI pHgsmi, PVBOXUHGSMI_BUFF
{
PVBOXUHGSMI_PRIVATE_KMT pHg = VBOXUHGSMIKMT_GET(pHgsmi);
UINT cbDmaCmd = pHg->Context.CommandBufferSize;
- int rc = vboxUhgsmiBaseDmaFill(aBuffers, cBuffers,
+ int rc = vboxUhgsmiBaseDxDmaFill(aBuffers, cBuffers,
pHg->Context.pCommandBuffer, &cbDmaCmd,
pHg->Context.pAllocationList, pHg->Context.AllocationListSize,
pHg->Context.pPatchLocationList, pHg->Context.PatchLocationListSize);
- AssertRC(rc);
if (RT_FAILURE(rc))
+ {
+ WARN(("vboxUhgsmiBaseDxDmaFill failed, rc %d", rc));
return rc;
+ }
D3DKMT_RENDER DdiRender = {0};
DdiRender.hContext = pHg->Context.hContext;
@@ -227,7 +205,7 @@ DECLCALLBACK(int) vboxUhgsmiKmtBufferSubmit(PVBOXUHGSMI pHgsmi, PVBOXUHGSMI_BUFF
return VERR_GENERAL_FAILURE;
}
-#endif
+
static HRESULT vboxUhgsmiKmtEngineCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D)
{
@@ -296,20 +274,81 @@ static DECLCALLBACK(int) vboxCrHhgsmiKmtEscape(struct VBOXUHGSMI_PRIVATE_BASE *p
return VERR_GENERAL_FAILURE;
}
+static void vboxUhgsmiKmtSetupCallbacks(PVBOXUHGSMI_PRIVATE_KMT pHgsmi)
+{
+ pHgsmi->BasePrivate.Base.pfnBufferCreate = vboxUhgsmiKmtBufferCreate;
+ pHgsmi->BasePrivate.Base.pfnBufferSubmit = vboxUhgsmiKmtBufferSubmit;
+ /* no escapes (for now) */
+ pHgsmi->BasePrivate.pfnEscape = NULL;
+}
+
+static void vboxUhgsmiKmtEscSetupCallbacks(PVBOXUHGSMI_PRIVATE_KMT pHgsmi)
+{
+ vboxUhgsmiBaseInit(&pHgsmi->BasePrivate, vboxCrHhgsmiKmtEscape);
+}
+
#if 0
HRESULT vboxUhgsmiKmtCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D)
{
- vboxUhgsmiBaseInit(&pHgsmi->BasePrivate, vboxCrHhgsmiKmtEscape);
-#error "port me!"
+ vboxUhgsmiKmtSetupCallbacks(pHgsmi);
return vboxUhgsmiKmtEngineCreate(pHgsmi, bD3D);
}
-#endif
HRESULT vboxUhgsmiKmtEscCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D)
{
- vboxUhgsmiBaseInit(&pHgsmi->BasePrivate, vboxCrHhgsmiKmtEscape);
+ vboxUhgsmiKmtEscSetupCallbacks(pHgsmi);
return vboxUhgsmiKmtEngineCreate(pHgsmi, bD3D);
}
+#endif
+
+static HRESULT vboxUhgsmiKmtQueryCaps(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, uint32_t *pu32Caps)
+{
+ VBOXWDDM_QI Query;
+ D3DKMT_QUERYADAPTERINFO Info;
+ Info.hAdapter = pHgsmi->Adapter.hAdapter;
+ Info.Type = KMTQAITYPE_UMDRIVERPRIVATE;
+ Info.pPrivateDriverData = &Query;
+ Info.PrivateDriverDataSize = sizeof (Query);
+
+ NTSTATUS Status = pHgsmi->Callbacks.pfnD3DKMTQueryAdapterInfo(&Info);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("pfnD3DKMTQueryAdapterInfo failed, Status %#x", Status));
+ return Status;
+ }
+
+ if (Query.u32Version != VBOXVIDEOIF_VERSION)
+ {
+ WARN(("Version mismatch"));
+ return E_FAIL;
+ }
+
+ *pu32Caps = Query.u32VBox3DCaps;
+
+ return S_OK;
+}
+
+HRESULT vboxUhgsmiKmtCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D)
+{
+ HRESULT hr = vboxUhgsmiKmtEngineCreate(pHgsmi, bD3D);
+ if (!SUCCEEDED(hr))
+ return hr;
+
+ uint32_t u32Caps = 0;
+ hr = vboxUhgsmiKmtQueryCaps(pHgsmi, &u32Caps);
+ if (!SUCCEEDED(hr))
+ {
+ WARN(("vboxUhgsmiKmtQueryCaps failed hr %#x", hr));
+ return hr;
+ }
+
+ if (u32Caps & CR_VBOX_CAP_CMDVBVA)
+ vboxUhgsmiKmtSetupCallbacks(pHgsmi);
+ else
+ vboxUhgsmiKmtEscSetupCallbacks(pHgsmi);
+
+ return S_OK;
+}
HRESULT vboxUhgsmiKmtDestroy(PVBOXUHGSMI_PRIVATE_KMT pHgsmi)
{
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.h
index 511aec6b..357bc288 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxUhgsmiKmt.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -34,12 +34,8 @@ typedef struct VBOXUHGSMI_PRIVATE_KMT
#define VBOXUHGSMIKMT_GET_PRIVATE(_p, _t) ((_t*)(((uint8_t*)_p) - RT_OFFSETOF(_t, BasePrivate.Base)))
#define VBOXUHGSMIKMT_GET(_p) VBOXUHGSMIKMT_GET_PRIVATE(_p, VBOXUHGSMI_PRIVATE_KMT)
-#if 0
-HRESULT vboxUhgsmiKmtCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D);
-#endif
HRESULT vboxUhgsmiKmtDestroy(PVBOXUHGSMI_PRIVATE_KMT pHgsmi);
-HRESULT vboxUhgsmiKmtEscCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D);
-
+HRESULT vboxUhgsmiKmtCreate(PVBOXUHGSMI_PRIVATE_KMT pHgsmi, BOOL bD3D);
#endif /* #ifndef ___VBoxUhgsmiKmt_h__ */
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dbg/DumpD3DCaps9.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dbg/DumpD3DCaps9.cpp
index 44be1a7f..e92e4d66 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dbg/DumpD3DCaps9.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dbg/DumpD3DCaps9.cpp
@@ -14,8 +14,12 @@
#include <windows.h>
#include <d3d9types.h>
#include <d3d9caps.h>
+#include <d3d9.h>
#include <stdio.h>
+#define MAX(_v1, _v2) ((_v1) > (_v2) ? (_v1) : (_v2))
+#define MIN(_v1, _v2) ((_v1) < (_v2) ? (_v1) : (_v2))
+
#define MISSING_FLAGS(_dw1, _dw2) ((_dw2) & ((_dw1) ^ (_dw2)))
#define Log(_m) do { printf _m ; } while (0)
@@ -496,6 +500,14 @@ static void printXxxCaps(const char* pszPrefix, const char* pszSeparator, DWORD
static void diffCaps(D3DCAPS9 *pCaps1, D3DCAPS9 *pCaps2)
{
+ if (!memcmp(pCaps1, pCaps2, sizeof (D3DCAPS9)))
+ {
+ Log(("caps are identical!\n"));
+ return;
+ }
+
+ Log(("caps differ, doing detailed diff..\n"));
+
if (pCaps1->DeviceType != pCaps2->DeviceType)
{
printDeviceType("pCaps->DeviceType = ", pCaps2->DeviceType, ";\n");
@@ -560,9 +572,9 @@ static void diffCaps(D3DCAPS9 *pCaps1, D3DCAPS9 *pCaps2)
DUMP_DIFF_VAL(MaxVertexIndex, "%d");
DUMP_DIFF_VAL(MaxStreams, "%d");
DUMP_DIFF_VAL(MaxStreamStride, "%d");
- DUMP_DIFF_VAL(VertexShaderVersion, "%d");
+ DUMP_DIFF_VAL(VertexShaderVersion, "0x%x");
DUMP_DIFF_VAL(MaxVertexShaderConst, "%d");
- DUMP_DIFF_VAL(PixelShaderVersion, "%d");
+ DUMP_DIFF_VAL(PixelShaderVersion, "0x%x");
DUMP_DIFF_VAL(PixelShader1xMaxValue, "%f");
/* D3D9 */
@@ -605,19 +617,19 @@ static void diffCaps(D3DCAPS9 *pCaps1, D3DCAPS9 *pCaps2)
}
static DWORD g_aCaps1[] = {
- 0x00000001, 0x00000000, 0x00000000, 0xe00a0000,
- 0x00000320, 0x80000001, 0x00000003, 0x0059aff1,
- 0x000e6ff2, 0x077363b1, 0x000000ff, 0x00003fff,
- 0x000023ff, 0x000000ff, 0x00084208, 0x0007eccd,
+ 0x00000001, 0x00000000, 0x00020000, 0xe0000000,
+ 0x00000320, 0x80000001, 0x00000003, 0x0019aff0,
+ 0x000f4ff2, 0x07736191, 0x000000ff, 0x00003fff,
+ 0x000023ff, 0x000000ff, 0x00084208, 0x0001ecc5,
0x07030700, 0x07030700, 0x03030300, 0x0000003f,
- 0x0000003f, 0x0000001f, 0x00002000, 0x00002000,
- 0x00000800, 0x00008000, 0x00002000, 0x00000010,
+ 0x0000003f, 0x0000001f, 0x00001000, 0x00001000,
+ 0x00000100, 0x00008000, 0x00001000, 0x00000010,
0x3f800000, 0xc6000000, 0xc6000000, 0x46000000,
0x46000000, 0x00000000, 0x000001ff, 0x00100008,
- 0x03feffff, 0x00000008, 0x00000008, 0x0000003b,
- 0x00000008, 0x00000006, 0x00000001, 0x00000000,
- 0x427c0000, 0x000fffff, 0x000fffff, 0x00000010,
- 0x00000400, 0xfffe0200, 0x00000100, 0xffff0200,
+ 0x03feffff, 0x00000008, 0x00000008, 0x0000013b,
+ 0x00000008, 0x00000006, 0x00000000, 0x00000000,
+ 0x437f0000, 0x000fffff, 0x000fffff, 0x00000010,
+ 0x00000400, 0xfffe0200, 0x00000080, 0xffff0200,
0x41000000, 0x00000051, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000001, 0x0000030f,
0x00000001, 0x03000300, 0x00000000, 0x00000018,
@@ -628,41 +640,438 @@ static DWORD g_aCaps1[] = {
static DWORD g_aCaps2[] = {
- 0x00000001, 0x00000000, 0x00020000, 0xe00a0000,
- 0x00000320, 0x80000001, 0x00000003, 0x0059aff1,
- 0x000e6ff2, 0x077263b1, 0x000000ff, 0x00003fff,
- 0x000023ff, 0x000000ff, 0x00084208, 0x0007eccd,
- 0x07030700, 0x07030700, 0x03030300, 0x0000003f,
- 0x0000003f, 0x0000001f, 0x00002000, 0x00002000,
- 0x00002000, 0x00008000, 0x00002000, 0x00000010,
- 0x3f800000, 0xc6000000, 0xc6000000, 0x46000000,
- 0x46000000, 0x00000000, 0x000001ff, 0x00100008,
- 0x03feffff, 0x00000008, 0x00000008, 0x0000003b,
- 0x00000008, 0x00000008, 0x00000001, 0x00000000,
- 0x46000000, 0x000fffff, 0x000fffff, 0x00000010,
- 0x00000400, 0xfffe0300, 0x00000100, 0xffff0300,
+ 0x00000001, 0x00000000, 0x00000000, 0x60020000,
+ 0x00000320, 0x80000001, 0x00000003, 0x0019aff0,
+ 0x000a0ff2, 0x07332191, 0x000000ff, 0x00003fff,
+ 0x000023ff, 0x000000ff, 0x00084208, 0x0001ec85,
+ 0x07030700, 0x07030700, 0x03030300, 0x0000001f,
+ 0x0000001f, 0x0000001f, 0x00001000, 0x00001000,
+ 0x00000100, 0x00008000, 0x00001000, 0x00000010,
+ 0x3f800000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x000001ff, 0x00100008,
+ 0x03feffff, 0x00000008, 0x00000008, 0x0000013b,
+ 0x00000008, 0x00000006, 0x00000000, 0x00000000,
+ 0x437f0000, 0x000fffff, 0x000fffff, 0x00000010,
+ 0x00000400, 0xfffe0200, 0x00000080, 0xffff0200,
0x41000000, 0x00000051, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000001, 0x0000030f,
- 0x00000001, 0x03000300, 0x00000001, 0x00000018,
- 0x00000020, 0x00000004, 0x0000001f, 0x00000018,
- 0x00000020, 0x00000004, 0x00000200, 0x01000100,
- 0x0000ffff, 0x0000ffff, 0x00008000, 0x00008000
+ 0x00000000, 0x00000000, 0x00000001, 0x0000000f,
+ 0x00000001, 0x03000300, 0x00000000, 0x00000000,
+ 0x0000001f, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000100, 0x00000000, 0x00000060, 0x00000000,
+ 0x0000ffff, 0x00000200, 0x00000000, 0x00000000
};
+
+/* ogl stuff */
+static const char * strNext(const char * pcszStr)
+{
+ pcszStr = strchr(pcszStr, ' ');
+ if (!pcszStr)
+ return NULL;
+
+ do
+ {
+ ++pcszStr;
+ if (*pcszStr == '\0')
+ return NULL;
+ else if (*pcszStr != ' ')
+ return pcszStr;
+ } while (1);
+
+ Log(("WARNING: should NOT be here!\n"));
+ return NULL;
+}
+
+static int strLength(const char * pcszStr, char sep)
+{
+ if (sep == '\0')
+ return (int)strlen(pcszStr);
+ const char * pcszNext = strchr(pcszStr, sep);
+ if (pcszNext)
+ return (int)(pcszNext - pcszStr);
+ return (int)strlen(pcszStr);
+}
+
+static int strCmp(const char * pcszStr1, const char * pcszStr2, char sep)
+{
+ if (sep == '\0')
+ return strcmp(pcszStr1, pcszStr2);
+
+ int cStr1 = strLength(pcszStr1, sep);
+ int cStr2 = strLength(pcszStr2, sep);
+ int iCmp = strncmp(pcszStr1, pcszStr2, MIN(cStr1, cStr2));
+ if (iCmp)
+ return iCmp;
+ return cStr1 - cStr2;
+}
+
+static char * strDupCur(const char * pcszStr, char sep)
+{
+ int cStr = strLength(pcszStr, sep);
+ char * newStr = (char *)malloc(cStr+1);
+ if (!newStr)
+ {
+ Log(("malloc failed!\n"));
+ return NULL;
+ }
+ memcpy(newStr, pcszStr, cStr);
+ newStr[cStr] = '\0';
+ return newStr;
+}
+
+static char * strDupTotal(const char * pcszStr)
+{
+ int cStr = (int)strlen(pcszStr);
+ char * newStr = (char *)malloc(cStr+1+1);
+ if (!newStr)
+ {
+ Log(("malloc failed!\n"));
+ return NULL;
+ }
+ memcpy(newStr, pcszStr, cStr);
+ newStr[cStr] = '\0';
+ newStr[cStr+1] = '\0';
+ return newStr;
+}
+
+static char * strDupSort(const char * pcszStr)
+{
+ int cStr = (int)strlen(pcszStr);
+ char * pNewStr = (char *)malloc(cStr+1+1+1);
+ if (!pNewStr)
+ {
+ Log(("malloc failed!\n"));
+ return NULL;
+ }
+ char *pCurNew = pNewStr;
+ const char *pPrevCmp = NULL;
+ const char * pCmp = "\001";
+ const char * pCur;
+ int cLength, cPrevLength;
+
+ do
+ {
+ cLength = 0;
+ for (pCur = pcszStr; pCur; pCur = strNext(pCur))
+ {
+ int cCur = strLength(pCur, ' ');
+ int cCmp = strLength(pCmp, ' ');
+ int iCmp = strncmp(pCur, pCmp, MIN(cCur, cCmp));
+ if (!iCmp)
+ iCmp = cCur - cCmp;
+ if (iCmp > 0)
+ {
+ if (!cLength)
+ {
+ pCmp = pCur;
+ cLength = cCur;
+ }
+ }
+ else if (iCmp < 0)
+ {
+ if (cLength)
+ {
+ if (pPrevCmp)
+ {
+ int iCmp = strncmp(pCur, pPrevCmp, MIN(cCur, cPrevLength));
+ if (!iCmp)
+ iCmp = cCur - cPrevLength;
+ if (iCmp > 0)
+ {
+ pCmp = pCur;
+ cLength = cCur;
+ }
+ }
+ else
+ {
+ pCmp = pCur;
+ cLength = cCur;
+ }
+ }
+ }
+ }
+
+ if (!cLength)
+ break;
+
+ pPrevCmp = pCmp;
+ cPrevLength = cLength;
+ memcpy(pCurNew, pCmp, cLength);
+ pCurNew += cLength;
+ *pCurNew = ' ';
+ ++pCurNew;
+ } while (1);
+
+ *pCurNew = '\0';
+ ++pCurNew;
+
+ return pNewStr;
+}
+
+
+#define DUMP_DIFF_STR_ADDED(_pStr) do { \
+ char * pszCopy = strDupCur(_pStr, ' '); \
+ Log(("+ %s\n", pszCopy)); \
+ if (pszCopy) free(pszCopy); \
+ } while (0)
+
+#define DUMP_DIFF_STR_REMOVED(_pStr) do { \
+ char * pszCopy = strDupCur(_pStr, ' '); \
+ Log(("- %s\n", pszCopy)); \
+ if (pszCopy) free(pszCopy); \
+ } while (0)
+
+#define DIFF_STR_ADDED(_ppStr) do { \
+ DUMP_DIFF_STR_ADDED(*(_ppStr)); \
+ *(_ppStr) = strNext(*(_ppStr)); \
+ } while (0)
+
+#define DIFF_STR_REMOVED(_ppStr) do { \
+ DUMP_DIFF_STR_REMOVED(*(_ppStr)); \
+ *(_ppStr) = strNext(*(_ppStr)); \
+ } while (0)
+
+#define DIFF_STR_MATCHED(_ppStr1, _ppStr2) do { \
+ *(_ppStr1) = strNext(*(_ppStr1)); \
+ *(_ppStr2) = strNext(*(_ppStr2)); \
+ } while (0)
+
+static void diffStrOrderedLists(const char * pcszStr1, const char * pcszStr2)
+{
+ while (pcszStr1 || pcszStr2)
+ {
+ if (pcszStr1 && pcszStr2)
+ {
+ int iCmp = strCmp(pcszStr1, pcszStr2, ' ');
+// int cStr1 = strLength(pcszStr1, ' ');
+// int cStr2 = strLength(pcszStr2, ' ');
+// int iCmp = strncmp(pcszStr1, pcszStr2, MAX(cStr1, cStr2));
+ if (iCmp > 0)
+ DIFF_STR_ADDED(&pcszStr2);
+ else if (iCmp < 0)
+ DIFF_STR_REMOVED(&pcszStr1);
+ else
+ DIFF_STR_MATCHED(&pcszStr1, &pcszStr2);
+ }
+ else if (pcszStr1)
+ DIFF_STR_REMOVED(&pcszStr1);
+ else
+ DIFF_STR_ADDED(&pcszStr2);
+ }
+}
+
+static void diffGlExts(const char * pcszExts1, const char * pcszExts2)
+{
+ pcszExts1 = strDupSort(pcszExts1);
+ pcszExts2 = strDupSort(pcszExts2);
+
+ if (!strcmp(pcszExts1, pcszExts2))
+ {
+ Log(("GL Exts identical!\n"));
+ Log(("%s\n", pcszExts1));
+ return;
+ }
+
+ Log(("%s\n", pcszExts1));
+
+ Log(("Diffing GL Exts..\n"));
+ diffStrOrderedLists(pcszExts1, pcszExts2);
+}
+
+static char *g_GlExts1 =
+ "GL_ARB_multisample GL_EXT_abgr GL_EXT_bgra GL_EXT_blend_color GL_EXT_blend_logic_op GL_EXT_blend_minmax GL_EXT_blend_subtract GL_EXT_copy_texture "
+ "GL_EXT_polygon_offset GL_EXT_subtexture GL_EXT_texture_object GL_EXT_vertex_array GL_EXT_compiled_vertex_array GL_EXT_texture GL_EXT_texture3D "
+ "GL_IBM_rasterpos_clip GL_ARB_point_parameters GL_EXT_draw_range_elements GL_EXT_packed_pixels GL_EXT_point_parameters GL_EXT_rescale_normal "
+ "GL_EXT_separate_specular_color GL_EXT_texture_edge_clamp GL_SGIS_generate_mipmap GL_SGIS_texture_border_clamp GL_SGIS_texture_edge_clamp "
+ "GL_SGIS_texture_lod GL_ARB_framebuffer_sRGB GL_ARB_multitexture GL_EXT_framebuffer_sRGB GL_IBM_multimode_draw_arrays GL_IBM_texture_mirrored_repeat "
+ "GL_ARB_texture_cube_map GL_ARB_texture_env_add GL_ARB_transpose_matrix GL_EXT_blend_func_separate GL_EXT_fog_coord GL_EXT_multi_draw_arrays "
+ "GL_EXT_secondary_color GL_EXT_texture_env_add GL_EXT_texture_filter_anisotropic GL_EXT_texture_lod_bias GL_INGR_blend_func_separate GL_NV_blend_square "
+ "GL_NV_light_max_exponent GL_NV_texgen_reflection GL_NV_texture_env_combine4 GL_SUN_multi_draw_arrays GL_ARB_texture_border_clamp GL_ARB_texture_compression GL_EXT_framebuffer_object "
+ "GL_EXT_texture_env_dot3 GL_MESA_window_pos GL_NV_packed_depth_stencil GL_NV_texture_rectangle GL_ARB_depth_texture GL_ARB_occlusion_query GL_ARB_shadow GL_ARB_texture_env_combine "
+ "GL_ARB_texture_env_crossbar GL_ARB_texture_env_dot3 GL_ARB_texture_mirrored_repeat GL_ARB_window_pos GL_EXT_stencil_two_side GL_EXT_texture_cube_map GL_NV_depth_clamp GL_APPLE_packed_pixels "
+ "GL_APPLE_vertex_array_object GL_ARB_draw_buffers GL_ARB_fragment_program GL_ARB_fragment_shader GL_ARB_shader_objects GL_ARB_vertex_program GL_ARB_vertex_shader GL_ATI_draw_buffers GL_ATI_texture_env_combine3 "
+ "GL_EXT_shadow_funcs GL_EXT_stencil_wrap GL_MESA_pack_invert GL_NV_primitive_restart GL_ARB_depth_clamp GL_ARB_fragment_program_shadow GL_ARB_half_float_pixel GL_ARB_occlusion_query2 GL_ARB_point_sprite "
+ "GL_ARB_shading_language_100 GL_ARB_sync GL_ARB_texture_non_power_of_two GL_ARB_vertex_buffer_object GL_ATI_blend_equation_separate GL_EXT_blend_equation_separate GL_OES_read_format GL_ARB_color_buffer_float "
+ "GL_ARB_pixel_buffer_object GL_ARB_texture_compression_rgtc GL_ARB_texture_rectangle GL_EXT_packed_float GL_EXT_pixel_buffer_object GL_EXT_texture_compression_rgtc GL_EXT_texture_mirror_clamp GL_EXT_texture_rectangle "
+ "GL_EXT_texture_sRGB GL_EXT_texture_shared_exponent GL_ARB_framebuffer_object GL_EXT_framebuffer_blit GL_EXT_framebuffer_multisample GL_EXT_packed_depth_stencil GL_ARB_vertex_array_object GL_ATI_separate_stencil "
+ "GL_ATI_texture_mirror_once GL_EXT_draw_buffers2 GL_EXT_draw_instanced GL_EXT_gpu_program_parameters GL_EXT_texture_env_combine GL_EXT_texture_sRGB_decode GL_EXT_timer_query GL_OES_EGL_image GL_ARB_copy_buffer "
+ "GL_ARB_draw_instanced GL_ARB_half_float_vertex GL_ARB_instanced_arrays GL_ARB_map_buffer_range GL_ARB_texture_rg GL_ARB_texture_swizzle GL_ARB_vertex_array_bgra GL_EXT_separate_shader_objects GL_EXT_texture_swizzle "
+ "GL_EXT_vertex_array_bgra GL_NV_conditional_render GL_ARB_ES2_compatibility GL_ARB_draw_elements_base_vertex GL_ARB_explicit_attrib_location GL_ARB_fragment_coord_conventions GL_ARB_provoking_vertex "
+ "GL_ARB_sampler_objects GL_ARB_shader_texture_lod GL_EXT_provoking_vertex GL_EXT_texture_snorm GL_MESA_texture_signed_rgba GL_NV_texture_barrier GL_ARB_robustness"
+ ;
+static char *g_GlExts2 = "GL_ARB_blend_func_extended GL_ARB_color_buffer_float GL_ARB_compatibility GL_ARB_copy_buffer GL_ARB_depth_buffer_float GL_ARB_depth_clamp GL_ARB_depth_texture GL_ARB_draw_buffers "
+ "GL_ARB_draw_elements_base_vertex GL_ARB_draw_instanced GL_ARB_ES2_compatibility GL_ARB_explicit_attrib_location GL_ARB_fragment_coord_conventions GL_ARB_fragment_program GL_ARB_fragment_program_shadow "
+ "GL_ARB_fragment_shader GL_ARB_framebuffer_object GL_ARB_framebuffer_sRGB GL_ARB_geometry_shader4 GL_ARB_get_program_binary GL_ARB_half_float_pixel GL_ARB_half_float_vertex GL_ARB_imaging GL_ARB_instanced_arrays "
+ "GL_ARB_map_buffer_range GL_ARB_multisample GL_ARB_multitexture GL_ARB_occlusion_query GL_ARB_occlusion_query2 GL_ARB_pixel_buffer_object GL_ARB_point_parameters GL_ARB_point_sprite GL_ARB_provoking_vertex "
+ "GL_ARB_robustness GL_ARB_sampler_objects GL_ARB_seamless_cube_map GL_ARB_separate_shader_objects GL_ARB_shader_bit_encoding GL_ARB_shader_objects GL_ARB_shading_language_100 GL_ARB_shading_language_include "
+ "GL_ARB_shadow GL_ARB_sync GL_ARB_texture_border_clamp GL_ARB_texture_buffer_object GL_ARB_texture_compression GL_ARB_texture_compression_rgtc GL_ARB_texture_cube_map GL_ARB_texture_env_add GL_ARB_texture_env_combine "
+ "GL_ARB_texture_env_crossbar GL_ARB_texture_env_dot3 GL_ARB_texture_float GL_ARB_texture_mirrored_repeat GL_ARB_texture_multisample GL_ARB_texture_non_power_of_two GL_ARB_texture_rectangle GL_ARB_texture_rg "
+ "GL_ARB_texture_rgb10_a2ui GL_ARB_texture_swizzle GL_ARB_timer_query GL_ARB_transpose_matrix GL_ARB_uniform_buffer_object GL_ARB_vertex_array_bgra GL_ARB_vertex_array_object GL_ARB_vertex_buffer_object GL_ARB_vertex_program "
+ "GL_ARB_vertex_shader GL_ARB_vertex_type_2_10_10_10_rev GL_ARB_viewport_array GL_ARB_window_pos GL_ATI_draw_buffers GL_ATI_texture_float GL_ATI_texture_mirror_once GL_S3_s3tc GL_EXT_texture_env_add GL_EXT_abgr GL_EXT_bgra "
+ "GL_EXT_bindable_uniform GL_EXT_blend_color GL_EXT_blend_equation_separate GL_EXT_blend_func_separate GL_EXT_blend_minmax GL_EXT_blend_subtract GL_EXT_compiled_vertex_array GL_EXT_Cg_shader GL_EXT_depth_bounds_test "
+ "GL_EXT_direct_state_access GL_EXT_draw_buffers2 GL_EXT_draw_instanced GL_EXT_draw_range_elements GL_EXT_fog_coord GL_EXT_framebuffer_blit GL_EXT_framebuffer_multisample GL_EXTX_framebuffer_mixed_formats "
+ "GL_EXT_framebuffer_object GL_EXT_framebuffer_sRGB GL_EXT_geometry_shader4 GL_EXT_gpu_program_parameters GL_EXT_gpu_shader4 GL_EXT_multi_draw_arrays GL_EXT_packed_depth_stencil GL_EXT_packed_float GL_EXT_packed_pixels "
+ "GL_EXT_pixel_buffer_object GL_EXT_point_parameters GL_EXT_provoking_vertex GL_EXT_rescale_normal GL_EXT_secondary_color GL_EXT_separate_shader_objects GL_EXT_separate_specular_color GL_EXT_shadow_funcs "
+ "GL_EXT_stencil_two_side GL_EXT_stencil_wrap GL_EXT_texture3D GL_EXT_texture_array GL_EXT_texture_buffer_object GL_EXT_texture_compression_dxt1 GL_EXT_texture_compression_latc GL_EXT_texture_compression_rgtc "
+ "GL_EXT_texture_compression_s3tc GL_EXT_texture_cube_map GL_EXT_texture_edge_clamp GL_EXT_texture_env_combine GL_EXT_texture_env_dot3 GL_EXT_texture_filter_anisotropic GL_EXT_texture_format_BGRA8888 GL_EXT_texture_integer "
+ "GL_EXT_texture_lod GL_EXT_texture_lod_bias GL_EXT_texture_mirror_clamp GL_EXT_texture_object GL_EXT_texture_shared_exponent GL_EXT_texture_sRGB GL_EXT_texture_swizzle GL_EXT_texture_type_2_10_10_10_REV GL_EXT_timer_query "
+ "GL_EXT_vertex_array GL_EXT_vertex_array_bgra GL_EXT_x11_sync_object GL_EXT_import_sync_object GL_IBM_rasterpos_clip GL_IBM_texture_mirrored_repeat GL_KTX_buffer_region GL_NV_alpha_test GL_NV_blend_minmax GL_NV_blend_square "
+ "GL_NV_complex_primitives GL_NV_conditional_render GL_NV_copy_depth_to_color GL_NV_copy_image GL_NV_depth_buffer_float GL_NV_depth_clamp GL_NV_explicit_multisample GL_NV_fbo_color_attachments "
+ "GL_NV_fence GL_NV_float_buffer GL_NV_fog_distance GL_NV_fragdepth GL_NV_fragment_program GL_NV_fragment_program_option GL_NV_fragment_program2 GL_NV_framebuffer_multisample_coverage GL_NV_geometry_shader4 "
+ "GL_NV_gpu_program4 GL_NV_half_float GL_NV_light_max_exponent GL_NV_multisample_coverage GL_NV_multisample_filter_hint GL_NV_occlusion_query GL_NV_packed_depth_stencil GL_NV_parameter_buffer_object "
+ "GL_NV_parameter_buffer_object2 GL_NV_path_rendering GL_NV_pixel_data_range GL_NV_point_sprite GL_NV_primitive_restart GL_NV_register_combiners GL_NV_register_combiners2 GL_NV_shader_buffer_load GL_NV_texgen_reflection "
+ "GL_NV_texture_barrier GL_NV_texture_compression_vtc GL_NV_texture_env_combine4 GL_NV_texture_expand_normal GL_NV_texture_lod_clamp GL_NV_texture_multisample GL_NV_texture_rectangle GL_NV_texture_shader GL_NV_texture_shader2 "
+ "GL_NV_texture_shader3 GL_NV_transform_feedback GL_NV_vdpau_interop GL_NV_vertex_array_range GL_NV_vertex_array_range2 GL_NV_vertex_buffer_unified_memory GL_NV_vertex_program GL_NV_vertex_program1_1 GL_NV_vertex_program2 "
+ "GL_NV_vertex_program2_option GL_NV_vertex_program3 GL_NVX_conditional_render GL_NVX_gpu_memory_info GL_OES_depth24 GL_OES_depth32 GL_OES_depth_texture GL_OES_element_index_uint GL_OES_fbo_render_mipmap "
+ "GL_OES_get_program_binary GL_OES_mapbuffer GL_OES_packed_depth_stencil GL_OES_rgb8_rgba8 GL_OES_standard_derivatives GL_OES_texture_3D GL_OES_texture_float GL_OES_texture_float_linear GL_OES_texture_half_float "
+ "GL_OES_texture_half_float_linear GL_OES_texture_npot GL_OES_vertex_array_object GL_OES_vertex_half_float GL_SGIS_generate_mipmap GL_SGIS_texture_lod GL_SGIX_depth_texture GL_SGIX_shadow GL_SUN_slice_accum";
+
+typedef enum
+{
+ D3DCAPSSOURCE_TYPE_UNDEFINED = 0,
+ D3DCAPSSOURCE_TYPE_EMBEDDED1,
+ D3DCAPSSOURCE_TYPE_EMBEDDED2,
+ D3DCAPSSOURCE_TYPE_NULL,
+ D3DCAPSSOURCE_TYPE_LOCAL,
+ D3DCAPSSOURCE_TYPE_FILE,
+ D3DCAPSSOURCE_TYPE_NONE
+} D3DCAPSSOURCE_TYPE;
+
+static D3DCAPS9* selectCaps(D3DCAPS9 *pLocalStorage, D3DCAPS9 *pLocalEmbedded1, D3DCAPS9 *pLocalEmbedded2, D3DCAPSSOURCE_TYPE enmCapsType)
+{
+ switch (enmCapsType)
+ {
+ case D3DCAPSSOURCE_TYPE_EMBEDDED1:
+ return pLocalEmbedded1;
+ case D3DCAPSSOURCE_TYPE_EMBEDDED2:
+ return pLocalEmbedded2;
+ case D3DCAPSSOURCE_TYPE_NULL:
+ memset (pLocalStorage, 0, sizeof (*pLocalStorage));
+ return pLocalStorage;
+ case D3DCAPSSOURCE_TYPE_LOCAL:
+ {
+ LPDIRECT3D9EX pD3D = NULL;
+ HRESULT hr = Direct3DCreate9Ex(D3D_SDK_VERSION, &pD3D);
+ if (FAILED(hr))
+ {
+ Log(("Direct3DCreate9Ex failed hr 0x%x\n", hr));
+ return NULL;
+ }
+
+ memset (pLocalStorage, 0, sizeof (*pLocalStorage));
+
+ hr = pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, pLocalStorage);
+
+ pD3D->Release();
+
+ if (FAILED(hr))
+ {
+ Log(("GetDeviceCaps failed hr 0x%x\n", hr));
+ return NULL;
+ }
+
+ return pLocalStorage;
+ }
+ case D3DCAPSSOURCE_TYPE_FILE:
+ {
+ Log(("Loading caps from file not implemented yet!"));
+ return NULL;
+ }
+ case D3DCAPSSOURCE_TYPE_NONE:
+ return NULL;
+ default:
+ {
+ Log(("Unsupported type %d", enmCapsType));
+ return NULL;
+ }
+ }
+
+ Log(("Should not be here!"));
+ return NULL;
+}
+
+static void vboxUmdDumpDword(DWORD *pvData, DWORD cData)
+{
+ char aBuf[16*4];
+ DWORD dw1, dw2, dw3, dw4;
+ for (UINT i = 0; i < (cData & (~3)); i+=4)
+ {
+ dw1 = *pvData++;
+ dw2 = *pvData++;
+ dw3 = *pvData++;
+ dw4 = *pvData++;
+ sprintf(aBuf, "0x%08x, 0x%08x, 0x%08x, 0x%08x,\n", dw1, dw2, dw3, dw4);
+ Log(("%s", aBuf));
+ }
+
+ cData = cData % 4;
+ switch (cData)
+ {
+ case 3:
+ dw1 = *pvData++;
+ dw2 = *pvData++;
+ dw3 = *pvData++;
+ sprintf(aBuf, "0x%08x, 0x%08x, 0x%08x\n", dw1, dw2, dw3);
+ Log(("%s", aBuf));
+ break;
+ case 2:
+ dw1 = *pvData++;
+ dw2 = *pvData++;
+ sprintf(aBuf, "0x%08x, 0x%08x\n", dw1, dw2);
+ Log(("%s", aBuf));
+ break;
+ case 1:
+ dw1 = *pvData++;
+ sprintf(aBuf, "0x%8x\n", dw1);
+ Log(("%s", aBuf));
+ break;
+ default:
+ break;
+ }
+}
+
int main()
{
+ diffGlExts(g_GlExts1, g_GlExts2);
+
if (sizeof (g_aCaps1) != sizeof (D3DCAPS9))
{
- Log(("incorrect caps 1 size (%d), expected(%d)", sizeof (g_aCaps1), sizeof (D3DCAPS9)));
+ Log(("incorrect caps 1 size (%d), expected(%d)\n", sizeof (g_aCaps1), sizeof (D3DCAPS9)));
return 1;
}
if (sizeof (g_aCaps2) != sizeof (D3DCAPS9))
{
- Log(("incorrect caps 2 size (%d), expected(%d)", sizeof (g_aCaps2), sizeof (D3DCAPS9)));
+ Log(("incorrect caps 2 size (%d), expected(%d)\n", sizeof (g_aCaps2), sizeof (D3DCAPS9)));
+ return 1;
+ }
+
+ D3DCAPS9 Caps1, Caps2;
+ D3DCAPS9 *pCaps1, *pCaps2;
+ D3DCAPSSOURCE_TYPE enmCaps1 = D3DCAPSSOURCE_TYPE_EMBEDDED1;
+ D3DCAPSSOURCE_TYPE enmCaps2 = D3DCAPSSOURCE_TYPE_EMBEDDED2;
+
+ pCaps1 = selectCaps(&Caps1, (D3DCAPS9*)g_aCaps1, (D3DCAPS9*)g_aCaps2, enmCaps1);
+ if (!pCaps1)
+ {
+ Log(("Failed to select Caps1"));
return 1;
}
- diffCaps((D3DCAPS9*)g_aCaps1, (D3DCAPS9*)g_aCaps2);
+ if (D3DCAPSSOURCE_TYPE_NONE != enmCaps2)
+ {
+ pCaps2 = selectCaps(&Caps2, (D3DCAPS9*)g_aCaps1, (D3DCAPS9*)g_aCaps2, enmCaps2);
+ if (!pCaps2)
+ {
+ Log(("Failed to select Caps2"));
+ return 1;
+ }
+
+ diffCaps((D3DCAPS9*)pCaps1, (D3DCAPS9*)pCaps2);
+ }
+ else
+ {
+ vboxUmdDumpDword((DWORD*)pCaps1, sizeof (*pCaps1) / sizeof (DWORD));
+ }
return 0;
}
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dbg/tstMvWnd.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dbg/tstMvWnd.cpp
index 221e45e7..432d9bf0 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dbg/tstMvWnd.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/dbg/tstMvWnd.cpp
@@ -1,6 +1,6 @@
/* $Id: tstMvWnd.cpp $ */
/*
- * Copyright (C) 2010 Oracle Corporation
+ * Copyright (C) 2010-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDisp.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDisp.h
index d727e4ef..af369986 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDisp.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDisp.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -134,6 +134,8 @@ typedef struct _VBOXDISPDEV
#ifdef VBOX_WITH_VIDEOHWACCEL
VBOXDISPVHWAINFO vhwa; /* VHWA Info */
#endif
+
+ BOOL bBitmapCacheDisabled;
} VBOXDISPDEV, *PVBOXDISPDEV;
/* -------------------- Driver callbacks -------------------- */
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDDraw.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDDraw.cpp
index bfb3b9d3..855aca55 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDDraw.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDDraw.cpp
@@ -66,11 +66,11 @@ DWORD APIENTRY VBoxDispDDCanCreateSurface(PDD_CANCREATESURFACEDATA lpCanCreateSu
{
if(pBody->u.out.ErrInfo)
{
+ WARN(("pBody->u.out.ErrInfo = %#x", pBody->u.out.ErrInfo));
lpCanCreateSurface->ddRVal = DDERR_GENERIC;
}
else
{
- WARN(("pBody->u.out.ErrInfo = %#x", pBody->u.out.ErrInfo));
lpCanCreateSurface->ddRVal = DD_OK;
}
}
@@ -274,8 +274,9 @@ DWORD APIENTRY VBoxDispDDDestroySurface(PDD_DESTROYSURFACEDATA lpDestroySurface)
memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_DESTROY));
pBody->u.in.hSurf = pDesc->hHostHandle;
- /* we're not interested in completion, just send the command */
- VBoxDispVHWACommandSubmitAsynchAndComplete(pDev, pCmd);
+ VBoxDispVHWACommandSubmit(pDev, pCmd);
+
+ VBoxDispVHWACommandRelease(pDev, pCmd);
VBoxDispVHWASurfDescFree(pDesc);
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDriver.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDriver.cpp
index a1b61f85..a0a17ee6 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDriver.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispDriver.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -518,6 +518,14 @@ VBoxDispDrvEnablePDEV(DEVMODEW *pdm, LPWSTR pwszLogAddress, ULONG cPat, HSURF *p
}
pDev->hDriver = hDriver;
+ ULONG ulRegistryFlags = 0;
+ rc = VBoxDispMPQueryRegistryFlags(hDriver, &ulRegistryFlags);
+ if (RT_SUCCESS(rc))
+ {
+ pDev->bBitmapCacheDisabled = (ulRegistryFlags & VBOXVIDEO_REGISTRY_FLAGS_DISABLE_BITMAP_CACHE) != 0;
+ LOG(("Bitmap cache %s", pDev->bBitmapCacheDisabled? "disabled": "enabled"));
+ }
+
/* Initialize device structure and query miniport to fill device and gdi infos */
rc = VBoxDispInitDevice(pDev, pdm, &gdiInfo, &devInfo);
if (RT_FAILURE(rc))
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMini.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMini.cpp
index 018d9b77..466acd71 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMini.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMini.cpp
@@ -406,3 +406,24 @@ int VBoxDispMPUnshareVideoMemory(HANDLE hDriver, PVIDEO_SHARE_MEMORY pSMem)
LOGF_LEAVE();
return VINF_SUCCESS;
}
+
+int VBoxDispMPQueryRegistryFlags(HANDLE hDriver, ULONG *pulFlags)
+{
+ DWORD dwrc;
+ ULONG cbReturned;
+ ULONG ulInfoLevel;
+ LOGF_ENTER();
+
+ *pulFlags = 0;
+ ulInfoLevel = VBOXVIDEO_INFO_LEVEL_REGISTRY_FLAGS;
+ dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_QUERY_VBOXVIDEO_INFO, &ulInfoLevel, sizeof(DWORD),
+ pulFlags, sizeof(DWORD), &cbReturned);
+ VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);
+ VBOX_WARN_IOCTLCB_RETRC("IOCTL_VIDEO_QUERY_INFO", cbReturned, sizeof(DWORD), VERR_DEV_IO_ERROR);
+
+ if (*pulFlags != 0)
+ LogRel(("VBoxDisp: video flags 0x%08X\n", *pulFlags));
+
+ LOGF_LEAVE();
+ return VINF_SUCCESS;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMini.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMini.h
index 9df90c16..35cf5cf9 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMini.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispMini.h
@@ -38,5 +38,6 @@ int VBoxDispMPSetVisibleRegion(HANDLE hDriver, PRTRECT pRects, DWORD cRects);
int VBoxDispMPResetDevice(HANDLE hDriver);
int VBoxDispMPShareVideoMemory(HANDLE hDriver, PVIDEO_SHARE_MEMORY pSMem, PVIDEO_SHARE_MEMORY_INFORMATION pSMemInfo);
int VBoxDispMPUnshareVideoMemory(HANDLE hDriver, PVIDEO_SHARE_MEMORY pSMem);
+int VBoxDispMPQueryRegistryFlags(HANDLE hDriver, ULONG *pulFlags);
#endif /*VBOXDISPMINI_H*/
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVRDP.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVRDP.cpp
index da9c3fdc..741bdae9 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVRDP.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVRDP.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -1460,8 +1460,9 @@ void vrdpDrvBitBlt(SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ *
VRDPBCHASH hashDeleted;
int cacheResult;
- LOG(("MEMBLT."));
- if ( (psoSrc->fjBitmap & BMF_DONTCACHE) != 0
+ LOG(("MEMBLT: bitmap %dx%d.", psoSrc->sizlBitmap.cx, psoSrc->sizlBitmap.cy));
+ if ( pDev->bBitmapCacheDisabled
+ || (psoSrc->fjBitmap & BMF_DONTCACHE) != 0
|| psoSrc->iUniq == 0
/* Bitmaps with hdev == 0 seems to have different RGB layout for 16BPP modes.
* Just do not cache these bitmaps and report the dirty display area instead.
@@ -1469,6 +1470,10 @@ void vrdpDrvBitBlt(SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ *
|| ( psoSrc->hdev == 0
&& !(psoSrc->iBitmapFormat == BMF_24BPP || psoSrc->iBitmapFormat == BMF_32BPP)
)
+ /* Do not try to cache large bitmaps. The cache should be mostly used for icons, etc.
+ * Computing a bitmap hash increases CPU load. Up to 384K pixels (~620x620)
+ */
+ || psoSrc->sizlBitmap.cx * psoSrc->sizlBitmap.cy > 384 * _1K
)
{
LOG(("MEMBLT: non cacheable bitmap."));
@@ -1476,17 +1481,11 @@ void vrdpDrvBitBlt(SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ *
}
else
{
- LOG(("going to cache."));
- cacheResult = vrdpbmpCacheSurface(&pDev->vrdpCache, psoSrc, &hash, &hashDeleted);
+ LOG(("MEMBLT: going to cache."));
+ cacheResult = vrdpbmpCacheSurface(&pDev->vrdpCache, psoSrc, &hash, &hashDeleted, FALSE);
}
- LOG(("MEMBLT: cacheResult 0x%08X. trg %d,%d %dx%d src %dx%d from %d,%d",
- cacheResult,
- rclTrg.left, rclTrg.top,
- rclTrg.right - rclTrg.left,
- rclTrg.bottom - rclTrg.top,
- psoSrc->sizlBitmap.cx, psoSrc->sizlBitmap.cy,
- pptlSrc->x, pptlSrc->y));
+ LOG(("MEMBLT: cacheResult 0x%08X", cacheResult));
if (cacheResult & VRDPBMP_RC_F_DELETED)
{
@@ -1499,10 +1498,17 @@ void vrdpDrvBitBlt(SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ *
{
case VRDPBMP_RC_CACHED:
vrdpReportCachedBitmap(pDev, psoSrc, &hash);
+ LOG(("MEMBLT: cached add %dx%d",
+ psoSrc->sizlBitmap.cx, psoSrc->sizlBitmap.cy));
/* Continue and report MEMBLT order. */
case VRDPBMP_RC_ALREADY_CACHED:
vrdpReportMemBlt(pDev, &clipRects, pptlSrc, (uint8_t)rop4, &hash);
+ LOG(("MEMBLT: cached use %dx%d from %d,%d %dx%d",
+ psoSrc->sizlBitmap.cx, psoSrc->sizlBitmap.cy,
+ pptlSrc->x, pptlSrc->y,
+ rclTrg.right - rclTrg.left,
+ rclTrg.bottom - rclTrg.top));
LOG((" %08X %08X %08X %08X",
*(uint32_t *)&((uint8_t *)&hash)[0],
*(uint32_t *)&((uint8_t *)&hash)[4],
@@ -1513,7 +1519,11 @@ void vrdpDrvBitBlt(SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ *
default:
/* The surface was not cached. Fallback to dirty rects. */
- LOG(("MEMBLT: bitmap not cached."));
+ LOG(("MEMBLT: not cached %dx%d from %d,%d %dx%d",
+ psoSrc->sizlBitmap.cx, psoSrc->sizlBitmap.cy,
+ pptlSrc->x, pptlSrc->y,
+ rclTrg.right - rclTrg.left,
+ rclTrg.bottom - rclTrg.top));
VBoxDispDumpPSO(psoSrc, "psoSrc");
vrdpReportDirtyRects(pDev, &clipRects);
}
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpBmp.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpBmp.cpp
index d9ac9960..9f64770c 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpBmp.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpBmp.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -21,9 +21,16 @@
#include <VBox/RemoteDesktop/VRDEOrders.h>
/*
- * Cache has a fixed number of preallocated entries. Entries are linked in the MRU
- * list. The list contains both used and free entries. Free entries are at the end.
- * The most recently used entry is in the head.
+ * Cache has a fixed number of preallocated entries. Entries are linked in the MRU lists.
+ *
+ * A new bitmap hash is added to the "temporary" list, and the caller is told that the
+ * bitmap was not cached. If the hash is used again, then it is moved to the "cached" list.
+ * This protects against "cache, memblt, cache, memblt, ..." sequences.
+ *
+ * "Temporary" list contains free and temporary entries. Temporary entries are at the head,
+ * free entries are at the tail. New temporary entries are inserted in the head.
+ *
+ * "Cached" list contains cached entries. When a entry is used, it is moved to the head.
*
* The purpose of the cache is to answer whether the bitmap was already encountered
* before.
@@ -74,127 +81,286 @@ static BOOL bcComputeHash (const SURFOBJ *pso, VRDPBCHASH *phash)
return TRUE;
}
-/* Meves an entry to the head of MRU list. */
-static void bcMoveToHead (VRDPBC *pCache, VRDPBCENTRY *pEntry)
+static void bcRemoveFromCached(VRDPBC *pCache, VRDPBCENTRY *pEntry)
{
if (pEntry->prev)
{
- /* The entry is not yet in the head. Exclude from list. */
pEntry->prev->next = pEntry->next;
+ }
+ else
+ {
+ pCache->headCached = pEntry->next;
+ }
- if (pEntry->next)
- {
- pEntry->next->prev = pEntry->prev;
- }
- else
- {
- pCache->tail = pEntry->prev;
- }
+ if (pEntry->next)
+ {
+ pEntry->next->prev = pEntry->prev;
+ }
+ else
+ {
+ pCache->tailCached = pEntry->prev;
+ }
+}
+
+static void bcRemoveFromTmp(VRDPBC *pCache, VRDPBCENTRY *pEntry)
+{
+ if (pEntry->prev)
+ {
+ pEntry->prev->next = pEntry->next;
+ }
+ else
+ {
+ pCache->headTmp = pEntry->next;
+ }
+
+ if (pEntry->next)
+ {
+ pEntry->next->prev = pEntry->prev;
+ }
+ else
+ {
+ pCache->tailTmp = pEntry->prev;
+ }
+}
+
+static void bcInsertHeadCached(VRDPBC *pCache, VRDPBCENTRY *pEntry)
+{
+ pEntry->prev = NULL;
+ pEntry->next = pCache->headCached;
+
+ if (pCache->headCached)
+ {
+ pCache->headCached->prev = pEntry;
+ }
+ else
+ {
+ pCache->tailCached = pEntry;
+ }
+
+ pCache->headCached = pEntry;
+}
+
+static void bcInsertHeadTmp(VRDPBC *pCache, VRDPBCENTRY *pEntry)
+{
+ pEntry->prev = NULL;
+ pEntry->next = pCache->headTmp;
+
+ if (pCache->headTmp)
+ {
+ pCache->headTmp->prev = pEntry;
+ }
+ else
+ {
+ pCache->tailTmp = pEntry;
+ }
+
+ pCache->headTmp = pEntry;
+}
+
+/* Moves an entry to the head of MRU list. */
+static void bcMoveToHeadCached(VRDPBC *pCache, VRDPBCENTRY *pEntry)
+{
+ if (pEntry->prev)
+ {
+ /* The entry is not yet in the head. Exclude from list. */
+ bcRemoveFromCached(pCache, pEntry);
/* Insert the entry at the head of MRU list. */
- pEntry->prev = NULL;
- pEntry->next = pCache->head;
+ bcInsertHeadCached(pCache, pEntry);
+ }
+}
- Assert(pCache->head);
+static void bcMoveToHeadTmp(VRDPBC *pCache, VRDPBCENTRY *pEntry)
+{
+ if (pEntry->prev)
+ {
+ /* The entry is not yet in the head. Exclude from list. */
+ bcRemoveFromTmp(pCache, pEntry);
- pCache->head->prev = pEntry;
- pCache->head = pEntry;
+ /* Insert the entry at the head of MRU list. */
+ bcInsertHeadTmp(pCache, pEntry);
}
}
-/* Returns TRUE if the hash already presents in the cache.
- * Moves the found entry to the head of MRU list.
+static void bcMoveTmpToCached(VRDPBC *pCache, VRDPBCENTRY *pEntry)
+{
+ /* Remove from Tmp list. */
+ bcRemoveFromTmp(pCache, pEntry);
+
+ /* Insert the entry at the head of Cached list. */
+ bcInsertHeadCached(pCache, pEntry);
+}
+
+static void bcMoveCachedToTmp(VRDPBC *pCache, VRDPBCENTRY *pEntry)
+{
+ /* Remove from cached list. */
+ bcRemoveFromCached(pCache, pEntry);
+
+ /* Insert the entry at the head of Tmp list. */
+ bcInsertHeadTmp(pCache, pEntry);
+}
+
+
+/* Returns pointer to the entry if the hash already presents in the cache.
+ * Moves the found entry to the head of cached MRU list.
*/
-static BOOL bcFindHash (VRDPBC *pCache, const VRDPBCHASH *phash)
+static VRDPBCENTRY *bcFindHash (VRDPBC *pCache, const VRDPBCHASH *phash)
{
- /* Search the MRU list. */
- VRDPBCENTRY *pEntry = pCache->head;
+ /* Search the "Cached" MRU list. */
+ VRDPBCENTRY *pEntry = pCache->headCached;
- while (pEntry && pEntry->fUsed)
+ while (pEntry)
{
if (memcmp (&pEntry->hash, phash, sizeof (VRDPBCHASH)) == 0)
{
- /* Found the entry. Move it to the head of MRU list. */
- bcMoveToHead (pCache, pEntry);
+ /* Found the entry. Move it to the head of Cached MRU list. */
+ bcMoveToHeadCached(pCache, pEntry);
- return TRUE;
+ return pEntry;
}
pEntry = pEntry->next;
}
- return FALSE;
+ /* Search the "Temporary" MRU list. */
+ pEntry = pCache->headTmp;
+
+ while ( pEntry
+ && pEntry->u32Status != VRDP_BC_ENTRY_STATUS_EMPTY)
+ {
+ if (memcmp (&pEntry->hash, phash, sizeof (VRDPBCHASH)) == 0)
+ {
+ /* Found the entry. It will be removed from the list by the caller. */
+ return pEntry;
+ }
+
+ pEntry = pEntry->next;
+ }
+
+ return NULL;
}
-/* Returns TRUE is a entry was also deleted to nake room for new entry. */
-static BOOL bcInsertHash (VRDPBC *pCache, const VRDPBCHASH *phash, VRDPBCHASH *phashDeleted)
+/* Returns TRUE is a entry was also deleted to make room for new entry. */
+static int bcInsertHash (VRDPBC *pCache, const VRDPBCHASH *phash, VRDPBCHASH *phashDeleted, BOOL bForce)
{
- BOOL bRc = FALSE;
- VRDPBCENTRY *pEntry;
+ LOG(("bcInsertHash %p, tmp tail %p, cached tail %p.", pCache, pCache->tailTmp, pCache->tailCached));
- LOG(("insert hash cache %p, tail %p.", pCache, pCache->tail));
+ /* Get the free entry to be used. Try Tmp list, then the tail of the Cached list. */
+ VRDPBCENTRY *pEntry = pCache->tailTmp;
+
+ if (pEntry != NULL)
+ {
+ /* Insert to the head of Tmp list. */
+ bcMoveToHeadTmp(pCache, pEntry);
+ LOG(("bcInsertHash %p, use tmp tail %p.", pCache, pEntry));
+ }
+ else
+ {
+ pEntry = pCache->tailCached;
+ LOG(("bcInsertHash %p, reuse cached tail %p.", pCache, pEntry, pEntry? pEntry->u32Status: 0));
- /* Get the free entry to be used. Try tail, that should be */
- pEntry = pCache->tail;
+ if (pEntry != NULL)
+ {
+ bcMoveCachedToTmp(pCache, pEntry);
+ }
+ }
- if (pEntry == NULL)
+ if (!pEntry)
{
- return bRc;
+ LOG(("bcInsertHash %p, failed to find an entry!!!", pCache));
+ return VRDPBMP_RC_NOT_CACHED;
}
- if (pEntry->fUsed)
+ BOOL bHashDeleted;
+ if (pEntry->u32Status == VRDP_BC_ENTRY_STATUS_CACHED)
{
- /* The cache is full. Remove the tail. */
+ /* The cache is full. Remove the tail hash. */
memcpy (phashDeleted, &pEntry->hash, sizeof (VRDPBCHASH));
- bRc = TRUE;
+ bHashDeleted = TRUE;
+ }
+ else
+ {
+ bHashDeleted = FALSE;
}
- bcMoveToHead (pCache, pEntry);
-
+ /* The just inserted entry is at the head of Tmp list, so the temporary
+ * entries will be deleted when there is no room in the cache.
+ */
memcpy (&pEntry->hash, phash, sizeof (VRDPBCHASH));
- pEntry->fUsed = TRUE;
- return bRc;
+ int rc;
+ if (bForce)
+ {
+ LOG(("Force cache"));
+ bcMoveTmpToCached(pCache, pEntry);
+ pEntry->u32Status = VRDP_BC_ENTRY_STATUS_CACHED;
+ rc = VRDPBMP_RC_CACHED;
+ }
+ else
+ {
+ pEntry->u32Status = VRDP_BC_ENTRY_STATUS_TEMPORARY;
+ rc = VRDPBMP_RC_NOT_CACHED;
+ }
+
+ if (bHashDeleted)
+ {
+ rc |= VRDPBMP_RC_F_DELETED;
+ }
+
+ return rc;
}
/* Find out whether the surface already in the cache.
* Insert in the cache if not.
+ * Protection against "cache, memblt, cache, memblt, ..." sequence:
+ * first time just append the bitmap hash and mark it as "temporary";
+ * if the hash is used again, mark as cached and tell the caller to cache the bitmap;
+ * remove "temporary" entries before any other.
+ *
*/
-int vrdpbmpCacheSurface(VRDPBC *pCache, const SURFOBJ *pso, VRDPBCHASH *phash, VRDPBCHASH *phashDeleted)
+int vrdpbmpCacheSurface(VRDPBC *pCache, const SURFOBJ *pso, VRDPBCHASH *phash, VRDPBCHASH *phashDeleted, BOOL bForce)
{
- int rc;
-
VRDPBCHASH hash;
BOOL bResult = bcComputeHash (pso, &hash);
-
LOG(("vrdpbmpCacheSurface: compute hash %d.", bResult));
+
if (!bResult)
{
WARN(("MEMBLT: vrdpbmpCacheSurface: could not compute hash."));
return VRDPBMP_RC_NOT_CACHED;
}
- bResult = bcFindHash (pCache, &hash);
-
- LOG(("vrdpbmpCacheSurface: find hash %d.", bResult));
*phash = hash;
- if (bResult)
+ VRDPBCENTRY *pEntry = bcFindHash (pCache, &hash);
+ LOG(("vrdpbmpCacheSurface: find hash %d.", pEntry? pEntry->u32Status: 0));
+
+ if (pEntry)
{
- return VRDPBMP_RC_ALREADY_CACHED;
- }
+ if (pEntry->u32Status == VRDP_BC_ENTRY_STATUS_CACHED)
+ {
+ return VRDPBMP_RC_ALREADY_CACHED;
+ }
- rc = VRDPBMP_RC_CACHED;
+ /* The status must be VRDP_BC_ENTRY_STATUS_TEMPORARY here.
+ * Update it to *_CACHED.
+ */
+ if (pEntry->u32Status != VRDP_BC_ENTRY_STATUS_TEMPORARY)
+ {
+ LOG(("MEMBLT: vrdpbmpCacheSurface: unexpected status %d.", pEntry->u32Status));
+ return VRDPBMP_RC_NOT_CACHED;
+ }
- bResult = bcInsertHash (pCache, &hash, phashDeleted);
+ bcMoveTmpToCached(pCache, pEntry);
- LOG(("vrdpbmpCacheSurface: insert hash %d.", bResult));
- if (bResult)
- {
- rc |= VRDPBMP_RC_F_DELETED;
+ pEntry->u32Status = VRDP_BC_ENTRY_STATUS_CACHED;
+ return VRDPBMP_RC_CACHED;
}
+ int rc = bcInsertHash (pCache, &hash, phashDeleted, bForce);
+ LOG(("vrdpbmpCacheSurface: insert hash %x.", rc));
+
return rc;
}
@@ -205,24 +371,29 @@ void vrdpbmpReset(VRDPBC *pCache)
Assert(sizeof (VRDPBCHASH) == sizeof (VRDEBITMAPHASH));
+ LOG(("vrdpbmpReset: %p.", pCache));
+
/* Reinitialize the cache structure. */
memset(pCache, 0, sizeof (VRDPBC));
- pCache->head = &pCache->aEntries[0];
- pCache->tail = &pCache->aEntries[RT_ELEMENTS(pCache->aEntries) - 1];
+ pCache->headTmp = &pCache->aEntries[0];
+ pCache->tailTmp = &pCache->aEntries[RT_ELEMENTS(pCache->aEntries) - 1];
for (i = 0; i < RT_ELEMENTS(pCache->aEntries); i++)
{
VRDPBCENTRY *pEntry = &pCache->aEntries[i];
- if (pEntry != pCache->tail)
+ if (pEntry != pCache->tailTmp)
{
pEntry->next = &pCache->aEntries[i + 1];
}
- if (pEntry != pCache->head)
+ if (pEntry != pCache->headTmp)
{
pEntry->prev = &pCache->aEntries[i - 1];
}
}
+
+ pCache->headCached = NULL;
+ pCache->tailCached = NULL;
}
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpBmp.h b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpBmp.h
index f1e93fb4..483adf5d 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpBmp.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpBmp.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -55,22 +55,28 @@ typedef struct _VRDPBCHASH
} VRDPBCHASH;
#pragma pack ()
+#define VRDP_BC_ENTRY_STATUS_EMPTY 0
+#define VRDP_BC_ENTRY_STATUS_TEMPORARY 1
+#define VRDP_BC_ENTRY_STATUS_CACHED 2
+
typedef struct _VRDPBCENTRY
{
- bool fUsed;
struct _VRDPBCENTRY *next;
struct _VRDPBCENTRY *prev;
VRDPBCHASH hash;
+ uint32_t u32Status;
} VRDPBCENTRY;
typedef struct _VRDPBC
{
- VRDPBCENTRY *head;
- VRDPBCENTRY *tail;
+ VRDPBCENTRY *headTmp;
+ VRDPBCENTRY *tailTmp;
+ VRDPBCENTRY *headCached;
+ VRDPBCENTRY *tailCached;
VRDPBCENTRY aEntries[VRDPBMP_N_CACHED_BITMAPS];
} VRDPBC;
void vrdpbmpReset (VRDPBC *pCache);
-int vrdpbmpCacheSurface (VRDPBC *pCache, const SURFOBJ *pso, VRDPBCHASH *phash, VRDPBCHASH *phashDeleted);
+int vrdpbmpCacheSurface (VRDPBC *pCache, const SURFOBJ *pso, VRDPBCHASH *phash, VRDPBCHASH *phashDeleted, BOOL bForce);
#endif /*VBOXDISPVRDPBMP_H*/
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpTxt.cpp b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpTxt.cpp
index b7cbe084..16f10b60 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpTxt.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVrdpTxt.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/Makefile.kmk b/src/VBox/Additions/WINNT/Graphics/Video/mp/Makefile.kmk
index fa2e1fa4..9cffaf28 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/Makefile.kmk
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/Makefile.kmk
@@ -87,13 +87,9 @@ ifdef VBOX_WITH_WDDM
VBoxVideoWddm_DEFS += LOG_ENABLED
endif
VBoxVideoWddm_DEFS += LOG_TO_BACKDOOR
- ifdef VBOX_WITH_CROGL
- VBoxVideoWddm_DEFS += VBOX_WITH_CROGL
- endif
ifdef VBOX_VDMA_WITH_WATCHDOG
VBoxVideoWddm_DEFS += VBOX_VDMA_WITH_WATCHDOG
endif
-
VBoxVideoWddm_INCS += \
../../../include \
.. \
@@ -121,14 +117,18 @@ ifdef VBOX_WITH_WDDM
common/VBoxMPHGSMI.cpp \
common/VBoxMPVidModes.cpp \
$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp \
- $(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp
- if defined(VBOX_WITH_CROGL) && defined(VBOX_WDDM_WITH_CRCMD)
+ $(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/VBVABase.cpp \
+ $(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp \
+ $(PATH_ROOT)/src/VBox/GuestHost/OpenGL/util/vreg.cpp
+ if defined(VBOX_WITH_CROGL)
VBoxVideoWddm_SOURCES += \
$(PATH_ROOT)/src/VBox/GuestHost/OpenGL/packer/pack_buffer.c \
$(PATH_ROOT)/src/VBox/GuestHost/OpenGL/packer/pack_bounds.c \
+ $(PATH_ROOT)/src/VBox/GuestHost/OpenGL/packer/pack_visibleregion.c \
+ $(PATH_ROOT)/src/VBox/GuestHost/OpenGL/packer/pack_misc.c \
$(VBOX_PATH_CROGL_GENFILES)/pack_bounds_swap.c \
wddm/VBoxMPCrUtil.cpp
- VBoxVideoWddm_DEFS + VBOX_WDDM_WITH_CRCMD
+ VBoxVideoWddm_DEFS += VBOX_WITH_CROGL
endif
ifdef VBOXWDDM_WITH_VBVA
VBoxVideoWddm_SOURCES += \
@@ -172,7 +172,7 @@ ifdef VBOX_WITH_WDDM
$(PATH_SDK_$(VBOX_WINDDK_GST_W8)_LIB)/displib.lib \
$(PATH_SDK_$(VBOX_WINDDK_GST_W8)_LIB)/BufferOverflowK.lib
endif # VBOX_WITH_WDDM_W8
-
+
endif # VBOX_WITH_WDDM
#
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPCommon.cpp b/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPCommon.cpp
index 7efb22a3..7ff0edcc 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPCommon.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPCommon.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPCommon.h b/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPCommon.h
index 406d2965..6fe20d93 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPCommon.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPCommon.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -29,22 +29,19 @@ typedef bool(*PFNVIDEOIRQSYNC)(void *);
bool VBoxMPCmnSyncToVideoIRQ(PVBOXMP_COMMON pCommon, PFNVIDEOIRQSYNC pfnSync, void *pvUser);
/* Video modes related */
-#define VBOXMP_MAX_VIDEO_MODES 128
void VBoxMPCmnInitCustomVideoModes(PVBOXMP_DEVEXT pExt);
VIDEO_MODE_INFORMATION* VBoxMPCmnGetCustomVideoModeInfo(ULONG ulIndex);
-VIDEO_MODE_INFORMATION* VBoxMPCmnGetVideoModeInfo(ULONG ulIndex);
#ifdef VBOX_XPDM_MINIPORT
+VIDEO_MODE_INFORMATION* VBoxMPCmnGetVideoModeInfo(PVBOXMP_DEVEXT pExt, ULONG ulIndex);
VIDEO_MODE_INFORMATION* VBoxMPXpdmCurrentVideoMode(PVBOXMP_DEVEXT pExt);
-ULONG VBoxMPXpdmGetVideoModesCount();
+ULONG VBoxMPXpdmGetVideoModesCount(PVBOXMP_DEVEXT pExt);
void VBoxMPXpdmBuildVideoModesTable(PVBOXMP_DEVEXT pExt);
#endif
#ifdef VBOX_WDDM_MINIPORT
-void VBoxWddmInvalidateAllVideoModesInfos(PVBOXMP_DEVEXT pExt);
-void VBoxWddmInvalidateVideoModesInfo(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId);
PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateVideoModesInfoByMask(PVBOXMP_DEVEXT pExt, uint8_t *pScreenIdMask);
-PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateAllVideoModesInfos(PVBOXMP_DEVEXT pExt);
+void VBoxWddmInitVideoModes(PVBOXMP_DEVEXT pExt);
NTSTATUS VBoxWddmGetModesForResolution(VIDEO_MODE_INFORMATION *pAllModes, uint32_t cAllModes, int iSearchPreferredMode,
const D3DKMDT_2DREGION *pResolution, VIDEO_MODE_INFORMATION * pModes,
uint32_t cModes, uint32_t *pcModes, int32_t *piPreferrableMode);
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPDevExt.h b/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPDevExt.h
index 965cb528..e61818fe 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPDevExt.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPDevExt.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -30,9 +30,13 @@
#endif
#ifdef VBOX_WDDM_MINIPORT
+# ifdef VBOX_WDDM_WIN8
+extern DWORD g_VBoxDisplayOnly;
+# endif
# include "wddm/VBoxMPTypes.h"
#endif
+#define VBOXMP_MAX_VIDEO_MODES 128
typedef struct VBOXMP_COMMON
{
int cDisplays; /* Number of displays. */
@@ -60,6 +64,8 @@ typedef struct VBOXMP_COMMON
HGSMIHOSTCOMMANDCONTEXT hostCtx;
/** Context information needed to submit commands to the host. */
HGSMIGUESTCOMMANDCONTEXT guestCtx;
+
+ BOOLEAN fAnyX; /* Unrestricted horizontal resolution flag. */
} VBOXMP_COMMON, *PVBOXMP_COMMON;
typedef struct _VBOXMP_DEVEXT
@@ -71,7 +77,13 @@ typedef struct _VBOXMP_DEVEXT
struct _VBOXMP_DEVEXT *pPrimary; /* Pointer to the primary device extension. */
ULONG iDevice; /* Device index: 0 for primary, otherwise a secondary device. */
-
+ /* Standart video modes list.
+ * Additional space is reserved for a custom video mode for this guest monitor.
+ * The custom video mode index is alternating for each mode set and 2 indexes are needed for the custom mode.
+ */
+ VIDEO_MODE_INFORMATION aVideoModes[VBOXMP_MAX_VIDEO_MODES + 2];
+ /* Number of available video modes, set by VBoxMPCmnBuildVideoModesTable. */
+ uint32_t cVideoModes;
ULONG CurrentMode; /* Saved information about video modes */
ULONG CurrentModeWidth;
ULONG CurrentModeHeight;
@@ -79,6 +91,11 @@ typedef struct _VBOXMP_DEVEXT
ULONG ulFrameBufferOffset; /* The framebuffer position in the VRAM. */
ULONG ulFrameBufferSize; /* The size of the current framebuffer. */
+
+ uint8_t iInvocationCounter;
+ uint32_t Prev_xres;
+ uint32_t Prev_yres;
+ uint32_t Prev_bpp;
#endif /*VBOX_XPDM_MINIPORT*/
#ifdef VBOX_WDDM_MINIPORT
@@ -89,22 +106,37 @@ typedef struct _VBOXMP_DEVEXT
uint8_t * pvVisibleVram;
VBOXVIDEOCM_MGR CmMgr;
+ VBOXVIDEOCM_MGR SeamlessCtxMgr;
/* hgsmi allocation manager */
VBOXVIDEOCM_ALLOC_MGR AllocMgr;
VBOXVDMADDI_NODE aNodes[VBOXWDDM_NUM_NODES];
LIST_ENTRY DpcCmdQueue;
LIST_ENTRY SwapchainList3D;
/* mutex for context list operations */
- FAST_MUTEX ContextMutex;
+ KSPIN_LOCK ContextLock;
KSPIN_LOCK SynchLock;
volatile uint32_t cContexts3D;
volatile uint32_t cContexts2D;
+ volatile uint32_t cContextsDispIfResize;
volatile uint32_t cRenderFromShadowDisabledContexts;
volatile uint32_t cUnlockedVBVADisabled;
+
+ volatile uint32_t fCompletingCommands;
+
+ DWORD dwDrvCfgFlags;
/* this is examined and swicthed by DxgkDdiSubmitCommand only! */
volatile BOOLEAN fRenderToShadowDisabled;
+ BOOLEAN f3DEnabled;
+ BOOLEAN fTexPresentEnabled;
+ BOOLEAN fCmdVbvaEnabled;
+
+ uint32_t u32CrConDefaultClientID;
+
+ VBOXCMDVBVA CmdVbva;
+
VBOXMP_CRCTLCON CrCtlCon;
+ VBOXMP_CRSHGSMITRANSPORT CrHgsmiTransport;
VBOXWDDM_GLOBAL_POINTER_INFO PointerInfo;
@@ -119,7 +151,9 @@ typedef struct _VBOXMP_DEVEXT
PKTHREAD pWdThread;
KEVENT WdEvent;
#endif
-
+ BOOL bVSyncTimerEnabled;
+ volatile uint32_t fVSyncInVBlank;
+ volatile LARGE_INTEGER VSyncTime;
KTIMER VSyncTimer;
KDPC VSyncDpc;
@@ -166,7 +200,6 @@ typedef struct _VBOXMP_DEVEXT
} u;
HGSMIAREA areaDisplay; /* Entire VRAM chunk for this display device. */
- BOOLEAN fAnyX; /* Unrestricted horizontal resolution flag. */
} VBOXMP_DEVEXT, *PVBOXMP_DEVEXT;
DECLINLINE(PVBOXMP_DEVEXT) VBoxCommonToPrimaryExt(PVBOXMP_COMMON pCommon)
@@ -186,21 +219,21 @@ DECLINLINE(PVBOXMP_COMMON) VBoxCommonFromDeviceExt(PVBOXMP_DEVEXT pExt)
#ifdef VBOX_WDDM_MINIPORT
DECLINLINE(ULONG) vboxWddmVramCpuVisibleSize(PVBOXMP_DEVEXT pDevExt)
{
-#ifdef VBOXWDDM_RENDER_FROM_SHADOW
- /* all memory layout info should be initialized */
- Assert(pDevExt->aSources[0].Vbva.offVBVA);
- /* page aligned */
- Assert(!(pDevExt->aSources[0].Vbva.offVBVA & 0xfff));
-
- return (ULONG)(pDevExt->aSources[0].Vbva.offVBVA & ~0xfffULL);
-#else
+ if (pDevExt->fCmdVbvaEnabled)
+ {
+ /* all memory layout info should be initialized */
+ Assert(pDevExt->CmdVbva.Vbva.offVRAMBuffer);
+ /* page aligned */
+ Assert(!(pDevExt->CmdVbva.Vbva.offVRAMBuffer & 0xfff));
+
+ return (ULONG)(pDevExt->CmdVbva.Vbva.offVRAMBuffer & ~0xfffULL);
+ }
/* all memory layout info should be initialized */
- Assert(pDevExt->u.primary.Vdma.CmdHeap.Heap.area.offBase);
+ Assert(pDevExt->aSources[0].Vbva.Vbva.offVRAMBuffer);
/* page aligned */
- Assert(!(pDevExt->u.primary.Vdma.CmdHeap.Heap.area.offBase & 0xfff));
+ Assert(!(pDevExt->aSources[0].Vbva.Vbva.offVRAMBuffer & 0xfff));
- return pDevExt->u.primary.Vdma.CmdHeap.Heap.area.offBase & ~0xfffUL;
-#endif
+ return (ULONG)(pDevExt->aSources[0].Vbva.Vbva.offVRAMBuffer & ~0xfffULL);
}
DECLINLINE(ULONG) vboxWddmVramCpuVisibleSegmentSize(PVBOXMP_DEVEXT pDevExt)
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPHGSMI.cpp b/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPHGSMI.cpp
index 51f03f8f..608abafb 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPHGSMI.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPHGSMI.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPHGSMI.h b/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPHGSMI.h
index a607463b..6dda2c7b 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPHGSMI.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPHGSMI.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPUtils.cpp b/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPUtils.cpp
index d9d353e8..bc7c39d8 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPUtils.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPUtils.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -61,7 +61,9 @@ vboxWinVersion_t VBoxQueryWinVersion()
if(major == 6)
{
- if (minor == 2)
+ if (minor == 3)
+ s_WinVersion = WIN81;
+ else if (minor == 2)
s_WinVersion = WIN8;
else if (minor == 1)
s_WinVersion = WIN7;
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPUtils.h b/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPUtils.h
index 4e6512ca..85c711cb 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPUtils.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPUtils.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -27,6 +27,11 @@
#define LOG_GROUP LOG_GROUP_DRV_MINIPORT
#include <VBox/log.h>
#define VBOX_VIDEO_LOG_NAME "VBoxMP"
+#ifdef VBOX_WDDM_MINIPORT
+# ifndef VBOX_WDDM_MINIPORT_WITH_FLOW_LOGGING
+# define VBOX_VIDEO_LOGFLOW_LOGGER(_m) do {} while (0)
+# endif
+#endif
#include "common/VBoxVideoLog.h"
#include <iprt/err.h>
#include <iprt/assert.h>
@@ -88,7 +93,8 @@ typedef enum
WINXP = 3,
WINVISTA = 4,
WIN7 = 5,
- WIN8 = 6
+ WIN8 = 6,
+ WIN81 = 7
} vboxWinVersion_t;
RT_C_DECLS_BEGIN
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPVidModes.cpp b/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPVidModes.cpp
index 697ce0d3..445aea0d 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPVidModes.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPVidModes.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -23,22 +23,14 @@
extern "C" int __cdecl swprintf(wchar_t *, const wchar_t *, ...);
#endif
#include <wchar.h>
+#include <VBox/Hardware/VBoxVideoVBE.h>
#ifdef VBOX_WITH_WDDM
# define VBOX_WITHOUT_24BPP_MODES
#endif
/* Custom video modes which are being read from registry at driver startup. */
-static VIDEO_MODE_INFORMATION g_CustomVideoModes[64] = { 0 };
-
-/* Standart video modes list.
- * Additional space is reserved for custom video modes for 64 guest monitors.
- * The custom video mode index is alternating and 2 indexes are reserved for the last custom mode.
- */
-static VIDEO_MODE_INFORMATION g_VideoModes[VBOXMP_MAX_VIDEO_MODES + 64 + 2] = { 0 };
-
-/* Number of available video modes, set by VBoxMPCmnBuildVideoModesTable. */
-static uint32_t g_NumVideoModes = 0;
+static VIDEO_MODE_INFORMATION g_CustomVideoModes[VBOX_VIDEO_MAX_SCREENS] = { 0 };
static BOOLEAN
VBoxMPValidateVideoModeParamsGuest(PVBOXMP_DEVEXT pExt, uint32_t iDisplay, uint32_t xres, uint32_t yres, uint32_t bpp)
@@ -209,10 +201,12 @@ VIDEO_MODE_INFORMATION *VBoxMPCmnGetCustomVideoModeInfo(ULONG ulIndex)
return (ulIndex<RT_ELEMENTS(g_CustomVideoModes)) ? &g_CustomVideoModes[ulIndex] : NULL;
}
-VIDEO_MODE_INFORMATION* VBoxMPCmnGetVideoModeInfo(ULONG ulIndex)
+#ifdef VBOX_XPDM_MINIPORT
+VIDEO_MODE_INFORMATION* VBoxMPCmnGetVideoModeInfo(PVBOXMP_DEVEXT pExt, ULONG ulIndex)
{
- return (ulIndex<RT_ELEMENTS(g_VideoModes)) ? &g_VideoModes[ulIndex] : NULL;
+ return (ulIndex<RT_ELEMENTS(pExt->aVideoModes)) ? &pExt->aVideoModes[ulIndex] : NULL;
}
+#endif
static bool VBoxMPVideoModesMatch(const PVIDEO_MODE_INFORMATION pMode1, const PVIDEO_MODE_INFORMATION pMode2)
{
@@ -351,9 +345,13 @@ VBoxMPFillModesTable(PVBOXMP_DEVEXT pExt, int iDisplay, PVIDEO_MODE_INFORMATION
* For small host display resolutions, host will dislike the mode 1024x768 and above
* if the framebuffer window requires scrolling to fit the guest resolution.
* So add 1024x768 resolution for win8 guest to allow user switch to it */
- (VBoxQueryWinVersion() != WIN8 || resolutionMatrix[resIndex].xRes != 1024 || resolutionMatrix[resIndex].yRes != 768) &&
+ ( (VBoxQueryWinVersion() != WIN8 && VBoxQueryWinVersion() != WIN81)
+ || resolutionMatrix[resIndex].xRes != 1024
+ || resolutionMatrix[resIndex].yRes != 768)
+ &&
#endif
- !VBoxLikesVideoMode(iDisplay, resolutionMatrix[resIndex].xRes, resolutionMatrix[resIndex].yRes - yOffset, bitsPerPixel))
+ !VBoxLikesVideoMode(iDisplay, resolutionMatrix[resIndex].xRes,
+ resolutionMatrix[resIndex].yRes - yOffset, bitsPerPixel))
{
/* host doesn't like this mode */
continue;
@@ -414,7 +412,7 @@ VBoxMPFillModesTable(PVBOXMP_DEVEXT pExt, int iDisplay, PVIDEO_MODE_INFORMATION
LOG(("got custom mode[%u]=%ux%u:%u", curKey, xres, yres, bpp));
/* round down width to be a multiple of 8 if necessary */
- if (!pExt->fAnyX)
+ if (!VBoxCommonFromDeviceExt(pExt)->fAnyX)
{
xres &= 0xFFF8;
}
@@ -491,14 +489,41 @@ static BOOLEAN VBoxMPIsStartingUp(PVBOXMP_DEVEXT pExt, uint32_t iDisplay)
{
#ifdef VBOX_XPDM_MINIPORT
return (pExt->CurrentMode == 0);
-#elif defined(VBOX_WDDM_WIN8)
- return FALSE;
-#else /* VBOX_WDDM_MINIPORT && !VBOX_WDDM_MINIPORT */
- return (!VBoxCommonFromDeviceExt(pExt)->cDisplays
- || !pExt->aSources[iDisplay].pPrimaryAllocation);
+#else
+ VBOXWDDM_SOURCE *pSource = &pExt->aSources[iDisplay];
+ return !pSource->AllocData.SurfDesc.width || !pSource->AllocData.SurfDesc.height;
+#endif
+}
+
+#ifdef VBOX_WDDM_MINIPORT
+static const uint32_t g_aVBoxVidModesSupportedBpps[] = {
+ 32
+#ifndef VBOX_WITHOUT_24BPP_MODES
+ , 24
+#endif
+ , 16
+#ifdef VBOX_WITH_8BPP_MODES
+ , 8
#endif
+};
+DECLINLINE(BOOLEAN) VBoxMPIsSupportedBpp(uint32_t bpp)
+{
+ for (int i = 0; i < RT_ELEMENTS(g_aVBoxVidModesSupportedBpps); ++i)
+ {
+ if (bpp == g_aVBoxVidModesSupportedBpps[i])
+ return TRUE;
+ }
+ return FALSE;
}
+DECLINLINE(uint32_t) VBoxMPAdjustBpp(uint32_t bpp)
+{
+ if (VBoxMPIsSupportedBpp(bpp))
+ return bpp;
+ Assert(g_aVBoxVidModesSupportedBpps[0] == 32);
+ return g_aVBoxVidModesSupportedBpps[0];
+}
+#endif
/* Updates missing video mode params with current values,
* Checks if resulting mode is liked by the host and fits into VRAM.
* Returns TRUE if resulting mode could be used.
@@ -527,12 +552,19 @@ VBoxMPValidateVideoModeParams(PVBOXMP_DEVEXT pExt, uint32_t iDisplay, uint32_t &
: &pExt->aSources[iDisplay].AllocData;
xres = xres ? xres:pAllocData->SurfDesc.width;
yres = yres ? yres:pAllocData->SurfDesc.height;
- bpp = bpp ? bpp :pAllocData->SurfDesc.bpp;
+ /* VBox WDDM driver does not allow 24 modes since OS could choose the 24bit mode as default in that case,
+ * the pExt->aSources[iDisplay].AllocData.SurfDesc.bpp could be initially 24 though,
+ * i.e. when driver occurs the current mode on driver load via DxgkCbAcquirePostDisplayOwnership
+ * and until driver reports the supported modes
+ * This is true for Win8 Display-Only driver currently since DxgkCbAcquirePostDisplayOwnership is only used by it
+ *
+ * This is why we need to adjust the current mode bpp to the value we actually report as supported */
+ bpp = bpp ? bpp : VBoxMPAdjustBpp(pAllocData->SurfDesc.bpp);
#endif
}
/* Round down width to be a multiple of 8 if necessary */
- if (!pExt->fAnyX)
+ if (!VBoxCommonFromDeviceExt(pExt)->fAnyX)
{
xres &= 0xFFF8;
}
@@ -544,12 +576,15 @@ VBoxMPValidateVideoModeParams(PVBOXMP_DEVEXT pExt, uint32_t iDisplay, uint32_t &
}
if (!VBoxMPValidateVideoModeParamsGuest(pExt, iDisplay, xres, yres, bpp))
+ {
+ WARN(("GUEST does not like special mode %dx%d:%d for display %d", xres, yres, bpp, iDisplay));
return FALSE;
+ }
/* Check if host likes this mode */
if (!VBoxLikesVideoMode(iDisplay, xres, yres, bpp))
{
- WARN_NOBP(("host does not like special mode %dx%d:%d for display %d", xres, yres, bpp, iDisplay));
+ WARN_NOBP(("HOST does not like special mode %dx%d:%d for display %d", xres, yres, bpp, iDisplay));
return FALSE;
}
@@ -557,8 +592,14 @@ VBoxMPValidateVideoModeParams(PVBOXMP_DEVEXT pExt, uint32_t iDisplay, uint32_t &
ULONG vramSize = pExt->pPrimary->u.primary.ulMaxFrameBufferSize;
#else
ULONG vramSize = vboxWddmVramCpuVisibleSegmentSize(pExt);
- /* at least two surfaces will be needed: primary & shadow */
- vramSize /= 2 * pExt->u.primary.commonInfo.cDisplays;
+ vramSize /= pExt->u.primary.commonInfo.cDisplays;
+# ifdef VBOX_WDDM_WIN8
+ if (!g_VBoxDisplayOnly)
+# endif
+ {
+ /* at least two surfaces will be needed: primary & shadow */
+ vramSize /= 2;
+ }
#endif
/* Check that values are valid and mode fits into VRAM */
@@ -609,11 +650,13 @@ VBoxMPCheckPendingVideoMode(PVBOXMP_DEVEXT pExt, PVIDEO_MODE_INFORMATION pPendin
if (display>RT_ELEMENTS(g_CustomVideoModes))
{
/*display = RT_ELEMENTS(g_CustomVideoModes) - 1;*/
+ WARN(("VBoxQueryDisplayRequest returned invalid display number %d", display));
return FALSE;
}
}
else
{
+ LOG(("no pending request"));
return FALSE;
}
@@ -667,12 +710,12 @@ static void VBoxMPRegSaveModeInfo(PVBOXMP_DEVEXT pExt, uint32_t iDisplay, PVIDEO
#ifdef VBOX_XPDM_MINIPORT
VIDEO_MODE_INFORMATION* VBoxMPXpdmCurrentVideoMode(PVBOXMP_DEVEXT pExt)
{
- return VBoxMPCmnGetVideoModeInfo(pExt->CurrentMode - 1);
+ return VBoxMPCmnGetVideoModeInfo(pExt, pExt->CurrentMode - 1);
}
-ULONG VBoxMPXpdmGetVideoModesCount()
+ULONG VBoxMPXpdmGetVideoModesCount(PVBOXMP_DEVEXT pExt)
{
- return g_NumVideoModes;
+ return pExt->cVideoModes;
}
/* Makes a table of video modes consisting of:
@@ -683,85 +726,86 @@ ULONG VBoxMPXpdmGetVideoModesCount()
*/
void VBoxMPXpdmBuildVideoModesTable(PVBOXMP_DEVEXT pExt)
{
- uint32_t cStandartModes, cCustomModes;
+ uint32_t cStandartModes;
BOOLEAN bPending, bHaveSpecial;
VIDEO_MODE_INFORMATION specialMode;
- /* Fill table with standart modes and ones manually added to registry */
- cStandartModes = VBoxMPFillModesTable(pExt, pExt->iDevice, g_VideoModes, RT_ELEMENTS(g_VideoModes), NULL);
+ /* Fill table with standart modes and ones manually added to registry.
+ * Up to VBOXMP_MAX_VIDEO_MODES elements can be used, the rest is reserved
+ * for custom mode alternating indexes.
+ */
+ cStandartModes = VBoxMPFillModesTable(pExt, pExt->iDevice, pExt->aVideoModes, VBOXMP_MAX_VIDEO_MODES, NULL);
- /* Add custom modes for all displays to the table */
- cCustomModes = VBoxCommonFromDeviceExt(pExt)->cDisplays;
- for (uint32_t i=0; i<cCustomModes; i++)
- {
- memcpy(&g_VideoModes[cStandartModes+i], &g_CustomVideoModes[i], sizeof(VIDEO_MODE_INFORMATION));
- g_VideoModes[cStandartModes+i].ModeIndex = cStandartModes+i+1;
- }
+ /* Add custom mode for this display to the table */
+ /* Make 2 entries in the video mode table. */
+ uint32_t iModeBase = cStandartModes;
+
+ /* Take the alternating index into account. */
+ BOOLEAN bAlternativeIndex = (pExt->iInvocationCounter % 2)? TRUE: FALSE;
+
+ uint32_t iSpecialMode = iModeBase + (bAlternativeIndex? 1: 0);
+ uint32_t iStandardMode = iModeBase + (bAlternativeIndex? 0: 1);
+
+ /* Fill the special mode. */
+ memcpy(&pExt->aVideoModes[iSpecialMode], &g_CustomVideoModes[pExt->iDevice], sizeof(VIDEO_MODE_INFORMATION));
+ pExt->aVideoModes[iSpecialMode].ModeIndex = iSpecialMode + 1;
+
+ /* Wipe the other entry so it is not selected. */
+ memcpy(&pExt->aVideoModes[iStandardMode], &pExt->aVideoModes[3], sizeof(VIDEO_MODE_INFORMATION));
+ pExt->aVideoModes[iStandardMode].ModeIndex = iStandardMode + 1;
+
+ LOG(("added special mode[%d] %dx%d:%d for display %d\n",
+ iSpecialMode,
+ pExt->aVideoModes[iSpecialMode].VisScreenWidth,
+ pExt->aVideoModes[iSpecialMode].VisScreenHeight,
+ pExt->aVideoModes[iSpecialMode].BitsPerPlane,
+ pExt->iDevice));
/* Check if host wants us to switch video mode and it's for this adapter */
bPending = VBoxMPCheckPendingVideoMode(pExt, &specialMode);
bHaveSpecial = bPending && (pExt->iDevice == specialMode.ModeIndex);
+ LOG(("bPending %d, pExt->iDevice %d, specialMode.ModeIndex %d",
+ bPending, pExt->iDevice, specialMode.ModeIndex));
/* Check the startup case */
if (!bHaveSpecial && VBoxMPIsStartingUp(pExt, pExt->iDevice))
{
uint32_t xres=0, yres=0, bpp=0;
+ LOG(("Startup for screen %d", pExt->iDevice));
/* Check if we could make valid mode from values stored to registry */
if (VBoxMPValidateVideoModeParams(pExt, pExt->iDevice, xres, yres, bpp))
{
+ LOG(("Startup for screen %d validated %dx%d %d", pExt->iDevice, xres, yres, bpp));
VBoxFillVidModeInfo(&specialMode, xres, yres, bpp, 0, 0);
bHaveSpecial = TRUE;
}
}
- /* Update number of modes */
- g_NumVideoModes = cStandartModes + cCustomModes;
+ /* Update number of modes. Each display has 2 entries for alternating custom mode index. */
+ pExt->cVideoModes = cStandartModes + 2;
- if (!bHaveSpecial)
- {
- /* Just add 2 dummy modes to maintain table size. */
- memcpy(&g_VideoModes[g_NumVideoModes], &g_VideoModes[2], sizeof(VIDEO_MODE_INFORMATION));
- g_VideoModes[g_NumVideoModes].ModeIndex = g_NumVideoModes+1;
- g_NumVideoModes++;
- memcpy(&g_VideoModes[g_NumVideoModes], &g_VideoModes[2], sizeof(VIDEO_MODE_INFORMATION));
- g_VideoModes[g_NumVideoModes].ModeIndex = g_NumVideoModes+1;
- g_NumVideoModes++;
- }
- else
+ if (bHaveSpecial)
{
/* We need to alternate mode index entry for a pending mode change,
* else windows will ignore actual mode change call.
* Only alternate index if one of mode parameters changed and
* regardless of conditions always add 2 entries to the table.
*/
- static int s_InvocationCounter=0;
BOOLEAN bAlternativeIndex = FALSE;
- static uint32_t s_Prev_xres=0;
- static uint32_t s_Prev_yres=0;
- static uint32_t s_Prev_bpp=0;
- BOOLEAN bChanged = (s_Prev_xres!=specialMode.VisScreenWidth
- || s_Prev_yres!=specialMode.VisScreenHeight
- || s_Prev_bpp!=specialMode.BitsPerPlane);
- if (bChanged)
- {
- s_Prev_xres = specialMode.VisScreenWidth;
- s_Prev_yres = specialMode.VisScreenHeight;
- s_Prev_bpp = specialMode.BitsPerPlane;
- }
+ BOOLEAN bChanged = (pExt->Prev_xres!=specialMode.VisScreenWidth
+ || pExt->Prev_yres!=specialMode.VisScreenHeight
+ || pExt->Prev_bpp!=specialMode.BitsPerPlane);
- /* Make sure there's no other mode in the table with same parameters,
- * because we need windows to pick up a new video mode index otherwise
- * actual mode change wouldn't happen.
- */
- int iFoundIdx;
- uint32_t uiStart=0;
+ LOG(("prev %dx%dx%d, special %dx%dx%d",
+ pExt->Prev_xres, pExt->Prev_yres, pExt->Prev_bpp,
+ specialMode.VisScreenWidth, specialMode.VisScreenHeight, specialMode.BitsPerPlane));
- while (0 <= (iFoundIdx = VBoxMPFindVideoMode(&g_VideoModes[uiStart], g_NumVideoModes-uiStart, &specialMode)))
+ if (bChanged)
{
- memcpy(&g_VideoModes[uiStart+iFoundIdx], &g_VideoModes[2], sizeof(VIDEO_MODE_INFORMATION));
- g_VideoModes[uiStart+iFoundIdx].ModeIndex = uiStart+iFoundIdx+1;
- uiStart += iFoundIdx+1;
+ pExt->Prev_xres = specialMode.VisScreenWidth;
+ pExt->Prev_yres = specialMode.VisScreenHeight;
+ pExt->Prev_bpp = specialMode.BitsPerPlane;
}
/* Check if we need to alternate the index */
@@ -769,46 +813,34 @@ void VBoxMPXpdmBuildVideoModesTable(PVBOXMP_DEVEXT pExt)
{
if (bChanged)
{
- s_InvocationCounter++;
+ pExt->iInvocationCounter++;
}
- if (s_InvocationCounter % 2)
+ if (pExt->iInvocationCounter % 2)
{
bAlternativeIndex = TRUE;
- memcpy(&g_VideoModes[g_NumVideoModes], &g_VideoModes[2], sizeof(VIDEO_MODE_INFORMATION));
- g_VideoModes[g_NumVideoModes].ModeIndex = g_NumVideoModes+1;
- ++g_NumVideoModes;
}
}
- LOG(("add special mode[%d] %dx%d:%d for display %d (bChanged=%d, bAlretnativeIndex=%d)",
- g_NumVideoModes, specialMode.VisScreenWidth, specialMode.VisScreenHeight, specialMode.BitsPerPlane,
+ uint32_t iSpecialModeElement = cStandartModes + (bAlternativeIndex? 1: 0);
+ uint32_t iSpecialModeElementOld = cStandartModes + (bAlternativeIndex? 0: 1);
+
+ LOG(("add special mode[%d] %dx%d:%d for display %d (bChanged=%d, bAlternativeIndex=%d)",
+ iSpecialModeElement, specialMode.VisScreenWidth, specialMode.VisScreenHeight, specialMode.BitsPerPlane,
pExt->iDevice, bChanged, bAlternativeIndex));
/* Add special mode to the table
* Note: Y offset isn't used for a host-supplied modes
*/
- specialMode.ModeIndex = g_NumVideoModes+1;
- memcpy(&g_VideoModes[g_NumVideoModes], &specialMode, sizeof(VIDEO_MODE_INFORMATION));
- ++g_NumVideoModes;
+ specialMode.ModeIndex = iSpecialModeElement + 1;
+ memcpy(&pExt->aVideoModes[iSpecialModeElement], &specialMode, sizeof(VIDEO_MODE_INFORMATION));
/* Save special mode in the custom modes table */
memcpy(&g_CustomVideoModes[pExt->iDevice], &specialMode, sizeof(VIDEO_MODE_INFORMATION));
-
- /* Make sure we've added 2nd mode if necessary to maintain table size */
- if (VBoxMPIsStartingUp(pExt, pExt->iDevice))
- {
- memcpy(&g_VideoModes[g_NumVideoModes], &g_VideoModes[g_NumVideoModes-1], sizeof(VIDEO_MODE_INFORMATION));
- g_VideoModes[g_NumVideoModes].ModeIndex = g_NumVideoModes+1;
- ++g_NumVideoModes;
- }
- else if (!bAlternativeIndex)
- {
- memcpy(&g_VideoModes[g_NumVideoModes], &g_VideoModes[2], sizeof(VIDEO_MODE_INFORMATION));
- g_VideoModes[g_NumVideoModes].ModeIndex = g_NumVideoModes+1;
- ++g_NumVideoModes;
- }
+ /* Wipe the old entry so the special mode will be found in the new positions. */
+ memcpy(&pExt->aVideoModes[iSpecialModeElementOld], &pExt->aVideoModes[3], sizeof(VIDEO_MODE_INFORMATION));
+ pExt->aVideoModes[iSpecialModeElementOld].ModeIndex = iSpecialModeElementOld + 1;
/* Save special mode info to registry */
VBoxMPRegSaveModeInfo(pExt, pExt->iDevice, &specialMode);
@@ -817,13 +849,13 @@ void VBoxMPXpdmBuildVideoModesTable(PVBOXMP_DEVEXT pExt)
#if defined(LOG_ENABLED)
do
{
- LOG(("Filled %d modes", g_NumVideoModes));
+ LOG(("Filled %d modes for display %d", pExt->cVideoModes, pExt->iDevice));
- for (uint32_t i=0; i<g_NumVideoModes; ++i)
+ for (uint32_t i=0; i < pExt->cVideoModes; ++i)
{
LOG(("Mode[%2d]: %4dx%4d:%2d (idx=%d)",
- i, g_VideoModes[i].VisScreenWidth, g_VideoModes[i].VisScreenHeight,
- g_VideoModes[i].BitsPerPlane, g_VideoModes[i].ModeIndex));
+ i, pExt->aVideoModes[i].VisScreenWidth, pExt->aVideoModes[i].VisScreenHeight,
+ pExt->aVideoModes[i].BitsPerPlane, pExt->aVideoModes[i].ModeIndex));
}
} while (0);
#endif
@@ -832,6 +864,7 @@ void VBoxMPXpdmBuildVideoModesTable(PVBOXMP_DEVEXT pExt)
#ifdef VBOX_WDDM_MINIPORT
static VBOXWDDM_VIDEOMODES_INFO g_aVBoxVideoModeInfos[VBOX_VIDEO_MAX_SCREENS] = {0};
+static VBOXWDDM_VIDEOMODES_INFO g_VBoxVideoModeTmp;
bool VBoxWddmFillMode(PVBOXMP_DEVEXT pExt, uint32_t iDisplay, VIDEO_MODE_INFORMATION *pInfo, D3DDDIFORMAT enmFormat, ULONG w, ULONG h)
{
@@ -886,6 +919,7 @@ VBoxWddmBuildResolutionTable(PVIDEO_MODE_INFORMATION pModesTable, size_t tableSi
uint32_t cResolutions = 0;
*piPreferredResolution = -1;
+ *pcResolutions = 0;
for (uint32_t i=0; i<tableSize; ++i)
{
@@ -935,6 +969,7 @@ static void VBoxWddmBuildResolutionTableForModes(PVBOXWDDM_VIDEOMODES_INFO pMode
(SIZE*)((void*)pModes->aResolutions), &pModes->cResolutions, &pModes->iPreferredResolution);
Assert(pModes->aResolutions[pModes->iPreferredResolution].cx == pModes->aModes[pModes->iPreferredMode].VisScreenWidth
&& pModes->aResolutions[pModes->iPreferredResolution].cy == pModes->aModes[pModes->iPreferredMode].VisScreenHeight);
+ Assert(pModes->cModes >= pModes->cResolutions);
}
AssertCompile(sizeof (SIZE) == sizeof (D3DKMDT_2DREGION));
@@ -951,6 +986,74 @@ VBoxWddmBuildVideoModesInfo(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID
pModes->cModes = VBoxMPFillModesTable(pExt, VidPnTargetId, pModes->aModes, RT_ELEMENTS(pModes->aModes), &pModes->iPreferredMode);
Assert(pModes->cModes<=RT_ELEMENTS(pModes->aModes));
+ if (!VBoxMPIsStartingUp(pExt, VidPnTargetId))
+ {
+ /* make sure we keep the current mode to avoid mode flickering */
+ PVBOXWDDM_ALLOC_DATA pAllocData = pExt->aSources[VidPnTargetId].pPrimaryAllocation ?
+ &pExt->aSources[VidPnTargetId].pPrimaryAllocation->AllocData
+ : &pExt->aSources[VidPnTargetId].AllocData;
+ if (pModes->cModes < RT_ELEMENTS(pModes->aModes))
+ {
+ /* VBox WDDM driver does not allow 24 modes since OS could choose the 24bit mode as default in that case,
+ * the pExt->aSources[iDisplay].AllocData.SurfDesc.bpp could be initially 24 though,
+ * i.e. when driver occurs the current mode on driver load via DxgkCbAcquirePostDisplayOwnership
+ * and until driver reports the supported modes
+ * This is true for Win8 Display-Only driver currently since DxgkCbAcquirePostDisplayOwnership is only used by it
+ *
+ * This is why we check the bpp to be supported here and add the current mode to the list only in that case */
+ if (VBoxMPIsSupportedBpp(pAllocData->SurfDesc.bpp))
+ {
+ int foundIdx;
+ VBoxFillVidModeInfo(&pModes->aModes[pModes->cModes], pAllocData->SurfDesc.width, pAllocData->SurfDesc.height, pAllocData->SurfDesc.bpp, 1/*index*/, 0);
+ if ((foundIdx=VBoxMPFindVideoMode(pModes->aModes, pModes->cModes, &pModes->aModes[pModes->cModes]))>=0)
+ {
+ pModes->iPreferredMode = foundIdx;
+ }
+ else
+ {
+ pModes->iPreferredMode = pModes->cModes;
+ ++pModes->cModes;
+ }
+
+#ifdef VBOX_WITH_8BPP_MODES
+ int bytesPerPixel=1;
+#else
+ int bytesPerPixel=2;
+#endif
+ for (; bytesPerPixel<=4; bytesPerPixel++)
+ {
+ int bpp = 8*bytesPerPixel;
+
+ if (bpp == pAllocData->SurfDesc.bpp)
+ continue;
+
+ if (!VBoxMPValidateVideoModeParamsGuest(pExt, VidPnTargetId,
+ pAllocData->SurfDesc.width, pAllocData->SurfDesc.height,
+ bpp))
+ continue;
+
+ if (pModes->cModes >= RT_ELEMENTS(pModes->aModes))
+ {
+ WARN(("ran out of video modes 2"));
+ break;
+ }
+
+ VBoxFillVidModeInfo(&pModes->aModes[pModes->cModes],
+ pAllocData->SurfDesc.width, pAllocData->SurfDesc.height,
+ bpp, pModes->cModes, 0);
+ if (VBoxMPFindVideoMode(pModes->aModes, pModes->cModes, &pModes->aModes[pModes->cModes]) < 0)
+ {
+ ++pModes->cModes;
+ }
+ }
+ }
+ }
+ else
+ {
+ WARN(("ran out of video modes 1"));
+ }
+ }
+
/* Check if there's a pending display change request for this adapter */
VIDEO_MODE_INFORMATION specialMode;
if (VBoxMPCheckPendingVideoMode(pExt, &specialMode) && (specialMode.ModeIndex==VidPnTargetId))
@@ -1064,7 +1167,7 @@ VBoxWddmBuildVideoModesInfo(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID
AssertRelease(RT_ELEMENTS(pModes->aModes) > pModes->cModes); /* if not - the driver state is screwed up, @todo: better do KeBugCheckEx here */
- if (!pExt->fAnyX)
+ if (!VBoxCommonFromDeviceExt(pExt)->fAnyX)
{
paAddlModes[i].VisScreenWidth &= 0xFFF8;
}
@@ -1089,49 +1192,276 @@ VBoxWddmBuildVideoModesInfo(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID
VBoxWddmBuildResolutionTableForModes(pModes);
}
-void VBoxWddmInvalidateVideoModesInfo(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
+static void VBoxWddmInitVideoMode(PVBOXMP_DEVEXT pExt, int i)
+{
+ VBoxWddmBuildVideoModesInfo(pExt, (D3DDDI_VIDEO_PRESENT_TARGET_ID)i, &g_aVBoxVideoModeInfos[i], NULL, 0);
+}
+
+void VBoxWddmInitVideoModes(PVBOXMP_DEVEXT pExt)
+{
+ for (int i = 0; i < VBoxCommonFromDeviceExt(pExt)->cDisplays; ++i)
+ {
+ VBoxWddmInitVideoMode(pExt, i);
+ }
+}
+
+static NTSTATUS vboxWddmChildStatusReportPerform(PVBOXMP_DEVEXT pDevExt, PVBOXVDMA_CHILD_STATUS pChildStatus, D3DDDI_VIDEO_PRESENT_TARGET_ID iChild)
{
- if (VidPnTargetId != D3DDDI_ID_ALL)
+ DXGK_CHILD_STATUS DdiChildStatus;
+
+ Assert(iChild < UINT32_MAX/2);
+ Assert(iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
+
+ PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[iChild];
+
+ if ((pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_DISCONNECTED)
+ && pTarget->fConnected)
{
- if (VidPnTargetId >= RT_ELEMENTS(g_aVBoxVideoModeInfos))
+ /* report disconnected */
+ memset(&DdiChildStatus, 0, sizeof (DdiChildStatus));
+ DdiChildStatus.Type = StatusConnection;
+ DdiChildStatus.ChildUid = iChild;
+ DdiChildStatus.HotPlug.Connected = FALSE;
+
+ LOG(("Reporting DISCONNECT to child %d", DdiChildStatus.ChildUid));
+
+ NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus);
+ if (!NT_SUCCESS(Status))
{
- WARN(("VidPnTargetId (%d) must be less than (%d)", VidPnTargetId, RT_ELEMENTS(g_aVBoxVideoModeInfos)));
- return;
+ WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status));
+ return Status;
}
- g_aVBoxVideoModeInfos[VidPnTargetId].cModes = 0;
- return;
+ pTarget->fConnected = FALSE;
}
- for (UINT i = 0; i < RT_ELEMENTS(g_aVBoxVideoModeInfos); ++i)
+ if ((pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_CONNECTED)
+ && !pTarget->fConnected)
+ {
+ /* report disconnected */
+ memset(&DdiChildStatus, 0, sizeof (DdiChildStatus));
+ DdiChildStatus.Type = StatusConnection;
+ DdiChildStatus.ChildUid = iChild;
+ DdiChildStatus.HotPlug.Connected = TRUE;
+
+ LOG(("Reporting CONNECT to child %d", DdiChildStatus.ChildUid));
+
+ NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status));
+ return Status;
+ }
+ pTarget->fConnected = TRUE;
+ }
+
+ if (pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_ROTATED)
+ {
+ /* report disconnected */
+ memset(&DdiChildStatus, 0, sizeof (DdiChildStatus));
+ DdiChildStatus.Type = StatusRotation;
+ DdiChildStatus.ChildUid = iChild;
+ DdiChildStatus.Rotation.Angle = pChildStatus->u8RotationAngle;
+
+ LOG(("Reporting ROTATED to child %d", DdiChildStatus.ChildUid));
+
+ NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status));
+ return Status;
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS vboxWddmChildStatusHandleRequest(PVBOXMP_DEVEXT pDevExt, VBOXVDMACMD_CHILD_STATUS_IRQ *pBody)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ for (UINT i = 0; i < pBody->cInfos; ++i)
{
- g_aVBoxVideoModeInfos[i].cModes = 0;
+ PVBOXVDMA_CHILD_STATUS pInfo = &pBody->aInfos[i];
+ if (pBody->fFlags & VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL)
+ {
+ for (D3DDDI_VIDEO_PRESENT_TARGET_ID iChild = 0; iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++iChild)
+ {
+ Status = vboxWddmChildStatusReportPerform(pDevExt, pInfo, iChild);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("vboxWddmChildStatusReportPerform failed with Status (0x%x)", Status));
+ break;
+ }
+ }
+ }
+ else
+ {
+ Status = vboxWddmChildStatusReportPerform(pDevExt, pInfo, pInfo->iChild);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("vboxWddmChildStatusReportPerform failed with Status (0x%x)", Status));
+ break;
+ }
+ }
}
+
+ return Status;
}
-void VBoxWddmInvalidateAllVideoModesInfos(PVBOXMP_DEVEXT pExt)
+#ifdef VBOX_WDDM_MONITOR_REPLUG_IRQ
+typedef struct VBOXWDDMCHILDSTATUSCB
{
- VBoxWddmInvalidateVideoModesInfo(pExt, D3DDDI_ID_ALL);
+ PVBOXVDMACBUF_DR pDr;
+ PKEVENT pEvent;
+} VBOXWDDMCHILDSTATUSCB, *PVBOXWDDMCHILDSTATUSCB;
+
+static DECLCALLBACK(VOID) vboxWddmChildStatusReportCompletion(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext)
+{
+ /* we should be called from our DPC routine */
+ Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+ PVBOXWDDMCHILDSTATUSCB pCtx = (PVBOXWDDMCHILDSTATUSCB)pvContext;
+ PVBOXVDMACBUF_DR pDr = pCtx->pDr;
+ PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
+ VBOXVDMACMD_CHILD_STATUS_IRQ *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHILD_STATUS_IRQ);
+
+ vboxWddmChildStatusHandleRequest(pDevExt, pBody);
+
+ vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);
+
+ if (pCtx->pEvent)
+ {
+ KeSetEvent(pCtx->pEvent, 0, FALSE);
+ }
}
+#endif
-PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateVideoModesInfoByMask(PVBOXMP_DEVEXT pExt, uint8_t *pScreenIdMask)
+static NTSTATUS vboxWddmChildStatusReportReconnected(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_TARGET_ID idTarget)
{
- for (int i = 0; i < VBoxCommonFromDeviceExt(pExt)->cDisplays; ++i)
+#ifdef VBOX_WDDM_MONITOR_REPLUG_IRQ
+ NTSTATUS Status = STATUS_UNSUCCESSFUL;
+ UINT cbCmd = VBOXVDMACMD_SIZE_FROMBODYSIZE(sizeof (VBOXVDMACMD_CHILD_STATUS_IRQ));
+
+ PVBOXVDMACBUF_DR pDr = vboxVdmaCBufDrCreate(&pDevExt->u.primary.Vdma, cbCmd);
+ if (pDr)
{
- if (ASMBitTest(pScreenIdMask, i))
- VBoxWddmInvalidateVideoModesInfo(pExt, i);
+ // vboxVdmaCBufDrCreate zero initializes the pDr
+ /* the command data follows the descriptor */
+ pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR;
+ pDr->cbBuf = cbCmd;
+ pDr->rc = VERR_NOT_IMPLEMENTED;
+
+ PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
+ pHdr->enmType = VBOXVDMACMD_TYPE_CHILD_STATUS_IRQ;
+ pHdr->u32CmdSpecific = 0;
+ PVBOXVDMACMD_CHILD_STATUS_IRQ pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHILD_STATUS_IRQ);
+ pBody->cInfos = 1;
+ if (idTarget == D3DDDI_ID_ALL)
+ {
+ pBody->fFlags |= VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL;
+ }
+ pBody->aInfos[0].iChild = idTarget;
+ pBody->aInfos[0].fFlags = VBOXVDMA_CHILD_STATUS_F_DISCONNECTED | VBOXVDMA_CHILD_STATUS_F_CONNECTED;
+ /* we're going to KeWaitForSingleObject */
+ Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
+
+ PVBOXVDMADDI_CMD pDdiCmd = VBOXVDMADDI_CMD_FROM_BUF_DR(pDr);
+ VBOXWDDMCHILDSTATUSCB Ctx;
+ KEVENT Event;
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ Ctx.pDr = pDr;
+ Ctx.pEvent = &Event;
+ vboxVdmaDdiCmdInit(pDdiCmd, 0, 0, vboxWddmChildStatusReportCompletion, &Ctx);
+ /* mark command as submitted & invisible for the dx runtime since dx did not originate it */
+ vboxVdmaDdiCmdSubmittedNotDx(pDdiCmd);
+ int rc = vboxVdmaCBufDrSubmit(pDevExt, &pDevExt->u.primary.Vdma, pDr);
+ Assert(rc == VINF_SUCCESS);
+ if (RT_SUCCESS(rc))
+ {
+ Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+ Assert(Status == STATUS_SUCCESS);
+ return STATUS_SUCCESS;
+ }
+
+ Status = STATUS_UNSUCCESSFUL;
+
+ vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);
+ }
+ else
+ {
+ /* @todo: try flushing.. */
+ WARN(("vboxVdmaCBufDrCreate returned NULL"));
+ Status = STATUS_INSUFFICIENT_RESOURCES;
}
- /* ensure we have all the rest populated */
- VBoxWddmGetAllVideoModesInfos(pExt);
- return g_aVBoxVideoModeInfos;
+ return Status;
+#else
+ VBOXVDMACMD_CHILD_STATUS_IRQ Body = {0};
+ Body.cInfos = 1;
+ if (idTarget == D3DDDI_ID_ALL)
+ {
+ Body.fFlags |= VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL;
+ }
+ Body.aInfos[0].iChild = idTarget;
+ Body.aInfos[0].fFlags = VBOXVDMA_CHILD_STATUS_F_DISCONNECTED | VBOXVDMA_CHILD_STATUS_F_CONNECTED;
+ Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+ return vboxWddmChildStatusHandleRequest(pDevExt, &Body);
+#endif
}
-PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateAllVideoModesInfos(PVBOXMP_DEVEXT pExt)
+NTSTATUS vboxWddmChildStatusConnect(PVBOXMP_DEVEXT pDevExt, uint32_t iChild, BOOLEAN fConnect)
{
- VBoxWddmInvalidateAllVideoModesInfos(pExt);
+#ifdef VBOX_WDDM_MONITOR_REPLUG_IRQ
+# error "port me!"
+#else
+ Assert(iChild < (uint32_t)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
+ NTSTATUS Status = STATUS_SUCCESS;
+ VBOXVDMACMD_CHILD_STATUS_IRQ Body = {0};
+ Body.cInfos = 1;
+ Body.aInfos[0].iChild = iChild;
+ Body.aInfos[0].fFlags = fConnect ? VBOXVDMA_CHILD_STATUS_F_CONNECTED : VBOXVDMA_CHILD_STATUS_F_DISCONNECTED;
+ Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+ Status = vboxWddmChildStatusHandleRequest(pDevExt, &Body);
+ if (!NT_SUCCESS(Status))
+ WARN(("vboxWddmChildStatusHandleRequest failed Status 0x%x", Status));
+
+ return Status;
+#endif
+}
+
+void VBoxWddmUpdateVideoMode(PVBOXMP_DEVEXT pExt, int i)
+{
+ g_VBoxVideoModeTmp = g_aVBoxVideoModeInfos[i];
+
+ Assert(g_aVBoxVideoModeInfos[i].cModes);
+
+ VBoxWddmInitVideoMode(pExt, i);
+
+ if (!memcmp(&g_VBoxVideoModeTmp, &g_aVBoxVideoModeInfos[i], sizeof (g_VBoxVideoModeTmp)))
+ return;
+
+#ifdef DEBUG_misha
+ g_VBoxDbgBreakModes = 0;
+#endif
+
+#ifdef DEBUG_misha
+ LOGREL(("modes changed for target %d", i));
+#else
+ LOG(("modes changed for target %d", i));
+#endif
+ vboxWddmChildStatusReportReconnected(pExt, (D3DDDI_VIDEO_PRESENT_TARGET_ID)i);
+}
+
+PVBOXWDDM_VIDEOMODES_INFO VBoxWddmUpdateVideoModesInfoByMask(PVBOXMP_DEVEXT pExt, uint8_t *pScreenIdMask)
+{
+ for (int i = 0; i < VBoxCommonFromDeviceExt(pExt)->cDisplays; ++i)
+ {
+ if (!pScreenIdMask || ASMBitTest(pScreenIdMask, i))
+ {
+ VBoxWddmUpdateVideoMode(pExt, i);
+ }
+ }
- /* ensure we have all the rest populated */
- VBoxWddmGetAllVideoModesInfos(pExt);
return g_aVBoxVideoModeInfos;
}
@@ -1149,14 +1479,6 @@ void VBoxWddmAdjustMode(PVBOXMP_DEVEXT pExt, PVBOXWDDM_ADJUSTVIDEOMODE pMode)
PVBOXWDDM_TARGET pTarget = &pExt->aTargets[pMode->Mode.Id];
/* @todo: this info should go from the target actually */
PVBOXWDDM_SOURCE pSource = &pExt->aSources[pMode->Mode.Id];
- if (pTarget->HeightVisible /* <- active */
- && pSource->AllocData.SurfDesc.width == pMode->Mode.Width
- && pSource->AllocData.SurfDesc.height == pMode->Mode.Height
- && pSource->AllocData.SurfDesc.bpp == pMode->Mode.BitsPerPixel)
- {
- pMode->fFlags = VBOXWDDM_ADJUSTVIDEOMODE_F_CURRENT;
- return;
- }
UINT newWidth = pMode->Mode.Width;
UINT newHeight = pMode->Mode.Height;
@@ -1165,7 +1487,7 @@ void VBoxWddmAdjustMode(PVBOXMP_DEVEXT pExt, PVBOXWDDM_ADJUSTVIDEOMODE pMode)
if (!VBoxMPValidateVideoModeParams(pExt, pMode->Mode.Id, newWidth, newHeight, newBpp))
{
PVBOXWDDM_SOURCE pSource = &pExt->aSources[pMode->Mode.Id];
- pMode->fFlags = VBOXWDDM_ADJUSTVIDEOMODE_F_UNSUPPORTED;
+ pMode->fFlags |= VBOXWDDM_ADJUSTVIDEOMODE_F_UNSUPPORTED;
}
if (pMode->Mode.Width != newWidth
@@ -1186,8 +1508,7 @@ void VBoxWddmAdjustMode(PVBOXMP_DEVEXT pExt, PVBOXWDDM_ADJUSTVIDEOMODE pMode)
pMode->fFlags |= VBOXWDDM_ADJUSTVIDEOMODE_F_CURRENT;
if (pMode->fFlags & VBOXWDDM_ADJUSTVIDEOMODE_F_UNSUPPORTED)
{
- WARN(("current mode is reported as unsupported, cleaning the unsupported flag"));
- pMode->fFlags &= ~VBOXWDDM_ADJUSTVIDEOMODE_F_UNSUPPORTED;
+ WARN(("current mode is reported as unsupported"));
}
}
}
@@ -1234,49 +1555,8 @@ NTSTATUS VBoxWddmGetModesForResolution(VIDEO_MODE_INFORMATION *pAllModes, uint32
return Status;
}
-static PVBOXWDDM_VIDEOMODES_INFO vboxWddmGetVideoModesInfoInternal(PVBOXMP_DEVEXT pExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
-{
- Assert(VidPnTargetId < (D3DDDI_VIDEO_PRESENT_TARGET_ID)VBoxCommonFromDeviceExt(pExt)->cDisplays);
- if (VidPnTargetId >= (D3DDDI_VIDEO_PRESENT_TARGET_ID)VBoxCommonFromDeviceExt(pExt)->cDisplays)
- {
- return NULL;
- }
-
- PVBOXWDDM_VIDEOMODES_INFO pInfo = &g_aVBoxVideoModeInfos[VidPnTargetId];
-
- if (!pInfo->cModes)
- {
- VBoxWddmBuildVideoModesInfo(pExt, VidPnTargetId, pInfo, NULL, 0);
- Assert(pInfo->cModes);
- }
-
- return pInfo;
-}
-
-static VOID vboxWddmAddVideoModes(PVBOXMP_DEVEXT pExt, PVBOXWDDM_VIDEOMODES_INFO pDstInfo, PVBOXWDDM_VIDEOMODES_INFO pSrcInfo)
-{
- for (int i = 0; i < (int)pSrcInfo->cModes; ++i)
- {
- int foundIdx = VBoxMPFindVideoMode(pDstInfo->aModes, pDstInfo->cModes, &pSrcInfo->aModes[i]);
- if (foundIdx >= 0)
- continue;
-
- Assert(0);
- pDstInfo->aModes[pDstInfo->cModes] = pSrcInfo->aModes[i];
- ++pDstInfo->cModes;
- }
-
- VBoxWddmBuildResolutionTableForModes(pDstInfo);
-}
-
PVBOXWDDM_VIDEOMODES_INFO VBoxWddmGetAllVideoModesInfos(PVBOXMP_DEVEXT pExt)
{
- /* ensure all modes are initialized */
- for (int i = 0; i < VBoxCommonFromDeviceExt(pExt)->cDisplays; ++i)
- {
- vboxWddmGetVideoModesInfoInternal(pExt, (D3DDDI_VIDEO_PRESENT_TARGET_ID)i);
- }
-
return g_aVBoxVideoModeInfos;
}
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCm.cpp b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCm.cpp
index 7448c7b0..0335de34 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCm.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCm.cpp
@@ -71,7 +71,7 @@ typedef struct VBOXVIDEOCM_SESSION
/* event used to notify UMD about pending commands */
PKEVENT pUmEvent;
/* sync lock */
- FAST_MUTEX Mutex;
+ KSPIN_LOCK SynchLock;
/* indicates whether event signaling is needed on cmd add */
bool bEventNeeded;
} VBOXVIDEOCM_SESSION, *PVBOXVIDEOCM_SESSION;
@@ -180,8 +180,10 @@ static void vboxVideoCmCmdPostByHdr(PVBOXVIDEOCM_SESSION pSession, PVBOXVIDEOCM_
pHdr->CmdHdr.cbCmd = cbSize;
}
- Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
- ExAcquireFastMutex(&pSession->Mutex);
+ Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+
+ KIRQL OldIrql;
+ KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
InsertHeadList(&pSession->CommandsList, &pHdr->QueueList);
if (pSession->bEventNeeded)
@@ -190,7 +192,7 @@ static void vboxVideoCmCmdPostByHdr(PVBOXVIDEOCM_SESSION pSession, PVBOXVIDEOCM_
bSignalEvent = true;
}
- ExReleaseFastMutex(&pSession->Mutex);
+ KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
if (bSignalEvent)
KeSetEvent(pSession->pUmEvent, 0, FALSE);
@@ -224,7 +226,8 @@ NTSTATUS vboxVideoCmCmdVisit(PVBOXVIDEOCM_CTX pContext, BOOLEAN bEntireSession,
PLIST_ENTRY pCurEntry = NULL;
PVBOXVIDEOCM_CMD_DR pHdr;
- ExAcquireFastMutex(&pSession->Mutex);
+ KIRQL OldIrql;
+ KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
pCurEntry = pSession->CommandsList.Blink;
do
@@ -259,7 +262,7 @@ NTSTATUS vboxVideoCmCmdVisit(PVBOXVIDEOCM_CTX pContext, BOOLEAN bEntireSession,
} while (1);
- ExReleaseFastMutex(&pSession->Mutex);
+ KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
return STATUS_SUCCESS;
}
@@ -279,11 +282,20 @@ static void vboxVideoCmSessionCtxAddLocked(PVBOXVIDEOCM_SESSION pSession, PVBOXV
void vboxVideoCmSessionCtxAdd(PVBOXVIDEOCM_SESSION pSession, PVBOXVIDEOCM_CTX pContext)
{
- Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
- ExAcquireFastMutex(&pSession->Mutex);
+ Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+ KIRQL OldIrql;
+ KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
+
vboxVideoCmSessionCtxAddLocked(pSession, pContext);
- ExReleaseFastMutex(&pSession->Mutex);
+ KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
+}
+
+void vboxVideoCmSessionSignalEvent(PVBOXVIDEOCM_SESSION pSession)
+{
+ Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+ if (pSession->pUmEvent)
+ KeSetEvent(pSession->pUmEvent, 0, FALSE);
}
static void vboxVideoCmSessionDestroyLocked(PVBOXVIDEOCM_SESSION pSession)
@@ -345,8 +357,10 @@ bool vboxVideoCmSessionCtxRemoveLocked(PVBOXVIDEOCM_SESSION pSession, PVBOXVIDEO
LIST_ENTRY *pCur;
InitializeListHead(&RemainedList);
InitializeListHead(&RemainedPpList);
- Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
- ExAcquireFastMutex(&pSession->Mutex);
+ Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+ KIRQL OldIrql;
+ KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
+
pContext->pSession = NULL;
RemoveEntryList(&pContext->SessionEntry);
bDestroy = !!(IsListEmpty(&pSession->ContextList));
@@ -361,7 +375,8 @@ bool vboxVideoCmSessionCtxRemoveLocked(PVBOXVIDEOCM_SESSION pSession, PVBOXVIDEO
vboxVideoCmSessionCtxDetachCmdsLocked(&pSession->CommandsList, pContext, &RemainedList);
vboxVideoCmSessionCtxDetachCmdsLocked(&pSession->PpCommandsList, pContext, &RemainedPpList);
}
- ExReleaseFastMutex(&pSession->Mutex);
+
+ KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
for (pCur = RemainedList.Flink; pCur != &RemainedList; pCur = RemainedList.Flink)
{
@@ -392,8 +407,8 @@ NTSTATUS vboxVideoCmSessionCreateLocked(PVBOXVIDEOCM_MGR pMgr, PVBOXVIDEOCM_SESS
InitializeListHead(&pSession->CommandsList);
InitializeListHead(&pSession->PpCommandsList);
pSession->pUmEvent = pUmEvent;
- Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
- ExInitializeFastMutex(&pSession->Mutex);
+ Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+ KeInitializeSpinLock(&pSession->SynchLock);
pSession->bEventNeeded = true;
vboxVideoCmSessionCtxAddLocked(pSession, pContext);
InsertHeadList(&pMgr->SessionList, &pSession->QueueEntry);
@@ -420,44 +435,39 @@ NTSTATUS vboxVideoCmCtxAdd(PVBOXVIDEOCM_MGR pMgr, PVBOXVIDEOCM_CTX pContext, HAN
Assert(Status == STATUS_SUCCESS);
if (Status == STATUS_SUCCESS)
{
- Status = KeWaitForSingleObject(&pMgr->SynchEvent, Executive, KernelMode,
- FALSE, /* BOOLEAN Alertable */
- NULL /* PLARGE_INTEGER Timeout */
- );
- Assert(Status == STATUS_SUCCESS);
- if (Status == STATUS_SUCCESS)
+ KIRQL OldIrql;
+ KeAcquireSpinLock(&pMgr->SynchLock, &OldIrql);
+
+ bool bFound = false;
+ PVBOXVIDEOCM_SESSION pSession = NULL;
+ for (PLIST_ENTRY pEntry = pMgr->SessionList.Flink; pEntry != &pMgr->SessionList; pEntry = pEntry->Flink)
{
- bool bFound = false;
- PVBOXVIDEOCM_SESSION pSession = NULL;
- for (PLIST_ENTRY pEntry = pMgr->SessionList.Flink; pEntry != &pMgr->SessionList; pEntry = pEntry->Flink)
+ pSession = VBOXCMENTRY_2_SESSION(pEntry);
+ if (pSession->pUmEvent == pUmEvent)
{
- pSession = VBOXCMENTRY_2_SESSION(pEntry);
- if (pSession->pUmEvent == pUmEvent)
- {
- bFound = true;
- break;
- }
+ bFound = true;
+ break;
}
+ }
- pContext->u64UmData = u64UmData;
+ pContext->u64UmData = u64UmData;
- if (!bFound)
- {
- Status = vboxVideoCmSessionCreateLocked(pMgr, &pSession, pUmEvent, pContext);
- Assert(Status == STATUS_SUCCESS);
- }
- else
- {
- /* Status = */vboxVideoCmSessionCtxAdd(pSession, pContext);
- /*Assert(Status == STATUS_SUCCESS);*/
- }
- LONG tstL = KeSetEvent(&pMgr->SynchEvent, 0, FALSE);
- Assert(!tstL);
+ if (!bFound)
+ {
+ Status = vboxVideoCmSessionCreateLocked(pMgr, &pSession, pUmEvent, pContext);
+ Assert(Status == STATUS_SUCCESS);
+ }
+ else
+ {
+ /* Status = */vboxVideoCmSessionCtxAdd(pSession, pContext);
+ /*Assert(Status == STATUS_SUCCESS);*/
+ }
- if (Status == STATUS_SUCCESS)
- {
- return STATUS_SUCCESS;
- }
+ KeReleaseSpinLock(&pMgr->SynchLock, OldIrql);
+
+ if (Status == STATUS_SUCCESS)
+ {
+ return STATUS_SUCCESS;
}
ObDereferenceObject(pUmEvent);
@@ -471,24 +481,19 @@ NTSTATUS vboxVideoCmCtxRemove(PVBOXVIDEOCM_MGR pMgr, PVBOXVIDEOCM_CTX pContext)
if (!pSession)
return STATUS_SUCCESS;
- NTSTATUS Status = KeWaitForSingleObject(&pMgr->SynchEvent, Executive, KernelMode,
- FALSE, /* BOOLEAN Alertable */
- NULL /* PLARGE_INTEGER Timeout */
- );
- Assert(Status == STATUS_SUCCESS);
- if (Status == STATUS_SUCCESS)
- {
- vboxVideoCmSessionCtxRemoveLocked(pSession, pContext);
- LONG tstL = KeSetEvent(&pMgr->SynchEvent, 0, FALSE);
- Assert(!tstL);
- }
+ KIRQL OldIrql;
+ KeAcquireSpinLock(&pMgr->SynchLock, &OldIrql);
- return Status;
+ vboxVideoCmSessionCtxRemoveLocked(pSession, pContext);
+
+ KeReleaseSpinLock(&pMgr->SynchLock, OldIrql);
+
+ return STATUS_SUCCESS;
}
NTSTATUS vboxVideoCmInit(PVBOXVIDEOCM_MGR pMgr)
{
- KeInitializeEvent(&pMgr->SynchEvent, SynchronizationEvent, TRUE);
+ KeInitializeSpinLock(&pMgr->SynchLock);
InitializeListHead(&pMgr->SessionList);
return STATUS_SUCCESS;
}
@@ -499,6 +504,25 @@ NTSTATUS vboxVideoCmTerm(PVBOXVIDEOCM_MGR pMgr)
return STATUS_SUCCESS;
}
+NTSTATUS vboxVideoCmSignalEvents(PVBOXVIDEOCM_MGR pMgr)
+{
+ Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+ PVBOXVIDEOCM_SESSION pSession = NULL;
+
+ KIRQL OldIrql;
+ KeAcquireSpinLock(&pMgr->SynchLock, &OldIrql);
+
+ for (PLIST_ENTRY pEntry = pMgr->SessionList.Flink; pEntry != &pMgr->SessionList; pEntry = pEntry->Flink)
+ {
+ pSession = VBOXCMENTRY_2_SESSION(pEntry);
+ vboxVideoCmSessionSignalEvent(pSession);
+ }
+
+ KeReleaseSpinLock(&pMgr->SynchLock, OldIrql);
+
+ return STATUS_SUCCESS;
+}
+
VOID vboxVideoCmProcessKm(PVBOXVIDEOCM_CTX pContext, PVBOXVIDEOCM_CMD_CTL_KM pCmd)
{
PVBOXVIDEOCM_SESSION pSession = pContext->pSession;
@@ -514,9 +538,10 @@ VOID vboxVideoCmProcessKm(PVBOXVIDEOCM_CTX pContext, PVBOXVIDEOCM_CMD_CTL_KM pCm
case VBOXVIDEOCM_CMD_CTL_KM_TYPE_POST_INVOKE:
{
PVBOXVIDEOCM_CMD_DR pHdr = VBOXVIDEOCM_HEAD(pCmd);
- ExAcquireFastMutex(&pSession->Mutex);
+ KIRQL OldIrql;
+ KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
InsertTailList(&pSession->PpCommandsList, &pHdr->QueueList);
- ExReleaseFastMutex(&pSession->Mutex);
+ KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
break;
}
@@ -549,8 +574,9 @@ NTSTATUS vboxVideoCmEscape(PVBOXVIDEOCM_CTX pContext, PVBOXDISPIFESCAPE_GETVBOXV
InitializeListHead(&DetachedPpList);
// PVBOXWDDM_GETVBOXVIDEOCMCMD_HDR *pvCmd
- Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
- ExAcquireFastMutex(&pSession->Mutex);
+ Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+ KIRQL OldIrql;
+ KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
vboxVideoCmSessionCtxDetachCmdsLocked(&pSession->PpCommandsList, pContext, &DetachedPpList);
@@ -605,7 +631,7 @@ NTSTATUS vboxVideoCmEscape(PVBOXVIDEOCM_CTX pContext, PVBOXDISPIFESCAPE_GETVBOXV
}
} while (1);
- ExReleaseFastMutex(&pSession->Mutex);
+ KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
vboxVideoCmSessionCtxPpList(pContext, &DetachedPpList);
@@ -646,103 +672,22 @@ NTSTATUS vboxVideoCmEscape(PVBOXVIDEOCM_CTX pContext, PVBOXDISPIFESCAPE_GETVBOXV
return STATUS_SUCCESS;
}
-VOID vboxVideoCmLock(PVBOXVIDEOCM_CTX pContext)
-{
- ExAcquireFastMutex(&pContext->pSession->Mutex);
-}
-
-VOID vboxVideoCmUnlock(PVBOXVIDEOCM_CTX pContext)
-{
- ExReleaseFastMutex(&pContext->pSession->Mutex);
-}
-
static BOOLEAN vboxVideoCmHasUncompletedCmdsLocked(PVBOXVIDEOCM_MGR pMgr)
{
PVBOXVIDEOCM_SESSION pSession = NULL;
for (PLIST_ENTRY pEntry = pMgr->SessionList.Flink; pEntry != &pMgr->SessionList; pEntry = pEntry->Flink)
{
pSession = VBOXCMENTRY_2_SESSION(pEntry);
- ExAcquireFastMutex(&pSession->Mutex);
+ KIRQL OldIrql;
+ KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
+
if (pSession->bEventNeeded)
{
/* commands still being processed */
- ExReleaseFastMutex(&pSession->Mutex);
+ KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
return TRUE;
}
- ExReleaseFastMutex(&pSession->Mutex);
+ KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
}
return FALSE;
}
-
-/* waits for all outstanding commands to completed by client
- * assumptions here are:
- * 1. no new commands are submitted while we are waiting
- * 2. it is assumed that a client completes all previously received commands
- * once it queries for the new set of commands */
-NTSTATUS vboxVideoCmWaitCompletedCmds(PVBOXVIDEOCM_MGR pMgr, uint32_t msTimeout)
-{
- LARGE_INTEGER Timeout;
- PLARGE_INTEGER pTimeout;
- uint32_t cIters;
-
- if (msTimeout != RT_INDEFINITE_WAIT)
- {
- uint32_t msIter = 2;
- cIters = msTimeout/msIter;
- if (!cIters)
- {
- msIter = msTimeout;
- cIters = 1;
- }
- Timeout.QuadPart = -(int64_t) msIter /* ms */ * 10000;
- pTimeout = &Timeout;
- }
- else
- {
- pTimeout = NULL;
- cIters = 1;
- }
-
- Assert(cIters);
- do
- {
- NTSTATUS Status = KeWaitForSingleObject(&pMgr->SynchEvent, Executive, KernelMode,
- FALSE, /* BOOLEAN Alertable */
- pTimeout /* PLARGE_INTEGER Timeout */
- );
- if (Status == STATUS_TIMEOUT)
- {
- --cIters;
- }
- else
- {
- if (!NT_SUCCESS(Status))
- {
- WARN(("KeWaitForSingleObject failed with Status (0x%x)", Status));
- return Status;
- }
-
- /* succeeded */
- if (!vboxVideoCmHasUncompletedCmdsLocked(pMgr))
- {
- LONG tstL = KeSetEvent(&pMgr->SynchEvent, 0, FALSE);
- Assert(!tstL);
- return STATUS_SUCCESS;
- }
-
- LONG tstL = KeSetEvent(&pMgr->SynchEvent, 0, FALSE);
- Assert(!tstL);
- }
-
- if (!cIters)
- break;
-
- KeDelayExecutionThread(KernelMode, FALSE, pTimeout);
- --cIters;
- if (!cIters)
- break;
- } while (0);
-
- return STATUS_TIMEOUT;
-}
-
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCm.h b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCm.h
index fcf94bb9..21be672c 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCm.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCm.h
@@ -21,7 +21,7 @@
typedef struct VBOXVIDEOCM_MGR
{
- KEVENT SynchEvent;
+ KSPIN_LOCK SynchLock;
/* session list */
LIST_ENTRY SessionList;
} VBOXVIDEOCM_MGR, *PVBOXVIDEOCM_MGR;
@@ -40,6 +40,7 @@ NTSTATUS vboxVideoCmCtxAdd(PVBOXVIDEOCM_MGR pMgr, PVBOXVIDEOCM_CTX pContext, HAN
NTSTATUS vboxVideoCmCtxRemove(PVBOXVIDEOCM_MGR pMgr, PVBOXVIDEOCM_CTX pContext);
NTSTATUS vboxVideoCmInit(PVBOXVIDEOCM_MGR pMgr);
NTSTATUS vboxVideoCmTerm(PVBOXVIDEOCM_MGR pMgr);
+NTSTATUS vboxVideoCmSignalEvents(PVBOXVIDEOCM_MGR pMgr);
NTSTATUS vboxVideoCmCmdSubmitCompleteEvent(PVBOXVIDEOCM_CTX pContext, PKEVENT pEvent);
void* vboxVideoCmCmdCreate(PVBOXVIDEOCM_CTX pContext, uint32_t cbSize);
@@ -57,9 +58,4 @@ NTSTATUS vboxVideoCmCmdVisit(PVBOXVIDEOCM_CTX pContext, BOOLEAN bEntireSession,
NTSTATUS vboxVideoCmEscape(PVBOXVIDEOCM_CTX pContext, PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pCmd, uint32_t cbCmd);
-NTSTATUS vboxVideoCmWaitCompletedCmds(PVBOXVIDEOCM_MGR pMgr, uint32_t msTimeout);
-
-VOID vboxVideoCmLock(PVBOXVIDEOCM_CTX pContext);
-VOID vboxVideoCmUnlock(PVBOXVIDEOCM_CTX pContext);
-
#endif /* #ifndef ___VBoxMPCm_h___ */
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp
index 070eb30f..0c55676d 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp
@@ -24,35 +24,18 @@
#ifdef VBOX_WITH_CROGL
#include <cr_protocol.h>
-# ifdef VBOX_WDDM_WITH_CRCMD
-# include <cr_pack.h>
+static uint32_t g_VBoxMpCrHostCaps = 0;
+static uint32_t g_VBoxMpCr3DSupported = 0;
-typedef struct VBOXMP_CRSHGSMICON_BUFDR
+uint32_t VBoxMpCrGetHostCaps()
{
- uint32_t cbBuf;
- void *pvBuf;
-} VBOXMP_CRSHGSMICON_BUFDR, *PVBOXMP_CRSHGSMICON_BUFDR;
-
-typedef struct VBOXMP_CRSHGSMICON_BUFDR_CACHE
-{
- volatile PVBOXMP_CRSHGSMICON_BUFDR pBufDr;
-} VBOXMP_CRSHGSMICON_BUFDR_CACHE, *PVBOXMP_CRSHGSMICON_BUFDR_CACHE;
-
-typedef struct VBOXMP_CRSHGSMICON
-{
- PVBOXMP_DEVEXT pDevExt;
- PVBOXMP_CRCTLCON pCtlCon;
- uint32_t u32ClientID;
- VBOXMP_CRSHGSMICON_BUFDR_CACHE CmdDrCache;
- VBOXMP_CRSHGSMICON_BUFDR_CACHE WbDrCache;
-} VBOXMP_CRSHGSMICON, *PVBOXMP_CRSHGSMICON;
+ return g_VBoxMpCrHostCaps;
+}
-typedef struct VBOXMP_CRSHGSMIPACKER
+bool VBoxMpCrCtlConIs3DSupported()
{
- PVBOXMP_CRSHGSMICON pCon;
- CRPackContext CrPacker;
- CRPackBuffer CrBuffer;
-} VBOXMP_CRSHGSMIPACKER, *PVBOXMP_CRSHGSMIPACKER;
+ return !!g_VBoxMpCr3DSupported;
+}
static void* vboxMpCrShgsmiBufferAlloc(PVBOXMP_DEVEXT pDevExt, HGSMISIZE cbData)
{
@@ -61,7 +44,12 @@ static void* vboxMpCrShgsmiBufferAlloc(PVBOXMP_DEVEXT pDevExt, HGSMISIZE cbData)
static VBOXVIDEOOFFSET vboxMpCrShgsmiBufferOffset(PVBOXMP_DEVEXT pDevExt, void *pvBuffer)
{
- return HGSMIPointerToOffset(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx.Heap.area, (const HGSMIBUFFERHEADER *)pvBuffer);
+ return (VBOXVIDEOOFFSET)HGSMIPointerToOffset(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx.Heap.area, (const HGSMIBUFFERHEADER *)pvBuffer);
+}
+
+static void* vboxMpCrShgsmiBufferFromOffset(PVBOXMP_DEVEXT pDevExt, VBOXVIDEOOFFSET offBuffer)
+{
+ return HGSMIOffsetToPointer(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx.Heap.area, (HGSMIOFFSET)offBuffer);
}
static void vboxMpCrShgsmiBufferFree(PVBOXMP_DEVEXT pDevExt, void *pvBuffer)
@@ -69,38 +57,38 @@ static void vboxMpCrShgsmiBufferFree(PVBOXMP_DEVEXT pDevExt, void *pvBuffer)
VBoxSHGSMIHeapBufferFree(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, pvBuffer);
}
-static void* vboxMpCrShgsmiConAlloc(PVBOXMP_CRSHGSMICON pCon, uint32_t cbBuffer)
+static VBOXVIDEOOFFSET vboxMpCrShgsmiTransportBufOffset(PVBOXMP_CRSHGSMITRANSPORT pCon, void* pvBuffer)
{
- return vboxMpCrShgsmiBufferAlloc(pCon->pDevExt, cbBuffer);
+ return vboxMpCrShgsmiBufferOffset(pCon->pDevExt, pvBuffer);
}
-static VBOXVIDEOOFFSET vboxMpCrShgsmiConBufOffset(PVBOXMP_CRSHGSMICON pCon, void* pvBuffer)
+static void* vboxMpCrShgsmiTransportBufFromOffset(PVBOXMP_CRSHGSMITRANSPORT pCon, VBOXVIDEOOFFSET offBuffer)
{
- return vboxMpCrShgsmiBufferOffset(pCon->pDevExt, pvBuffer);
+ return vboxMpCrShgsmiBufferFromOffset(pCon->pDevExt, offBuffer);
}
+void* VBoxMpCrShgsmiTransportBufAlloc(PVBOXMP_CRSHGSMITRANSPORT pCon, uint32_t cbBuffer)
+{
+ return vboxMpCrShgsmiBufferAlloc(pCon->pDevExt, cbBuffer);
+}
-static void vboxMpCrShgsmiConFree(PVBOXMP_CRSHGSMICON pCon, void* pvBuffer)
+void VBoxMpCrShgsmiTransportBufFree(PVBOXMP_CRSHGSMITRANSPORT pCon, void* pvBuffer)
{
vboxMpCrShgsmiBufferFree(pCon->pDevExt, pvBuffer);
}
-#define VBOXMP_CRSHGSMICON_DR_CMDBUF_OFFSET(_cBuffers) VBOXWDDM_ROUNDBOUND((VBOXVDMACMD_SIZE_FROMBODYSIZE(RT_OFFSETOF(VBOXVDMACMD_CHROMIUM_CMD, aBuffers[_cBuffers]))), 8)
-#define VBOXMP_CRSHGSMICON_DR_GET_CMDBUF(_pDr, _cBuffers, _type) ((_type*)(((uint8_t*)(_pDr)) + VBOXMP_CRSHGSMICON_DR_CMDBUF_OFFSET(_cBuffers)))
-#define VBOXMP_CRSHGSMICON_DR_SIZE(_cBuffers, _cbCmdBuf) ( VBOXMP_CRSHGSMICON_DR_CMDBUF_OFFSET(_cBuffers) + _cbCmdBuf)
-
-static int vboxMpCrShgsmiBufCacheBufReinit(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache, PVBOXMP_CRSHGSMICON_BUFDR pDr, uint32_t cbRequested)
+static int vboxMpCrShgsmiBufCacheBufReinit(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache, PVBOXMP_CRSHGSMICON_BUFDR pDr, uint32_t cbRequested)
{
if (pDr->cbBuf >= cbRequested)
return VINF_SUCCESS;
if (pDr->pvBuf)
- vboxMpCrShgsmiConFree(pCon, pDr->pvBuf);
+ VBoxMpCrShgsmiTransportBufFree(pCon, pDr->pvBuf);
- pDr->pvBuf = vboxMpCrShgsmiConAlloc(pCon, cbRequested);
+ pDr->pvBuf = VBoxMpCrShgsmiTransportBufAlloc(pCon, cbRequested);
if (!pDr->pvBuf)
{
- WARN(("vboxMpCrShgsmiConAlloc failed"));
+ WARN(("VBoxMpCrShgsmiTransportBufAlloc failed"));
pDr->cbBuf = 0;
return VERR_NO_MEMORY;
}
@@ -109,13 +97,13 @@ static int vboxMpCrShgsmiBufCacheBufReinit(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_CRS
return VINF_SUCCESS;
}
-static void vboxMpCrShgsmiBufCacheFree(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache, PVBOXMP_CRSHGSMICON_BUFDR pDr)
+static void vboxMpCrShgsmiBufCacheFree(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache, PVBOXMP_CRSHGSMICON_BUFDR pDr)
{
if (ASMAtomicCmpXchgPtr(&pCache->pBufDr, pDr, NULL))
return;
/* the value is already cached, free the current one */
- vboxMpCrShgsmiConFree(pCon, pDr->pvBuf);
+ VBoxMpCrShgsmiTransportBufFree(pCon, pDr->pvBuf);
vboxWddmMemFree(pDr);
}
@@ -134,7 +122,7 @@ static PVBOXMP_CRSHGSMICON_BUFDR vboxMpCrShgsmiBufCacheGetAllocDr(PVBOXMP_CRSHGS
return pBufDr;
}
-static PVBOXMP_CRSHGSMICON_BUFDR vboxMpCrShgsmiBufCacheAlloc(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache, uint32_t cbBuffer)
+static PVBOXMP_CRSHGSMICON_BUFDR vboxMpCrShgsmiBufCacheAlloc(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache, uint32_t cbBuffer)
{
PVBOXMP_CRSHGSMICON_BUFDR pBufDr = vboxMpCrShgsmiBufCacheGetAllocDr(pCache);
int rc = vboxMpCrShgsmiBufCacheBufReinit(pCon, pCache, pBufDr, cbBuffer);
@@ -147,7 +135,7 @@ static PVBOXMP_CRSHGSMICON_BUFDR vboxMpCrShgsmiBufCacheAlloc(PVBOXMP_CRSHGSMICON
return NULL;
}
-static PVBOXMP_CRSHGSMICON_BUFDR vboxMpCrShgsmiBufCacheAllocAny(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache, uint32_t cbBuffer)
+static PVBOXMP_CRSHGSMICON_BUFDR vboxMpCrShgsmiBufCacheAllocAny(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache, uint32_t cbBuffer)
{
PVBOXMP_CRSHGSMICON_BUFDR pBufDr = vboxMpCrShgsmiBufCacheGetAllocDr(pCache);
@@ -165,128 +153,396 @@ static PVBOXMP_CRSHGSMICON_BUFDR vboxMpCrShgsmiBufCacheAllocAny(PVBOXMP_CRSHGSMI
}
-static int vboxMpCrShgsmiBufCacheInit(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache)
+static int vboxMpCrShgsmiBufCacheInit(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache)
{
memset(pCache, 0, sizeof (*pCache));
return VINF_SUCCESS;
}
-static void vboxMpCrShgsmiBufCacheTerm(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache)
+static void vboxMpCrShgsmiBufCacheTerm(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXMP_CRSHGSMICON_BUFDR_CACHE pCache)
{
if (pCache->pBufDr)
vboxMpCrShgsmiBufCacheFree(pCon, pCache, pCache->pBufDr);
}
-static int vboxMpCrShgsmiConConnect(PVBOXMP_CRSHGSMICON pCon, PVBOXMP_DEVEXT pDevExt, PVBOXMP_CRCTLCON pCrCtlCon)
+int VBoxMpCrShgsmiTransportCreate(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXMP_DEVEXT pDevExt)
{
memset(pCon, 0, sizeof (*pCon));
- int rc = vboxMpCrShgsmiBufCacheInit(pCon, &pCon->CmdDrCache);
- if (RT_SUCCESS(rc))
+ pCon->pDevExt = pDevExt;
+ return VINF_SUCCESS;
+ int rc;
+// int rc = vboxMpCrShgsmiBufCacheInit(pCon, &pCon->CmdDrCache);
+// if (RT_SUCCESS(rc))
{
rc = vboxMpCrShgsmiBufCacheInit(pCon, &pCon->WbDrCache);
if (RT_SUCCESS(rc))
{
- rc = VBoxMpCrCtlConConnect(pCrCtlCon, CR_PROTOCOL_VERSION_MAJOR, CR_PROTOCOL_VERSION_MINOR, &pCon->u32ClientID);
- if (RT_SUCCESS(rc))
- {
- pCon->pDevExt = pDevExt;
- pCon->pCtlCon = pCrCtlCon;
- return VINF_SUCCESS;
- }
- else
- {
- WARN(("VBoxMpCrCtlConConnect failed rc %d", rc));
- }
- vboxMpCrShgsmiBufCacheTerm(pCon, &pCon->WbDrCache);
}
else
{
WARN(("vboxMpCrShgsmiBufCacheInit2 failed rc %d", rc));
}
- vboxMpCrShgsmiBufCacheTerm(pCon, &pCon->CmdDrCache);
+// vboxMpCrShgsmiBufCacheTerm(pCon, &pCon->CmdDrCache);
}
- else
+// else
+// {
+// WARN(("vboxMpCrShgsmiBufCacheInit1 failed rc %d", rc));
+// }
+
+ return rc;
+}
+
+void VBoxMpCrShgsmiTransportTerm(PVBOXMP_CRSHGSMITRANSPORT pCon)
+{
+ vboxMpCrShgsmiBufCacheTerm(pCon, &pCon->WbDrCache);
+// vboxMpCrShgsmiBufCacheTerm(pCon, &pCon->CmdDrCache);
+}
+
+typedef struct VBOXMP_CRHGSMICMD_BASE
+{
+// VBOXMP_CRHGSMICMD_HDR Hdr;
+ CRVBOXHGSMIHDR CmdHdr;
+} VBOXMP_CRHGSMICMD_BASE, *PVBOXMP_CRHGSMICMD_BASE;
+
+typedef struct VBOXMP_CRHGSMICMD_WRITEREAD
+{
+// VBOXMP_CRHGSMICMD_HDR Hdr;
+ CRVBOXHGSMIWRITEREAD Cmd;
+} VBOXMP_CRHGSMICMD_WRITEREAD, *PVBOXMP_CRHGSMICMD_WRITEREAD;
+
+typedef struct VBOXMP_CRHGSMICMD_READ
+{
+// VBOXMP_CRHGSMICMD_HDR Hdr;
+ CRVBOXHGSMIREAD Cmd;
+} VBOXMP_CRHGSMICMD_READ, *PVBOXMP_CRHGSMICMD_READ;
+
+typedef struct VBOXMP_CRHGSMICMD_WRITE
+{
+// VBOXMP_CRHGSMICMD_HDR Hdr;
+ CRVBOXHGSMIWRITE Cmd;
+} VBOXMP_CRHGSMICMD_WRITE, *PVBOXMP_CRHGSMICMD_WRITE;
+
+#define VBOXMP_CRSHGSMICON_DR_CMDBUF_OFFSET(_cBuffers) VBOXWDDM_ROUNDBOUND((VBOXVDMACMD_SIZE_FROMBODYSIZE(RT_OFFSETOF(VBOXVDMACMD_CHROMIUM_CMD, aBuffers[_cBuffers]))), 8)
+#define VBOXMP_CRSHGSMICON_DR_CMDCTX_OFFSET(_cBuffers, _cbCmdBuf) ( VBOXMP_CRSHGSMICON_DR_CMDBUF_OFFSET(_cBuffers) + VBOXWDDM_ROUNDBOUND(_cbCmdBuf, 8))
+#define VBOXMP_CRSHGSMICON_DR_GET_CRCMD(_pDr) (VBOXVDMACMD_BODY((_pDr), VBOXVDMACMD_CHROMIUM_CMD))
+#define VBOXMP_CRSHGSMICON_DR_GET_CMDBUF(_pDr, _cBuffers, _type) ((_type*)(((uint8_t*)(_pDr)) + VBOXMP_CRSHGSMICON_DR_CMDBUF_OFFSET(_cBuffers)))
+#define VBOXMP_CRSHGSMICON_DR_GET_CMDCTX(_pDr, _cBuffers, _cbCmdBuf, _type) ((_type*)(((uint8_t*)(_pDr)) + VBOXMP_CRSHGSMICON_DR_CMDCTX_OFFSET(_cBuffers, _cbCmdBuf)))
+#define VBOXMP_CRSHGSMICON_DR_GET_FROM_CMDCTX(_pCtx, _cBuffers, _cbCmdBuf) ((VBOXVDMACMD*)(((uint8_t*)(_pCtx)) - VBOXMP_CRSHGSMICON_DR_CMDCTX_OFFSET(_cBuffers, _cbCmdBuf)))
+#define VBOXMP_CRSHGSMICON_DR_SIZE(_cBuffers, _cbCmdBuf, _cbCtx) (VBOXMP_CRSHGSMICON_DR_CMDCTX_OFFSET(_cBuffers, _cbCmdBuf) + (_cbCtx))
+
+
+static int vboxMpCrShgsmiTransportCmdSubmitDr(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXVDMACBUF_DR pDr, PFNVBOXVDMADDICMDCOMPLETE_DPC pfnComplete)
+{
+
+ PVBOXVDMADDI_CMD pDdiCmd = VBOXVDMADDI_CMD_FROM_BUF_DR(pDr);
+ PVBOXMP_DEVEXT pDevExt = pCon->pDevExt;
+ vboxVdmaDdiCmdInit(pDdiCmd, 0, 0, pfnComplete, pCon);
+ /* mark command as submitted & invisible for the dx runtime since dx did not originate it */
+ vboxVdmaDdiCmdSubmittedNotDx(pDdiCmd);
+ int rc = vboxVdmaCBufDrSubmit(pDevExt, &pDevExt->u.primary.Vdma, pDr);
+ if (RT_SUCCESS(rc))
{
- WARN(("vboxMpCrShgsmiBufCacheInit1 failed rc %d", rc));
+ return VINF_SUCCESS;
}
+ WARN(("vboxVdmaCBufDrSubmit failed rc %d", rc));
return rc;
}
-static int vboxMpCrShgsmiConDisconnect(PVBOXMP_CRSHGSMICON pCon)
+static int vboxMpCrShgsmiTransportCmdSubmitDmaCmd(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXVDMACMD pHdr, PFNVBOXVDMADDICMDCOMPLETE_DPC pfnComplete)
{
- int rc = VBoxMpCrCtlConDisconnect(pCon->pCtlCon, pCon->u32ClientID);
- if (RT_FAILURE(rc))
+ PVBOXVDMACBUF_DR pDr = VBOXVDMACBUF_DR_FROM_TAIL(pHdr);
+ return vboxMpCrShgsmiTransportCmdSubmitDr(pCon, pDr, pfnComplete);
+}
+
+static void vboxMpCrShgsmiTransportCmdTermDmaCmd(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXVDMACMD pHdr)
+{
+ PVBOXVDMACBUF_DR pDr = VBOXVDMACBUF_DR_FROM_TAIL(pHdr);
+ PVBOXMP_DEVEXT pDevExt = pCon->pDevExt;
+ vboxVdmaCBufDrFree (&pDevExt->u.primary.Vdma, pDr);
+}
+
+
+typedef DECLCALLBACK(void) FNVBOXMP_CRSHGSMITRANSPORT_SENDREADASYNC_COMPLETION(PVBOXMP_CRSHGSMITRANSPORT pCon, int rc, void *pvRx, uint32_t cbRx, void *pvCtx);
+typedef FNVBOXMP_CRSHGSMITRANSPORT_SENDREADASYNC_COMPLETION *PFNVBOXMP_CRSHGSMITRANSPORT_SENDREADASYNC_COMPLETION;
+
+static DECLCALLBACK(VOID) vboxMpCrShgsmiTransportSendReadAsyncCompletion(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pDdiCmd, PVOID pvContext)
+{
+ /* we should be called from our DPC routine */
+ Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+ PVBOXMP_CRSHGSMITRANSPORT pCon = (PVBOXMP_CRSHGSMITRANSPORT)pvContext;
+ PVBOXVDMACBUF_DR pDr = VBOXVDMACBUF_DR_FROM_DDI_CMD(pDdiCmd);
+ PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
+ VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXMP_CRSHGSMICON_DR_GET_CRCMD(pHdr);
+ const UINT cBuffers = 2;
+ Assert(pBody->cBuffers == cBuffers);
+ PVBOXMP_CRHGSMICMD_READ pWrData = VBOXMP_CRSHGSMICON_DR_GET_CMDBUF(pHdr, cBuffers, VBOXMP_CRHGSMICMD_READ);
+ CRVBOXHGSMIREAD *pCmd = &pWrData->Cmd;
+ VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[0];
+ Assert(pBufCmd->cbBuffer == sizeof (CRVBOXHGSMIREAD));
+ CRVBOXHGSMIREAD * pWr = (CRVBOXHGSMIREAD*)vboxMpCrShgsmiTransportBufFromOffset(pCon, pBufCmd->offBuffer);
+ PFNVBOXMP_CRSHGSMITRANSPORT_SENDREADASYNC_COMPLETION pfnCompletion = (PFNVBOXMP_CRSHGSMITRANSPORT_SENDREADASYNC_COMPLETION)pBufCmd->u64GuestData;
+ VBOXVDMACMD_CHROMIUM_BUFFER *pRxBuf = &pBody->aBuffers[1];
+ PVBOXMP_CRSHGSMICON_BUFDR pWbDr = (PVBOXMP_CRSHGSMICON_BUFDR)pRxBuf->u64GuestData;
+ void *pvRx = NULL;
+ uint32_t cbRx = 0;
+
+ int rc = pDr->rc;
+ if (RT_SUCCESS(rc))
{
- WARN(("VBoxMpCrCtlConDisconnect failed rc %d", rc));
- return rc;
+ rc = pWr->hdr.result;
+ if (RT_SUCCESS(rc))
+ {
+ cbRx = pCmd->cbBuffer;
+ if (cbRx)
+ pvRx = pWbDr->pvBuf;
+ }
+ else
+ {
+ WARN(("CRVBOXHGSMIREAD failed, rc %d", rc));
+ }
+ }
+ else
+ {
+ WARN(("dma command buffer failed rc %d!", rc));
}
- vboxMpCrShgsmiBufCacheTerm(pCon, &pCon->WbDrCache);
- vboxMpCrShgsmiBufCacheTerm(pCon, &pCon->CmdDrCache);
+ if (pfnCompletion)
+ {
+ void *pvCtx = VBOXMP_CRSHGSMICON_DR_GET_CMDCTX(pHdr, cBuffers, sizeof (VBOXMP_CRHGSMICMD_READ), void);
+ pfnCompletion(pCon, rc, pvRx, cbRx, pvCtx);
+ }
- return VINF_SUCCESS;
+ vboxMpCrShgsmiBufCacheFree(pCon, &pCon->WbDrCache, pWbDr);
+}
+
+static void* vboxMpCrShgsmiTransportCmdCreateReadAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, uint32_t u32ClientID, PVBOXVDMACBUF_DR pDr, uint32_t cbDrData, PVBOXMP_CRSHGSMICON_BUFDR pWbDr,
+ PFNVBOXMP_CRSHGSMITRANSPORT_SENDREADASYNC_COMPLETION pfnCompletion, uint32_t cbContextData)
+{
+ const uint32_t cBuffers = 2;
+ const uint32_t cbCmd = VBOXMP_CRSHGSMICON_DR_SIZE(cBuffers, sizeof (VBOXMP_CRHGSMICMD_READ), cbContextData);
+ PVBOXMP_DEVEXT pDevExt = pCon->pDevExt;
+ PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
+ VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXMP_CRSHGSMICON_DR_GET_CRCMD(pHdr);
+ PVBOXMP_CRHGSMICMD_READ pWrData = VBOXMP_CRSHGSMICON_DR_GET_CMDBUF(pHdr, cBuffers, VBOXMP_CRHGSMICMD_READ);
+ CRVBOXHGSMIREAD *pCmd = &pWrData->Cmd;
+
+ if (cbCmd > cbContextData)
+ {
+ ERR(("the passed descriptor is less than needed!"));
+ return NULL;
+ }
+
+ memset(pDr, 0, VBOXVDMACBUF_DR_SIZE(cbCmd));
+
+ pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_VRAM_OFFSET;
+ pDr->cbBuf = cbCmd;
+ pDr->rc = VERR_NOT_IMPLEMENTED;
+ pDr->Location.offVramBuf = vboxMpCrShgsmiTransportBufOffset(pCon, pCmd);
+
+ pHdr->enmType = VBOXVDMACMD_TYPE_CHROMIUM_CMD;
+ pHdr->u32CmdSpecific = 0;
+
+ pBody->cBuffers = cBuffers;
+
+ pCmd->hdr.result = VERR_WRONG_ORDER;
+ pCmd->hdr.u32ClientID = u32ClientID;
+ pCmd->hdr.u32Function = SHCRGL_GUEST_FN_WRITE_READ;
+ // pCmd->hdr.u32Reserved = 0;
+ pCmd->iBuffer = 1;
+
+ VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[0];
+ pBufCmd->offBuffer = vboxMpCrShgsmiTransportBufOffset(pCon, pCmd);
+ pBufCmd->cbBuffer = sizeof (*pCmd);
+ pBufCmd->u32GuestData = 0;
+ pBufCmd->u64GuestData = (uint64_t)pfnCompletion;
+
+ pBufCmd = &pBody->aBuffers[1];
+ pBufCmd->offBuffer = vboxMpCrShgsmiTransportBufOffset(pCon, pWbDr->pvBuf);
+ pBufCmd->cbBuffer = pWbDr->cbBuf;
+ pBufCmd->u32GuestData = 0;
+ pBufCmd->u64GuestData = (uint64_t)pWbDr;
+
+ return VBOXMP_CRSHGSMICON_DR_GET_CMDCTX(pHdr, cBuffers, sizeof (VBOXMP_CRHGSMICMD_READ), void);
}
-typedef DECLCALLBACK(void) FNVBOXMP_CRSHGSMICON_SEND_COMPLETION(PVBOXMP_CRSHGSMICON pCon, void *pvRx, uint32_t cbRx, void *pvCtx);
-typedef FNVBOXMP_CRSHGSMICON_SEND_COMPLETION *PFNVBOXMP_CRSHGSMICON_SEND_COMPLETION;
+static int vboxMpCrShgsmiTransportCmdSubmitReadAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, void *pvContext)
+{
+ VBOXVDMACMD* pHdr = VBOXMP_CRSHGSMICON_DR_GET_FROM_CMDCTX(pvContext, 2, sizeof (VBOXMP_CRHGSMICMD_READ));
+ return vboxMpCrShgsmiTransportCmdSubmitDmaCmd(pCon, pHdr, vboxMpCrShgsmiTransportSendReadAsyncCompletion);
+}
-typedef struct VBOXMP_CRSHGSMICON_SEND_COMPLETION
+typedef struct VBOXMP_CRHGSMICON_WRR_COMPLETION_CTX
{
- PVBOXMP_CRSHGSMICON pCon;
- PFNVBOXMP_CRSHGSMICON_SEND_COMPLETION pvnCompletion;
- void *pvCompletion;
-} VBOXMP_CRSHGSMICON_SEND_COMPLETION, *PVBOXMP_CRSHGSMICON_SEND_COMPLETION;
+ PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEREADASYNC_COMPLETION pfnCompletion;
+ void *pvContext;
+
+} VBOXMP_CRHGSMICON_WRR_COMPLETION_CTX, *PVBOXMP_CRHGSMICON_WRR_COMPLETION_CTX;
-static DECLCALLBACK(VOID) vboxMpCrShgsmiConSendAsyncCompletion(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext)
+static DECLCALLBACK(void) vboxMpCrShgsmiTransportSendWriteReadReadRepostCompletion(PVBOXMP_CRSHGSMITRANSPORT pCon, int rc, void *pvRx, uint32_t cbRx, void *pvCtx)
+{
+ PVBOXMP_CRHGSMICON_WRR_COMPLETION_CTX pData = (PVBOXMP_CRHGSMICON_WRR_COMPLETION_CTX)pvCtx;
+ PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEREADASYNC_COMPLETION pfnCompletion = pData->pfnCompletion;
+ if (pfnCompletion)
+ pfnCompletion(pCon, rc, pvRx, cbRx, pData->pvContext);
+}
+
+static DECLCALLBACK(VOID) vboxMpCrShgsmiTransportSendWriteReadAsyncCompletion(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pDdiCmd, PVOID pvContext)
{
/* we should be called from our DPC routine */
Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
- PVBOXMP_CRSHGSMICON_SEND_COMPLETION pData = (PVBOXMP_CRSHGSMICON_SEND_COMPLETION)pvContext;
- PVBOXVDMACBUF_DR pDr = VBOXVDMACBUF_DR_FROM_DDI_CMD(pCmd);
+ PVBOXMP_CRSHGSMITRANSPORT pCon = (PVBOXMP_CRSHGSMITRANSPORT)pvContext;
+ PVBOXVDMACBUF_DR pDr = VBOXVDMACBUF_DR_FROM_DDI_CMD(pDdiCmd);
PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
- VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHROMIUM_CMD);
- UINT cBufs = pBody->cBuffers;
- /* the first one is a command buffer: obtain it and get the result */
+ VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXMP_CRSHGSMICON_DR_GET_CRCMD(pHdr);
+ const UINT cBuffers = 3;
+ Assert(pBody->cBuffers == cBuffers);
+ PVBOXMP_CRHGSMICMD_WRITEREAD pWrData = VBOXMP_CRSHGSMICON_DR_GET_CMDBUF(pHdr, cBuffers, VBOXMP_CRHGSMICMD_WRITEREAD);
+ CRVBOXHGSMIWRITEREAD *pCmd = &pWrData->Cmd;
+ VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[0];
+ Assert(pBufCmd->cbBuffer == sizeof (CRVBOXHGSMIWRITEREAD));
+ CRVBOXHGSMIWRITEREAD * pWr = (CRVBOXHGSMIWRITEREAD*)vboxMpCrShgsmiTransportBufFromOffset(pCon, pBufCmd->offBuffer);
+ VBOXVDMACMD_CHROMIUM_BUFFER *pRxBuf = &pBody->aBuffers[2];
+ PVBOXMP_CRSHGSMICON_BUFDR pWbDr = (PVBOXMP_CRSHGSMICON_BUFDR)pRxBuf->u64GuestData;
+ PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEREADASYNC_COMPLETION pfnCompletion = (PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEREADASYNC_COMPLETION)pBufCmd->u64GuestData;
+ void *pvRx = NULL;
+ uint32_t cbRx = 0;
+
+ int rc = pDr->rc;
+ if (RT_SUCCESS(rc))
+ {
+ rc = pWr->hdr.result;
+ if (RT_SUCCESS(rc))
+ {
+ cbRx = pCmd->cbWriteback;
+ if (cbRx)
+ pvRx = pWbDr->pvBuf;
+ }
+ else if (rc == VERR_BUFFER_OVERFLOW)
+ {
+ /* issue read */
+ void *pvCtx = VBOXMP_CRSHGSMICON_DR_GET_CMDCTX(pHdr, cBuffers, sizeof (VBOXMP_CRHGSMICMD_WRITEREAD), void);
+ vboxMpCrShgsmiBufCacheFree(pCon, &pCon->WbDrCache, pWbDr);
+ pWbDr = vboxMpCrShgsmiBufCacheAlloc(pCon, &pCon->WbDrCache, pCmd->cbWriteback);
+ if (pWbDr)
+ {
+ /* the Read Command is shorter than WriteRead, so just reuse the Write-Read descriptor here */
+ PVBOXMP_CRHGSMICON_WRR_COMPLETION_CTX pReadCtx = (PVBOXMP_CRHGSMICON_WRR_COMPLETION_CTX)vboxMpCrShgsmiTransportCmdCreateReadAsync(pCon, pCmd->hdr.u32ClientID,
+ pDr, VBOXMP_CRSHGSMICON_DR_SIZE(cBuffers, sizeof (VBOXMP_CRHGSMICMD_WRITEREAD), 0),
+ pWbDr, vboxMpCrShgsmiTransportSendWriteReadReadRepostCompletion, sizeof (*pReadCtx));
+ pReadCtx->pfnCompletion = pfnCompletion;
+ pReadCtx->pvContext = pvCtx;
+ vboxMpCrShgsmiTransportCmdSubmitReadAsync(pCon, pReadCtx);
+ /* don't do completion here, the completion will be called from the read completion we issue here */
+ pfnCompletion = NULL;
+ /* the current pWbDr was already freed, and we'll free the Read dr in the Read Completion */
+ pWbDr = NULL;
+ }
+ else
+ {
+ WARN(("vboxMpCrShgsmiBufCacheAlloc failed for %d", pCmd->cbWriteback));
+ rc = VERR_NO_MEMORY;
+ }
+ }
+ else
+ {
+ WARN(("CRVBOXHGSMIWRITEREAD failed, rc %d", rc));
+ }
+ }
+ else
+ {
+ WARN(("dma command buffer failed rc %d!", rc));
+ }
+
+ if (pfnCompletion)
+ {
+ void *pvCtx = VBOXMP_CRSHGSMICON_DR_GET_CMDCTX(pHdr, cBuffers, sizeof (VBOXMP_CRHGSMICMD_WRITEREAD), void);
+ pfnCompletion(pCon, rc, pvRx, cbRx, pvCtx);
+ }
+
+ if (pWbDr)
+ vboxMpCrShgsmiBufCacheFree(pCon, &pCon->WbDrCache, pWbDr);
+}
+
+static DECLCALLBACK(VOID) vboxMpCrShgsmiTransportSendWriteAsyncCompletion(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pDdiCmd, PVOID pvContext)
+{
+ /* we should be called from our DPC routine */
+ Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
- /* if write back buffer is too small, issue read command.
- * we can use exactly the same command buffer for it */
- /* impl */
- Assert(0);
+ PVBOXMP_CRSHGSMITRANSPORT pCon = (PVBOXMP_CRSHGSMITRANSPORT)pvContext;
+ PVBOXVDMACBUF_DR pDr = VBOXVDMACBUF_DR_FROM_DDI_CMD(pDdiCmd);
+ PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
+ VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXMP_CRSHGSMICON_DR_GET_CRCMD(pHdr);
+ const UINT cBuffers = 2;
+ Assert(pBody->cBuffers == cBuffers);
+ PVBOXMP_CRHGSMICMD_WRITE pWrData = VBOXMP_CRSHGSMICON_DR_GET_CMDBUF(pHdr, cBuffers, VBOXMP_CRHGSMICMD_WRITE);
+ CRVBOXHGSMIWRITE *pCmd = &pWrData->Cmd;
+ VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[0];
+ Assert(pBufCmd->cbBuffer == sizeof (CRVBOXHGSMIWRITE));
+ PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEASYNC_COMPLETION pfnCompletion = (PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEASYNC_COMPLETION)pBufCmd->u64GuestData;
+
+ int rc = pDr->rc;
+ if (RT_SUCCESS(rc))
+ {
+ rc = pCmd->hdr.result;
+ if (!RT_SUCCESS(rc))
+ {
+ WARN(("CRVBOXHGSMIWRITE failed, rc %d", rc));
+ }
+ }
+ else
+ {
+ WARN(("dma command buffer failed rc %d!", rc));
+ }
+
+ if (pfnCompletion)
+ {
+ void *pvCtx = VBOXMP_CRSHGSMICON_DR_GET_CMDCTX(pHdr, cBuffers, sizeof (VBOXMP_CRHGSMICMD_WRITE), void);
+ pfnCompletion(pCon, rc, pvCtx);
+ }
}
-static int vboxMpCrShgsmiConSendAsync(PVBOXMP_CRSHGSMICON pCon, void *pvTx, uint32_t cbTx, PFNVBOXMP_CRSHGSMICON_SEND_COMPLETION pfnCompletion, void *pvCompletion)
+void* VBoxMpCrShgsmiTransportCmdCreateWriteReadAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, uint32_t u32ClientID, void *pvBuffer, uint32_t cbBuffer,
+ PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEREADASYNC_COMPLETION pfnCompletion, uint32_t cbContextData)
{
const uint32_t cBuffers = 3;
- const uint32_t cbCmd = VBOXMP_CRSHGSMICON_DR_SIZE(cBuffers, sizeof (CRVBOXHGSMIWRITEREAD));
- PVBOXMP_CRSHGSMICON_BUFDR pCmdDr = vboxMpCrShgsmiBufCacheAlloc(pCon, &pCon->CmdDrCache, cbCmd);
- if (!pCmdDr)
+ const uint32_t cbCmd = VBOXMP_CRSHGSMICON_DR_SIZE(cBuffers, sizeof (VBOXMP_CRHGSMICMD_WRITEREAD), cbContextData);
+ PVBOXMP_DEVEXT pDevExt = pCon->pDevExt;
+ PVBOXVDMACBUF_DR pDr = vboxVdmaCBufDrCreate(&pDevExt->u.primary.Vdma, cbCmd);
+ if (!pDr)
{
- WARN(("vboxMpCrShgsmiBufCacheAlloc for cmd dr failed"));
- return VERR_NO_MEMORY;
+ WARN(("vboxVdmaCBufDrCreate failed"));
+ return NULL;
}
+
PVBOXMP_CRSHGSMICON_BUFDR pWbDr = vboxMpCrShgsmiBufCacheAllocAny(pCon, &pCon->WbDrCache, 1000);
if (!pWbDr)
{
WARN(("vboxMpCrShgsmiBufCacheAlloc for wb dr failed"));
- vboxMpCrShgsmiBufCacheFree(pCon, &pCon->CmdDrCache, pCmdDr);
- return VERR_NO_MEMORY;
+ vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);
+ return NULL;
}
- PVBOXVDMACBUF_DR pDr = (PVBOXVDMACBUF_DR)pCmdDr->pvBuf;
+ PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
+ VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXMP_CRSHGSMICON_DR_GET_CRCMD(pHdr);
+ PVBOXMP_CRHGSMICMD_WRITEREAD pWrData = VBOXMP_CRSHGSMICON_DR_GET_CMDBUF(pHdr, cBuffers, VBOXMP_CRHGSMICMD_WRITEREAD);
+ CRVBOXHGSMIWRITEREAD *pCmd = &pWrData->Cmd;
+
pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR;
pDr->cbBuf = cbCmd;
pDr->rc = VERR_NOT_IMPLEMENTED;
+// pDr->Location.offVramBuf = vboxMpCrShgsmiTransportBufOffset(pCon, pCmd);
+
- PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
pHdr->enmType = VBOXVDMACMD_TYPE_CHROMIUM_CMD;
pHdr->u32CmdSpecific = 0;
- VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHROMIUM_CMD);
+
pBody->cBuffers = cBuffers;
- CRVBOXHGSMIWRITEREAD *pCmd = VBOXMP_CRSHGSMICON_DR_GET_CMDBUF(pDr, cBuffers, CRVBOXHGSMIWRITEREAD);
+
pCmd->hdr.result = VERR_WRONG_ORDER;
- pCmd->hdr.u32ClientID = pCon->u32ClientID;
+ pCmd->hdr.u32ClientID = u32ClientID;
pCmd->hdr.u32Function = SHCRGL_GUEST_FN_WRITE_READ;
// pCmd->hdr.u32Reserved = 0;
pCmd->iBuffer = 1;
@@ -294,105 +550,99 @@ static int vboxMpCrShgsmiConSendAsync(PVBOXMP_CRSHGSMICON pCon, void *pvTx, uint
pCmd->cbWriteback = 0;
VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[0];
- pBufCmd->offBuffer = vboxMpCrShgsmiConBufOffset(pCon, pCmd);
+ pBufCmd->offBuffer = vboxVdmaCBufDrPtrOffset(&pDevExt->u.primary.Vdma, pCmd);
pBufCmd->cbBuffer = sizeof (*pCmd);
pBufCmd->u32GuestData = 0;
- pBufCmd->u64GuestData = (uint64_t)pCmdDr;
+ pBufCmd->u64GuestData = (uint64_t)pfnCompletion;
pBufCmd = &pBody->aBuffers[1];
- pBufCmd->offBuffer = vboxMpCrShgsmiConBufOffset(pCon, pvTx);
- pBufCmd->cbBuffer = cbTx;
+ pBufCmd->offBuffer = vboxMpCrShgsmiTransportBufOffset(pCon, pvBuffer);
+ pBufCmd->cbBuffer = cbBuffer;
pBufCmd->u32GuestData = 0;
pBufCmd->u64GuestData = 0;
pBufCmd = &pBody->aBuffers[2];
- pBufCmd->offBuffer = vboxMpCrShgsmiConBufOffset(pCon, pWbDr->pvBuf);
+ pBufCmd->offBuffer = vboxMpCrShgsmiTransportBufOffset(pCon, pWbDr->pvBuf);
pBufCmd->cbBuffer = pWbDr->cbBuf;
pBufCmd->u32GuestData = 0;
pBufCmd->u64GuestData = (uint64_t)pWbDr;
+ return VBOXMP_CRSHGSMICON_DR_GET_CMDCTX(pHdr, cBuffers, sizeof (VBOXMP_CRHGSMICMD_WRITEREAD), void);
+}
+
+void* VBoxMpCrShgsmiTransportCmdCreateWriteAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, uint32_t u32ClientID, void *pvBuffer, uint32_t cbBuffer,
+ PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEASYNC_COMPLETION pfnCompletion, uint32_t cbContextData)
+{
+ const uint32_t cBuffers = 2;
+ const uint32_t cbCmd = VBOXMP_CRSHGSMICON_DR_SIZE(cBuffers, sizeof (VBOXMP_CRHGSMICMD_WRITE), cbContextData);
PVBOXMP_DEVEXT pDevExt = pCon->pDevExt;
- PVBOXVDMADDI_CMD pDdiCmd = VBOXVDMADDI_CMD_FROM_BUF_DR(pDr);
- vboxVdmaDdiCmdInit(pDdiCmd, 0, 0, vboxMpCrShgsmiConSendAsyncCompletion, pDr);
- /* mark command as submitted & invisible for the dx runtime since dx did not originate it */
- vboxVdmaDdiCmdSubmittedNotDx(pDdiCmd);
- int rc = vboxVdmaCBufDrSubmit(pDevExt, &pDevExt->u.primary.Vdma, pDr);
- if (RT_SUCCESS(rc))
+ PVBOXVDMACBUF_DR pDr = vboxVdmaCBufDrCreate(&pDevExt->u.primary.Vdma, cbCmd);
+ if (!pDr)
{
- return STATUS_SUCCESS;
+ WARN(("vboxVdmaCBufDrCreate failed"));
+ return NULL;
}
- /* impl failure branch */
- Assert(0);
- return rc;
-}
+ PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
+ VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXMP_CRSHGSMICON_DR_GET_CRCMD(pHdr);
+ PVBOXMP_CRHGSMICMD_WRITE pWrData = VBOXMP_CRSHGSMICON_DR_GET_CMDBUF(pHdr, cBuffers, VBOXMP_CRHGSMICMD_WRITE);
+ CRVBOXHGSMIWRITE *pCmd = &pWrData->Cmd;
-static CRMessageOpcodes *
-vboxMpCrPackerPrependHeader( CRPackBuffer *buf, unsigned int *len, unsigned int senderID )
-{
- UINT num_opcodes;
- CRMessageOpcodes *hdr;
+ pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR;
+ pDr->cbBuf = cbCmd;
+ pDr->rc = VERR_NOT_IMPLEMENTED;
+// pDr->Location.offVramBuf = vboxMpCrShgsmiTransportBufOffset(pCon, pCmd);
- Assert(buf);
- Assert(buf->opcode_current < buf->opcode_start);
- Assert(buf->opcode_current >= buf->opcode_end);
- Assert(buf->data_current > buf->data_start);
- Assert(buf->data_current <= buf->data_end);
+ pHdr->enmType = VBOXVDMACMD_TYPE_CHROMIUM_CMD;
+ pHdr->u32CmdSpecific = 0;
- num_opcodes = (UINT)(buf->opcode_start - buf->opcode_current);
- hdr = (CRMessageOpcodes *)
- ( buf->data_start - ( ( num_opcodes + 3 ) & ~0x3 ) - sizeof(*hdr) );
+ pBody->cBuffers = cBuffers;
- Assert((void *) hdr >= buf->pack);
+ pCmd->hdr.result = VERR_WRONG_ORDER;
+ pCmd->hdr.u32ClientID = u32ClientID;
+ pCmd->hdr.u32Function = SHCRGL_GUEST_FN_WRITE;
+ // pCmd->hdr.u32Reserved = 0;
+ pCmd->iBuffer = 1;
- hdr->header.type = CR_MESSAGE_OPCODES;
- hdr->numOpcodes = num_opcodes;
+ VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[0];
+ pBufCmd->offBuffer = vboxVdmaCBufDrPtrOffset(&pDevExt->u.primary.Vdma, pCmd);
+ pBufCmd->cbBuffer = sizeof (*pCmd);
+ pBufCmd->u32GuestData = 0;
+ pBufCmd->u64GuestData = (uint64_t)pfnCompletion;
- *len = (UINT)(buf->data_current - (unsigned char *) hdr);
+ pBufCmd = &pBody->aBuffers[1];
+ pBufCmd->offBuffer = vboxMpCrShgsmiTransportBufOffset(pCon, pvBuffer);
+ pBufCmd->cbBuffer = cbBuffer;
+ pBufCmd->u32GuestData = 0;
+ pBufCmd->u64GuestData = 0;
- return hdr;
+ return VBOXMP_CRSHGSMICON_DR_GET_CMDCTX(pHdr, cBuffers, sizeof (VBOXMP_CRHGSMICMD_WRITE), void);
}
-static void vboxMpCrShgsmiPackerCbFlush(void *pvFlush)
+int VBoxMpCrShgsmiTransportCmdSubmitWriteReadAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, void *pvContext)
{
- PVBOXMP_CRSHGSMIPACKER pPacker = (PVBOXMP_CRSHGSMIPACKER)pvFlush;
-
- crPackReleaseBuffer(&pPacker->CrPacker);
-
- if (pPacker->CrBuffer.opcode_current != pPacker->CrBuffer.opcode_start)
- {
- CRMessageOpcodes *pHdr;
- unsigned int len;
- pHdr = vboxMpCrPackerPrependHeader(&pPacker->CrBuffer, &len, 0);
-
- /*Send*/
- }
-
+ VBOXVDMACMD* pHdr = VBOXMP_CRSHGSMICON_DR_GET_FROM_CMDCTX(pvContext, 3, sizeof (VBOXMP_CRHGSMICMD_WRITEREAD));
+ return vboxMpCrShgsmiTransportCmdSubmitDmaCmd(pCon, pHdr, vboxMpCrShgsmiTransportSendWriteReadAsyncCompletion);
+}
- crPackSetBuffer(&pPacker->CrPacker, &pPacker->CrBuffer);
- crPackResetPointers(&pPacker->CrPacker);
+int VBoxMpCrShgsmiTransportCmdSubmitWriteAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, void *pvContext)
+{
+ VBOXVDMACMD* pHdr = VBOXMP_CRSHGSMICON_DR_GET_FROM_CMDCTX(pvContext, 2, sizeof (VBOXMP_CRHGSMICMD_WRITE));
+ return vboxMpCrShgsmiTransportCmdSubmitDmaCmd(pCon, pHdr, vboxMpCrShgsmiTransportSendWriteAsyncCompletion);
}
-int vboxMpCrShgsmiPackerInit(PVBOXMP_CRSHGSMIPACKER pPacker, PVBOXMP_CRSHGSMICON pCon)
+void VBoxMpCrShgsmiTransportCmdTermWriteReadAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, void *pvContext)
{
- memset(pPacker, 0, sizeof (*pPacker));
+ VBOXVDMACMD* pHdr = VBOXMP_CRSHGSMICON_DR_GET_FROM_CMDCTX(pvContext, 3, sizeof (VBOXMP_CRHGSMICMD_WRITEREAD));
+ vboxMpCrShgsmiTransportCmdTermDmaCmd(pCon, pHdr);
+}
- static const HGSMISIZE cbBuffer = 1000;
- void *pvBuffer = vboxMpCrShgsmiConAlloc(pCon, cbBuffer);
- if (!pvBuffer)
- {
- WARN(("vboxMpCrShgsmiConAlloc failed"));
- return VERR_NO_MEMORY;
- }
- pPacker->pCon = pCon;
- crPackInitBuffer(&pPacker->CrBuffer, pvBuffer, cbBuffer, cbBuffer);
- crPackSetBuffer(&pPacker->CrPacker, &pPacker->CrBuffer);
- crPackFlushFunc(&pPacker->CrPacker, vboxMpCrShgsmiPackerCbFlush);
- crPackFlushArg(&pPacker->CrPacker, pPacker);
-// crPackSendHugeFunc( thread->packer, packspuHuge );
- return VINF_SUCCESS;
+void VBoxMpCrShgsmiTransportCmdTermWriteAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, void *pvContext)
+{
+ VBOXVDMACMD* pHdr = VBOXMP_CRSHGSMICON_DR_GET_FROM_CMDCTX(pvContext, 2, sizeof (VBOXMP_CRHGSMICMD_WRITE));
+ vboxMpCrShgsmiTransportCmdTermDmaCmd(pCon, pHdr);
}
-# endif
+
#endif
static int vboxMpCrCtlAddRef(PVBOXMP_CRCTLCON pCrCtlCon)
@@ -464,6 +714,39 @@ static int vboxMpCrCtlConSetVersion(PVBOXMP_CRCTLCON pCrCtlCon, uint32_t u32Clie
return VINF_SUCCESS;
}
+static int vboxMpCrCtlConGetCaps(PVBOXMP_CRCTLCON pCrCtlCon, uint32_t u32ClientID, uint32_t *pu32Caps)
+{
+ CRVBOXHGCMGETCAPS parms;
+ int rc;
+
+ parms.hdr.result = VERR_WRONG_ORDER;
+ parms.hdr.u32ClientID = u32ClientID;
+ parms.hdr.u32Function = SHCRGL_GUEST_FN_GET_CAPS;
+ parms.hdr.cParms = SHCRGL_CPARMS_GET_CAPS;
+
+ parms.Caps.type = VMMDevHGCMParmType_32bit;
+ parms.Caps.u.value32 = 0;
+
+ *pu32Caps = 0;
+
+ rc = vboxCrCtlConCall(pCrCtlCon->hCrCtl, &parms.hdr, sizeof (parms));
+ if (RT_FAILURE(rc))
+ {
+ WARN(("vboxCrCtlConCall failed, rc (%d)", rc));
+ return rc;
+ }
+
+ if (RT_FAILURE(parms.hdr.result))
+ {
+ WARN(("SHCRGL_GUEST_FN_GET_CAPS failed, rc (%d)", parms.hdr.result));
+ return parms.hdr.result;
+ }
+
+ *pu32Caps = parms.Caps.u.value32;
+
+ return VINF_SUCCESS;
+}
+
static int vboxMpCrCtlConSetPID(PVBOXMP_CRCTLCON pCrCtlCon, uint32_t u32ClientID)
{
CRVBOXHGCMSETPID parms;
@@ -576,8 +859,11 @@ int VBoxMpCrCtlConCallUserData(PVBOXMP_CRCTLCON pCrCtlCon, VBoxGuestHGCMCallInfo
return rc;
}
-bool VBoxMpCrCtlConIs3DSupported()
+void VBoxMpCrCtlConInit()
{
+ g_VBoxMpCr3DSupported = 0;
+ g_VBoxMpCrHostCaps = 0;
+
#ifdef VBOX_WITH_CROGL
VBOXMP_CRCTLCON CrCtlCon = {0};
uint32_t u32ClientID = 0;
@@ -585,15 +871,57 @@ bool VBoxMpCrCtlConIs3DSupported()
if (RT_FAILURE(rc))
{
LOGREL(("VBoxMpCrCtlConConnect failed with rc(%d), 3D not supported!"));
- return false;
+ return;
}
- rc = VBoxMpCrCtlConDisconnect(&CrCtlCon, u32ClientID);
+ g_VBoxMpCr3DSupported = 1;
+
+ rc = vboxMpCrCtlConGetCaps(&CrCtlCon, u32ClientID, &g_VBoxMpCrHostCaps);
if (RT_FAILURE(rc))
- WARN(("VBoxMpCrCtlConDisconnect failed, ignoring.."));
+ {
+ WARN(("vboxMpCrCtlConGetCaps failed rc (%d), ignoring..", rc));
+ g_VBoxMpCrHostCaps = 0;
+ }
- return true;
-#else
- return false;
+#if 1 /*def DEBUG_misha*/
+ g_VBoxMpCrHostCaps &= ~CR_VBOX_CAP_CMDVBVA;
#endif
+
+ rc = VBoxMpCrCtlConDisconnect(&CrCtlCon, u32ClientID);
+ if (RT_FAILURE(rc))
+ WARN(("VBoxMpCrCtlConDisconnect failed rc (%d), ignoring..", rc));
+#endif
+}
+
+int VBoxMpCrCmdRxReadbackHandler(CRMessageReadback *pRx, uint32_t cbRx)
+{
+ if (cbRx < sizeof (*pRx))
+ {
+ WARN(("invalid rx size %d", cbRx));
+ return VERR_INVALID_PARAMETER;
+ }
+ void* pvData = VBoxMpCrCmdRxReadbackData(pRx);
+ uint32_t cbData = VBoxMpCrCmdRxReadbackDataSize(pRx, cbRx);
+ void *pvDataPtr = *((void**)&pRx->readback_ptr);
+ memcpy(pvDataPtr, pvData, cbData);
+ return VINF_SUCCESS;
}
+
+int VBoxMpCrCmdRxHandler(CRMessageHeader *pRx, uint32_t cbRx)
+{
+ if (cbRx < sizeof (*pRx))
+ {
+ WARN(("invalid rx size %d", cbRx));
+ return VERR_INVALID_PARAMETER;
+ }
+ CRMessageHeader *pHdr = (CRMessageHeader*)pRx;
+ switch (pHdr->type)
+ {
+ case CR_MESSAGE_READBACK:
+ return VBoxMpCrCmdRxReadbackHandler((CRMessageReadback*)pRx, cbRx);
+ default:
+ WARN(("unsupported rx message type: %d", pHdr->type));
+ return VERR_INVALID_PARAMETER;
+ }
+}
+
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.h b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.h
index 4bf2ab98..cc00f90d 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.h
@@ -27,6 +27,8 @@ typedef struct VBOXMP_CRCTLCON
uint32_t cCrCtlRefs;
} VBOXMP_CRCTLCON, *PVBOXMP_CRCTLCON;
+void VBoxMpCrCtlConInit();
+
bool VBoxMpCrCtlConIs3DSupported();
int VBoxMpCrCtlConConnect(PVBOXMP_CRCTLCON pCrCtlCon,
@@ -36,4 +38,214 @@ int VBoxMpCrCtlConDisconnect(PVBOXMP_CRCTLCON pCrCtlCon, uint32_t u32ClientID);
int VBoxMpCrCtlConCall(PVBOXMP_CRCTLCON pCrCtlCon, struct VBoxGuestHGCMCallInfo *pData, uint32_t cbData);
int VBoxMpCrCtlConCallUserData(PVBOXMP_CRCTLCON pCrCtlCon, struct VBoxGuestHGCMCallInfo *pData, uint32_t cbData);
+# include <cr_pack.h>
+
+typedef struct VBOXMP_CRDATACON
+{
+ PVBOXMP_CRCTLCON pCtl;
+ uint32_t u32ClientID;
+} VBOXMP_CRDATACON, *PVBOXMP_CRDATACON;
+
+DECLINLINE(int) VBoxMpCrDataConCreate(PVBOXMP_CRDATACON pDataCon, PVBOXMP_CRCTLCON pCtlCon)
+{
+ int rc = VBoxMpCrCtlConConnect(pCtlCon, CR_PROTOCOL_VERSION_MAJOR, CR_PROTOCOL_VERSION_MINOR, &pDataCon->u32ClientID);
+ if (RT_SUCCESS(rc))
+ {
+ Assert(pDataCon->u32ClientID);
+ pDataCon->pCtl = pCtlCon;
+ return VINF_SUCCESS;
+ }
+ WARN(("VBoxMpCrCtlConConnect failed, rc %d", rc));
+ return rc;
+}
+
+DECLINLINE(int) VBoxMpCrDataConDestroy(PVBOXMP_CRDATACON pDataCon)
+{
+ int rc = VBoxMpCrCtlConDisconnect(pDataCon->pCtl, pDataCon->u32ClientID);
+ if (RT_SUCCESS(rc))
+ {
+ /* sanity */
+ pDataCon->pCtl = NULL;
+ pDataCon->u32ClientID = 0;
+ return VINF_SUCCESS;
+ }
+ WARN(("VBoxMpCrCtlConDisconnect failed, rc %d", rc));
+ return rc;
+}
+
+typedef struct VBOXMP_CRSHGSMICON_BUFDR
+{
+ uint32_t cbBuf;
+ void *pvBuf;
+} VBOXMP_CRSHGSMICON_BUFDR, *PVBOXMP_CRSHGSMICON_BUFDR;
+
+typedef struct VBOXMP_CRSHGSMICON_BUFDR_CACHE
+{
+ volatile PVBOXMP_CRSHGSMICON_BUFDR pBufDr;
+} VBOXMP_CRSHGSMICON_BUFDR_CACHE, *PVBOXMP_CRSHGSMICON_BUFDR_CACHE;
+
+typedef struct VBOXMP_CRSHGSMITRANSPORT
+{
+ PVBOXMP_DEVEXT pDevExt;
+ VBOXMP_CRSHGSMICON_BUFDR_CACHE WbDrCache;
+} VBOXMP_CRSHGSMITRANSPORT, *PVBOXMP_CRSHGSMITRANSPORT;
+
+/** the rx buffer passed here is only valid in the context of the callback.
+ * the callee must NOT free it or use outside of the callback context.
+ * */
+typedef DECLCALLBACK(void) FNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEREADASYNC_COMPLETION(PVBOXMP_CRSHGSMITRANSPORT pCon, int rc, void *pvRx, uint32_t cbRx, void *pvCtx);
+typedef FNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEREADASYNC_COMPLETION *PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEREADASYNC_COMPLETION;
+
+typedef DECLCALLBACK(void) FNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEASYNC_COMPLETION(PVBOXMP_CRSHGSMITRANSPORT pCon, int rc, void *pvCtx);
+typedef FNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEASYNC_COMPLETION *PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEASYNC_COMPLETION;
+
+int VBoxMpCrShgsmiTransportCreate(PVBOXMP_CRSHGSMITRANSPORT pCon, PVBOXMP_DEVEXT pDevExt);
+void VBoxMpCrShgsmiTransportTerm(PVBOXMP_CRSHGSMITRANSPORT pCon);
+void* VBoxMpCrShgsmiTransportCmdCreateWriteReadAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, uint32_t u32ClientID, void *pvBuffer, uint32_t cbBuffer,
+ PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEREADASYNC_COMPLETION pfnCompletion, uint32_t cbContextData);
+void* VBoxMpCrShgsmiTransportCmdCreateWriteAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, uint32_t u32ClientID, void *pvBuffer, uint32_t cbBuffer,
+ PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEASYNC_COMPLETION pfnCompletion, uint32_t cbContextData);
+int VBoxMpCrShgsmiTransportCmdSubmitWriteReadAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, void *pvContext);
+int VBoxMpCrShgsmiTransportCmdSubmitWriteAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, void *pvContext);
+void VBoxMpCrShgsmiTransportCmdTermWriteReadAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, void *pvContext);
+void VBoxMpCrShgsmiTransportCmdTermWriteAsync(PVBOXMP_CRSHGSMITRANSPORT pCon, void *pvContext);
+
+void* VBoxMpCrShgsmiTransportBufAlloc(PVBOXMP_CRSHGSMITRANSPORT pCon, uint32_t cbBuffer);
+void VBoxMpCrShgsmiTransportBufFree(PVBOXMP_CRSHGSMITRANSPORT pCon, void* pvBuffer);
+
+typedef struct VBOXMP_CRPACKER
+{
+ CRPackContext CrPacker;
+ CRPackBuffer CrBuffer;
+} VBOXMP_CRPACKER, *PVBOXMP_CRPACKER;
+
+DECLINLINE(void) VBoxMpCrPackerInit(PVBOXMP_CRPACKER pPacker)
+{
+ memset(pPacker, 0, sizeof (*pPacker));
+}
+
+DECLINLINE(void) VBoxMpCrPackerTerm(PVBOXMP_CRPACKER pPacker)
+{}
+
+DECLINLINE(void) VBoxMpCrPackerTxBufferInit(PVBOXMP_CRPACKER pPacker, void *pvBuffer, uint32_t cbBuffer, uint32_t cCommands)
+{
+ crPackInitBuffer(&pPacker->CrBuffer, pvBuffer, cbBuffer, cbBuffer, cCommands);
+ crPackSetBuffer(&pPacker->CrPacker, &pPacker->CrBuffer);
+}
+
+DECLINLINE(CRMessageOpcodes*) vboxMpCrPackerPrependHeader( const CRPackBuffer *pBuffer, uint32_t *cbData, void **ppvPackBuffer)
+{
+ UINT num_opcodes;
+ CRMessageOpcodes *hdr;
+
+ Assert(pBuffer);
+ Assert(pBuffer->opcode_current < pBuffer->opcode_start);
+ Assert(pBuffer->opcode_current >= pBuffer->opcode_end);
+ Assert(pBuffer->data_current > pBuffer->data_start);
+ Assert(pBuffer->data_current <= pBuffer->data_end);
+
+ num_opcodes = (UINT)(pBuffer->opcode_start - pBuffer->opcode_current);
+ hdr = (CRMessageOpcodes *)
+ ( pBuffer->data_start - ( ( num_opcodes + 3 ) & ~0x3 ) - sizeof(*hdr) );
+
+ Assert((void *) hdr >= pBuffer->pack);
+
+ hdr->header.type = CR_MESSAGE_OPCODES;
+ hdr->numOpcodes = num_opcodes;
+
+ *cbData = (UINT)(pBuffer->data_current - (unsigned char *) hdr);
+ *ppvPackBuffer = pBuffer->pack;
+
+ return hdr;
+}
+
+DECLINLINE(void*) VBoxMpCrPackerTxBufferComplete(PVBOXMP_CRPACKER pPacker, uint32_t *pcbBuffer, void **ppvPackBuffer)
+{
+ crPackReleaseBuffer(&pPacker->CrPacker);
+ uint32_t cbData;
+ CRMessageOpcodes *pHdr;
+ void *pvPackBuffer;
+ if (pPacker->CrBuffer.opcode_current != pPacker->CrBuffer.opcode_start)
+ pHdr = vboxMpCrPackerPrependHeader(&pPacker->CrBuffer, &cbData, &pvPackBuffer);
+ else
+ {
+ cbData = 0;
+ pHdr = NULL;
+ pvPackBuffer = NULL;
+ }
+ *pcbBuffer = cbData;
+ *ppvPackBuffer = pvPackBuffer;
+ return pHdr;
+}
+
+DECLINLINE(uint32_t) VBoxMpCrPackerTxBufferGetFreeBufferSize(PVBOXMP_CRPACKER pPacker)
+{
+ return (uint32_t)(pPacker->CrBuffer.data_end - pPacker->CrBuffer.data_start);
+}
+
+DECLINLINE(void) vboxMpCrUnpackerRxWriteback(CRMessageWriteback *pWb)
+{
+ int *pWriteback;
+ memcpy(&pWriteback, &(pWb->writeback_ptr), sizeof (pWriteback));
+ (*pWriteback)--;
+}
+
+DECLINLINE(void) vboxMpCrUnpackerRxReadback(CRMessageReadback *pRb, uint32_t cbRx)
+{
+ int cbPayload = cbRx - sizeof (*pRb);
+ int *pWriteback;
+ void *pDst;
+ memcpy(&pWriteback, &(pRb->writeback_ptr), sizeof (pWriteback));
+ memcpy(&pDst, &(pRb->readback_ptr), sizeof (pDst));
+
+ (*pWriteback)--;
+ memcpy(pDst, ((uint8_t*)pRb) + sizeof (*pRb), cbPayload);
+}
+
+DECLINLINE(int) VBoxMpCrUnpackerRxBufferProcess(void *pvBuffer, uint32_t cbBuffer)
+{
+ CRMessage *pMsg = (CRMessage*)pvBuffer;
+ switch (pMsg->header.type)
+ {
+ case CR_MESSAGE_WRITEBACK:
+ vboxMpCrUnpackerRxWriteback(&(pMsg->writeback));
+ return VINF_SUCCESS;
+ case CR_MESSAGE_READBACK:
+ vboxMpCrUnpackerRxReadback(&(pMsg->readback), cbBuffer);
+ return VINF_SUCCESS;
+ default:
+ WARN(("unknown msg code %d", pMsg->header.type));
+ return VERR_NOT_SUPPORTED;
+ }
+}
+
+DECLINLINE(void*) VBoxMpCrCmdRxReadbackData(CRMessageReadback *pRx)
+{
+ return (void*)(pRx+1);
+}
+
+DECLINLINE(uint32_t) VBoxMpCrCmdRxReadbackDataSize(CRMessageReadback *pRx, uint32_t cbRx)
+{
+ return cbRx - sizeof (*pRx);
+}
+int VBoxMpCrCmdRxReadbackHandler(CRMessageReadback *pRx, uint32_t cbRx);
+int VBoxMpCrCmdRxHandler(CRMessageHeader *pRx, uint32_t cbRx);
+
+/* must be called after calling VBoxMpCrCtlConIs3DSupported only */
+uint32_t VBoxMpCrGetHostCaps();
+
+#define VBOXMP_CRCMD_HEADER_SIZE sizeof (CRMessageOpcodes)
+/* last +4 below is 4-aligned command opcode size (i.e. ((1 + 3) & ~3)) */
+#define VBOXMP_CRCMD_SIZE_WINDOWPOSITION (20 + 4)
+#define VBOXMP_CRCMD_SIZE_WINDOWVISIBLEREGIONS(_cRects) (16 + (_cRects) * 4 * sizeof (GLint) + 4)
+#define VBOXMP_CRCMD_SIZE_VBOXTEXPRESENT(_cRects) (28 + (_cRects) * 4 * sizeof (GLint) + 4)
+#define VBOXMP_CRCMD_SIZE_WINDOWSHOW (16 + 4)
+#define VBOXMP_CRCMD_SIZE_WINDOWSIZE (20 + 4)
+#define VBOXMP_CRCMD_SIZE_GETCHROMIUMPARAMETERVCR (36 + 4)
+#define VBOXMP_CRCMD_SIZE_CHROMIUMPARAMETERICR (16 + 4)
+#define VBOXMP_CRCMD_SIZE_WINDOWCREATE (256 + 28 + 4)
+#define VBOXMP_CRCMD_SIZE_WINDOWDESTROY (12 + 4)
+#define VBOXMP_CRCMD_SIZE_CREATECONTEXT (256 + 32 + 4)
+#define VBOXMP_CRCMD_SIZE_DESTROYCONTEXT (12 + 4)
+
#endif /* #ifndef ___VBoxMPCr_h__ */
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCrUtil.cpp b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCrUtil.cpp
index fdcea8d3..0eca622c 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCrUtil.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCrUtil.cpp
@@ -31,7 +31,10 @@ DECLEXPORT(void) crMemset( void *ptr, int value, unsigned int bytes );
DECLEXPORT(void) crMemZero( void *ptr, unsigned int bytes );
DECLEXPORT(int) crMemcmp( const void *p1, const void *p2, unsigned int bytes );
DECLEXPORT(void) crDebug(const char *format, ... );
+#ifndef DEBUG_misha
DECLEXPORT(void) crWarning(const char *format, ... );
+#endif
+
DECLEXPORT(void) crInfo(const char *format, ... );
DECLEXPORT(void) crError(const char *format, ... );
@@ -73,10 +76,12 @@ DECLEXPORT(void) crDebug(const char *format, ... )
}
+#ifndef DEBUG_misha
DECLEXPORT(void) crWarning(const char *format, ... )
{
}
+#endif
DECLEXPORT(void) crInfo(const char *format, ... )
{
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.cpp b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.cpp
index 83f8ca21..b6d74cd6 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -193,7 +193,7 @@ PVBOXWDDM_SWAPCHAIN vboxWddmSwapchainCreate(UINT w, UINT h)
pSwapchain->Pos.x = pSwapchain->Pos.y = VBOXWDDM_INVALID_COORD;
pSwapchain->width = w;
pSwapchain->height = h;
- VBoxWddmVrListInit(&pSwapchain->VisibleRegions);
+ VBoxVrListInit(&pSwapchain->VisibleRegions);
}
return pSwapchain;
}
@@ -208,7 +208,7 @@ DECLINLINE(BOOLEAN) vboxWddmSwapchainRetainLocked(PVBOXWDDM_SWAPCHAIN pSwapchain
return FALSE;
}
-DECLINLINE(BOOLEAN) vboxWddmSwapchainRetain(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain)
+BOOLEAN vboxWddmSwapchainRetain(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain)
{
KIRQL OldIrql;
BOOLEAN bRc;
@@ -218,35 +218,40 @@ DECLINLINE(BOOLEAN) vboxWddmSwapchainRetain(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SW
return bRc;
}
-DECLINLINE(VOID) vboxWddmSwapchainRelease(PVBOXWDDM_SWAPCHAIN pSwapchain)
+VOID vboxWddmSwapchainRelease(PVBOXWDDM_SWAPCHAIN pSwapchain)
{
const uint32_t cRefs = ASMAtomicDecU32(&pSwapchain->cRefs);
Assert(cRefs < UINT32_MAX/2);
if (!cRefs)
{
- VBoxWddmVrListClear(&pSwapchain->VisibleRegions);
+ VBoxVrListClear(&pSwapchain->VisibleRegions);
vboxWddmMemFree(pSwapchain);
}
}
-PVBOXWDDM_SWAPCHAIN vboxWddmSwapchainRetainByAlloc(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAlloc)
+PVBOXWDDM_SWAPCHAIN vboxWddmSwapchainRetainByAllocData(PVBOXMP_DEVEXT pDevExt, const struct VBOXWDDM_ALLOC_DATA *pAllocData)
{
KIRQL OldIrql;
PVBOXWDDM_SWAPCHAIN pSwapchain;
KeAcquireSpinLock(&pDevExt->SynchLock, &OldIrql);
- pSwapchain = pAlloc->pSwapchain;
+ pSwapchain = pAllocData->pSwapchain;
if (pSwapchain && !vboxWddmSwapchainRetainLocked(pSwapchain))
pSwapchain = NULL;
KeReleaseSpinLock(&pDevExt->SynchLock, OldIrql);
return pSwapchain;
}
+PVBOXWDDM_SWAPCHAIN vboxWddmSwapchainRetainByAlloc(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOCATION *pAlloc)
+{
+ return vboxWddmSwapchainRetainByAllocData(pDevExt, &pAlloc->AllocData);
+}
+
VOID vboxWddmSwapchainAllocRemove(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain, PVBOXWDDM_ALLOCATION pAlloc)
{
KIRQL OldIrql;
KeAcquireSpinLock(&pDevExt->SynchLock, &OldIrql);
- Assert(pAlloc->pSwapchain == pSwapchain);
- pAlloc->pSwapchain = NULL;
+ Assert(pAlloc->AllocData.pSwapchain == pSwapchain);
+ pAlloc->AllocData.pSwapchain = NULL;
RemoveEntryList(&pAlloc->SwapchainEntry);
KeReleaseSpinLock(&pDevExt->SynchLock, OldIrql);
vboxWddmSwapchainRelease(pSwapchain);
@@ -256,17 +261,17 @@ BOOLEAN vboxWddmSwapchainAllocAdd(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pS
{
KIRQL OldIrql;
BOOLEAN bRc;
- Assert(!pAlloc->pSwapchain);
+ Assert(!pAlloc->AllocData.pSwapchain);
KeAcquireSpinLock(&pDevExt->SynchLock, &OldIrql);
bRc = vboxWddmSwapchainRetainLocked(pSwapchain);
if (bRc)
{
- if (pAlloc->pSwapchain)
+ if (pAlloc->AllocData.pSwapchain)
{
RemoveEntryList(&pAlloc->SwapchainEntry);
}
InsertTailList(&pSwapchain->AllocList, &pAlloc->SwapchainEntry);
- pAlloc->pSwapchain = pSwapchain;
+ pAlloc->AllocData.pSwapchain = pSwapchain;
}
KeReleaseSpinLock(&pDevExt->SynchLock, OldIrql);
return bRc;
@@ -286,8 +291,8 @@ static VOID vboxWddmSwapchainAllocRemoveAllInternal(PVBOXMP_DEVEXT pDevExt, PVBO
{
PVBOXWDDM_ALLOCATION pAlloc = VBOXSCENTRY_2_ALLOC(pEntry);
pEntry = pEntry->Flink;
- Assert(pAlloc->pSwapchain == pSwapchain);
- pAlloc->pSwapchain = NULL;
+ Assert(pAlloc->AllocData.pSwapchain == pSwapchain);
+ pAlloc->AllocData.pSwapchain = NULL;
RemoveEntryList(&pAlloc->SwapchainEntry);
++cRemoved;
}
@@ -312,16 +317,6 @@ VOID vboxWddmSwapchainDestroy(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapc
{
vboxWddmSwapchainAllocRemoveAllInternal(pDevExt, pSwapchain, TRUE);
- Assert(pSwapchain->pContext);
- if (pSwapchain->pContext)
- {
- NTSTATUS tmpStatus = vboxVdmaGgCmdCancel(pDevExt, pSwapchain->pContext, pSwapchain);
- if (tmpStatus != STATUS_SUCCESS)
- {
- WARN(("vboxVdmaGgCmdCancel returned Status (0x%x)", tmpStatus));
- }
- }
-
vboxWddmSwapchainRelease(pSwapchain);
}
@@ -347,7 +342,7 @@ static VOID vboxWddmSwapchainCtxRemoveLocked(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_C
Assert(pTst == pSwapchain);
RemoveEntryList(&pSwapchain->DevExtListEntry);
pSwapchain->hSwapchainKm = NULL;
- VBoxWddmVrListClear(&pSwapchain->VisibleRegions);
+ VBoxVrListClear(&pSwapchain->VisibleRegions);
vboxWddmSwapchainRelease(pSwapchain);
}
@@ -356,9 +351,10 @@ static VOID vboxWddmSwapchainCtxRemoveLocked(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_C
BOOLEAN vboxWddmSwapchainCtxAdd(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXWDDM_SWAPCHAIN pSwapchain)
{
BOOLEAN bRc;
- ExAcquireFastMutex(&pDevExt->ContextMutex);
+ VBOXWDDM_CTXLOCK_DATA
+ VBOXWDDM_CTXLOCK_LOCK(pDevExt);
bRc = vboxWddmSwapchainCtxAddLocked(pDevExt, pContext, pSwapchain);
- ExReleaseFastMutex(&pDevExt->ContextMutex);
+ VBOXWDDM_CTXLOCK_UNLOCK(pDevExt);
return bRc;
}
@@ -366,9 +362,10 @@ BOOLEAN vboxWddmSwapchainCtxAdd(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pConte
* */
VOID vboxWddmSwapchainCtxRemove(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXWDDM_SWAPCHAIN pSwapchain)
{
- ExAcquireFastMutex(&pDevExt->ContextMutex);
+ VBOXWDDM_CTXLOCK_DATA
+ VBOXWDDM_CTXLOCK_LOCK(pDevExt);
vboxWddmSwapchainCtxRemoveLocked(pDevExt, pContext, pSwapchain);
- ExReleaseFastMutex(&pDevExt->ContextMutex);
+ VBOXWDDM_CTXLOCK_UNLOCK(pDevExt);
}
/* destroys all swapchains for the given context
@@ -376,9 +373,10 @@ VOID vboxWddmSwapchainCtxRemove(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pConte
VOID vboxWddmSwapchainCtxDestroyAll(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext)
{
VBOXWDDM_HTABLE_ITERATOR Iter;
+ VBOXWDDM_CTXLOCK_DATA
do
{
- ExAcquireFastMutex(&pDevExt->ContextMutex);
+ VBOXWDDM_CTXLOCK_LOCK(pDevExt);
vboxWddmHTableIterInit(&pContext->Swapchains, &Iter);
PVBOXWDDM_SWAPCHAIN pSwapchain = (PVBOXWDDM_SWAPCHAIN)vboxWddmHTableIterNext(&Iter, NULL);
if (!pSwapchain)
@@ -387,30 +385,48 @@ VOID vboxWddmSwapchainCtxDestroyAll(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pC
/* yes, we can call remove locked even when using iterator */
vboxWddmSwapchainCtxRemoveLocked(pDevExt, pContext, pSwapchain);
- ExReleaseFastMutex(&pDevExt->ContextMutex);
+ VBOXWDDM_CTXLOCK_UNLOCK(pDevExt);
/* we must not do vboxWddmSwapchainDestroy inside a context mutex */
vboxWddmSwapchainDestroy(pDevExt, pSwapchain);
/* start from the very beginning, we will quit the loop when no swapchains left */
} while (1);
/* no swapchains left, we exiteed the while loop via the "break", and we still owning the mutex */
- ExReleaseFastMutex(&pDevExt->ContextMutex);
+ VBOXWDDM_CTXLOCK_UNLOCK(pDevExt);
}
/* process the swapchain info passed from user-mode display driver & synchronizes the driver state with it */
NTSTATUS vboxWddmSwapchainCtxEscape(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXDISPIFESCAPE_SWAPCHAININFO pSwapchainInfo, UINT cbSize)
{
- Assert((cbSize >= RT_OFFSETOF(VBOXDISPIFESCAPE_SWAPCHAININFO, SwapchainInfo.ahAllocs[0])));
if (cbSize < RT_OFFSETOF(VBOXDISPIFESCAPE_SWAPCHAININFO, SwapchainInfo.ahAllocs[0]))
+ {
+ WARN(("invalid cbSize1 %d", cbSize));
return STATUS_INVALID_PARAMETER;
- Assert(cbSize >= RT_OFFSETOF(VBOXDISPIFESCAPE_SWAPCHAININFO, SwapchainInfo.ahAllocs[pSwapchainInfo->SwapchainInfo.cAllocs]));
+ }
+
if (cbSize < RT_OFFSETOF(VBOXDISPIFESCAPE_SWAPCHAININFO, SwapchainInfo.ahAllocs[pSwapchainInfo->SwapchainInfo.cAllocs]))
+ {
return STATUS_INVALID_PARAMETER;
+ WARN(("invalid cbSize2 %d", cbSize));
+ }
+
+ if (!pSwapchainInfo->SwapchainInfo.winHostID)
+ {
+ WARN(("Zero winHostID specified!"));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (!pContext)
+ {
+ WARN(("vboxWddmSwapchainCtxEscape: no context specified"));
+ return STATUS_INVALID_PARAMETER;
+ }
PVBOXWDDM_SWAPCHAIN pSwapchain = NULL;
PVBOXWDDM_ALLOCATION *apAlloc = NULL;
Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
NTSTATUS Status = STATUS_SUCCESS;
+ VBOXWDDM_CTXLOCK_DATA
do {
if (pSwapchainInfo->SwapchainInfo.cAllocs)
@@ -452,12 +468,12 @@ NTSTATUS vboxWddmSwapchainCtxEscape(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pC
if (pSwapchainInfo->SwapchainInfo.hSwapchainKm)
{
- ExAcquireFastMutex(&pDevExt->ContextMutex);
+ VBOXWDDM_CTXLOCK_LOCK(pDevExt);
pSwapchain = (PVBOXWDDM_SWAPCHAIN)vboxWddmHTableGet(&pContext->Swapchains, (VBOXWDDM_HANDLE)pSwapchainInfo->SwapchainInfo.hSwapchainKm);
Assert(pSwapchain);
if (!pSwapchain)
{
- ExReleaseFastMutex(&pDevExt->ContextMutex);
+ VBOXWDDM_CTXLOCK_UNLOCK(pDevExt);
Status = STATUS_INVALID_PARAMETER;
break;
}
@@ -465,7 +481,7 @@ NTSTATUS vboxWddmSwapchainCtxEscape(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pC
Assert(pSwapchain->pContext == pContext);
if (pSwapchain->pContext != pContext)
{
- ExReleaseFastMutex(&pDevExt->ContextMutex);
+ VBOXWDDM_CTXLOCK_UNLOCK(pDevExt);
Status = STATUS_INVALID_PARAMETER;
break;
}
@@ -479,7 +495,7 @@ NTSTATUS vboxWddmSwapchainCtxEscape(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pC
break;
}
- ExAcquireFastMutex(&pDevExt->ContextMutex);
+ VBOXWDDM_CTXLOCK_LOCK(pDevExt);
BOOLEAN bRc = vboxWddmSwapchainCtxAddLocked(pDevExt, pContext, pSwapchain);
Assert(bRc);
}
@@ -492,7 +508,7 @@ NTSTATUS vboxWddmSwapchainCtxEscape(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pC
/* do not zero up the view rect since it may still be valid */
// memset(&pSwapchain->ViewRect, 0, sizeof (pSwapchain->ViewRect));
/* @todo: do we really need to zero this up here ? */
- VBoxWddmVrListClear(&pSwapchain->VisibleRegions);
+ VBoxVrListClear(&pSwapchain->VisibleRegions);
vboxWddmSwapchainAllocRemoveAll(pDevExt, pSwapchain);
@@ -503,13 +519,18 @@ NTSTATUS vboxWddmSwapchainCtxEscape(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pC
vboxWddmSwapchainAllocAdd(pDevExt, pSwapchain, apAlloc[i]);
}
pSwapchain->hSwapchainUm = pSwapchainInfo->SwapchainInfo.hSwapchainUm;
+ if (pSwapchain->winHostID != pSwapchainInfo->SwapchainInfo.winHostID)
+ {
+ pSwapchain->fExposed = FALSE;
+ pSwapchain->winHostID = pSwapchainInfo->SwapchainInfo.winHostID;
+ }
}
else
{
vboxWddmSwapchainCtxRemoveLocked(pDevExt, pContext, pSwapchain);
}
- ExReleaseFastMutex(&pDevExt->ContextMutex);
+ VBOXWDDM_CTXLOCK_UNLOCK(pDevExt);
if (pSwapchainInfo->SwapchainInfo.cAllocs)
{
@@ -551,8 +572,6 @@ VOID vboxWddmSwapchainCtxTerm(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext
vboxWddmHTableDestroy(&pContext->Swapchains);
}
-#define VBOXWDDM_REG_DRVKEY_PREFIX L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\"
-
NTSTATUS vboxWddmRegQueryDrvKeyName(PVBOXMP_DEVEXT pDevExt, ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult)
{
WCHAR fallBackBuf[2];
@@ -585,13 +604,6 @@ NTSTATUS vboxWddmRegQueryDrvKeyName(PVBOXMP_DEVEXT pDevExt, ULONG cbBuf, PWCHAR
return Status;
}
-#define VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_VISTA L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Control\\VIDEO\\"
-#define VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_WIN7 L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\UnitedVideo\\CONTROL\\VIDEO\\"
-
-#define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_RELX L"Attach.RelativeX"
-#define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_RELY L"Attach.RelativeY"
-#define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_DESKTOP L"Attach.ToDesktop"
-
NTSTATUS vboxWddmRegQueryDisplaySettingsKeyName(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId,
ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult)
{
@@ -613,7 +625,7 @@ NTSTATUS vboxWddmRegQueryDisplaySettingsKeyName(PVBOXMP_DEVEXT pDevExt, D3DDDI_V
}
else
{
- Assert(ver == WIN7 || ver == WIN8);
+ Assert(ver == WIN7 || ver == WIN8 || ver == WIN81);
pKeyPrefix = VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_WIN7;
cbKeyPrefix = sizeof (VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_WIN7);
}
@@ -639,13 +651,61 @@ NTSTATUS vboxWddmRegQueryDisplaySettingsKeyName(PVBOXMP_DEVEXT pDevExt, D3DDDI_V
return Status;
}
-#define VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\"
-#define VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY_SUBKEY L"\\Video"
-
-NTSTATUS vboxWddmRegQueryVideoGuidString(ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult)
+NTSTATUS vboxWddmRegQueryVideoGuidString(PVBOXMP_DEVEXT pDevExt, ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult)
{
- HANDLE hKey;
- NTSTATUS Status = vboxWddmRegOpenKey(&hKey, VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY, GENERIC_READ);
+ BOOLEAN fNewMethodSucceeded = FALSE;
+ HANDLE hKey = NULL;
+ NTSTATUS Status = IoOpenDeviceRegistryKey(pDevExt->pPDO, PLUGPLAY_REGKEY_DEVICE, GENERIC_READ, &hKey);
+ if (NT_SUCCESS(Status))
+ {
+ struct
+ {
+ KEY_VALUE_PARTIAL_INFORMATION Info;
+ UCHAR Buf[1024]; /* should be enough */
+ } KeyData;
+ ULONG cbResult;
+ UNICODE_STRING RtlStr;
+ RtlInitUnicodeString(&RtlStr, L"VideoID");
+ Status = ZwQueryValueKey(hKey,
+ &RtlStr,
+ KeyValuePartialInformation,
+ &KeyData.Info,
+ sizeof(KeyData),
+ &cbResult);
+ if (NT_SUCCESS(Status))
+ {
+ if (KeyData.Info.Type == REG_SZ)
+ {
+ fNewMethodSucceeded = TRUE;
+ *pcbResult = KeyData.Info.DataLength + 2;
+ if (cbBuf >= KeyData.Info.DataLength)
+ {
+ memcpy(pBuf, KeyData.Info.Data, KeyData.Info.DataLength + 2);
+ Status = STATUS_SUCCESS;
+ }
+ else
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ }
+ else
+ {
+ WARN(("ZwQueryValueKey failed, Status 0x%x", Status));
+ }
+
+ NTSTATUS tmpStatus = ZwClose(hKey);
+ Assert(tmpStatus == STATUS_SUCCESS);
+ }
+ else
+ {
+ WARN(("IoOpenDeviceRegistryKey failed Status 0x%x", Status));
+ }
+
+ if (fNewMethodSucceeded)
+ return Status;
+ else
+ WARN(("failed to acquire the VideoID, falling back to the old impl"));
+
+ Status = vboxWddmRegOpenKey(&hKey, VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY, GENERIC_READ);
Assert(Status == STATUS_SUCCESS);
if (Status == STATUS_SUCCESS)
{
@@ -727,17 +787,22 @@ NTSTATUS vboxWddmRegQueryVideoGuidString(ULONG cbBuf, PWCHAR pBuf, PULONG pcbRes
return Status;
}
-NTSTATUS vboxWddmRegOpenKey(OUT PHANDLE phKey, IN PWCHAR pName, IN ACCESS_MASK fAccess)
+NTSTATUS vboxWddmRegOpenKeyEx(OUT PHANDLE phKey, IN HANDLE hRootKey, IN PWCHAR pName, IN ACCESS_MASK fAccess)
{
OBJECT_ATTRIBUTES ObjAttr;
UNICODE_STRING RtlStr;
RtlInitUnicodeString(&RtlStr, pName);
- InitializeObjectAttributes(&ObjAttr, &RtlStr, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
+ InitializeObjectAttributes(&ObjAttr, &RtlStr, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, hRootKey, NULL);
return ZwOpenKey(phKey, fAccess, &ObjAttr);
}
+NTSTATUS vboxWddmRegOpenKey(OUT PHANDLE phKey, IN PWCHAR pName, IN ACCESS_MASK fAccess)
+{
+ return vboxWddmRegOpenKeyEx(phKey, NULL, pName, fAccess);
+}
+
NTSTATUS vboxWddmRegOpenDisplaySettingsKey(IN PVBOXMP_DEVEXT pDeviceExtension, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, OUT PHANDLE phKey)
{
WCHAR Buf[512];
@@ -813,6 +878,50 @@ NTSTATUS vboxWddmDisplaySettingsQueryPos(IN PVBOXMP_DEVEXT pDeviceExtension, D3D
return Status;
}
+NTSTATUS vboxWddmRegDrvFlagsSet(PVBOXMP_DEVEXT pDevExt, DWORD fVal)
+{
+ HANDLE hKey = NULL;
+ NTSTATUS Status = IoOpenDeviceRegistryKey(pDevExt->pPDO, PLUGPLAY_REGKEY_DRIVER, GENERIC_WRITE, &hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("IoOpenDeviceRegistryKey failed, Status = 0x%x", Status));
+ return Status;
+ }
+
+ Status = vboxWddmRegSetValueDword(hKey, VBOXWDDM_REG_DRV_FLAGS_NAME, fVal);
+ if (!NT_SUCCESS(Status))
+ WARN(("vboxWddmRegSetValueDword failed, Status = 0x%x", Status));
+
+ NTSTATUS tmpStatus = ZwClose(hKey);
+ Assert(tmpStatus == STATUS_SUCCESS);
+
+ return Status;
+}
+
+DWORD vboxWddmRegDrvFlagsGet(PVBOXMP_DEVEXT pDevExt, DWORD fDefault)
+{
+ HANDLE hKey = NULL;
+ NTSTATUS Status = IoOpenDeviceRegistryKey(pDevExt->pPDO, PLUGPLAY_REGKEY_DRIVER, GENERIC_READ, &hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("IoOpenDeviceRegistryKey failed, Status = 0x%x", Status));
+ return fDefault;
+ }
+
+ DWORD dwVal = 0;
+ Status = vboxWddmRegQueryValueDword(hKey, VBOXWDDM_REG_DRV_FLAGS_NAME, &dwVal);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("vboxWddmRegQueryValueDword failed, Status = 0x%x", Status));
+ dwVal = fDefault;
+ }
+
+ NTSTATUS tmpStatus = ZwClose(hKey);
+ Assert(tmpStatus == STATUS_SUCCESS);
+
+ return dwVal;
+}
+
NTSTATUS vboxWddmRegQueryValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT PDWORD pDword)
{
struct
@@ -842,7 +951,7 @@ NTSTATUS vboxWddmRegQueryValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT PDWORD
return STATUS_INVALID_PARAMETER;
}
-NTSTATUS vboxWddmRegSetValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT DWORD val)
+NTSTATUS vboxWddmRegSetValueDword(IN HANDLE hKey, IN PWCHAR pName, IN DWORD val)
{
UNICODE_STRING RtlStr;
RtlInitUnicodeString(&RtlStr, pName);
@@ -861,7 +970,7 @@ UNICODE_STRING* vboxWddmVGuidGet(PVBOXMP_DEVEXT pDevExt)
Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
WCHAR VideoGuidBuf[512];
ULONG cbVideoGuidBuf = sizeof (VideoGuidBuf);
- NTSTATUS Status = vboxWddmRegQueryVideoGuidString(cbVideoGuidBuf, VideoGuidBuf, &cbVideoGuidBuf);
+ NTSTATUS Status = vboxWddmRegQueryVideoGuidString(pDevExt ,cbVideoGuidBuf, VideoGuidBuf, &cbVideoGuidBuf);
Assert(Status == STATUS_SUCCESS);
if (Status == STATUS_SUCCESS)
{
@@ -1240,7 +1349,7 @@ NTSTATUS vboxVideoAMgrCtxAllocSubmit(PVBOXMP_DEVEXT pDevExt, PVBOXVIDEOCM_ALLOC_
NTSTATUS Status = STATUS_SUCCESS;
UINT cbCmd = VBOXVDMACMD_SIZE_FROMBODYSIZE(RT_OFFSETOF(VBOXVDMACMD_CHROMIUM_CMD, aBuffers[cBuffers]));
- PVBOXVDMACBUF_DR pDr = vboxVdmaCBufDrCreate (&pDevExt->u.primary.Vdma, cbCmd);
+ PVBOXVDMACBUF_DR pDr = vboxVdmaCBufDrCreate(&pDevExt->u.primary.Vdma, cbCmd);
if (pDr)
{
// vboxVdmaCBufDrCreate zero initializes the pDr
@@ -1265,7 +1374,7 @@ NTSTATUS vboxVideoAMgrCtxAllocSubmit(PVBOXMP_DEVEXT pDevExt, PVBOXVIDEOCM_ALLOC_
#endif
pBufCmd->offBuffer = pRef->pAlloc->offData + pBufInfo->Info.offData;
pBufCmd->cbBuffer = pBufInfo->Info.cbData;
- pBufCmd->u32GuestData = pBufInfo->Info.bDoNotSignalCompletion;
+ pBufCmd->u32GuestData = 0;
pBufCmd->u64GuestData = (uint64_t)pRef;
}
else
@@ -1402,6 +1511,8 @@ NTSTATUS vboxVideoAMgrCtxDestroy(PVBOXVIDEOCM_ALLOC_CONTEXT pCtx)
if (!pRef)
break;
+ Assert(0);
+
Status = vboxVideoAMgrCtxAllocDestroy(pCtx, pRef->hSessionHandle);
Assert(Status == STATUS_SUCCESS);
if (Status != STATUS_SUCCESS)
@@ -1598,750 +1709,6 @@ BOOLEAN vboxShRcTreeRemove(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAlloc)
}
#endif
-
-/* visible rects */
-typedef struct VBOXWDDMVR_REG
-{
- LIST_ENTRY ListEntry;
- RECT Rect;
-} VBOXWDDMVR_REG, *PVBOXWDDMVR_REG;
-
-#define PVBOXWDDMVR_REG_FROM_ENTRY(_pEntry) ((PVBOXWDDMVR_REG)(((uint8_t*)(_pEntry)) - RT_OFFSETOF(VBOXWDDMVR_REG, ListEntry)))
-
-#ifdef DEBUG_misha
-//# define VBOXVDBG_VR_LAL_DISABLE
-#endif
-
-#ifndef VBOXVDBG_VR_LAL_DISABLE
-static LOOKASIDE_LIST_EX g_VBoxWddmVrLookasideList;
-#endif
-
-static PVBOXWDDMVR_REG vboxWddmVrRegCreate()
-{
-#ifndef VBOXVDBG_VR_LAL_DISABLE
- PVBOXWDDMVR_REG pReg = (PVBOXWDDMVR_REG)ExAllocateFromLookasideListEx(&g_VBoxWddmVrLookasideList);
- if (!pReg)
- {
- WARN(("ExAllocateFromLookasideListEx failed!"));
- }
- return pReg;
-#else
- return (PVBOXWDDMVR_REG)vboxWddmMemAlloc(sizeof (VBOXWDDMVR_REG));
-#endif
-}
-
-static void vboxWddmVrRegTerm(PVBOXWDDMVR_REG pReg)
-{
-#ifndef VBOXVDBG_VR_LAL_DISABLE
- ExFreeToLookasideListEx(&g_VBoxWddmVrLookasideList, pReg);
-#else
- vboxWddmMemFree(pReg);
-#endif
-}
-
-void VBoxWddmVrListClear(PVBOXWDDMVR_LIST pList)
-{
- PLIST_ENTRY pNext;
- for (PLIST_ENTRY pEntry = pList->ListHead.Flink; pEntry != &pList->ListHead; pEntry = pNext)
- {
- pNext = pEntry->Flink;
- PVBOXWDDMVR_REG pReg = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry);
- vboxWddmVrRegTerm(pReg);
- }
- VBoxWddmVrListInit(pList);
-}
-
-#define VBOXWDDMVR_MEMTAG 'vDBV'
-
-NTSTATUS VBoxWddmVrInit()
-{
-#ifndef VBOXVDBG_VR_LAL_DISABLE
- NTSTATUS Status = ExInitializeLookasideListEx(&g_VBoxWddmVrLookasideList,
- NULL, /* PALLOCATE_FUNCTION_EX Allocate */
- NULL, /* PFREE_FUNCTION_EX Free */
- NonPagedPool,
- 0, /* ULONG Flags */
- sizeof (VBOXWDDMVR_REG),
- VBOXWDDMVR_MEMTAG,
- 0 /* USHORT Depth - reserved, must be null */
- );
- if (!NT_SUCCESS(Status))
- {
- WARN(("ExInitializeLookasideListEx failed, Status (0x%x)", Status));
- return Status;
- }
-#endif
-
- return STATUS_SUCCESS;
-}
-
-void VBoxWddmVrTerm()
-{
-#ifndef VBOXVDBG_VR_LAL_DISABLE
- ExDeleteLookasideListEx(&g_VBoxWddmVrLookasideList);
-#endif
-}
-
-typedef DECLCALLBACK(int) FNVBOXWDDMVR_CB_COMPARATOR(const PVBOXWDDMVR_REG pReg1, const PVBOXWDDMVR_REG pReg2);
-typedef FNVBOXWDDMVR_CB_COMPARATOR *PFNVBOXWDDMVR_CB_COMPARATOR;
-
-static DECLCALLBACK(int) vboxWddmVrRegNonintersectedComparator(const RECT* pRect1, const RECT* pRect2)
-{
- Assert(!vboxWddmRectIsIntersect(pRect1, pRect2));
- if (pRect1->top != pRect2->top)
- return pRect1->top - pRect2->top;
- return pRect1->left - pRect2->left;
-}
-
-#ifdef DEBUG_misha
-static void vboxWddmVrDbgListDoVerify(PVBOXWDDMVR_LIST pList)
-{
- PLIST_ENTRY pEntry1 = pList->ListHead.Flink;
-
- for (PLIST_ENTRY pEntry1 = pList->ListHead.Flink; pEntry1 != &pList->ListHead; pEntry1 = pEntry1->Flink)
- {
- PVBOXWDDMVR_REG pReg1 = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry1);
- for (PLIST_ENTRY pEntry2 = pEntry1->Flink; pEntry2 != &pList->ListHead; pEntry2 = pEntry2->Flink)
- {
- PVBOXWDDMVR_REG pReg2 = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry2);
- Assert(vboxWddmVrRegNonintersectedComparator(&pReg1->Rect, &pReg2->Rect) < 0);
- }
- }
-}
-
-#define vboxWddmVrDbgListVerify vboxWddmVrDbgListDoVerify
-#else
-#define vboxWddmVrDbgListVerify(_p) do {} while (0)
-#endif
-
-static NTSTATUS vboxWddmVrListUniteIntersection(PVBOXWDDMVR_LIST pList, PVBOXWDDMVR_LIST pIntersection);
-
-#define VBOXWDDMVR_INVALID_COORD (~0UL)
-
-DECLINLINE(void) vboxWddmVrListRegAdd(PVBOXWDDMVR_LIST pList, PVBOXWDDMVR_REG pReg, PLIST_ENTRY pPlace, BOOLEAN fAfter)
-{
- if (fAfter)
- InsertHeadList(pPlace, &pReg->ListEntry);
- else
- InsertTailList(pPlace, &pReg->ListEntry);
- ++pList->cEntries;
- vboxWddmVrDbgListVerify(pList);
-}
-
-DECLINLINE(void) vboxWddmVrListRegRemove(PVBOXWDDMVR_LIST pList, PVBOXWDDMVR_REG pReg)
-{
- RemoveEntryList(&pReg->ListEntry);
- --pList->cEntries;
-}
-
-static void vboxWddmVrListRegAddOrder(PVBOXWDDMVR_LIST pList, PLIST_ENTRY pMemberEntry, PVBOXWDDMVR_REG pReg)
-{
- do
- {
- if (pMemberEntry != &pList->ListHead)
- {
- PVBOXWDDMVR_REG pMemberReg = PVBOXWDDMVR_REG_FROM_ENTRY(pMemberEntry);
- if (vboxWddmVrRegNonintersectedComparator(&pMemberReg->Rect, &pReg->Rect) < 0)
- {
- pMemberEntry = pMemberEntry->Flink;
- continue;
- }
- }
- vboxWddmVrListRegAdd(pList, pReg, pMemberEntry, FALSE);
- break;
- } while (1);
-}
-
-static void vboxWddmVrListAddNonintersected(PVBOXWDDMVR_LIST pList1, PVBOXWDDMVR_LIST pList2)
-{
- PLIST_ENTRY pEntry1 = pList1->ListHead.Flink;
-
- for (PLIST_ENTRY pEntry2 = pList2->ListHead.Flink; pEntry2 != &pList2->ListHead; pEntry2 = pList2->ListHead.Flink)
- {
- PVBOXWDDMVR_REG pReg2 = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry2);
- do {
- if (pEntry1 != &pList1->ListHead)
- {
- PVBOXWDDMVR_REG pReg1 = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry1);
- if (vboxWddmVrRegNonintersectedComparator(&pReg1->Rect, &pReg2->Rect) < 0)
- {
- pEntry1 = pEntry1->Flink;
- continue;
- }
- }
- vboxWddmVrListRegRemove(pList2, pReg2);
- vboxWddmVrListRegAdd(pList1, pReg2, pEntry1, FALSE);
- break;
- } while (1);
- }
-
- Assert(VBoxWddmVrListIsEmpty(pList2));
-}
-
-static NTSTATUS vboxWddmVrListRegIntersectSubstNoJoin(PVBOXWDDMVR_LIST pList1, PVBOXWDDMVR_REG pReg1, const RECT * pRect2)
-{
- UINT topLim = VBOXWDDMVR_INVALID_COORD;
- UINT bottomLim = VBOXWDDMVR_INVALID_COORD;
- LIST_ENTRY List;
- PVBOXWDDMVR_REG pBottomReg = NULL;
-#ifdef DEBUG_misha
- RECT tmpRect = pReg1->Rect;
- vboxWddmVrDbgListVerify(pList1);
-#endif
-
- InitializeListHead(&List);
-
- Assert(vboxWddmRectIsIntersect(&pReg1->Rect, pRect2));
-
- if (pReg1->Rect.top < pRect2->top)
- {
- Assert(pRect2->top < pReg1->Rect.bottom);
- PVBOXWDDMVR_REG pRegResult = vboxWddmVrRegCreate();
- pRegResult->Rect.top = pReg1->Rect.top;
- pRegResult->Rect.left = pReg1->Rect.left;
- pRegResult->Rect.bottom = pRect2->top;
- pRegResult->Rect.right = pReg1->Rect.right;
- topLim = pRect2->top;
- InsertTailList(&List, &pRegResult->ListEntry);
- }
-
- if (pReg1->Rect.bottom > pRect2->bottom)
- {
- Assert(pRect2->bottom > pReg1->Rect.top);
- PVBOXWDDMVR_REG pRegResult = vboxWddmVrRegCreate();
- pRegResult->Rect.top = pRect2->bottom;
- pRegResult->Rect.left = pReg1->Rect.left;
- pRegResult->Rect.bottom = pReg1->Rect.bottom;
- pRegResult->Rect.right = pReg1->Rect.right;
- bottomLim = pRect2->bottom;
- pBottomReg = pRegResult;
- }
-
- if (pReg1->Rect.left < pRect2->left)
- {
- Assert(pRect2->left < pReg1->Rect.right);
- PVBOXWDDMVR_REG pRegResult = vboxWddmVrRegCreate();
- pRegResult->Rect.top = topLim == VBOXWDDMVR_INVALID_COORD ? pReg1->Rect.top : topLim;
- pRegResult->Rect.left = pReg1->Rect.left;
- pRegResult->Rect.bottom = bottomLim == VBOXWDDMVR_INVALID_COORD ? pReg1->Rect.bottom : bottomLim;
- pRegResult->Rect.right = pRect2->left;
- InsertTailList(&List, &pRegResult->ListEntry);
- }
-
- if (pReg1->Rect.right > pRect2->right)
- {
- Assert(pRect2->right > pReg1->Rect.left);
- PVBOXWDDMVR_REG pRegResult = vboxWddmVrRegCreate();
- pRegResult->Rect.top = topLim == VBOXWDDMVR_INVALID_COORD ? pReg1->Rect.top : topLim;
- pRegResult->Rect.left = pRect2->right;
- pRegResult->Rect.bottom = bottomLim == VBOXWDDMVR_INVALID_COORD ? pReg1->Rect.bottom : bottomLim;
- pRegResult->Rect.right = pReg1->Rect.right;
- InsertTailList(&List, &pRegResult->ListEntry);
- }
-
- if (pBottomReg)
- InsertTailList(&List, &pBottomReg->ListEntry);
-
- PLIST_ENTRY pMemberEntry = pReg1->ListEntry.Flink;
- vboxWddmVrListRegRemove(pList1, pReg1);
- vboxWddmVrRegTerm(pReg1);
-
- if (IsListEmpty(&List))
- return STATUS_SUCCESS; /* the region is covered by the pRect2 */
-
- PLIST_ENTRY pEntry = List.Flink, pNext;
- for (; pEntry != &List; pEntry = pNext)
- {
- pNext = pEntry->Flink;
- PVBOXWDDMVR_REG pReg = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry);
-
- vboxWddmVrListRegAddOrder(pList1, pMemberEntry, pReg);
- pMemberEntry = pEntry->Flink; /* the following elements should go after the given pEntry since they are ordered already */
- }
- return STATUS_SUCCESS;
-}
-
-typedef DECLCALLBACK(PLIST_ENTRY) FNVBOXWDDMVR_CB_INTERSECTED_VISITOR(PVBOXWDDMVR_LIST pList1, PVBOXWDDMVR_REG pReg1, const RECT * pRect2, void *pvContext, PLIST_ENTRY *ppNext);
-typedef FNVBOXWDDMVR_CB_INTERSECTED_VISITOR *PFNVBOXWDDMVR_CB_INTERSECTED_VISITOR;
-
-static void vboxWddmVrListVisitIntersected(PVBOXWDDMVR_LIST pList1, UINT cRects, const RECT *aRects, PFNVBOXWDDMVR_CB_INTERSECTED_VISITOR pfnVisitor, void* pvVisitor)
-{
- PLIST_ENTRY pEntry1 = pList1->ListHead.Flink;
- PLIST_ENTRY pNext1;
- UINT iFirst2 = 0;
-
- for (; pEntry1 != &pList1->ListHead; pEntry1 = pNext1)
- {
- pNext1 = pEntry1->Flink;
- PVBOXWDDMVR_REG pReg1 = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry1);
- for (UINT i = iFirst2; i < cRects; ++i)
- {
- const RECT *pRect2 = &aRects[i];
- if (pReg1->Rect.bottom <= pRect2->top)
- continue;
- else if (pRect2->bottom <= pReg1->Rect.top)
- continue;
- /* y coords intersect */
- else if (pReg1->Rect.right <= pRect2->left)
- continue;
- else if (pRect2->right <= pReg1->Rect.left)
- continue;
- /* x coords intersect */
-
- /* the visitor can modify the list 1, apply necessary adjustments after it */
- PLIST_ENTRY pEntry1 = pfnVisitor (pList1, pReg1, pRect2, pvVisitor, &pNext1);
- if (pEntry1 == &pList1->ListHead)
- break;
- }
- }
-}
-
-
-static void vboxWddmVrListJoinRectsHV(PVBOXWDDMVR_LIST pList, BOOLEAN fHorizontal)
-{
- PLIST_ENTRY pNext1, pNext2;
-
- for (PLIST_ENTRY pEntry1 = pList->ListHead.Flink; pEntry1 != &pList->ListHead; pEntry1 = pNext1)
- {
- PVBOXWDDMVR_REG pReg1 = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry1);
- pNext1 = pEntry1->Flink;
- for (PLIST_ENTRY pEntry2 = pEntry1->Flink; pEntry2 != &pList->ListHead; pEntry2 = pNext2)
- {
- PVBOXWDDMVR_REG pReg2 = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry2);
- pNext2 = pEntry2->Flink;
- if (fHorizontal)
- {
- if (pReg1->Rect.top == pReg2->Rect.top)
- {
- if (pReg1->Rect.right == pReg2->Rect.left)
- {
- /* join rectangles */
- vboxWddmVrListRegRemove(pList, pReg2);
- if (pReg1->Rect.bottom > pReg2->Rect.bottom)
- {
- LONG oldRight1 = pReg1->Rect.right;
- LONG oldBottom1 = pReg1->Rect.bottom;
- pReg1->Rect.right = pReg2->Rect.right;
- pReg1->Rect.bottom = pReg2->Rect.bottom;
-
- vboxWddmVrDbgListVerify(pList);
-
- pReg2->Rect.left = pReg1->Rect.left;
- pReg2->Rect.top = pReg1->Rect.bottom;
- pReg2->Rect.right = oldRight1;
- pReg2->Rect.bottom = oldBottom1;
- vboxWddmVrListRegAddOrder(pList, pReg1->ListEntry.Flink, pReg2);
- /* restart the pNext1 & pNext2 since regs are splitted into smaller ones in y dimension
- * and thus can match one of the previous rects */
- pNext1 = pList->ListHead.Flink;
- break;
- }
- else if (pReg1->Rect.bottom < pReg2->Rect.bottom)
- {
- pReg1->Rect.right = pReg2->Rect.right;
- vboxWddmVrDbgListVerify(pList);
- pReg2->Rect.top = pReg1->Rect.bottom;
- vboxWddmVrListRegAddOrder(pList, pReg1->ListEntry.Flink, pReg2);
- /* restart the pNext1 & pNext2 since regs are splitted into smaller ones in y dimension
- * and thus can match one of the previous rects */
- pNext1 = pList->ListHead.Flink;
- break;
- }
- else
- {
- pReg1->Rect.right = pReg2->Rect.right;
- vboxWddmVrDbgListVerify(pList);
- /* reset the pNext1 since it could be the pReg2 being destroyed */
- pNext1 = pEntry1->Flink;
- /* pNext2 stays the same since it is pReg2->ListEntry.pNext, which is kept intact */
- vboxWddmVrRegTerm(pReg2);
- }
- }
- continue;
- }
- else if (pReg1->Rect.bottom == pReg2->Rect.bottom)
- {
- Assert(pReg1->Rect.top < pReg2->Rect.top); /* <- since pReg1 > pReg2 && pReg1->Rect.top != pReg2->Rect.top*/
- if (pReg1->Rect.right == pReg2->Rect.left)
- {
- /* join rectangles */
- vboxWddmVrListRegRemove(pList, pReg2);
-
- pReg1->Rect.bottom = pReg2->Rect.top;
- vboxWddmVrDbgListVerify(pList);
- pReg2->Rect.left = pReg1->Rect.left;
-
- vboxWddmVrListRegAddOrder(pList, pReg2->ListEntry.Flink, pReg2);
-
- /* restart the pNext1 & pNext2 since regs are splitted into smaller ones in y dimension
- * and thus can match one of the previous rects */
- pNext1 = pList->ListHead.Flink;
- break;
- }
- else if (pReg1->Rect.left == pReg2->Rect.right)
- {
- /* join rectangles */
- vboxWddmVrListRegRemove(pList, pReg2);
-
- pReg1->Rect.bottom = pReg2->Rect.top;
- vboxWddmVrDbgListVerify(pList);
- pReg2->Rect.right = pReg1->Rect.right;
-
- vboxWddmVrListRegAddOrder(pList, pReg2->ListEntry.Flink, pReg2);
-
- /* restart the pNext1 & pNext2 since regs are splitted into smaller ones in y dimension
- * and thus can match one of the previous rects */
- pNext1 = pList->ListHead.Flink;
- break;
- }
- continue;
- }
- }
- else
- {
- if (pReg1->Rect.bottom == pReg2->Rect.top)
- {
- if (pReg1->Rect.left == pReg2->Rect.left)
- {
- if (pReg1->Rect.right == pReg2->Rect.right)
- {
- /* join rects */
- vboxWddmVrListRegRemove(pList, pReg2);
-
- pReg1->Rect.bottom = pReg2->Rect.bottom;
- vboxWddmVrDbgListVerify(pList);
-
- /* reset the pNext1 since it could be the pReg2 being destroyed */
- pNext1 = pEntry1->Flink;
- /* pNext2 stays the same since it is pReg2->ListEntry.pNext, which is kept intact */
- vboxWddmVrRegTerm(pReg2);
- continue;
- }
- /* no more to be done for for pReg1 */
- break;
- }
- else if (pReg1->Rect.right > pReg2->Rect.left)
- {
- /* no more to be done for for pReg1 */
- break;
- }
-
- continue;
- }
- else if (pReg1->Rect.bottom < pReg2->Rect.top)
- {
- /* no more to be done for for pReg1 */
- break;
- }
- }
- }
- }
-}
-
-static void vboxWddmVrListJoinRects(PVBOXWDDMVR_LIST pList)
-{
- vboxWddmVrListJoinRectsHV(pList, TRUE);
- vboxWddmVrListJoinRectsHV(pList, FALSE);
-}
-
-typedef struct VBOXWDDMVR_CBDATA_SUBST
-{
- NTSTATUS Status;
- BOOLEAN fChanged;
-} VBOXWDDMVR_CBDATA_SUBST, *PVBOXWDDMVR_CBDATA_SUBST;
-
-static DECLCALLBACK(PLIST_ENTRY) vboxWddmVrListSubstNoJoinCb(PVBOXWDDMVR_LIST pList, PVBOXWDDMVR_REG pReg1, const RECT *pRect2, void *pvContext, PLIST_ENTRY *ppNext)
-{
- PVBOXWDDMVR_CBDATA_SUBST pData = (PVBOXWDDMVR_CBDATA_SUBST)pvContext;
- /* store the prev to get the new Flink out of it*/
- PLIST_ENTRY pPrev = pReg1->ListEntry.Blink;
- pData->fChanged = TRUE;
-
- Assert(vboxWddmRectIsIntersect(&pReg1->Rect, pRect2));
-
- /* NOTE: the pReg1 will be invalid after the vboxWddmVrListRegIntersectSubstNoJoin call!!! */
- NTSTATUS Status = vboxWddmVrListRegIntersectSubstNoJoin(pList, pReg1, pRect2);
- if (NT_SUCCESS(Status))
- {
- *ppNext = pPrev->Flink;
- return &pList->ListHead;
- }
- WARN(("vboxWddmVrListRegIntersectSubstNoJoin failed!"));
- Assert(!NT_SUCCESS(Status));
- pData->Status = Status;
- *ppNext = &pList->ListHead;
- return &pList->ListHead;
-}
-
-static NTSTATUS vboxWddmVrListSubstNoJoin(PVBOXWDDMVR_LIST pList, UINT cRects, const PRECT aRects, BOOLEAN *pfChanged)
-{
- if (VBoxWddmVrListIsEmpty(pList))
- return STATUS_SUCCESS;
-
- VBOXWDDMVR_CBDATA_SUBST Data;
- Data.Status = STATUS_SUCCESS;
- Data.fChanged = FALSE;
-
- *pfChanged = FALSE;
-
- vboxWddmVrListVisitIntersected(pList, cRects, aRects, vboxWddmVrListSubstNoJoinCb, &Data);
- if (!NT_SUCCESS(Data.Status))
- {
- WARN(("vboxWddmVrListVisitIntersected failed!"));
- return Data.Status;
- }
-
- *pfChanged = Data.fChanged;
- return STATUS_SUCCESS;
-}
-
-#if 0
-static const PRECT vboxWddmVrRectsOrder(UINT cRects, const PRECT aRects)
-{
-#ifdef DEBUG
- {
- for (UINT i = 0; i < cRects; ++i)
- {
- RECT *pRectI = &aRects[i];
- for (UINT j = i + 1; j < cRects; ++j)
- {
- RECT *pRectJ = &aRects[j];
- Assert(!vboxWddmRectIsIntersect(pRectI, pRectJ));
- }
- }
- }
-#endif
-
- RECT * pRects = (RECT *)aRects;
- /* check if rects are ordered already */
- for (UINT i = 0; i < cRects - 1; ++i)
- {
- RECT *pRect1 = &pRects[i];
- RECT *pRect2 = &pRects[i+1];
- if (vboxWddmVrRegNonintersectedComparator(pRect1, pRect2) < 0)
- continue;
-
- WARN(("rects are unoreded!"));
-
- if (pRects == aRects)
- {
- pRects = (RECT *)vboxWddmMemAlloc(sizeof (RECT) * cRects);
- if (!pRects)
- {
- WARN(("vboxWddmMemAlloc failed!"));
- return NULL;
- }
-
- memcpy(pRects, aRects, sizeof (RECT) * cRects);
- }
-
- Assert(pRects != aRects);
-
- int j = (int)i - 1;
- do {
- RECT Tmp = *pRect1;
- *pRect1 = *pRect2;
- *pRect2 = Tmp;
-
- if (j < 0)
- break;
-
- if (vboxWddmVrRegNonintersectedComparator(pRect1, pRect1-1) > 0)
- break;
-
- pRect2 = pRect1--;
- --j;
- } while (1);
- }
-
- return pRects;
-}
-#endif
-
-void VBoxWddmVrListTranslate(PVBOXWDDMVR_LIST pList, LONG x, LONG y)
-{
- for (PLIST_ENTRY pEntry1 = pList->ListHead.Flink; pEntry1 != &pList->ListHead; pEntry1 = pEntry1->Flink)
- {
- PVBOXWDDMVR_REG pReg1 = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry1);
- vboxWddmRectTranslate(&pReg1->Rect, x, y);
- }
-}
-
-NTSTATUS VBoxWddmVrListRectsSubst(PVBOXWDDMVR_LIST pList, UINT cRects, const PRECT aRects, BOOLEAN *pfChanged)
-{
-#if 0
- const PRECT pRects = vboxWddmVrRectsOrder(cRects, aRects);
- if (!pRects)
- {
- WARN(("vboxWddmVrRectsOrder failed!"));
- return STATUS_NO_MEMORY;
- }
-#endif
-
- NTSTATUS Status = vboxWddmVrListSubstNoJoin(pList, cRects, aRects, pfChanged);
- if (!NT_SUCCESS(Status))
- {
- WARN(("vboxWddmVrListSubstNoJoin failed!"));
- goto done;
- }
-
- if (!*pfChanged)
- goto done;
-
- vboxWddmVrListJoinRects(pList);
-
-done:
-#if 0
- if (pRects != aRects)
- vboxWddmMemFree(pRects);
-#endif
- return Status;
-}
-
-NTSTATUS VBoxWddmVrListRectsAdd(PVBOXWDDMVR_LIST pList, UINT cRects, const PRECT aRects, BOOLEAN *pfChanged)
-{
- UINT cCovered = 0;
-
-#if 0
-#ifdef DEBUG
- {
- for (UINT i = 0; i < cRects; ++i)
- {
- RECT *pRectI = &aRects[i];
- for (UINT j = i + 1; j < cRects; ++j)
- {
- RECT *pRectJ = &aRects[j];
- Assert(!vboxWddmRectIsIntersect(pRectI, pRectJ));
- }
- }
- }
-#endif
-#endif
-
- /* early sort out the case when there are no new rects */
- for (UINT i = 0; i < cRects; ++i)
- {
- for (PLIST_ENTRY pEntry1 = pList->ListHead.Flink; pEntry1 != &pList->ListHead; pEntry1 = pEntry1->Flink)
- {
- PVBOXWDDMVR_REG pReg1 = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry1);
- if (vboxWddmRectIsCoveres(&pReg1->Rect, &aRects[i]))
- {
- cCovered++;
- break;
- }
- }
- }
-
- if (cCovered == cRects)
- {
- *pfChanged = FALSE;
- return STATUS_SUCCESS;
- }
-
- /* rects are not covered, need to go the slow way */
-
- VBOXWDDMVR_LIST DiffList;
- VBoxWddmVrListInit(&DiffList);
- PRECT pListRects = NULL;
- UINT cAllocatedRects = 0;
- BOOLEAN fNeedRectreate = TRUE;
- BOOLEAN fChanged = FALSE;
- NTSTATUS Status = STATUS_SUCCESS;
-
- for (UINT i = 0; i < cRects; ++i)
- {
- PVBOXWDDMVR_REG pReg = vboxWddmVrRegCreate();
- if (!pReg)
- {
- WARN(("vboxWddmVrRegCreate failed!"));
- Status = STATUS_NO_MEMORY;
- break;
- }
- pReg->Rect = aRects[i];
-
- UINT cListRects = VBoxWddmVrListRectsCount(pList);
- if (!cListRects)
- {
- vboxWddmVrListRegAdd(pList, pReg, &pList->ListHead, FALSE);
- fChanged = TRUE;
- continue;
- }
- else
- {
- Assert(VBoxWddmVrListIsEmpty(&DiffList));
- vboxWddmVrListRegAdd(&DiffList, pReg, &DiffList.ListHead, FALSE);
- }
-
- if (cAllocatedRects < cListRects)
- {
- cAllocatedRects = cListRects + cRects;
- Assert(fNeedRectreate);
- if (pListRects)
- vboxWddmMemFree(pListRects);
- pListRects = (PRECT)vboxWddmMemAlloc(sizeof (RECT) * cAllocatedRects);
- if (!pListRects)
- {
- WARN(("vboxWddmMemAllocZero failed!"));
- Status = STATUS_NO_MEMORY;
- break;
- }
- }
-
-
- if (fNeedRectreate)
- {
- Status = VBoxWddmVrListRectsGet(pList, cListRects, pListRects);
- Assert(Status == STATUS_SUCCESS);
- fNeedRectreate = FALSE;
- }
-
- BOOLEAN fDummyChanged = FALSE;
- Status = vboxWddmVrListSubstNoJoin(&DiffList, cListRects, pListRects, &fDummyChanged);
- if (!NT_SUCCESS(Status))
- {
- WARN(("vboxWddmVrListSubstNoJoin failed!"));
- Status = STATUS_NO_MEMORY;
- break;
- }
-
- if (!VBoxWddmVrListIsEmpty(&DiffList))
- {
- vboxWddmVrListAddNonintersected(pList, &DiffList);
- fNeedRectreate = TRUE;
- fChanged = TRUE;
- }
-
- Assert(VBoxWddmVrListIsEmpty(&DiffList));
- }
-
- if (pListRects)
- vboxWddmMemFree(pListRects);
-
- Assert(VBoxWddmVrListIsEmpty(&DiffList) || Status != STATUS_SUCCESS);
- VBoxWddmVrListClear(&DiffList);
-
- if (fChanged)
- vboxWddmVrListJoinRects(pList);
-
- *pfChanged = fChanged;
-
- return STATUS_SUCCESS;
-}
-
-NTSTATUS VBoxWddmVrListRectsGet(PVBOXWDDMVR_LIST pList, UINT cRects, PRECT aRects)
-{
- if (cRects < VBoxWddmVrListRectsCount(pList))
- return STATUS_BUFFER_TOO_SMALL;
-
- UINT i = 0;
- for (PLIST_ENTRY pEntry1 = pList->ListHead.Flink; pEntry1 != &pList->ListHead; pEntry1 = pEntry1->Flink, ++i)
- {
- PVBOXWDDMVR_REG pReg1 = PVBOXWDDMVR_REG_FROM_ENTRY(pEntry1);
- aRects[i] = pReg1->Rect;
- }
- return STATUS_SUCCESS;
-}
-
NTSTATUS vboxWddmDrvCfgInit(PUNICODE_STRING pRegStr)
{
HANDLE hKey;
@@ -2527,16 +1894,24 @@ static int vboxWddmSlConfigure(PVBOXMP_DEVEXT pDevExt, uint32_t fFlags)
NTSTATUS VBoxWddmSlEnableVSyncNotification(PVBOXMP_DEVEXT pDevExt, BOOLEAN fEnable)
{
+ if (!pDevExt->bVSyncTimerEnabled == !fEnable)
+ return STATUS_SUCCESS;
+
if (!fEnable)
{
KeCancelTimer(&pDevExt->VSyncTimer);
}
else
{
+ KeQuerySystemTime((PLARGE_INTEGER)&pDevExt->VSyncTime);
+
LARGE_INTEGER DueTime;
DueTime.QuadPart = -166666LL; /* 60 Hz */
KeSetTimerEx(&pDevExt->VSyncTimer, DueTime, 16, &pDevExt->VSyncDpc);
}
+
+ pDevExt->bVSyncTimerEnabled = !!fEnable;
+
return STATUS_SUCCESS;
}
@@ -2547,16 +1922,37 @@ NTSTATUS VBoxWddmSlGetScanLine(PVBOXMP_DEVEXT pDevExt, DXGKARG_GETSCANLINE *pGet
Assert(pTarget->HeightTotal);
Assert(pTarget->HeightVisible);
Assert(pTarget->HeightTotal >= pTarget->HeightVisible);
- Assert(pTarget->ScanLineState < pTarget->HeightTotal);
if (pTarget->HeightTotal)
{
- uint32_t curScanLine = pTarget->ScanLineState;
- ++pTarget->ScanLineState;
- if (pTarget->ScanLineState >= pTarget->HeightTotal)
- pTarget->ScanLineState = 0;
+ uint32_t curScanLine;
+ BOOL bVBlank;
+ LARGE_INTEGER DevVSyncTime;
+ DevVSyncTime.QuadPart = ASMAtomicReadU64((volatile uint64_t*)&pDevExt->VSyncTime.QuadPart);
+ LARGE_INTEGER VSyncTime;
+ KeQuerySystemTime(&VSyncTime);
+ if (VSyncTime.QuadPart < DevVSyncTime.QuadPart)
+ {
+ WARN(("vsync time is less than the one stored in device"));
+ curScanLine = 0;
+ }
+ else
+ {
+ VSyncTime.QuadPart = VSyncTime.QuadPart - DevVSyncTime.QuadPart;
+ /* time is in 100ns, */
+ curScanLine = (uint32_t)((pTarget->HeightTotal * VSyncTime.QuadPart) / DevVSyncTime.QuadPart);
+ if (pDevExt->bVSyncTimerEnabled)
+ {
+ if (curScanLine >= pTarget->HeightTotal)
+ curScanLine = 0;
+ }
+ else
+ {
+ curScanLine %= pTarget->HeightTotal;
+ }
+ }
- BOOL bVBlank = (!curScanLine || curScanLine > pTarget->HeightVisible);
+ bVBlank = (!curScanLine || curScanLine > pTarget->HeightVisible);
pGetScanLine->ScanLine = curScanLine;
pGetScanLine->InVerticalBlank = bVBlank;
}
@@ -2568,36 +1964,21 @@ NTSTATUS VBoxWddmSlGetScanLine(PVBOXMP_DEVEXT pDevExt, DXGKARG_GETSCANLINE *pGet
return STATUS_SUCCESS;
}
-static VOID vboxWddmSlVSyncDpc(
- __in struct _KDPC *Dpc,
- __in_opt PVOID DeferredContext,
- __in_opt PVOID SystemArgument1,
- __in_opt PVOID SystemArgument2
-)
+static BOOLEAN vboxWddmSlVSyncIrqCb(PVOID pvContext)
{
- PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)DeferredContext;
+ PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)pvContext;
DXGKARGCB_NOTIFY_INTERRUPT_DATA notify;
BOOLEAN bNeedDpc = FALSE;
for (UINT i = 0; i < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
{
- PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[i];
- PVBOXWDDM_ALLOCATION pPrimary = vboxWddmAquirePrimary(pDevExt, pSource, i);
- if (pPrimary)
+ PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[i];
+ if (pTarget->fConnected)
{
- VBOXVIDEOOFFSET offVram = pPrimary->AllocData.Addr.offVram;
- if (offVram != VBOXVIDEOOFFSET_VOID)
- {
- memset(&notify, 0, sizeof(DXGKARGCB_NOTIFY_INTERRUPT_DATA));
- notify.InterruptType = DXGK_INTERRUPT_CRTC_VSYNC;
- /* @todo: !!!this is not correct in case we want source[i]->target[i!=j] mapping */
- notify.CrtcVsync.VidPnTargetId = i;
- notify.CrtcVsync.PhysicalAddress.QuadPart = offVram;
- /* yes, we can report VSync at dispatch */
- pDevExt->u.primary.DxgkInterface.DxgkCbNotifyInterrupt(pDevExt->u.primary.DxgkInterface.DeviceHandle, &notify);
- bNeedDpc = TRUE;
- }
-
- vboxWddmAllocationRelease(pPrimary);
+ memset(&notify, 0, sizeof(DXGKARGCB_NOTIFY_INTERRUPT_DATA));
+ notify.InterruptType = DXGK_INTERRUPT_CRTC_VSYNC;
+ notify.CrtcVsync.VidPnTargetId = i;
+ pDevExt->u.primary.DxgkInterface.DxgkCbNotifyInterrupt(pDevExt->u.primary.DxgkInterface.DeviceHandle, &notify);
+ bNeedDpc = TRUE;
}
}
@@ -2605,10 +1986,43 @@ static VOID vboxWddmSlVSyncDpc(
{
pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
}
+
+ return FALSE;
+}
+
+static VOID vboxWddmSlVSyncDpc(
+ __in struct _KDPC *Dpc,
+ __in_opt PVOID DeferredContext,
+ __in_opt PVOID SystemArgument1,
+ __in_opt PVOID SystemArgument2
+)
+{
+ PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)DeferredContext;
+ Assert(!pDevExt->fVSyncInVBlank);
+ ASMAtomicWriteU32(&pDevExt->fVSyncInVBlank, 1);
+
+ BOOLEAN bDummy;
+ NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbSynchronizeExecution(
+ pDevExt->u.primary.DxgkInterface.DeviceHandle,
+ vboxWddmSlVSyncIrqCb,
+ pDevExt,
+ 0, /* IN ULONG MessageNumber */
+ &bDummy);
+ if (!NT_SUCCESS(Status))
+ WARN(("DxgkCbSynchronizeExecution failed Status %#x", Status));
+
+ LARGE_INTEGER VSyncTime;
+ KeQuerySystemTime(&VSyncTime);
+ ASMAtomicWriteU64((volatile uint64_t*)&pDevExt->VSyncTime.QuadPart, VSyncTime.QuadPart);
+
+ ASMAtomicWriteU32(&pDevExt->fVSyncInVBlank, 0);
}
NTSTATUS VBoxWddmSlInit(PVBOXMP_DEVEXT pDevExt)
{
+ pDevExt->bVSyncTimerEnabled = FALSE;
+ pDevExt->fVSyncInVBlank = 0;
+ KeQuerySystemTime((PLARGE_INTEGER)&pDevExt->VSyncTime);
KeInitializeTimer(&pDevExt->VSyncTimer);
KeInitializeDpc(&pDevExt->VSyncDpc, vboxWddmSlVSyncDpc, pDevExt);
return STATUS_SUCCESS;
@@ -2667,7 +2081,7 @@ void vboxWddmDmAdjustDefaultVramLocations(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_P
pSource = &pDevExt->aSources[i];
if (pSource->AllocData.Addr.offVram != PhAddr.QuadPart
|| pSource->AllocData.Addr.SegmentId != 1)
- pSource->bGhSynced = FALSE;
+ pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_LOCATION;
pSource->AllocData.Addr.SegmentId = 1;
pSource->AllocData.Addr.offVram = PhAddr.QuadPart;
}
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.h b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.h
index 27a919c0..742ecc22 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -71,9 +71,10 @@ PVOID vboxWddmHTableGet(PVBOXWDDM_HTABLE pTbl, VBOXWDDM_HANDLE hHandle);
PVBOXWDDM_SWAPCHAIN vboxWddmSwapchainCreate();
-DECLINLINE(BOOLEAN) vboxWddmSwapchainRetain(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain);
-DECLINLINE(VOID) vboxWddmSwapchainRelease(PVBOXWDDM_SWAPCHAIN pSwapchain);
-PVBOXWDDM_SWAPCHAIN vboxWddmSwapchainRetainByAlloc(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAlloc);
+BOOLEAN vboxWddmSwapchainRetain(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain);
+VOID vboxWddmSwapchainRelease(PVBOXWDDM_SWAPCHAIN pSwapchain);
+PVBOXWDDM_SWAPCHAIN vboxWddmSwapchainRetainByAlloc(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOCATION *pAlloc);
+PVBOXWDDM_SWAPCHAIN vboxWddmSwapchainRetainByAllocData(PVBOXMP_DEVEXT pDevExt, const struct VBOXWDDM_ALLOC_DATA *pAllocData);
VOID vboxWddmSwapchainAllocRemove(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain, PVBOXWDDM_ALLOCATION pAlloc);
BOOLEAN vboxWddmSwapchainAllocAdd(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain, PVBOXWDDM_ALLOCATION pAlloc);
VOID vboxWddmSwapchainAllocRemoveAll(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain);
@@ -90,13 +91,17 @@ NTSTATUS vboxWddmRegOpenDisplaySettingsKey(IN PVBOXMP_DEVEXT pDeviceExtension, D
NTSTATUS vboxWddmRegDisplaySettingsQueryRelX(HANDLE hKey, int * pResult);
NTSTATUS vboxWddmRegDisplaySettingsQueryRelY(HANDLE hKey, int * pResult);
NTSTATUS vboxWddmDisplaySettingsQueryPos(IN PVBOXMP_DEVEXT pDeviceExtension, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, POINT * pPos);
-NTSTATUS vboxWddmRegQueryVideoGuidString(ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult);
+NTSTATUS vboxWddmRegQueryVideoGuidString(PVBOXMP_DEVEXT pDevExt, ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult);
NTSTATUS vboxWddmRegQueryDrvKeyName(PVBOXMP_DEVEXT pDevExt, ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult);
+NTSTATUS vboxWddmRegOpenKeyEx(OUT PHANDLE phKey, IN HANDLE hRootKey, IN PWCHAR pName, IN ACCESS_MASK fAccess);
NTSTATUS vboxWddmRegOpenKey(OUT PHANDLE phKey, IN PWCHAR pName, IN ACCESS_MASK fAccess);
NTSTATUS vboxWddmRegQueryValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT PDWORD pDword);
-NTSTATUS vboxWddmRegSetValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT DWORD val);
+NTSTATUS vboxWddmRegSetValueDword(IN HANDLE hKey, IN PWCHAR pName, IN DWORD val);
+
+NTSTATUS vboxWddmRegDrvFlagsSet(PVBOXMP_DEVEXT pDevExt, DWORD fVal);
+DWORD vboxWddmRegDrvFlagsGet(PVBOXMP_DEVEXT pDevExt, DWORD fDefault);
UNICODE_STRING* vboxWddmVGuidGet(PVBOXMP_DEVEXT pDevExt);
VOID vboxWddmVGuidFree(PVBOXMP_DEVEXT pDevExt);
@@ -163,40 +168,6 @@ PVBOXWDDM_ALLOCATION vboxShRcTreeGet(PVBOXMP_DEVEXT pDevExt, HANDLE hSharedRc);
BOOLEAN vboxShRcTreeRemove(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAlloc);
#endif
-/* visible rects */
-typedef struct VBOXWDDMVR_LIST
-{
- LIST_ENTRY ListHead;
- UINT cEntries;
-} VBOXWDDMVR_LIST, *PVBOXWDDMVR_LIST;
-
-DECLINLINE(UINT) VBoxWddmVrListRectsCount(PVBOXWDDMVR_LIST pList)
-{
- return pList->cEntries;
-}
-
-DECLINLINE(BOOLEAN) VBoxWddmVrListIsEmpty(PVBOXWDDMVR_LIST pList)
-{
- return !VBoxWddmVrListRectsCount(pList);
-}
-
-DECLINLINE(void) VBoxWddmVrListInit(PVBOXWDDMVR_LIST pList)
-{
- InitializeListHead(&pList->ListHead);
- pList->cEntries = 0;
-}
-
-void VBoxWddmVrListClear(PVBOXWDDMVR_LIST pList);
-
-void VBoxWddmVrListTranslate(PVBOXWDDMVR_LIST pList, LONG x, LONG y);
-
-NTSTATUS VBoxWddmVrListRectsAdd(PVBOXWDDMVR_LIST pList, UINT cRects, const PRECT aRects, BOOLEAN *pfChanged);
-NTSTATUS VBoxWddmVrListRectsSubst(PVBOXWDDMVR_LIST pList, UINT cRects, const PRECT aRects, BOOLEAN *pfChanged);
-NTSTATUS VBoxWddmVrListRectsGet(PVBOXWDDMVR_LIST pList, UINT cRects, PRECT aRects);
-
-NTSTATUS VBoxWddmVrInit();
-void VBoxWddmVrTerm();
-
NTSTATUS vboxWddmDrvCfgInit(PUNICODE_STRING pRegStr);
#ifdef VBOX_VDMA_WITH_WATCHDOG
@@ -215,4 +186,6 @@ void vboxWddmDiToAllocData(PVBOXMP_DEVEXT pDevExt, const DXGK_DISPLAY_INFORMATIO
void vboxWddmDmAdjustDefaultVramLocations(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID ModifiedVidPnSourceId);
#endif
+NTSTATUS vboxWddmChildStatusConnect(PVBOXMP_DEVEXT pDevExt, uint32_t iChild, BOOLEAN fConnect);
+
#endif /* #ifndef ___VBoxMPMisc_h__ */
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPShgsmi.cpp b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPShgsmi.cpp
index b38c5587..d10580d7 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPShgsmi.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPShgsmi.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPShgsmi.h b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPShgsmi.h
index 4fdc1f3e..491498f6 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPShgsmi.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPShgsmi.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -48,11 +48,18 @@ int VBoxSHGSMICommandDoneSynch(PVBOXSHGSMI pHeap, const VBOXSHGSMIHEADER* pHeade
void VBoxSHGSMICommandCancelAsynch(PVBOXSHGSMI pHeap, const VBOXSHGSMIHEADER* pHeader);
void VBoxSHGSMICommandCancelSynch(PVBOXSHGSMI pHeap, const VBOXSHGSMIHEADER* pHeader);
-DECLINLINE(HGSMIOFFSET) VBoxSHGSMICommandOffset(PVBOXSHGSMI pHeap, const VBOXSHGSMIHEADER* pHeader)
+DECLINLINE(HGSMIOFFSET) VBoxSHGSMICommandOffset(const PVBOXSHGSMI pHeap, const VBOXSHGSMIHEADER* pHeader)
{
return HGSMIHeapBufferOffset(&pHeap->Heap, (void*)pHeader);
}
+/* allows getting VRAM offset of arbitrary pointer within the SHGSMI command
+ * if invalid pointer is passed in, behavior is undefined */
+DECLINLINE(HGSMIOFFSET) VBoxSHGSMICommandPtrOffset(const PVBOXSHGSMI pHeap, const void * pvPtr)
+{
+ return HGSMIPointerToOffset (&pHeap->Heap.area, (const HGSMIBUFFERHEADER *)pvPtr);
+}
+
int VBoxSHGSMIInit(PVBOXSHGSMI pHeap, void *pvBase, HGSMISIZE cbArea, HGSMIOFFSET offBase, bool fOffsetBased);
void VBoxSHGSMITerm(PVBOXSHGSMI pHeap);
void* VBoxSHGSMIHeapAlloc(PVBOXSHGSMI pHeap, HGSMISIZE cbData, uint8_t u8Channel, uint16_t u16ChannelInfo);
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPTypes.h b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPTypes.h
index 701dfb78..061bc7f4 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPTypes.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPTypes.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -32,6 +32,12 @@ typedef struct VBOXWDDM_ALLOCATION *PVBOXWDDM_ALLOCATION;
#include "VBoxMPVbva.h"
#include "VBoxMPCr.h"
+#include <cr_vreg.h>
+
+#ifdef DEBUG_misha
+extern DWORD g_VBoxDbgBreakModes;
+#endif
+
#if 0
#include <iprt/avl.h>
#endif
@@ -100,8 +106,16 @@ typedef struct VBOXWDDM_ALLOC_DATA
{
VBOXWDDM_SURFACE_DESC SurfDesc;
VBOXWDDM_ADDR Addr;
+ uint32_t hostID;
+ uint32_t cHostIDRefs;
+ struct VBOXWDDM_SWAPCHAIN *pSwapchain;
} VBOXWDDM_ALLOC_DATA, *PVBOXWDDM_ALLOC_DATA;
+#define VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS 0x01
+#define VBOXWDDM_HGSYNC_F_SYNCED_LOCATION 0x02
+#define VBOXWDDM_HGSYNC_F_SYNCED_ALL (VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS | VBOXWDDM_HGSYNC_F_SYNCED_LOCATION)
+#define VBOXWDDM_HGSYNC_F_CHANGED_LOCATION_ONLY (VBOXWDDM_HGSYNC_F_SYNCED_ALL & ~VBOXWDDM_HGSYNC_F_SYNCED_LOCATION)
+
typedef struct VBOXWDDM_SOURCE
{
struct VBOXWDDM_ALLOCATION * pPrimaryAllocation;
@@ -109,8 +123,11 @@ typedef struct VBOXWDDM_SOURCE
struct VBOXWDDM_ALLOCATION * pShadowAllocation;
#endif
VBOXWDDM_ALLOC_DATA AllocData;
+ uint8_t u8SyncState;
BOOLEAN bVisible;
- BOOLEAN bGhSynced;
+ /* specifies whether the source has 3D overlay data visible */
+ BOOLEAN fHas3DVrs;
+ VBOXVR_LIST VrList;
VBOXVBVAINFO Vbva;
#ifdef VBOX_WITH_VIDEOHWACCEL
/* @todo: in our case this seems more like a target property,
@@ -127,9 +144,13 @@ typedef struct VBOXWDDM_SOURCE
typedef struct VBOXWDDM_TARGET
{
- uint32_t ScanLineState;
uint32_t HeightVisible;
uint32_t HeightTotal;
+ /* since there coul be multiple state changes on auto-resize,
+ * we pend notifying host to avoid flickering */
+ volatile bool fStateSyncPening;
+ bool fConnected;
+ bool fConfigured;
} VBOXWDDM_TARGET, *PVBOXWDDM_TARGET;
/* allocation */
@@ -137,7 +158,6 @@ typedef struct VBOXWDDM_TARGET
typedef struct VBOXWDDM_ALLOCATION
{
LIST_ENTRY SwapchainEntry;
- struct VBOXWDDM_SWAPCHAIN *pSwapchain;
VBOXWDDM_ALLOC_TYPE enmType;
volatile uint32_t cRefs;
D3DDDI_RESOURCEFLAGS fRcFlags;
@@ -166,7 +186,6 @@ typedef struct VBOXWDDM_ALLOCATION
AVLPVNODECORE ShRcTreeEntry;
#endif
VBOXUHGSMI_BUFFER_TYPE_FLAGS fUhgsmiType;
- PKEVENT pSynchEvent;
} VBOXWDDM_ALLOCATION, *PVBOXWDDM_ALLOCATION;
typedef struct VBOXWDDM_RESOURCE
@@ -220,10 +239,12 @@ typedef struct VBOXWDDM_SWAPCHAIN
volatile uint32_t cRefs;
VBOXDISP_UMHANDLE hSwapchainUm;
VBOXDISP_KMHANDLE hSwapchainKm;
+ int32_t winHostID;
+ BOOLEAN fExposed;
POINT Pos;
UINT width;
UINT height;
- VBOXWDDMVR_LIST VisibleRegions;
+ VBOXVR_LIST VisibleRegions;
}VBOXWDDM_SWAPCHAIN, *PVBOXWDDM_SWAPCHAIN;
typedef struct VBOXWDDM_CONTEXT
@@ -234,7 +255,9 @@ typedef struct VBOXWDDM_CONTEXT
UINT NodeOrdinal;
UINT EngineAffinity;
BOOLEAN fRenderFromShadowDisabled;
+ int32_t hostID;
uint32_t u32CrConClientID;
+ VBOXMP_CRPACKER CrPacker;
VBOXWDDM_HTABLE Swapchains;
VBOXVIDEOCM_CTX CmContext;
VBOXVIDEOCM_ALLOC_CONTEXT AllocContext;
@@ -300,6 +323,7 @@ typedef struct VBOXWDDM_OPENALLOCATION
PVBOXWDDM_DEVICE pDevice;
uint32_t cShRcRefs;
uint32_t cOpens;
+ uint32_t cHostIDRefs;
} VBOXWDDM_OPENALLOCATION, *PVBOXWDDM_OPENALLOCATION;
#define VBOXWDDM_MAX_VIDEOMODES 128
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.cpp b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.cpp
index 93ff48f4..ac7e908c 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -19,85 +19,23 @@
#include "VBoxMPWddm.h"
#include "common/VBoxMPCommon.h"
-static int vboxVBVAInformHost (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO * pVbva, BOOL bEnable)
-{
- int rc = VERR_NO_MEMORY;
- void *p = VBoxHGSMIBufferAlloc (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx,
- sizeof (VBVAENABLE_EX),
- HGSMI_CH_VBVA,
- VBVA_ENABLE);
- Assert(p);
- if (!p)
- {
- LOGREL(("HGSMIHeapAlloc failed"));
- rc = VERR_NO_MEMORY;
- }
- else
- {
- VBVAENABLE_EX *pEnableEx = (VBVAENABLE_EX *)p;
- pEnableEx->u32ScreenId = pVbva->srcId;
-
- VBVAENABLE *pEnable = &pEnableEx->Base;
- pEnable->u32Flags = bEnable? VBVA_F_ENABLE: VBVA_F_DISABLE;
- pEnable->u32Flags |= VBVA_F_EXTENDED | VBVA_F_ABSOFFSET;
- pEnable->u32Offset = (uint32_t)pVbva->offVBVA;
- pEnable->i32Result = VERR_NOT_SUPPORTED;
-
- VBoxHGSMIBufferSubmit (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx, p);
-
- if (bEnable)
- {
- rc = pEnable->i32Result;
- AssertRC(rc);
- }
- else
- rc = VINF_SUCCESS;
-
- VBoxHGSMIBufferFree (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx, p);
- }
- return rc;
-}
-
/*
* Public hardware buffer methods.
*/
int vboxVbvaEnable (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva)
{
- VBVABUFFER *pVBVA = pVbva->pVBVA;
-
-// DISPDBG((1, "VBoxDisp::vboxVbvaEnable screen %p vbva off 0x%x\n", ppdev->pjScreen, ppdev->layout.offVBVABuffer));
-
- pVBVA->hostFlags.u32HostEvents = 0;
- pVBVA->hostFlags.u32SupportedOrders = 0;
- pVBVA->off32Data = 0;
- pVBVA->off32Free = 0;
- RtlZeroMemory (pVBVA->aRecords, sizeof (pVBVA->aRecords));
- pVBVA->indexRecordFirst = 0;
- pVBVA->indexRecordFree = 0;
- pVBVA->cbPartialWriteThreshold = 256;
- pVBVA->cbData = pVbva->cbVBVA - sizeof (VBVABUFFER) + sizeof (pVBVA->au8Data);
+ if (VBoxVBVAEnable(&pVbva->Vbva, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx,
+ pVbva->Vbva.pVBVA, pVbva->srcId))
+ return VINF_SUCCESS;
- pVbva->fHwBufferOverflow = FALSE;
- pVbva->pRecord = NULL;
-
- int rc = vboxVBVAInformHost (pDevExt, pVbva, TRUE);
- AssertRC(rc);
-
- if (!RT_SUCCESS(rc))
- vboxVbvaDisable (pDevExt, pVbva);
-
- return rc;
+ WARN(("VBoxVBVAEnable failed!"));
+ return VERR_GENERAL_FAILURE;
}
int vboxVbvaDisable (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva)
{
-// DISPDBG((1, "VBoxDisp::vbvaDisable called.\n"));
-
- pVbva->fHwBufferOverflow = FALSE;
- pVbva->pRecord = NULL;
-// ppdev->pVBVA = NULL;
-
- return vboxVBVAInformHost (pDevExt, pVbva, FALSE);
+ VBoxVBVADisable(&pVbva->Vbva, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx, pVbva->srcId);
+ return VINF_SUCCESS;
}
int vboxVbvaCreate(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva, ULONG offBuffer, ULONG cbBuffer, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId)
@@ -107,17 +45,20 @@ int vboxVbvaCreate(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva, ULONG offBuffer,
KeInitializeSpinLock(&pVbva->Lock);
int rc = VBoxMPCmnMapAdapterMemory(VBoxCommonFromDeviceExt(pDevExt),
- (void**)&pVbva->pVBVA,
+ (void**)&pVbva->Vbva.pVBVA,
offBuffer,
cbBuffer);
- AssertRC(rc);
if (RT_SUCCESS(rc))
{
- Assert(pVbva->pVBVA);
- pVbva->offVBVA = offBuffer;
- pVbva->cbVBVA = cbBuffer;
+ Assert(pVbva->Vbva.pVBVA);
+ VBoxVBVASetupBufferContext(&pVbva->Vbva, offBuffer, cbBuffer);
pVbva->srcId = srcId;
}
+ else
+ {
+ WARN(("VBoxMPCmnMapAdapterMemory failed rc %d", rc));
+ }
+
return rc;
}
@@ -125,188 +66,421 @@ int vboxVbvaCreate(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva, ULONG offBuffer,
int vboxVbvaDestroy(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva)
{
int rc = VINF_SUCCESS;
- VBoxMPCmnUnmapAdapterMemory(VBoxCommonFromDeviceExt(pDevExt), (void**)&pVbva->pVBVA);
- memset(pVbva, 0, sizeof(VBOXVBVAINFO));
+ VBoxMPCmnUnmapAdapterMemory(VBoxCommonFromDeviceExt(pDevExt), (void**)&pVbva->Vbva.pVBVA);
+ memset(pVbva, 0, sizeof (VBOXVBVAINFO));
return rc;
}
-/*
- * Private operations.
- */
-static uint32_t vboxHwBufferAvail (const VBVABUFFER *pVBVA)
+int vboxVbvaReportDirtyRect (PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSrc, RECT *pRectOrig)
{
- int32_t i32Diff = pVBVA->off32Data - pVBVA->off32Free;
+ VBVACMDHDR hdr;
- return i32Diff > 0? i32Diff: pVBVA->cbData + i32Diff;
+ RECT rect = *pRectOrig;
+
+// if (rect.left < 0) rect.left = 0;
+// if (rect.top < 0) rect.top = 0;
+// if (rect.right > (int)ppdev->cxScreen) rect.right = ppdev->cxScreen;
+// if (rect.bottom > (int)ppdev->cyScreen) rect.bottom = ppdev->cyScreen;
+
+ hdr.x = (int16_t)rect.left;
+ hdr.y = (int16_t)rect.top;
+ hdr.w = (uint16_t)(rect.right - rect.left);
+ hdr.h = (uint16_t)(rect.bottom - rect.top);
+
+ hdr.x += (int16_t)pSrc->VScreenPos.x;
+ hdr.y += (int16_t)pSrc->VScreenPos.y;
+
+ if (VBoxVBVAWrite(&pSrc->Vbva.Vbva, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx, &hdr, sizeof(hdr)))
+ return VINF_SUCCESS;
+
+ WARN(("VBoxVBVAWrite failed"));
+ return VERR_GENERAL_FAILURE;
}
-static void vboxHwBufferFlush (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva)
+/* command vbva ring buffer */
+
+/* customized VBVA implementation */
+
+/* Forward declarations of internal functions. */
+static void vboxHwBufferPlaceDataAt(PVBVAEXBUFFERCONTEXT pCtx, const void *p,
+ uint32_t cb, uint32_t offset);
+static bool vboxHwBufferWrite(PVBVAEXBUFFERCONTEXT pCtx,
+ PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
+ const void *p, uint32_t cb);
+
+DECLINLINE(void) vboxVBVAExFlush(struct VBVAEXBUFFERCONTEXT *pCtx, PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx)
{
- /* Issue the flush command. */
- void *p = VBoxHGSMIBufferAlloc (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx,
- sizeof (VBVAFLUSH),
- HGSMI_CH_VBVA,
- VBVA_FLUSH);
- Assert(p);
- if (!p)
+ pCtx->pfnFlush(pCtx, pHGSMICtx, pCtx->pvFlush);
+}
+
+static int vboxCmdVbvaSubmitHgsmi(PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx, HGSMIOFFSET offDr)
+{
+ VBoxVideoCmnPortWriteUlong(pHGSMICtx->port, offDr);
+ return VINF_SUCCESS;
+}
+#define vboxCmdVbvaSubmit vboxCmdVbvaSubmitHgsmi
+
+static VBOXCMDVBVA_CTL * vboxCmdVbvaCtlCreate(PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx, uint32_t cbCtl)
+{
+ Assert(cbCtl >= sizeof (VBOXCMDVBVA_CTL));
+ return (VBOXCMDVBVA_CTL*)VBoxSHGSMICommandAlloc(&pHGSMICtx->heapCtx, cbCtl, HGSMI_CH_VBVA, VBVA_CMDVBVA_CTL);
+}
+
+static void vboxCmdVbvaCtlFree(PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx, VBOXCMDVBVA_CTL * pCtl)
+{
+ VBoxSHGSMICommandFree(&pHGSMICtx->heapCtx, pCtl);
+}
+
+static int vboxCmdVbvaCtlSubmitSync(PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx, VBOXCMDVBVA_CTL * pCtl)
+{
+ const VBOXSHGSMIHEADER* pHdr = VBoxSHGSMICommandPrepSynch(&pHGSMICtx->heapCtx, pCtl);
+ if (!pHdr)
{
- LOGREL(("HGSMIHeapAlloc failed"));
+ WARN(("VBoxSHGSMICommandPrepSynch returnd NULL"));
+ return VERR_INVALID_PARAMETER;
}
- else
+
+ HGSMIOFFSET offCmd = VBoxSHGSMICommandOffset(&pHGSMICtx->heapCtx, pHdr);
+ if (offCmd == HGSMIOFFSET_VOID)
{
- VBVAFLUSH *pFlush = (VBVAFLUSH *)p;
+ WARN(("VBoxSHGSMICommandOffset returnd NULL"));
+ VBoxSHGSMICommandCancelSynch(&pHGSMICtx->heapCtx, pHdr);
+ return VERR_INVALID_PARAMETER;
+ }
+
+ int rc = vboxCmdVbvaSubmit(pHGSMICtx, offCmd);
+ if (RT_SUCCESS(rc))
+ {
+ rc = VBoxSHGSMICommandDoneSynch(&pHGSMICtx->heapCtx, pHdr);
+ if (RT_SUCCESS(rc))
+ {
+ rc = pCtl->i32Result;
+ if (!RT_SUCCESS(rc))
+ WARN(("pCtl->i32Result %d", pCtl->i32Result));
+
+ return rc;
+ }
+ else
+ WARN(("VBoxSHGSMICommandDoneSynch returnd %d", rc));
+ }
+ else
+ WARN(("vboxCmdVbvaSubmit returnd %d", rc));
+
+ VBoxSHGSMICommandCancelSynch(&pHGSMICtx->heapCtx, pHdr);
- pFlush->u32Reserved = 0;
+ return rc;
+}
- VBoxHGSMIBufferSubmit (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx, p);
+static int vboxCmdVbvaCtlSubmitAsync(PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx, VBOXCMDVBVA_CTL * pCtl, PFNVBOXSHGSMICMDCOMPLETION_IRQ pfnCompletionIrq, void *pvCompletionIrq)
+{
+ const VBOXSHGSMIHEADER* pHdr = VBoxSHGSMICommandPrepAsynchIrq(&pHGSMICtx->heapCtx, pCtl, pfnCompletionIrq, pvCompletionIrq, VBOXSHGSMI_FLAG_GH_ASYNCH_FORCE);
+ if (!pHdr)
+ {
+ WARN(("VBoxSHGSMICommandPrepAsynchIrq returnd NULL"));
+ return VERR_INVALID_PARAMETER;
+ }
- VBoxHGSMIBufferFree (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx, p);
+ HGSMIOFFSET offCmd = VBoxSHGSMICommandOffset(&pHGSMICtx->heapCtx, pHdr);
+ if (offCmd == HGSMIOFFSET_VOID)
+ {
+ WARN(("VBoxSHGSMICommandOffset returnd NULL"));
+ VBoxSHGSMICommandCancelAsynch(&pHGSMICtx->heapCtx, pHdr);
+ return VERR_INVALID_PARAMETER;
}
- return;
+ int rc = vboxCmdVbvaSubmit(pHGSMICtx, offCmd);
+ if (RT_SUCCESS(rc))
+ {
+ VBoxSHGSMICommandDoneAsynch(&pHGSMICtx->heapCtx, pHdr);
+ return rc;
+ }
+ else
+ WARN(("vboxCmdVbvaSubmit returnd %d", rc));
+
+ VBoxSHGSMICommandCancelAsynch(&pHGSMICtx->heapCtx, pHdr);
+
+ return rc;
}
-static void vboxHwBufferPlaceDataAt (VBVABUFFER *pVBVA, const void *p, uint32_t cb, uint32_t offset)
+static int vboxVBVAExCtlSubmitEnableDisable(PVBVAEXBUFFERCONTEXT pCtx, PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx, bool fEnable)
{
- uint32_t u32BytesTillBoundary = pVBVA->cbData - offset;
- uint8_t *dst = &pVBVA->au8Data[offset];
- int32_t i32Diff = cb - u32BytesTillBoundary;
+ VBOXCMDVBVA_CTL_ENABLE *pCtl = (VBOXCMDVBVA_CTL_ENABLE*)vboxCmdVbvaCtlCreate(pHGSMICtx, sizeof (*pCtl));
+ if (!pCtl)
+ {
+ WARN(("vboxCmdVbvaCtlCreate failed"));
+ return VERR_NO_MEMORY;
+ }
- if (i32Diff <= 0)
+ pCtl->Hdr.u32Type = VBOXCMDVBVACTL_TYPE_ENABLE;
+ pCtl->Hdr.i32Result = VERR_NOT_IMPLEMENTED;
+ memset(&pCtl->Enable, 0, sizeof (pCtl->Enable));
+ pCtl->Enable.u32Flags = fEnable? VBVA_F_ENABLE: VBVA_F_DISABLE;
+ pCtl->Enable.u32Offset = pCtx->offVRAMBuffer;
+ pCtl->Enable.i32Result = VERR_NOT_SUPPORTED;
+ pCtl->Enable.u32Flags |= VBVA_F_ABSOFFSET;
+
+ int rc = vboxCmdVbvaCtlSubmitSync(pHGSMICtx, &pCtl->Hdr);
+ if (RT_SUCCESS(rc))
{
- /* Chunk will not cross buffer boundary. */
- memcpy (dst, p, cb);
+ rc = pCtl->Hdr.i32Result;
+ if (!RT_SUCCESS(rc))
+ WARN(("vboxCmdVbvaCtlSubmitSync Disable failed %d", rc));
}
else
+ WARN(("vboxCmdVbvaCtlSubmitSync returnd %d", rc));
+
+ vboxCmdVbvaCtlFree(pHGSMICtx, &pCtl->Hdr);
+
+ return rc;
+}
+
+/*
+ * Public hardware buffer methods.
+ */
+RTDECL(int) VBoxVBVAExEnable(PVBVAEXBUFFERCONTEXT pCtx,
+ PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
+ VBVABUFFER *pVBVA)
+{
+ int rc = VERR_GENERAL_FAILURE;
+
+ LogFlowFunc(("pVBVA %p\n", pVBVA));
+
+#if 0 /* All callers check this */
+ if (ppdev->bHGSMISupported)
+#endif
{
- /* Chunk crosses buffer boundary. */
- memcpy (dst, p, u32BytesTillBoundary);
- memcpy (&pVBVA->au8Data[0], (uint8_t *)p + u32BytesTillBoundary, i32Diff);
+ LogFunc(("pVBVA %p vbva off 0x%x\n", pVBVA, pCtx->offVRAMBuffer));
+
+ pVBVA->hostFlags.u32HostEvents = 0;
+ pVBVA->hostFlags.u32SupportedOrders = 0;
+ pVBVA->off32Data = 0;
+ pVBVA->off32Free = 0;
+ memset(pVBVA->aRecords, 0, sizeof (pVBVA->aRecords));
+ pVBVA->indexRecordFirst = 0;
+ pVBVA->indexRecordFree = 0;
+ pVBVA->cbPartialWriteThreshold = 256;
+ pVBVA->cbData = pCtx->cbBuffer - sizeof (VBVABUFFER) + sizeof (pVBVA->au8Data);
+
+ pCtx->fHwBufferOverflow = false;
+ pCtx->pRecord = NULL;
+ pCtx->pVBVA = pVBVA;
+
+ rc = vboxVBVAExCtlSubmitEnableDisable(pCtx, pHGSMICtx, true);
+ }
+
+ if (!RT_SUCCESS(rc))
+ {
+ WARN(("enable failed %d", rc));
+ VBoxVBVAExDisable(pCtx, pHGSMICtx);
}
+ return rc;
+}
+
+RTDECL(void) VBoxVBVAExDisable(PVBVAEXBUFFERCONTEXT pCtx,
+ PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx)
+{
+ LogFlowFunc(("\n"));
+
+ pCtx->fHwBufferOverflow = false;
+ pCtx->pRecord = NULL;
+ pCtx->pVBVA = NULL;
+
+ vboxVBVAExCtlSubmitEnableDisable(pCtx, pHGSMICtx, false);
+
return;
}
-BOOL vboxVbvaBufferBeginUpdate (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva)
+RTDECL(bool) VBoxVBVAExBufferBeginUpdate(PVBVAEXBUFFERCONTEXT pCtx,
+ PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx)
{
- BOOL bRc = FALSE;
+ bool bRc = false;
- // DISPDBG((1, "VBoxDisp::vboxHwBufferBeginUpdate called flags = 0x%08X\n",
- // ppdev->pVBVA? ppdev->pVBVA->u32HostEvents: -1));
+ // LogFunc(("flags = 0x%08X\n", pCtx->pVBVA? pCtx->pVBVA->u32HostEvents: -1));
- if ( pVbva->pVBVA
- && (pVbva->pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))
+ if ( pCtx->pVBVA
+ && (pCtx->pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))
{
uint32_t indexRecordNext;
- Assert (!pVbva->fHwBufferOverflow);
- Assert (pVbva->pRecord == NULL);
+ Assert(!pCtx->fHwBufferOverflow);
+ Assert(pCtx->pRecord == NULL);
- indexRecordNext = (pVbva->pVBVA->indexRecordFree + 1) % VBVA_MAX_RECORDS;
+ indexRecordNext = (pCtx->pVBVA->indexRecordFree + 1) % VBVA_MAX_RECORDS;
- if (indexRecordNext == pVbva->pVBVA->indexRecordFirst)
+ if (indexRecordNext == pCtx->indexRecordFirstUncompleted)
{
/* All slots in the records queue are used. */
- vboxHwBufferFlush (pDevExt, pVbva);
+ vboxVBVAExFlush (pCtx, pHGSMICtx);
}
- if (indexRecordNext == pVbva->pVBVA->indexRecordFirst)
+ if (indexRecordNext == pCtx->indexRecordFirstUncompleted)
{
-// /* Even after flush there is no place. Fail the request. */
-// LOG(("no space in the queue of records!!! first %d, last %d",
-// ppdev->pVBVA->indexRecordFirst, ppdev->pVBVA->indexRecordFree));
+ /* Even after flush there is no place. Fail the request. */
+ LogFunc(("no space in the queue of records!!! first %d, last %d\n",
+ indexRecordNext, pCtx->pVBVA->indexRecordFree));
}
else
{
/* Initialize the record. */
- VBVARECORD *pRecord = &pVbva->pVBVA->aRecords[pVbva->pVBVA->indexRecordFree];
+ VBVARECORD *pRecord = &pCtx->pVBVA->aRecords[pCtx->pVBVA->indexRecordFree];
pRecord->cbRecord = VBVA_F_RECORD_PARTIAL;
- pVbva->pVBVA->indexRecordFree = indexRecordNext;
+ pCtx->pVBVA->indexRecordFree = indexRecordNext;
- // LOG(("indexRecordNext = %d\n", indexRecordNext));
+ // LogFunc(("indexRecordNext = %d\n", indexRecordNext));
/* Remember which record we are using. */
- pVbva->pRecord = pRecord;
+ pCtx->pRecord = pRecord;
- bRc = TRUE;
+ bRc = true;
}
}
return bRc;
}
-void vboxVbvaBufferEndUpdate (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva)
+RTDECL(void) VBoxVBVAExBufferEndUpdate(PVBVAEXBUFFERCONTEXT pCtx)
{
VBVARECORD *pRecord;
- // LOG(("VBoxDisp::vboxHwBufferEndUpdate called"));
+ // LogFunc(("\n"));
- Assert(pVbva->pVBVA);
+ Assert(pCtx->pVBVA);
- pRecord = pVbva->pRecord;
- Assert (pRecord && (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL));
+ pRecord = pCtx->pRecord;
+ Assert(pRecord && (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL));
/* Mark the record completed. */
pRecord->cbRecord &= ~VBVA_F_RECORD_PARTIAL;
- pVbva->fHwBufferOverflow = FALSE;
- pVbva->pRecord = NULL;
+ pCtx->fHwBufferOverflow = false;
+ pCtx->pRecord = NULL;
+
+ return;
+}
+
+DECLINLINE(bool) vboxVBVAExIsEntryInRange(uint32_t u32First, uint32_t u32Entry, uint32_t u32Free)
+{
+ return ( u32First != u32Free
+ && (
+ (u32First < u32Free && u32Entry >= u32First && u32Entry < u32Free)
+ || (u32First > u32Free && (u32Entry >= u32First || u32Entry < u32Free))
+ )
+ );
+}
+
+#ifdef DEBUG
+
+DECLINLINE(void) vboxHwBufferVerifyCompleted(PVBVAEXBUFFERCONTEXT pCtx)
+{
+ VBVABUFFER *pVBVA = pCtx->pVBVA;
+ if (!vboxVBVAExIsEntryInRange(pCtx->indexRecordFirstUncompleted, pVBVA->indexRecordFirst, pVBVA->indexRecordFree))
+ {
+ WARN(("invalid record set"));
+ }
+
+ if (!vboxVBVAExIsEntryInRange(pCtx->off32DataUncompleted, pVBVA->off32Data, pVBVA->off32Free))
+ {
+ WARN(("invalid data set"));
+ }
+}
+#endif
+
+/*
+ * Private operations.
+ */
+static uint32_t vboxHwBufferAvail(PVBVAEXBUFFERCONTEXT pCtx, const VBVABUFFER *pVBVA)
+{
+ int32_t i32Diff = pCtx->off32DataUncompleted - pVBVA->off32Free;
+
+ return i32Diff > 0? i32Diff: pVBVA->cbData + i32Diff;
+}
+
+static uint32_t vboxHwBufferContiguousAvail(PVBVAEXBUFFERCONTEXT pCtx, const VBVABUFFER *pVBVA)
+{
+ int32_t i32Diff = pCtx->off32DataUncompleted - pVBVA->off32Free;
+
+ return i32Diff > 0 ? i32Diff: pVBVA->cbData - pVBVA->off32Free;
+}
+
+static void vboxHwBufferPlaceDataAt(PVBVAEXBUFFERCONTEXT pCtx, const void *p,
+ uint32_t cb, uint32_t offset)
+{
+ VBVABUFFER *pVBVA = pCtx->pVBVA;
+ uint32_t u32BytesTillBoundary = pVBVA->cbData - offset;
+ uint8_t *dst = &pVBVA->au8Data[offset];
+ int32_t i32Diff = cb - u32BytesTillBoundary;
+
+ if (i32Diff <= 0)
+ {
+ /* Chunk will not cross buffer boundary. */
+ memcpy (dst, p, cb);
+ }
+ else
+ {
+ /* Chunk crosses buffer boundary. */
+ memcpy (dst, p, u32BytesTillBoundary);
+ memcpy (&pVBVA->au8Data[0], (uint8_t *)p + u32BytesTillBoundary, i32Diff);
+ }
return;
}
-static int vboxHwBufferWrite (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva, const void *p, uint32_t cb)
+static bool vboxHwBufferWrite(PVBVAEXBUFFERCONTEXT pCtx,
+ PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
+ const void *p, uint32_t cb)
{
VBVARECORD *pRecord;
uint32_t cbHwBufferAvail;
uint32_t cbWritten = 0;
- VBVABUFFER *pVBVA = pVbva->pVBVA;
+ VBVABUFFER *pVBVA = pCtx->pVBVA;
Assert(pVBVA);
- if (!pVBVA || pVbva->fHwBufferOverflow)
+ if (!pVBVA || pCtx->fHwBufferOverflow)
{
- return VERR_INVALID_STATE;
+ return false;
}
- Assert (pVBVA->indexRecordFirst != pVBVA->indexRecordFree);
+ Assert(pVBVA->indexRecordFirst != pVBVA->indexRecordFree);
+ Assert(pCtx->indexRecordFirstUncompleted != pVBVA->indexRecordFree);
- pRecord = pVbva->pRecord;
- Assert (pRecord && (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL));
+ pRecord = pCtx->pRecord;
+ Assert(pRecord && (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL));
-// LOGF(("VW %d", cb));
+ // LogFunc(("%d\n", cb));
- cbHwBufferAvail = vboxHwBufferAvail (pVBVA);
+ cbHwBufferAvail = vboxHwBufferAvail(pCtx, pVBVA);
while (cb > 0)
{
uint32_t cbChunk = cb;
- // LOG(("pVBVA->off32Free %d, pRecord->cbRecord 0x%08X, cbHwBufferAvail %d, cb %d, cbWritten %d\n",
- // pVBVA->off32Free, pRecord->cbRecord, cbHwBufferAvail, cb, cbWritten));
+ // LogFunc(("pVBVA->off32Free %d, pRecord->cbRecord 0x%08X, cbHwBufferAvail %d, cb %d, cbWritten %d\n",
+ // pVBVA->off32Free, pRecord->cbRecord, cbHwBufferAvail, cb, cbWritten));
if (cbChunk >= cbHwBufferAvail)
{
- LOGF(("1) avail %d, chunk %d", cbHwBufferAvail, cbChunk));
+ LogFunc(("1) avail %d, chunk %d\n", cbHwBufferAvail, cbChunk));
- vboxHwBufferFlush (pDevExt, pVbva);
+ vboxVBVAExFlush(pCtx, pHGSMICtx);
- cbHwBufferAvail = vboxHwBufferAvail (pVBVA);
+ cbHwBufferAvail = vboxHwBufferAvail(pCtx, pVBVA);
if (cbChunk >= cbHwBufferAvail)
{
- LOG(("no place for %d bytes. Only %d bytes available after flush. Going to partial writes.",
- cb, cbHwBufferAvail));
+ WARN(("no place for %d bytes. Only %d bytes available after flush. Going to partial writes.\n",
+ cb, cbHwBufferAvail));
if (cbHwBufferAvail <= pVBVA->cbPartialWriteThreshold)
{
- LOGREL(("Buffer overflow!!!"));
- pVbva->fHwBufferOverflow = TRUE;
- Assert(FALSE);
- return VERR_NO_MEMORY;
+ WARN(("Buffer overflow!!!\n"));
+ pCtx->fHwBufferOverflow = true;
+ Assert(false);
+ return false;
}
cbChunk = cbHwBufferAvail - pVBVA->cbPartialWriteThreshold;
@@ -314,9 +488,9 @@ static int vboxHwBufferWrite (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva, const
}
Assert(cbChunk <= cb);
- Assert(cbChunk <= vboxHwBufferAvail (pVBVA));
+ Assert(cbChunk <= vboxHwBufferAvail(pCtx, pVBVA));
- vboxHwBufferPlaceDataAt (pVbva->pVBVA, (uint8_t *)p + cbWritten, cbChunk, pVBVA->off32Free);
+ vboxHwBufferPlaceDataAt (pCtx, (uint8_t *)p + cbWritten, cbChunk, pVBVA->off32Free);
pVBVA->off32Free = (pVBVA->off32Free + cbChunk) % pVBVA->cbData;
pRecord->cbRecord += cbChunk;
@@ -326,45 +500,632 @@ static int vboxHwBufferWrite (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva, const
cbWritten += cbChunk;
}
- return VINF_SUCCESS;
+ return true;
}
/*
* Public writer to the hardware buffer.
*/
-int vboxWrite (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva, const void *pv, uint32_t cb)
+RTDECL(uint32_t) VBoxVBVAExGetFreeTail(PVBVAEXBUFFERCONTEXT pCtx)
{
- return vboxHwBufferWrite (pDevExt, pVbva, pv, cb);
+ VBVABUFFER *pVBVA = pCtx->pVBVA;
+ if (pVBVA->off32Data <= pVBVA->off32Free)
+ return pVBVA->cbData - pVBVA->off32Free;
+ return 0;
}
-
-int vboxVbvaReportDirtyRect (PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSrc, RECT *pRectOrig)
+RTDECL(void*) VBoxVBVAExAllocContiguous(PVBVAEXBUFFERCONTEXT pCtx, PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx, uint32_t cb)
{
- VBVACMDHDR hdr;
+ VBVARECORD *pRecord;
+ uint32_t cbHwBufferContiguousAvail;
+ uint32_t offset;
- RECT rect = *pRectOrig;
+ VBVABUFFER *pVBVA = pCtx->pVBVA;
+ Assert(pVBVA);
-// if (rect.left < 0) rect.left = 0;
-// if (rect.top < 0) rect.top = 0;
-// if (rect.right > (int)ppdev->cxScreen) rect.right = ppdev->cxScreen;
-// if (rect.bottom > (int)ppdev->cyScreen) rect.bottom = ppdev->cyScreen;
+ if (!pVBVA || pCtx->fHwBufferOverflow)
+ {
+ return NULL;
+ }
+
+ Assert(pVBVA->indexRecordFirst != pVBVA->indexRecordFree);
+ Assert(pCtx->indexRecordFirstUncompleted != pVBVA->indexRecordFree);
- hdr.x = (int16_t)rect.left;
- hdr.y = (int16_t)rect.top;
- hdr.w = (uint16_t)(rect.right - rect.left);
- hdr.h = (uint16_t)(rect.bottom - rect.top);
+ pRecord = pCtx->pRecord;
+ Assert(pRecord && (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL));
- hdr.x += (int16_t)pSrc->VScreenPos.x;
- hdr.y += (int16_t)pSrc->VScreenPos.y;
+ // LogFunc(("%d\n", cb));
- return vboxWrite (pDevExt, &pSrc->Vbva, &hdr, sizeof(hdr));
+ if (pVBVA->cbData < cb)
+ {
+ WARN(("requested to allocate buffer of size %d bigger than the VBVA ring buffer size %d", cb, pVBVA->cbData));
+ return NULL;
+ }
+
+ cbHwBufferContiguousAvail = vboxHwBufferContiguousAvail(pCtx, pVBVA);
+
+ if (cbHwBufferContiguousAvail < cb)
+ {
+ if (cb < pVBVA->cbData - pVBVA->off32Free)
+ {
+ /* the entire contiguous part is smaller than the requested buffer */
+ return NULL;
+ }
+
+ vboxVBVAExFlush(pCtx, pHGSMICtx);
+
+ cbHwBufferContiguousAvail = vboxHwBufferContiguousAvail(pCtx, pVBVA);
+ if (cbHwBufferContiguousAvail < cb)
+ {
+ /* this is really bad - the host did not clean up buffer even after we requested it to flush */
+ WARN(("Host did not clean up the buffer!"));
+ return NULL;
+ }
+ }
+
+ offset = pVBVA->off32Free;
+
+ pVBVA->off32Free = (pVBVA->off32Free + cb) % pVBVA->cbData;
+ pRecord->cbRecord += cb;
+
+ return &pVBVA->au8Data[offset];
}
-#ifdef VBOXVDMA_WITH_VBVA
-int vboxVbvaReportCmdOffset (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva, uint32_t offCmd)
+RTDECL(bool) VBoxVBVAExIsProcessing(PVBVAEXBUFFERCONTEXT pCtx)
{
- VBOXVDMAVBVACMD cmd;
- cmd.offCmd = offCmd;
- return vboxWrite (pDevExt, pVbva, &cmd, sizeof(cmd));
+ uint32_t u32HostEvents = pCtx->pVBVA->hostFlags.u32HostEvents;
+ return !!(u32HostEvents & VBVA_F_STATE_PROCESSING);
}
+
+RTDECL(void) VBoxVBVAExCBufferCompleted(PVBVAEXBUFFERCONTEXT pCtx)
+{
+ VBVABUFFER *pVBVA = pCtx->pVBVA;
+ uint32_t cbBuffer = pVBVA->aRecords[pCtx->indexRecordFirstUncompleted].cbRecord;
+ pCtx->indexRecordFirstUncompleted = (pCtx->indexRecordFirstUncompleted + 1) % VBVA_MAX_RECORDS;
+ pCtx->off32DataUncompleted = (pCtx->off32DataUncompleted + cbBuffer) % pVBVA->cbData;
+#ifdef DEBUG
+ vboxHwBufferVerifyCompleted(pCtx);
#endif
+}
+
+RTDECL(bool) VBoxVBVAExWrite(PVBVAEXBUFFERCONTEXT pCtx,
+ PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
+ const void *pv, uint32_t cb)
+{
+ return vboxHwBufferWrite(pCtx, pHGSMICtx, pv, cb);
+}
+
+RTDECL(bool) VBoxVBVAExOrderSupported(PVBVAEXBUFFERCONTEXT pCtx, unsigned code)
+{
+ VBVABUFFER *pVBVA = pCtx->pVBVA;
+
+ if (!pVBVA)
+ {
+ return false;
+ }
+
+ if (pVBVA->hostFlags.u32SupportedOrders & (1 << code))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+RTDECL(void) VBoxVBVAExSetupBufferContext(PVBVAEXBUFFERCONTEXT pCtx,
+ uint32_t offVRAMBuffer,
+ uint32_t cbBuffer,
+ PFNVBVAEXBUFFERFLUSH pfnFlush,
+ void *pvFlush)
+{
+ memset(pCtx, 0, RT_OFFSETOF(VBVAEXBUFFERCONTEXT, pVBVA));
+ pCtx->offVRAMBuffer = offVRAMBuffer;
+ pCtx->cbBuffer = cbBuffer;
+ pCtx->pfnFlush = pfnFlush;
+ pCtx->pvFlush = pvFlush;
+}
+
+static void* vboxVBVAExIterCur(PVBVAEXBUFFERITERBASE pIter, struct VBVABUFFER *pVBVA, uint32_t *pcbBuffer, bool *pfProcessed)
+{
+ uint32_t cbRecord = pVBVA->aRecords[pIter->iCurRecord].cbRecord;
+ if (cbRecord == VBVA_F_RECORD_PARTIAL)
+ return NULL;
+ if (pcbBuffer)
+ *pcbBuffer = cbRecord;
+ if (pfProcessed)
+ *pfProcessed = !vboxVBVAExIsEntryInRange(pVBVA->indexRecordFirst, pIter->iCurRecord, pVBVA->indexRecordFree);
+ return &pVBVA->au8Data[pIter->off32CurCmd];
+}
+
+DECLINLINE(uint32_t) vboxVBVAExSubst(uint32_t x, uint32_t val, uint32_t maxVal)
+{
+ int32_t result = (int32_t)(x - val);
+ return result >= 0 ? (uint32_t)result : maxVal - (((uint32_t)(-result)) % maxVal);
+}
+
+RTDECL(void) VBoxVBVAExBIterInit(PVBVAEXBUFFERCONTEXT pCtx, PVBVAEXBUFFERBACKWARDITER pIter)
+{
+ struct VBVABUFFER *pVBVA = pCtx->pVBVA;
+ pIter->Base.pCtx = pCtx;
+ uint32_t iCurRecord = vboxVBVAExSubst(pVBVA->indexRecordFree, 1, VBVA_MAX_RECORDS);
+ if (vboxVBVAExIsEntryInRange(pCtx->indexRecordFirstUncompleted, iCurRecord, pVBVA->indexRecordFree))
+ {
+ /* even if the command gets completed by the time we're doing the pCtx->pVBVA->aRecords[iCurRecord].cbRecord below,
+ * the pCtx->pVBVA->aRecords[iCurRecord].cbRecord will still be valid, as it can only be modified by a submitter,
+ * and we are in a submitter context now */
+ pIter->Base.iCurRecord = iCurRecord;
+ pIter->Base.off32CurCmd = vboxVBVAExSubst(pVBVA->off32Free, pCtx->pVBVA->aRecords[iCurRecord].cbRecord, pVBVA->cbData);
+ }
+ else
+ {
+ /* no data */
+ pIter->Base.iCurRecord = pVBVA->indexRecordFree;
+ pIter->Base.off32CurCmd = pVBVA->off32Free;
+ }
+}
+
+RTDECL(void*) VBoxVBVAExBIterNext(PVBVAEXBUFFERBACKWARDITER pIter, uint32_t *pcbBuffer, bool *pfProcessed)
+{
+ PVBVAEXBUFFERCONTEXT pCtx = pIter->Base.pCtx;
+ struct VBVABUFFER *pVBVA = pCtx->pVBVA;
+ uint32_t indexRecordFirstUncompleted = pCtx->indexRecordFirstUncompleted;
+ if (!vboxVBVAExIsEntryInRange(indexRecordFirstUncompleted, pIter->Base.iCurRecord, pVBVA->indexRecordFree))
+ return NULL;
+
+ void *pvBuffer = vboxVBVAExIterCur(&pIter->Base, pVBVA, pcbBuffer, pfProcessed);
+ AssertRelease(pvBuffer);
+
+ /* even if the command gets completed by the time we're doing the pCtx->pVBVA->aRecords[pIter->Base.iCurRecord].cbRecord below,
+ * the pCtx->pVBVA->aRecords[pIter->Base.iCurRecord].cbRecord will still be valid, as it can only be modified by a submitter,
+ * and we are in a submitter context now */
+ pIter->Base.iCurRecord = vboxVBVAExSubst(pIter->Base.iCurRecord, 1, VBVA_MAX_RECORDS);
+ pIter->Base.off32CurCmd = vboxVBVAExSubst(pIter->Base.off32CurCmd, pCtx->pVBVA->aRecords[pIter->Base.iCurRecord].cbRecord, pVBVA->cbData);
+
+ return pvBuffer;
+}
+
+RTDECL(void) VBoxVBVAExCFIterInit(PVBVAEXBUFFERCONTEXT pCtx, PVBVAEXBUFFERFORWARDITER pIter)
+{
+ pIter->Base.pCtx = pCtx;
+ pIter->Base.iCurRecord = pCtx->indexRecordFirstUncompleted;
+ pIter->Base.off32CurCmd = pCtx->off32DataUncompleted;
+}
+
+RTDECL(void*) VBoxVBVAExCFIterNext(PVBVAEXBUFFERFORWARDITER pIter, uint32_t *pcbBuffer, bool *pfProcessed)
+{
+ PVBVAEXBUFFERCONTEXT pCtx = pIter->Base.pCtx;
+ struct VBVABUFFER *pVBVA = pCtx->pVBVA;
+ uint32_t indexRecordFree = pVBVA->indexRecordFree;
+ if (!vboxVBVAExIsEntryInRange(pCtx->indexRecordFirstUncompleted, pIter->Base.iCurRecord, indexRecordFree))
+ return NULL;
+
+ uint32_t cbBuffer;
+ void *pvData = vboxVBVAExIterCur(&pIter->Base, pVBVA, &cbBuffer, pfProcessed);
+ if (!pvData)
+ return NULL;
+
+ pIter->Base.iCurRecord = (pIter->Base.iCurRecord + 1) % VBVA_MAX_RECORDS;
+ pIter->Base.off32CurCmd = (pIter->Base.off32CurCmd + cbBuffer) % pVBVA->cbData;
+
+ if (pcbBuffer)
+ *pcbBuffer = cbBuffer;
+
+ return pvData;
+}
+
+/**/
+
+int VBoxCmdVbvaEnable(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva)
+{
+ return VBoxVBVAExEnable(&pVbva->Vbva, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx, pVbva->Vbva.pVBVA);
+}
+
+int VBoxCmdVbvaDisable(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva)
+{
+ VBoxVBVAExDisable(&pVbva->Vbva, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx);
+ return VINF_SUCCESS;
+}
+
+int VBoxCmdVbvaDestroy(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva)
+{
+ int rc = VINF_SUCCESS;
+ VBoxMPCmnUnmapAdapterMemory(VBoxCommonFromDeviceExt(pDevExt), (void**)&pVbva->Vbva.pVBVA);
+ memset(pVbva, 0, sizeof (*pVbva));
+ return rc;
+}
+
+static void vboxCmdVbvaDdiNotifyCompleteIrq(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, UINT u32FenceId, DXGK_INTERRUPT_TYPE enmComplType)
+{
+ DXGKARGCB_NOTIFY_INTERRUPT_DATA notify;
+ memset(&notify, 0, sizeof(DXGKARGCB_NOTIFY_INTERRUPT_DATA));
+ switch (enmComplType)
+ {
+ case DXGK_INTERRUPT_DMA_COMPLETED:
+ notify.InterruptType = DXGK_INTERRUPT_DMA_COMPLETED;
+ notify.DmaCompleted.SubmissionFenceId = u32FenceId;
+ notify.DmaCompleted.NodeOrdinal = pVbva->idNode;
+ break;
+
+ case DXGK_INTERRUPT_DMA_PREEMPTED:
+ notify.InterruptType = DXGK_INTERRUPT_DMA_PREEMPTED;
+ notify.DmaPreempted.PreemptionFenceId = u32FenceId;
+ notify.DmaPreempted.NodeOrdinal = pVbva->idNode;
+ notify.DmaPreempted.LastCompletedFenceId = pVbva->u32FenceCompleted;
+ break;
+
+ case DXGK_INTERRUPT_DMA_FAULTED:
+ Assert(0);
+ notify.InterruptType = DXGK_INTERRUPT_DMA_FAULTED;
+ notify.DmaFaulted.FaultedFenceId = u32FenceId;
+ notify.DmaFaulted.Status = STATUS_UNSUCCESSFUL; /* @todo: better status ? */
+ notify.DmaFaulted.NodeOrdinal = pVbva->idNode;
+ break;
+
+ default:
+ WARN(("unrecognized completion type %d", enmComplType));
+ break;
+ }
+
+ pDevExt->u.primary.DxgkInterface.DxgkCbNotifyInterrupt(pDevExt->u.primary.DxgkInterface.DeviceHandle, &notify);
+}
+
+typedef struct VBOXCMDVBVA_NOTIFYCOMPLETED_CB
+{
+ PVBOXMP_DEVEXT pDevExt;
+ VBOXCMDVBVA *pVbva;
+ volatile UINT *pu32FenceId;
+ DXGK_INTERRUPT_TYPE enmComplType;
+} VBOXCMDVBVA_NOTIFYCOMPLETED_CB, *PVBOXCMDVBVA_NOTIFYCOMPLETED_CB;
+
+static BOOLEAN vboxCmdVbvaDdiNotifyCompleteCb(PVOID pvContext)
+{
+ PVBOXCMDVBVA_NOTIFYCOMPLETED_CB pData = (PVBOXCMDVBVA_NOTIFYCOMPLETED_CB)pvContext;
+ if (*pData->pu32FenceId)
+ {
+ UINT u32FenceId = *pData->pu32FenceId;
+ *pData->pu32FenceId = 0;
+
+ vboxCmdVbvaDdiNotifyCompleteIrq(pData->pDevExt, pData->pVbva, u32FenceId, pData->enmComplType);
+
+ pData->pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pData->pDevExt->u.primary.DxgkInterface.DeviceHandle);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static int vboxCmdVbvaDdiNotifyComplete(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, volatile UINT *pu32FenceId, DXGK_INTERRUPT_TYPE enmComplType)
+{
+ VBOXCMDVBVA_NOTIFYCOMPLETED_CB Data;
+ Data.pDevExt = pDevExt;
+ Data.pVbva = pVbva;
+ Data.pu32FenceId = pu32FenceId;
+ Data.enmComplType = enmComplType;
+ BOOLEAN bDummy;
+ NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbSynchronizeExecution(
+ pDevExt->u.primary.DxgkInterface.DeviceHandle,
+ vboxCmdVbvaDdiNotifyCompleteCb,
+ &Data,
+ 0, /* IN ULONG MessageNumber */
+ &bDummy);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("DxgkCbSynchronizeExecution failed Status %#x", Status));
+ return VERR_GENERAL_FAILURE;
+ }
+ return Status;
+}
+
+static int vboxCmdVbvaFlush(PVBOXMP_DEVEXT pDevExt, HGSMIGUESTCOMMANDCONTEXT *pCtx, bool fBufferOverflow)
+{
+ /* Issue the flush command. */
+ VBVACMDVBVAFLUSH *pFlush = (VBVACMDVBVAFLUSH*)VBoxHGSMIBufferAlloc(pCtx,
+ sizeof (VBVACMDVBVAFLUSH),
+ HGSMI_CH_VBVA,
+ VBVA_CMDVBVA_FLUSH);
+ if (!pFlush)
+ {
+ WARN(("VBoxHGSMIBufferAlloc failed\n"));
+ return VERR_OUT_OF_RESOURCES;
+ }
+
+ pFlush->u32Flags = fBufferOverflow ? VBVACMDVBVAFLUSH_F_GUEST_BUFFER_OVERFLOW : 0;
+
+ VBoxHGSMIBufferSubmit(pCtx, pFlush);
+
+ VBoxHGSMIBufferFree(pCtx, pFlush);
+
+ return VINF_SUCCESS;
+}
+
+typedef struct VBOXCMDVBVA_CHECK_COMPLETED_CB
+{
+ PVBOXMP_DEVEXT pDevExt;
+ VBOXCMDVBVA *pVbva;
+ uint32_t u32FenceID;
+} VBOXCMDVBVA_CHECK_COMPLETED_CB;
+
+static BOOLEAN vboxCmdVbvaCheckCompletedIrqCb(PVOID pContext)
+{
+ VBOXCMDVBVA_CHECK_COMPLETED_CB *pCompleted = (VBOXCMDVBVA_CHECK_COMPLETED_CB*)pContext;
+ BOOLEAN bRc = DxgkDdiInterruptRoutineNew(pCompleted->pDevExt, 0);
+ if (pCompleted->pVbva)
+ pCompleted->u32FenceID = pCompleted->pVbva->u32FenceCompleted;
+ return bRc;
+}
+
+
+static uint32_t vboxCmdVbvaCheckCompleted(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, bool fPingHost, HGSMIGUESTCOMMANDCONTEXT *pCtx, bool fBufferOverflow)
+{
+ if (fPingHost)
+ vboxCmdVbvaFlush(pDevExt, pCtx, fBufferOverflow);
+
+ VBOXCMDVBVA_CHECK_COMPLETED_CB context;
+ context.pDevExt = pDevExt;
+ context.pVbva = pVbva;
+ context.u32FenceID = 0;
+ BOOLEAN bRet;
+ NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbSynchronizeExecution(
+ pDevExt->u.primary.DxgkInterface.DeviceHandle,
+ vboxCmdVbvaCheckCompletedIrqCb,
+ &context,
+ 0, /* IN ULONG MessageNumber */
+ &bRet);
+ Assert(Status == STATUS_SUCCESS);
+
+ return context.u32FenceID;
+}
+
+DECLCALLBACK(void) voxCmdVbvaFlushCb(struct VBVAEXBUFFERCONTEXT *pCtx, PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx, void *pvFlush)
+{
+ PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)pvFlush;
+
+ vboxCmdVbvaCheckCompleted(pDevExt, NULL, true /*fPingHost*/, pHGSMICtx, true /*fBufferOverflow*/);
+}
+
+int VBoxCmdVbvaCreate(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, ULONG offBuffer, ULONG cbBuffer)
+{
+ memset(pVbva, 0, sizeof (*pVbva));
+
+ int rc = VBoxMPCmnMapAdapterMemory(VBoxCommonFromDeviceExt(pDevExt),
+ (void**)&pVbva->Vbva.pVBVA,
+ offBuffer,
+ cbBuffer);
+ if (RT_SUCCESS(rc))
+ {
+ Assert(pVbva->Vbva.pVBVA);
+ VBoxVBVAExSetupBufferContext(&pVbva->Vbva, offBuffer, cbBuffer, voxCmdVbvaFlushCb, pDevExt);
+ }
+ else
+ {
+ WARN(("VBoxMPCmnMapAdapterMemory failed rc %d", rc));
+ }
+
+ return rc;
+}
+
+int VBoxCmdVbvaSubmit(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, struct VBOXCMDVBVA_HDR *pCmd, uint32_t cbCmd)
+{
+ int rc = VINF_SUCCESS;
+
+ pCmd->u8State = VBOXCMDVBVA_STATE_SUBMITTED;
+ pVbva->u32FenceSubmitted = pCmd->u32FenceID;
+
+ if (VBoxVBVAExGetSize(&pVbva->Vbva) > cbCmd)
+ {
+ WARN(("buffer does not fit the vbva buffer, we do not support splitting buffers"));
+ return VERR_NOT_SUPPORTED;
+ }
+
+ if (!VBoxVBVAExBufferBeginUpdate(&pVbva->Vbva, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx))
+ {
+ WARN(("VBoxVBVAExBufferBeginUpdate failed!"));
+ return VERR_GENERAL_FAILURE;
+ }
+
+ void* pvBuffer = VBoxVBVAExAllocContiguous(&pVbva->Vbva, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx, cbCmd);
+ if (!pvBuffer)
+ {
+ WARN(("failed to allocate contiguous buffer, trying nopping the tail"));
+ uint32_t cbTail = VBoxVBVAExGetFreeTail(&pVbva->Vbva);
+ if (!cbTail)
+ {
+ WARN(("this is not a free tail case, cbTail is NULL"));
+ return VERR_BUFFER_OVERFLOW;
+ }
+
+ Assert(cbTail < cbCmd);
+
+ pvBuffer = VBoxVBVAExAllocContiguous(&pVbva->Vbva, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx, cbTail);
+
+ Assert(pvBuffer);
+
+ *((uint8_t*)pvBuffer) = VBOXCMDVBVA_OPTYPE_NOP;
+
+ VBoxVBVAExBufferEndUpdate(&pVbva->Vbva);
+
+ if (!VBoxVBVAExBufferBeginUpdate(&pVbva->Vbva, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx))
+ {
+ WARN(("VBoxVBVAExBufferBeginUpdate 2 failed!"));
+ return VERR_GENERAL_FAILURE;
+ }
+
+ pvBuffer = VBoxVBVAExAllocContiguous(&pVbva->Vbva, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx, cbCmd);
+ if (!pvBuffer)
+ {
+ WARN(("failed to allocate contiguous buffer, failing"));
+ return VERR_GENERAL_FAILURE;
+ }
+ }
+
+ Assert(pvBuffer);
+
+ memcpy(pvBuffer, pCmd, cbCmd);
+
+ VBoxVBVAExBufferEndUpdate(&pVbva->Vbva);
+
+ if (!VBoxVBVAExIsProcessing(&pVbva->Vbva))
+ {
+ /* Issue the submit command. */
+ HGSMIGUESTCOMMANDCONTEXT *pCtx = &VBoxCommonFromDeviceExt(pDevExt)->guestCtx;
+ VBVACMDVBVASUBMIT *pSubmit = (VBVACMDVBVASUBMIT*)VBoxHGSMIBufferAlloc(pCtx,
+ sizeof (VBVACMDVBVASUBMIT),
+ HGSMI_CH_VBVA,
+ VBVA_CMDVBVA_SUBMIT);
+ if (!pSubmit)
+ {
+ WARN(("VBoxHGSMIBufferAlloc failed\n"));
+ return VERR_OUT_OF_RESOURCES;
+ }
+
+ pSubmit->u32Reserved = 0;
+
+ VBoxHGSMIBufferSubmit(pCtx, pSubmit);
+
+ VBoxHGSMIBufferFree(pCtx, pSubmit);
+ }
+
+ return VINF_SUCCESS;
+}
+
+bool VBoxCmdVbvaPreempt(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, uint32_t u32FenceID)
+{
+ VBVAEXBUFFERBACKWARDITER Iter;
+ VBoxVBVAExBIterInit(&pVbva->Vbva, &Iter);
+
+ uint32_t cbBuffer;
+ bool fProcessed;
+ uint8_t* pu8Cmd;
+
+ while ((pu8Cmd = (uint8_t*)VBoxVBVAExBIterNext(&Iter, &cbBuffer, &fProcessed)) != NULL)
+ {
+ if (*pu8Cmd == VBOXCMDVBVA_OPTYPE_NOP)
+ continue;
+
+ VBOXCMDVBVA_HDR *pCmd = (VBOXCMDVBVA_HDR*)pu8Cmd;
+
+ if (pCmd->u32FenceID != u32FenceID)
+ continue;
+
+ if (!ASMAtomicCmpXchgU8(&pCmd->u8State, VBOXCMDVBVA_STATE_CANCELLED, VBOXCMDVBVA_STATE_SUBMITTED))
+ {
+ Assert(pCmd->u8State == VBOXCMDVBVA_STATE_IN_PROGRESS);
+ break;
+ }
+
+ /* we have canceled the command successfully */
+ vboxCmdVbvaDdiNotifyComplete(pDevExt, pVbva, &pCmd->u32FenceID, DXGK_INTERRUPT_DMA_PREEMPTED);
+ return true;
+ }
+
+ return false;
+}
+
+bool VBoxCmdVbvaCheckCompletedIrq(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva)
+{
+ VBVAEXBUFFERFORWARDITER Iter;
+ VBoxVBVAExCFIterInit(&pVbva->Vbva, &Iter);
+
+ bool fHasCommandsCompletedPreempted = false;
+ bool fProcessed;
+ uint8_t* pu8Cmd;
+
+
+ while ((pu8Cmd = (uint8_t*)VBoxVBVAExCFIterNext(&Iter, NULL, &fProcessed)) != NULL)
+ {
+ if (!fProcessed)
+ break;
+
+ if (*pu8Cmd == VBOXCMDVBVA_OPTYPE_NOP)
+ continue;
+
+ VBOXCMDVBVA_HDR *pCmd = (VBOXCMDVBVA_HDR*)pu8Cmd;
+ uint8_t u8State = pCmd->u8State;
+ uint32_t u32FenceID = pCmd->u32FenceID;
+
+ Assert(u8State == VBOXCMDVBVA_STATE_IN_PROGRESS
+ || u8State == VBOXCMDVBVA_STATE_CANCELLED);
+ Assert(u32FenceID);
+ VBoxVBVAExCBufferCompleted(&pVbva->Vbva);
+ DXGK_INTERRUPT_TYPE enmDdiNotify;
+
+ if (u8State == VBOXCMDVBVA_STATE_IN_PROGRESS)
+ {
+ if (u32FenceID)
+ pVbva->u32FenceCompleted = u32FenceID;
+ enmDdiNotify = DXGK_INTERRUPT_DMA_COMPLETED;
+ }
+ else
+ {
+ Assert(u8State == VBOXCMDVBVA_STATE_CANCELLED);
+ enmDdiNotify = DXGK_INTERRUPT_DMA_PREEMPTED;
+ /* to prevent concurrent notifications from DdiPreemptCommand */
+ pCmd->u32FenceID = 0;
+ }
+
+ if (u32FenceID)
+ vboxCmdVbvaDdiNotifyCompleteIrq(pDevExt, pVbva, u32FenceID, enmDdiNotify);
+
+ fHasCommandsCompletedPreempted = true;
+ }
+
+ return fHasCommandsCompletedPreempted;
+}
+
+uint32_t VBoxCmdVbvaCheckCompleted(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, bool fPingHost)
+{
+ return vboxCmdVbvaCheckCompleted(pDevExt, pVbva, fPingHost, &VBoxCommonFromDeviceExt(pDevExt)->guestCtx, false /* fBufferOverflow */);
+}
+
+
+static uint32_t vboxCVDdiSysMemElBuild(VBOXCMDVBVA_SYSMEMEL *pEl, PMDL pMdl, uint32_t iPfn, uint32_t cPages)
+{
+ PFN_NUMBER cur = MmGetMdlPfnArray(pMdl)[iPfn];
+ uint32_t cbEl = sizeof (*pEl);
+ uint32_t cStoredPages = 1;
+ PFN_NUMBER next;
+ pEl->iPage1 = (uint32_t)(cur & 0xfffff);
+ pEl->iPage2 = (uint32_t)(cur >> 20);
+ --cPages;
+ for ( ; cPages && cStoredPages < VBOXCMDVBVA_SYSMEMEL_CPAGES_MAX; --cPages, ++cStoredPages, cur = next)
+ {
+ next = MmGetMdlPfnArray(pMdl)[iPfn+cStoredPages];
+ if (next != cur+1)
+ break;
+ }
+
+ Assert(cStoredPages);
+ pEl->cPagesAfterFirst = cStoredPages - 1;
+
+ return cPages;
+}
+
+uint32_t VBoxCVDdiPTransferVRamSysBuildEls(VBOXCMDVBVA_PAGING_TRANSFER *pCmd, PMDL pMdl, uint32_t iPfn, uint32_t cPages, uint32_t cbBuffer, uint32_t *pcPagesWritten)
+{
+ uint32_t cInitPages = cPages;
+ uint32_t cbInitBuffer = cbBuffer;
+ uint32_t cEls = 0;
+ VBOXCMDVBVA_SYSMEMEL *pEl = pCmd->aSysMem;
+
+ if (cbBuffer < sizeof (VBOXCMDVBVA_PAGING_TRANSFER))
+ {
+ WARN(("cbBuffer < sizeof (VBOXCMDVBVA_PAGING_TRANSFER)"));
+ goto done;
+ }
+
+ cbBuffer -= RT_OFFSETOF(VBOXCMDVBVA_PAGING_TRANSFER, aSysMem);
+ uint32_t i = 0;
+
+ for (; cPages && cbBuffer >= sizeof (VBOXCMDVBVA_PAGING_TRANSFER); ++cEls, cbBuffer-=sizeof (VBOXCMDVBVA_SYSMEMEL), ++pEl, ++i)
+ {
+ cPages = vboxCVDdiSysMemElBuild(pEl, pMdl, iPfn + cInitPages - cPages, cPages);
+ }
+
+ pCmd->cSysMem = i;
+
+done:
+ *pcPagesWritten = cInitPages - cPages;
+ return cbInitBuffer - cbBuffer;
+}
+
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.h b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.h
index 90b2a911..46bb2459 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.h
@@ -21,11 +21,7 @@
typedef struct VBOXVBVAINFO
{
- VBOXVIDEOOFFSET offVBVA;
- uint32_t cbVBVA;
- VBVABUFFER *pVBVA;
- BOOL fHwBufferOverflow;
- VBVARECORD *pRecord;
+ VBVABUFFERCONTEXT Vbva;
D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId;
KSPIN_LOCK Lock;
} VBOXVBVAINFO;
@@ -34,17 +30,14 @@ int vboxVbvaEnable(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva);
int vboxVbvaDisable(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva);
int vboxVbvaDestroy(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva);
int vboxVbvaCreate(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva, ULONG offBuffer, ULONG cbBuffer, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId);
-int vboxVbvaReportCmdOffset(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva, uint32_t offCmd);
int vboxVbvaReportDirtyRect(PVBOXMP_DEVEXT pDevExt, struct VBOXWDDM_SOURCE *pSrc, RECT *pRectOrig);
-BOOL vboxVbvaBufferBeginUpdate(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva);
-void vboxVbvaBufferEndUpdate(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva);
#define VBOXVBVA_OP(_op, _pdext, _psrc, _arg) \
do { \
- if (vboxVbvaBufferBeginUpdate(_pdext, &(_psrc)->Vbva)) \
+ if (VBoxVBVABufferBeginUpdate(&(_psrc)->Vbva.Vbva, &VBoxCommonFromDeviceExt(_pdext)->guestCtx)) \
{ \
vboxVbva##_op(_pdext, _psrc, _arg); \
- vboxVbvaBufferEndUpdate(_pdext, &(_psrc)->Vbva); \
+ VBoxVBVABufferEndUpdate(&(_psrc)->Vbva.Vbva); \
} \
} while (0)
@@ -65,4 +58,169 @@ void vboxVbvaBufferEndUpdate(PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva);
} while (0)
+/* customized VBVA implementation */
+struct VBVAEXBUFFERCONTEXT;
+
+typedef DECLCALLBACKPTR(void, PFNVBVAEXBUFFERFLUSH) (struct VBVAEXBUFFERCONTEXT *pCtx, PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx, void *pvFlush);
+
+/**
+ * Structure grouping the context needed for sending graphics acceleration
+ * information to the host via VBVA. Each screen has its own VBVA buffer.
+ */
+typedef struct VBVAEXBUFFERCONTEXT
+{
+ /** Offset of the buffer in the VRAM section for the screen */
+ uint32_t offVRAMBuffer;
+ /** Length of the buffer in bytes */
+ uint32_t cbBuffer;
+ /** This flag is set if we wrote to the buffer faster than the host could
+ * read it. */
+ bool fHwBufferOverflow;
+ /* the window between indexRecordFirstUncompleted and pVBVA->::indexRecordFirst represents
+ * command records processed by the host, but not completed by the guest yet */
+ volatile uint32_t indexRecordFirstUncompleted;
+ /* the window between off32DataUncompleted and pVBVA->::off32Data represents
+ * command data processed by the host, but not completed by the guest yet */
+ uint32_t off32DataUncompleted;
+ /* flush function */
+ PFNVBVAEXBUFFERFLUSH pfnFlush;
+ void *pvFlush;
+ /** The VBVA record that we are currently preparing for the host, NULL if
+ * none. */
+ struct VBVARECORD *pRecord;
+ /** Pointer to the VBVA buffer mapped into the current address space. Will
+ * be NULL if VBVA is not enabled. */
+ struct VBVABUFFER *pVBVA;
+} VBVAEXBUFFERCONTEXT, *PVBVAEXBUFFERCONTEXT;
+
+typedef struct VBVAEXBUFFERITERBASE
+{
+ struct VBVAEXBUFFERCONTEXT *pCtx;
+ /* index of the current record */
+ uint32_t iCurRecord;
+ /* offset of the current command */
+ uint32_t off32CurCmd;
+} VBVAEXBUFFERITERBASE, *PVBVAEXBUFFERITERBASE;
+
+typedef struct VBVAEXBUFFERFORWARDITER
+{
+ VBVAEXBUFFERITERBASE Base;
+} VBVAEXBUFFERFORWARDITER, *PVBVAEXBUFFERFORWARDITER;
+
+typedef struct VBVAEXBUFFERBACKWARDITER
+{
+ VBVAEXBUFFERITERBASE Base;
+} VBVAEXBUFFERBACKWARDITER, *PVBVAEXBUFFERBACKWARDITER;
+
+#define VBOXCMDVBVA_BUFFERSIZE(_cbCmdApprox) (RT_OFFSETOF(VBVABUFFER, au8Data) + ((RT_SIZEOFMEMB(VBVABUFFER, aRecords)/RT_SIZEOFMEMB(VBVABUFFER, aRecords[0])) * (_cbCmdApprox)))
+
+typedef struct VBOXCMDVBVA
+{
+ VBVAEXBUFFERCONTEXT Vbva;
+
+ /* last completted fence id */
+ uint32_t u32FenceCompleted;
+ /* last submitted fence id */
+ uint32_t u32FenceSubmitted;
+
+ /* node ordinal */
+ uint32_t idNode;
+} VBOXCMDVBVA;
+
+/** @name VBVAEx APIs
+ * @{ */
+RTDECL(int) VBoxVBVAExEnable(PVBVAEXBUFFERCONTEXT pCtx,
+ PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
+ struct VBVABUFFER *pVBVA);
+RTDECL(void) VBoxVBVAExDisable(PVBVAEXBUFFERCONTEXT pCtx,
+ PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx);
+RTDECL(bool) VBoxVBVAExBufferBeginUpdate(PVBVAEXBUFFERCONTEXT pCtx,
+ PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx);
+RTDECL(void) VBoxVBVAExBufferEndUpdate(PVBVAEXBUFFERCONTEXT pCtx);
+RTDECL(bool) VBoxVBVAExWrite(PVBVAEXBUFFERCONTEXT pCtx,
+ PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
+ const void *pv, uint32_t cb);
+
+RTDECL(bool) VBoxVBVAExOrderSupported(PVBVAEXBUFFERCONTEXT pCtx, unsigned code);
+
+RTDECL(void) VBoxVBVAExSetupBufferContext(PVBVAEXBUFFERCONTEXT pCtx,
+ uint32_t offVRAMBuffer,
+ uint32_t cbBuffer,
+ PFNVBVAEXBUFFERFLUSH pfnFlush,
+ void *pvFlush);
+
+DECLINLINE(uint32_t) VBoxVBVAExGetSize(PVBVAEXBUFFERCONTEXT pCtx)
+{
+ return pCtx->pVBVA->cbData;
+}
+
+/* can be used to ensure the command will not cross the ring buffer boundary,
+ * and thus will not be splitted */
+RTDECL(uint32_t) VBoxVBVAExGetFreeTail(PVBVAEXBUFFERCONTEXT pCtx);
+/* allocates a contiguous buffer of a given size, i.e. the one that is not splitted across ringbuffer boundaries */
+RTDECL(void*) VBoxVBVAExAllocContiguous(PVBVAEXBUFFERCONTEXT pCtx, PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx, uint32_t cb);
+/* answers whether host is in "processing" state now,
+ * i.e. if "processing" is true after the command is submitted, no notification is required to be posted to host to make the commandbe processed,
+ * otherwise, host should be notified about the command */
+RTDECL(bool) VBoxVBVAExIsProcessing(PVBVAEXBUFFERCONTEXT pCtx);
+
+/* initializes iterator that starts with free record,
+ * i.e. VBoxVBVAExIterNext would return the first uncompleted record.
+ *
+ * can be used by submitter only */
+RTDECL(void) VBoxVBVAExBIterInit(PVBVAEXBUFFERCONTEXT pCtx, PVBVAEXBUFFERBACKWARDITER pIter);
+/* can be used by submitter only */
+RTDECL(void*) VBoxVBVAExBIterNext(PVBVAEXBUFFERBACKWARDITER pIter, uint32_t *pcbBuffer, bool *pfProcessed);
+
+/* completer functions
+ * completer can only use below ones, and submitter is NOT allowed to use them.
+ * Completter functions are prefixed with VBoxVBVAExC as opposed to submitter ones,
+ * that do not have the last "C" in the prefix */
+/* initializes iterator that starts with completed record,
+ * i.e. VBoxVBVAExIterPrev would return the first uncompleted record.
+ * note that we can not have iterator that starts at processed record
+ * (i.e. the one processed by host, but not completed by guest, since host modifies
+ * VBVABUFFER::off32Data and VBVABUFFER::indexRecordFirst concurrently,
+ * and so we may end up with inconsistent index-offData pair
+ *
+ * can be used by completter only */
+RTDECL(void) VBoxVBVAExCFIterInit(PVBVAEXBUFFERCONTEXT pCtx, PVBVAEXBUFFERFORWARDITER pIter);
+/* can be used by completter only */
+RTDECL(void*) VBoxVBVAExCFIterNext(PVBVAEXBUFFERFORWARDITER pIter, uint32_t *pcbBuffer, bool *pfProcessed);
+
+RTDECL(void) VBoxVBVAExCBufferCompleted(PVBVAEXBUFFERCONTEXT pCtx);
+
+/** @} */
+
+struct VBOXCMDVBVA_HDR;
+
+int VBoxCmdVbvaEnable(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva);
+int VBoxCmdVbvaDisable(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva);
+int VBoxCmdVbvaDestroy(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva);
+int VBoxCmdVbvaCreate(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, ULONG offBuffer, ULONG cbBuffer);
+int VBoxCmdVbvaSubmit(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, struct VBOXCMDVBVA_HDR *pCmd, uint32_t cbCmd);
+bool VBoxCmdVbvaPreempt(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, uint32_t u32FenceID);
+uint32_t VBoxCmdVbvaCheckCompleted(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, bool fPingHost);
+bool VBoxCmdVbvaCheckCompletedIrq(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva);
+
+/*helper functions for filling vbva commands */
+DECLINLINE(void) VBoxCVDdiPackRect(VBOXCMDVBVA_RECT *pVbvaRect, const RECT *pRect)
+{
+ pVbvaRect->xLeft = (int16_t)pRect->left;
+ pVbvaRect->yTop = (int16_t)pRect->top;
+ pVbvaRect->xRight = (int16_t)pRect->right;
+ pVbvaRect->yBottom = (int16_t)pRect->bottom;
+}
+
+DECLINLINE(void) VBoxCVDdiPackRects(VBOXCMDVBVA_RECT *paVbvaRects, const RECT *paRects, uint32_t cRects)
+{
+ for (uint32_t i = 0; i < cRects; ++i)
+ {
+ VBoxCVDdiPackRect(&paVbvaRects[i], &paRects[i]);
+ }
+
+}
+
+uint32_t VBoxCVDdiPTransferVRamSysBuildEls(VBOXCMDVBVA_PAGING_TRANSFER *pCmd, PMDL pMdl, uint32_t iPfn, uint32_t cPages, uint32_t cbBuffer, uint32_t *pcPagesWritten);
+
#endif /* #ifndef ___VBoxMPVbva_h___ */
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.cpp b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.cpp
index 373a8fcf..0036147e 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -21,6 +21,9 @@
#include "VBoxMPVdma.h"
#include "VBoxMPVhwa.h"
#include <iprt/asm.h>
+#include "VBoxMPCr.h"
+
+# include <packer.h>
NTSTATUS vboxVdmaPipeConstruct(PVBOXVDMAPIPE pPipe)
{
@@ -212,106 +215,7 @@ NTSTATUS vboxVdmaPipeCltCmdPut(PVBOXVDMAPIPE pPipe, PVBOXVDMAPIPE_CMD_HDR pCmd)
return Status;
}
-PVBOXVDMAPIPE_CMD_DR vboxVdmaGgCmdCreate(PVBOXMP_DEVEXT pDevExt, VBOXVDMAPIPE_CMD_TYPE enmType, uint32_t cbCmd)
-{
- PVBOXVDMAPIPE_CMD_DR pHdr;
-#ifdef VBOX_WDDM_IRQ_COMPLETION
- if (enmType == VBOXVDMAPIPE_CMD_TYPE_DMACMD)
- {
- UINT cbAlloc = VBOXVDMACMD_SIZE_FROMBODYSIZE(cbCmd);
- VBOXVDMACBUF_DR* pDr = vboxVdmaCBufDrCreate(&pDevExt->u.primary.Vdma, cbAlloc);
- if (!pDr)
- {
- WARN(("dr allocation failed"));
- return NULL;
- }
- pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR;
- pDr->cbBuf = VBOXVDMACMD_HEADER_SIZE();
- pDr->rc = VINF_SUCCESS;
-
-
- PVBOXVDMACMD pDmaHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
- pDmaHdr->enmType = VBOXVDMACMD_TYPE_DMA_NOP;
- pDmaHdr->u32CmdSpecific = 0;
-
- pHdr = VBOXVDMACMD_BODY(pDmaHdr, VBOXVDMAPIPE_CMD_DR);
- }
- else
-#endif
- {
- pHdr = (PVBOXVDMAPIPE_CMD_DR)vboxWddmMemAllocZero(cbCmd);
- if (!pHdr)
- {
- WARN(("cmd allocation failed"));
- return NULL;
- }
- }
- pHdr->enmType = enmType;
- pHdr->cRefs = 1;
- return pHdr;
-}
-
-#ifdef VBOX_WDDM_IRQ_COMPLETION
-DECLINLINE(VBOXVDMACBUF_DR*) vboxVdmaGgCmdDmaGetDr(PVBOXVDMAPIPE_CMD_DMACMD pDr)
-{
- VBOXVDMACMD* pDmaCmd = VBOXVDMACMD_FROM_BODY(pDr);
- VBOXVDMACBUF_DR* pDmaDr = VBOXVDMACBUF_DR_FROM_TAIL(pDmaCmd);
- return pDmaDr;
-}
-
-DECLINLINE(PVBOXVDMADDI_CMD) vboxVdmaGgCmdDmaGetDdiCmd(PVBOXVDMAPIPE_CMD_DMACMD pDr)
-{
- VBOXVDMACBUF_DR* pDmaDr = vboxVdmaGgCmdDmaGetDr(pDr);
- return VBOXVDMADDI_CMD_FROM_BUF_DR(pDmaDr);
-}
-
-#endif
-
-void vboxVdmaGgCmdDestroy(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DR pDr)
-{
-#ifdef VBOX_WDDM_IRQ_COMPLETION
- if (pDr->enmType == VBOXVDMAPIPE_CMD_TYPE_DMACMD)
- {
- VBOXVDMACBUF_DR* pDmaDr = vboxVdmaGgCmdDmaGetDr((PVBOXVDMAPIPE_CMD_DMACMD)pDr);
- vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDmaDr);
- return;
- }
-#endif
- vboxWddmMemFree(pDr);
-}
-
-DECLCALLBACK(VOID) vboxVdmaGgDdiCmdRelease(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext)
-{
- vboxVdmaGgCmdRelease(pDevExt, (PVBOXVDMAPIPE_CMD_DR)pvContext);
-}
-
-/**
- * helper function used for system thread creation
- */
-static NTSTATUS vboxVdmaGgThreadCreate(PKTHREAD * ppThread, PKSTART_ROUTINE pStartRoutine, PVOID pStartContext)
-{
- NTSTATUS fStatus;
- HANDLE hThread;
- OBJECT_ATTRIBUTES fObjectAttributes;
-
- Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
-
- InitializeObjectAttributes(&fObjectAttributes, NULL, OBJ_KERNEL_HANDLE,
- NULL, NULL);
-
- fStatus = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS,
- &fObjectAttributes, NULL, NULL,
- (PKSTART_ROUTINE) pStartRoutine, pStartContext);
- if (!NT_SUCCESS(fStatus))
- return fStatus;
-
- ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, NULL,
- KernelMode, (PVOID*) ppThread, NULL);
- ZwClose(hThread);
- return STATUS_SUCCESS;
-}
-
-DECLINLINE(void) vboxVdmaDirtyRectsCalcIntersection(const RECT *pArea, const PVBOXWDDM_RECTS_INFO pRects, PVBOXWDDM_RECTS_INFO pResult)
+DECLINLINE(void) vboxVdmaDirtyRectsCalcIntersection(const RECT *pArea, const VBOXWDDM_RECTS_INFO *pRects, PVBOXWDDM_RECTS_INFO pResult)
{
uint32_t cRects = 0;
for (uint32_t i = 0; i < pRects->cRects; ++i)
@@ -379,20 +283,196 @@ NTSTATUS vboxVdmaPostHideSwapchain(PVBOXWDDM_SWAPCHAIN pSwapchain)
return STATUS_NO_MEMORY;
}
+static VOID vboxWddmBltPipeRectsTranslate(VBOXVDMAPIPE_RECTS *pRects, int x, int y)
+{
+ vboxWddmRectTranslate(&pRects->ContextRect, x, y);
+
+ for (UINT i = 0; i < pRects->UpdateRects.cRects; ++i)
+ {
+ vboxWddmRectTranslate(&pRects->UpdateRects.aRects[i], x, y);
+ }
+}
+
+static VBOXVDMAPIPE_RECTS * vboxWddmBltPipeRectsDup(const VBOXVDMAPIPE_RECTS *pRects)
+{
+ const size_t cbDup = RT_OFFSETOF(VBOXVDMAPIPE_RECTS, UpdateRects.aRects[pRects->UpdateRects.cRects]);
+ VBOXVDMAPIPE_RECTS *pDup = (VBOXVDMAPIPE_RECTS*)vboxWddmMemAllocZero(cbDup);
+ if (!pDup)
+ {
+ WARN(("vboxWddmMemAllocZero failed"));
+ return NULL;
+ }
+ memcpy(pDup, pRects, cbDup);
+ return pDup;
+}
+
+typedef struct VBOXMP_VDMACR_WRITECOMPLETION
+{
+ void *pvBufferToFree;
+} VBOXMP_VDMACR_WRITECOMPLETION, *PVBOXMP_VDMACR_WRITECOMPLETION;
+
+static DECLCALLBACK(void) vboxVdmaCrWriteCompletion(PVBOXMP_CRSHGSMITRANSPORT pCon, int rc, void *pvCtx)
+{
+ PVBOXMP_VDMACR_WRITECOMPLETION pData = (PVBOXMP_VDMACR_WRITECOMPLETION)pvCtx;
+ void* pvBufferToFree = pData->pvBufferToFree;
+ if (pvBufferToFree)
+ VBoxMpCrShgsmiTransportBufFree(pCon, pvBufferToFree);
+
+ VBoxMpCrShgsmiTransportCmdTermWriteAsync(pCon, pvCtx);
+}
+
+typedef struct VBOXMP_VDMACR_WRITEREADCOMPLETION
+{
+ void *pvBufferToFree;
+ void *pvContext;
+} VBOXMP_VDMACR_WRITEREADCOMPLETION, *PVBOXMP_VDMACR_WRITEREADCOMPLETION;
+
+void vboxVdmaCrSubmitWriteReadAsyncGenericCompletion(PVBOXMP_CRSHGSMITRANSPORT pCon, void *pvCtx)
+{
+ PVBOXMP_VDMACR_WRITEREADCOMPLETION pData = (PVBOXMP_VDMACR_WRITEREADCOMPLETION)pvCtx;
+ void* pvBufferToFree = pData->pvBufferToFree;
+ if (pvBufferToFree)
+ VBoxMpCrShgsmiTransportBufFree(pCon, pvBufferToFree);
+
+ VBoxMpCrShgsmiTransportCmdTermWriteReadAsync(pCon, pvCtx);
+}
+
+NTSTATUS vboxVdmaCrSubmitWriteReadAsync(PVBOXMP_DEVEXT pDevExt, VBOXMP_CRPACKER *pCrPacker, uint32_t u32CrConClientID, PFNVBOXMP_CRSHGSMITRANSPORT_SENDWRITEREADASYNC_COMPLETION pfnCompletion, void *pvCompletion)
+{
+ Assert(u32CrConClientID);
+ NTSTATUS Status = STATUS_SUCCESS;
+ uint32_t cbBuffer;
+ void * pvPackBuffer;
+ void * pvBuffer = VBoxMpCrPackerTxBufferComplete(pCrPacker, &cbBuffer, &pvPackBuffer);
+ if (pvBuffer)
+ {
+ PVBOXMP_VDMACR_WRITEREADCOMPLETION pvCompletionData = (PVBOXMP_VDMACR_WRITEREADCOMPLETION)VBoxMpCrShgsmiTransportCmdCreateWriteReadAsync(&pDevExt->CrHgsmiTransport, u32CrConClientID, pvBuffer, cbBuffer,
+ pfnCompletion, sizeof (*pvCompletionData));
+ if (pvCompletionData)
+ {
+ pvCompletionData->pvBufferToFree = pvPackBuffer;
+ pvCompletionData->pvContext = pvCompletion;
+ int rc = VBoxMpCrShgsmiTransportCmdSubmitWriteReadAsync(&pDevExt->CrHgsmiTransport, pvCompletionData);
+ if (RT_SUCCESS(rc))
+ {
+ return STATUS_SUCCESS;
+ }
+ WARN(("VBoxMpCrShgsmiTransportCmdSubmitWriteAsync failed, rc %d", rc));
+ Status = STATUS_UNSUCCESSFUL;
+ VBoxMpCrShgsmiTransportCmdTermWriteReadAsync(&pDevExt->CrHgsmiTransport, pvCompletionData);
+ }
+ else
+ {
+ WARN(("VBoxMpCrShgsmiTransportCmdCreateWriteAsync failed"));
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+
+ return Status;
+}
+
+NTSTATUS vboxVdmaCrSubmitWriteAsync(PVBOXMP_DEVEXT pDevExt, VBOXMP_CRPACKER *pCrPacker, uint32_t u32CrConClientID)
+{
+ Assert(u32CrConClientID);
+ NTSTATUS Status = STATUS_SUCCESS;
+ uint32_t cbBuffer;
+ void * pvPackBuffer;
+ void * pvBuffer = VBoxMpCrPackerTxBufferComplete(pCrPacker, &cbBuffer, &pvPackBuffer);
+ if (pvBuffer)
+ {
+ PVBOXMP_VDMACR_WRITECOMPLETION pvCompletionData = (PVBOXMP_VDMACR_WRITECOMPLETION)VBoxMpCrShgsmiTransportCmdCreateWriteAsync(&pDevExt->CrHgsmiTransport, u32CrConClientID, pvBuffer, cbBuffer,
+ vboxVdmaCrWriteCompletion, sizeof (*pvCompletionData));
+ if (pvCompletionData)
+ {
+ pvCompletionData->pvBufferToFree = pvPackBuffer;
+ int rc = VBoxMpCrShgsmiTransportCmdSubmitWriteAsync(&pDevExt->CrHgsmiTransport, pvCompletionData);
+ if (RT_SUCCESS(rc))
+ {
+ return STATUS_SUCCESS;
+ }
+ WARN(("VBoxMpCrShgsmiTransportCmdSubmitWriteAsync failed, rc %d", rc));
+ Status = STATUS_UNSUCCESSFUL;
+ VBoxMpCrShgsmiTransportCmdTermWriteAsync(&pDevExt->CrHgsmiTransport, pvCompletionData);
+ }
+ else
+ {
+ WARN(("VBoxMpCrShgsmiTransportCmdCreateWriteAsync failed"));
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+
+ return Status;
+}
+
+static NTSTATUS vboxVdmaVRegGet(PVBOXWDDM_SWAPCHAIN pSwapchain, const RTRECT *pCtxRect, uint32_t *pcVRects, RTRECT **ppVRectsBuff, uint32_t *pcVRectsBuff)
+{
+ RTRECT *pVRectsBuff = *ppVRectsBuff;
+ uint32_t cVRectsBuff = *pcVRectsBuff;
+ uint32_t cVRects = VBoxVrListRectsCount(&pSwapchain->VisibleRegions);
+ if (cVRectsBuff < cVRects)
+ {
+ if (pVRectsBuff)
+ vboxWddmMemFree(pVRectsBuff);
+ pVRectsBuff = (RTRECT*)vboxWddmMemAlloc(cVRects * sizeof (pVRectsBuff[0]));
+ if (!pVRectsBuff)
+ {
+ WARN(("vboxWddmMemAlloc failed"));
+ *pcVRectsBuff = 0;
+ *ppVRectsBuff = NULL;
+ *pcVRects = NULL;
+ return STATUS_NO_MEMORY;
+ }
+
+ cVRectsBuff = cVRects;
+ *pcVRectsBuff = cVRectsBuff;
+ *ppVRectsBuff = pVRectsBuff;
+ }
+
+ int rc = VBoxVrListRectsGet(&pSwapchain->VisibleRegions, cVRects, pVRectsBuff);
+ AssertRC(rc);
+ if (pCtxRect->xLeft || pCtxRect->yTop)
+ {
+ for (UINT i = 0; i < cVRects; ++i)
+ {
+ VBoxRectTranslate(&pVRectsBuff[i], -pCtxRect->xLeft, -pCtxRect->yTop);
+ }
+ }
+
+ *pcVRects = cVRects;
+ return STATUS_SUCCESS;
+}
+
+
/**
* @param pDevExt
*/
-static NTSTATUS vboxVdmaGgDirtyRectsProcess(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXWDDM_SWAPCHAIN pSwapchain, RECT *pSrcRect, VBOXVDMAPIPE_RECTS *pContextRects)
-{
- PVBOXWDDM_RECTS_INFO pRects = &pContextRects->UpdateRects;
+static NTSTATUS vboxVdmaProcessVRegCmdLegacy(PVBOXMP_DEVEXT pDevExt,
+ VBOXMP_CRPACKER *pCrPacker,
+ uint32_t u32CrConClientID,
+ PVBOXWDDM_SOURCE pSource,
+ PVBOXWDDM_SWAPCHAIN pSwapchain,
+ const RECT *pSrcRect,
+ const VBOXVDMAPIPE_RECTS *pContextRects)
+{
+ VBOXVDMAPIPE_RECTS *pRectsToFree = NULL;
+ POINT pos = pSource->VScreenPos;
+ if (pos.x || pos.y)
+ {
+ pRectsToFree = vboxWddmBltPipeRectsDup(pContextRects);
+ /* note: do NOT translate the src rect since it is used for screen pos calculation */
+ vboxWddmBltPipeRectsTranslate(pRectsToFree, pos.x, pos.y);
+ pContextRects = pRectsToFree;
+ }
+ const VBOXWDDM_RECTS_INFO *pRects = &pContextRects->UpdateRects;
NTSTATUS Status = STATUS_SUCCESS;
- PVBOXVIDEOCM_CMD_RECTS_INTERNAL pCmdInternal = NULL;
- uint32_t cbCmdInternal = VBOXVIDEOCM_CMD_RECTS_INTERNAL_SIZE4CRECTS(pRects->cRects);
- BOOLEAN fCurChanged = FALSE, fCurRectChanged = FALSE;
+ int rc;
+ bool fCurChanged = FALSE, fCurRectChanged = FALSE;
POINT CurPos;
- Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
+ RTRECT *pVRectsBuff = NULL;
+ uint32_t cVRectsBuff = 0;
+ VBOXWDDM_CTXLOCK_DATA
- ExAcquireFastMutex(&pDevExt->ContextMutex);
+ VBOXWDDM_CTXLOCK_LOCK(pDevExt);
if (pSwapchain)
{
@@ -403,18 +483,19 @@ static NTSTATUS vboxVdmaGgDirtyRectsProcess(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CO
{
#if 0
if (pSwapchain->Pos.x != VBOXWDDM_INVALID_COORD)
- VBoxWddmVrListTranslate(&pSwapchain->VisibleRegions, pSwapchain->Pos.x - CurPos.x, pSwapchain->Pos.y - CurPos.y);
+ VBoxVrListTranslate(&pSwapchain->VisibleRegions, pSwapchain->Pos.x - CurPos.x, pSwapchain->Pos.y - CurPos.y);
else
#endif
- VBoxWddmVrListClear(&pSwapchain->VisibleRegions);
+ VBoxVrListClear(&pSwapchain->VisibleRegions);
fCurRectChanged = TRUE;
pSwapchain->Pos = CurPos;
}
- Status = VBoxWddmVrListRectsAdd(&pSwapchain->VisibleRegions, pRects->cRects, pRects->aRects, &fCurChanged);
- if (!NT_SUCCESS(Status))
+ rc = VBoxVrListRectsAdd(&pSwapchain->VisibleRegions, pRects->cRects, (const RTRECT*)pRects->aRects, &fCurChanged);
+ if (!RT_SUCCESS(rc))
{
- WARN(("VBoxWddmVrListRectsAdd failed!"));
+ WARN(("VBoxWddmVrListRectsAdd failed, rc %d!", rc));
+ Status = STATUS_UNSUCCESSFUL;
goto done;
}
@@ -432,113 +513,140 @@ static NTSTATUS vboxVdmaGgDirtyRectsProcess(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CO
if (pCur != &pSwapchain->DevExtListEntry)
{
PVBOXWDDM_SWAPCHAIN pCurSwapchain = VBOXWDDMENTRY_2_SWAPCHAIN(pCur);
- BOOLEAN fChanged = FALSE;
+ PVBOXWDDM_CONTEXT pCurContext = pCurSwapchain->pContext;
+ PVBOXMP_CRPACKER pCurPacker = &pCurContext->CrPacker;
+ bool fChanged = FALSE;
- Status = VBoxWddmVrListRectsSubst(&pCurSwapchain->VisibleRegions, pRects->cRects, pRects->aRects, &fChanged);
- if (!NT_SUCCESS(Status))
+ rc = VBoxVrListRectsSubst(&pCurSwapchain->VisibleRegions, pRects->cRects, (const RTRECT*)pRects->aRects, &fChanged);
+ if (!RT_SUCCESS(rc))
{
- WARN(("vboxWddmVrListRectsAdd failed!"));
+ WARN(("VBoxWddmVrListRectsAdd failed, rc %d!", rc));
+ Status = STATUS_UNSUCCESSFUL;
goto done;
}
if (!fChanged)
continue;
- if (!pCmdInternal)
+ uint32_t cVRects;
+ RTRECT CurCtxRect;
+ CurCtxRect.xLeft = pCurSwapchain->Pos.x;
+ CurCtxRect.yTop = pCurSwapchain->Pos.y;
+ CurCtxRect.xRight = CurCtxRect.xLeft + pCurSwapchain->width;
+ CurCtxRect.yBottom = CurCtxRect.yTop + pCurSwapchain->height;
+ Status = vboxVdmaVRegGet(pCurSwapchain, &CurCtxRect, &cVRects, &pVRectsBuff, &cVRectsBuff);
+ if (!NT_SUCCESS(Status))
{
- pCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)vboxVideoCmCmdCreate(&pCurSwapchain->pContext->CmContext, cbCmdInternal);
- if (!pCmdInternal)
- {
- WARN(("vboxVideoCmCmdCreate failed!"));
- Status = STATUS_NO_MEMORY;
- goto done;
- }
+ WARN(("vboxVdmaVRegGet Status 0x%x", Status));
+ goto done;
}
- else
+
+ void *pvCommandBuffer = NULL;
+ uint32_t cbCommandBuffer = VBOXMP_CRCMD_HEADER_SIZE;
+ cbCommandBuffer += VBOXMP_CRCMD_SIZE_WINDOWVISIBLEREGIONS(cVRects);
+
+ pvCommandBuffer = VBoxMpCrShgsmiTransportBufAlloc(&pDevExt->CrHgsmiTransport, cbCommandBuffer);
+ if (!pvCommandBuffer)
{
- pCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)vboxVideoCmCmdReinitForContext(pCmdInternal, &pCurSwapchain->pContext->CmContext);
+ WARN(("VBoxMpCrShgsmiTransportBufAlloc failed!"));
+ Status = VERR_OUT_OF_RESOURCES;
+ goto done;
}
- pCmdInternal->Cmd.fFlags.Value = 0;
- pCmdInternal->Cmd.fFlags.bAddHiddenRects = 1;
- memcpy(&pCmdInternal->Cmd.RectsInfo, pRects, RT_OFFSETOF(VBOXWDDM_RECTS_INFO, aRects[pRects->cRects]));
+ VBoxMpCrPackerTxBufferInit(pCurPacker, pvCommandBuffer, cbCommandBuffer, 1);
- pCmdInternal->hSwapchainUm = pCurSwapchain->hSwapchainUm;
+ Assert(pCurSwapchain->winHostID);
+ crPackWindowVisibleRegion(&pCurPacker->CrPacker, pCurSwapchain->winHostID, cVRects, (GLint*)pVRectsBuff);
- vboxVideoCmCmdSubmit(pCmdInternal, VBOXVIDEOCM_CMD_RECTS_INTERNAL_SIZE4CRECTS(pCmdInternal->Cmd.RectsInfo.cRects));
- pCmdInternal = NULL;
+ Status = vboxVdmaCrSubmitWriteAsync(pDevExt, pCurPacker, pCurContext->u32CrConClientID);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("vboxVdmaCrSubmitWriteAsync failed Status 0x%x", Status));
+ VBoxMpCrShgsmiTransportBufFree(&pDevExt->CrHgsmiTransport, pvCommandBuffer);
+ }
}
}
if (!pSwapchain)
goto done;
- RECT *pVisRects;
+ uint32_t cbCommandBuffer = VBOXMP_CRCMD_HEADER_SIZE, cCommands = 0;
+
+ uint32_t cVRects;
+ Status = vboxVdmaVRegGet(pSwapchain, (const RTRECT *)&pContextRects->ContextRect, &cVRects, &pVRectsBuff, &cVRectsBuff);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("vboxVdmaVRegGet Status 0x%x", Status));
+ goto done;
+ }
+
+ ++cCommands;
+ cbCommandBuffer += VBOXMP_CRCMD_SIZE_WINDOWVISIBLEREGIONS(cVRects);
if (fCurRectChanged && fCurChanged)
{
- cbCmdInternal = VBOXVIDEOCM_CMD_RECTS_INTERNAL_SIZE4CRECTS(pRects->cRects + 1);
- if (pCmdInternal)
- vboxVideoCmCmdRelease(pCmdInternal);
- pCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)vboxVideoCmCmdCreate(&pContext->CmContext, cbCmdInternal);
- pCmdInternal->Cmd.fFlags.Value = 0;
- pCmdInternal->Cmd.fFlags.bSetViewRect = 1;
- pCmdInternal->Cmd.fFlags.bAddVisibleRects = 1;
- pCmdInternal->Cmd.RectsInfo.cRects = pRects->cRects + 1;
- pCmdInternal->Cmd.RectsInfo.aRects[0].left = CurPos.x;
- pCmdInternal->Cmd.RectsInfo.aRects[0].top = CurPos.y;
- pCmdInternal->Cmd.RectsInfo.aRects[0].right = CurPos.x + pSwapchain->width;
- pCmdInternal->Cmd.RectsInfo.aRects[0].bottom = CurPos.y + pSwapchain->height;
- pVisRects = &pCmdInternal->Cmd.RectsInfo.aRects[1];
+ ++cCommands;
+ cbCommandBuffer += VBOXMP_CRCMD_SIZE_WINDOWPOSITION;
}
- else
+
+ if (!pSwapchain->fExposed)
{
- if (!pCmdInternal)
- {
- Assert(pContext == pSwapchain->pContext);
- pCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)vboxVideoCmCmdCreate(&pContext->CmContext, cbCmdInternal);
- if (!pCmdInternal)
- {
- WARN(("vboxVideoCmCmdCreate failed!"));
- Status = STATUS_NO_MEMORY;
- goto done;
- }
- }
- else
- {
- pCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)vboxVideoCmCmdReinitForContext(pCmdInternal, &pContext->CmContext);
- }
+ ++cCommands;
+ cbCommandBuffer += VBOXMP_CRCMD_SIZE_WINDOWSHOW;
+ ++cCommands;
+ cbCommandBuffer += VBOXMP_CRCMD_SIZE_WINDOWSIZE;
+ }
- pCmdInternal->Cmd.fFlags.Value = 0;
- pCmdInternal->Cmd.fFlags.bAddVisibleRects = 1;
- pCmdInternal->Cmd.RectsInfo.cRects = pRects->cRects;
- pVisRects = &pCmdInternal->Cmd.RectsInfo.aRects[0];
+ void *pvCommandBuffer = VBoxMpCrShgsmiTransportBufAlloc(&pDevExt->CrHgsmiTransport, cbCommandBuffer);
+ if (!pvCommandBuffer)
+ {
+ WARN(("VBoxMpCrShgsmiTransportBufAlloc failed!"));
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
}
- pCmdInternal->hSwapchainUm = pSwapchain->hSwapchainUm;
+ VBoxMpCrPackerTxBufferInit(pCrPacker, pvCommandBuffer, cbCommandBuffer, cCommands);
+
+ Assert(pSwapchain->winHostID);
+
+ if (fCurRectChanged && fCurChanged)
+ crPackWindowPosition(&pCrPacker->CrPacker, pSwapchain->winHostID, CurPos.x, CurPos.y);
+
+ if (!pSwapchain->fExposed)
+ {
+ crPackWindowSize(&pCrPacker->CrPacker, pSwapchain->winHostID, pSwapchain->width, pSwapchain->height);
+ crPackWindowShow(&pCrPacker->CrPacker, pSwapchain->winHostID, TRUE);
+ pSwapchain->fExposed = TRUE;
+ }
- if (pRects->cRects)
- memcpy(pVisRects, pRects->aRects, sizeof (RECT) * pRects->cRects);
+ crPackWindowVisibleRegion(&pCrPacker->CrPacker, pSwapchain->winHostID, cVRects, (GLint*)pVRectsBuff);
- vboxVideoCmCmdSubmit(pCmdInternal, VBOXVIDEOCM_CMD_RECTS_INTERNAL_SIZE4CRECTS(pCmdInternal->Cmd.RectsInfo.cRects));
- pCmdInternal = NULL;
+ Status = vboxVdmaCrSubmitWriteAsync(pDevExt, pCrPacker, u32CrConClientID);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("vboxVdmaCrSubmitWriteAsync failed Status 0x%x", Status));
+ VBoxMpCrShgsmiTransportBufFree(&pDevExt->CrHgsmiTransport, pvCommandBuffer);
+ }
done:
- ExReleaseFastMutex(&pDevExt->ContextMutex);
+ VBOXWDDM_CTXLOCK_UNLOCK(pDevExt);
- if (pCmdInternal)
- vboxVideoCmCmdRelease(pCmdInternal);
+ if (pRectsToFree)
+ vboxWddmMemFree(pRectsToFree);
+
+ if (pVRectsBuff)
+ vboxWddmMemFree(pVRectsBuff);
return Status;
}
-static NTSTATUS vboxVdmaGgDmaColorFill(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL pCF)
+static NTSTATUS vboxVdmaGgDmaColorFill(PVBOXMP_DEVEXT pDevExt, VBOXVDMA_CLRFILL *pCF)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
Assert (pDevExt->pvVisibleVram);
if (pDevExt->pvVisibleVram)
{
- PVBOXWDDM_ALLOCATION pAlloc = pCF->ClrFill.Alloc.pAlloc;
+ PVBOXWDDM_ALLOCATION pAlloc = pCF->Alloc.pAlloc;
Assert(pAlloc->AllocData.Addr.offVram != VBOXVIDEOOFFSET_VOID);
if (pAlloc->AllocData.Addr.offVram != VBOXVIDEOOFFSET_VOID)
{
@@ -552,9 +660,9 @@ static NTSTATUS vboxVdmaGgDmaColorFill(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD
case 32:
{
uint8_t bytestPP = bpp >> 3;
- for (UINT i = 0; i < pCF->ClrFill.Rects.cRects; ++i)
+ for (UINT i = 0; i < pCF->Rects.cRects; ++i)
{
- RECT *pRect = &pCF->ClrFill.Rects.aRects[i];
+ RECT *pRect = &pCF->Rects.aRects[i];
for (LONG ir = pRect->top; ir < pRect->bottom; ++ir)
{
uint32_t * pvU32Mem = (uint32_t*)(pvMem + (ir * pAlloc->AllocData.SurfDesc.pitch) + (pRect->left * bytestPP));
@@ -565,7 +673,7 @@ static NTSTATUS vboxVdmaGgDmaColorFill(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD
Assert(pRect->bottom <= (LONG)pAlloc->AllocData.SurfDesc.height);
for (UINT j = 0; j < cRaw; ++j)
{
- *pvU32Mem = pCF->ClrFill.Color;
+ *pvU32Mem = pCF->Color;
++pvU32Mem;
}
}
@@ -590,7 +698,7 @@ static NTSTATUS vboxVdmaGgDmaColorFill(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD
{
if (!vboxWddmRectIsEmpty(&UnionRect))
{
- PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pCF->ClrFill.Alloc.pAlloc->AllocData.SurfDesc.VidPnSourceId];
+ PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pCF->Alloc.pAlloc->AllocData.SurfDesc.VidPnSourceId];
uint32_t cUnlockedVBVADisabled = ASMAtomicReadU32(&pDevExt->cUnlockedVBVADisabled);
if (!cUnlockedVBVADisabled)
{
@@ -736,464 +844,524 @@ static NTSTATUS vboxVdmaGgDmaBlt(PVBOXMP_DEVEXT pDevExt, PVBOXVDMA_BLT pBlt)
return Status;
}
-static VOID vboxWddmBltPipeRectsTranslate(VBOXVDMAPIPE_RECTS *pRects, int x, int y)
+typedef struct VBOXVDMA_CRRXGENERICSYNC
{
- vboxWddmRectTranslate(&pRects->ContextRect, x, y);
+ int rc;
+ KEVENT Event;
+} VBOXVDMA_CRRXGENERICSYNC, *PVBOXVDMA_CRRXGENERICSYNC;
- for (UINT i = 0; i < pRects->UpdateRects.cRects; ++i)
+static DECLCALLBACK(void) vboxVdmaCrRxGenericSyncCompletion(PVBOXMP_CRSHGSMITRANSPORT pCon, int rc, void *pvRx, uint32_t cbRx, void *pvCtx)
+{
+ PVBOXMP_VDMACR_WRITEREADCOMPLETION pvCompletionData = (PVBOXMP_VDMACR_WRITEREADCOMPLETION)pvCtx;
+ PVBOXVDMA_CRRXGENERICSYNC pData = (PVBOXVDMA_CRRXGENERICSYNC)pvCompletionData->pvContext;
+ if (RT_SUCCESS(rc))
{
- vboxWddmRectTranslate(&pRects->UpdateRects.aRects[i], x, y);
+ rc = VBoxMpCrCmdRxHandler((CRMessageHeader*)pvRx, cbRx);
+ if (!RT_SUCCESS(rc))
+ {
+ WARN(("VBoxMpCrCmdRxHandler failed %d", rc));
+ }
}
+ else
+ {
+ WARN(("rx failure %d", rc));
+ }
+
+ pData->rc = rc;
+
+ KeSetEvent(&pData->Event, 0, FALSE);
+
+ vboxVdmaCrSubmitWriteReadAsyncGenericCompletion(pCon, pvCtx);
}
-static NTSTATUS vboxVdmaGgDmaCmdProcessFast(PVBOXMP_DEVEXT pDevExt, VBOXVDMAPIPE_CMD_DMACMD *pDmaCmd)
+NTSTATUS vboxVdmaCrRxGenericSync(PVBOXMP_DEVEXT pDevExt, VBOXMP_CRPACKER *pCrPacker, uint32_t u32CrConClientID)
{
- NTSTATUS Status = STATUS_SUCCESS;
- PVBOXWDDM_CONTEXT pContext = pDmaCmd->pContext;
- DXGK_INTERRUPT_TYPE enmComplType = DXGK_INTERRUPT_DMA_COMPLETED;
- switch (pDmaCmd->enmCmd)
+ VBOXVDMA_CRRXGENERICSYNC Data;
+ Data.rc = VERR_NOT_SUPPORTED;
+ KeInitializeEvent(&Data.Event, SynchronizationEvent, FALSE);
+ NTSTATUS Status = vboxVdmaCrSubmitWriteReadAsync(pDevExt, pCrPacker, u32CrConClientID, vboxVdmaCrRxGenericSyncCompletion, &Data);
+ if (!NT_SUCCESS(Status))
{
- case VBOXVDMACMD_TYPE_DMA_PRESENT_BLT:
- {
- PVBOXVDMAPIPE_CMD_DMACMD_BLT pBlt = (PVBOXVDMAPIPE_CMD_DMACMD_BLT)pDmaCmd;
- PVBOXWDDM_ALLOCATION pDstAlloc = pBlt->Blt.DstAlloc.pAlloc;
- PVBOXWDDM_ALLOCATION pSrcAlloc = pBlt->Blt.SrcAlloc.pAlloc;
+ WARN(("vboxVdmaCrSubmitWriteAsync failed Status 0x%x", Status));
+ return Status;
+ }
- if (pBlt->Hdr.fFlags.fRealOp)
- {
- vboxVdmaGgDmaBlt(pDevExt, &pBlt->Blt);
+ Status = KeWaitForSingleObject(&Data.Event, Executive, KernelMode, FALSE, NULL /* PLARGE_INTEGER Timeout */);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("KeWaitForSingleObject failed Status 0x%x", Status));
+ return Status;
+ }
- if (VBOXWDDM_IS_FB_ALLOCATION(pDevExt, pDstAlloc)
- && pDstAlloc->bVisible)
- {
- VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pDstAlloc->AllocData.SurfDesc.VidPnSourceId];
- Assert(pDstAlloc->AllocData.SurfDesc.VidPnSourceId < VBOX_VIDEO_MAX_SCREENS);
- Assert(pSource->pPrimaryAllocation == pDstAlloc);
+ return STATUS_SUCCESS;
+}
- RECT UpdateRect;
- UpdateRect = pBlt->Blt.DstRects.UpdateRects.aRects[0];
- for (UINT i = 1; i < pBlt->Blt.DstRects.UpdateRects.cRects; ++i)
- {
- vboxWddmRectUnite(&UpdateRect, &pBlt->Blt.DstRects.UpdateRects.aRects[i]);
- }
+typedef struct VBOXMP_CRHGSMIMGR
+{
+ VBOXMP_CRPACKER CrPacker;
+ void *pvCommandBuffer;
+} VBOXMP_CRHGSMIMGR;
- uint32_t cUnlockedVBVADisabled = ASMAtomicReadU32(&pDevExt->cUnlockedVBVADisabled);
- if (!cUnlockedVBVADisabled)
- {
- VBOXVBVA_OP(ReportDirtyRect, pDevExt, pSource, &UpdateRect);
- }
- else
- {
- VBOXVBVA_OP_WITHLOCK(ReportDirtyRect, pDevExt, pSource, &UpdateRect);
- }
- }
- }
+DECLINLINE(CRPackContext*) vboxVdmaCrHmGetPackContext(VBOXMP_CRHGSMIMGR *pMgr)
+{
+ return &pMgr->CrPacker.CrPacker;
+}
- if (pBlt->Hdr.fFlags.fVisibleRegions)
- {
- Status = STATUS_MORE_PROCESSING_REQUIRED;
- vboxWddmAllocationRetain(pDstAlloc);
- vboxWddmAllocationRetain(pSrcAlloc);
- }
- break;
- }
+NTSTATUS vboxVdmaCrHmCreate(PVBOXMP_DEVEXT pDevExt, VBOXMP_CRHGSMIMGR *pMgr, uint32_t cbCommandBuffer, uint32_t cCommands)
+{
+ pMgr->pvCommandBuffer = VBoxMpCrShgsmiTransportBufAlloc(&pDevExt->CrHgsmiTransport, cbCommandBuffer);
+ if (!pMgr->pvCommandBuffer)
+ {
+ WARN(("VBoxMpCrShgsmiTransportBufAlloc failed!"));
+ return VERR_OUT_OF_RESOURCES;
+ }
- case VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP:
- {
- PVBOXVDMAPIPE_CMD_DMACMD_FLIP pFlip = (PVBOXVDMAPIPE_CMD_DMACMD_FLIP)pDmaCmd;
- Assert(pFlip->Hdr.fFlags.fVisibleRegions);
- Assert(!pFlip->Hdr.fFlags.fRealOp);
- PVBOXWDDM_ALLOCATION pAlloc = pFlip->Flip.Alloc.pAlloc;
- VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pAlloc->AllocData.SurfDesc.VidPnSourceId];
- vboxWddmAssignPrimary(pDevExt, pSource, pAlloc, pAlloc->AllocData.SurfDesc.VidPnSourceId);
- if (pFlip->Hdr.fFlags.fVisibleRegions)
- {
- Status = STATUS_MORE_PROCESSING_REQUIRED;
- vboxWddmAllocationRetain(pFlip->Flip.Alloc.pAlloc);
- }
+ VBoxMpCrPackerInit(&pMgr->CrPacker);
- break;
- }
- case VBOXVDMACMD_TYPE_DMA_PRESENT_CLRFILL:
- {
- PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL pCF = (PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL)pDmaCmd;
- Assert(pCF->Hdr.fFlags.fRealOp);
- Assert(!pCF->Hdr.fFlags.fVisibleRegions);
- Status = vboxVdmaGgDmaColorFill(pDevExt, pCF);
- Assert(Status == STATUS_SUCCESS);
- break;
- }
+ VBoxMpCrPackerTxBufferInit(&pMgr->CrPacker, pMgr->pvCommandBuffer, cbCommandBuffer, cCommands);
- default:
- Assert(0);
- break;
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS vboxVdmaCrHmSubmitWrSync(PVBOXMP_DEVEXT pDevExt, VBOXMP_CRHGSMIMGR *pMgr, uint32_t u32CrConClientID)
+{
+ NTSTATUS Status = vboxVdmaCrRxGenericSync(pDevExt, &pMgr->CrPacker, u32CrConClientID);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("vboxVdmaCrRxGenericSync failed Status 0x%x", Status));
+ VBoxMpCrShgsmiTransportBufFree(&pDevExt->CrHgsmiTransport, pMgr->pvCommandBuffer);
+ return Status;
+ }
+
+ return STATUS_SUCCESS;
+}
+#if 0
+NTSTATUS vboxVdmaCrCmdGetChromiumParametervCR(PVBOXMP_DEVEXT pDevExt, uint32_t u32CrConClientID, GLenum target, GLuint index, GLenum type, GLsizei count, GLvoid * values)
+{
+ uint32_t cbCommandBuffer = VBOXMP_CRCMD_HEADER_SIZE + VBOXMP_CRCMD_SIZE_GETCHROMIUMPARAMETERVCR;
+ uint32_t cCommands = 1;
+
+ VBOXMP_CRHGSMIMGR Mgr;
+ NTSTATUS Status = vboxVdmaCrHmCreate(pDevExt, &Mgr, cbCommandBuffer, cCommands);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("vboxVdmaCrHmCreate failed Status 0x%x", Status));
+ return Status;
}
- /* Corresponding Release is done by dma command completion handler */
- vboxVdmaGgCmdAddRef(&pDmaCmd->Hdr);
+ int dummy = 1;
- NTSTATUS tmpStatus = vboxVdmaGgCmdDmaNotifyCompleted(pDevExt, pDmaCmd, enmComplType);
- if (!NT_SUCCESS(tmpStatus))
+ crPackGetChromiumParametervCR(vboxVdmaCrHmGetPackContext(&Mgr), target, index, type, count, values, &dummy);
+
+ Status = vboxVdmaCrHmSubmitWrSync(pDevExt, &Mgr, u32CrConClientID);
+ if (!NT_SUCCESS(Status))
{
- WARN(("vboxVdmaGgCmdDmaNotifyCompleted failed, Status 0x%x", tmpStatus));
- /* the command was NOT submitted, and thus will not be released, release it here */
- vboxVdmaGgCmdRelease(pDevExt, &pDmaCmd->Hdr);
- Status = tmpStatus;
+ WARN(("vboxVdmaCrHmSubmitWrSync failed Status 0x%x", Status));
+ return Status;
}
- return Status;
+ return STATUS_SUCCESS;
}
-static NTSTATUS vboxVdmaGgDmaCmdProcessSlow(PVBOXMP_DEVEXT pDevExt, VBOXVDMAPIPE_CMD_DMACMD *pDmaCmd)
+static NTSTATUS vboxVdmaCrCmdCreateContext(PVBOXMP_DEVEXT pDevExt, int32_t visualBits, int32_t *pi32CtxID)
{
- NTSTATUS Status = STATUS_SUCCESS;
- PVBOXWDDM_CONTEXT pContext = pDmaCmd->pContext;
- DXGK_INTERRUPT_TYPE enmComplType = DXGK_INTERRUPT_DMA_COMPLETED;
+ uint32_t cbCommandBuffer = VBOXMP_CRCMD_HEADER_SIZE + VBOXMP_CRCMD_SIZE_CREATECONTEXT;
+ uint32_t cCommands = 1;
+
+ VBOXMP_CRHGSMIMGR Mgr;
+ NTSTATUS Status = vboxVdmaCrHmCreate(pDevExt, &Mgr, cbCommandBuffer, cCommands);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("vboxVdmaCrHmCreate failed Status 0x%x", Status));
+ return Status;
+ }
+
+ int dummy = 1;
- Assert(pDmaCmd->fFlags.Value);
- Assert(!pDmaCmd->fFlags.fRealOp);
+ crPackCreateContext(&CrPacker.CrPacker, "", visualBits, 0, &pi32CtxID, &dummy);
- switch (pDmaCmd->enmCmd)
+ Status = vboxVdmaCrHmSubmitWrSync(pDevExt, &Mgr, u32CrConClientID);
+ if (!NT_SUCCESS(Status))
{
- case VBOXVDMACMD_TYPE_DMA_PRESENT_BLT:
- {
- PVBOXVDMAPIPE_CMD_DMACMD_BLT pBlt = (PVBOXVDMAPIPE_CMD_DMACMD_BLT)pDmaCmd;
- PVBOXWDDM_ALLOCATION pDstAlloc = pBlt->Blt.DstAlloc.pAlloc;
- PVBOXWDDM_ALLOCATION pSrcAlloc = pBlt->Blt.SrcAlloc.pAlloc;
- BOOLEAN bComplete = TRUE;
- VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pDstAlloc->AllocData.SurfDesc.VidPnSourceId];
- Assert(pDstAlloc->AllocData.SurfDesc.VidPnSourceId < VBOX_VIDEO_MAX_SCREENS);
-
- if (pBlt->Hdr.fFlags.fVisibleRegions)
- {
- PVBOXWDDM_SWAPCHAIN pSwapchain = vboxWddmSwapchainRetainByAlloc(pDevExt, pSrcAlloc);
- POINT pos = pSource->VScreenPos;
- if (pos.x || pos.y)
- {
- /* note: do NOT translate the src rect since it is used for screen pos calculation */
- vboxWddmBltPipeRectsTranslate(&pBlt->Blt.DstRects, pos.x, pos.y);
- }
+ WARN(("vboxVdmaCrHmSubmitWrSync failed Status 0x%x", Status));
+ return Status;
+ }
- Status = vboxVdmaGgDirtyRectsProcess(pDevExt, pContext, pSwapchain, &pBlt->Blt.SrcRect, &pBlt->Blt.DstRects);
- Assert(Status == STATUS_SUCCESS);
+ return STATUS_SUCCESS;
+}
- if (pSwapchain)
- vboxWddmSwapchainRelease(pSwapchain);
- }
- else
- {
- WARN(("not expected!"));
- }
+static NTSTATUS vboxVdmaCrCmdWindowCreate(PVBOXMP_DEVEXT pDevExt, int32_t visualBits, int32_t *pi32WinID)
+{
+ uint32_t cbCommandBuffer = VBOXMP_CRCMD_HEADER_SIZE + VBOXMP_CRCMD_SIZE_WINDOWCREATE;
+ uint32_t cCommands = 1;
- vboxWddmAllocationRelease(pDstAlloc);
- vboxWddmAllocationRelease(pSrcAlloc);
+ VBOXMP_CRHGSMIMGR Mgr;
+ NTSTATUS Status = vboxVdmaCrHmCreate(pDevExt, &Mgr, cbCommandBuffer, cCommands);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("vboxVdmaCrHmCreate failed Status 0x%x", Status));
+ return Status;
+ }
- break;
+ int dummy = 1;
+
+ crPackWindowCreate(&CrPacker.CrPacker, "", visualBits, 0, &pi32CtxID, &dummy);
+
+ Status = vboxVdmaCrHmSubmitWrSync(pDevExt, &Mgr, u32CrConClientID);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("vboxVdmaCrHmSubmitWrSync failed Status 0x%x", Status));
+ return Status;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS vboxVdmaCrCtlGetDefaultCtxId(PVBOXMP_DEVEXT pDevExt, int32_t *pi32CtxID)
+{
+ if (!pDevExt->i32CrConDefaultCtxID)
+ {
+ if (!pDevExt->f3DEnabled)
+ {
+ WARN(("3D disabled, should not be here!"));
+ return STATUS_UNSUCCESSFUL;
}
- case VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP:
+ uint32_t u32ClienID;
+ NTSTATUS Status = vboxVdmaCrCtlGetDefaultClientId(pDevExt, &u32ClienID);
+ if (!NT_SUCCESS(Status))
{
- PVBOXVDMAPIPE_CMD_DMACMD_FLIP pFlip = (PVBOXVDMAPIPE_CMD_DMACMD_FLIP)pDmaCmd;
- PVBOXWDDM_ALLOCATION pAlloc = pFlip->Flip.Alloc.pAlloc;
- VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pAlloc->AllocData.SurfDesc.VidPnSourceId];
- if (pFlip->Hdr.fFlags.fVisibleRegions)
- {
- PVBOXWDDM_SWAPCHAIN pSwapchain;
- pSwapchain = vboxWddmSwapchainRetainByAlloc(pDevExt, pAlloc);
- if (pSwapchain)
- {
- POINT pos = pSource->VScreenPos;
- RECT SrcRect;
- VBOXVDMAPIPE_RECTS Rects;
- SrcRect.left = 0;
- SrcRect.top = 0;
- SrcRect.right = pAlloc->AllocData.SurfDesc.width;
- SrcRect.bottom = pAlloc->AllocData.SurfDesc.height;
- Rects.ContextRect.left = pos.x;
- Rects.ContextRect.top = pos.y;
- Rects.ContextRect.right = pAlloc->AllocData.SurfDesc.width + pos.x;
- Rects.ContextRect.bottom = pAlloc->AllocData.SurfDesc.height + pos.y;
- Rects.UpdateRects.cRects = 1;
- Rects.UpdateRects.aRects[0] = Rects.ContextRect;
- Status = vboxVdmaGgDirtyRectsProcess(pDevExt, pContext, pSwapchain, &SrcRect, &Rects);
- Assert(Status == STATUS_SUCCESS);
- vboxWddmSwapchainRelease(pSwapchain);
- }
- }
- else
- {
- WARN(("not expected!"));
- }
+ WARN(("vboxVdmaCrCtlGetDefaultClientId failed, Status %#x", Status));
+ return Status;
+ }
- vboxWddmAllocationRelease(pAlloc);
+ Status = vboxVdmaCrCmdWindowCreate(PVBOXMP_DEVEXT pDevExt, int32_t visualBits, int32_t *pi32WinID)
- break;
- }
+ VBOXMP_CRPACKER CrPacker;
+ VBoxMpCrPackerInit(&CrPacker);
- default:
+ int rc = VBoxMpCrCtlConConnect(&pDevExt->CrCtlCon, CR_PROTOCOL_VERSION_MAJOR, CR_PROTOCOL_VERSION_MINOR, &pDevExt->u32CrConDefaultClientID);
+ if (!RT_SUCCESS(rc))
{
- WARN(("not expected!"));
- break;
+ WARN(("VBoxMpCrCtlConConnect failed, rc %d", rc));
+ return STATUS_UNSUCCESSFUL;
}
}
- vboxVdmaGgCmdRelease(pDevExt, &pDmaCmd->Hdr);
+ *pi32CtxID = pDevExt->i32CrConDefaultCtxID;
+ return STATUS_SUCCESS;
+}
+#endif
+
+static NTSTATUS vboxVdmaTexPresentSubmit(PVBOXMP_DEVEXT pDevExt,
+ VBOXMP_CRPACKER *pCrPacker,
+ uint32_t u32CrConClientID,
+ uint32_t hostID,
+ uint32_t cfg,
+ int32_t posX,
+ int32_t posY,
+ uint32_t cRects,
+ const RTRECT*paRects)
+{
+ Assert(pDevExt->fTexPresentEnabled);
+
+ uint32_t cbCommandBuffer = VBOXMP_CRCMD_HEADER_SIZE + VBOXMP_CRCMD_SIZE_VBOXTEXPRESENT(cRects);
+ uint32_t cCommands = 1;
+ void *pvCommandBuffer = VBoxMpCrShgsmiTransportBufAlloc(&pDevExt->CrHgsmiTransport, cbCommandBuffer);
+ if (!pvCommandBuffer)
+ {
+ WARN(("VBoxMpCrShgsmiTransportBufAlloc failed!"));
+ return VERR_OUT_OF_RESOURCES;
+ }
+
+ VBoxMpCrPackerTxBufferInit(pCrPacker, pvCommandBuffer, cbCommandBuffer, cCommands);
+
+ crPackVBoxTexPresent(&pCrPacker->CrPacker, hostID, cfg, posX, posY, cRects, (int32_t*)paRects);
+
+ NTSTATUS Status = vboxVdmaCrSubmitWriteAsync(pDevExt, pCrPacker, u32CrConClientID);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("vboxVdmaCrSubmitWriteAsync failed Status 0x%x", Status));
+ VBoxMpCrShgsmiTransportBufFree(&pDevExt->CrHgsmiTransport, pvCommandBuffer);
+ }
return Status;
}
-static DECLCALLBACK(UINT) vboxVdmaGgCmdCancelVisitor(PVBOXVIDEOCM_CTX pContext, PVOID pvCmd, uint32_t cbCmd, PVOID pvVisitor)
+static NTSTATUS vboxVdmaCrCtlGetDefaultClientId(PVBOXMP_DEVEXT pDevExt, uint32_t *pu32ClienID)
{
- PVBOXWDDM_SWAPCHAIN pSwapchain = (PVBOXWDDM_SWAPCHAIN)pvVisitor;
- if (!pSwapchain)
- return VBOXVIDEOCMCMDVISITOR_RETURN_RMCMD;
- PVBOXVIDEOCM_CMD_RECTS_INTERNAL pCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)pvCmd;
- if (pCmdInternal->hSwapchainUm == pSwapchain->hSwapchainUm)
- return VBOXVIDEOCMCMDVISITOR_RETURN_RMCMD;
- return 0;
+ if (!pDevExt->u32CrConDefaultClientID)
+ {
+ if (!pDevExt->f3DEnabled)
+ {
+ WARN(("3D disabled, should not be here!"));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ int rc = VBoxMpCrCtlConConnect(&pDevExt->CrCtlCon, CR_PROTOCOL_VERSION_MAJOR, CR_PROTOCOL_VERSION_MINOR, &pDevExt->u32CrConDefaultClientID);
+ if (!RT_SUCCESS(rc))
+ {
+ WARN(("VBoxMpCrCtlConConnect failed, rc %d", rc));
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ *pu32ClienID = pDevExt->u32CrConDefaultClientID;
+ return STATUS_SUCCESS;
}
-static VOID vboxVdmaGgWorkerThread(PVOID pvUser)
+static NTSTATUS vboxVdmaProcessVReg(PVBOXMP_DEVEXT pDevExt,
+ VBOXMP_CRPACKER *pCrPacker,
+ uint32_t u32CrConClientID,
+ const VBOXWDDM_ALLOCATION *pSrcAlloc,
+ const VBOXWDDM_ALLOCATION *pDstAlloc,
+ const RECT *pSrcRect, const VBOXVDMAPIPE_RECTS *pDstRects)
{
- PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)pvUser;
- PVBOXVDMAGG pVdma = &pDevExt->u.primary.Vdma.DmaGg;
+ D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId = pDstAlloc->AllocData.SurfDesc.VidPnSourceId;
+ VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[srcId];
+ NTSTATUS Status = STATUS_SUCCESS;
- NTSTATUS Status = vboxVdmaPipeSvrOpen(&pVdma->CmdPipe);
- Assert(Status == STATUS_SUCCESS);
- if (Status == STATUS_SUCCESS)
+ if (pDevExt->fTexPresentEnabled)
{
- do
+ /* we care only about screen regions */
+ if (pDstAlloc != pSource->pPrimaryAllocation)
{
- LIST_ENTRY CmdList;
- Status = vboxVdmaPipeSvrCmdGetList(&pVdma->CmdPipe, &CmdList);
- Assert(Status == STATUS_SUCCESS || Status == STATUS_PIPE_CLOSING);
- if (Status == STATUS_SUCCESS)
+ WARN(("non-primary allocation passed to vboxWddmSubmitBltCmd!"));
+ return STATUS_NOT_SUPPORTED;
+ }
+
+ uint32_t hostID = pSrcAlloc->AllocData.hostID;
+ int rc;
+ if (hostID)
+ {
+// Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D);
+ int32_t posX = pDstRects->ContextRect.left - pSrcRect->left;
+ int32_t posY = pDstRects->ContextRect.top - pSrcRect->top;
+
+ Status = vboxVdmaTexPresentSubmit(pDevExt, pCrPacker, u32CrConClientID, hostID, srcId, posX, posY, pDstRects->UpdateRects.cRects, (const RTRECT*)pDstRects->UpdateRects.aRects);
+ if (NT_SUCCESS(Status))
{
- for (PLIST_ENTRY pCur = CmdList.Blink; pCur != &CmdList;)
+ rc = VBoxVrListRectsSubst(&pSource->VrList, pDstRects->UpdateRects.cRects, (const RTRECT*)pDstRects->UpdateRects.aRects, NULL);
+ if (RT_SUCCESS(rc))
+ pSource->fHas3DVrs = TRUE;
+ else
+ WARN(("VBoxVrListRectsSubst failed rc %d, ignoring..", rc));
+ }
+ else
+ WARN(("vboxVdmaTexPresentSubmit failed Status 0x%x", Status));
+ }
+ else if (pSource->pPrimaryAllocation == pDstAlloc)
+ {
+ bool fChanged = false;
+ Assert(pSource->pPrimaryAllocation->bVisible);
+ rc = VBoxVrListRectsAdd(&pSource->VrList, pDstRects->UpdateRects.cRects, (const RTRECT*)pDstRects->UpdateRects.aRects, &fChanged);
+ if (RT_SUCCESS(rc))
+ {
+ if (fChanged)
{
- PVBOXVDMAPIPE_CMD_DR pDr = VBOXVDMAPIPE_CMD_DR_FROM_ENTRY(pCur);
- RemoveEntryList(pCur);
- pCur = CmdList.Blink;
- switch (pDr->enmType)
+ Status = vboxVdmaTexPresentSubmit(pDevExt, pCrPacker, u32CrConClientID, hostID, srcId, 0, 0, pDstRects->UpdateRects.cRects, (const RTRECT*)pDstRects->UpdateRects.aRects);
+ if (NT_SUCCESS(Status))
{
- case VBOXVDMAPIPE_CMD_TYPE_DMACMD:
- {
- PVBOXVDMAPIPE_CMD_DMACMD pDmaCmd = (PVBOXVDMAPIPE_CMD_DMACMD)pDr;
- Status = vboxVdmaGgDmaCmdProcessSlow(pDevExt, pDmaCmd);
- Assert(Status == STATUS_SUCCESS);
- } break;
-#if 0
- case VBOXVDMAPIPE_CMD_TYPE_RECTSINFO:
+ if (pSource->fHas3DVrs)
{
- PVBOXVDMAPIPE_CMD_RECTSINFO pRects = (PVBOXVDMAPIPE_CMD_RECTSINFO)pDr;
- Status = vboxVdmaGgDirtyRectsProcess(pDevExt, pRects->pContext, pRects->pSwapchain, &pRects->ContextsRects);
- Assert(Status == STATUS_SUCCESS);
- vboxVdmaGgCmdRelease(pDevExt, pDr);
- break;
- }
-#endif
- case VBOXVDMAPIPE_CMD_TYPE_FINISH:
- {
- PVBOXVDMAPIPE_CMD_FINISH pCmd = (PVBOXVDMAPIPE_CMD_FINISH)pDr;
- PVBOXWDDM_CONTEXT pContext = pCmd->pContext;
- Assert(pCmd->pEvent);
- Status = vboxVideoCmCmdSubmitCompleteEvent(&pContext->CmContext, pCmd->pEvent);
- if (Status != STATUS_SUCCESS)
- {
- WARN(("vboxVideoCmCmdWaitCompleted failedm Status (0x%x)", Status));
- }
- vboxVdmaGgCmdRelease(pDevExt, &pCmd->Hdr);
- break;
- }
- case VBOXVDMAPIPE_CMD_TYPE_CANCEL:
- {
- PVBOXVDMAPIPE_CMD_CANCEL pCmd = (PVBOXVDMAPIPE_CMD_CANCEL)pDr;
- PVBOXWDDM_CONTEXT pContext = pCmd->pContext;
- Status = vboxVideoCmCmdVisit(&pContext->CmContext, FALSE, vboxVdmaGgCmdCancelVisitor, pCmd->pSwapchain);
- if (Status != STATUS_SUCCESS)
+ if (VBoxVrListRectsCount(&pSource->VrList) == 1)
{
- WARN(("vboxVideoCmCmdWaitCompleted failedm Status (0x%x)", Status));
+ RTRECT Rect;
+ VBoxVrListRectsGet(&pSource->VrList, 1, &Rect);
+ if (Rect.xLeft == 0
+ && Rect.yTop == 0
+ && Rect.xRight == pDstAlloc->AllocData.SurfDesc.width
+ && Rect.yBottom == pDstAlloc->AllocData.SurfDesc.height)
+ {
+ pSource->fHas3DVrs = FALSE;
+ }
}
- Assert(pCmd->pEvent);
- KeSetEvent(pCmd->pEvent, 0, FALSE);
- vboxVdmaGgCmdRelease(pDevExt, &pCmd->Hdr);
- break;
}
- default:
- AssertBreakpoint();
}
+ else
+ WARN(("vboxVdmaTexPresentSubmit failed Status 0x%x", Status));
}
}
else
- break;
- } while (1);
+ WARN(("VBoxVrListRectsAdd failed rc %d, ignoring..", rc));
+ }
+ else
+ {
+ WARN(("unexpected"));
+ Status = STATUS_INVALID_PARAMETER;
+ }
}
+ else
+ {
+ PVBOXWDDM_SWAPCHAIN pSwapchain = vboxWddmSwapchainRetainByAlloc(pDevExt, pSrcAlloc);
- /* always try to close the pipe to make sure the client side is notified */
- Status = vboxVdmaPipeSvrClose(&pVdma->CmdPipe);
- Assert(Status == STATUS_SUCCESS);
-}
+ if (pSwapchain)
+ {
+ Assert(pSrcAlloc->AllocData.SurfDesc.width == pSwapchain->width);
+ Assert(pSrcAlloc->AllocData.SurfDesc.height == pSwapchain->height);
+ }
-NTSTATUS vboxVdmaGgConstruct(PVBOXMP_DEVEXT pDevExt)
-{
- PVBOXVDMAGG pVdma = &pDevExt->u.primary.Vdma.DmaGg;
- NTSTATUS Status = vboxVdmaPipeConstruct(&pVdma->CmdPipe);
- Assert(Status == STATUS_SUCCESS);
- if (Status == STATUS_SUCCESS)
- {
- Status = vboxVdmaGgThreadCreate(&pVdma->pThread, vboxVdmaGgWorkerThread, pDevExt);
- Assert(Status == STATUS_SUCCESS);
- if (Status == STATUS_SUCCESS)
- return STATUS_SUCCESS;
+ Status = vboxVdmaProcessVRegCmdLegacy(pDevExt, pCrPacker, u32CrConClientID, pSource, pSwapchain, pSrcRect, pDstRects);
+ if (!NT_SUCCESS(Status))
+ WARN(("vboxVdmaProcessVRegCmdLegacy failed Status 0x%x", Status));
- NTSTATUS tmpStatus = vboxVdmaPipeDestruct(&pVdma->CmdPipe);
- Assert(tmpStatus == STATUS_SUCCESS);
+ if (pSwapchain)
+ vboxWddmSwapchainRelease(pSwapchain);
}
- /* we're here ONLY in case of an error */
- Assert(Status != STATUS_SUCCESS);
return Status;
}
-NTSTATUS vboxVdmaGgDestruct(PVBOXMP_DEVEXT pDevExt)
+NTSTATUS vboxVdmaTexPresentSetAlloc(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pRealFbAlloc)
{
- PVBOXVDMAGG pVdma = &pDevExt->u.primary.Vdma.DmaGg;
- /* this informs the server thread that it should complete all current commands and exit */
- NTSTATUS Status = vboxVdmaPipeCltClose(&pVdma->CmdPipe);
- Assert(Status == STATUS_SUCCESS);
- if (Status == STATUS_SUCCESS)
+ VBOXMP_CRPACKER CrPacker;
+ VBoxMpCrPackerInit(&CrPacker);
+ uint32_t u32CrConClientID;
+
+ NTSTATUS Status = vboxVdmaCrCtlGetDefaultClientId(pDevExt, &u32CrConClientID);
+ if (!NT_SUCCESS(Status))
{
- Status = KeWaitForSingleObject(pVdma->pThread, Executive, KernelMode, FALSE, NULL /* PLARGE_INTEGER Timeout */);
- Assert(Status == STATUS_SUCCESS);
- if (Status == STATUS_SUCCESS)
- {
- Status = vboxVdmaPipeDestruct(&pVdma->CmdPipe);
- Assert(Status == STATUS_SUCCESS);
- }
+ WARN(("vboxVdmaCrCtlGetDefaultClientId failed Status 0x%x", Status));
+ return Status;
}
- return Status;
-}
+ RECT Rect;
+ Rect.left = 0;
+ Rect.top = 0;
+ Rect.right = pRealFbAlloc->AllocData.SurfDesc.width;
+ Rect.bottom = pRealFbAlloc->AllocData.SurfDesc.height;
-NTSTATUS vboxVdmaGgCmdSubmit(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DR pCmd)
-{
- switch (pCmd->enmType)
- {
- case VBOXVDMAPIPE_CMD_TYPE_DMACMD:
- {
- PVBOXVDMAPIPE_CMD_DMACMD pDmaCmd = (PVBOXVDMAPIPE_CMD_DMACMD)pCmd;
- NTSTATUS Status = vboxVdmaGgDmaCmdProcessFast(pDevExt, pDmaCmd);
- if (Status == STATUS_MORE_PROCESSING_REQUIRED)
- break;
- return Status;
- }
- default:
- break;
- }
- /* correspondinf Release is done by the pipe command handler */
- vboxVdmaGgCmdAddRef(pCmd);
- return vboxVdmaPipeCltCmdPut(&pDevExt->u.primary.Vdma.DmaGg.CmdPipe, &pCmd->PipeHdr);
+ VBOXVDMAPIPE_RECTS RectInfo;
+ RectInfo.ContextRect = Rect;
+ RectInfo.UpdateRects.cRects = 1;
+ RectInfo.UpdateRects.aRects[0] = Rect;
+
+ return vboxVdmaProcessVReg(pDevExt, &CrPacker, u32CrConClientID,
+ pRealFbAlloc, pRealFbAlloc,
+ &Rect, &RectInfo);
}
-NTSTATUS vboxVdmaGgCmdDmaNotifySubmitted(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DMACMD pCmd)
+static NTSTATUS vboxVdmaProcessVRegCmd(PVBOXMP_DEVEXT pDevExt, VBOXWDDM_CONTEXT *pContext,
+ const VBOXWDDM_DMA_ALLOCINFO *pSrcAllocInfo,
+ const VBOXWDDM_DMA_ALLOCINFO *pDstAllocInfo,
+ const RECT *pSrcRect, const VBOXVDMAPIPE_RECTS *pDstRects)
{
- PVBOXVDMADDI_CMD pDdiCmd;
-#ifdef VBOX_WDDM_IRQ_COMPLETION
- pDdiCmd = vboxVdmaGgCmdDmaGetDdiCmd(pCmd);
-#else
- pDdiCmd = &pCmd->DdiCmd;
-#endif
- NTSTATUS Status = vboxVdmaDdiCmdSubmitted(pDevExt, pDdiCmd);
- Assert(Status == STATUS_SUCCESS);
- return Status;
+ return vboxVdmaProcessVReg(pDevExt, &pContext->CrPacker, pContext->u32CrConClientID,
+ pSrcAllocInfo->pAlloc, pDstAllocInfo->pAlloc,
+ pSrcRect, pDstRects);
}
-NTSTATUS vboxVdmaGgCmdDmaNotifyCompleted(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DMACMD pCmd, DXGK_INTERRUPT_TYPE enmComplType)
+static void vboxVdmaBltDirtyRectsUpdate(PVBOXMP_DEVEXT pDevExt, VBOXWDDM_SOURCE *pSource, uint32_t cRects, const RECT *paRects)
{
-#ifdef VBOX_WDDM_IRQ_COMPLETION
- VBOXVDMACBUF_DR* pDr = vboxVdmaGgCmdDmaGetDr(pCmd);
- int rc = vboxVdmaCBufDrSubmit(pDevExt, &pDevExt->u.primary.Vdma, pDr);
- Assert(rc == VINF_SUCCESS);
- if (RT_SUCCESS(rc))
+ if (!cRects)
{
- return STATUS_SUCCESS;
+ WARN(("vboxVdmaBltDirtyRectsUpdate: no rects specified"));
+ return;
}
- return STATUS_UNSUCCESSFUL;
-#else
- return vboxVdmaDdiCmdCompleted(pDevExt, &pCmd->DdiCmd, enmComplType);
-#endif
-}
-VOID vboxVdmaGgCmdDmaNotifyInit(PVBOXVDMAPIPE_CMD_DMACMD pCmd,
- uint32_t u32NodeOrdinal, uint32_t u32FenceId,
- PFNVBOXVDMADDICMDCOMPLETE_DPC pfnComplete, PVOID pvComplete)
-{
- PVBOXVDMADDI_CMD pDdiCmd;
-#ifdef VBOX_WDDM_IRQ_COMPLETION
- pDdiCmd = vboxVdmaGgCmdDmaGetDdiCmd(pCmd);
-#else
- pDdiCmd = &pCmd->DdiCmd;
-#endif
- vboxVdmaDdiCmdInit(pDdiCmd, u32NodeOrdinal, u32FenceId, pfnComplete, pvComplete);
+ RECT rect;
+ rect = paRects[0];
+ for (UINT i = 1; i < cRects; ++i)
+ {
+ vboxWddmRectUnited(&rect, &rect, &paRects[i]);
+ }
+
+ uint32_t cUnlockedVBVADisabled = ASMAtomicReadU32(&pDevExt->cUnlockedVBVADisabled);
+ if (!cUnlockedVBVADisabled)
+ {
+ VBOXVBVA_OP(ReportDirtyRect, pDevExt, pSource, &rect);
+ }
+ else
+ {
+ VBOXVBVA_OP_WITHLOCK_ATDPC(ReportDirtyRect, pDevExt, pSource, &rect);
+ }
}
-NTSTATUS vboxVdmaGgCmdFinish(PVBOXMP_DEVEXT pDevExt, VBOXWDDM_CONTEXT *pContext, PKEVENT pEvent)
+NTSTATUS vboxVdmaProcessBltCmd(PVBOXMP_DEVEXT pDevExt, VBOXWDDM_CONTEXT *pContext, VBOXWDDM_DMA_PRIVATEDATA_BLT *pBlt)
{
NTSTATUS Status = STATUS_SUCCESS;
+ PVBOXWDDM_ALLOCATION pDstAlloc = pBlt->Blt.DstAlloc.pAlloc;
+ PVBOXWDDM_ALLOCATION pSrcAlloc = pBlt->Blt.SrcAlloc.pAlloc;
+ BOOLEAN fRenderFromSharedDisabled = pDevExt->fRenderToShadowDisabled;
+ BOOLEAN fVRAMUpdated = FALSE;
- PVBOXVDMAPIPE_CMD_FINISH pCmd = (PVBOXVDMAPIPE_CMD_FINISH)vboxVdmaGgCmdCreate(pDevExt, VBOXVDMAPIPE_CMD_TYPE_FINISH, sizeof (*pCmd));
- if (pCmd)
+ if (!pDstAlloc->AllocData.hostID && !pSrcAlloc->AllocData.hostID)
{
- pCmd->pContext = pContext;
- pCmd->pEvent = pEvent;
- Status = vboxVdmaGgCmdSubmit(pDevExt, &pCmd->Hdr);
- if (!NT_SUCCESS(Status))
+ /* the allocations contain a real data in VRAM, do blitting */
+ vboxVdmaGgDmaBlt(pDevExt, &pBlt->Blt);
+ fVRAMUpdated = TRUE;
+ }
+
+ if (VBOXWDDM_IS_REAL_FB_ALLOCATION(pDevExt, pDstAlloc)
+ && pDstAlloc->bVisible)
+ {
+ VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pDstAlloc->AllocData.SurfDesc.VidPnSourceId];
+ Assert(pDstAlloc->AllocData.SurfDesc.VidPnSourceId < VBOX_VIDEO_MAX_SCREENS);
+ Assert(pSource->pPrimaryAllocation == pDstAlloc);
+
+
+ if (fVRAMUpdated)
+ vboxVdmaBltDirtyRectsUpdate(pDevExt, pSource, pBlt->Blt.DstRects.UpdateRects.cRects, pBlt->Blt.DstRects.UpdateRects.aRects);
+
+ if (pSrcAlloc->AllocData.hostID || (pDevExt->fTexPresentEnabled ? pSource->fHas3DVrs : !!pDevExt->cContexts3D))
{
- WARN(("vboxVdmaGgCmdSubmit returned 0x%x", Status));
+ Status = vboxVdmaProcessVRegCmd(pDevExt, pContext, &pBlt->Blt.SrcAlloc, &pBlt->Blt.DstAlloc, &pBlt->Blt.SrcRect, &pBlt->Blt.DstRects);
+ if (!NT_SUCCESS(Status))
+ WARN(("vboxVdmaProcessVRegCmd failed Status 0x%x", Status));
}
- vboxVdmaGgCmdRelease(pDevExt, &pCmd->Hdr);
}
- else
+
+ return Status;
+}
+
+NTSTATUS vboxVdmaProcessFlipCmd(PVBOXMP_DEVEXT pDevExt, VBOXWDDM_CONTEXT *pContext, VBOXWDDM_DMA_PRIVATEDATA_FLIP *pFlip)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ PVBOXWDDM_ALLOCATION pAlloc = pFlip->Flip.Alloc.pAlloc;
+ VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pAlloc->AllocData.SurfDesc.VidPnSourceId];
+ vboxWddmAssignPrimary(pDevExt, pSource, pAlloc, pAlloc->AllocData.SurfDesc.VidPnSourceId);
+ if (pAlloc->AllocData.hostID)
{
- WARN(("vboxVdmaGgCmdCreate failed"));
- Status = STATUS_NO_MEMORY;
+ RECT SrcRect;
+ VBOXVDMAPIPE_RECTS Rects;
+ SrcRect.left = 0;
+ SrcRect.top = 0;
+ SrcRect.right = pAlloc->AllocData.SurfDesc.width;
+ SrcRect.bottom = pAlloc->AllocData.SurfDesc.height;
+ Rects.ContextRect.left = 0;
+ Rects.ContextRect.top = 0;
+ Rects.ContextRect.right = pAlloc->AllocData.SurfDesc.width;
+ Rects.ContextRect.bottom = pAlloc->AllocData.SurfDesc.height;
+ Rects.UpdateRects.cRects = 1;
+ Rects.UpdateRects.aRects[0] = Rects.ContextRect;
+
+ Status = vboxVdmaProcessVRegCmd(pDevExt, pContext, &pFlip->Flip.Alloc, &pFlip->Flip.Alloc, &SrcRect, &Rects);
+ if (!NT_SUCCESS(Status))
+ WARN(("vboxVdmaProcessVRegCmd failed Status 0x%x", Status));
}
+ else
+ WARN(("unexpected flip request"));
+
return Status;
}
-NTSTATUS vboxVdmaGgCmdCancel(PVBOXMP_DEVEXT pDevExt, VBOXWDDM_CONTEXT *pContext, PVBOXWDDM_SWAPCHAIN pSwapchain)
+NTSTATUS vboxVdmaProcessClrFillCmd(PVBOXMP_DEVEXT pDevExt, VBOXWDDM_CONTEXT *pContext, VBOXWDDM_DMA_PRIVATEDATA_CLRFILL *pCF)
{
NTSTATUS Status = STATUS_SUCCESS;
+ PVBOXWDDM_ALLOCATION pAlloc = pCF->ClrFill.Alloc.pAlloc;
- PVBOXVDMAPIPE_CMD_CANCEL pCmd = (PVBOXVDMAPIPE_CMD_CANCEL)vboxVdmaGgCmdCreate(pDevExt, VBOXVDMAPIPE_CMD_TYPE_CANCEL, sizeof (*pCmd));
- if (pCmd)
+ if (!pAlloc->AllocData.hostID)
{
- KEVENT Event;
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
- pCmd->pContext = pContext;
- pCmd->pSwapchain = pSwapchain;
- pCmd->pEvent = &Event;
- Status = vboxVdmaGgCmdSubmit(pDevExt, &pCmd->Hdr);
- if (NT_SUCCESS(Status))
- {
- Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
- Assert(Status == STATUS_SUCCESS);
- }
- else
- {
- WARN(("vboxVdmaGgCmdSubmit returned 0x%x", Status));
- }
- vboxVdmaGgCmdRelease(pDevExt, &pCmd->Hdr);
+ Status = vboxVdmaGgDmaColorFill(pDevExt, &pCF->ClrFill);
+ if (!NT_SUCCESS(Status))
+ WARN(("vboxVdmaGgDmaColorFill failed Status 0x%x", Status));
}
else
- {
- WARN(("vboxVdmaGgCmdCreate failed"));
- Status = STATUS_NO_MEMORY;
- }
+ WARN(("unexpected clrfill request"));
+
return Status;
}
-/* end */
#ifdef VBOX_WITH_VDMA
/*
@@ -1325,11 +1493,7 @@ int vboxVdmaCreate(PVBOXMP_DEVEXT pDevExt, VBOXVDMAINFO *pInfo
if(RT_SUCCESS(rc))
#endif
{
- NTSTATUS Status = vboxVdmaGgConstruct(pDevExt);
- Assert(Status == STATUS_SUCCESS);
- if (Status == STATUS_SUCCESS)
- return VINF_SUCCESS;
- rc = VERR_GENERAL_FAILURE;
+ return VINF_SUCCESS;
}
#ifdef VBOX_WITH_VDMA
else
@@ -1345,8 +1509,6 @@ int vboxVdmaCreate(PVBOXMP_DEVEXT pDevExt, VBOXVDMAINFO *pInfo
int vboxVdmaDisable (PVBOXMP_DEVEXT pDevExt, PVBOXVDMAINFO pInfo)
{
- LOGF(("."));
-
Assert(pInfo->fEnabled);
if (!pInfo->fEnabled)
return VINF_ALREADY_INITIALIZED;
@@ -1364,8 +1526,6 @@ int vboxVdmaDisable (PVBOXMP_DEVEXT pDevExt, PVBOXVDMAINFO pInfo)
int vboxVdmaEnable (PVBOXMP_DEVEXT pDevExt, PVBOXVDMAINFO pInfo)
{
- LOGF(("."));
-
Assert(!pInfo->fEnabled);
if (pInfo->fEnabled)
return VINF_ALREADY_INITIALIZED;
@@ -1384,8 +1544,6 @@ int vboxVdmaEnable (PVBOXMP_DEVEXT pDevExt, PVBOXVDMAINFO pInfo)
#ifdef VBOX_WITH_VDMA
int vboxVdmaFlush (PVBOXMP_DEVEXT pDevExt, PVBOXVDMAINFO pInfo)
{
- LOGF(("."));
-
Assert(pInfo->fEnabled);
if (!pInfo->fEnabled)
return VINF_ALREADY_INITIALIZED;
@@ -1400,20 +1558,13 @@ int vboxVdmaFlush (PVBOXMP_DEVEXT pDevExt, PVBOXVDMAINFO pInfo)
int vboxVdmaDestroy (PVBOXMP_DEVEXT pDevExt, PVBOXVDMAINFO pInfo)
{
int rc = VINF_SUCCESS;
- NTSTATUS Status = vboxVdmaGgDestruct(pDevExt);
- Assert(Status == STATUS_SUCCESS);
- if (Status == STATUS_SUCCESS)
- {
- Assert(!pInfo->fEnabled);
- if (pInfo->fEnabled)
- rc = vboxVdmaDisable (pDevExt, pInfo);
+ Assert(!pInfo->fEnabled);
+ if (pInfo->fEnabled)
+ rc = vboxVdmaDisable (pDevExt, pInfo);
#ifdef VBOX_WITH_VDMA
- VBoxSHGSMITerm(&pInfo->CmdHeap);
- VBoxMPCmnUnmapAdapterMemory(VBoxCommonFromDeviceExt(pDevExt), (void**)&pInfo->CmdHeap.Heap.area.pu8Base);
+ VBoxSHGSMITerm(&pInfo->CmdHeap);
+ VBoxMPCmnUnmapAdapterMemory(VBoxCommonFromDeviceExt(pDevExt), (void**)&pInfo->CmdHeap.Heap.area.pu8Base);
#endif
- }
- else
- rc = VERR_GENERAL_FAILURE;
return rc;
}
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.h b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.h
index 653520fd..4b544ac5 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -211,19 +211,6 @@ typedef struct VBOXVDMAPIPE_CMD_CANCEL
PKEVENT pEvent;
} VBOXVDMAPIPE_CMD_CANCEL, *PVBOXVDMAPIPE_CMD_CANCEL;
-typedef struct VBOXVDMAPIPE_FLAGS_DMACMD
-{
- union
- {
- struct
- {
- UINT fRealOp : 1;
- UINT fVisibleRegions : 1;
- UINT Reserve : 30;
- };
- UINT Value;
- };
-} VBOXVDMAPIPE_FLAGS_DMACMD, *PVBOXVDMAPIPE_FLAGS_DMACMD;
typedef struct VBOXVDMAPIPE_CMD_DMACMD
{
VBOXVDMAPIPE_CMD_DR Hdr;
@@ -232,7 +219,7 @@ typedef struct VBOXVDMAPIPE_CMD_DMACMD
#endif
PVBOXWDDM_CONTEXT pContext;
VBOXVDMACMD_TYPE enmCmd;
- VBOXVDMAPIPE_FLAGS_DMACMD fFlags;
+// VBOXVDMAPIPE_FLAGS_DMACMD fFlags;
} VBOXVDMAPIPE_CMD_DMACMD, *PVBOXVDMAPIPE_CMD_DMACMD;
typedef struct VBOXVDMA_CLRFILL
@@ -294,8 +281,6 @@ typedef struct VBOXVDMAINFO
#endif
UINT uLastCompletedPagingBufferCmdFenceId;
BOOL fEnabled;
- /* dma-related commands list processed on the guest w/o host part involvement (guest-guest commands) */
- VBOXVDMAGG DmaGg;
} VBOXVDMAINFO, *PVBOXVDMAINFO;
int vboxVdmaCreate (PVBOXMP_DEVEXT pDevExt, VBOXVDMAINFO *pInfo
@@ -312,6 +297,10 @@ int vboxVdmaDestroy(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAINFO pInfo);
#ifdef VBOX_WITH_VDMA
int vboxVdmaFlush(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAINFO pInfo);
+DECLINLINE(HGSMIOFFSET) vboxVdmaCBufDrPtrOffset(const PVBOXVDMAINFO pInfo, const void* pvPtr)
+{
+ return VBoxSHGSMICommandPtrOffset(&pInfo->CmdHeap, pvPtr);
+}
int vboxVdmaCBufDrSubmit(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAINFO pInfo, PVBOXVDMACBUF_DR pDr);
int vboxVdmaCBufDrSubmitSynch(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAINFO pInfo, PVBOXVDMACBUF_DR pDr);
struct VBOXVDMACBUF_DR* vboxVdmaCBufDrCreate(PVBOXVDMAINFO pInfo, uint32_t cbTrailingData);
@@ -326,22 +315,6 @@ AssertCompile(sizeof (VBOXVDMADDI_CMD) <= RT_SIZEOFMEMB(VBOXVDMACBUF_DR, aGuestD
#define VBOXVDMACBUF_DR_FROM_DDI_CMD(_pCmd) ((PVBOXVDMACBUF_DR)(((uint8_t*)(_pCmd)) - RT_OFFSETOF(VBOXVDMACBUF_DR, aGuestData)))
#endif
-NTSTATUS vboxVdmaGgCmdSubmit(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DR pCmd);
-PVBOXVDMAPIPE_CMD_DR vboxVdmaGgCmdCreate(PVBOXMP_DEVEXT pDevExt, VBOXVDMAPIPE_CMD_TYPE enmType, uint32_t cbCmd);
-DECLINLINE(void) vboxVdmaGgCmdAddRef(PVBOXVDMAPIPE_CMD_DR pDr)
-{
- ASMAtomicIncU32(&pDr->cRefs);
-}
-void vboxVdmaGgCmdDestroy(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DR pDr);
-DECLINLINE(void) vboxVdmaGgCmdRelease(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DR pDr)
-{
- uint32_t cRefs = ASMAtomicDecU32(&pDr->cRefs);
- Assert(cRefs < UINT32_MAX/2);
- if (!cRefs)
- vboxVdmaGgCmdDestroy(pDevExt, pDr);
-}
-NTSTATUS vboxVdmaGgCmdFinish(PVBOXMP_DEVEXT pDevExt, struct VBOXWDDM_CONTEXT *pContext, PKEVENT pEvent);
-NTSTATUS vboxVdmaGgCmdCancel(PVBOXMP_DEVEXT pDevExt, VBOXWDDM_CONTEXT *pContext, PVBOXWDDM_SWAPCHAIN pSwapchain);
NTSTATUS vboxVdmaPostHideSwapchain(PVBOXWDDM_SWAPCHAIN pSwapchain);
@@ -355,5 +328,11 @@ NTSTATUS vboxVdmaGgDmaBltPerform(PVBOXMP_DEVEXT pDevExt, struct VBOXWDDM_ALLOC_D
struct VBOXWDDM_ALLOC_DATA *pDstAlloc, RECT* pDstRect);
#define VBOXVDMAPIPE_CMD_DR_FROM_DDI_CMD(_pCmd) ((PVBOXVDMAPIPE_CMD_DR)(((uint8_t*)(_pCmd)) - RT_OFFSETOF(VBOXVDMAPIPE_CMD_DR, DdiCmd)))
-DECLCALLBACK(VOID) vboxVdmaGgDdiCmdRelease(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext);
+
+NTSTATUS vboxVdmaProcessBltCmd(PVBOXMP_DEVEXT pDevExt, struct VBOXWDDM_CONTEXT *pContext, struct VBOXWDDM_DMA_PRIVATEDATA_BLT *pBlt);
+NTSTATUS vboxVdmaProcessFlipCmd(PVBOXMP_DEVEXT pDevExt, struct VBOXWDDM_CONTEXT *pContext, struct VBOXWDDM_DMA_PRIVATEDATA_FLIP *pFlip);
+NTSTATUS vboxVdmaProcessClrFillCmd(PVBOXMP_DEVEXT pDevExt, struct VBOXWDDM_CONTEXT *pContext, struct VBOXWDDM_DMA_PRIVATEDATA_CLRFILL *pCF);
+
+NTSTATUS vboxVdmaTexPresentSetAlloc(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pRealFbAlloc);
+
#endif /* #ifndef ___VBoxMPVdma_h___ */
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVhwa.cpp b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVhwa.cpp
index d948ea97..a6deff29 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVhwa.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVhwa.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVhwa.h b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVhwa.h
index e4279154..ca08d756 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVhwa.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVhwa.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVidPn.cpp b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVidPn.cpp
index 4813f818..a9e1d8e3 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVidPn.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVidPn.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -552,6 +552,10 @@ static DECLCALLBACK(BOOLEAN) vboxFidPnMatchMonitorModesEnum(D3DKMDT_HMONITORSOUR
if (!fFound)
pInfo->fMatched = FALSE;
+ if (!pInfo->fMatched)
+ LOG(("Found non-matching mode (%d X %d)",
+ pMonitorSMI->VideoSignalInfo.ActiveSize.cx, pMonitorSMI->VideoSignalInfo.ActiveSize.cy));
+
pMonitorSMSIf->pfnReleaseModeInfo(hMonitorSMS, pMonitorSMI);
return pInfo->fMatched;
@@ -596,7 +600,10 @@ NTSTATUS vboxVidPnMatchMonitorModes(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT
if (NT_SUCCESS(Status))
{
if (cModes < cResolutions)
+ {
*pfMatch = FALSE;
+ LOG(("num modes(%d) and resolutions(%d) do not match, treat as not matched..", cModes, cResolutions));
+ }
else
{
VBOXVIDPNMATCHMONMODESENUM Info;
@@ -606,7 +613,12 @@ NTSTATUS vboxVidPnMatchMonitorModes(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT
Status = vboxVidPnEnumMonitorSourceModes(hMonitorSMS, pMonitorSMSIf, vboxFidPnMatchMonitorModesEnum, &Info);
if (NT_SUCCESS(Status))
+ {
*pfMatch = Info.fMatched;
+ LOG(("modes %smatched", Info.fMatched ? "" : "NOT "));
+ }
+ else
+ WARN(("vboxVidPnEnumMonitorSourceModes failed, Status 0x%x", Status));
}
}
else
@@ -1250,10 +1262,7 @@ static NTSTATUS vboxVidPnCofuncModalityForPathTarget(PVBOXVIDPNCOFUNCMODALITY pC
D3DKMDT_HVIDPNTARGETMODESET hNewVidPnTargetModeSet = NULL;
const DXGK_VIDPNTARGETMODESET_INTERFACE *pNewVidPnTargetModeSetInterface;
- if (VidPnSourceId != VidPnTargetId || pCbContext->apPathInfos[VidPnTargetId].enmState != VBOXVIDPNPATHITEM_STATE_PRESENT)
- {
- return STATUS_SUCCESS;
- }
+ Assert(VidPnSourceId == VidPnTargetId);
D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
const DXGK_VIDPNSOURCEMODESET_INTERFACE *pCurVidPnSourceModeSetInterface;
@@ -1293,10 +1302,9 @@ static NTSTATUS vboxVidPnCofuncModalityForPathTarget(PVBOXVIDPNCOFUNCMODALITY pC
if (NT_SUCCESS(Status))
{
Assert(hNewVidPnTargetModeSet);
- if (VidPnSourceId == VidPnTargetId && pCbContext->apPathInfos[VidPnTargetId].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
+ Assert(VidPnSourceId == VidPnTargetId);
+// if (VidPnSourceId == VidPnTargetId && pCbContext->apPathInfos[VidPnTargetId].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
{
- Assert(VidPnSourceId == VidPnTargetId);
-
for (uint32_t i = 0; i < pInfo->cResolutions; ++i)
{
D3DKMDT_2DREGION *pResolution = &pInfo->aResolutions[i];
@@ -1385,10 +1393,7 @@ static NTSTATUS vboxVidPnCofuncModalityForPathSource(PVBOXVIDPNCOFUNCMODALITY pC
D3DKMDT_HVIDPNSOURCEMODESET hNewVidPnSourceModeSet = NULL;
const DXGK_VIDPNSOURCEMODESET_INTERFACE *pNewVidPnSourceModeSetInterface;
- if (VidPnSourceId != VidPnTargetId || pCbContext->apPathInfos[VidPnSourceId].enmState != VBOXVIDPNPATHITEM_STATE_PRESENT)
- {
- return STATUS_SUCCESS;
- }
+ Assert(VidPnSourceId == VidPnTargetId);
D3DKMDT_HVIDPNTARGETMODESET hCurVidPnTargetModeSet;
const DXGK_VIDPNTARGETMODESET_INTERFACE *pCurVidPnTargetModeSetInterface;
@@ -1428,9 +1433,9 @@ static NTSTATUS vboxVidPnCofuncModalityForPathSource(PVBOXVIDPNCOFUNCMODALITY pC
if (NT_SUCCESS(Status))
{
Assert(hNewVidPnSourceModeSet);
- if (VidPnSourceId == VidPnTargetId && pCbContext->apPathInfos[VidPnSourceId].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
+ Assert(VidPnSourceId == VidPnTargetId);
+// if (VidPnSourceId == VidPnTargetId && pCbContext->apPathInfos[VidPnSourceId].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
{
- Assert(VidPnSourceId == VidPnTargetId);
for (uint32_t i = 0; i < pInfo->cModes; ++i)
{
VIDEO_MODE_INFORMATION *pMode = &pInfo->aModes[i];
@@ -1742,7 +1747,7 @@ static DECLCALLBACK(BOOLEAN) vboxVidPnCheckTopologyEnum(D3DKMDT_HVIDPNTOPOLOGY h
}
else
{
- AssertFailed();
+ WARN(("cItems(%d) <= VidPnSourceId(%d)", pCbContext->cItems, VidPnSourceId));
Status = STATUS_BUFFER_OVERFLOW;
break;
}
@@ -1753,7 +1758,7 @@ static DECLCALLBACK(BOOLEAN) vboxVidPnCheckTopologyEnum(D3DKMDT_HVIDPNTOPOLOGY h
}
else
{
- AssertFailed();
+ WARN(("cItems(%d) <= VidPnTargetId(%d)", pCbContext->cItems, VidPnTargetId));
Status = STATUS_BUFFER_OVERFLOW;
break;
}
@@ -1762,6 +1767,7 @@ static DECLCALLBACK(BOOLEAN) vboxVidPnCheckTopologyEnum(D3DKMDT_HVIDPNTOPOLOGY h
}
/* VidPnSourceId == VidPnTargetId */
+ Assert(VidPnSourceId == VidPnTargetId);
if (pCbContext->cItems > VidPnSourceId)
{
if (pCbContext->paItems[VidPnSourceId].enmState != VBOXVIDPNPATHITEM_STATE_DISABLED)
@@ -1772,7 +1778,7 @@ static DECLCALLBACK(BOOLEAN) vboxVidPnCheckTopologyEnum(D3DKMDT_HVIDPNTOPOLOGY h
}
else
{
- AssertFailed();
+ WARN(("cItems(%d) <= VidPnSource/TargetId(%d)", pCbContext->cItems, VidPnSourceId));
Status = STATUS_BUFFER_OVERFLOW;
break;
}
@@ -1788,20 +1794,21 @@ static DECLCALLBACK(BOOLEAN) vboxVidPnCheckTopologyEnum(D3DKMDT_HVIDPNTOPOLOGY h
/* we currently support only 0 -> 0, 1 -> 1, 2 -> 2 paths, AND 0 -> 0 must be present
* this routine disables all paths unsupported */
-NTSTATUS vboxVidPnCheckTopology(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
- BOOLEAN fBreakOnDisabled, UINT cItems, PVBOXVIDPNPATHITEM paItems, BOOLEAN *pfDisabledFound)
+NTSTATUS vboxVidPnCheckTopology(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface, BOOLEAN *pfSupported)
{
+ VBOXVIDPNPATHITEM aItems[VBOX_VIDEO_MAX_SCREENS];
+ const uint32_t cItems = RT_ELEMENTS(aItems);
UINT i;
for (i = 0; i < cItems; ++i)
{
- paItems[i].enmState = VBOXVIDPNPATHITEM_STATE_NOT_EXISTS;
+ aItems[i].enmState = VBOXVIDPNPATHITEM_STATE_NOT_EXISTS;
}
VBOXVIDPNGETPATHSINFO CbContext = {0};
CbContext.Status = STATUS_SUCCESS;
- CbContext.fBreakOnDisabled = fBreakOnDisabled;
+ CbContext.fBreakOnDisabled = FALSE;
CbContext.fDisabledFound = FALSE;
CbContext.cItems = cItems;
- CbContext.paItems = paItems;
+ CbContext.paItems = aItems;
NTSTATUS Status = vboxVidPnEnumPaths(hVidPnTopology, pVidPnTopologyInterface, vboxVidPnCheckTopologyEnum, &CbContext);
if (!NT_SUCCESS(Status))
{
@@ -1816,22 +1823,22 @@ NTSTATUS vboxVidPnCheckTopology(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXG
return Status;
}
- if (pfDisabledFound)
- *pfDisabledFound = CbContext.fDisabledFound;
+ BOOLEAN fSupported = !CbContext.fDisabledFound;
- if (!fBreakOnDisabled)
- {
- /* now check if 0->0 path is present and enabled, and if not, disable everything */
- if (cItems && paItems[0].enmState != VBOXVIDPNPATHITEM_STATE_PRESENT)
- {
- LOGREL(("path 0 not set to present\n"));
- for (i = 0; i < cItems; ++i)
- {
- if (paItems[i].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
- paItems[i].enmState = VBOXVIDPNPATHITEM_STATE_DISABLED;
- }
- }
- }
+ /* now check if 0->0 path is present and enabled, and if not, disable everything */
+// if (cItems && aItems[0].enmState != VBOXVIDPNPATHITEM_STATE_PRESENT)
+// {
+// LOG(("path 0 not set to present\n"));
+//// for (i = 0; i < cItems; ++i)
+//// {
+//// if (aItems[i].enmState == VBOXVIDPNPATHITEM_STATE_PRESENT)
+//// aItems[i].enmState = VBOXVIDPNPATHITEM_STATE_DISABLED;
+//// }
+// fSupported = FALSE;
+// }
+
+ if (pfSupported)
+ *pfSupported = fSupported;
return Status;
}
@@ -2050,9 +2057,8 @@ NTSTATUS vboxVidPnEnumPaths(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VI
pVidPnTopologyInterface->pfnReleasePathInfo(hVidPnTopology, pNextVidPnPresentPathInfo);
else
{
- Assert(Status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET);
if (Status != STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET)
- LOGREL(("pfnAcquireNextPathInfo Failed Status(0x%x), ignored since callback returned false", Status));
+ WARN(("pfnAcquireNextPathInfo Failed Status(0x%x), ignored since callback returned false", Status));
Status = STATUS_SUCCESS;
}
@@ -2067,8 +2073,7 @@ NTSTATUS vboxVidPnEnumPaths(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VI
}
else
{
- AssertBreakpoint();
- LOGREL(("pfnAcquireNextPathInfo Failed Status(0x%x)", Status));
+ WARN(("pfnAcquireNextPathInfo Failed Status(0x%x)", Status));
pNewVidPnPresentPathInfo = NULL;
break;
}
@@ -2077,26 +2082,54 @@ NTSTATUS vboxVidPnEnumPaths(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VI
else if (Status == STATUS_GRAPHICS_DATASET_IS_EMPTY)
Status = STATUS_SUCCESS;
else
- LOGREL(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status));
+ WARN(("pfnAcquireFirstModeInfo failed Status(0x%x)", Status));
return Status;
}
NTSTATUS vboxVidPnSetupSourceInfo(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId, PVBOXWDDM_SOURCE pSource, CONST D3DKMDT_VIDPN_SOURCE_MODE* pVidPnSourceModeInfo, PVBOXWDDM_ALLOCATION pAllocation)
{
- vboxWddmAssignPrimary(pDevExt, pSource, pAllocation, srcId);
/* pVidPnSourceModeInfo could be null if STATUS_GRAPHICS_MODE_NOT_PINNED,
* see vboxVidPnCommitSourceModeForSrcId */
+ uint8_t fChanges = 0;
if (pVidPnSourceModeInfo)
{
- pSource->AllocData.SurfDesc.width = pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx;
- pSource->AllocData.SurfDesc.height = pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy;
- pSource->AllocData.SurfDesc.format = pVidPnSourceModeInfo->Format.Graphics.PixelFormat;
- pSource->AllocData.SurfDesc.bpp = vboxWddmCalcBitsPerPixel(pVidPnSourceModeInfo->Format.Graphics.PixelFormat);
- pSource->AllocData.SurfDesc.pitch = pVidPnSourceModeInfo->Format.Graphics.Stride;
+ if (pSource->AllocData.SurfDesc.width != pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx)
+ {
+ fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
+ pSource->AllocData.SurfDesc.width = pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cx;
+ }
+ if (pSource->AllocData.SurfDesc.height != pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy)
+ {
+ fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
+ pSource->AllocData.SurfDesc.height = pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy;
+ }
+ if (pSource->AllocData.SurfDesc.format != pVidPnSourceModeInfo->Format.Graphics.PixelFormat)
+ {
+ fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
+ pSource->AllocData.SurfDesc.format = pVidPnSourceModeInfo->Format.Graphics.PixelFormat;
+ }
+ if (pSource->AllocData.SurfDesc.bpp != vboxWddmCalcBitsPerPixel(pVidPnSourceModeInfo->Format.Graphics.PixelFormat))
+ {
+ fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
+ pSource->AllocData.SurfDesc.bpp = vboxWddmCalcBitsPerPixel(pVidPnSourceModeInfo->Format.Graphics.PixelFormat);
+ }
+ if(pSource->AllocData.SurfDesc.pitch != pVidPnSourceModeInfo->Format.Graphics.Stride)
+ {
+ fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
+ pSource->AllocData.SurfDesc.pitch = pVidPnSourceModeInfo->Format.Graphics.Stride;
+ }
pSource->AllocData.SurfDesc.depth = 1;
- pSource->AllocData.SurfDesc.slicePitch = pVidPnSourceModeInfo->Format.Graphics.Stride;
- pSource->AllocData.SurfDesc.cbSize = pVidPnSourceModeInfo->Format.Graphics.Stride * pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy;
+ if (pSource->AllocData.SurfDesc.slicePitch != pVidPnSourceModeInfo->Format.Graphics.Stride)
+ {
+ fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
+ pSource->AllocData.SurfDesc.slicePitch = pVidPnSourceModeInfo->Format.Graphics.Stride;
+ }
+ if (pSource->AllocData.SurfDesc.cbSize != pVidPnSourceModeInfo->Format.Graphics.Stride * pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy)
+ {
+ fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
+ pSource->AllocData.SurfDesc.cbSize = pVidPnSourceModeInfo->Format.Graphics.Stride * pVidPnSourceModeInfo->Format.Graphics.PrimSurfSize.cy;
+ }
#ifdef VBOX_WDDM_WIN8
if (g_VBoxDisplayOnly)
{
@@ -2107,9 +2140,13 @@ NTSTATUS vboxVidPnSetupSourceInfo(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_S
else
{
Assert(!pAllocation);
+ fChanges |= VBOXWDDM_HGSYNC_F_SYNCED_ALL;
}
+
+ vboxWddmAssignPrimary(pDevExt, pSource, pAllocation, srcId);
+
Assert(pSource->AllocData.SurfDesc.VidPnSourceId == srcId);
- pSource->bGhSynced = FALSE;
+ pSource->u8SyncState &= ~fChanges;
return STATUS_SUCCESS;
}
@@ -2155,7 +2192,6 @@ DECLCALLBACK(BOOLEAN) vboxVidPnCommitTargetModeEnum(PVBOXMP_DEVEXT pDevExt, D3DK
{
pTarget->HeightVisible = pPinnedVidPnTargetModeInfo->VideoSignalInfo.ActiveSize.cy;
pTarget->HeightTotal = pPinnedVidPnTargetModeInfo->VideoSignalInfo.TotalSize.cy;
- pTarget->ScanLineState = 0;
}
pVidPnTargetModeSetInterface->pfnReleaseModeInfo(hVidPnTargetModeSet, pPinnedVidPnTargetModeInfo);
}
@@ -2169,6 +2205,10 @@ DECLCALLBACK(BOOLEAN) vboxVidPnCommitTargetModeEnum(PVBOXMP_DEVEXT pDevExt, D3DK
return Status == STATUS_SUCCESS;
}
+#ifdef DEBUG_misha
+DWORD g_VBoxDbgBreakModes = 0;
+#endif
+
NTSTATUS vboxVidPnCommitSourceModeForSrcId(PVBOXMP_DEVEXT pDevExt, const D3DKMDT_HVIDPN hDesiredVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId, PVBOXWDDM_ALLOCATION pAllocation)
{
D3DKMDT_HVIDPNSOURCEMODESET hCurVidPnSourceModeSet;
@@ -2222,29 +2262,33 @@ NTSTATUS vboxVidPnCommitSourceModeForSrcId(PVBOXMP_DEVEXT pDevExt, const D3DKMDT
Status = STATUS_SUCCESS;
}
else
- LOGREL(("vboxVidPnEnumTargetsForSource failed Status(0x%x)", Status));
+ WARN(("vboxVidPnEnumTargetsForSource failed Status(0x%x)", Status));
}
else
- LOGREL(("pfnGetTopology failed Status(0x%x)", Status));
+ WARN(("pfnGetTopology failed Status(0x%x)", Status));
}
else
- LOGREL(("vboxVidPnCommitSourceMode failed Status(0x%x)", Status));
+ WARN(("vboxVidPnCommitSourceMode failed Status(0x%x)", Status));
/* release */
pCurVidPnSourceModeSetInterface->pfnReleaseModeInfo(hCurVidPnSourceModeSet, pPinnedVidPnSourceModeInfo);
}
else if (Status == STATUS_GRAPHICS_MODE_NOT_PINNED)
{
+#ifdef DEBUG_misha
+ Assert(!g_VBoxDbgBreakModes);
+ ++g_VBoxDbgBreakModes;
+#endif
Status = vboxVidPnCommitSourceMode(pDevExt, srcId, NULL, pAllocation);
Assert(Status == STATUS_SUCCESS);
}
else
- LOGREL(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
+ WARN(("pfnAcquirePinnedModeInfo failed Status(0x%x)", Status));
pVidPnInterface->pfnReleaseSourceModeSet(hDesiredVidPn, hCurVidPnSourceModeSet);
}
else
{
- LOGREL(("pfnAcquireSourceModeSet failed Status(0x%x)", Status));
+ WARN(("pfnAcquireSourceModeSet failed Status(0x%x)", Status));
}
return Status;
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVidPn.h b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVidPn.h
index f9a4d1e1..e51a0287 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVidPn.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVidPn.h
@@ -57,8 +57,8 @@ typedef struct VBOXVIDPNCOFUNCMODALITY
const DXGK_VIDPN_INTERFACE* pVidPnInterface;
CONST DXGKARG_ENUMVIDPNCOFUNCMODALITY* pEnumCofuncModalityArg;
PVBOXWDDM_VIDEOMODES_INFO pInfos;
- UINT cPathInfos;
- PVBOXVIDPNPATHITEM apPathInfos;
+// UINT cPathInfos;
+// PVBOXVIDPNPATHITEM apPathInfos;
} VBOXVIDPNCOFUNCMODALITY, *PVBOXVIDPNCOFUNCMODALITY;
typedef struct VBOXVIDPNCOMMIT
@@ -145,8 +145,7 @@ NTSTATUS vboxVidPnMatchMonitorModes(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT
NTSTATUS vboxVidPnCofuncModalityForPath(PVBOXVIDPNCOFUNCMODALITY pCbContext, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId);
-NTSTATUS vboxVidPnCheckTopology(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface,
- BOOLEAN fBreakOnDisabled, UINT cItems, PVBOXVIDPNPATHITEM paItems, BOOLEAN *pfDisabledFound);
+NTSTATUS vboxVidPnCheckTopology(D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, const DXGK_VIDPNTOPOLOGY_INTERFACE* pVidPnTopologyInterface, BOOLEAN *pfSupported);
NTSTATUS vboxVidPnPathAdd(D3DKMDT_HVIDPN hVidPn, const DXGK_VIDPN_INTERFACE* pVidPnInterface,
const D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, const D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId);
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp
index 446d048c..39b66cf1 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -30,6 +30,10 @@
#include <VBoxDisplay.h> /* this is from Additions/WINNT/include/ to include escape codes */
#include <VBox/Hardware/VBoxVideoVBE.h>
+#include <stdio.h>
+
+#define VBOXWDDM_DUMMY_DMABUFFER_SIZE sizeof (RECT)
+
DWORD g_VBoxLogUm = 0;
#ifdef VBOX_WDDM_WIN8
DWORD g_VBoxDisplayOnly = 0;
@@ -54,12 +58,31 @@ VOID vboxWddmMemFree(PVOID pvMem)
ExFreePool(pvMem);
}
+DECLINLINE(void) VBoxWddmOaHostIDReleaseLocked(PVBOXWDDM_OPENALLOCATION pOa)
+{
+ Assert(pOa->cHostIDRefs);
+ PVBOXWDDM_ALLOCATION pAllocation = pOa->pAllocation;
+ Assert(pAllocation->AllocData.cHostIDRefs >= pOa->cHostIDRefs);
+ Assert(pAllocation->AllocData.hostID);
+ --pOa->cHostIDRefs;
+ --pAllocation->AllocData.cHostIDRefs;
+ if (!pAllocation->AllocData.cHostIDRefs)
+ pAllocation->AllocData.hostID = 0;
+}
+
+DECLINLINE(void) VBoxWddmOaHostIDCheckReleaseLocked(PVBOXWDDM_OPENALLOCATION pOa)
+{
+ if (pOa->cHostIDRefs)
+ VBoxWddmOaHostIDReleaseLocked(pOa);
+}
+
DECLINLINE(void) VBoxWddmOaRelease(PVBOXWDDM_OPENALLOCATION pOa)
{
PVBOXWDDM_ALLOCATION pAllocation = pOa->pAllocation;
KIRQL OldIrql;
KeAcquireSpinLock(&pAllocation->OpenLock, &OldIrql);
Assert(pAllocation->cOpens);
+ VBoxWddmOaHostIDCheckReleaseLocked(pOa);
--pAllocation->cOpens;
uint32_t cOpens = --pOa->cOpens;
Assert(cOpens < UINT32_MAX/2);
@@ -96,6 +119,47 @@ DECLINLINE(PVBOXWDDM_OPENALLOCATION) VBoxWddmOaSearch(PVBOXWDDM_DEVICE pDevice,
return pOa;
}
+DECLINLINE(int) VBoxWddmOaSetHostID(PVBOXWDDM_DEVICE pDevice, PVBOXWDDM_ALLOCATION pAllocation, uint32_t hostID, uint32_t *pHostID)
+{
+ PVBOXWDDM_OPENALLOCATION pOa;
+ KIRQL OldIrql;
+ int rc = VINF_SUCCESS;
+ KeAcquireSpinLock(&pAllocation->OpenLock, &OldIrql);
+ pOa = VBoxWddmOaSearchLocked(pDevice, pAllocation);
+ if (!pOa)
+ {
+ KeReleaseSpinLock(&pAllocation->OpenLock, OldIrql);;
+ WARN(("no open allocation!"));
+ return VERR_INVALID_STATE;
+ }
+
+ if (hostID)
+ {
+ if (pAllocation->AllocData.hostID == 0)
+ {
+ pAllocation->AllocData.hostID = hostID;
+ }
+ else if (pAllocation->AllocData.hostID != hostID)
+ {
+ WARN(("hostID differ: alloc(%d), trying to assign(%d)", pAllocation->AllocData.hostID, hostID));
+ hostID = pAllocation->AllocData.hostID;
+ rc = VERR_NOT_EQUAL;
+ }
+
+ ++pAllocation->AllocData.cHostIDRefs;
+ ++pOa->cHostIDRefs;
+ }
+ else
+ VBoxWddmOaHostIDCheckReleaseLocked(pOa);
+
+ KeReleaseSpinLock(&pAllocation->OpenLock, OldIrql);
+
+ if (pHostID)
+ *pHostID = hostID;
+
+ return rc;
+}
+
DECLINLINE(PVBOXWDDM_ALLOCATION) vboxWddmGetAllocationFromHandle(PVBOXMP_DEVEXT pDevExt, D3DKMT_HANDLE hAllocation)
{
DXGKARGCB_GETHANDLEDATA GhData;
@@ -137,7 +201,7 @@ static void vboxWddmPopulateDmaAllocInfoWithOffset(PVBOXWDDM_DMA_ALLOCINFO pInfo
pInfo->srcId = pAlloc->AllocData.SurfDesc.VidPnSourceId;
}
-NTSTATUS vboxWddmGhDisplayPostInfoScreenBySDesc (PVBOXMP_DEVEXT pDevExt, const PVBOXWDDM_SURFACE_DESC pDesc, const POINT * pVScreenPos, uint16_t fFlags)
+NTSTATUS vboxWddmGhDisplayPostInfoScreenBySDesc (PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_SURFACE_DESC *pDesc, const POINT * pVScreenPos, uint16_t fFlags)
{
void *p = VBoxHGSMIBufferAlloc (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx,
sizeof (VBVAINFOSCREEN),
@@ -167,7 +231,7 @@ NTSTATUS vboxWddmGhDisplayPostInfoScreenBySDesc (PVBOXMP_DEVEXT pDevExt, const P
}
-NTSTATUS vboxWddmGhDisplayPostInfoScreen(PVBOXMP_DEVEXT pDevExt, const PVBOXWDDM_ALLOC_DATA pAllocData, const POINT * pVScreenPos)
+NTSTATUS vboxWddmGhDisplayPostInfoScreen(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOC_DATA *pAllocData, const POINT * pVScreenPos)
{
NTSTATUS Status = vboxWddmGhDisplayPostInfoScreenBySDesc(pDevExt, &pAllocData->SurfDesc, pVScreenPos, VBVA_SCREEN_F_ACTIVE);
if (!NT_SUCCESS(Status))
@@ -177,16 +241,26 @@ NTSTATUS vboxWddmGhDisplayPostInfoScreen(PVBOXMP_DEVEXT pDevExt, const PVBOXWDDM
NTSTATUS vboxWddmGhDisplayHideScreen(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
{
- VBOXWDDM_SURFACE_DESC SurfDesc = {0};
+ PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[VidPnTargetId];
+ /* this will force update on re-activation */
+ pSource->AllocData.SurfDesc.width = 0;
+ pSource->AllocData.SurfDesc.height = 0;
POINT VScreenPos = {0};
- SurfDesc.VidPnSourceId = VidPnTargetId;
- NTSTATUS Status = vboxWddmGhDisplayPostInfoScreenBySDesc(pDevExt, &SurfDesc, &VScreenPos, VBVA_SCREEN_F_ACTIVE | VBVA_SCREEN_F_DISABLED);
+
+ NTSTATUS Status = vboxWddmGhDisplayPostInfoScreenBySDesc(pDevExt, &pSource->AllocData.SurfDesc, &VScreenPos, VBVA_SCREEN_F_ACTIVE | VBVA_SCREEN_F_DISABLED);
if (!NT_SUCCESS(Status))
WARN(("vboxWddmGhDisplayPostInfoScreenBySDesc failed Status 0x%x", Status));
return Status;
}
-NTSTATUS vboxWddmGhDisplayPostInfoView(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOC_DATA pAllocData)
+BOOL vboxWddmGhDisplayCheckCompletePeningScreenInfo(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_TARGET_ID VidPnTargetId)
+{
+ if (!ASMAtomicCmpXchgBool(&pDevExt->aTargets[VidPnTargetId].fStateSyncPening, false, true))
+ return FALSE;
+ return vboxWddmGhDisplayCheckSetInfoFromSource(pDevExt, &pDevExt->aSources[VidPnTargetId]);
+}
+
+NTSTATUS vboxWddmGhDisplayPostInfoView(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOC_DATA *pAllocData)
{
VBOXVIDEOOFFSET offVram = pAllocData->Addr.offVram;
if (offVram == VBOXVIDEOOFFSET_VOID)
@@ -219,7 +293,7 @@ NTSTATUS vboxWddmGhDisplayPostInfoView(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOC_D
return STATUS_SUCCESS;
}
-NTSTATUS vboxWddmGhDisplaySetMode(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOC_DATA pAllocData)
+NTSTATUS vboxWddmGhDisplaySetMode(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOC_DATA *pAllocData)
{
// PVBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE pPrimaryInfo = VBOXWDDM_ALLOCATION_BODY(pAllocation, VBOXWDDM_ALLOCATION_SHAREDPRIMARYSURFACE);
if (/*pPrimaryInfo->*/pAllocData->SurfDesc.VidPnSourceId)
@@ -269,38 +343,77 @@ NTSTATUS vboxWddmGhDisplayUpdateScreenPos(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOUR
return Status;
}
-NTSTATUS vboxWddmGhDisplaySetInfo(PVBOXMP_DEVEXT pDevExt, const PVBOXWDDM_ALLOC_DATA pAllocData, const POINT * pVScreenPos)
+NTSTATUS vboxWddmGhDisplaySetInfo(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pRealFbAlloc, const VBOXWDDM_ALLOC_DATA *pAllocData, const POINT * pVScreenPos, uint8_t u8CurCyncState)
{
- NTSTATUS Status = vboxWddmGhDisplaySetMode(pDevExt, pAllocData);
- Assert(Status == STATUS_SUCCESS);
- if (Status == STATUS_SUCCESS)
+ NTSTATUS Status;
+
+ if ((u8CurCyncState & VBOXWDDM_HGSYNC_F_CHANGED_LOCATION_ONLY) == VBOXWDDM_HGSYNC_F_CHANGED_LOCATION_ONLY
+ && pRealFbAlloc->AllocData.hostID)
+ {
+ Status = vboxVdmaTexPresentSetAlloc(pDevExt, pRealFbAlloc);
+ if (!NT_SUCCESS(Status))
+ WARN(("vboxVdmaTexPresentSetAlloc failed, Status 0x%x", Status));
+ return Status;
+ }
+
+ Status = vboxWddmGhDisplaySetMode(pDevExt, pAllocData);
+ if (NT_SUCCESS(Status))
{
Status = vboxWddmGhDisplayPostInfoView(pDevExt, pAllocData);
- Assert(Status == STATUS_SUCCESS);
- if (Status == STATUS_SUCCESS)
+ if (NT_SUCCESS(Status))
{
Status = vboxWddmGhDisplayPostInfoScreen(pDevExt, pAllocData, pVScreenPos);
- Assert(Status == STATUS_SUCCESS);
- if (!NT_SUCCESS(Status))
- WARN(("vboxWddmGhDisplayPostInfoScreen failed"));
+ if (NT_SUCCESS(Status))
+ {
+ if (pDevExt->f3DEnabled)
+ {
+ Status = vboxVdmaTexPresentSetAlloc(pDevExt, pRealFbAlloc);
+ if (NT_SUCCESS(Status))
+ return STATUS_SUCCESS;
+ else
+ WARN(("vboxVdmaTexPresentSetAlloc failed, Status 0x%x", Status));
+ }
+ }
+ else
+ WARN(("vboxWddmGhDisplayPostInfoScreen failed, Status 0x%x", Status));
}
else
- WARN(("vboxWddmGhDisplayPostInfoView failed"));
+ WARN(("vboxWddmGhDisplayPostInfoView failed, Status 0x%x", Status));
}
else
- WARN(("vboxWddmGhDisplaySetMode failed"));
+ WARN(("vboxWddmGhDisplaySetMode failed, Status 0x%x", Status));
return Status;
}
-bool vboxWddmGhDisplayCheckSetInfoFromSource(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource)
+bool vboxWddmGhDisplaySetInfoFromSourceTarget(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource, PVBOXWDDM_TARGET pTarget)
{
- Assert(VBOXVIDEOOFFSET_VOID != pSource->AllocData.Addr.offVram);
-
- if (pSource->bGhSynced)
- return false;
+ if (!pTarget->HeightVisible)
+ {
+ vboxWddmGhDisplayHideScreen(pDevExt, pSource->AllocData.SurfDesc.VidPnSourceId);
+ pSource->u8SyncState = VBOXWDDM_HGSYNC_F_SYNCED_ALL;
+ return true;
+ }
PVBOXWDDM_ALLOCATION pFbAlloc = VBOXWDDM_FB_ALLOCATION(pDevExt, pSource);
+ PVBOXWDDM_ALLOCATION pRealFbAlloc = pSource->pPrimaryAllocation;
+#ifdef VBOXWDDM_RENDER_FROM_SHADOW
+# ifdef VBOX_WDDM_WIN8
+ if (!g_VBoxDisplayOnly)
+# endif
+ {
+ if (!pRealFbAlloc)
+ return false;
+
+ if (!pFbAlloc)
+ pFbAlloc = pRealFbAlloc;
+
+ if (!pFbAlloc || pFbAlloc->AllocData.Addr.offVram == VBOXVIDEOOFFSET_VOID)
+ {
+ return false;
+ }
+ }
+#endif
#ifdef VBOX_WDDM_WIN8
Assert(!g_VBoxDisplayOnly == !!pFbAlloc);
@@ -312,15 +425,32 @@ bool vboxWddmGhDisplayCheckSetInfoFromSource(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_S
#endif
Assert(!pFbAlloc || pFbAlloc->AllocData.Addr.SegmentId == pSource->AllocData.Addr.SegmentId);
- NTSTATUS Status = vboxWddmGhDisplaySetInfo(pDevExt, pFbAlloc ? &pFbAlloc->AllocData : &pSource->AllocData, &pSource->VScreenPos);
+ NTSTATUS Status = vboxWddmGhDisplaySetInfo(pDevExt, pRealFbAlloc, pFbAlloc ? &pFbAlloc->AllocData : &pSource->AllocData, &pSource->VScreenPos, pSource->u8SyncState);
if (NT_SUCCESS(Status))
- pSource->bGhSynced = TRUE;
+ pSource->u8SyncState = VBOXWDDM_HGSYNC_F_SYNCED_ALL;
else
WARN(("vboxWddmGhDisplaySetInfo failed, Status (0x%x)", Status));
+ vboxVideoCmSignalEvents(&pDevExt->SeamlessCtxMgr);
+
return true;
}
+bool vboxWddmGhDisplayCheckSetInfoFromSource(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource)
+{
+ Assert(VBOXVIDEOOFFSET_VOID != pSource->AllocData.Addr.offVram
+ || !pDevExt->aTargets[pSource->AllocData.SurfDesc.VidPnSourceId].HeightVisible);
+
+ if (pSource->u8SyncState == VBOXWDDM_HGSYNC_F_SYNCED_ALL)
+ return false;
+
+ PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[pSource->AllocData.SurfDesc.VidPnSourceId];
+ if (ASMAtomicUoReadBool(&pTarget->fStateSyncPening))
+ return false;
+
+ return vboxWddmGhDisplaySetInfoFromSourceTarget(pDevExt, pSource, pTarget);
+}
+
static VOID vboxWddmModeRenderFromShadowDisableOnSubmitCommand(PVBOXMP_DEVEXT pDevExt, BOOLEAN fDisable)
{
for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
@@ -354,7 +484,7 @@ static VOID vboxWddmModeRenderFromShadowDisableOnSubmitCommand(PVBOXMP_DEVEXT pD
}
/* ensure we issue resize command on next update */
- pSource->bGhSynced = FALSE;
+ pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_LOCATION;
}
}
@@ -397,19 +527,6 @@ static VOID vboxWddmModeRenderFromShadowDisableUnregister(PVBOXMP_DEVEXT pDevExt
pContext->fRenderFromShadowDisabled = FALSE;
}
-#ifdef VBOXWDDM_RENDER_FROM_SHADOW
-bool vboxWddmCheckUpdateFramebufferAddress(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource)
-{
- if (pSource->pPrimaryAllocation->enmType == VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC)
- {
- Assert(pSource->bGhSynced == FALSE);
- return false;
- }
-
- return vboxWddmGhDisplayCheckSetInfoFromSource(pDevExt, pSource);
-}
-#endif
-
PVBOXSHGSMI vboxWddmHgsmiGetHeapFromCmdOffset(PVBOXMP_DEVEXT pDevExt, HGSMIOFFSET offCmd)
{
#ifdef VBOX_WITH_VDMA
@@ -441,322 +558,6 @@ VBOXWDDM_HGSMICMD_TYPE vboxWddmHgsmiGetCmdTypeFromOffset(PVBOXMP_DEVEXT pDevExt,
return VBOXWDDM_HGSMICMD_TYPE_UNDEFINED;
}
-static NTSTATUS vboxWddmChildStatusReportPerform(PVBOXMP_DEVEXT pDevExt, PVBOXVDMA_CHILD_STATUS pChildStatus, D3DDDI_VIDEO_PRESENT_TARGET_ID iChild)
-{
- DXGK_CHILD_STATUS DdiChildStatus;
- if (pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_DISCONNECTED)
- {
- /* report disconnected */
- memset(&DdiChildStatus, 0, sizeof (DdiChildStatus));
- DdiChildStatus.Type = StatusConnection;
- if (iChild != D3DDDI_ID_UNINITIALIZED)
- {
- Assert(iChild < UINT32_MAX/2);
- Assert(iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
- DdiChildStatus.ChildUid = iChild;
- }
- else
- {
- Assert(pChildStatus->iChild < UINT32_MAX/2);
- Assert(pChildStatus->iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
- DdiChildStatus.ChildUid = pChildStatus->iChild;
- }
- DdiChildStatus.HotPlug.Connected = FALSE;
- NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus);
- if (!NT_SUCCESS(Status))
- {
- WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status));
- return Status;
- }
- }
-
- if (pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_CONNECTED)
- {
- /* report disconnected */
- memset(&DdiChildStatus, 0, sizeof (DdiChildStatus));
- DdiChildStatus.Type = StatusConnection;
- if (iChild != D3DDDI_ID_UNINITIALIZED)
- {
- Assert(iChild < UINT32_MAX/2);
- Assert(iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
- DdiChildStatus.ChildUid = iChild;
- }
- else
- {
- Assert(pChildStatus->iChild < UINT32_MAX/2);
- Assert(pChildStatus->iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
- DdiChildStatus.ChildUid = pChildStatus->iChild;
- }
- DdiChildStatus.HotPlug.Connected = TRUE;
- NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus);
- if (!NT_SUCCESS(Status))
- {
- WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status));
- return Status;
- }
- }
-
- if (pChildStatus->fFlags & VBOXVDMA_CHILD_STATUS_F_ROTATED)
- {
- /* report disconnected */
- memset(&DdiChildStatus, 0, sizeof (DdiChildStatus));
- DdiChildStatus.Type = StatusRotation;
- if (iChild != D3DDDI_ID_UNINITIALIZED)
- {
- Assert(iChild < UINT32_MAX/2);
- Assert(iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
- DdiChildStatus.ChildUid = iChild;
- }
- else
- {
- Assert(pChildStatus->iChild < UINT32_MAX/2);
- Assert(pChildStatus->iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays);
- DdiChildStatus.ChildUid = pChildStatus->iChild;
- }
- DdiChildStatus.Rotation.Angle = pChildStatus->u8RotationAngle;
- NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbIndicateChildStatus(pDevExt->u.primary.DxgkInterface.DeviceHandle, &DdiChildStatus);
- if (!NT_SUCCESS(Status))
- {
- WARN(("DxgkCbIndicateChildStatus failed with Status (0x%x)", Status));
- return Status;
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-static NTSTATUS vboxWddmChildStatusDoReportReconnected(PVBOXMP_DEVEXT pDevExt, VBOXVDMACMD_CHILD_STATUS_IRQ *pBody)
-{
- NTSTATUS Status = STATUS_SUCCESS;
-
- for (UINT i = 0; i < pBody->cInfos; ++i)
- {
- PVBOXVDMA_CHILD_STATUS pInfo = &pBody->aInfos[i];
- if (pBody->fFlags & VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL)
- {
- for (D3DDDI_VIDEO_PRESENT_TARGET_ID iChild = 0; iChild < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++iChild)
- {
- Status = vboxWddmChildStatusReportPerform(pDevExt, pInfo, iChild);
- if (!NT_SUCCESS(Status))
- {
- WARN(("vboxWddmChildStatusReportPerform failed with Status (0x%x)", Status));
- break;
- }
- }
- }
- else
- {
- Status = vboxWddmChildStatusReportPerform(pDevExt, pInfo, D3DDDI_ID_UNINITIALIZED);
- if (!NT_SUCCESS(Status))
- {
- WARN(("vboxWddmChildStatusReportPerform failed with Status (0x%x)", Status));
- break;
- }
- }
- }
-
- return Status;
-}
-
-typedef struct VBOXWDDMCHILDSTATUSCB
-{
- PVBOXVDMACBUF_DR pDr;
- PKEVENT pEvent;
-} VBOXWDDMCHILDSTATUSCB, *PVBOXWDDMCHILDSTATUSCB;
-
-static DECLCALLBACK(VOID) vboxWddmChildStatusReportCompletion(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext)
-{
- /* we should be called from our DPC routine */
- Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
-
- PVBOXWDDMCHILDSTATUSCB pCtx = (PVBOXWDDMCHILDSTATUSCB)pvContext;
- PVBOXVDMACBUF_DR pDr = pCtx->pDr;
- PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
- VBOXVDMACMD_CHILD_STATUS_IRQ *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHILD_STATUS_IRQ);
-
- vboxWddmChildStatusDoReportReconnected(pDevExt, pBody);
-
- vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);
-
- if (pCtx->pEvent)
- {
- KeSetEvent(pCtx->pEvent, 0, FALSE);
- }
-}
-
-static NTSTATUS vboxWddmChildStatusReportReconnected(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_TARGET_ID idTarget)
-{
-#ifdef VBOX_WDDM_MONITOR_REPLUG_IRQ
- NTSTATUS Status = STATUS_UNSUCCESSFUL;
- UINT cbCmd = VBOXVDMACMD_SIZE_FROMBODYSIZE(sizeof (VBOXVDMACMD_CHILD_STATUS_IRQ));
-
- PVBOXVDMACBUF_DR pDr = vboxVdmaCBufDrCreate(&pDevExt->u.primary.Vdma, cbCmd);
- if (pDr)
- {
- // vboxVdmaCBufDrCreate zero initializes the pDr
- /* the command data follows the descriptor */
- pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR;
- pDr->cbBuf = cbCmd;
- pDr->rc = VERR_NOT_IMPLEMENTED;
-
- PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
- pHdr->enmType = VBOXVDMACMD_TYPE_CHILD_STATUS_IRQ;
- pHdr->u32CmdSpecific = 0;
- PVBOXVDMACMD_CHILD_STATUS_IRQ pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHILD_STATUS_IRQ);
- pBody->cInfos = 1;
- if (idTarget == D3DDDI_ID_ALL)
- {
- pBody->fFlags |= VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL;
- }
- pBody->aInfos[0].iChild = idTarget;
- pBody->aInfos[0].fFlags = VBOXVDMA_CHILD_STATUS_F_DISCONNECTED | VBOXVDMA_CHILD_STATUS_F_CONNECTED;
- /* we're going to KeWaitForSingleObject */
- Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
-
- PVBOXVDMADDI_CMD pDdiCmd = VBOXVDMADDI_CMD_FROM_BUF_DR(pDr);
- VBOXWDDMCHILDSTATUSCB Ctx;
- KEVENT Event;
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
- Ctx.pDr = pDr;
- Ctx.pEvent = &Event;
- vboxVdmaDdiCmdInit(pDdiCmd, 0, 0, vboxWddmChildStatusReportCompletion, &Ctx);
- /* mark command as submitted & invisible for the dx runtime since dx did not originate it */
- vboxVdmaDdiCmdSubmittedNotDx(pDdiCmd);
- int rc = vboxVdmaCBufDrSubmit(pDevExt, &pDevExt->u.primary.Vdma, pDr);
- Assert(rc == VINF_SUCCESS);
- if (RT_SUCCESS(rc))
- {
- Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
- Assert(Status == STATUS_SUCCESS);
- return STATUS_SUCCESS;
- }
-
- Status = STATUS_UNSUCCESSFUL;
-
- vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);
- }
- else
- {
- Assert(0);
- /* @todo: try flushing.. */
- LOGREL(("vboxVdmaCBufDrCreate returned NULL"));
- Status = STATUS_INSUFFICIENT_RESOURCES;
- }
-
- return Status;
-#else
- VBOXVDMACMD_CHILD_STATUS_IRQ Body = {0};
- Body.cInfos = 1;
- if (idTarget == D3DDDI_ID_ALL)
- {
- Body.fFlags |= VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL;
- }
- Body.aInfos[0].iChild = idTarget;
- Body.aInfos[0].fFlags = VBOXVDMA_CHILD_STATUS_F_DISCONNECTED | VBOXVDMA_CHILD_STATUS_F_CONNECTED;
- Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
- return vboxWddmChildStatusDoReportReconnected(pDevExt, &Body);
-#endif
-}
-
-static NTSTATUS vboxWddmChildStatusCheckByMask(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_VIDEOMODES_INFO paInfos, uint8_t *pMask)
-{
- NTSTATUS Status = STATUS_SUCCESS;
- bool bChanged[VBOX_VIDEO_MAX_SCREENS] = {0};
- int i;
-
- for (i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
- {
- if (pMask && !ASMBitTest(pMask, i))
- continue;
-
- /* @todo: check that we actually need the current source->target */
- PVBOXWDDM_VIDEOMODES_INFO pInfo = &paInfos[i];
- VIDEO_MODE_INFORMATION *pModeInfo = &pInfo->aModes[pInfo->iPreferredMode];
- BOOLEAN fMatch = FALSE;
- Status = vboxVidPnMatchMonitorModes(pDevExt, i, pInfo->aResolutions, pInfo->cResolutions, &fMatch);
- if (!NT_SUCCESS(Status))
- {
- WARN(("vboxVidPnMatchMonitorModes failed Status(0x%x)", Status));
- /* ignore the failures here, although we probably should not?? */
- break;
- }
-
- bChanged[i] = !fMatch;
- }
-
- if (!NT_SUCCESS(Status))
- {
- WARN(("updating monitor modes failed, Status(0x%x)", Status));
- return Status;
- }
-
- for (i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
- {
- if (bChanged[i])
- {
- NTSTATUS tmpStatus = vboxWddmChildStatusReportReconnected(pDevExt, i);
- if (!NT_SUCCESS(tmpStatus))
- {
- WARN(("vboxWddmChildStatusReportReconnected failed Status(0x%x)", Status));
- /* ignore the failures here, although we probably should not?? */
- break;
- }
- }
- }
-
- /* wait for the reconnected monitor data to be picked up */
- CONST DXGK_MONITOR_INTERFACE *pMonitorInterface;
- Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryMonitorInterface(pDevExt->u.primary.DxgkInterface.DeviceHandle, DXGK_MONITOR_INTERFACE_VERSION_V1, &pMonitorInterface);
- if (!NT_SUCCESS(Status))
- {
- WARN(("DxgkCbQueryMonitorInterface failed, Status()0x%x", Status));
- return Status;
- }
-
- for (i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
- {
- D3DKMDT_HMONITORSOURCEMODESET hMonitorSMS;
- CONST DXGK_MONITORSOURCEMODESET_INTERFACE *pMonitorSMSIf;
- if (!bChanged[i])
- continue;
-
- while (1)
- {
- Status = pMonitorInterface->pfnAcquireMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle,
- i,
- &hMonitorSMS,
- &pMonitorSMSIf);
- if (NT_SUCCESS(Status))
- {
- NTSTATUS tmpStatus = pMonitorInterface->pfnReleaseMonitorSourceModeSet(pDevExt->u.primary.DxgkInterface.DeviceHandle, hMonitorSMS);
- if (!NT_SUCCESS(tmpStatus))
- {
- WARN(("pfnReleaseMonitorSourceModeSet failed tmpStatus(0x%x)", tmpStatus));
- }
- break;
- }
-
- if (Status != STATUS_GRAPHICS_MONITOR_NOT_CONNECTED)
- {
- WARN(("DxgkCbQueryMonitorInterface failed, Status()0x%x", Status));
- break;
- }
-
- Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
-
- LARGE_INTEGER Interval;
- Interval.QuadPart = -(int64_t) 2 /* ms */ * 10000;
- NTSTATUS tmpStatus = KeDelayExecutionThread(KernelMode, FALSE, &Interval);
- if (!NT_SUCCESS(tmpStatus))
- {
- WARN(("KeDelayExecutionThread failed tmpStatus(0x%x)", tmpStatus));
- }
- }
- }
-
- return STATUS_SUCCESS;
-}
-
typedef struct VBOXWDDM_HWRESOURCES
{
PHYSICAL_ADDRESS phVRAM;
@@ -856,7 +657,7 @@ static void vboxWddmDevExtZeroinit(PVBOXMP_DEVEXT pDevExt, CONST PDEVICE_OBJECT
#endif
}
-static void vboxWddmSetupDisplays(PVBOXMP_DEVEXT pDevExt)
+static void vboxWddmSetupDisplaysLegacy(PVBOXMP_DEVEXT pDevExt)
{
/* For WDDM, we simply store the number of monitors as we will deal with
* VidPN stuff later */
@@ -968,6 +769,74 @@ static void vboxWddmSetupDisplays(PVBOXMP_DEVEXT pDevExt)
}
}
+static NTSTATUS vboxWddmSetupDisplaysNew(PVBOXMP_DEVEXT pDevExt)
+{
+ if (!VBoxCommonFromDeviceExt(pDevExt)->bHGSMI)
+ return STATUS_UNSUCCESSFUL;
+
+ ULONG cbAvailable = VBoxCommonFromDeviceExt(pDevExt)->cbVRAM
+ - VBoxCommonFromDeviceExt(pDevExt)->cbMiniportHeap
+ - VBVA_ADAPTER_INFORMATION_SIZE;
+
+ ULONG cbCmdVbva = cbAvailable / 2;
+ ULONG cbCmdVbvaApprox = VBOXCMDVBVA_BUFFERSIZE(4096);
+ if (cbCmdVbvaApprox > cbCmdVbva)
+ {
+ WARN(("too few VRAM memory %d, cmdVbva %d, while approximately needed %d, trying to adjust", cbAvailable, cbCmdVbva, cbCmdVbvaApprox));
+ cbCmdVbva = cbCmdVbvaApprox;
+ }
+
+ cbCmdVbva = VBOXWDDM_ROUNDBOUND(cbCmdVbva, 0x1000);
+ if (cbCmdVbva > cbAvailable - 0x1000)
+ {
+ WARN(("too few VRAM memory fatal, %d, requested for CmdVbva %d", cbAvailable, cbCmdVbva));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+
+ ULONG offCmdVbva = cbAvailable - cbCmdVbva;
+
+ int rc = VBoxCmdVbvaCreate(pDevExt, &pDevExt->CmdVbva, offCmdVbva, cbCmdVbva);
+ if (RT_SUCCESS(rc))
+ {
+ rc = VBoxCmdVbvaEnable(pDevExt, &pDevExt->CmdVbva);
+ if (RT_SUCCESS(rc))
+ {
+ rc = VBoxMPCmnMapAdapterMemory(VBoxCommonFromDeviceExt(pDevExt), (void**)&pDevExt->pvVisibleVram,
+ 0, vboxWddmVramCpuVisibleSize(pDevExt));
+ if (RT_SUCCESS(rc))
+ return STATUS_SUCCESS;
+ else
+ WARN(("VBoxMPCmnMapAdapterMemory failed, rc %d", rc));
+
+ VBoxCmdVbvaDisable(pDevExt, &pDevExt->CmdVbva);
+ }
+ else
+ WARN(("VBoxCmdVbvaEnable failed, rc %d", rc));
+
+ VBoxCmdVbvaDestroy(pDevExt, &pDevExt->CmdVbva);
+ }
+ else
+ WARN(("VBoxCmdVbvaCreate failed, rc %d", rc));
+
+ return STATUS_UNSUCCESSFUL;
+}
+
+static NTSTATUS vboxWddmSetupDisplays(PVBOXMP_DEVEXT pDevExt)
+{
+ if (pDevExt->fCmdVbvaEnabled)
+ {
+ NTSTATUS Status = vboxWddmSetupDisplaysNew(pDevExt);
+ if (!NT_SUCCESS(Status))
+ VBoxCommonFromDeviceExt(pDevExt)->bHGSMI = FALSE;
+ return Status;
+ }
+
+ vboxWddmSetupDisplaysLegacy(pDevExt);
+ return VBoxCommonFromDeviceExt(pDevExt)->bHGSMI ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
+ return STATUS_UNSUCCESSFUL;
+}
+
static int vboxWddmFreeDisplays(PVBOXMP_DEVEXT pDevExt)
{
int rc = VINF_SUCCESS;
@@ -1095,6 +964,19 @@ NTSTATUS DxgkDdiStartDevice(
Status = vboxWddmPickResources(pDevExt, &DeviceInfo, &HwRc);
if (Status == STATUS_SUCCESS)
{
+ pDevExt->f3DEnabled = VBoxMpCrCtlConIs3DSupported();
+
+ if (pDevExt->f3DEnabled)
+ {
+ pDevExt->fTexPresentEnabled = !!(VBoxMpCrGetHostCaps() & CR_VBOX_CAP_TEX_PRESENT);
+ pDevExt->fCmdVbvaEnabled = !!(VBoxMpCrGetHostCaps() & CR_VBOX_CAP_CMDVBVA);
+ }
+ else
+ {
+ pDevExt->fTexPresentEnabled = FALSE;
+ pDevExt->fCmdVbvaEnabled = FALSE;
+ }
+
/* Guest supports only HGSMI, the old VBVA via VMMDev is not supported.
* The host will however support both old and new interface to keep compatibility
* with old guest additions.
@@ -1117,17 +999,18 @@ NTSTATUS DxgkDdiStartDevice(
vboxVdmaDdiNodesInit(pDevExt);
vboxVideoCmInit(&pDevExt->CmMgr);
+ vboxVideoCmInit(&pDevExt->SeamlessCtxMgr);
InitializeListHead(&pDevExt->SwapchainList3D);
pDevExt->cContexts3D = 0;
pDevExt->cContexts2D = 0;
+ pDevExt->cContextsDispIfResize = 0;
pDevExt->cUnlockedVBVADisabled = 0;
- ExInitializeFastMutex(&pDevExt->ContextMutex);
+ VBOXWDDM_CTXLOCK_INIT(pDevExt);
KeInitializeSpinLock(&pDevExt->SynchLock);
VBoxMPCmnInitCustomVideoModes(pDevExt);
- VBoxWddmInvalidateAllVideoModesInfos(pDevExt);
- pDevExt->fAnyX = VBoxVideoAnyWidthAllowed();
+ VBoxCommonFromDeviceExt(pDevExt)->fAnyX = VBoxVideoAnyWidthAllowed();
#if 0
vboxShRcTreeInit(pDevExt);
#endif
@@ -1137,12 +1020,73 @@ NTSTATUS DxgkDdiStartDevice(
#endif
VBoxWddmSlInit(pDevExt);
+ VBoxMpCrShgsmiTransportCreate(&pDevExt->CrHgsmiTransport, pDevExt);
+
+
for (UINT i = 0; i < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
{
PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[i];
KeInitializeSpinLock(&pSource->AllocationLock);
+ VBoxVrListInit(&pSource->VrList);
+ }
+
+ DWORD dwVal = VBOXWDDM_CFG_DRV_DEFAULT;
+ HANDLE hKey = NULL;
+ WCHAR aNameBuf[100];
+
+ Status = IoOpenDeviceRegistryKey(pDevExt->pPDO, PLUGPLAY_REGKEY_DRIVER, GENERIC_READ, &hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("IoOpenDeviceRegistryKey failed, Status = 0x%x", Status));
+ hKey = NULL;
+ }
+
+
+ if (hKey)
+ {
+ Status = vboxWddmRegQueryValueDword(hKey, VBOXWDDM_REG_DRV_FLAGS_NAME, &dwVal);
+ if (!NT_SUCCESS(Status))
+ {
+ LOG(("vboxWddmRegQueryValueDword failed, Status = 0x%x", Status));
+ dwVal = VBOXWDDM_CFG_DRV_DEFAULT;
+ }
+ }
+
+ pDevExt->dwDrvCfgFlags = dwVal;
+
+ for (UINT i = 0; i < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
+ {
+ PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[i];
+ if (i == 0 || (pDevExt->dwDrvCfgFlags & VBOXWDDM_CFG_DRV_SECONDARY_TARGETS_CONNECTED) || !hKey)
+ {
+ pTarget->fConnected = true;
+ pTarget->fConfigured = true;
+ }
+ else if (hKey)
+ {
+ swprintf(aNameBuf, L"%s%d", VBOXWDDM_REG_DRV_DISPFLAGS_PREFIX, i);
+ Status = vboxWddmRegQueryValueDword(hKey, aNameBuf, &dwVal);
+ if (NT_SUCCESS(Status))
+ {
+ pTarget->fConnected = !!(dwVal & VBOXWDDM_CFG_DRVTARGET_CONNECTED);
+ pTarget->fConfigured = true;
+ }
+ else
+ {
+ WARN(("vboxWddmRegQueryValueDword failed, Status = 0x%x", Status));
+ pTarget->fConnected = false;
+ pTarget->fConfigured = false;
+ }
+ }
+ }
+
+ if (hKey)
+ {
+ NTSTATUS tmpStatus = ZwClose(hKey);
+ Assert(tmpStatus == STATUS_SUCCESS);
}
+ Status = STATUS_SUCCESS;
#ifdef VBOX_WDDM_WIN8
DXGK_DISPLAY_INFORMATION DisplayInfo;
Status = pDevExt->u.primary.DxgkInterface.DxgkCbAcquirePostDisplayOwnership(pDevExt->u.primary.DxgkInterface.DeviceHandle,
@@ -1181,6 +1125,8 @@ NTSTATUS DxgkDdiStartDevice(
WARN(("DxgkCbAcquirePostDisplayOwnership failed, Status 0x%x", Status));
}
#endif
+
+ VBoxWddmInitVideoModes(pDevExt);
}
else
{
@@ -1226,10 +1172,14 @@ NTSTATUS DxgkDdiStopDevice(
PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)MiniportDeviceContext;
NTSTATUS Status = STATUS_SUCCESS;
+ VBoxMpCrShgsmiTransportTerm(&pDevExt->CrHgsmiTransport);
+
VBoxWddmSlTerm(pDevExt);
vboxVideoCmTerm(&pDevExt->CmMgr);
+ vboxVideoCmTerm(&pDevExt->SeamlessCtxMgr);
+
/* do everything we did on DxgkDdiStartDevice in the reverse order */
#ifdef VBOX_WITH_VIDEOHWACCEL
vboxVhwaFree(pDevExt);
@@ -1347,7 +1297,148 @@ NTSTATUS DxgkDdiDispatchIoRequest(
return STATUS_SUCCESS;
}
-BOOLEAN DxgkDdiInterruptRoutine(
+
+BOOLEAN DxgkDdiInterruptRoutineNew(
+ IN CONST PVOID MiniportDeviceContext,
+ IN ULONG MessageNumber
+ )
+{
+// LOGF(("ENTER, context(0x%p), msg(0x%x)", MiniportDeviceContext, MessageNumber));
+
+ vboxVDbgBreakFv();
+
+ PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)MiniportDeviceContext;
+ BOOLEAN bOur = FALSE;
+ bool bNeedDpc = FALSE;
+ if (!VBoxCommonFromDeviceExt(pDevExt)->hostCtx.pfHostFlags) /* If HGSMI is enabled at all. */
+ {
+ WARN(("ISR called with hgsmi disabled!"));
+ return FALSE;
+ }
+
+ VBOXVTLIST CtlList;
+ vboxVtListInit(&CtlList);
+#ifdef VBOX_WITH_VIDEOHWACCEL
+ VBOXVTLIST VhwaCmdList;
+ vboxVtListInit(&VhwaCmdList);
+#endif
+
+ uint32_t flags = VBoxCommonFromDeviceExt(pDevExt)->hostCtx.pfHostFlags->u32HostFlags;
+ bOur = (flags & HGSMIHOSTFLAGS_IRQ);
+
+ if (bOur)
+ VBoxHGSMIClearIrq(&VBoxCommonFromDeviceExt(pDevExt)->hostCtx);
+
+ bNeedDpc |= VBoxCmdVbvaCheckCompletedIrq(pDevExt, &pDevExt->CmdVbva);
+
+ do {
+ if (flags & HGSMIHOSTFLAGS_GCOMMAND_COMPLETED)
+ {
+ /* read the command offset */
+ HGSMIOFFSET offCmd = VBoxVideoCmnPortReadUlong(VBoxCommonFromDeviceExt(pDevExt)->guestCtx.port);
+ if (offCmd == HGSMIOFFSET_VOID)
+ {
+ WARN(("void command offset!"));
+ continue;
+ }
+
+ uint16_t chInfo;
+ uint8_t *pvCmd = HGSMIBufferDataAndChInfoFromOffset (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx.Heap.area, offCmd, &chInfo);
+ if (!pvCmd)
+ {
+ WARN(("zero cmd"));
+ continue;
+ }
+
+ switch (chInfo)
+ {
+ case VBVA_CMDVBVA_CTL:
+ {
+ int rc = VBoxSHGSMICommandProcessCompletion (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, (VBOXSHGSMIHEADER*)pvCmd, TRUE /*bool bIrq*/ , &CtlList);
+ AssertRC(rc);
+ break;
+ }
+#ifdef VBOX_WITH_VIDEOHWACCEL
+ case VBVA_VHWA_CMD:
+ {
+ vboxVhwaPutList(&VhwaCmdList, (VBOXVHWACMD*)pvCmd);
+ break;
+ }
+#endif /* # ifdef VBOX_WITH_VIDEOHWACCEL */
+ default:
+ AssertBreakpoint();
+ }
+ }
+ else if (flags & HGSMIHOSTFLAGS_COMMANDS_PENDING)
+ {
+ AssertBreakpoint();
+ /* @todo: FIXME: implement !!! */
+ }
+ else
+ break;
+
+ flags = VBoxCommonFromDeviceExt(pDevExt)->hostCtx.pfHostFlags->u32HostFlags;
+
+ } while (1);
+
+ if (!vboxVtListIsEmpty(&CtlList))
+ {
+ vboxVtListCat(&pDevExt->CtlList, &CtlList);
+ bNeedDpc = TRUE;
+ ASMAtomicWriteU32(&pDevExt->fCompletingCommands, 1);
+ }
+
+ if (!vboxVtListIsEmpty(&VhwaCmdList))
+ {
+ vboxVtListCat(&pDevExt->VhwaCmdList, &VhwaCmdList);
+ bNeedDpc = TRUE;
+ ASMAtomicWriteU32(&pDevExt->fCompletingCommands, 1);
+ }
+
+ bNeedDpc |= !vboxVdmaDdiCmdIsCompletedListEmptyIsr(pDevExt);
+
+ if (bOur)
+ {
+#ifdef VBOX_VDMA_WITH_WATCHDOG
+ if (flags & HGSMIHOSTFLAGS_WATCHDOG)
+ {
+ Assert(0);
+ }
+#endif
+ if (flags & HGSMIHOSTFLAGS_VSYNC)
+ {
+ Assert(0);
+ DXGKARGCB_NOTIFY_INTERRUPT_DATA notify;
+ for (UINT i = 0; i < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
+ {
+ PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[i];
+ PVBOXWDDM_ALLOCATION pPrimary = pSource->pPrimaryAllocation;
+ if (pPrimary && pPrimary->AllocData.Addr.offVram != VBOXVIDEOOFFSET_VOID)
+ {
+ memset(&notify, 0, sizeof(DXGKARGCB_NOTIFY_INTERRUPT_DATA));
+ notify.InterruptType = DXGK_INTERRUPT_CRTC_VSYNC;
+ /* @todo: !!!this is not correct in case we want source[i]->target[i!=j] mapping */
+ notify.CrtcVsync.VidPnTargetId = i;
+ notify.CrtcVsync.PhysicalAddress.QuadPart = pPrimary->AllocData.Addr.offVram;
+ pDevExt->u.primary.DxgkInterface.DxgkCbNotifyInterrupt(pDevExt->u.primary.DxgkInterface.DeviceHandle, &notify);
+
+ bNeedDpc = TRUE;
+ }
+ }
+ }
+ }
+
+ if (pDevExt->bNotifyDxDpc)
+ bNeedDpc = TRUE;
+
+ if (bNeedDpc)
+ pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
+
+ return bOur;
+}
+
+
+static BOOLEAN DxgkDdiInterruptRoutineLegacy(
IN CONST PVOID MiniportDeviceContext,
IN ULONG MessageNumber
)
@@ -1377,6 +1468,10 @@ BOOLEAN DxgkDdiInterruptRoutine(
uint32_t flags = VBoxCommonFromDeviceExt(pDevExt)->hostCtx.pfHostFlags->u32HostFlags;
bOur = (flags & HGSMIHOSTFLAGS_IRQ);
+
+ if (bOur)
+ VBoxHGSMIClearIrq(&VBoxCommonFromDeviceExt(pDevExt)->hostCtx);
+
do
{
if (flags & HGSMIHOSTFLAGS_GCOMMAND_COMPLETED)
@@ -1508,7 +1603,6 @@ BOOLEAN DxgkDdiInterruptRoutine(
bNeedDpc = TRUE;
}
- VBoxHGSMIClearIrq(&VBoxCommonFromDeviceExt(pDevExt)->hostCtx);
#if 0 //def DEBUG_misha
/* this is not entirely correct since host may concurrently complete some commands and raise a new IRQ while we are here,
* still this allows to check that the host flags are correctly cleared after the ISR */
@@ -1552,22 +1646,73 @@ typedef struct VBOXWDDM_GETDPCDATA_CONTEXT
BOOLEAN vboxWddmGetDPCDataCallback(PVOID Context)
{
PVBOXWDDM_GETDPCDATA_CONTEXT pdc = (PVBOXWDDM_GETDPCDATA_CONTEXT)Context;
-
- vboxVtListDetach2List(&pdc->pDevExt->CtlList, &pdc->data.CtlList);
+ PVBOXMP_DEVEXT pDevExt = pdc->pDevExt;
+ vboxVtListDetach2List(&pDevExt->CtlList, &pdc->data.CtlList);
#ifdef VBOX_WITH_VDMA
- vboxVtListDetach2List(&pdc->pDevExt->DmaCmdList, &pdc->data.DmaCmdList);
+ vboxVtListDetach2List(&pDevExt->DmaCmdList, &pdc->data.DmaCmdList);
#endif
#ifdef VBOX_WITH_VIDEOHWACCEL
- vboxVtListDetach2List(&pdc->pDevExt->VhwaCmdList, &pdc->data.VhwaCmdList);
+ vboxVtListDetach2List(&pDevExt->VhwaCmdList, &pdc->data.VhwaCmdList);
#endif
- vboxVdmaDdiCmdGetCompletedListIsr(pdc->pDevExt, &pdc->data.CompletedDdiCmdQueue);
+ if (!pDevExt->fCmdVbvaEnabled)
+ vboxVdmaDdiCmdGetCompletedListIsr(pDevExt, &pdc->data.CompletedDdiCmdQueue);
+
+ pdc->data.bNotifyDpc = pDevExt->bNotifyDxDpc;
+ pDevExt->bNotifyDxDpc = FALSE;
+
+ ASMAtomicWriteU32(&pDevExt->fCompletingCommands, 0);
- pdc->data.bNotifyDpc = pdc->pDevExt->bNotifyDxDpc;
- pdc->pDevExt->bNotifyDxDpc = FALSE;
return TRUE;
}
-VOID DxgkDdiDpcRoutine(
+static VOID DxgkDdiDpcRoutineNew(
+ IN CONST PVOID MiniportDeviceContext
+ )
+{
+// LOGF(("ENTER, context(0x%p)", MiniportDeviceContext));
+
+ vboxVDbgBreakFv();
+
+ PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)MiniportDeviceContext;
+
+ pDevExt->u.primary.DxgkInterface.DxgkCbNotifyDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
+
+ if (ASMAtomicReadU32(&pDevExt->fCompletingCommands))
+ {
+ VBOXWDDM_GETDPCDATA_CONTEXT context = {0};
+ BOOLEAN bRet;
+
+ context.pDevExt = pDevExt;
+
+ /* get DPC data at IRQL */
+ NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbSynchronizeExecution(
+ pDevExt->u.primary.DxgkInterface.DeviceHandle,
+ vboxWddmGetDPCDataCallback,
+ &context,
+ 0, /* IN ULONG MessageNumber */
+ &bRet);
+ Assert(Status == STATUS_SUCCESS);
+
+ // if (context.data.bNotifyDpc)
+ pDevExt->u.primary.DxgkInterface.DxgkCbNotifyDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
+
+ if (!vboxVtListIsEmpty(&context.data.CtlList))
+ {
+ int rc = VBoxSHGSMICommandPostprocessCompletion (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, &context.data.CtlList);
+ AssertRC(rc);
+ }
+#ifdef VBOX_WITH_VIDEOHWACCEL
+ if (!vboxVtListIsEmpty(&context.data.VhwaCmdList))
+ {
+ vboxVhwaCompletionListProcess(pDevExt, &context.data.VhwaCmdList);
+ }
+#endif
+ }
+// LOGF(("LEAVE, context(0x%p)", MiniportDeviceContext));
+}
+
+
+static VOID DxgkDdiDpcRoutineLegacy(
IN CONST PVOID MiniportDeviceContext
)
{
@@ -1637,7 +1782,7 @@ NTSTATUS DxgkDdiQueryChildRelations(
{
ChildRelations[i].ChildDeviceType = TypeVideoOutput;
ChildRelations[i].ChildCapabilities.Type.VideoOutput.InterfaceTechnology = D3DKMDT_VOT_HD15; /* VGA */
- ChildRelations[i].ChildCapabilities.Type.VideoOutput.MonitorOrientationAwareness = D3DKMDT_MOA_INTERRUPTIBLE; /* ?? D3DKMDT_MOA_NONE*/
+ ChildRelations[i].ChildCapabilities.Type.VideoOutput.MonitorOrientationAwareness = D3DKMDT_MOA_NONE; //D3DKMDT_MOA_INTERRUPTIBLE; /* ?? D3DKMDT_MOA_NONE*/
ChildRelations[i].ChildCapabilities.Type.VideoOutput.SupportsSdtvModes = FALSE;
ChildRelations[i].ChildCapabilities.HpdAwareness = HpdAwarenessInterruptible; /* ?? HpdAwarenessAlwaysConnected; */
ChildRelations[i].AcpiUid = 0; /* */
@@ -1660,20 +1805,24 @@ NTSTATUS DxgkDdiQueryChildStatus(
LOGF(("ENTER, context(0x%x)", MiniportDeviceContext));
+ PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)MiniportDeviceContext;
+
NTSTATUS Status = STATUS_SUCCESS;
switch (ChildStatus->Type)
{
case StatusConnection:
- ChildStatus->HotPlug.Connected = TRUE;
+ {
LOGF(("StatusConnection"));
+ VBOXWDDM_TARGET *pTarget = &pDevExt->aTargets[ChildStatus->ChildUid];
+ ChildStatus->HotPlug.Connected = !!pTarget->fConnected;
break;
+ }
case StatusRotation:
- ChildStatus->Rotation.Angle = 0;
LOGF(("StatusRotation"));
+ ChildStatus->Rotation.Angle = 0;
break;
default:
- LOGREL(("ERROR: status type: %d", ChildStatus->Type));
- AssertBreakpoint();
+ WARN(("ERROR: status type: %d", ChildStatus->Type));
Status = STATUS_INVALID_PARAMETER;
break;
}
@@ -1763,7 +1912,7 @@ VOID DxgkDdiUnload(
VbglTerminate();
- VBoxWddmVrTerm();
+ VBoxVrTerm();
PRTLOGGER pLogger = RTLogRelSetDefaultInstance(NULL);
if (pLogger)
@@ -1953,12 +2102,12 @@ NTSTATUS APIENTRY DxgkDdiQueryAdapterInfo(
if (!g_VBoxDisplayOnly)
#endif
{
- Assert (pQueryAdapterInfo->OutputDataSize >= sizeof (VBOXWDDM_QI));
- if (pQueryAdapterInfo->OutputDataSize >= sizeof (VBOXWDDM_QI))
+ if (pQueryAdapterInfo->OutputDataSize == sizeof (VBOXWDDM_QI))
{
VBOXWDDM_QI * pQi = (VBOXWDDM_QI*)pQueryAdapterInfo->pOutputData;
memset (pQi, 0, sizeof (VBOXWDDM_QI));
pQi->u32Version = VBOXVIDEOIF_VERSION;
+ pQi->u32VBox3DCaps = VBoxMpCrGetHostCaps();
pQi->cInfos = VBoxCommonFromDeviceExt(pDevExt)->cDisplays;
#ifdef VBOX_WITH_VIDEOHWACCEL
for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
@@ -1969,7 +2118,7 @@ NTSTATUS APIENTRY DxgkDdiQueryAdapterInfo(
}
else
{
- LOGREL(("buffer too small"));
+ WARN(("incorrect buffer size %d, expected %d", pQueryAdapterInfo->OutputDataSize, sizeof (VBOXWDDM_QI)));
Status = STATUS_BUFFER_TOO_SMALL;
}
}
@@ -2133,8 +2282,6 @@ VOID vboxWddmAllocationCleanup(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAll
}
case VBOXWDDM_ALLOC_TYPE_UMD_HGSMI_BUFFER:
{
- if (pAllocation->pSynchEvent)
- ObDereferenceObject(pAllocation->pSynchEvent);
break;
}
default:
@@ -2237,6 +2384,7 @@ NTSTATUS vboxWddmAllocationCreate(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_RESOURCE pRe
{
pAllocation->fRcFlags = pAllocInfo->fFlags;
pAllocation->AllocData.SurfDesc = pAllocInfo->SurfDesc;
+ pAllocation->AllocData.hostID = pAllocInfo->hostID;
pAllocationInfo->Size = pAllocInfo->SurfDesc.cbSize;
@@ -2327,13 +2475,6 @@ NTSTATUS vboxWddmAllocationCreate(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_RESOURCE pRe
pAllocationInfo->Flags.CpuVisible = 1;
// pAllocationInfo->Flags.SynchronousPaging = 1;
pAllocationInfo->AllocationPriority = D3DDDI_ALLOCATIONPRIORITY_MAXIMUM;
- if (pAllocInfo->hSynch)
- {
- Status = ObReferenceObjectByHandle((HANDLE)pAllocInfo->hSynch, EVENT_MODIFY_STATE, *ExEventObjectType, UserMode,
- (PVOID*)&pAllocation->pSynchEvent,
- NULL);
- Assert(Status == STATUS_SUCCESS);
- }
break;
}
@@ -2673,9 +2814,59 @@ DxgkDdiReleaseSwizzlingRange(
return STATUS_SUCCESS;
}
-NTSTATUS
+static NTSTATUS
+APIENTRY
+DxgkDdiPatchNew(
+ CONST HANDLE hAdapter,
+ CONST DXGKARG_PATCH* pPatch)
+{
+ /* DxgkDdiPatch should be made pageable. */
+ PAGED_CODE();
+
+ LOGF(("ENTER, context(0x%x)", hAdapter));
+
+ vboxVDbgBreakFv();
+
+ uint8_t * pPrivateBuf = (uint8_t*)((uint8_t*)pPatch->pDmaBufferPrivateData + pPatch->DmaBufferPrivateDataSubmissionStartOffset);
+ UINT cbPatchBuff = pPatch->DmaBufferPrivateDataSubmissionEndOffset - pPatch->DmaBufferPrivateDataSubmissionStartOffset;
+
+ for (UINT i = pPatch->PatchLocationListSubmissionStart; i < pPatch->PatchLocationListSubmissionLength; ++i)
+ {
+ const D3DDDI_PATCHLOCATIONLIST* pPatchList = &pPatch->pPatchLocationList[i];
+ Assert(pPatchList->AllocationIndex < pPatch->AllocationListSize);
+ const DXGK_ALLOCATIONLIST *pAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
+ if (!pAllocationList->SegmentId)
+ {
+ WARN(("no segment id specified"));
+ continue;
+ }
+
+ if (pPatchList->PatchOffset == ~0UL)
+ {
+ /* this is a dummy patch request, ignore */
+ continue;
+ }
+
+ if (pPatchList->PatchOffset >= cbPatchBuff)
+ {
+ WARN(("pPatchList->PatchOffset(%d) >= cbPatchBuff(%d)", pPatchList->PatchOffset, cbPatchBuff));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ VBOXCMDVBVAOFFSET *poffVram = (VBOXCMDVBVAOFFSET*)(pPrivateBuf + pPatchList->PatchOffset);
+ Assert(pAllocationList->SegmentId);
+ Assert(!pAllocationList->PhysicalAddress.HighPart);
+ Assert(!(pAllocationList->PhysicalAddress.QuadPart & 0xfffUL)); /* <- just a check to ensure allocation offset does not go here */
+ *poffVram = pAllocationList->PhysicalAddress.LowPart + pPatchList->AllocationOffset;;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
APIENTRY
-DxgkDdiPatch(
+DxgkDdiPatchLegacy(
CONST HANDLE hAdapter,
CONST DXGKARG_PATCH* pPatch)
{
@@ -2815,7 +3006,7 @@ DxgkDdiPatch(
else if (pPatch->DmaBufferPrivateDataSubmissionEndOffset == pPatch->DmaBufferPrivateDataSubmissionStartOffset)
{
/* this is a NOP, just return success */
- WARN(("null data size, treating as NOP"));
+// LOG(("null data size, treating as NOP"));
return STATUS_SUCCESS;
}
else
@@ -2841,7 +3032,10 @@ typedef struct VBOXWDDM_CALL_ISR
static BOOLEAN vboxWddmCallIsrCb(PVOID Context)
{
PVBOXWDDM_CALL_ISR pdc = (PVBOXWDDM_CALL_ISR)Context;
- return DxgkDdiInterruptRoutine(pdc->pDevExt, pdc->MessageNumber);
+ PVBOXMP_DEVEXT pDevExt = pdc->pDevExt;
+ if (pDevExt->fCmdVbvaEnabled)
+ return DxgkDdiInterruptRoutineNew(pDevExt, pdc->MessageNumber);
+ return DxgkDdiInterruptRoutineLegacy(pDevExt, pdc->MessageNumber);
}
NTSTATUS vboxWddmCallIsr(PVBOXMP_DEVEXT pDevExt)
@@ -2860,54 +3054,6 @@ NTSTATUS vboxWddmCallIsr(PVBOXMP_DEVEXT pDevExt)
return Status;
}
-static NTSTATUS vboxWddmSubmitCmd(PVBOXMP_DEVEXT pDevExt, VBOXVDMAPIPE_CMD_DMACMD *pCmd)
-{
- NTSTATUS Status = vboxVdmaGgCmdDmaNotifySubmitted(pDevExt, pCmd);
- Assert(Status == STATUS_SUCCESS);
- if (Status == STATUS_SUCCESS)
- {
- NTSTATUS submStatus = vboxVdmaGgCmdSubmit(pDevExt, &pCmd->Hdr);
- Assert(submStatus == STATUS_SUCCESS);
- if (submStatus != STATUS_SUCCESS)
- {
- vboxVdmaGgCmdDmaNotifyCompleted(pDevExt, pCmd, DXGK_INTERRUPT_DMA_FAULTED);
- }
- }
- else
- {
- vboxVdmaGgCmdRelease(pDevExt, &pCmd->Hdr);
- }
- return Status;
-}
-
-static NTSTATUS vboxWddmSubmitBltCmd(PVBOXMP_DEVEXT pDevExt, VBOXWDDM_CONTEXT *pContext, UINT u32FenceId, PVBOXWDDM_DMA_PRIVATEDATA_BLT pBlt, VBOXVDMAPIPE_FLAGS_DMACMD fBltFlags)
-{
- NTSTATUS Status = STATUS_SUCCESS;
- PVBOXVDMAPIPE_CMD_DMACMD_BLT pBltCmd = (PVBOXVDMAPIPE_CMD_DMACMD_BLT)vboxVdmaGgCmdCreate(pDevExt, VBOXVDMAPIPE_CMD_TYPE_DMACMD, RT_OFFSETOF(VBOXVDMAPIPE_CMD_DMACMD_BLT, Blt.DstRects.UpdateRects.aRects[pBlt->Blt.DstRects.UpdateRects.cRects]));
- Assert(pBltCmd);
- if (pBltCmd)
- {
- VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pBlt->Blt.DstAlloc.srcId];
- vboxVdmaGgCmdDmaNotifyInit(&pBltCmd->Hdr, pContext->NodeOrdinal, u32FenceId, vboxVdmaGgDdiCmdRelease, pBltCmd);
- pBltCmd->Hdr.fFlags = fBltFlags;
- pBltCmd->Hdr.pContext = pContext;
- pBltCmd->Hdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_BLT;
- memcpy(&pBltCmd->Blt, &pBlt->Blt, RT_OFFSETOF(VBOXVDMA_BLT, DstRects.UpdateRects.aRects[pBlt->Blt.DstRects.UpdateRects.cRects]));
- Status = vboxWddmSubmitCmd(pDevExt, &pBltCmd->Hdr);
- if (Status != STATUS_SUCCESS)
- {
- WARN(("vboxWddmSubmitCmd failed, Status 0x%x", Status));
- Status = STATUS_SUCCESS;
- }
- vboxVdmaGgCmdRelease(pDevExt, &pBltCmd->Hdr.Hdr);
- }
- else
- {
- Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, u32FenceId, DXGK_INTERRUPT_DMA_FAULTED);
- }
- return Status;
-}
-
#ifdef VBOX_WITH_CRHGSMI
DECLCALLBACK(VOID) vboxWddmDmaCompleteChromiumCmd(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext)
{
@@ -2915,25 +3061,56 @@ DECLCALLBACK(VOID) vboxWddmDmaCompleteChromiumCmd(PVBOXMP_DEVEXT pDevExt, PVBOXV
PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHROMIUM_CMD);
UINT cBufs = pBody->cBuffers;
- for (UINT i = 0; i < cBufs; ++i)
+ vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);
+}
+#endif
+
+static NTSTATUS
+APIENTRY
+DxgkDdiSubmitCommandNew(
+ CONST HANDLE hAdapter,
+ CONST DXGKARG_SUBMITCOMMAND* pSubmitCommand)
+{
+ /* DxgkDdiSubmitCommand runs at dispatch, should not be pageable. */
+
+// LOGF(("ENTER, context(0x%x)", hAdapter));
+
+ vboxVDbgBreakFv();
+
+ PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
+#ifdef DEBUG
+ PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pSubmitCommand->hContext;
+ Assert(pContext);
+ Assert(pContext->pDevice);
+ Assert(pContext->pDevice->pAdapter == pDevExt);
+ Assert(!pSubmitCommand->DmaBufferSegmentId);
+#endif
+
+ /* the DMA command buffer is located in system RAM, the host will need to pick it from there */
+ //BufInfo.fFlags = 0; /* see VBOXVDMACBUF_FLAG_xx */
+ uint32_t cbCmd = pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset - pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset;
+ if (cbCmd < sizeof (VBOXCMDVBVA_HDR))
{
- VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[i];
- if (!pBufCmd->u32GuestData)
- {
- /* signal completion */
- PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pBufCmd->u64GuestData;
- if (pAlloc->pSynchEvent)
- KeSetEvent(pAlloc->pSynchEvent, 3, FALSE);
- }
+ WARN(("DmaBufferPrivateDataSubmissionEndOffset (%d) - DmaBufferPrivateDataSubmissionStartOffset (%d) < sizeof (VBOXCMDVBVA_HDR) (%d)",
+ pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset,
+ pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset,
+ sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR)));
+ return STATUS_INVALID_PARAMETER;
}
- vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);
+ VBOXCMDVBVA_HDR *pHdr = (VBOXCMDVBVA_HDR*)((uint8_t*)pSubmitCommand->pDmaBufferPrivateData + pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset);
+ pHdr->u32FenceID = pSubmitCommand->SubmissionFenceId;
+ int rc = VBoxCmdVbvaSubmit(pDevExt, &pDevExt->CmdVbva, pHdr, cbCmd);
+ if (RT_SUCCESS(rc))
+ return STATUS_SUCCESS;
+
+ WARN(("VBoxCmdVbvaSubmit failed rc %d", rc));
+ return STATUS_UNSUCCESSFUL;
}
-#endif
-NTSTATUS
+static NTSTATUS
APIENTRY
-DxgkDdiSubmitCommand(
+DxgkDdiSubmitCommandLegacy(
CONST HANDLE hAdapter,
CONST DXGKARG_SUBMITCOMMAND* pSubmitCommand)
{
@@ -2963,7 +3140,6 @@ DxgkDdiSubmitCommand(
}
else if (pSubmitCommand->DmaBufferPrivateDataSubmissionEndOffset == pSubmitCommand->DmaBufferPrivateDataSubmissionStartOffset)
{
- WARN(("null data size, treating as NOP"));
enmCmd = VBOXVDMACMD_TYPE_DMA_NOP;
}
else
@@ -2978,8 +3154,6 @@ DxgkDdiSubmitCommand(
if (pContext->enmType == VBOXWDDM_CONTEXT_TYPE_CUSTOM_2D)
vboxWddmModeRenderFromShadowDisableRegister(pDevExt, pContext);
- BOOLEAN fRenderFromSharedDisabled = pDevExt->fRenderToShadowDisabled;
-
switch (enmCmd)
{
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
@@ -2988,10 +3162,12 @@ DxgkDdiSubmitCommand(
PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY pS2P = (PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY)pPrivateDataBase;
VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pS2P->Shadow2Primary.VidPnSourceId];
PVBOXWDDM_ALLOCATION pSrcAlloc = pS2P->Shadow2Primary.ShadowAlloc.pAlloc;
- vboxWddmAddrSetVram(&pSrcAlloc->AllocData.Addr, pS2P->Shadow2Primary.ShadowAlloc.segmentIdAlloc, pS2P->Shadow2Primary.ShadowAlloc.offAlloc);
+ BOOLEAN fShadowChanged = vboxWddmAddrSetVram(&pSrcAlloc->AllocData.Addr, pS2P->Shadow2Primary.ShadowAlloc.segmentIdAlloc, pS2P->Shadow2Primary.ShadowAlloc.offAlloc);
+ if (fShadowChanged)
+ pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_LOCATION;
vboxWddmAssignShadow(pDevExt, pSource, pSrcAlloc, pS2P->Shadow2Primary.VidPnSourceId);
- fRenderFromSharedDisabled = vboxWddmModeRenderFromShadowCheckOnSubmitCommand(pDevExt, NULL);
- vboxWddmCheckUpdateFramebufferAddress(pDevExt, pSource);
+ vboxWddmModeRenderFromShadowCheckOnSubmitCommand(pDevExt, NULL);
+ vboxWddmGhDisplayCheckSetInfoFromSource(pDevExt, pSource);
if (pSrcAlloc->bVisible)
{
uint32_t cUnlockedVBVADisabled = ASMAtomicReadU32(&pDevExt->cUnlockedVBVADisabled);
@@ -3014,253 +3190,77 @@ DxgkDdiSubmitCommand(
PVBOXWDDM_DMA_PRIVATEDATA_BLT pBlt = (PVBOXWDDM_DMA_PRIVATEDATA_BLT)pPrivateData;
PVBOXWDDM_ALLOCATION pDstAlloc = pBlt->Blt.DstAlloc.pAlloc;
PVBOXWDDM_ALLOCATION pSrcAlloc = pBlt->Blt.SrcAlloc.pAlloc;
+ BOOLEAN fSrcChanged;
+ BOOLEAN fDstChanged;
- vboxWddmAddrSetVram(&pDstAlloc->AllocData.Addr, pBlt->Blt.DstAlloc.segmentIdAlloc, pBlt->Blt.DstAlloc.offAlloc);
- vboxWddmAddrSetVram(&pSrcAlloc->AllocData.Addr, pBlt->Blt.SrcAlloc.segmentIdAlloc, pBlt->Blt.SrcAlloc.offAlloc);
+ fDstChanged = vboxWddmAddrSetVram(&pDstAlloc->AllocData.Addr, pBlt->Blt.DstAlloc.segmentIdAlloc, pBlt->Blt.DstAlloc.offAlloc);
+ fSrcChanged = vboxWddmAddrSetVram(&pSrcAlloc->AllocData.Addr, pBlt->Blt.SrcAlloc.segmentIdAlloc, pBlt->Blt.SrcAlloc.offAlloc);
- uint32_t cContexts3D = ASMAtomicReadU32(&pDevExt->cContexts3D);
+ vboxWddmModeRenderFromShadowCheckOnSubmitCommand(pDevExt, NULL);
- VBOXVDMAPIPE_FLAGS_DMACMD fBltFlags;
- fBltFlags.Value = 0;
-
- if (pDstAlloc->bAssigned &&
- (pDstAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE
- || pDstAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE)
- )
+ if (VBOXWDDM_IS_REAL_FB_ALLOCATION(pDevExt, pDstAlloc))
{
VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pDstAlloc->AllocData.SurfDesc.VidPnSourceId];
- Assert(pDstAlloc->AllocData.SurfDesc.VidPnSourceId < VBOX_VIDEO_MAX_SCREENS);
- if (pSrcAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE)
- vboxWddmAssignShadow(pDevExt, pSource, pSrcAlloc, pDstAlloc->AllocData.SurfDesc.VidPnSourceId);
- fRenderFromSharedDisabled = vboxWddmModeRenderFromShadowCheckOnSubmitCommand(pDevExt, NULL);
- if(pContext->enmType != VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D
- || pDstAlloc->enmType !=VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC)
- vboxWddmCheckUpdateFramebufferAddress(pDevExt, pSource);
- }
- else if (pSrcAlloc->bAssigned &&
- (pSrcAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE
- || pSrcAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE)
- )
- {
- VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pDstAlloc->AllocData.SurfDesc.VidPnSourceId];
Assert(pDstAlloc->AllocData.SurfDesc.VidPnSourceId < VBOX_VIDEO_MAX_SCREENS);
-
- if (pDstAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE)
- vboxWddmAssignShadow(pDevExt, pSource, pDstAlloc, pSrcAlloc->AllocData.SurfDesc.VidPnSourceId);
- fRenderFromSharedDisabled = vboxWddmModeRenderFromShadowCheckOnSubmitCommand(pDevExt, NULL);
- if(pContext->enmType != VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D
- || pSrcAlloc->enmType !=VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC)
- vboxWddmCheckUpdateFramebufferAddress(pDevExt, pSource);
- }
-
- if (pContext->enmType != VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D && fRenderFromSharedDisabled)
- fBltFlags.fRealOp = 1;
-
- switch (pDstAlloc->enmType)
- {
- case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE:
- case VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC:
+#if 0
+ if (VBOXWDDM_IS_FB_ALLOCATION(pDevExt, pDstAlloc) && pDstAlloc->AllocData.hostID)
{
- if (pDstAlloc->bAssigned)
+ if (pSource->AllocData.hostID != pDstAlloc->AllocData.hostID)
{
-// Assert(pSource->pPrimaryAllocation == pDstAlloc);
-
- switch (pSrcAlloc->enmType)
- {
- case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
- {
- fBltFlags.fVisibleRegions = !!cContexts3D;
- Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_SYSTEM);
- VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pDstAlloc->AllocData.SurfDesc.VidPnSourceId];
- Assert(pDstAlloc->AllocData.SurfDesc.VidPnSourceId < VBOX_VIDEO_MAX_SCREENS);
-
- if (!fRenderFromSharedDisabled && pSource->bVisible)
- {
- RECT rect;
- if (pBlt->Blt.DstRects.UpdateRects.cRects)
- {
- rect = pBlt->Blt.DstRects.UpdateRects.aRects[0];
- for (UINT i = 1; i < pBlt->Blt.DstRects.UpdateRects.cRects; ++i)
- {
- vboxWddmRectUnited(&rect, &rect, &pBlt->Blt.DstRects.UpdateRects.aRects[i]);
- }
- }
- else
- rect = pBlt->Blt.DstRects.ContextRect;
-
- uint32_t cUnlockedVBVADisabled = ASMAtomicReadU32(&pDevExt->cUnlockedVBVADisabled);
- if (!cUnlockedVBVADisabled)
- {
- VBOXVBVA_OP(ReportDirtyRect, pDevExt, pSource, &rect);
- }
- else
- {
- VBOXVBVA_OP_WITHLOCK_ATDPC(ReportDirtyRect, pDevExt, pSource, &rect);
- }
- }
-
- break;
- }
- case VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC:
- {
- if(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D)
- {
- Assert(pSrcAlloc->fRcFlags.RenderTarget);
- if (pSrcAlloc->fRcFlags.RenderTarget)
- fBltFlags.fVisibleRegions = 1;
- }
- break;
- }
- default:
- {
- AssertBreakpoint();
- break;
- }
- }
+ pSource->AllocData.hostID = pDstAlloc->AllocData.hostID;
+ fDstChanged = TRUE;
}
- break;
- }
- case VBOXWDDM_ALLOC_TYPE_STD_STAGINGSURFACE:
- {
-// Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D);
- Assert(pSrcAlloc->enmType == VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC);
- Assert(pSrcAlloc->fRcFlags.RenderTarget);
- Assert(vboxWddmRectIsEqual(&pBlt->Blt.SrcRect, &pBlt->Blt.DstRects.ContextRect));
- Assert(pBlt->Blt.DstRects.UpdateRects.cRects == 1);
- Assert(vboxWddmRectIsEqual(&pBlt->Blt.SrcRect, pBlt->Blt.DstRects.UpdateRects.aRects));
- break;
+ if (fDstChanged)
+ pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_LOCATION;
}
- case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
+ else
+#endif
+ if (pSrcAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE)
{
- Assert(pSrcAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE);
- Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_SYSTEM);
- break;
+ if (fSrcChanged)
+ pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_LOCATION;
+
+ vboxWddmAssignShadow(pDevExt, pSource, pSrcAlloc, pDstAlloc->AllocData.SurfDesc.VidPnSourceId);
+ vboxWddmGhDisplayCheckSetInfoFromSource(pDevExt, pSource);
}
- default:
- AssertBreakpoint();
- break;
- }
- if (fBltFlags.Value)
- {
- Status = vboxWddmSubmitBltCmd(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, pBlt, fBltFlags);
- }
- else
- {
- Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_COMPLETED);
+ Assert(pSource->u8SyncState == VBOXWDDM_HGSYNC_F_SYNCED_ALL || pDevExt->aTargets[pDstAlloc->AllocData.SurfDesc.VidPnSourceId].fStateSyncPening);
}
- break;
- }
- case VBOXVDMACMD_TYPE_CHROMIUM_CMD:
- {
-#ifdef VBOX_WITH_CRHGSMI
- VBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD *pChromiumCmd = (VBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD*)pPrivateDataBase;
- UINT cbCmd = VBOXVDMACMD_SIZE_FROMBODYSIZE(RT_OFFSETOF(VBOXVDMACMD_CHROMIUM_CMD, aBuffers[pChromiumCmd->Base.u32CmdReserved]));
- PVBOXVDMACBUF_DR pDr = vboxVdmaCBufDrCreate (&pDevExt->u.primary.Vdma, cbCmd);
- if (!pDr)
- {
- /* @todo: try flushing.. */
- LOGREL(("vboxVdmaCBufDrCreate returned NULL"));
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- // vboxVdmaCBufDrCreate zero initializes the pDr
- pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR;
- pDr->cbBuf = cbCmd;
- pDr->rc = VERR_NOT_IMPLEMENTED;
-
- PVBOXVDMACMD pHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
- pHdr->enmType = VBOXVDMACMD_TYPE_CHROMIUM_CMD;
- pHdr->u32CmdSpecific = 0;
- VBOXVDMACMD_CHROMIUM_CMD *pBody = VBOXVDMACMD_BODY(pHdr, VBOXVDMACMD_CHROMIUM_CMD);
- pBody->cBuffers = pChromiumCmd->Base.u32CmdReserved;
- for (UINT i = 0; i < pChromiumCmd->Base.u32CmdReserved; ++i)
- {
- VBOXVDMACMD_CHROMIUM_BUFFER *pBufCmd = &pBody->aBuffers[i];
- VBOXWDDM_UHGSMI_BUFFER_SUBMIT_INFO *pBufInfo = &pChromiumCmd->aBufInfos[i];
-
- pBufCmd->offBuffer = pBufInfo->Alloc.offAlloc;
- pBufCmd->cbBuffer = pBufInfo->cbData;
- pBufCmd->u32GuestData = pBufInfo->bDoNotSignalCompletion;
- pBufCmd->u64GuestData = (uint64_t)pBufInfo->Alloc.pAlloc;
- }
+ Status = vboxVdmaProcessBltCmd(pDevExt, pContext, pBlt);
+ if (!NT_SUCCESS(Status))
+ WARN(("vboxVdmaProcessBltCmd failed, Status 0x%x", Status));
- PVBOXVDMADDI_CMD pDdiCmd = VBOXVDMADDI_CMD_FROM_BUF_DR(pDr);
- vboxVdmaDdiCmdInit(pDdiCmd, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, vboxWddmDmaCompleteChromiumCmd, pDr);
- NTSTATUS Status = vboxVdmaDdiCmdSubmitted(pDevExt, pDdiCmd);
- Assert(Status == STATUS_SUCCESS);
- if (Status == STATUS_SUCCESS)
- {
- int rc = vboxVdmaCBufDrSubmit(pDevExt, &pDevExt->u.primary.Vdma, pDr);
- Assert(rc == VINF_SUCCESS);
- }
- else
- {
- vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDr);
- }
-#else
- Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_COMPLETED);
- Assert(Status == STATUS_SUCCESS);
-#endif
+ Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId,
+ NT_SUCCESS(Status) ? DXGK_INTERRUPT_DMA_COMPLETED : DXGK_INTERRUPT_DMA_FAULTED);
break;
}
case VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP:
{
VBOXWDDM_DMA_PRIVATEDATA_FLIP *pFlip = (VBOXWDDM_DMA_PRIVATEDATA_FLIP*)pPrivateDataBase;
- vboxWddmAddrSetVram(&pFlip->Flip.Alloc.pAlloc->AllocData.Addr, pFlip->Flip.Alloc.segmentIdAlloc, pFlip->Flip.Alloc.offAlloc);
- PVBOXVDMAPIPE_CMD_DMACMD_FLIP pFlipCmd = (PVBOXVDMAPIPE_CMD_DMACMD_FLIP)vboxVdmaGgCmdCreate(pDevExt,
- VBOXVDMAPIPE_CMD_TYPE_DMACMD, sizeof (VBOXVDMAPIPE_CMD_DMACMD_FLIP));
- Assert(pFlipCmd);
- if (pFlipCmd)
- {
- VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pFlip->Flip.Alloc.srcId];
- vboxVdmaGgCmdDmaNotifyInit(&pFlipCmd->Hdr, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, vboxVdmaGgDdiCmdRelease, pFlipCmd);
- pFlipCmd->Hdr.fFlags.Value = 0;
- pFlipCmd->Hdr.fFlags.fVisibleRegions = 1;
- pFlipCmd->Hdr.pContext = pContext;
- pFlipCmd->Hdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP;
- memcpy(&pFlipCmd->Flip, &pFlip->Flip, sizeof (pFlipCmd->Flip));
- Status = vboxWddmSubmitCmd(pDevExt, &pFlipCmd->Hdr);
- if (Status != STATUS_SUCCESS)
- WARN(("vboxWddmSubmitCmd failed, Status 0x%x", Status));
- vboxVdmaGgCmdRelease(pDevExt, &pFlipCmd->Hdr.Hdr);
- }
- else
- {
- Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_FAULTED);
- Assert(Status == STATUS_SUCCESS);
- }
+ PVBOXWDDM_ALLOCATION pAlloc = pFlip->Flip.Alloc.pAlloc;
+ VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pAlloc->AllocData.SurfDesc.VidPnSourceId];
+ vboxWddmAddrSetVram(&pAlloc->AllocData.Addr, pFlip->Flip.Alloc.segmentIdAlloc, pFlip->Flip.Alloc.offAlloc);
+ vboxWddmAssignPrimary(pDevExt, pSource, pAlloc, pAlloc->AllocData.SurfDesc.VidPnSourceId);
+ vboxWddmGhDisplayCheckSetInfoFromSource(pDevExt, pSource);
+
+ Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId,
+ NT_SUCCESS(Status) ? DXGK_INTERRUPT_DMA_COMPLETED : DXGK_INTERRUPT_DMA_FAULTED);
break;
}
case VBOXVDMACMD_TYPE_DMA_PRESENT_CLRFILL:
{
PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL pCF = (PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL)pPrivateDataBase;
vboxWddmAddrSetVram(&pCF->ClrFill.Alloc.pAlloc->AllocData.Addr, pCF->ClrFill.Alloc.segmentIdAlloc, pCF->ClrFill.Alloc.offAlloc);
- PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL pCFCmd = (PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL)vboxVdmaGgCmdCreate(pDevExt,
- VBOXVDMAPIPE_CMD_TYPE_DMACMD, RT_OFFSETOF(VBOXVDMAPIPE_CMD_DMACMD_CLRFILL, ClrFill.Rects.aRects[pCF->ClrFill.Rects.cRects]));
- Assert(pCFCmd);
- if (pCFCmd)
- {
- vboxVdmaGgCmdDmaNotifyInit(&pCFCmd->Hdr, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, vboxVdmaGgDdiCmdRelease, pCFCmd);
- pCFCmd->Hdr.fFlags.Value = 0;
- pCFCmd->Hdr.fFlags.fRealOp = 1;
- pCFCmd->Hdr.pContext = pContext;
- pCFCmd->Hdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_CLRFILL;
- memcpy(&pCFCmd->ClrFill, &pCF->ClrFill, RT_OFFSETOF(VBOXVDMA_CLRFILL, Rects.aRects[pCF->ClrFill.Rects.cRects]));
- Status = vboxWddmSubmitCmd(pDevExt, &pCFCmd->Hdr);
- if (Status != STATUS_SUCCESS)
- WARN(("vboxWddmSubmitCmd failed, Status 0x%x", Status));
- vboxVdmaGgCmdRelease(pDevExt, &pCFCmd->Hdr.Hdr);
- }
- else
- {
- Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_FAULTED);
- Assert(Status == STATUS_SUCCESS);
- }
+ Status = vboxVdmaProcessClrFillCmd(pDevExt, pContext, pCF);
+ if (!NT_SUCCESS(Status))
+ WARN(("vboxVdmaProcessClrFillCmd failed, Status 0x%x", Status));
+ Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId,
+ NT_SUCCESS(Status) ? DXGK_INTERRUPT_DMA_COMPLETED : DXGK_INTERRUPT_DMA_FAULTED);
break;
}
case VBOXVDMACMD_TYPE_DMA_NOP:
@@ -3302,9 +3302,27 @@ DxgkDdiSubmitCommand(
return Status;
}
-NTSTATUS
+static NTSTATUS
APIENTRY
-DxgkDdiPreemptCommand(
+DxgkDdiPreemptCommandNew(
+ CONST HANDLE hAdapter,
+ CONST DXGKARG_PREEMPTCOMMAND* pPreemptCommand)
+{
+ LOGF(("ENTER, hAdapter(0x%x)", hAdapter));
+
+ PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
+
+ VBoxCmdVbvaPreempt(pDevExt, &pDevExt->CmdVbva, pPreemptCommand->PreemptionFenceId);
+
+ LOGF(("LEAVE, hAdapter(0x%x)", hAdapter));
+
+ return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
+APIENTRY
+DxgkDdiPreemptCommandLegacy(
CONST HANDLE hAdapter,
CONST DXGKARG_PREEMPTCOMMAND* pPreemptCommand)
{
@@ -3318,103 +3336,159 @@ DxgkDdiPreemptCommand(
return STATUS_SUCCESS;
}
-#if 0
-static uint32_t vboxWddmSysMemElBuild(PVBOXVDMACMD_SYSMEMEL pEl, PMDL pMdl, uint32_t iPfn, uint32_t cPages, uint32_t cbBuffer, uint32_t *pcPagesRemaining)
-{
- uint32_t cbInitialBuffer = cbBuffer;
- if (cbBuf >= sizeof (*pEl))
- {
- PFN_NUMBER cur = MmGetMdlPfnArray(pMdl)[iPfn];
- uint32_t cbEl = sizeof (*pEl);
- uint32_t cBufs = 1;
- pEl->phBuf[0] = (cur << 12);
- --cPages;
- cbBuffer -= sizeof (*pEl);
- bool bArrayMode = false;
- while (cPages)
- {
- PFN_NUMBER next = MmGetMdlPfnArray(pMdl)[iPfn+cBufs];
- if (!bArrayMode)
+/*
+ * DxgkDdiBuildPagingBuffer
+ */
+static NTSTATUS
+APIENTRY
+DxgkDdiBuildPagingBufferNew(
+ CONST HANDLE hAdapter,
+ DXGKARG_BUILDPAGINGBUFFER* pBuildPagingBuffer)
+{
+ /* DxgkDdiBuildPagingBuffer should be made pageable. */
+ PAGED_CODE();
+
+ vboxVDbgBreakFv();
+
+ PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
+ uint32_t cbBuffer = 0, cbPrivateData = 0;
+
+ LOGF(("ENTER, context(0x%x)", hAdapter));
+
+ /* paging buffer transfer is nop for hostID allocations */
+ if (pBuildPagingBuffer->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_HDR))
+ {
+ WARN(("pBuildPagingBuffer->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_HDR (%d)", pBuildPagingBuffer->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_HDR)));
+ /* @todo: can this actually happen? what status to return? */
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ switch (pBuildPagingBuffer->Operation)
+ {
+ case DXGK_OPERATION_TRANSFER:
+ {
+ VBOXCMDVBVA_HDR *pHdr = (VBOXCMDVBVA_HDR*)pBuildPagingBuffer->pDmaBuffer;
+ pHdr->u8Flags = 0;
+ pHdr->u8State = VBOXCMDVBVA_STATE_SUBMITTED;
+ /* sanity */
+ pHdr->u32FenceID = 0;
+
+ if ((!pBuildPagingBuffer->Transfer.Source.SegmentId) == (!pBuildPagingBuffer->Transfer.Destination.SegmentId))
{
- if (next == cur+1)
- {
- cur = next;
- ++cBufs;
- --cPages;
- }
- else if (cBufs > 1)
- {
- break;
- }
- else
- {
- bArrayMode = true;
- }
+ WARN(("we only support RAM <-> VRAM moves, Src Seg(%d), Dst Seg(%d)", pBuildPagingBuffer->Transfer.Source.SegmentId, pBuildPagingBuffer->Transfer.Destination.SegmentId));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pBuildPagingBuffer->Transfer.hAllocation;
+ if (!pAlloc)
+ {
+ WARN(("allocation is null"));
+ return STATUS_INVALID_PARAMETER;
}
- /* array mode */
- if (cbBuffer < sizeof (pEl->phBuf[0]))
+ if (pAlloc->AllocData.hostID)
{
+ pHdr->u8OpCode = VBOXCMDVBVA_OPTYPE_NOPCMD;
+ cbBuffer = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
+ cbPrivateData = sizeof (*pHdr);
break;
}
- pEl->phBuf[cBufs] = (next << 12);
- cbBuffer -= sizeof (pEl->phBuf[0]);
- ++cBufs;
- --cPages;
- }
+ if (pBuildPagingBuffer->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_PAGING_TRANSFER))
+ {
+ WARN(("pBuildPagingBuffer->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_PAGING_TRANSFER (%d)", pBuildPagingBuffer->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_PAGING_TRANSFER)));
+ /* @todo: can this actually happen? what status to return? */
+ return STATUS_INVALID_PARAMETER;
+ }
- pEl->cPages = cPages;
- if (bArrayMode)
- pEl->fFlags = VBOXVDMACMD_SYSMEMEL_F_PAGELIST;
- else
- pEl->fFlags = 0;
- }
- else
- {
- Assert(0);
- }
+ VBOXCMDVBVA_PAGING_TRANSFER *pPaging = (VBOXCMDVBVA_PAGING_TRANSFER*)pBuildPagingBuffer->pDmaBuffer;
+ pPaging->Hdr.u8OpCode = VBOXCMDVBVA_OPTYPE_PAGING_TRANSFER;
- *pcPagesRemaining = cPages;
- return cbInitialBuffer - cbBuffer;
-}
+ PMDL pMdl;
+ uint32_t offVRAM;
+ BOOLEAN fIn;
-static uint32_t vboxWddmBpbTransferVRamSysBuildEls(PVBOXVDMACMD_DMA_BPB_TRANSFER_VRAMSYS pCmd, PMDL pMdl, uint32_t iPfn, uint32_t cPages, uint32_t cbBuffer, uint32_t *pcPagesRemaining)
-{
- uint32_t cInitPages = cPages;
- uint32_t cbBufferUsed = vboxWddmSysMemElBuild(&pCmd->FirstEl, pMdl, iPfn, cPages, cbBuffer, &cPages);
- if (cbBufferUsed)
- {
- uint32_t cEls = 1;
- PVBOXVDMACMD_SYSMEMEL pEl = &pCmd->FirstEl;
- while (cPages)
- {
- PVBOXVDMACMD_SYSMEMEL pEl = VBOXVDMACMD_SYSMEMEL_NEXT(pEl);
- cbBufferUsed = vboxWddmSysMemElBuild(pEl, pMdl, iPfn + cInitPages - cPages, cPages, cbBuffer - cbBufferUsed, &cPages);
- if (cbBufferUsed)
+ if (pBuildPagingBuffer->Transfer.Source.SegmentId)
{
- ++cEls;
+ Assert(!pBuildPagingBuffer->Transfer.Destination.SegmentId);
+ Assert(!pBuildPagingBuffer->Transfer.Source.SegmentAddress.HighPart);
+ offVRAM = pBuildPagingBuffer->Transfer.Source.SegmentAddress.LowPart;
+ pMdl = pBuildPagingBuffer->Transfer.Destination.pMdl;
+ fIn = FALSE;
}
else
- break;
+ {
+ Assert(pBuildPagingBuffer->Transfer.Destination.SegmentId);
+ Assert(!pBuildPagingBuffer->Transfer.Source.SegmentId);
+ Assert(!pBuildPagingBuffer->Transfer.Destination.SegmentAddress.HighPart);
+ offVRAM = pBuildPagingBuffer->Transfer.Destination.SegmentAddress.LowPart;
+ pMdl = pBuildPagingBuffer->Transfer.Source.pMdl;
+ fIn = TRUE;
+ }
+
+ uint32_t cPages = (uint32_t)((pBuildPagingBuffer->Transfer.TransferSize + 0xfff) >> PAGE_SHIFT);
+ uint32_t cTotalPages = cPages;
+ cPages -= pBuildPagingBuffer->MultipassOffset;
+ uint32_t iFirstPage = pBuildPagingBuffer->Transfer.MdlOffset + pBuildPagingBuffer->MultipassOffset;
+ uint32_t cPagesWritten;
+ offVRAM += pBuildPagingBuffer->Transfer.TransferOffset + pBuildPagingBuffer->MultipassOffset;
+
+ pPaging->Alloc.u.offVRAM = offVRAM;
+ if (fIn)
+ pPaging->Hdr.u8Flags |= VBOXCMDVBVA_OPF_PAGING_TRANSFER_IN;
+ cbPrivateData = VBoxCVDdiPTransferVRamSysBuildEls(pPaging, pMdl, iFirstPage, cPages, pBuildPagingBuffer->DmaBufferPrivateDataSize, &cPagesWritten);
+ if (cPagesWritten != cPages)
+ pBuildPagingBuffer->MultipassOffset += cPagesWritten;
+ else
+ pBuildPagingBuffer->MultipassOffset = 0;
+
+ cbBuffer = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
+ break;
+ }
+ case DXGK_OPERATION_FILL:
+ {
+ Assert(pBuildPagingBuffer->Fill.FillPattern == 0);
+ PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pBuildPagingBuffer->Fill.hAllocation;
+ if (!pAlloc)
+ {
+ WARN(("allocation is null"));
+ return STATUS_INVALID_PARAMETER;
+ }
+ /** @todo: add necessary bits */
+ WARN(("Impl!"));
+ break;
+ }
+ case DXGK_OPERATION_DISCARD_CONTENT:
+ {
+ PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pBuildPagingBuffer->DiscardContent.hAllocation;
+ if (!pAlloc)
+ {
+ WARN(("allocation is null"));
+ return STATUS_INVALID_PARAMETER;
+ }
+ break;
+ }
+ default:
+ {
+ WARN(("unsupported op (%d)", pBuildPagingBuffer->Operation));
+ break;
}
}
- else
- {
- Assert(0);
- }
- pCmd->cTransferPages = (cInitPages - cPages);
- *pcPagesRemaining = cPages;
- return cbBufferUsed;
+ pBuildPagingBuffer->pDmaBuffer = ((uint8_t*)pBuildPagingBuffer->pDmaBuffer) + cbBuffer;
+ pBuildPagingBuffer->pDmaBufferPrivateData = ((uint8_t*)pBuildPagingBuffer->pDmaBufferPrivateData) + cbPrivateData;
+
+ LOGF(("LEAVE, context(0x%x)", hAdapter));
+
+ if (pBuildPagingBuffer->MultipassOffset)
+ return STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
+ return STATUS_SUCCESS;
}
-#endif
-/*
- * DxgkDdiBuildPagingBuffer
- */
-NTSTATUS
+
+
+static NTSTATUS
APIENTRY
-DxgkDdiBuildPagingBuffer(
+DxgkDdiBuildPagingBufferLegacy(
CONST HANDLE hAdapter,
DXGKARG_BUILDPAGINGBUFFER* pBuildPagingBuffer)
{
@@ -3428,11 +3502,14 @@ DxgkDdiBuildPagingBuffer(
LOGF(("ENTER, context(0x%x)", hAdapter));
+ uint32_t cbCmdDma = 0;
+
/* @todo: */
switch (pBuildPagingBuffer->Operation)
{
case DXGK_OPERATION_TRANSFER:
{
+ cbCmdDma = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
#ifdef VBOX_WITH_VDMA
#if 0
if ((!pBuildPagingBuffer->Transfer.Source.SegmentId) != (!pBuildPagingBuffer->Transfer.Destination.SegmentId))
@@ -3583,6 +3660,7 @@ DxgkDdiBuildPagingBuffer(
}
case DXGK_OPERATION_FILL:
{
+ cbCmdDma = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
Assert(pBuildPagingBuffer->Fill.FillPattern == 0);
PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pBuildPagingBuffer->Fill.hAllocation;
// pBuildPagingBuffer->pDmaBuffer = (uint8_t*)pBuildPagingBuffer->pDmaBuffer + VBOXVDMACMD_SIZE(VBOXVDMACMD_DMA_BPB_FILL);
@@ -3595,12 +3673,16 @@ DxgkDdiBuildPagingBuffer(
}
default:
{
- LOGREL(("unsupported op (%d)", pBuildPagingBuffer->Operation));
- AssertBreakpoint();
+ WARN(("unsupported op (%d)", pBuildPagingBuffer->Operation));
break;
}
}
+ if (cbCmdDma)
+ {
+ pBuildPagingBuffer->pDmaBuffer = ((uint8_t*)pBuildPagingBuffer->pDmaBuffer) + cbCmdDma;
+ }
+
LOGF(("LEAVE, context(0x%x)", hAdapter));
return Status;
@@ -3929,6 +4011,12 @@ DxgkDdiEscape(
#ifdef VBOX_WITH_CRHGSMI
case VBOXESC_UHGSMI_SUBMIT:
{
+ if (pDevExt->fCmdVbvaEnabled)
+ {
+ WARN(("VBOXESC_UHGSMI_SUBMIT not supported for CmdVbva mode"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
/* submit VBOXUHGSMI command */
PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
PVBOXDISPIFESCAPE_UHGSMI_SUBMIT pSubmit = (PVBOXDISPIFESCAPE_UHGSMI_SUBMIT)pEscapeHdr;
@@ -3949,6 +4037,13 @@ DxgkDdiEscape(
case VBOXESC_UHGSMI_ALLOCATE:
{
/* allocate VBOXUHGSMI buffer */
+ if (pDevExt->fCmdVbvaEnabled)
+ {
+ WARN(("VBOXESC_UHGSMI_ALLOCATE not supported for CmdVbva mode"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
PVBOXDISPIFESCAPE_UHGSMI_ALLOCATE pAlocate = (PVBOXDISPIFESCAPE_UHGSMI_ALLOCATE)pEscapeHdr;
Assert(pEscape->PrivateDriverDataSize == sizeof (VBOXDISPIFESCAPE_UHGSMI_ALLOCATE));
@@ -3965,6 +4060,12 @@ DxgkDdiEscape(
case VBOXESC_UHGSMI_DEALLOCATE:
{
+ if (pDevExt->fCmdVbvaEnabled)
+ {
+ WARN(("VBOXESC_UHGSMI_DEALLOCATE not supported for CmdVbva mode"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
/* deallocate VBOXUHGSMI buffer */
PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
PVBOXDISPIFESCAPE_UHGSMI_DEALLOCATE pDealocate = (PVBOXDISPIFESCAPE_UHGSMI_DEALLOCATE)pEscapeHdr;
@@ -3982,14 +4083,29 @@ DxgkDdiEscape(
case VBOXESC_GETVBOXVIDEOCMCMD:
{
+ if (pDevExt->fCmdVbvaEnabled || pDevExt->fTexPresentEnabled)
+ {
+ WARN(("VBOXESC_GETVBOXVIDEOCMCMD not supported for CmdVbva or TexPresent mode"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
/* get the list of r0->r3 commands (d3d window visible regions reporting )*/
PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pRegions = (PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD)pEscapeHdr;
Assert(pEscape->PrivateDriverDataSize >= sizeof (VBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD));
if (pEscape->PrivateDriverDataSize >= sizeof (VBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD))
{
- Status = vboxVideoCmEscape(&pContext->CmContext, pRegions, pEscape->PrivateDriverDataSize);
- Assert(Status == STATUS_SUCCESS);
+ if (pContext->enmType == VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D)
+ {
+ Status = vboxVideoCmEscape(&pContext->CmContext, pRegions, pEscape->PrivateDriverDataSize);
+ Assert(Status == STATUS_SUCCESS);
+ }
+ else
+ {
+ WARN(("VBOXESC_GETVBOXVIDEOCMCMD recieved invalid context type %d", pContext->enmType));
+ Status = STATUS_INVALID_PARAMETER;
+ }
}
else
Status = STATUS_BUFFER_TOO_SMALL;
@@ -3999,6 +4115,13 @@ DxgkDdiEscape(
case VBOXESC_CRHGSMICTLCON_CALL:
{
+ if (pDevExt->fCmdVbvaEnabled)
+ {
+ WARN(("VBOXESC_CRHGSMICTLCON_CALL not supported for CmdVbva mode"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
PVBOXDISPIFESCAPE_CRHGSMICTLCON_CALL pCall = (PVBOXDISPIFESCAPE_CRHGSMICTLCON_CALL)pEscapeHdr;
if (pEscape->PrivateDriverDataSize >= sizeof (*pCall))
@@ -4006,13 +4129,11 @@ DxgkDdiEscape(
/* this is true due to the above condition */
Assert(pEscape->PrivateDriverDataSize > RT_OFFSETOF(VBOXDISPIFESCAPE_CRHGSMICTLCON_CALL, CallInfo));
int rc = VBoxMpCrCtlConCallUserData(&pDevExt->CrCtlCon, &pCall->CallInfo, pEscape->PrivateDriverDataSize - RT_OFFSETOF(VBOXDISPIFESCAPE_CRHGSMICTLCON_CALL, CallInfo));
- if (RT_SUCCESS(rc))
- Status = STATUS_SUCCESS;
- else
- {
+ pEscapeHdr->u32CmdSpecific = (uint32_t)rc;
+ Status = STATUS_SUCCESS; /* <- always return success here, otherwise the private data buffer modifications
+ * i.e. rc status stored in u32CmdSpecific will not be copied to user mode */
+ if (!RT_SUCCESS(rc))
WARN(("VBoxMpCrUmCtlConCall failed, rc(%d)", rc));
- Status = STATUS_UNSUCCESSFUL;
- }
}
else
{
@@ -4042,6 +4163,22 @@ DxgkDdiEscape(
case VBOXESC_SETVISIBLEREGION:
{
+ PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
+#ifdef VBOX_DISPIF_WITH_OPCONTEXT
+ if (!pContext)
+ {
+ WARN(("VBOXESC_SETVISIBLEREGION no context supplied!"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if (pContext->enmType != VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_SEAMLESS)
+ {
+ WARN(("VBOXESC_SETVISIBLEREGION invalid context supplied %d!", pContext->enmType));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+#endif
/* visible regions for seamless */
LPRGNDATA lpRgnData = VBOXDISPIFESCAPE_DATA(pEscapeHdr, RGNDATA);
uint32_t cbData = VBOXDISPIFESCAPE_DATA_SIZE(pEscape->PrivateDriverDataSize);
@@ -4080,22 +4217,23 @@ DxgkDdiEscape(
rc = VbglGRPerform (&req->header);
AssertRC(rc);
- if (!RT_SUCCESS(rc))
+ if (RT_SUCCESS(rc))
+ Status = STATUS_SUCCESS;
+ else
{
- LOGREL(("VbglGRPerform failed rc (%d)", rc));
+ WARN(("VbglGRPerform failed rc (%d)", rc));
Status = STATUS_UNSUCCESSFUL;
}
}
else
{
- LOGREL(("VbglGRAlloc failed rc (%d)", rc));
+ WARN(("VbglGRAlloc failed rc (%d)", rc));
Status = STATUS_UNSUCCESSFUL;
}
}
else
{
- LOGREL(("VBOXESC_SETVISIBLEREGION: incorrect buffer size (%d), reported count (%d)", cbRects, lpRgnData->rdh.nCount));
- AssertBreakpoint();
+ WARN(("VBOXESC_SETVISIBLEREGION: incorrect buffer size (%d), reported count (%d)", cbRects, lpRgnData->rdh.nCount));
Status = STATUS_INVALID_PARAMETER;
}
break;
@@ -4139,6 +4277,43 @@ DxgkDdiEscape(
Status = STATUS_SUCCESS;
break;
}
+ case VBOXESC_SETCTXHOSTID:
+ {
+ /* set swapchain information */
+ PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
+ if (!pContext)
+ {
+ WARN(("VBOXESC_SETCTXHOSTID: no context specified"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if (pEscape->PrivateDriverDataSize != sizeof (VBOXDISPIFESCAPE))
+ {
+ WARN(("VBOXESC_SETCTXHOSTID: invalid data size %d", pEscape->PrivateDriverDataSize));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ int32_t hostID = (int32_t)pEscapeHdr->u32CmdSpecific;
+ if (hostID <= 0)
+ {
+ WARN(("VBOXESC_SETCTXHOSTID: invalid hostID %d", hostID));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if (pContext->hostID)
+ {
+ WARN(("VBOXESC_SETCTXHOSTID: context already has hostID specified"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ pContext->hostID = hostID;
+ Status = STATUS_SUCCESS;
+ break;
+ }
case VBOXESC_SWAPCHAININFO:
{
/* set swapchain information */
@@ -4149,46 +4324,171 @@ DxgkDdiEscape(
}
case VBOXESC_REINITVIDEOMODES:
{
- if (pEscape->Flags.HardwareAccess)
+ if (!pEscape->Flags.HardwareAccess)
{
- WARN(("VBOXESC_REINITVIDEOMODES called with HardwareAccess flag set, failing"));
+ WARN(("VBOXESC_REINITVIDEOMODESBYMASK called without HardwareAccess flag set, failing"));
Status = STATUS_INVALID_PARAMETER;
break;
}
- WARN(("VBOXESC_REINITVIDEOMODESBYMASK should be called instead"));
- PVBOXWDDM_VIDEOMODES_INFO pInfos = VBoxWddmUpdateAllVideoModesInfos(pDevExt);
- Status = vboxWddmChildStatusCheckByMask(pDevExt, pInfos, NULL);
- if (!NT_SUCCESS(Status))
+
+#ifdef VBOX_DISPIF_WITH_OPCONTEXT
+ /* win8.1 does not allow context-based escapes for display-only mode */
+ PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
+ if (!pContext)
+ {
+ WARN(("VBOXESC_REINITVIDEOMODES no context supplied!"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if (pContext->enmType != VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_RESIZE)
{
- WARN(("vboxWddmChildStatusCheckByMask failed, Status 0x%x", Status));
+ WARN(("VBOXESC_REINITVIDEOMODES invalid context supplied %d!", pContext->enmType));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
}
+#endif
+
+ WARN(("VBOXESC_REINITVIDEOMODESBYMASK should be called instead"));
+ VBoxWddmUpdateVideoModesInfoByMask(pDevExt, NULL);
+ Status = STATUS_SUCCESS;
break;
}
case VBOXESC_REINITVIDEOMODESBYMASK:
{
- BOOLEAN fCheckDisplayRecconect = (pEscapeHdr->u32CmdSpecific & VBOXWDDM_REINITVIDEOMODESBYMASK_F_RECONNECT_DISPLAYS_ON_CHANGE);
- if (fCheckDisplayRecconect && pEscape->Flags.HardwareAccess)
+ if (!pEscape->Flags.HardwareAccess)
+ {
+ WARN(("VBOXESC_REINITVIDEOMODESBYMASK called without HardwareAccess flag set, failing"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+#ifdef VBOX_DISPIF_WITH_OPCONTEXT
+ /* win8.1 does not allow context-based escapes for display-only mode */
+ PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
+ if (!pContext)
+ {
+ WARN(("VBOXESC_REINITVIDEOMODESBYMASK no context supplied!"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if (pContext->enmType != VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_RESIZE)
{
- WARN(("VBOXESC_REINITVIDEOMODESBYMASK called with HardwareAccess flag set, failing"));
+ WARN(("VBOXESC_REINITVIDEOMODESBYMASK invalid context supplied %d!", pContext->enmType));
Status = STATUS_INVALID_PARAMETER;
break;
}
+#endif
+
if (pEscape->PrivateDriverDataSize != sizeof (VBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK))
{
WARN(("invalid private driver size %d", pEscape->PrivateDriverDataSize));
Status = STATUS_INVALID_PARAMETER;
break;
}
+ LOG(("=> VBOXESC_REINITVIDEOMODESBYMASK"));
PVBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK pData = (PVBOXDISPIFESCAPE_REINITVIDEOMODESBYMASK)pEscapeHdr;
- PVBOXWDDM_VIDEOMODES_INFO pInfos = VBoxWddmUpdateVideoModesInfoByMask(pDevExt, pData->ScreenMask);
- if (fCheckDisplayRecconect)
+ VBoxWddmUpdateVideoModesInfoByMask(pDevExt, pData->ScreenMask);
+ Status = STATUS_SUCCESS;
+ LOG(("<= VBOXESC_REINITVIDEOMODESBYMASK"));
+ break;
+ }
+ case VBOXESC_CONFIGURETARGETS:
+ {
+ LOG(("=> VBOXESC_CONFIGURETARGETS"));
+
+ if (!pEscape->Flags.HardwareAccess)
{
- Status = vboxWddmChildStatusCheckByMask(pDevExt, pInfos, pData->ScreenMask);
- if (!NT_SUCCESS(Status))
+ WARN(("VBOXESC_CONFIGURETARGETS called without HardwareAccess flag set, failing"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+#ifdef VBOX_DISPIF_WITH_OPCONTEXT
+ /* win8.1 does not allow context-based escapes for display-only mode */
+ PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pEscape->hContext;
+ if (!pContext)
+ {
+ WARN(("VBOXESC_CONFIGURETARGETS no context supplied!"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if (pContext->enmType != VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_RESIZE)
+ {
+ WARN(("VBOXESC_CONFIGURETARGETS invalid context supplied %d!", pContext->enmType));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+#endif
+
+ if (pEscape->PrivateDriverDataSize != sizeof (*pEscapeHdr))
+ {
+ WARN(("VBOXESC_CONFIGURETARGETS invalid private driver size %d", pEscape->PrivateDriverDataSize));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if (pEscapeHdr->u32CmdSpecific)
+ {
+ WARN(("VBOXESC_CONFIGURETARGETS invalid command %d", pEscapeHdr->u32CmdSpecific));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ HANDLE hKey = NULL;
+ WCHAR aNameBuf[100];
+ uint32_t cAdjusted = 0;
+
+ for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
+ {
+ VBOXWDDM_TARGET *pTarget = &pDevExt->aTargets[i];
+ if (pTarget->fConfigured)
+ continue;
+
+ pTarget->fConfigured = true;
+
+ if (!pTarget->fConnected)
{
- WARN(("vboxWddmChildStatusCheckByMask failed, Status 0x%x", Status));
+ Status = vboxWddmChildStatusConnect(pDevExt, (uint32_t)i, TRUE);
+ if (NT_SUCCESS(Status))
+ ++cAdjusted;
+ else
+ WARN(("VBOXESC_CONFIGURETARGETS vboxWddmChildStatusConnectSecondaries failed Status 0x%x\n", Status));
}
+
+ if (!hKey)
+ {
+ Status = IoOpenDeviceRegistryKey(pDevExt->pPDO, PLUGPLAY_REGKEY_DRIVER, GENERIC_WRITE, &hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("VBOXESC_CONFIGURETARGETS IoOpenDeviceRegistryKey failed, Status = 0x%x", Status));
+ hKey = NULL;
+ continue;
+ }
+ }
+
+ Assert(hKey);
+
+ swprintf(aNameBuf, L"%s%d", VBOXWDDM_REG_DRV_DISPFLAGS_PREFIX, i);
+ Status = vboxWddmRegSetValueDword(hKey, aNameBuf, VBOXWDDM_CFG_DRVTARGET_CONNECTED);
+ if (!NT_SUCCESS(Status))
+ WARN(("VBOXESC_CONFIGURETARGETS vboxWddmRegSetValueDword (%d) failed Status 0x%x\n", aNameBuf, Status));
+
+ }
+
+ if (hKey)
+ {
+ NTSTATUS tmpStatus = ZwClose(hKey);
+ Assert(tmpStatus == STATUS_SUCCESS);
}
+
+ pEscapeHdr->u32CmdSpecific = cAdjusted;
+
+ Status = STATUS_SUCCESS;
+
+ LOG(("<= VBOXESC_CONFIGURETARGETS"));
break;
}
case VBOXESC_ADJUSTVIDEOMODES:
@@ -4212,11 +4512,57 @@ DxgkDdiEscape(
PVBOXDISPIFESCAPE_ADJUSTVIDEOMODES pPodesInfo = (PVBOXDISPIFESCAPE_ADJUSTVIDEOMODES)pEscapeHdr;
VBoxWddmAdjustModes(pDevExt, cModes, pPodesInfo->aScreenInfos);
Status = STATUS_SUCCESS;
+ break;
+ }
+ case VBOXESC_SETALLOCHOSTID:
+ {
+ PVBOXWDDM_DEVICE pDevice = (PVBOXWDDM_DEVICE)pEscape->hDevice;
+ if (!pDevice)
+ {
+ WARN(("VBOXESC_SETALLOCHOSTID called without no device specified, failing"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if (pEscape->PrivateDriverDataSize != sizeof (VBOXDISPIFESCAPE_SETALLOCHOSTID))
+ {
+ WARN(("invalid buffer size for VBOXDISPIFESCAPE_SHRC_REF, was(%d), but expected (%d)",
+ pEscape->PrivateDriverDataSize, sizeof (VBOXDISPIFESCAPE_SHRC_REF)));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ PVBOXDISPIFESCAPE_SETALLOCHOSTID pSetHostID = (PVBOXDISPIFESCAPE_SETALLOCHOSTID)pEscapeHdr;
+ PVBOXWDDM_ALLOCATION pAlloc = vboxWddmGetAllocationFromHandle(pDevExt, (D3DKMT_HANDLE)pSetHostID->hAlloc);
+ if (!pAlloc)
+ {
+ WARN(("failed to get allocation from handle"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ if (pAlloc->enmType != VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE)
+ {
+ WARN(("setHostID: invalid allocation type: %d", pAlloc->enmType));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ pSetHostID->rc = VBoxWddmOaSetHostID(pDevice, pAlloc, pSetHostID->hostID, &pSetHostID->EscapeHdr.u32CmdSpecific);
+ Status = STATUS_SUCCESS;
+ break;
}
case VBOXESC_SHRC_ADDREF:
case VBOXESC_SHRC_RELEASE:
{
PVBOXWDDM_DEVICE pDevice = (PVBOXWDDM_DEVICE)pEscape->hDevice;
+ if (!pDevice)
+ {
+ WARN(("VBOXESC_SHRC_ADDREF|VBOXESC_SHRC_RELEASE called without no device specified, failing"));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
/* query whether the allocation represanted by the given [wine-generated] shared resource handle still exists */
if (pEscape->PrivateDriverDataSize != sizeof (VBOXDISPIFESCAPE_SHRC_REF))
{
@@ -4282,7 +4628,7 @@ DxgkDdiEscape(
}
PVBOXDISPIFESCAPE_ISANYX pIsAnyX = (PVBOXDISPIFESCAPE_ISANYX)pEscapeHdr;
- pIsAnyX->u32IsAnyX = pDevExt->fAnyX;
+ pIsAnyX->u32IsAnyX = VBoxCommonFromDeviceExt(pDevExt)->fAnyX;
Status = STATUS_SUCCESS;
break;
}
@@ -4313,15 +4659,13 @@ DxgkDdiEscape(
break;
}
default:
- Assert(0);
- LOGREL(("unsupported escape code (0x%x)", pEscapeHdr->escapeCode));
+ WARN(("unsupported escape code (0x%x)", pEscapeHdr->escapeCode));
break;
}
}
else
{
- LOGREL(("pEscape->PrivateDriverDataSize(%d) < (%d)", pEscape->PrivateDriverDataSize, sizeof (VBOXDISPIFESCAPE)));
- AssertBreakpoint();
+ WARN(("pEscape->PrivateDriverDataSize(%d) < (%d)", pEscape->PrivateDriverDataSize, sizeof (VBOXDISPIFESCAPE)));
Status = STATUS_BUFFER_TOO_SMALL;
}
@@ -4356,14 +4700,34 @@ typedef struct VBOXWDDM_QUERYCURFENCE_CB
static BOOLEAN vboxWddmQueryCurrentFenceCb(PVOID Context)
{
PVBOXWDDM_QUERYCURFENCE_CB pdc = (PVBOXWDDM_QUERYCURFENCE_CB)Context;
- BOOL bRc = DxgkDdiInterruptRoutine(pdc->pDevExt, pdc->MessageNumber);
- pdc->uLastCompletedCmdFenceId = pdc->pDevExt->u.primary.Vdma.uLastCompletedPagingBufferCmdFenceId;
+ PVBOXMP_DEVEXT pDevExt = pdc->pDevExt;
+ BOOL bRc = DxgkDdiInterruptRoutineLegacy(pDevExt, pdc->MessageNumber);
+ pdc->uLastCompletedCmdFenceId = pDevExt->u.primary.Vdma.uLastCompletedPagingBufferCmdFenceId;
return bRc;
}
-NTSTATUS
+static NTSTATUS
+APIENTRY
+DxgkDdiQueryCurrentFenceNew(
+ CONST HANDLE hAdapter,
+ DXGKARG_QUERYCURRENTFENCE* pCurrentFence)
+{
+ LOGF(("ENTER, hAdapter(0x%x)", hAdapter));
+
+ vboxVDbgBreakF();
+
+ PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
+ pCurrentFence->CurrentFence = VBoxCmdVbvaCheckCompleted(pDevExt, &pDevExt->CmdVbva, false);
+
+ LOGF(("LEAVE, hAdapter(0x%x)", hAdapter));
+
+ return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
APIENTRY
-DxgkDdiQueryCurrentFence(
+DxgkDdiQueryCurrentFenceLegacy(
CONST HANDLE hAdapter,
DXGKARG_QUERYCURRENTFENCE* pCurrentFence)
{
@@ -4407,7 +4771,6 @@ DxgkDdiIsSupportedVidPn(
vboxVDbgBreakFv();
NTSTATUS Status = STATUS_SUCCESS;
- BOOLEAN bSupported = TRUE;
PVBOXMP_DEVEXT pContext = (PVBOXMP_DEVEXT)hAdapter;
const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
@@ -4431,23 +4794,18 @@ DxgkDdiIsSupportedVidPn(
return Status;
}
- VBOXVIDPNPATHITEM aItems[VBOX_VIDEO_MAX_SCREENS];
- BOOLEAN fDisabledFound = FALSE;
- Status = vboxVidPnCheckTopology(hVidPnTopology, pVidPnTopologyInterface, TRUE /* fBreakOnDisabled */, RT_ELEMENTS(aItems), aItems, &fDisabledFound);
- Assert(Status == STATUS_SUCCESS);
+ BOOLEAN fSupported = FALSE;
+ Status = vboxVidPnCheckTopology(hVidPnTopology, pVidPnTopologyInterface, &fSupported);
if (!NT_SUCCESS(Status))
{
WARN(("vboxVidPnCheckTopology failed Status()0x%x\n", Status));
return Status;
}
- if (fDisabledFound)
- {
+ if (!fSupported)
LOG(("found unsupported path"));
- bSupported = FALSE;
- }
- pIsSupportedVidPnArg->IsVidPnSupported = bSupported;
+ pIsSupportedVidPnArg->IsVidPnSupported = fSupported;
#ifdef VBOXWDDM_DEBUG_VIDPN
LOGREL(("The Given VidPn is %ssupported\n", pIsSupportedVidPnArg->IsVidPnSupported ? "" : "!!NOT!! "));
@@ -4472,11 +4830,15 @@ DxgkDdiRecommendFunctionalVidPn(
vboxVDbgBreakFv();
+#ifdef DEBUG_misha
+ Assert(0);
+#endif
+
PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
NTSTATUS Status;
PVBOXWDDM_RECOMMENDVIDPN pVidPnInfo = pRecommendFunctionalVidPnArg->PrivateDriverDataSize >= sizeof (VBOXWDDM_RECOMMENDVIDPN) ?
(PVBOXWDDM_RECOMMENDVIDPN)pRecommendFunctionalVidPnArg->pPrivateDriverData : NULL;
- PVBOXWDDM_VIDEOMODES_INFO pInfos = VBoxWddmUpdateAllVideoModesInfos(pDevExt);
+ PVBOXWDDM_VIDEOMODES_INFO pInfos = VBoxWddmGetAllVideoModesInfos(pDevExt);
int i;
for (i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
@@ -4621,26 +4983,25 @@ DxgkDdiEnumVidPnCofuncModality(
return Status;
}
- VBOXVIDPNPATHITEM aItems[VBOX_VIDEO_MAX_SCREENS];
- Status = vboxVidPnCheckTopology(hVidPnTopology, pVidPnTopologyInterface, FALSE /* fBreakOnDisabled */, RT_ELEMENTS(aItems), aItems, NULL /* *pfDisabledFound */);
- Assert(Status == STATUS_SUCCESS);
+#ifdef DEBUG_misha
+ BOOLEAN fSupported = FALSE;
+ Status = vboxVidPnCheckTopology(hVidPnTopology, pVidPnTopologyInterface, &fSupported);
if (!NT_SUCCESS(Status))
{
WARN(("vboxVidPnCheckTopology failed Status()0x%x\n", Status));
return Status;
}
+ Assert(fSupported);
+#endif
VBOXVIDPNCOFUNCMODALITY CbContext = {0};
CbContext.pDevExt = pDevExt;
CbContext.pVidPnInterface = pVidPnInterface;
CbContext.pEnumCofuncModalityArg = pEnumCofuncModalityArg;
CbContext.pInfos = VBoxWddmGetAllVideoModesInfos(pDevExt);
- CbContext.cPathInfos = RT_ELEMENTS(aItems);
- CbContext.apPathInfos = aItems;
Status = vboxVidPnEnumPaths(hVidPnTopology, pVidPnTopologyInterface,
vboxVidPnCofuncModalityPathEnum, &CbContext);
- Assert(Status == STATUS_SUCCESS);
if (!NT_SUCCESS(Status))
{
WARN(("vboxVidPnEnumPaths failed Status()0x%x\n", Status));
@@ -4682,8 +5043,18 @@ DxgkDdiSetVidPnSourceAddress(
Assert((UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays > pSetVidPnSourceAddress->VidPnSourceId);
PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pSetVidPnSourceAddress->VidPnSourceId];
- Status= vboxWddmDisplaySettingsQueryPos(pDevExt, pSetVidPnSourceAddress->VidPnSourceId, &pSource->VScreenPos);
+ POINT Pos;
+ Status= vboxWddmDisplaySettingsQueryPos(pDevExt, pSetVidPnSourceAddress->VidPnSourceId, &Pos);
Assert(Status == STATUS_SUCCESS);
+ if (NT_SUCCESS(Status))
+ {
+ if (memcmp(&pSource->VScreenPos, &Pos, sizeof (Pos)))
+ {
+ pSource->VScreenPos = Pos;
+ pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
+ }
+ }
+
Status = STATUS_SUCCESS;
if ((UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays <= pSetVidPnSourceAddress->VidPnSourceId)
@@ -4728,26 +5099,9 @@ DxgkDdiSetVidPnSourceAddress(
pSetVidPnSourceAddress->PrimaryAddress.QuadPart);
}
- pSource->bGhSynced = FALSE; /* force guest->host notification */
+ pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_LOCATION;
- if (pSource->bVisible
-#if defined(VBOXWDDM_RENDER_FROM_SHADOW)
- && (
-# if defined(VBOX_WDDM_WIN8)
- g_VBoxDisplayOnly
- ||
-# endif
- pDevExt->fRenderToShadowDisabled
- /* only update for UMD_RC_GENERIC when resolution changes to inform host about it
- * otherwise keep host using the same VRAM, containing a valid data before the switch (i.e. SHADOW) */
- || (pAllocation
- && pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC
- && (pAllocation->AllocData.SurfDesc.width != pSource->AllocData.SurfDesc.width
- || pAllocation->AllocData.SurfDesc.height != pSource->AllocData.SurfDesc.height)
- )
- )
-#endif
- )
+ if (pSource->bVisible)
{
vboxWddmGhDisplayCheckSetInfoFromSource(pDevExt, pSource);
}
@@ -4776,8 +5130,17 @@ DxgkDdiSetVidPnSourceVisibility(
Assert((UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays > pSetVidPnSourceVisibility->VidPnSourceId);
PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pSetVidPnSourceVisibility->VidPnSourceId];
- Status= vboxWddmDisplaySettingsQueryPos(pDevExt, pSetVidPnSourceVisibility->VidPnSourceId, &pSource->VScreenPos);
+ POINT Pos;
+ Status= vboxWddmDisplaySettingsQueryPos(pDevExt, pSetVidPnSourceVisibility->VidPnSourceId, &Pos);
Assert(Status == STATUS_SUCCESS);
+ if (NT_SUCCESS(Status))
+ {
+ if (memcmp(&pSource->VScreenPos, &Pos, sizeof (Pos)))
+ {
+ pSource->VScreenPos = Pos;
+ pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_DIMENSIONS;
+ }
+ }
Status = STATUS_SUCCESS;
if ((UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays <= pSetVidPnSourceVisibility->VidPnSourceId)
@@ -4793,24 +5156,7 @@ DxgkDdiSetVidPnSourceVisibility(
if (pSource->bVisible != pSetVidPnSourceVisibility->Visible)
{
pSource->bVisible = pSetVidPnSourceVisibility->Visible;
- if (pSource->bVisible
-#if defined(VBOXWDDM_RENDER_FROM_SHADOW)
- && (
-# if defined(VBOX_WDDM_WIN8)
- g_VBoxDisplayOnly
- ||
-# endif
- pDevExt->fRenderToShadowDisabled
- /* only update for UMD_RC_GENERIC when resolution changes to inform host about it
- * otherwise keep host using the same VRAM, containing a valid data before the switch (i.e. SHADOW) */
- || (pAllocation
- && pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC
- && (pAllocation->AllocData.SurfDesc.width != pSource->AllocData.SurfDesc.width
- || pAllocation->AllocData.SurfDesc.height != pSource->AllocData.SurfDesc.height)
- )
- )
-#endif
- )
+ if (pSource->bVisible)
{
vboxWddmGhDisplayCheckSetInfoFromSource(pDevExt, pSource);
}
@@ -4831,7 +5177,6 @@ static DECLCALLBACK(BOOLEAN) vboxWddmVidPnCleanupTargetsForSrcEnum(PVBOXMP_DEVEX
return TRUE;
}
-
NTSTATUS
APIENTRY
DxgkDdiCommitVidPn(
@@ -4842,24 +5187,10 @@ DxgkDdiCommitVidPn(
LOGF(("ENTER, context(0x%x)", hAdapter));
PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
- uint32_t au32OldHeightVisible[VBOX_VIDEO_MAX_SCREENS];
NTSTATUS Status;
vboxVDbgBreakFv();
- /* we first store the current visible height for each target (monitor)
- * and then we will zero up it for targets either for the given source
- * (in case pCommitVidPnArg->AffectedVidPnSourceId != D3DDDI_ID_ALL)
- * or all targets otherwize.
- * In the end we will match the old and new visible height for all targets to see if
- * some of them become inactivated and hide them accordingly,
- * or we will restore the old height values on failure */
- for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
- {
- PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[i];
- au32OldHeightVisible[i] = pTarget->HeightVisible;
- }
-
do {
const DXGK_VIDPN_INTERFACE* pVidPnInterface = NULL;
Status = pDevExt->u.primary.DxgkInterface.DxgkCbQueryVidPnInterface(pCommitVidPnArg->hFunctionalVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &pVidPnInterface);
@@ -4895,7 +5226,7 @@ DxgkDdiCommitVidPn(
break;
}
- /* this will zero up visible height for all targets of the fiven source, see above comment */
+ /* this will zero up visible height for all targets of the given source, see above comment */
Status = vboxVidPnEnumTargetsForSource(pDevExt, hVidPnTopology, pVidPnTopologyInterface,
pCommitVidPnArg->AffectedVidPnSourceId,
vboxWddmVidPnCleanupTargetsForSrcEnum, NULL);
@@ -4966,43 +5297,26 @@ DxgkDdiCommitVidPn(
Assert(NT_SUCCESS(Status));
pDevExt->u.primary.hCommittedVidPn = pCommitVidPnArg->hFunctionalVidPn;
- for (int i = 1; /* <- never try to hide a primary monitor */
- i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
+ for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
{
PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[i];
- if (!pTarget->HeightVisible && !!au32OldHeightVisible[i])
- {
- /* the target was previously visible */
- vboxWddmGhDisplayHideScreen(pDevExt, i);
- }
- }
-
-#ifdef VBOX_WDDM_WIN8
- if (g_VBoxDisplayOnly)
- {
- for (int i = 0; /* <- never try to hide a primary monitor */
- i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
+ PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[i];
+ uint32_t cAutoresizes = pDevExt->cContextsDispIfResize;
+ if (!cAutoresizes)
{
- PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[i];
- if (pSource->bVisible && !pSource->bGhSynced)
- {
+ if (pSource->bVisible || !pTarget->HeightVisible)
vboxWddmGhDisplayCheckSetInfoFromSource(pDevExt, pSource);
- }
}
+ else
+ pTarget->fStateSyncPening = true;
}
-#endif
+
LOGF(("LEAVE, SUCCESS status(0x%x), context(0x%x)", Status, hAdapter));
return Status;
} while (0);
AssertRelease(!NT_SUCCESS(Status));
- /* failure branch restore original visible height values, see comments above */
- for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
- {
- PVBOXWDDM_TARGET pTarget = &pDevExt->aTargets[i];
- pTarget->HeightVisible = au32OldHeightVisible[i];
- }
LOGF(("LEAVE, !!FAILURE!! status(0x%x), context(0x%x)", Status, hAdapter));
return Status;
@@ -5139,7 +5453,7 @@ DxgkDdiControlInterrupt(
{
LOGF(("ENTER, hAdapter(0x%x)", hAdapter));
- NTSTATUS Status = STATUS_SUCCESS;
+ NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
switch (InterruptType)
@@ -5147,7 +5461,9 @@ DxgkDdiControlInterrupt(
case DXGK_INTERRUPT_CRTC_VSYNC:
{
Status = VBoxWddmSlEnableVSyncNotification(pDevExt, Enable);
- if (!NT_SUCCESS(Status))
+ if (NT_SUCCESS(Status))
+ Status = STATUS_SUCCESS; /* <- sanity */
+ else
WARN(("VSYNC Interrupt control failed Enable(%d), Status(0x%x)", Enable, Status));
break;
}
@@ -5243,15 +5559,17 @@ DxgkDdiOpenAllocation(
PVBOXWDDM_RCINFO pRcInfo = NULL;
if (pOpenAllocation->PrivateDriverSize)
{
- Assert(pOpenAllocation->PrivateDriverSize == sizeof (VBOXWDDM_RCINFO));
Assert(pOpenAllocation->pPrivateDriverData);
- if (pOpenAllocation->PrivateDriverSize >= sizeof (VBOXWDDM_RCINFO))
+ if (pOpenAllocation->PrivateDriverSize == sizeof (VBOXWDDM_RCINFO))
{
pRcInfo = (PVBOXWDDM_RCINFO)pOpenAllocation->pPrivateDriverData;
Assert(pRcInfo->cAllocInfos == pOpenAllocation->NumAllocations);
}
else
+ {
+ WARN(("Invalid PrivateDriverSize %d", pOpenAllocation->PrivateDriverSize));
Status = STATUS_INVALID_PARAMETER;
+ }
}
if (Status == STATUS_SUCCESS)
@@ -5387,26 +5705,24 @@ DxgkDdiCloseAllocation(
return STATUS_SUCCESS;
}
-NTSTATUS
+static NTSTATUS
APIENTRY
-DxgkDdiRender(
+DxgkDdiRenderNew(
CONST HANDLE hContext,
DXGKARG_RENDER *pRender)
{
// LOGF(("ENTER, hContext(0x%x)", hContext));
- Assert(pRender->DmaBufferPrivateDataSize >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR));
- if (pRender->DmaBufferPrivateDataSize < sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR))
+ if (pRender->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_HDR))
{
- LOGREL(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_BASEHDR (%d)",
- pRender->DmaBufferPrivateDataSize , sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR)));
+ WARN(("pRender->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_HDR (%d)",
+ pRender->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_HDR)));
/* @todo: can this actually happen? what status to return? */
return STATUS_INVALID_PARAMETER;
}
if (pRender->CommandLength < sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR))
{
- Assert(0);
- LOGREL(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_BASEHDR (%d)",
+ WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_BASEHDR (%d)",
pRender->DmaBufferPrivateDataSize , sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR)));
/* @todo: can this actually happen? what status to return? */
return STATUS_INVALID_PARAMETER;
@@ -5414,87 +5730,249 @@ DxgkDdiRender(
PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR pInputHdr = (PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR)pRender->pCommand;
NTSTATUS Status = STATUS_SUCCESS;
+
+ uint32_t cbBuffer = 0;
+ uint32_t cbCmdDma = 0;
+ VBOXCMDVBVA_HDR* pCmd = (VBOXCMDVBVA_HDR*)pRender->pDmaBufferPrivateData;
+
switch (pInputHdr->enmCmd)
{
case VBOXVDMACMD_TYPE_CHROMIUM_CMD:
{
- if (pRender->CommandLength != RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos[pInputHdr->u32CmdReserved]))
+ if (pRender->AllocationListSize >= (UINT32_MAX - RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos))/ RT_SIZEOFMEMB(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos[0]))
{
- Assert(0);
+ WARN(("Invalid AllocationListSize %d", pRender->AllocationListSize));
return STATUS_INVALID_PARAMETER;
}
- PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD pUmCmd = (PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD)pInputHdr;
- PVBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD pChromiumCmd = (PVBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD)pRender->pDmaBufferPrivateData;
- const uint32_t cbDma = RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD, aBufInfos[pInputHdr->u32CmdReserved]);
- if (pRender->DmaBufferPrivateDataSize < cbDma)
+
+ if (pRender->CommandLength != RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos[pRender->AllocationListSize]))
{
- Assert(0);
+ WARN(("pRender->CommandLength (%d) != RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos[pRender->AllocationListSize](%d)",
+ pRender->CommandLength, RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD, aBufInfos[pRender->AllocationListSize])));
return STATUS_INVALID_PARAMETER;
}
- if (pRender->DmaSize < cbDma)
+
+ if (pRender->AllocationListSize >= (UINT32_MAX - RT_OFFSETOF(VBOXCMDVBVA_CRCMD, Cmd.aBuffers))/ RT_SIZEOFMEMB(VBOXCMDVBVA_CRCMD, Cmd.aBuffers[0]))
{
- Assert(0);
+ WARN(("Invalid AllocationListSize %d", pRender->AllocationListSize));
return STATUS_INVALID_PARAMETER;
}
- if (pRender->PatchLocationListOutSize < pInputHdr->u32CmdReserved)
+ cbBuffer = RT_OFFSETOF(VBOXCMDVBVA_CRCMD, Cmd.aBuffers[pRender->AllocationListSize]);
+ if (cbBuffer > 4096)
{
- Assert(0);
+ /* this should not be bigger actually */
+ WARN(("too big command buffer %d", cbBuffer));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ cbCmdDma = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
+
+ if (pRender->DmaBufferPrivateDataSize < cbBuffer)
+ {
+ WARN(("pRender->DmaBufferPrivateDataSize too small %d, requested %d", pRender->DmaBufferPrivateDataSize, cbBuffer));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (pRender->DmaSize < cbCmdDma)
+ {
+ WARN(("dma buffer %d too small", pRender->DmaSize));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ Assert(pRender->PatchLocationListOutSize == pRender->AllocationListSize);
+
+ if (pRender->PatchLocationListOutSize < pRender->AllocationListSize)
+ {
+ WARN(("pRender->PatchLocationListOutSize too small %d, requested %d", pRender->PatchLocationListOutSize, pRender->AllocationListSize));
return STATUS_INVALID_PARAMETER;
}
+ PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD pUmCmd = (PVBOXWDDM_DMA_PRIVATEDATA_UM_CHROMIUM_CMD)pInputHdr;
+ VBOXCMDVBVA_CRCMD* pChromiumCmd = (VBOXCMDVBVA_CRCMD*)pRender->pDmaBufferPrivateData;
+
PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext;
PVBOXWDDM_DEVICE pDevice = pContext->pDevice;
PVBOXMP_DEVEXT pDevExt = pDevice->pAdapter;
- pChromiumCmd->Base.enmCmd = VBOXVDMACMD_TYPE_CHROMIUM_CMD;
- pChromiumCmd->Base.u32CmdReserved = pInputHdr->u32CmdReserved;
- pRender->pDmaBufferPrivateData = (uint8_t*)pRender->pDmaBufferPrivateData + cbDma;
- pRender->pDmaBuffer = ((uint8_t*)pRender->pDmaBuffer) + cbDma;
- D3DDDI_PATCHLOCATIONLIST* pPLL = pRender->pPatchLocationListOut;
- memset(pPLL, 0, sizeof (*pPLL) * pChromiumCmd->Base.u32CmdReserved);
- pRender->pPatchLocationListOut += pInputHdr->u32CmdReserved;
- PVBOXWDDM_UHGSMI_BUFFER_SUBMIT_INFO pSubmInfo = pChromiumCmd->aBufInfos;
- PVBOXWDDM_UHGSMI_BUFFER_UI_SUBMIT_INFO pSubmUmInfo = pUmCmd->aBufInfos;
+ pChromiumCmd->Hdr.u8OpCode = VBOXCMDVBVA_OPTYPE_CRCMD;
+ pChromiumCmd->Hdr.u8Flags = 0;
+ pChromiumCmd->Cmd.cBuffers = pRender->AllocationListSize;
+
DXGK_ALLOCATIONLIST *pAllocationList = pRender->pAllocationList;
- for (UINT i = 0; i < pChromiumCmd->Base.u32CmdReserved; ++i)
+ VBOXCMDVBVA_CRCMD_BUFFER *pSubmInfo = pChromiumCmd->Cmd.aBuffers;
+ PVBOXWDDM_UHGSMI_BUFFER_UI_SUBMIT_INFO pSubmUmInfo = pUmCmd->aBufInfos;
+
+ for (UINT i = 0; i < pRender->AllocationListSize; ++i, ++pRender->pPatchLocationListOut, ++pAllocationList, ++pSubmInfo, ++pSubmUmInfo)
{
+ D3DDDI_PATCHLOCATIONLIST* pPLL = pRender->pPatchLocationListOut;
PVBOXWDDM_ALLOCATION pAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pAllocationList);
- vboxWddmPopulateDmaAllocInfoWithOffset(&pSubmInfo->Alloc, pAlloc, pAllocationList, pSubmUmInfo->offData);
+ if (pSubmUmInfo->offData >= pAlloc->AllocData.SurfDesc.cbSize
+ || pSubmUmInfo->cbData > pAlloc->AllocData.SurfDesc.cbSize
+ || pSubmUmInfo->offData + pSubmUmInfo->cbData > pAlloc->AllocData.SurfDesc.cbSize)
+ {
+ WARN(("invalid data"));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ memset(pPLL, 0, sizeof (*pPLL));
+
+ if (pAllocationList->SegmentId)
+ pSubmInfo->offBuffer = pAllocationList->PhysicalAddress.LowPart + pSubmUmInfo->offData;
- pSubmInfo->cbData = pSubmUmInfo->cbData;
- pSubmInfo->bDoNotSignalCompletion = pSubmUmInfo->bDoNotSignalCompletion;
+ pSubmInfo->cbBuffer = pSubmUmInfo->cbData;
pPLL->AllocationIndex = i;
- pPLL->PatchOffset = RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_CHROMIUM_CMD, aBufInfos[i].Alloc);
+ pPLL->PatchOffset = RT_OFFSETOF(VBOXCMDVBVA_CRCMD, Cmd.aBuffers[i].offBuffer);
pPLL->AllocationOffset = pSubmUmInfo->offData;
-
- ++pPLL;
- ++pSubmInfo;
- ++pSubmUmInfo;
- ++pAllocationList;
}
break;
}
case VBOXVDMACMD_TYPE_DMA_NOP:
{
- PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR pPrivateData = (PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR)pRender->pDmaBufferPrivateData;
- pPrivateData->enmCmd = VBOXVDMACMD_TYPE_DMA_NOP;
+ cbBuffer = sizeof (VBOXCMDVBVA_HDR);
+ cbCmdDma = VBOXWDDM_DUMMY_DMABUFFER_SIZE;
+
+ if (pRender->DmaBufferPrivateDataSize < cbBuffer)
+ {
+ WARN(("pRender->DmaBufferPrivateDataSize too small %d, requested %d", pRender->DmaBufferPrivateDataSize, cbBuffer));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (pRender->DmaSize < cbCmdDma)
+ {
+ WARN(("dma buffer %d too small", pRender->DmaSize));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ pCmd->u8OpCode = VBOXCMDVBVA_OPTYPE_NOPCMD;
+ pCmd->u8Flags = 0;
+
+ for (UINT i = 0; i < pRender->AllocationListSize; ++i, ++pRender->pPatchLocationListOut)
+ {
+ D3DDDI_PATCHLOCATIONLIST* pPLL = pRender->pPatchLocationListOut;
+ memset(pPLL, 0, sizeof (*pPLL));
+ pPLL->AllocationIndex = i;
+ pPLL->PatchOffset = ~0UL;
+ pPLL->AllocationOffset = 0;
+ }
- pRender->pDmaBufferPrivateData = (uint8_t*)pRender->pDmaBufferPrivateData + sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR);
- pRender->pDmaBuffer = ((uint8_t*)pRender->pDmaBuffer) + pRender->CommandLength;
- Assert(pRender->DmaSize >= pRender->CommandLength);
- Assert(pRender->PatchLocationListOutSize >= pRender->PatchLocationListInSize);
- UINT cbPLL = pRender->PatchLocationListInSize * sizeof (pRender->pPatchLocationListOut[0]);
- memcpy(pRender->pPatchLocationListOut, pRender->pPatchLocationListIn, cbPLL);
- pRender->pPatchLocationListOut += pRender->PatchLocationListInSize;
break;
}
default:
+ {
+ WARN(("unsupported render command %d", pInputHdr->enmCmd));
return STATUS_INVALID_PARAMETER;
+ }
}
+ pRender->pDmaBufferPrivateData = ((uint8_t*)pRender->pDmaBufferPrivateData) + cbBuffer;
+ pRender->pDmaBuffer = ((uint8_t*)pRender->pDmaBuffer) + cbCmdDma;
+
+ pCmd->u8State = VBOXCMDVBVA_STATE_SUBMITTED;
+ /* sanity */
+ pCmd->u32FenceID = 0;
+
+// LOGF(("LEAVE, hContext(0x%x)", hContext));
+
+ return STATUS_SUCCESS;
+}
+
+static void vboxWddmPatchLocationInit(D3DDDI_PATCHLOCATIONLIST *pPatchLocationListOut, UINT idx, UINT offPatch)
+{
+ memset(pPatchLocationListOut, 0, sizeof (*pPatchLocationListOut));
+ pPatchLocationListOut->AllocationIndex = idx;
+ pPatchLocationListOut->PatchOffset = offPatch;
+}
+
+static NTSTATUS
+APIENTRY
+DxgkDdiRenderLegacy(
+ CONST HANDLE hContext,
+ DXGKARG_RENDER *pRender)
+{
+// LOGF(("ENTER, hContext(0x%x)", hContext));
+
+ Assert(pRender->DmaBufferPrivateDataSize >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR));
+ if (pRender->DmaBufferPrivateDataSize < sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR))
+ {
+ WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_BASEHDR (%d)",
+ pRender->DmaBufferPrivateDataSize , sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR)));
+ return STATUS_INVALID_PARAMETER;
+ }
+ if (pRender->CommandLength < sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR))
+ {
+ WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_BASEHDR (%d)",
+ pRender->DmaBufferPrivateDataSize , sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR)));
+ return STATUS_INVALID_PARAMETER;
+ }
+ if (pRender->DmaSize < pRender->CommandLength)
+ {
+ WARN(("pRender->DmaSize(%d) < pRender->CommandLength(%d)",
+ pRender->DmaSize, pRender->CommandLength));
+ return STATUS_INVALID_PARAMETER;
+ }
+ if (pRender->PatchLocationListOutSize < pRender->PatchLocationListInSize)
+ {
+ WARN(("pRender->PatchLocationListOutSize(%d) < pRender->PatchLocationListInSize(%d)",
+ pRender->PatchLocationListOutSize, pRender->PatchLocationListInSize));
+ return STATUS_INVALID_PARAMETER;
+ }
+ if (pRender->AllocationListSize != pRender->PatchLocationListInSize)
+ {
+ WARN(("pRender->AllocationListSize(%d) != pRender->PatchLocationListInSize(%d)",
+ pRender->AllocationListSize, pRender->PatchLocationListInSize));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ __try
+ {
+ PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR pInputHdr = (PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR)pRender->pCommand;
+ switch (pInputHdr->enmCmd)
+ {
+ case VBOXVDMACMD_TYPE_DMA_NOP:
+ {
+ PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR pPrivateData = (PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR)pRender->pDmaBufferPrivateData;
+ pPrivateData->enmCmd = VBOXVDMACMD_TYPE_DMA_NOP;
+ pRender->pDmaBufferPrivateData = (uint8_t*)pRender->pDmaBufferPrivateData + sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR);
+ pRender->pDmaBuffer = ((uint8_t*)pRender->pDmaBuffer) + pRender->CommandLength;
+ for (UINT i = 0; i < pRender->PatchLocationListInSize; ++i)
+ {
+ UINT offPatch = i * 4;
+ if (offPatch + 4 > pRender->CommandLength)
+ {
+ WARN(("wrong offPatch"));
+ return STATUS_INVALID_PARAMETER;
+ }
+ if (offPatch != pRender->pPatchLocationListIn[i].PatchOffset)
+ {
+ WARN(("wrong PatchOffset"));
+ return STATUS_INVALID_PARAMETER;
+ }
+ if (i != pRender->pPatchLocationListIn[i].AllocationIndex)
+ {
+ WARN(("wrong AllocationIndex"));
+ return STATUS_INVALID_PARAMETER;
+ }
+ vboxWddmPatchLocationInit(&pRender->pPatchLocationListOut[i], i, offPatch);
+ }
+ break;
+ }
+ default:
+ {
+ WARN(("unsupported command %d", pInputHdr->enmCmd));
+ return STATUS_INVALID_PARAMETER;
+ }
+ }
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ WARN(("invalid parameter"));
+ }
// LOGF(("LEAVE, hContext(0x%x)", hContext));
return Status;
@@ -5536,12 +6014,27 @@ DECLINLINE(BOOLEAN) vboxWddmPixFormatConversionSupported(D3DDDIFORMAT From, D3DD
return From == To;
}
+DECLINLINE(bool) VBoxCVDdiFillAllocInfo(VBOXCMDVBVA_HDR* pHdr,
+ VBOXCMDVBVA_ALLOCINFO *pInfo, PVBOXWDDM_ALLOCATION pAlloc, DXGK_ALLOCATIONLIST *pList, bool fDst)
+{
+ if (pAlloc->AllocData.hostID)
+ {
+ pHdr->u8Flags |= (fDst ? VBOXCMDVBVA_OPF_ALLOC_DSTID : VBOXCMDVBVA_OPF_ALLOC_SRCID);
+ pInfo->u.id = pAlloc->AllocData.hostID;
+ return false;
+ }
+
+ Assert(!pList->PhysicalAddress.HighPart);
+ pInfo->u.offVRAM = pList->PhysicalAddress.LowPart;
+ return true;
+}
+
/**
* DxgkDdiPresent
*/
-NTSTATUS
+static NTSTATUS
APIENTRY
-DxgkDdiPresent(
+DxgkDdiPresentNew(
CONST HANDLE hContext,
DXGKARG_PRESENT *pPresent)
{
@@ -5551,24 +6044,32 @@ DxgkDdiPresent(
vboxVDbgBreakFv();
- NTSTATUS Status = STATUS_SUCCESS;
PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext;
PVBOXWDDM_DEVICE pDevice = pContext->pDevice;
PVBOXMP_DEVEXT pDevExt = pDevice->pAdapter;
- Assert(pPresent->DmaBufferPrivateDataSize >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR));
- if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR))
+ if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_HDR))
{
- LOGREL(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR (%d)", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR)));
- /* @todo: can this actually happen? what status tu return? */
+ WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_HDR (%d)", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_HDR)));
+ /* @todo: can this actually happen? what status to return? */
return STATUS_INVALID_PARAMETER;
}
- PVBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR pPrivateData = (PVBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR)pPresent->pDmaBufferPrivateData;
- pPrivateData->BaseHdr.fFlags.Value = 0;
- uint32_t cContexts3D = ASMAtomicReadU32(&pDevExt->cContexts3D);
- uint32_t cContexts2D = ASMAtomicReadU32(&pDevExt->cContexts2D);
-#define VBOXWDDM_DUMMY_DMABUFFER_SIZE sizeof(RECT)
+ VBOXCMDVBVA_HDR* pHdr = (VBOXCMDVBVA_HDR*)pPresent->pDmaBufferPrivateData;
+
+ UINT u32SrcPatch = ~0UL;
+ UINT u32DstPatch = ~0UL;
+ BOOLEAN fPatchSrc = false;
+ BOOLEAN fPatchDst = false;
+ VBOXCMDVBVA_RECT *paRects = NULL;
+ uint32_t cbMaxRects;
+
+ if (pPresent->DmaSize < VBOXWDDM_DUMMY_DMABUFFER_SIZE)
+ {
+ WARN(("Present->DmaSize(%d) < VBOXWDDM_DUMMY_DMABUFFER_SIZE (%d)", pPresent->DmaSize , VBOXWDDM_DUMMY_DMABUFFER_SIZE));
+ /* @todo: can this actually happen? what status to return? */
+ return STATUS_INVALID_PARAMETER;
+ }
if (pPresent->Flags.Blt)
{
@@ -5576,348 +6077,348 @@ DxgkDdiPresent(
DXGK_ALLOCATIONLIST *pSrc = &pPresent->pAllocationList[DXGK_PRESENT_SOURCE_INDEX];
DXGK_ALLOCATIONLIST *pDst = &pPresent->pAllocationList[DXGK_PRESENT_DESTINATION_INDEX];
PVBOXWDDM_ALLOCATION pSrcAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pSrc);
- Assert(pSrcAlloc);
- if (pSrcAlloc)
+ if (!pSrcAlloc)
{
- PVBOXWDDM_ALLOCATION pDstAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pDst);
- Assert(pDstAlloc);
- if (pDstAlloc)
- {
- do
- {
-#ifdef VBOXWDDM_RENDER_FROM_SHADOW
-#if 0
- Assert (pSrcAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE);
- Assert (pDstAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE);
-#else
- if (pContext->enmType == VBOXWDDM_CONTEXT_TYPE_SYSTEM)
- {
- Assert ((pSrcAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE
- && pDstAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE)
- || (pSrcAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE
- && pDstAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE));
- }
-#endif
- /* issue VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE ONLY in case there are no 3D contexts currently
- * otherwise we would need info about all rects being updated on primary for visible rect reporting */
- if (!cContexts3D && !cContexts2D)
- {
- if (pDstAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE
- && pSrcAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE)
- {
- Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_SYSTEM);
- Assert(pDstAlloc->bAssigned);
- if (pDstAlloc->bAssigned)
- {
-#ifdef VBOX_WITH_VIDEOHWACCEL
-// if (vboxVhwaHlpOverlayListIsEmpty(pDevExt, pDstAlloc->AllocData.SurfDesc.VidPnSourceId))
-#endif
- {
- Assert(pPresent->DmaBufferPrivateDataSize >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY));
- if (pPresent->DmaBufferPrivateDataSize >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY))
- {
- Assert(pPresent->SrcRect.left == pPresent->DstRect.left);
- Assert(pPresent->SrcRect.right == pPresent->DstRect.right);
- Assert(pPresent->SrcRect.top == pPresent->DstRect.top);
- Assert(pPresent->SrcRect.bottom == pPresent->DstRect.bottom);
- RECT rect;
- if (pPresent->SubRectCnt)
- {
- rect = pPresent->pDstSubRects[0];
- for (UINT i = 1; i < pPresent->SubRectCnt; ++i)
- {
- vboxWddmRectUnited(&rect, &rect, &pPresent->pDstSubRects[i]);
- }
- }
- else
- rect = pPresent->SrcRect;
-
-
- pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + sizeof (VBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY);
- pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + VBOXWDDM_DUMMY_DMABUFFER_SIZE;
- Assert(pPresent->DmaSize >= VBOXWDDM_DUMMY_DMABUFFER_SIZE);
- memset(pPresent->pPatchLocationListOut, 0, 2*sizeof (D3DDDI_PATCHLOCATIONLIST));
- pPresent->pPatchLocationListOut->PatchOffset = 0;
- pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_SOURCE_INDEX;
- ++pPresent->pPatchLocationListOut;
- pPresent->pPatchLocationListOut->PatchOffset = 4;
- pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_DESTINATION_INDEX;
- ++pPresent->pPatchLocationListOut;
-
- pPrivateData->BaseHdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_SHADOW2PRIMARY;
- PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY pS2P = (PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY)pPrivateData;
- /* we do not know the shadow address yet, perform dummy DMA cycle */
- vboxWddmPopulateDmaAllocInfo(&pS2P->Shadow2Primary.ShadowAlloc, pSrcAlloc, pSrc);
-// vboxWddmPopulateDmaAllocInfo(&pPrivateData->DstAllocInfo, pDstAlloc, pDst);
- pS2P->Shadow2Primary.SrcRect = rect;
- pS2P->Shadow2Primary.VidPnSourceId = pDstAlloc->AllocData.SurfDesc.VidPnSourceId;
- break;
- }
- else
- {
- Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
- break;
- }
- }
- }
- }
- }
+ /* this should not happen actually */
+ WARN(("failed to get Src Allocation info for hDeviceSpecificAllocation(0x%x)",pSrc->hDeviceSpecificAllocation));
+ return STATUS_INVALID_HANDLE;
+ }
- /* we're here because this is NOT a shadow->primary update
- * or because there are d3d contexts and we need to report visible rects
- * or because we have overlays active and we need a special handling for primary */
-#endif
- UINT cbCmd = pPresent->DmaBufferPrivateDataSize;
- pPrivateData->BaseHdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_BLT;
-
- PVBOXWDDM_DMA_PRIVATEDATA_BLT pBlt = (PVBOXWDDM_DMA_PRIVATEDATA_BLT)pPrivateData;
-
- vboxWddmPopulateDmaAllocInfo(&pBlt->Blt.SrcAlloc, pSrcAlloc, pSrc);
- vboxWddmPopulateDmaAllocInfo(&pBlt->Blt.DstAlloc, pDstAlloc, pDst);
-
- ASSERT_WARN(!pSrcAlloc->fRcFlags.SharedResource, ("Shared Allocatoin used in Present!"));
-
- pBlt->Blt.SrcRect = pPresent->SrcRect;
- pBlt->Blt.DstRects.ContextRect = pPresent->DstRect;
- pBlt->Blt.DstRects.UpdateRects.cRects = 0;
- UINT cbHead = RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_BLT, Blt.DstRects.UpdateRects.aRects[0]);
- Assert(pPresent->SubRectCnt > pPresent->MultipassOffset);
- UINT cbRects = (pPresent->SubRectCnt - pPresent->MultipassOffset) * sizeof (RECT);
- pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + cbHead + cbRects;
- pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + VBOXWDDM_DUMMY_DMABUFFER_SIZE;
- Assert(pPresent->DmaSize >= VBOXWDDM_DUMMY_DMABUFFER_SIZE);
- cbCmd -= cbHead;
- Assert(cbCmd < UINT32_MAX/2);
- Assert(cbCmd > sizeof (RECT));
- if (cbCmd >= cbRects)
- {
- cbCmd -= cbRects;
- memcpy(&pBlt->Blt.DstRects.UpdateRects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbRects);
- pBlt->Blt.DstRects.UpdateRects.cRects += cbRects/sizeof (RECT);
- }
- else
- {
- UINT cbFitingRects = (cbCmd/sizeof (RECT)) * sizeof (RECT);
- Assert(cbFitingRects);
- memcpy(&pBlt->Blt.DstRects.UpdateRects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbFitingRects);
- cbCmd -= cbFitingRects;
- pPresent->MultipassOffset += cbFitingRects/sizeof (RECT);
- pBlt->Blt.DstRects.UpdateRects.cRects += cbFitingRects/sizeof (RECT);
- Assert(pPresent->SubRectCnt > pPresent->MultipassOffset);
- Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
- }
+ PVBOXWDDM_ALLOCATION pDstAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pDst);
+ if (!pDstAlloc)
+ {
+ /* this should not happen actually */
+ WARN(("failed to get Dst Allocation info for hDeviceSpecificAllocation(0x%x)",pDst->hDeviceSpecificAllocation));
+ return STATUS_INVALID_HANDLE;
+ }
- memset(pPresent->pPatchLocationListOut, 0, 2*sizeof (D3DDDI_PATCHLOCATIONLIST));
- pPresent->pPatchLocationListOut->PatchOffset = 0;
- pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_SOURCE_INDEX;
- ++pPresent->pPatchLocationListOut;
- pPresent->pPatchLocationListOut->PatchOffset = 4;
- pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_DESTINATION_INDEX;
- ++pPresent->pPatchLocationListOut;
+ fPatchSrc = TRUE;
+ fPatchDst = TRUE;
- break;
-#ifdef VBOX_WITH_VDMA
- cbCmd = pPresent->DmaSize;
-
- Assert(pPresent->SubRectCnt);
- UINT cmdSize = VBOXVDMACMD_DMA_PRESENT_BLT_SIZE(pPresent->SubRectCnt - pPresent->MultipassOffset);
- PVBOXVDMACMD pCmd = (PVBOXVDMACMD)pPresent->pDmaBuffer;
- pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + cmdSize;
- Assert(cbCmd >= VBOXVDMACMD_DMA_PRESENT_BLT_MINSIZE());
- if (cbCmd >= VBOXVDMACMD_DMA_PRESENT_BLT_MINSIZE())
- {
- if (vboxWddmPixFormatConversionSupported(pSrcAlloc->AllocData.SurfDesc.format, pDstAlloc->AllocData.SurfDesc.format))
- {
- memset(pPresent->pPatchLocationListOut, 0, 2*sizeof (D3DDDI_PATCHLOCATIONLIST));
- // pPresent->pPatchLocationListOut->PatchOffset = 0;
- // ++pPresent->pPatchLocationListOut;
- pPresent->pPatchLocationListOut->PatchOffset = VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, offSrc);
- pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_SOURCE_INDEX;
- ++pPresent->pPatchLocationListOut;
- pPresent->pPatchLocationListOut->PatchOffset = VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, offDst);
- pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_DESTINATION_INDEX;
- ++pPresent->pPatchLocationListOut;
-
- pCmd->enmType = VBOXVDMACMD_TYPE_DMA_PRESENT_BLT;
- pCmd->u32CmdSpecific = 0;
- PVBOXVDMACMD_DMA_PRESENT_BLT pTransfer = VBOXVDMACMD_BODY(pCmd, VBOXVDMACMD_DMA_PRESENT_BLT);
- pTransfer->offSrc = (VBOXVIDEOOFFSET)pSrc->PhysicalAddress.QuadPart;
- pTransfer->offDst = (VBOXVIDEOOFFSET)pDst->PhysicalAddress.QuadPart;
- vboxWddmSurfDescFromAllocation(pSrcAlloc, &pTransfer->srcDesc);
- vboxWddmSurfDescFromAllocation(pDstAlloc, &pTransfer->dstDesc);
- vboxWddmRectlFromRect(&pPresent->SrcRect, &pTransfer->srcRectl);
- vboxWddmRectlFromRect(&pPresent->DstRect, &pTransfer->dstRectl);
- UINT i = 0;
- cbCmd -= VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, aDstSubRects);
- Assert(cbCmd >= sizeof (VBOXVDMA_RECTL));
- Assert(cbCmd < pPresent->DmaSize);
- for (; i < pPresent->SubRectCnt; ++i)
- {
- if (cbCmd < sizeof (VBOXVDMA_RECTL))
- {
- Assert(i);
- pPresent->MultipassOffset += i;
- Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
- break;
- }
- vboxWddmRectlFromRect(&pPresent->pDstSubRects[i + pPresent->MultipassOffset], &pTransfer->aDstSubRects[i]);
- cbCmd -= sizeof (VBOXVDMA_RECTL);
- }
- Assert(i);
- pPrivateData->BaseHdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_BLT;
- pTransfer->cDstSubRects = i;
- pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + sizeof(VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR);
- }
- else
- {
- AssertBreakpoint();
- LOGREL(("unsupported format conversion from(%d) to (%d)",pSrcAlloc->AllocData.SurfDesc.format, pDstAlloc->AllocData.SurfDesc.format));
- Status = STATUS_GRAPHICS_CANNOTCOLORCONVERT;
- }
- }
- else
- {
- /* this should not happen actually */
- LOGREL(("cbCmd too small!! (%d)", cbCmd));
- Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
- }
-#endif
- } while(0);
- }
- else
+ BOOLEAN fDstPrimary = (!pDstAlloc->AllocData.hostID
+ && pDstAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE
+ && pDstAlloc->bAssigned);
+ BOOLEAN fSrcPrimary = (!pSrcAlloc->AllocData.hostID
+ && pSrcAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE
+ && pSrcAlloc->bAssigned);
+
+ pHdr->u8OpCode = VBOXCMDVBVA_OPTYPE_BLT_OFFPRIMSZFMT_OR_ID;
+ pHdr->u8Flags = 0;
+
+ if (fDstPrimary || fSrcPrimary)
+ {
+ if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_BLT_PRIMARY))
{
- /* this should not happen actually */
- LOGREL(("failed to get Dst Allocation info for hDeviceSpecificAllocation(0x%x)",pDst->hDeviceSpecificAllocation));
- Status = STATUS_INVALID_HANDLE;
+ WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_BLT_PRIMARY (%d)", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_BLT_PRIMARY)));
+ /* @todo: can this actually happen? what status to return? */
+ return STATUS_INVALID_PARAMETER;
}
- }
- else
- {
- /* this should not happen actually */
- LOGREL(("failed to get Src Allocation info for hDeviceSpecificAllocation(0x%x)",pSrc->hDeviceSpecificAllocation));
- Status = STATUS_INVALID_HANDLE;
- }
-#if 0
- UINT cbCmd = pPresent->DmaSize;
-
- Assert(pPresent->SubRectCnt);
- UINT cmdSize = VBOXVDMACMD_DMA_PRESENT_BLT_SIZE(pPresent->SubRectCnt - pPresent->MultipassOffset);
- PVBOXVDMACMD pCmd = (PVBOXVDMACMD)pPresent->pDmaBuffer;
- pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + cmdSize;
- Assert(cbCmd >= VBOXVDMACMD_DMA_PRESENT_BLT_MINSIZE());
- if (cbCmd >= VBOXVDMACMD_DMA_PRESENT_BLT_MINSIZE())
- {
- DXGK_ALLOCATIONLIST *pSrc = &pPresent->pAllocationList[DXGK_PRESENT_SOURCE_INDEX];
- DXGK_ALLOCATIONLIST *pDst = &pPresent->pAllocationList[DXGK_PRESENT_DESTINATION_INDEX];
- PVBOXWDDM_ALLOCATION pSrcAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pSrc);
- Assert(pSrcAlloc);
- if (pSrcAlloc)
+
+ VBOXCMDVBVA_BLT_PRIMARY *pBlt = (VBOXCMDVBVA_BLT_PRIMARY*)pHdr;
+
+ /* this is the most common case, so we optimize it a bit with VBOXCMDVBVA_BLT_PRIMARY */
+
+ if (fSrcPrimary)
{
- PVBOXWDDM_ALLOCATION pDstAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pDst);
- Assert(pDstAlloc);
- if (pDstAlloc)
- {
- if (vboxWddmPixFormatConversionSupported(pSrcAlloc->AllocData.SurfDesc.format, pDstAlloc->AllocData.SurfDesc.format))
- {
- memset(pPresent->pPatchLocationListOut, 0, 2*sizeof (D3DDDI_PATCHLOCATIONLIST));
-// pPresent->pPatchLocationListOut->PatchOffset = 0;
-// ++pPresent->pPatchLocationListOut;
- pPresent->pPatchLocationListOut->PatchOffset = VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, offSrc);
- pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_SOURCE_INDEX;
- ++pPresent->pPatchLocationListOut;
- pPresent->pPatchLocationListOut->PatchOffset = VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, offDst);
- pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_DESTINATION_INDEX;
- ++pPresent->pPatchLocationListOut;
-
- pCmd->enmType = VBOXVDMACMD_TYPE_DMA_PRESENT_BLT;
- pCmd->u32CmdSpecific = 0;
- PVBOXVDMACMD_DMA_PRESENT_BLT pTransfer = VBOXVDMACMD_BODY(pCmd, VBOXVDMACMD_DMA_PRESENT_BLT);
- pTransfer->offSrc = (VBOXVIDEOOFFSET)pSrc->PhysicalAddress.QuadPart;
- pTransfer->offDst = (VBOXVIDEOOFFSET)pDst->PhysicalAddress.QuadPart;
- vboxWddmSurfDescFromAllocation(pSrcAlloc, &pTransfer->srcDesc);
- vboxWddmSurfDescFromAllocation(pDstAlloc, &pTransfer->dstDesc);
- vboxWddmRectlFromRect(&pPresent->SrcRect, &pTransfer->srcRectl);
- vboxWddmRectlFromRect(&pPresent->DstRect, &pTransfer->dstRectl);
- UINT i = 0;
- cbCmd -= VBOXVDMACMD_BODY_FIELD_OFFSET(UINT, VBOXVDMACMD_DMA_PRESENT_BLT, aDstSubRects);
- Assert(cbCmd >= sizeof (VBOXVDMA_RECTL));
- Assert(cbCmd < pPresent->DmaSize);
- for (; i < pPresent->SubRectCnt; ++i)
- {
- if (cbCmd < sizeof (VBOXVDMA_RECTL))
- {
- Assert(i);
- pPresent->MultipassOffset += i;
- Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
- break;
- }
- vboxWddmRectlFromRect(&pPresent->pDstSubRects[i + pPresent->MultipassOffset], &pTransfer->aDstSubRects[i]);
- cbCmd -= sizeof (VBOXVDMA_RECTL);
- }
- Assert(i);
- pTransfer->cDstSubRects = i;
- pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + sizeof(VBOXWDDM_DMA_PRIVATEDATA_HDR);
- }
- else
- {
- AssertBreakpoint();
- LOGREL(("unsupported format conversion from(%d) to (%d)",pSrcAlloc->AllocData.SurfDesc.format, pDstAlloc->AllocData.SurfDesc.format));
- Status = STATUS_GRAPHICS_CANNOTCOLORCONVERT;
- }
- }
- else
+ pBlt->Hdr.u8Flags |= VBOXCMDVBVA_OPF_ALLOC_SRCPRIMARY;
+ pBlt->Hdr.u.u8PrimaryID = pSrcAlloc->AllocData.SurfDesc.VidPnSourceId;
+
+ if (fDstPrimary)
{
- /* this should not happen actually */
- LOGREL(("failed to get Dst Allocation info for hDeviceSpecificAllocation(0x%x)",pDst->hDeviceSpecificAllocation));
- Status = STATUS_INVALID_HANDLE;
+ pBlt->Hdr.u8Flags |= VBOXCMDVBVA_OPF_ALLOC_DSTPRIMARY;
+ pBlt->alloc.u.id = pDstAlloc->AllocData.SurfDesc.VidPnSourceId;
}
+ else if (VBoxCVDdiFillAllocInfo(pHdr, &pBlt->alloc, pDstAlloc, pDst, true))
+ u32DstPatch = RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, alloc.u.offVRAM);
}
else
{
- /* this should not happen actually */
- LOGREL(("failed to get Src Allocation info for hDeviceSpecificAllocation(0x%x)",pSrc->hDeviceSpecificAllocation));
- Status = STATUS_INVALID_HANDLE;
+ Assert(fDstPrimary);
+ pBlt->Hdr.u8Flags |= VBOXCMDVBVA_OPF_ALLOC_DSTPRIMARY;
+ pBlt->Hdr.u.u8PrimaryID = pDstAlloc->AllocData.SurfDesc.VidPnSourceId;
+
+ if (VBoxCVDdiFillAllocInfo(pHdr, &pBlt->alloc, pSrcAlloc, pSrc, false))
+ u32SrcPatch = RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, alloc.u.offVRAM);
}
+
+ pBlt->Pos.x = (int16_t)(pPresent->DstRect.left - pPresent->SrcRect.left);
+ pBlt->Pos.y = (int16_t)(pPresent->DstRect.top - pPresent->SrcRect.top);
+
+ paRects = pBlt->aRects;
+ cbMaxRects = pPresent->DmaBufferPrivateDataSize - RT_OFFSETOF(VBOXCMDVBVA_BLT_PRIMARY, aRects);
}
else
{
- /* this should not happen actually */
- LOGREL(("cbCmd too small!! (%d)", cbCmd));
- Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
+ if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID))
+ {
+ WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID (%d)", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID)));
+ /* @todo: can this actually happen? what status to return? */
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID *pBlt = (VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID*)pHdr;
+
+ if (VBoxCVDdiFillAllocInfo(pHdr, &pBlt->src, pSrcAlloc, pSrc, false))
+ u32SrcPatch = RT_OFFSETOF(VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID, src.u.offVRAM);
+
+ if (VBoxCVDdiFillAllocInfo(pHdr, &pBlt->dst, pDstAlloc, pDst, true))
+ u32DstPatch = RT_OFFSETOF(VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID, dst.u.offVRAM);
+
+ pBlt->Pos.x = (int16_t)(pPresent->DstRect.left - pPresent->SrcRect.left);
+ pBlt->Pos.y = (int16_t)(pPresent->DstRect.top - pPresent->SrcRect.top);
+
+ paRects = pBlt->aRects;
+ cbMaxRects = pPresent->DmaBufferPrivateDataSize - RT_OFFSETOF(VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID, aRects);
}
-#endif
}
else if (pPresent->Flags.Flip)
{
+ if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_FLIP))
+ {
+ WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_FLIP (%d)", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_FLIP)));
+ /* @todo: can this actually happen? what status to return? */
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ fPatchSrc = TRUE;
+
Assert(pPresent->Flags.Value == 4); /* only Blt is set, we do not support anything else for now */
Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D);
DXGK_ALLOCATIONLIST *pSrc = &pPresent->pAllocationList[DXGK_PRESENT_SOURCE_INDEX];
PVBOXWDDM_ALLOCATION pSrcAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pSrc);
- Assert(pSrcAlloc);
- if (pSrcAlloc)
+
+ if (!pSrcAlloc)
{
- Assert(cContexts3D);
- pPrivateData->BaseHdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP;
- PVBOXWDDM_DMA_PRIVATEDATA_FLIP pFlip = (PVBOXWDDM_DMA_PRIVATEDATA_FLIP)pPrivateData;
+ /* this should not happen actually */
+ WARN(("failed to get pSrc Allocation info for hDeviceSpecificAllocation(0x%x)",pSrc->hDeviceSpecificAllocation));
+ return STATUS_INVALID_HANDLE;
+ }
- vboxWddmPopulateDmaAllocInfo(&pFlip->Flip.Alloc, pSrcAlloc, pSrc);
+ Assert(pDevExt->cContexts3D);
+ pHdr->u8OpCode = VBOXCMDVBVA_OPTYPE_FLIP;
+ pHdr->u8Flags = 0;
+ VBOXCMDVBVA_FLIP *pFlip = (VBOXCMDVBVA_FLIP*)pHdr;
- UINT cbCmd = sizeof (VBOXWDDM_DMA_PRIVATEDATA_FLIP);
- pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + cbCmd;
- pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + VBOXWDDM_DUMMY_DMABUFFER_SIZE;
- Assert(pPresent->DmaSize >= VBOXWDDM_DUMMY_DMABUFFER_SIZE);
+ if (VBoxCVDdiFillAllocInfo(pHdr, &pFlip->src, pSrcAlloc, pSrc, false))
+ u32SrcPatch = RT_OFFSETOF(VBOXCMDVBVA_FLIP, src.u.offVRAM);
+ }
+ else if (pPresent->Flags.ColorFill)
+ {
+ if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXCMDVBVA_CLRFILL))
+ {
+ WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXCMDVBVA_CLRFILL (%d)", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXCMDVBVA_CLRFILL)));
+ /* @todo: can this actually happen? what status to return? */
+ return STATUS_INVALID_PARAMETER;
+ }
- memset(pPresent->pPatchLocationListOut, 0, sizeof (D3DDDI_PATCHLOCATIONLIST));
- pPresent->pPatchLocationListOut->PatchOffset = 0;
- pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_SOURCE_INDEX;
- ++pPresent->pPatchLocationListOut;
+ fPatchDst = TRUE;
+
+ Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_CUSTOM_2D);
+ Assert(pPresent->Flags.Value == 2); /* only ColorFill is set, we do not support anything else for now */
+ DXGK_ALLOCATIONLIST *pDst = &pPresent->pAllocationList[DXGK_PRESENT_DESTINATION_INDEX];
+ PVBOXWDDM_ALLOCATION pDstAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pDst);
+ if (!pDstAlloc)
+ {
+ /* this should not happen actually */
+ WARN(("failed to get pDst Allocation info for hDeviceSpecificAllocation(0x%x)",pDst->hDeviceSpecificAllocation));
+ return STATUS_INVALID_HANDLE;
+ }
+
+ pHdr->u8OpCode = VBOXCMDVBVA_OPTYPE_CLRFILL;
+ pHdr->u8Flags = 0;
+ VBOXCMDVBVA_CLRFILL *pCFill = (VBOXCMDVBVA_CLRFILL*)pHdr;
+
+ if (VBoxCVDdiFillAllocInfo(pHdr, &pCFill->dst, pDstAlloc, pDst, true))
+ u32DstPatch = RT_OFFSETOF(VBOXCMDVBVA_CLRFILL, dst.u.offVRAM);
+
+ paRects = pCFill->aRects;
+ cbMaxRects = pPresent->DmaBufferPrivateDataSize - RT_OFFSETOF(VBOXCMDVBVA_CLRFILL, aRects);
+ }
+ else
+ {
+ WARN(("cmd NOT IMPLEMENTED!! Flags(0x%x)", pPresent->Flags.Value));
+ return STATUS_NOT_SUPPORTED;
+ }
+
+ if (paRects)
+ {
+ UINT iStartRect = pPresent->MultipassOffset;
+ UINT cMaxRects = cbMaxRects / sizeof (VBOXCMDVBVA_RECT);
+ Assert(pPresent->SubRectCnt > iStartRect);
+ UINT cRects = pPresent->SubRectCnt - iStartRect;
+ if (cRects > cMaxRects)
+ {
+ pPresent->MultipassOffset += cMaxRects;
+ cRects = cMaxRects;
}
else
+ pPresent->MultipassOffset = 0;
+
+ const RECT *paDstSubRects = &pPresent->pDstSubRects[iStartRect];
+ VBoxCVDdiPackRects(paRects, paDstSubRects, cRects);
+ }
+
+ if (fPatchSrc)
+ {
+ memset(pPresent->pPatchLocationListOut, 0, sizeof (D3DDDI_PATCHLOCATIONLIST));
+ pPresent->pPatchLocationListOut->PatchOffset = u32SrcPatch;
+ pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_SOURCE_INDEX;
+ ++pPresent->pPatchLocationListOut;
+ }
+
+ if (fPatchDst)
+ {
+ memset(pPresent->pPatchLocationListOut, 0, sizeof (D3DDDI_PATCHLOCATIONLIST));
+ pPresent->pPatchLocationListOut->PatchOffset = u32DstPatch;
+ pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_DESTINATION_INDEX;
+ ++pPresent->pPatchLocationListOut;
+ }
+
+ pHdr->u8State = VBOXCMDVBVA_STATE_SUBMITTED;
+ /* sanity */
+ pHdr->u32FenceID = 0;
+
+ pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + VBOXWDDM_DUMMY_DMABUFFER_SIZE;
+
+ if (pPresent->MultipassOffset)
+ return STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
+ return STATUS_SUCCESS;
+}
+
+/**
+ * DxgkDdiPresent
+ */
+static NTSTATUS
+APIENTRY
+DxgkDdiPresentLegacy(
+ CONST HANDLE hContext,
+ DXGKARG_PRESENT *pPresent)
+{
+ PAGED_CODE();
+
+// LOGF(("ENTER, hContext(0x%x)", hContext));
+
+ vboxVDbgBreakFv();
+
+ NTSTATUS Status = STATUS_SUCCESS;
+ PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext;
+ PVBOXWDDM_DEVICE pDevice = pContext->pDevice;
+ PVBOXMP_DEVEXT pDevExt = pDevice->pAdapter;
+
+ Assert(pPresent->DmaBufferPrivateDataSize >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR));
+ if (pPresent->DmaBufferPrivateDataSize < sizeof (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR))
+ {
+ LOGREL(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR (%d)", pPresent->DmaBufferPrivateDataSize , sizeof (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR)));
+ /* @todo: can this actually happen? what status tu return? */
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ PVBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR pPrivateData = (PVBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR)pPresent->pDmaBufferPrivateData;
+ pPrivateData->BaseHdr.fFlags.Value = 0;
+ uint32_t cContexts2D = ASMAtomicReadU32(&pDevExt->cContexts2D);
+
+ if (pPresent->Flags.Blt)
+ {
+ Assert(pPresent->Flags.Value == 1); /* only Blt is set, we do not support anything else for now */
+ DXGK_ALLOCATIONLIST *pSrc = &pPresent->pAllocationList[DXGK_PRESENT_SOURCE_INDEX];
+ DXGK_ALLOCATIONLIST *pDst = &pPresent->pAllocationList[DXGK_PRESENT_DESTINATION_INDEX];
+ PVBOXWDDM_ALLOCATION pSrcAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pSrc);
+ if (!pSrcAlloc)
{
/* this should not happen actually */
- LOGREL(("failed to get pSrc Allocation info for hDeviceSpecificAllocation(0x%x)",pSrc->hDeviceSpecificAllocation));
+ WARN(("failed to get Src Allocation info for hDeviceSpecificAllocation(0x%x)",pSrc->hDeviceSpecificAllocation));
Status = STATUS_INVALID_HANDLE;
+ goto done;
}
+
+ PVBOXWDDM_ALLOCATION pDstAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pDst);
+ if (!pDstAlloc)
+ {
+ /* this should not happen actually */
+ WARN(("failed to get Dst Allocation info for hDeviceSpecificAllocation(0x%x)",pDst->hDeviceSpecificAllocation));
+ Status = STATUS_INVALID_HANDLE;
+ goto done;
+ }
+
+
+ UINT cbCmd = pPresent->DmaBufferPrivateDataSize;
+ pPrivateData->BaseHdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_BLT;
+
+ PVBOXWDDM_DMA_PRIVATEDATA_BLT pBlt = (PVBOXWDDM_DMA_PRIVATEDATA_BLT)pPrivateData;
+
+ vboxWddmPopulateDmaAllocInfo(&pBlt->Blt.SrcAlloc, pSrcAlloc, pSrc);
+ vboxWddmPopulateDmaAllocInfo(&pBlt->Blt.DstAlloc, pDstAlloc, pDst);
+
+ ASSERT_WARN(!pSrcAlloc->fRcFlags.SharedResource, ("Shared Allocatoin used in Present!"));
+
+ pBlt->Blt.SrcRect = pPresent->SrcRect;
+ pBlt->Blt.DstRects.ContextRect = pPresent->DstRect;
+ pBlt->Blt.DstRects.UpdateRects.cRects = 0;
+ UINT cbHead = RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_BLT, Blt.DstRects.UpdateRects.aRects[0]);
+ Assert(pPresent->SubRectCnt > pPresent->MultipassOffset);
+ UINT cbRects = (pPresent->SubRectCnt - pPresent->MultipassOffset) * sizeof (RECT);
+ pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + cbHead + cbRects;
+ pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + VBOXWDDM_DUMMY_DMABUFFER_SIZE;
+ Assert(pPresent->DmaSize >= VBOXWDDM_DUMMY_DMABUFFER_SIZE);
+ cbCmd -= cbHead;
+ Assert(cbCmd < UINT32_MAX/2);
+ Assert(cbCmd > sizeof (RECT));
+ if (cbCmd >= cbRects)
+ {
+ cbCmd -= cbRects;
+ memcpy(&pBlt->Blt.DstRects.UpdateRects.aRects[pPresent->MultipassOffset], &pPresent->pDstSubRects[pPresent->MultipassOffset], cbRects);
+ pBlt->Blt.DstRects.UpdateRects.cRects += cbRects/sizeof (RECT);
+ }
+ else
+ {
+ UINT cbFitingRects = (cbCmd/sizeof (RECT)) * sizeof (RECT);
+ Assert(cbFitingRects);
+ memcpy(&pBlt->Blt.DstRects.UpdateRects.aRects[pPresent->MultipassOffset], &pPresent->pDstSubRects[pPresent->MultipassOffset], cbFitingRects);
+ cbCmd -= cbFitingRects;
+ pPresent->MultipassOffset += cbFitingRects/sizeof (RECT);
+ pBlt->Blt.DstRects.UpdateRects.cRects += cbFitingRects/sizeof (RECT);
+ Assert(pPresent->SubRectCnt > pPresent->MultipassOffset);
+ Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
+ }
+
+ memset(pPresent->pPatchLocationListOut, 0, 2*sizeof (D3DDDI_PATCHLOCATIONLIST));
+ pPresent->pPatchLocationListOut->PatchOffset = 0;
+ pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_SOURCE_INDEX;
+ ++pPresent->pPatchLocationListOut;
+ pPresent->pPatchLocationListOut->PatchOffset = 4;
+ pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_DESTINATION_INDEX;
+ ++pPresent->pPatchLocationListOut;
+ }
+ else if (pPresent->Flags.Flip)
+ {
+ Assert(pPresent->Flags.Value == 4); /* only Blt is set, we do not support anything else for now */
+ Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D);
+ DXGK_ALLOCATIONLIST *pSrc = &pPresent->pAllocationList[DXGK_PRESENT_SOURCE_INDEX];
+ PVBOXWDDM_ALLOCATION pSrcAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pSrc);
+
+ if (!pSrcAlloc)
+ {
+ /* this should not happen actually */
+ WARN(("failed to get pSrc Allocation info for hDeviceSpecificAllocation(0x%x)",pSrc->hDeviceSpecificAllocation));
+ Status = STATUS_INVALID_HANDLE;
+ goto done;
+ }
+
+ Assert(pDevExt->cContexts3D);
+ pPrivateData->BaseHdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP;
+ PVBOXWDDM_DMA_PRIVATEDATA_FLIP pFlip = (PVBOXWDDM_DMA_PRIVATEDATA_FLIP)pPrivateData;
+
+ vboxWddmPopulateDmaAllocInfo(&pFlip->Flip.Alloc, pSrcAlloc, pSrc);
+
+ UINT cbCmd = sizeof (VBOXWDDM_DMA_PRIVATEDATA_FLIP);
+ pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + cbCmd;
+ pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + VBOXWDDM_DUMMY_DMABUFFER_SIZE;
+ Assert(pPresent->DmaSize >= VBOXWDDM_DUMMY_DMABUFFER_SIZE);
+
+ memset(pPresent->pPatchLocationListOut, 0, sizeof (D3DDDI_PATCHLOCATIONLIST));
+ pPresent->pPatchLocationListOut->PatchOffset = 0;
+ pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_SOURCE_INDEX;
+ ++pPresent->pPatchLocationListOut;
}
else if (pPresent->Flags.ColorFill)
{
@@ -5925,63 +6426,62 @@ DxgkDdiPresent(
Assert(pPresent->Flags.Value == 2); /* only ColorFill is set, we do not support anything else for now */
DXGK_ALLOCATIONLIST *pDst = &pPresent->pAllocationList[DXGK_PRESENT_DESTINATION_INDEX];
PVBOXWDDM_ALLOCATION pDstAlloc = vboxWddmGetAllocationFromAllocList(pDevExt, pDst);
- Assert(pDstAlloc);
- if (pDstAlloc)
+ if (!pDstAlloc)
{
- UINT cbCmd = pPresent->DmaBufferPrivateDataSize;
- pPrivateData->BaseHdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_CLRFILL;
- PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL pCF = (PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL)pPrivateData;
-
- vboxWddmPopulateDmaAllocInfo(&pCF->ClrFill.Alloc, pDstAlloc, pDst);
- pCF->ClrFill.Color = pPresent->Color;
- pCF->ClrFill.Rects.cRects = 0;
- UINT cbHead = RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_CLRFILL, ClrFill.Rects.aRects[0]);
- Assert(pPresent->SubRectCnt > pPresent->MultipassOffset);
- UINT cbRects = (pPresent->SubRectCnt - pPresent->MultipassOffset) * sizeof (RECT);
- pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + cbHead + cbRects;
- pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + VBOXWDDM_DUMMY_DMABUFFER_SIZE;
- Assert(pPresent->DmaSize >= VBOXWDDM_DUMMY_DMABUFFER_SIZE);
- cbCmd -= cbHead;
- Assert(cbCmd < UINT32_MAX/2);
- Assert(cbCmd > sizeof (RECT));
- if (cbCmd >= cbRects)
- {
- cbCmd -= cbRects;
- memcpy(&pCF->ClrFill.Rects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbRects);
- pCF->ClrFill.Rects.cRects += cbRects/sizeof (RECT);
- }
- else
- {
- UINT cbFitingRects = (cbCmd/sizeof (RECT)) * sizeof (RECT);
- Assert(cbFitingRects);
- memcpy(&pCF->ClrFill.Rects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbFitingRects);
- cbCmd -= cbFitingRects;
- pPresent->MultipassOffset += cbFitingRects/sizeof (RECT);
- pCF->ClrFill.Rects.cRects += cbFitingRects/sizeof (RECT);
- Assert(pPresent->SubRectCnt > pPresent->MultipassOffset);
- Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
- }
+ /* this should not happen actually */
+ WARN(("failed to get pDst Allocation info for hDeviceSpecificAllocation(0x%x)",pDst->hDeviceSpecificAllocation));
+ Status = STATUS_INVALID_HANDLE;
+ goto done;
+ }
- memset(pPresent->pPatchLocationListOut, 0, sizeof (D3DDDI_PATCHLOCATIONLIST));
- pPresent->pPatchLocationListOut->PatchOffset = 0;
- pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_DESTINATION_INDEX;
- ++pPresent->pPatchLocationListOut;
+ UINT cbCmd = pPresent->DmaBufferPrivateDataSize;
+ pPrivateData->BaseHdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_CLRFILL;
+ PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL pCF = (PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL)pPrivateData;
+
+ vboxWddmPopulateDmaAllocInfo(&pCF->ClrFill.Alloc, pDstAlloc, pDst);
+
+ pCF->ClrFill.Color = pPresent->Color;
+ pCF->ClrFill.Rects.cRects = 0;
+ UINT cbHead = RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_CLRFILL, ClrFill.Rects.aRects[0]);
+ Assert(pPresent->SubRectCnt > pPresent->MultipassOffset);
+ UINT cbRects = (pPresent->SubRectCnt - pPresent->MultipassOffset) * sizeof (RECT);
+ pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + cbHead + cbRects;
+ pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + VBOXWDDM_DUMMY_DMABUFFER_SIZE;
+ Assert(pPresent->DmaSize >= VBOXWDDM_DUMMY_DMABUFFER_SIZE);
+ cbCmd -= cbHead;
+ Assert(cbCmd < UINT32_MAX/2);
+ Assert(cbCmd > sizeof (RECT));
+ if (cbCmd >= cbRects)
+ {
+ cbCmd -= cbRects;
+ memcpy(&pCF->ClrFill.Rects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbRects);
+ pCF->ClrFill.Rects.cRects += cbRects/sizeof (RECT);
}
else
{
- /* this should not happen actually */
- LOGREL(("failed to get pDst Allocation info for hDeviceSpecificAllocation(0x%x)",pDst->hDeviceSpecificAllocation));
- Status = STATUS_INVALID_HANDLE;
+ UINT cbFitingRects = (cbCmd/sizeof (RECT)) * sizeof (RECT);
+ Assert(cbFitingRects);
+ memcpy(&pCF->ClrFill.Rects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbFitingRects);
+ cbCmd -= cbFitingRects;
+ pPresent->MultipassOffset += cbFitingRects/sizeof (RECT);
+ pCF->ClrFill.Rects.cRects += cbFitingRects/sizeof (RECT);
+ Assert(pPresent->SubRectCnt > pPresent->MultipassOffset);
+ Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
}
+ memset(pPresent->pPatchLocationListOut, 0, sizeof (D3DDDI_PATCHLOCATIONLIST));
+ pPresent->pPatchLocationListOut->PatchOffset = 0;
+ pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_DESTINATION_INDEX;
+ ++pPresent->pPatchLocationListOut;
}
else
{
- LOGREL(("cmd NOT IMPLEMENTED!! Flags(0x%x)", pPresent->Flags.Value));
- AssertBreakpoint();
+ WARN(("cmd NOT IMPLEMENTED!! Flags(0x%x)", pPresent->Flags.Value));
+ Status = STATUS_NOT_SUPPORTED;
}
+done:
// LOGF(("LEAVE, hContext(0x%x), Status(0x%x)", hContext, Status));
return Status;
@@ -6100,10 +6600,20 @@ DxgkDdiCreateContext(
pContext->enmType = VBOXWDDM_CONTEXT_TYPE_SYSTEM;
for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
{
- pDevExt->aSources[i].bGhSynced = FALSE;
+ pDevExt->aSources[i].u8SyncState = 0;
NTSTATUS tmpStatus= vboxWddmDisplaySettingsQueryPos(pDevExt, i, &pDevExt->aSources[i].VScreenPos);
Assert(tmpStatus == STATUS_SUCCESS);
}
+
+ if (!VBOXWDDM_IS_DISPLAYONLY() && pDevExt->f3DEnabled)
+ {
+ VBoxMpCrPackerInit(&pContext->CrPacker);
+ int rc = VBoxMpCrCtlConConnect(&pDevExt->CrCtlCon, CR_PROTOCOL_VERSION_MAJOR, CR_PROTOCOL_VERSION_MINOR, &pContext->u32CrConClientID);
+ if (!RT_SUCCESS(rc))
+ WARN(("VBoxMpCrCtlConConnect failed rc (%d), ignoring for system context", rc));
+ }
+
+ Status = STATUS_SUCCESS;
}
else
{
@@ -6130,20 +6640,31 @@ DxgkDdiCreateContext(
Assert(Status == STATUS_SUCCESS);
if (Status == STATUS_SUCCESS)
{
- int rc = VINF_SUCCESS;
if (pInfo->crVersionMajor || pInfo->crVersionMinor)
{
- rc = VBoxMpCrCtlConConnect(&pDevExt->CrCtlCon,
- pInfo->crVersionMajor, pInfo->crVersionMinor,
- &pContext->u32CrConClientID);
- if (!RT_SUCCESS(rc))
+ if (pDevExt->f3DEnabled)
+ {
+ int rc = VBoxMpCrCtlConConnect(&pDevExt->CrCtlCon,
+ pInfo->crVersionMajor, pInfo->crVersionMinor,
+ &pContext->u32CrConClientID);
+ if (RT_SUCCESS(rc))
+ {
+ VBoxMpCrPackerInit(&pContext->CrPacker);
+ }
+ else
+ {
+ WARN(("VBoxMpCrCtlConConnect failed rc (%d)", rc));
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ }
+ else
{
- WARN(("VBoxMpCrCtlConConnect failed rc (%d)", rc));
+ LOG(("3D Not Enabled, failing 3D context creation"));
Status = STATUS_UNSUCCESSFUL;
}
}
- if (RT_SUCCESS(rc))
+ if (NT_SUCCESS(Status))
{
ASMAtomicIncU32(&pDevExt->cContexts3D);
break;
@@ -6164,20 +6685,27 @@ DxgkDdiCreateContext(
Assert(Status == STATUS_SUCCESS);
if (Status == STATUS_SUCCESS)
{
- int rc = VINF_SUCCESS;
if (pInfo->crVersionMajor || pInfo->crVersionMinor)
{
- rc = VBoxMpCrCtlConConnect(&pDevExt->CrCtlCon,
- pInfo->crVersionMajor, pInfo->crVersionMinor,
- &pContext->u32CrConClientID);
- if (!RT_SUCCESS(rc))
+ if (pDevExt->f3DEnabled)
{
- WARN(("VBoxMpCrCtlConConnect failed rc (%d)", rc));
+ int rc = VBoxMpCrCtlConConnect(&pDevExt->CrCtlCon,
+ pInfo->crVersionMajor, pInfo->crVersionMinor,
+ &pContext->u32CrConClientID);
+ if (!RT_SUCCESS(rc))
+ {
+ WARN(("VBoxMpCrCtlConConnect failed rc (%d)", rc));
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ }
+ else
+ {
+ LOG(("3D Not Enabled, failing 3D (hgsmi) context creation"));
Status = STATUS_UNSUCCESSFUL;
}
}
- if (RT_SUCCESS(rc))
+ if (NT_SUCCESS(Status))
{
ASMAtomicIncU32(&pDevExt->cContexts3D);
break;
@@ -6192,9 +6720,25 @@ DxgkDdiCreateContext(
ASMAtomicIncU32(&pDevExt->cContexts2D);
break;
}
+ case VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_RESIZE:
+ {
+ pContext->enmType = pInfo->enmType;
+ ASMAtomicIncU32(&pDevExt->cContextsDispIfResize);
+ break;
+ }
+ case VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_SEAMLESS:
+ {
+ pContext->enmType = pInfo->enmType;
+ Status = vboxVideoCmCtxAdd(&pDevice->pAdapter->SeamlessCtxMgr, &pContext->CmContext, (HANDLE)pInfo->hUmEvent, pInfo->u64UmInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ WARN(("vboxVideoCmCtxAdd failed, Status 0x%x", Status));
+ }
+ break;
+ }
default:
{
- Assert(0);
+ WARN(("unsupported context type %d", pInfo->enmType));
Status = STATUS_INVALID_PARAMETER;
break;
}
@@ -6235,6 +6779,8 @@ DxgkDdiDestroyContext(
vboxVDbgBreakFv();
PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)hContext;
PVBOXMP_DEVEXT pDevExt = pContext->pDevice->pAdapter;
+ NTSTATUS Status = STATUS_SUCCESS;
+
switch(pContext->enmType)
{
case VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D:
@@ -6243,10 +6789,6 @@ DxgkDdiDestroyContext(
{
uint32_t cContexts = ASMAtomicDecU32(&pDevExt->cContexts3D);
Assert(cContexts < UINT32_MAX/2);
- if (pContext->u32CrConClientID)
- {
- VBoxMpCrCtlConDisconnect(&pDevExt->CrCtlCon, pContext->u32CrConClientID);
- }
break;
}
case VBOXWDDM_CONTEXT_TYPE_CUSTOM_2D:
@@ -6255,10 +6797,37 @@ DxgkDdiDestroyContext(
Assert(cContexts < UINT32_MAX/2);
break;
}
+ case VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_RESIZE:
+ {
+ uint32_t cContexts = ASMAtomicDecU32(&pDevExt->cContextsDispIfResize);
+ Assert(cContexts < UINT32_MAX/2);
+ if (!cContexts)
+ {
+ for (int i = 0; i < VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
+ {
+ vboxWddmGhDisplayCheckCompletePeningScreenInfo(pDevExt, i);
+ }
+ }
+ break;
+ }
+ case VBOXWDDM_CONTEXT_TYPE_CUSTOM_DISPIF_SEAMLESS:
+ {
+ Status = vboxVideoCmCtxRemove(&pContext->pDevice->pAdapter->SeamlessCtxMgr, &pContext->CmContext);
+ if (!NT_SUCCESS(Status))
+ WARN(("vboxVideoCmCtxRemove failed, Status 0x%x", Status));
+
+ Assert(pContext->CmContext.pSession == NULL);
+ break;
+ }
default:
break;
}
+ if (pContext->u32CrConClientID)
+ {
+ VBoxMpCrCtlConDisconnect(&pDevExt->CrCtlCon, pContext->u32CrConClientID);
+ }
+
vboxWddmModeRenderFromShadowDisableUnregister(pDevExt, pContext);
/* first terminate the swapchain, this will also ensure
@@ -6266,17 +6835,17 @@ DxgkDdiDestroyContext(
* (i.e. visible regions commands) are completed */
vboxWddmSwapchainCtxTerm(pDevExt, pContext);
- NTSTATUS Status = vboxVideoAMgrCtxDestroy(&pContext->AllocContext);
- Assert(Status == STATUS_SUCCESS);
- if (Status == STATUS_SUCCESS)
+ Status = vboxVideoAMgrCtxDestroy(&pContext->AllocContext);
+ if (NT_SUCCESS(Status))
{
Status = vboxVideoCmCtxRemove(&pContext->pDevice->pAdapter->CmMgr, &pContext->CmContext);
- Assert(Status == STATUS_SUCCESS);
- if (Status == STATUS_SUCCESS)
- {
+ if (NT_SUCCESS(Status))
vboxWddmMemFree(pContext);
- }
+ else
+ WARN(("vboxVideoCmCtxRemove failed, Status 0x%x", Status));
}
+ else
+ WARN(("vboxVideoAMgrCtxDestroy failed, Status 0x%x", Status));
LOGF(("LEAVE, hContext(0x%x)", hContext));
@@ -6380,6 +6949,8 @@ static NTSTATUS APIENTRY DxgkDdiPresentDisplayOnly(
SrcAllocData.SurfDesc.cbSize = ~0UL;
SrcAllocData.Addr.SegmentId = 0;
SrcAllocData.Addr.pvMem = pPresentDisplayOnly->pSource;
+ SrcAllocData.hostID = 0;
+ SrcAllocData.pSwapchain = NULL;
RECT UpdateRect;
BOOLEAN bUpdateRectInited = FALSE;
@@ -6528,8 +7099,8 @@ static NTSTATUS vboxWddmInitDisplayOnlyDriver(IN PDRIVER_OBJECT pDriverObject, I
DriverInitializationData.DxgkDdiStopDevice = DxgkDdiStopDevice;
DriverInitializationData.DxgkDdiRemoveDevice = DxgkDdiRemoveDevice;
DriverInitializationData.DxgkDdiDispatchIoRequest = DxgkDdiDispatchIoRequest;
- DriverInitializationData.DxgkDdiInterruptRoutine = DxgkDdiInterruptRoutine;
- DriverInitializationData.DxgkDdiDpcRoutine = DxgkDdiDpcRoutine;
+ DriverInitializationData.DxgkDdiInterruptRoutine = DxgkDdiInterruptRoutineLegacy;
+ DriverInitializationData.DxgkDdiDpcRoutine = DxgkDdiDpcRoutineLegacy;
DriverInitializationData.DxgkDdiQueryChildRelations = DxgkDdiQueryChildRelations;
DriverInitializationData.DxgkDdiQueryChildStatus = DxgkDdiQueryChildStatus;
DriverInitializationData.DxgkDdiQueryDeviceDescriptor = DxgkDdiQueryDeviceDescriptor;
@@ -6575,8 +7146,10 @@ static NTSTATUS vboxWddmInitDisplayOnlyDriver(IN PDRIVER_OBJECT pDriverObject, I
}
#endif
-static NTSTATUS vboxWddmInitFullGraphicsDriver(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
+static NTSTATUS vboxWddmInitFullGraphicsDriver(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath, BOOLEAN fCmdVbva)
{
+#define VBOXWDDM_CALLBACK_NAME(_base, _fCmdVbva) ((_fCmdVbva) ? _base##New : _base##Legacy)
+
DRIVER_INITIALIZATION_DATA DriverInitializationData = {'\0'};
// Fill in the DriverInitializationData structure and call DxgkInitialize()
@@ -6587,8 +7160,8 @@ static NTSTATUS vboxWddmInitFullGraphicsDriver(IN PDRIVER_OBJECT pDriverObject,
DriverInitializationData.DxgkDdiStopDevice = DxgkDdiStopDevice;
DriverInitializationData.DxgkDdiRemoveDevice = DxgkDdiRemoveDevice;
DriverInitializationData.DxgkDdiDispatchIoRequest = DxgkDdiDispatchIoRequest;
- DriverInitializationData.DxgkDdiInterruptRoutine = DxgkDdiInterruptRoutine;
- DriverInitializationData.DxgkDdiDpcRoutine = DxgkDdiDpcRoutine;
+ DriverInitializationData.DxgkDdiInterruptRoutine = VBOXWDDM_CALLBACK_NAME(DxgkDdiInterruptRoutine, fCmdVbva);
+ DriverInitializationData.DxgkDdiDpcRoutine = VBOXWDDM_CALLBACK_NAME(DxgkDdiDpcRoutine, fCmdVbva);
DriverInitializationData.DxgkDdiQueryChildRelations = DxgkDdiQueryChildRelations;
DriverInitializationData.DxgkDdiQueryChildStatus = DxgkDdiQueryChildStatus;
DriverInitializationData.DxgkDdiQueryDeviceDescriptor = DxgkDdiQueryDeviceDescriptor;
@@ -6607,10 +7180,10 @@ static NTSTATUS vboxWddmInitFullGraphicsDriver(IN PDRIVER_OBJECT pDriverObject,
DriverInitializationData.DxgkDdiGetStandardAllocationDriverData = DxgkDdiGetStandardAllocationDriverData;
DriverInitializationData.DxgkDdiAcquireSwizzlingRange = DxgkDdiAcquireSwizzlingRange;
DriverInitializationData.DxgkDdiReleaseSwizzlingRange = DxgkDdiReleaseSwizzlingRange;
- DriverInitializationData.DxgkDdiPatch = DxgkDdiPatch;
- DriverInitializationData.DxgkDdiSubmitCommand = DxgkDdiSubmitCommand;
- DriverInitializationData.DxgkDdiPreemptCommand = DxgkDdiPreemptCommand;
- DriverInitializationData.DxgkDdiBuildPagingBuffer = DxgkDdiBuildPagingBuffer;
+ DriverInitializationData.DxgkDdiPatch = VBOXWDDM_CALLBACK_NAME(DxgkDdiPatch, fCmdVbva);
+ DriverInitializationData.DxgkDdiSubmitCommand = VBOXWDDM_CALLBACK_NAME(DxgkDdiSubmitCommand, fCmdVbva);
+ DriverInitializationData.DxgkDdiPreemptCommand = VBOXWDDM_CALLBACK_NAME(DxgkDdiPreemptCommand, fCmdVbva);
+ DriverInitializationData.DxgkDdiBuildPagingBuffer = VBOXWDDM_CALLBACK_NAME(DxgkDdiBuildPagingBuffer, fCmdVbva);
DriverInitializationData.DxgkDdiSetPalette = DxgkDdiSetPalette;
DriverInitializationData.DxgkDdiSetPointerPosition = DxgkDdiSetPointerPosition;
DriverInitializationData.DxgkDdiSetPointerShape = DxgkDdiSetPointerShape;
@@ -6618,7 +7191,7 @@ static NTSTATUS vboxWddmInitFullGraphicsDriver(IN PDRIVER_OBJECT pDriverObject,
DriverInitializationData.DxgkDdiRestartFromTimeout = DxgkDdiRestartFromTimeout;
DriverInitializationData.DxgkDdiEscape = DxgkDdiEscape;
DriverInitializationData.DxgkDdiCollectDbgInfo = DxgkDdiCollectDbgInfo;
- DriverInitializationData.DxgkDdiQueryCurrentFence = DxgkDdiQueryCurrentFence;
+ DriverInitializationData.DxgkDdiQueryCurrentFence = VBOXWDDM_CALLBACK_NAME(DxgkDdiQueryCurrentFence, fCmdVbva);
DriverInitializationData.DxgkDdiIsSupportedVidPn = DxgkDdiIsSupportedVidPn;
DriverInitializationData.DxgkDdiRecommendFunctionalVidPn = DxgkDdiRecommendFunctionalVidPn;
DriverInitializationData.DxgkDdiEnumVidPnCofuncModality = DxgkDdiEnumVidPnCofuncModality;
@@ -6636,8 +7209,8 @@ static NTSTATUS vboxWddmInitFullGraphicsDriver(IN PDRIVER_OBJECT pDriverObject,
DriverInitializationData.DxgkDdiDestroyDevice = DxgkDdiDestroyDevice;
DriverInitializationData.DxgkDdiOpenAllocation = DxgkDdiOpenAllocation;
DriverInitializationData.DxgkDdiCloseAllocation = DxgkDdiCloseAllocation;
- DriverInitializationData.DxgkDdiRender = DxgkDdiRender;
- DriverInitializationData.DxgkDdiPresent = DxgkDdiPresent;
+ DriverInitializationData.DxgkDdiRender = VBOXWDDM_CALLBACK_NAME(DxgkDdiRender, fCmdVbva);
+ DriverInitializationData.DxgkDdiPresent = VBOXWDDM_CALLBACK_NAME(DxgkDdiPresent, fCmdVbva);
DriverInitializationData.DxgkDdiUpdateOverlay = DxgkDdiUpdateOverlay;
DriverInitializationData.DxgkDdiFlipOverlay = DxgkDdiFlipOverlay;
@@ -6677,14 +7250,14 @@ DriverEntry(
vboxVDbgBreakFv();
-#ifdef DEBUG_misha
+#if 0//def DEBUG_misha
RTLogGroupSettings(0, "+default.e.l.f.l2.l3");
#endif
#ifdef VBOX_WDDM_WIN8
- LOGREL(("VBox WDDM Driver for Windows 8; Built %s %s", __DATE__, __TIME__));
+ LOGREL(("VBox WDDM Driver for Windows 8, %d bit; Built %s %s", (sizeof (void*) << 3), __DATE__, __TIME__));
#else
- LOGREL(("VBox WDDM Driver for Windows Vista and 7; Built %s %s", __DATE__, __TIME__));
+ LOGREL(("VBox WDDM Driver for Windows Vista and 7, %d bit; Built %s %s", (sizeof (void*) << 3), __DATE__, __TIME__));
#endif
if (! ARGUMENT_PRESENT(DriverObject) ||
@@ -6697,7 +7270,7 @@ DriverEntry(
ULONG major, minor, build;
BOOLEAN checkedBuild = PsGetVersion(&major, &minor, &build, NULL);
- BOOLEAN f3DCheckRequired = FALSE;
+ BOOLEAN f3DRequired = FALSE;
LOGREL(("OsVersion( %d, %d, %d )", major, minor, build));
@@ -6709,47 +7282,53 @@ DriverEntry(
if (major > 6)
{
WARN(("Unknow win version, newer major release, assuming 3D check is required"));
- f3DCheckRequired = TRUE;
+ f3DRequired = TRUE;
}
else if (major == 6)
{
- if (minor > 2)
+ if (minor > 3)
{
WARN(("Unknow win version, newer minor release, assuming 3D check is required"));
- f3DCheckRequired = TRUE;
+ f3DRequired = TRUE;
}
- else if (minor == 2)
+ else if (minor >= 2)
{
LOG(("3D check is required!"));
- f3DCheckRequired = TRUE;
+ f3DRequired = TRUE;
}
else
{
LOG(("3D is NOT required!"));
- f3DCheckRequired = FALSE;
+ f3DRequired = FALSE;
}
}
else
{
WARN(("Unsupported OLDER win version, ignore and assume 3D is NOT required"));
- f3DCheckRequired = FALSE;
+ f3DRequired = FALSE;
}
Status = STATUS_SUCCESS;
- if (f3DCheckRequired)
+ VBoxMpCrCtlConInit();
+
+ /* always need to do the check to request host caps */
+ LOG(("Doing the 3D check.."));
+ if (!VBoxMpCrCtlConIs3DSupported())
{
- LOG(("3D check is required, doing the 3D check.."));
- if (!VBoxMpCrCtlConIs3DSupported())
- {
#ifdef VBOX_WDDM_WIN8
- LOGREL(("3D is NOT supported by the host, falling back to display-only mode.."));
- g_VBoxDisplayOnly = 1;
+ Assert(f3DRequired);
+ LOGREL(("3D is NOT supported by the host, falling back to display-only mode.."));
+ g_VBoxDisplayOnly = 1;
#else
+ if (f3DRequired)
+ {
LOGREL(("3D is NOT supported by the host, but is required for the current guest version using this driver.."));
Status = STATUS_UNSUCCESSFUL;
-#endif
}
+ else
+ LOGREL(("3D is NOT supported by the host, but is NOT required for the current guest version using this driver, continuing with Disabled 3D.."));
+#endif
}
#if 0 //defined(DEBUG_misha) && defined(VBOX_WDDM_WIN8)
@@ -6760,8 +7339,8 @@ DriverEntry(
if (NT_SUCCESS(Status))
{
- Status = VBoxWddmVrInit();
- if (NT_SUCCESS(Status))
+ rc = VBoxVrInit();
+ if (RT_SUCCESS(rc))
{
#ifdef VBOX_WDDM_WIN8
if (g_VBoxDisplayOnly)
@@ -6771,16 +7350,19 @@ DriverEntry(
else
#endif
{
- Status = vboxWddmInitFullGraphicsDriver(DriverObject, RegistryPath);
+ Status = vboxWddmInitFullGraphicsDriver(DriverObject, RegistryPath, !!(VBoxMpCrGetHostCaps() & CR_VBOX_CAP_CMDVBVA));
}
if (NT_SUCCESS(Status))
return Status;
- VBoxWddmVrTerm();
+ VBoxVrTerm();
}
else
- WARN(("VBoxWddmVrInit failed, Status(0x%x)", Status));
+ {
+ WARN(("VBoxVrInit failed, rc(%d)", rc));
+ Status = STATUS_UNSUCCESSFUL;
+ }
}
else
LOGREL(("Aborting the video driver load due to 3D support missing"));
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.h b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.h
index bed17c57..ab50708e 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -36,13 +36,32 @@
//#define VBOXWDDM_DEBUG_VIDPN
+#define VBOXWDDM_CFG_DRV_DEFAULT 0
+#define VBOXWDDM_CFG_DRV_SECONDARY_TARGETS_CONNECTED 1
+
+#define VBOXWDDM_CFG_DRVTARGET_CONNECTED 1
+
#define VBOXWDDM_CFG_LOG_UM_BACKDOOR 0x00000001
#define VBOXWDDM_CFG_LOG_UM_DBGPRINT 0x00000002
#define VBOXWDDM_CFG_STR_LOG_UM L"VBoxLogUm"
+
+#define VBOXWDDM_REG_DRV_FLAGS_NAME L"VBoxFlags"
+#define VBOXWDDM_REG_DRV_DISPFLAGS_PREFIX L"VBoxDispFlags"
+
+#define VBOXWDDM_REG_DRVKEY_PREFIX L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\"
+
+#define VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\"
+#define VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY_SUBKEY L"\\Video"
+
+
+#define VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_VISTA L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Control\\VIDEO\\"
+#define VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_WIN7 L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\UnitedVideo\\CONTROL\\VIDEO\\"
+
+#define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_RELX L"Attach.RelativeX"
+#define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_RELY L"Attach.RelativeY"
+#define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_DESKTOP L"Attach.ToDesktop"
+
extern DWORD g_VBoxLogUm;
-#ifdef VBOX_WDDM_WIN8
-extern DWORD g_VBoxDisplayOnly;
-#endif
RT_C_DECLS_BEGIN
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
@@ -83,10 +102,14 @@ DECLINLINE(VOID) vboxWddmAllocationRetain(PVBOXWDDM_ALLOCATION pAllocation)
ASMAtomicIncU32(&pAllocation->cRefs);
}
-DECLINLINE(VOID) vboxWddmAddrSetVram(PVBOXWDDM_ADDR pAddr, UINT SegmentId, VBOXVIDEOOFFSET offVram)
+DECLINLINE(BOOLEAN) vboxWddmAddrSetVram(PVBOXWDDM_ADDR pAddr, UINT SegmentId, VBOXVIDEOOFFSET offVram)
{
+ if (pAddr->SegmentId == SegmentId && pAddr->offVram == offVram)
+ return FALSE;
+
pAddr->SegmentId = SegmentId;
pAddr->offVram = offVram;
+ return TRUE;
}
DECLINLINE(bool) vboxWddmAddrVramEqual(PVBOXWDDM_ADDR pAddr1, PVBOXWDDM_ADDR pAddr2)
@@ -104,6 +127,12 @@ DECLINLINE(VBOXVIDEOOFFSET) vboxWddmVramAddrToOffset(PVBOXMP_DEVEXT pDevExt, PHY
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
DECLINLINE(void) vboxWddmAssignShadow(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource, PVBOXWDDM_ALLOCATION pAllocation, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId)
{
+ if (pDevExt->fCmdVbvaEnabled)
+ {
+ WARN(("Trying to assign shadow surface for CmdVbva enabled mode!"));
+ return;
+ }
+
if (pSource->pShadowAllocation == pAllocation)
{
Assert(pAllocation->bAssigned);
@@ -132,9 +161,18 @@ DECLINLINE(void) vboxWddmAssignShadow(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE p
pAllocation->bVisible = pSource->bVisible;
if(!vboxWddmAddrVramEqual(&pSource->AllocData.Addr, &pAllocation->AllocData.Addr))
- pSource->bGhSynced = FALSE; /* force guest->host notification */
- pSource->AllocData.Addr = pAllocation->AllocData.Addr;
+ {
+ pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_LOCATION; /* force guest->host notification */
+ pSource->AllocData.Addr = pAllocation->AllocData.Addr;
+ }
+ if (pSource->AllocData.hostID != pAllocation->AllocData.hostID)
+ {
+ pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_LOCATION; /* force guest->host notification */
+ pSource->AllocData.hostID = pAllocation->AllocData.hostID;
+ }
}
+ else
+ pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_LOCATION; /* force guest->host notification */
pSource->pShadowAllocation = pAllocation;
}
@@ -164,11 +202,20 @@ DECLINLINE(VOID) vboxWddmAssignPrimary(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE
pAllocation->bVisible = pSource->bVisible;
if(!vboxWddmAddrVramEqual(&pSource->AllocData.Addr, &pAllocation->AllocData.Addr))
- pSource->bGhSynced = FALSE; /* force guest->host notification */
- pSource->AllocData.Addr = pAllocation->AllocData.Addr;
+ {
+ pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_LOCATION; /* force guest->host notification */
+ pSource->AllocData.Addr = pAllocation->AllocData.Addr;
+ }
+ if (pSource->AllocData.hostID != pAllocation->AllocData.hostID)
+ {
+ pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_LOCATION; /* force guest->host notification */
+ pSource->AllocData.hostID = pAllocation->AllocData.hostID;
+ }
vboxWddmAllocationRetain(pAllocation);
}
+ else
+ pSource->u8SyncState &= ~VBOXWDDM_HGSYNC_F_SYNCED_LOCATION; /* force guest->host notification */
KIRQL OldIrql;
KeAcquireSpinLock(&pSource->AllocationLock, &OldIrql);
@@ -188,31 +235,60 @@ DECLINLINE(PVBOXWDDM_ALLOCATION) vboxWddmAquirePrimary(PVBOXMP_DEVEXT pDevExt, P
return pPrimary;
}
+bool vboxWddmGhDisplayCheckSetInfoFromSource(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource);
+
#define VBOXWDDMENTRY_2_SWAPCHAIN(_pE) ((PVBOXWDDM_SWAPCHAIN)((uint8_t*)(_pE) - RT_OFFSETOF(VBOXWDDM_SWAPCHAIN, DevExtListEntry)))
+BOOLEAN DxgkDdiInterruptRoutineNew(
+ IN CONST PVOID MiniportDeviceContext,
+ IN ULONG MessageNumber
+ );
+
+#ifdef VBOX_WDDM_WIN8
+# define VBOXWDDM_IS_DISPLAYONLY() (g_VBoxDisplayOnly)
+#else
+# define VBOXWDDM_IS_DISPLAYONLY() (FALSE)
+#endif
+
#ifdef VBOXWDDM_RENDER_FROM_SHADOW
-# ifdef VBOX_WDDM_WIN8
-# define VBOXWDDM_IS_FB_ALLOCATION(_pDevExt, _pAlloc) ( (_pAlloc)->bAssigned \
- && ( (_pAlloc)->enmType == VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC \
+
+# define VBOXWDDM_IS_FB_ALLOCATION(_pDevExt, _pAlloc) ( (_pAlloc)->bAssigned \
+ && ( (_pAlloc)->AllocData.hostID \
|| (_pAlloc)->enmType == \
- ((g_VBoxDisplayOnly || (_pDevExt)->fRenderToShadowDisabled) ? VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE : VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE) \
+ ((VBOXWDDM_IS_DISPLAYONLY() || (_pDevExt)->fRenderToShadowDisabled) ? VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE : VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE) \
))
-# else
-# define VBOXWDDM_IS_FB_ALLOCATION(_pDevExt, _pAlloc) ( (_pAlloc)->bAssigned \
- && ( (_pAlloc)->enmType == VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC \
- || (_pAlloc)->enmType == \
- (((_pDevExt)->fRenderToShadowDisabled) ? VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE : VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE) \
+
+# define VBOXWDDM_IS_REAL_FB_ALLOCATION(_pDevExt, _pAlloc) ( (_pAlloc)->bAssigned \
+ && ( (_pAlloc)->AllocData.hostID \
+ || (_pAlloc)->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE \
))
-# endif
+
# define VBOXWDDM_FB_ALLOCATION(_pDevExt, _pSrc) ( ((_pSrc)->pPrimaryAllocation && VBOXWDDM_IS_FB_ALLOCATION(_pDevExt, (_pSrc)->pPrimaryAllocation)) ? \
(_pSrc)->pPrimaryAllocation : ( \
((_pSrc)->pShadowAllocation && VBOXWDDM_IS_FB_ALLOCATION(_pDevExt, (_pSrc)->pShadowAllocation)) ? \
(_pSrc)->pShadowAllocation : NULL \
) \
)
+# define VBOXWDDM_NONFB_ALLOCATION(_pDevExt, _pSrc) ( !((_pSrc)->pPrimaryAllocation && VBOXWDDM_IS_FB_ALLOCATION(_pDevExt, (_pSrc)->pPrimaryAllocation)) ? \
+ (_pSrc)->pPrimaryAllocation : ( \
+ ((_pSrc)->pShadowAllocation && VBOXWDDM_IS_FB_ALLOCATION(_pDevExt, (_pSrc)->pShadowAllocation)) ? \
+ (_pSrc)->pShadowAllocation : NULL \
+ ) \
+ )
#else
# define VBOXWDDM_FB_ALLOCATION(_pDevExt, _pSrc) ((_pSrc)->pPrimaryAllocation)
#endif
+#define VBOXWDDM_CTXLOCK_INIT(_p) do { \
+ KeInitializeSpinLock(&(_p)->ContextLock); \
+ } while (0)
+#define VBOXWDDM_CTXLOCK_DATA KIRQL _ctxLockOldIrql;
+#define VBOXWDDM_CTXLOCK_LOCK(_p) do { \
+ KeAcquireSpinLock(&(_p)->ContextLock, &_ctxLockOldIrql); \
+ } while (0)
+#define VBOXWDDM_CTXLOCK_UNLOCK(_p) do { \
+ KeReleaseSpinLock(&(_p)->ContextLock, _ctxLockOldIrql); \
+ } while (0)
+
#endif /* #ifndef ___VBoxMPWddm_h___ */
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.rc b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.rc
index 435a9a5a..e4d271d9 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.rc
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.rc
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxVideoWddm.inf b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxVideoWddm.inf
index 6cfda59e..9a2e7c87 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxVideoWddm.inf
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxVideoWddm.inf
@@ -1,7 +1,7 @@
;
; VirtualBox Video Wddm driver
;
-; Copyright (C) 2011 Oracle Corporation
+; Copyright (C) 2011-2012 Oracle Corporation
;
; This file is part of VirtualBox Open Source Edition (OSE), as
; available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPDriver.cpp b/src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPDriver.cpp
index 6bb3d7d0..e448468e 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPDriver.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPDriver.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -147,6 +147,18 @@ VBoxDrvFindAdapter(IN PVOID HwDeviceExtension, IN PVOID HwContext, IN PWSTR Argu
*/
VBoxSetupDisplaysHGSMI(&pExt->u.primary.commonInfo, phVRAM, ulApertureSize, cbVRAM, 0);
+ /* Check if the chip restricts horizontal resolution or not.
+ * Must be done after VBoxSetupDisplaysHGSMI, because it initializes the common structure.
+ */
+ VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
+ VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_ANYX);
+ DispiId = VideoPortReadPortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA);
+
+ if (DispiId == VBE_DISPI_ID_ANYX)
+ VBoxCommonFromDeviceExt(pExt)->fAnyX = TRUE;
+ else
+ VBoxCommonFromDeviceExt(pExt)->fAnyX = FALSE;
+
if (pExt->u.primary.commonInfo.bHGSMI)
{
LOGREL(("using HGSMI"));
@@ -166,7 +178,6 @@ static BOOLEAN
VBoxDrvInitialize(PVOID HwDeviceExtension)
{
PVBOXMP_DEVEXT pExt = (PVBOXMP_DEVEXT) HwDeviceExtension;
- USHORT DispiId;
PAGED_CODE();
LOGF_ENTER();
@@ -174,16 +185,6 @@ VBoxDrvInitialize(PVOID HwDeviceExtension)
/* Initialize the request pointer. */
pExt->u.primary.pvReqFlush = NULL;
- /* Check if the chip restricts horizontal resolution or not. */
- VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
- VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_ANYX);
- DispiId = VideoPortReadPortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA);
-
- if (DispiId == VBE_DISPI_ID_ANYX)
- pExt->fAnyX = TRUE;
- else
- pExt->fAnyX = FALSE;
-
VBoxMPCmnInitCustomVideoModes(pExt);
LOGF_LEAVE();
@@ -308,7 +309,7 @@ VBoxDrvStartIO(PVOID HwDeviceExtension, PVIDEO_REQUEST_PACKET RequestPacket)
{
PVIDEO_MODE_INFORMATION pModes = (PVIDEO_MODE_INFORMATION) RequestPacket->OutputBuffer;
- if (RequestPacket->OutputBufferLength < VBoxMPXpdmGetVideoModesCount()*sizeof(VIDEO_MODE_INFORMATION))
+ if (RequestPacket->OutputBufferLength < VBoxMPXpdmGetVideoModesCount(pExt)*sizeof(VIDEO_MODE_INFORMATION))
{
pStatus->Status = ERROR_INSUFFICIENT_BUFFER;
break;
@@ -538,12 +539,29 @@ VBoxDrvStartIO(PVOID HwDeviceExtension, PVIDEO_REQUEST_PACKET RequestPacket)
case IOCTL_VIDEO_VBOX_ISANYX:
{
STARTIO_OUT(uint32_t, pu32AnyX);
- *pu32AnyX = pExt->fAnyX;
+ *pu32AnyX = VBoxCommonFromDeviceExt(pExt)->fAnyX;
pStatus->Information = sizeof (uint32_t);
bResult = TRUE;
break;
}
+ case IOCTL_VIDEO_QUERY_VBOXVIDEO_INFO:
+ {
+ STARTIO_IN(ULONG, pulInfoLevel);
+ if (*pulInfoLevel == VBOXVIDEO_INFO_LEVEL_REGISTRY_FLAGS)
+ {
+ STARTIO_OUT(ULONG, pulFlags);
+ bResult = VBoxMPQueryRegistryFlags(pExt, pulFlags, pStatus);
+ }
+ else
+ {
+ pStatus->Status = ERROR_INVALID_PARAMETER;
+ bResult = FALSE;
+ }
+
+ break;
+ }
+
default:
{
WARN(("unsupported IOCTL %p, fn(%#x)",
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPIOCTL.cpp b/src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPIOCTL.cpp
index 3769fbe1..772f6c92 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPIOCTL.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPIOCTL.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -192,15 +192,15 @@ BOOLEAN VBoxMPSetCurrentMode(PVBOXMP_DEVEXT pExt, PVIDEO_MODE pMode, PSTATUS_BLO
WARN(("ignoring set VIDEO_MODE_NO_ZERO_MEMORY or VIDEO_MODE_MAP_MEM_LINEAR"));
}
- pModeInfo = VBoxMPCmnGetVideoModeInfo(RequestedMode-1);
+ pModeInfo = VBoxMPCmnGetVideoModeInfo(pExt, RequestedMode-1);
if (!pModeInfo)
{
pStatus->Status = ERROR_INVALID_PARAMETER;
return FALSE;
}
- LOG(("width %d, height %d, bpp %d",
- pModeInfo->VisScreenWidth, pModeInfo->VisScreenHeight, pModeInfo->BitsPerPlane));
+ LOG(("screen [%d] mode %d width %d, height %d, bpp %d",
+ pExt->iDevice, pModeInfo->ModeIndex, pModeInfo->VisScreenWidth, pModeInfo->VisScreenHeight, pModeInfo->BitsPerPlane));
/* Update device info */
pExt->CurrentMode = RequestedMode;
@@ -249,7 +249,7 @@ BOOLEAN VBoxMPQueryNumAvailModes(PVBOXMP_DEVEXT pExt, PVIDEO_NUM_MODES pNumModes
VBoxMPXpdmBuildVideoModesTable(pExt);
- pNumModes->NumModes = VBoxMPXpdmGetVideoModesCount();
+ pNumModes->NumModes = VBoxMPXpdmGetVideoModesCount(pExt);
pNumModes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION);
pStatus->Information = sizeof(VIDEO_NUM_MODES);
@@ -264,9 +264,9 @@ BOOLEAN VBoxMPQueryAvailModes(PVBOXMP_DEVEXT pExt, PVIDEO_MODE_INFORMATION pMode
{
LOGF_ENTER();
- ULONG ulSize = VBoxMPXpdmGetVideoModesCount()*sizeof(VIDEO_MODE_INFORMATION);
+ ULONG ulSize = VBoxMPXpdmGetVideoModesCount(pExt)*sizeof(VIDEO_MODE_INFORMATION);
pStatus->Information = ulSize;
- VideoPortMoveMemory(pModes, VBoxMPCmnGetVideoModeInfo(0), ulSize);
+ VideoPortMoveMemory(pModes, VBoxMPCmnGetVideoModeInfo(pExt, 0), ulSize);
LOGF_LEAVE();
return TRUE;
@@ -616,3 +616,35 @@ BOOLEAN VBoxMPVhwaQueryInfo(PVBOXMP_DEVEXT pExt, VHWAQUERYINFO *pInfo, PSTATUS_B
return bRC;
}
#endif
+
+BOOLEAN VBoxMPQueryRegistryFlags(PVBOXMP_DEVEXT pExt, ULONG *pulFlags, PSTATUS_BLOCK pStatus)
+{
+ BOOLEAN bRC = TRUE;
+ LOGF_ENTER();
+
+ VBOXMPCMNREGISTRY Registry;
+
+ int rc = VBoxMPCmnRegInit(pExt, &Registry);
+ VBOXMP_WARN_VPS_NOBP(rc);
+
+ if (rc == NO_ERROR)
+ {
+ uint32_t u32Flags = 0;
+ rc = VBoxMPCmnRegQueryDword(Registry, L"VBoxVideoFlags", &u32Flags);
+ VBOXMP_WARN_VPS_NOBP(rc);
+ if (rc != NO_ERROR)
+ {
+ u32Flags = 0;
+ }
+
+ LOG(("Registry flags 0x%08X", u32Flags));
+ *pulFlags = u32Flags;
+ pStatus->Information = sizeof(ULONG);
+ }
+
+ rc = VBoxMPCmnRegFini(Registry);
+ VBOXMP_WARN_VPS_NOBP(rc);
+
+ LOGF_LEAVE();
+ return bRC;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPInternal.cpp b/src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPInternal.cpp
index 97dd0d50..e7841d42 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPInternal.cpp
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPInternal.cpp
@@ -130,7 +130,10 @@ void VBoxCreateDisplays(PVBOXMP_DEVEXT pExt, PVIDEO_PORT_CONFIG_INFO pConfigInfo
PVBOXMP_DEVEXT pSExt = NULL;
VP_STATUS rc;
- rc = pAPI->pfnCreateSecondaryDisplay(pExt, (PVOID*)&pSExt, VIDEO_DUALVIEW_REMOVABLE);
+ /* If VIDEO_DUALVIEW_REMOVABLE is passed as the 3rd parameter, then
+ * the guest does not allow to choose the primary screen.
+ */
+ rc = pAPI->pfnCreateSecondaryDisplay(pExt, (PVOID*)&pSExt, 0);
VBOXMP_WARN_VPS(rc);
if (rc != NO_ERROR)
diff --git a/src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPInternal.h b/src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPInternal.h
index fd9628b8..14ed1571 100644
--- a/src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPInternal.h
+++ b/src/VBox/Additions/WINNT/Graphics/Video/mp/xpdm/VBoxMPInternal.h
@@ -61,5 +61,6 @@ BOOLEAN VBoxMPHGSMIQueryCallbacks(PVBOXMP_DEVEXT pExt, HGSMIQUERYCALLBACKS *pCal
BOOLEAN VBoxMPQueryHgsmiInfo(PVBOXMP_DEVEXT pExt, QUERYHGSMIRESULT *pResult, PSTATUS_BLOCK pStatus);
BOOLEAN VBoxMPHgsmiHandlerEnable(PVBOXMP_DEVEXT pExt, HGSMIHANDLERENABLE *pChannel, PSTATUS_BLOCK pStatus);
BOOLEAN VBoxMPVhwaQueryInfo(PVBOXMP_DEVEXT pExt, VHWAQUERYINFO *pInfo, PSTATUS_BLOCK pStatus);
+BOOLEAN VBoxMPQueryRegistryFlags(PVBOXMP_DEVEXT pExt, ULONG *pulFlags, PSTATUS_BLOCK pStatus);
#endif /*VBOXMPINTERNAL_H*/
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/Makefile.kmk b/src/VBox/Additions/WINNT/Graphics/Wine/Makefile.kmk
index 5adf8d1e..80a5c9c9 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/Makefile.kmk
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/Makefile.kmk
@@ -224,6 +224,9 @@ ifdef VBOX_WITH_WDDM
VBOX_WINE_WITH_SINGLE_CONTEXT \
IN_VBOXLIBWINE \
VBOX_WINE_WITH_SHADER_CACHE
+ifdef VBOX_WINE_WITH_PROFILE
+ wined3dwddm_DEFS += VBOX_WINE_WITH_PROFILE
+endif
wined3dwddm_INCS = $(wined3d_INCS) \
$(PATH_ROOT)/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm
wined3dwddm_SOURCES = $(subst wined3d.def,wined3dwddm.def,$(wined3d_SOURCES)) \
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/d3d9wddm.def b/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/d3d9wddm.def
index d4292ebe..dc72dbfb 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/d3d9wddm.def
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/d3d9wddm.def
@@ -12,6 +12,8 @@ EXPORTS
Direct3DCreate9
Direct3DCreate9Ex
VBoxWineExD3DDev9Flush
+ VBoxWineExD3DDev9FlushToHost
+ VBoxWineExD3DDev9Finish
VBoxWineExD3DDev9CreateTexture
VBoxWineExD3DDev9CreateCubeTexture
VBoxWineExD3DDev9CreateVolumeTexture
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/device.c b/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/device.c
index 32e55aad..a1ebc4ec 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/device.c
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/device.c
@@ -790,6 +790,34 @@ VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9Flush(IDirect3DDevice9Ex *iface)
return hr;
}
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9FlushToHost(IDirect3DDevice9Ex *iface)
+{
+ IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
+ HRESULT hr;
+
+ TRACE("iface %p, FlushToHost\n", iface);
+
+ wined3d_mutex_lock();
+ hr = IWineD3DDevice_FlushToHost(This->WineD3DDevice);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9Finish(IDirect3DDevice9Ex *iface)
+{
+ IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
+ HRESULT hr;
+
+ TRACE("iface %p, Finish\n", iface);
+
+ wined3d_mutex_lock();
+ hr = IWineD3DDevice_Finish(This->WineD3DDevice);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
//#pragma comment(linker, "/export:VBoxWineExD3DDev9CreateTexture=_VBoxWineExD3DDev9CreateTexture@40")
VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9CreateTexture(IDirect3DDevice9Ex *iface,
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/switcher/d3d8_main.c b/src/VBox/Additions/WINNT/Graphics/Wine/switcher/d3d8_main.c
index cff6129d..3b0ae8bf 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/switcher/d3d8_main.c
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/switcher/d3d8_main.c
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/switcher/d3d9_main.c b/src/VBox/Additions/WINNT/Graphics/Wine/switcher/d3d9_main.c
index f3df1756..5f188859 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/switcher/d3d9_main.c
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/switcher/d3d9_main.c
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/switcher/sw_common.c b/src/VBox/Additions/WINNT/Graphics/Wine/switcher/sw_common.c
index b078dce7..5b4da767 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/switcher/sw_common.c
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/switcher/sw_common.c
@@ -1,11 +1,10 @@
/* $Id: sw_common.c $ */
-
/** @file
* VBox D3D8/9 dll switcher
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -22,6 +21,24 @@
static char* gsBlackListExe[] = {"Dwm.exe", "java.exe", "javaw.exe", "javaws.exe"/*, "taskeng.exe"*/, NULL};
static char* gsBlackListDll[] = {"awt.dll", "wpfgfx_v0400.dll", "wpfgfx_v0300.dll", NULL};
+/**
+ * Loads a system DLL.
+ *
+ * @returns Module handle or NULL
+ * @param pszName The DLL name.
+ */
+static HMODULE loadSystemDll(const char *pszName)
+{
+ char szPath[MAX_PATH];
+ UINT cchPath = GetSystemDirectoryA(szPath, sizeof(szPath));
+ size_t cbName = strlen(pszName) + 1;
+ if (cchPath + 1 + cbName > sizeof(szPath))
+ return NULL;
+ szPath[cchPath] = '\\';
+ memcpy(&szPath[cchPath + 1], pszName, cbName);
+ return LoadLibraryA(szPath);
+}
+
/* Checks if 3D is enabled for VM and it works on host machine */
BOOL isVBox3DEnabled(void)
{
@@ -30,9 +47,9 @@ BOOL isVBox3DEnabled(void)
BOOL result = FALSE;
#ifdef VBOX_WDDM_WOW64
- hDLL = LoadLibrary("VBoxOGL-x86.dll");
+ hDLL = loadSystemDll("VBoxOGL-x86.dll");
#else
- hDLL = LoadLibrary("VBoxOGL.dll");
+ hDLL = loadSystemDll("VBoxOGL.dll");
#endif
/* note: this isn't really needed as our library will refuse to load if it can't connect to host.
@@ -65,8 +82,8 @@ BOOL checkOptionsExe(void)
char *filename = name, *pName;
int i;
- if (!GetModuleFileName(NULL, name, 1000))
- return TRUE;
+ if (!GetModuleFileName(NULL, name, 1000))
+ return TRUE;
/*Extract filename*/
for (pName=name; *pName; ++pName)
@@ -107,13 +124,11 @@ void InitD3DExports(const char *vboxName, const char *msName)
HANDLE hDLL;
if (isVBox3DEnabled() && checkOptions())
- {
dllName = vboxName;
- } else
- {
+ else
dllName = msName;
- }
- hDLL = LoadLibrary(dllName);
+ hDLL = loadSystemDll(dllName);
FillD3DExports(hDLL);
}
+
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/switcher/switcher.h b/src/VBox/Additions/WINNT/Graphics/Wine/switcher/switcher.h
index 45e18efc..bdb01dc8 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/switcher/switcher.h
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/switcher/switcher.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/vbox/VBoxDbgGl.c b/src/VBox/Additions/WINNT/Graphics/Wine/vbox/VBoxDbgGl.c
index 467b2ec1..9fb564c0 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/vbox/VBoxDbgGl.c
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/vbox/VBoxDbgGl.c
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/vbox/VBoxDbgGl.h b/src/VBox/Additions/WINNT/Graphics/Wine/vbox/VBoxDbgGl.h
index 2e98cbd3..247e94e9 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/vbox/VBoxDbgGl.h
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/vbox/VBoxDbgGl.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/vbox/VBoxWineEx.h b/src/VBox/Additions/WINNT/Graphics/Wine/vbox/VBoxWineEx.h
index 011caa8b..c2283b5e 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/vbox/VBoxWineEx.h
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/vbox/VBoxWineEx.h
@@ -2,7 +2,7 @@
*
* VBox extension to Wine D3D
*
- * Copyright (C) 2010 Oracle Corporation
+ * Copyright (C) 2010-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -68,6 +68,12 @@ typedef FNVBOXWINEEXD3DDEV9_VOLTEXBLT *PFNVBOXWINEEXD3DDEV9_VOLTEXBLT;
typedef VBOXWINEEX_DECL(HRESULT) FNVBOXWINEEXD3DDEV9_FLUSH(IDirect3DDevice9Ex *iface);
typedef FNVBOXWINEEXD3DDEV9_FLUSH *PFNVBOXWINEEXD3DDEV9_FLUSH;
+typedef VBOXWINEEX_DECL(HRESULT) FNVBOXWINEEXD3DDEV9_FLUSHTOHOST(IDirect3DDevice9Ex *iface);
+typedef FNVBOXWINEEXD3DDEV9_FLUSHTOHOST *PFNVBOXWINEEXD3DDEV9_FLUSHTOHOST;
+
+typedef VBOXWINEEX_DECL(HRESULT) FNVBOXWINEEXD3DDEV9_FINISH(IDirect3DDevice9Ex *iface);
+typedef FNVBOXWINEEXD3DDEV9_FINISH *PFNVBOXWINEEXD3DDEV9_FINISH;
+
typedef VBOXWINEEX_DECL(HRESULT) FNVBOXWINEEXD3DDEV9_UPDATE(IDirect3DDevice9Ex *iface, D3DPRESENT_PARAMETERS * pParams, IDirect3DDevice9Ex **outIface);
typedef FNVBOXWINEEXD3DDEV9_UPDATE *PFNVBOXWINEEXD3DDEV9_UPDATE;
@@ -113,6 +119,10 @@ VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9VolTexBlt(IDirect3DDevice9Ex *iface,
VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9Flush(IDirect3DDevice9Ex *iface); /* perform glFlush */
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9Finish(IDirect3DDevice9Ex *iface); /* perform glFinish */
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9FlushToHost(IDirect3DDevice9Ex *iface); /* flash data to host */
+
VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9Update(IDirect3DDevice9Ex *iface, D3DPRESENT_PARAMETERS * pParams,
IDirect3DDevice9Ex **outIface); /* update device parameters */
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/vbox/libWineStub/include/wine/debug.h b/src/VBox/Additions/WINNT/Graphics/Wine/vbox/libWineStub/include/wine/debug.h
index b52e82ce..e9d7c7ba 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/vbox/libWineStub/include/wine/debug.h
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/vbox/libWineStub/include/wine/debug.h
@@ -358,16 +358,18 @@ static inline const char *debugstr_w( const WCHAR *s ) { return wine_dbgstr_wn(
#endif
-#ifdef DEBUG_misha
-//# define VBOXWINEDBG_SHADERS
+#if 0//def DEBUG_misha
+# define VBOXWINEDBG_SHADERS
#endif
-#ifdef VBOXWINEDBG_SHADERS
+#if defined(VBOXWINEDBG_SHADERS) || defined(VBOX_WINE_WITH_PROFILE)
#include <stdio.h>
#include <stdarg.h>
void vboxWDbgPrintF(char * szString, ...);
+#endif
+#ifdef VBOXWINEDBG_SHADERS
# define WDLOG(_m) do {\
vboxWDbgPrintF _m ; \
} while (0)
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/vbox/libWineStub/include/wine/wined3d.h b/src/VBox/Additions/WINNT/Graphics/Wine/vbox/libWineStub/include/wine/wined3d.h
index 41ee98bb..5dbf7a46 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/vbox/libWineStub/include/wine/wined3d.h
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/vbox/libWineStub/include/wine/wined3d.h
@@ -8251,6 +8251,12 @@ typedef struct IWineD3DDeviceVtbl {
const WINED3DBOX *pSrcBoxArg,
const struct VBOXPOINT3D *pDstPoin3D
);
+
+ HRESULT (STDMETHODCALLTYPE *FlushToHost)(
+ IWineD3DDevice *iface);
+
+ HRESULT (STDMETHODCALLTYPE *Finish)(
+ IWineD3DDevice* This);
#endif
END_INTERFACE
@@ -8426,6 +8432,8 @@ interface IWineD3DDevice {
#define IWineD3DDevice_Flush(This) (This)->lpVtbl->Flush(This)
#define IWineD3DDevice_VolBlt(This, pSourceVolume, pDestinationVolume, pSrcBoxArg, pDstPoin3D) (This)->lpVtbl->VolBlt(This, pSourceVolume, pDestinationVolume, pSrcBoxArg, pDstPoin3D)
#define IWineD3DDevice_VolTexBlt(This, pSourceTexture, pDestinationTexture, pSrcBoxArg, pDstPoin3D) (This)->lpVtbl->VolTexBlt(This, pSourceTexture, pDestinationTexture, pSrcBoxArg, pDstPoin3D)
+#define IWineD3DDevice_FlushToHost(This) (This)->lpVtbl->FlushToHost(This)
+#define IWineD3DDevice_Finish(This) (This)->lpVtbl->Finish(This)
#endif
#endif
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/buffer.c b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/buffer.c
index 3f2eb51b..9094774d 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/buffer.c
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/buffer.c
@@ -1503,6 +1503,7 @@ HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device,
{
TRACE("Not creating a vbo because GL_ARB_vertex_buffer is not supported\n");
}
+#ifndef VBOX_WITH_WDDM
else if(buffer->resource.pool == WINED3DPOOL_SYSTEMMEM)
{
TRACE("Not creating a vbo because the vertex buffer is in system memory\n");
@@ -1511,6 +1512,7 @@ HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device,
{
TRACE("Not creating a vbo because the buffer has dynamic usage and no GL support\n");
}
+#endif
else
{
buffer->flags |= WINED3D_BUFFER_CREATEBO;
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c
index 0334ee50..d12af8bd 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c
@@ -1603,7 +1603,7 @@ static void WINAPI IWineD3DDeviceImpl_ReleaseFocusWindow(IWineD3DDevice *iface)
#ifndef VBOX_WITH_WDDM
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)iface;
- if (device->focus_window) wined3d_unregister_window(device->focus_window);
+ if (device->focus_window) wined3d_unregister_window(device->focus_window, device);
device->focus_window = NULL;
#else
ERR("should not be here");
@@ -1870,6 +1870,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface,
if(!This->d3d_initialized) return WINED3DERR_INVALIDCALL;
+#ifdef VBOX_WINE_WITH_PROFILE
+ VBOXWINEPROFILE_DRAWPRIM_TERM(&This->DrawPrimProfile);
+#endif
+
/* I don't think that the interface guarantees that the device is destroyed from the same thread
* it was created. Thus make sure a context is active for the glDelete* calls
*/
@@ -5527,7 +5531,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
* needed, use BltFast instead to copy in sysmem and use regular surface
* loading. */
d3dfmt_get_conv(dst_impl, FALSE, TRUE, &dummy_desc, &convert);
- if (convert != NO_CONVERSION)
+ if (convert != NO_CONVERSION || dummy_desc.convert)
return IWineD3DSurface_BltFast(dst_surface, dst_x, dst_y, src_surface, src_rect, 0);
context = context_acquire(This, NULL, CTXUSAGE_RESOURCELOAD);
@@ -7269,6 +7273,52 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Flush(IWineD3DDevice *iface)
return WINED3D_OK;
}
+static HRESULT WINAPI IWineD3DDeviceImpl_Finish(IWineD3DDevice *iface)
+{
+ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+ struct wined3d_context *context;
+ int i;
+
+ /* first call swapchain flush to ensure all swapchain-pending data gets flushed */
+ for (i = 0; i < This->NumberOfSwapChains; ++i)
+ {
+ IWineD3DSwapChain *pSwapchain = This->swapchains[i];
+ IWineD3DSwapChain_Flush(pSwapchain);
+ }
+
+ for (i = 0; i < This->numContexts; ++i)
+ {
+ context = This->contexts[i];
+ if (context_acquire_context(context, NULL, CTXUSAGE_RESOURCELOAD, TRUE))
+ {
+ Assert(context->valid);
+ wglFinish();
+ context_release(context);
+ }
+ else
+ {
+ WARN("Invalid context, skipping flush.\n");
+ }
+ }
+ return WINED3D_OK;
+}
+
+static HRESULT WINAPI IWineD3DDeviceImpl_FlushToHost(IWineD3DDevice *iface)
+{
+ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+ struct wined3d_context *context;
+ int i;
+
+ /* no context acquisition is needed */
+ for (i = 0; i < This->numContexts; ++i)
+ {
+ context = This->contexts[i];
+ pVBoxFlushToHost(context->glCtx);
+ }
+ return WINED3D_OK;
+}
+
+
/* context activation is done by the caller */
void device_cleanup_durtify_texture_target(IWineD3DDeviceImpl *This, GLuint texture_target)
{
@@ -7473,6 +7523,8 @@ static const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl =
IWineD3DDeviceImpl_Flush,
IWineD3DDeviceImpl_VolBlt,
IWineD3DDeviceImpl_VolTexBlt,
+ IWineD3DDeviceImpl_FlushToHost,
+ IWineD3DDeviceImpl_Finish,
#endif
};
@@ -7519,6 +7571,10 @@ HRESULT device_init(IWineD3DDeviceImpl *device, IWineD3DImpl *wined3d,
device->createParms.hFocusWindow = focus_window;
device->createParms.BehaviorFlags = flags;
+#ifdef VBOX_WINE_WITH_PROFILE
+ VBOXWINEPROFILE_DRAWPRIM_INIT(&device->DrawPrimProfile);
+#endif
+
device->devType = device_type;
for (i = 0; i < PATCHMAP_SIZE; ++i) list_init(&device->patches[i]);
@@ -7610,7 +7666,7 @@ LRESULT device_process_message(IWineD3DDeviceImpl *device, HWND window,
if (message == WM_DESTROY)
{
TRACE("unregister window %p.\n", window);
- wined3d_unregister_window(window);
+ wined3d_unregister_window(window, NULL);
if (device->focus_window == window) device->focus_window = NULL;
else ERR("Window %p is not the focus window for device %p.\n", window, device);
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/directx.c b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/directx.c
index ebd596c0..4f73c2fe 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/directx.c
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/directx.c
@@ -5307,6 +5307,24 @@ static void fillGLAttribFuncs(const struct wined3d_gl_info *gl_info)
}
}
+/**
+ * Loads a system DLL.
+ *
+ * @returns Module handle or NULL
+ * @param pszName The DLL name.
+ */
+static HMODULE loadSystemDll(const char *pszName)
+{
+ char szPath[MAX_PATH];
+ UINT cchPath = GetSystemDirectoryA(szPath, sizeof(szPath));
+ size_t cbName = strlen(pszName) + 1;
+ if (cchPath + 1 + cbName > sizeof(szPath))
+ return NULL;
+ szPath[cchPath] = '\\';
+ memcpy(&szPath[cchPath + 1], pszName, cbName);
+ return LoadLibraryA(szPath);
+}
+
static BOOL InitAdapters(IWineD3DImpl *This)
{
static HMODULE mod_gl;
@@ -5322,22 +5340,22 @@ static BOOL InitAdapters(IWineD3DImpl *This)
if(!mod_gl) {
#ifdef USE_WIN32_OPENGL
-#define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(mod_gl, #pfn);
-#if defined(VBOX_WITH_WDDM) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+# define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(mod_gl, #pfn);
+# if defined(VBOX_WITH_WDDM) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
BOOL (APIENTRY *pDrvValidateVersion)(DWORD) DECLSPEC_HIDDEN;
-#ifdef VBOX_WDDM_WOW64
- mod_gl = LoadLibraryA("VBoxOGL-x86.dll");
-#else
- mod_gl = LoadLibraryA("VBoxOGL.dll");
-#endif
-#else
- mod_gl = LoadLibraryA("opengl32.dll");
-#endif
+# ifdef VBOX_WDDM_WOW64
+ mod_gl = loadSystemDll("VBoxOGL-x86.dll");
+# else
+ mod_gl = loadSystemDll("VBoxOGL.dll");
+# endif
+# else
+ mod_gl = loadSystemDll("opengl32.dll");
+# endif
if(!mod_gl) {
ERR("Can't load opengl32.dll!\n");
goto nogl_adapter;
}
-#if defined(VBOX_WITH_WDDM) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+# if defined(VBOX_WITH_WDDM) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
/* init properly */
pDrvValidateVersion = (void*)GetProcAddress(mod_gl, "DrvValidateVersion");
if(!pDrvValidateVersion) {
@@ -5348,9 +5366,9 @@ static BOOL InitAdapters(IWineD3DImpl *This)
ERR("DrvValidateVersion FAILED\n");
goto nogl_adapter;
}
-#endif
+# endif
#else
-#define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
+# define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
/* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
mod_gl = GetModuleHandleA("gdi32.dll");
#endif
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/glsl_shader.c b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/glsl_shader.c
index d9cbdd7a..923017c0 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/glsl_shader.c
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/glsl_shader.c
@@ -3971,6 +3971,9 @@ static void generate_texcoord_assignment(struct wined3d_shader_buffer *buffer, I
unsigned int i;
char reg_mask[6];
+ if (!ps)
+ return;
+
for (i = 0, map = ps->baseShader.reg_maps.texcoord; map && i < min(8, MAX_REG_TEXCRD); map >>= 1, ++i)
{
if (!map & 1)
@@ -5334,7 +5337,7 @@ const shader_backend_t glsl_shader_backend = {
shader_glsl_color_fixup_supported,
};
-#ifdef VBOXWINEDBG_SHADERS
+#if defined(VBOXWINEDBG_SHADERS) || defined(VBOX_WINE_WITH_PROFILE)
void vboxWDbgPrintF(char * szString, ...)
{
char szBuffer[4096*2] = {0};
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/surface.c b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/surface.c
index e231b1f5..f18797fc 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/surface.c
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/surface.c
@@ -2864,7 +2864,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BO
}
#endif
- if (!(This->Flags & SFLAG_DONOTFREE)) {
+ if (!(This->Flags & SFLAG_DONOTFREE) && !This->resource.format_desc->convert) {
HeapFree(GetProcessHeap(), 0, This->resource.heapMemory);
This->resource.allocatedMemory = NULL;
This->resource.heapMemory = NULL;
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain.c b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain.c
index 2b3b546b..96e67507 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain.c
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain.c
@@ -519,16 +519,9 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
#endif
#ifdef VBOX_WITH_WDDM
- /* We're directly using wglMakeCurrent calls skipping GDI layer, which causes GDI SwapBuffers to fail trying to
- * call glFinish, which doesn't have any context set. So we use wglSwapLayerBuffers directly as well.
- */
- pwglSwapLayerBuffers(context->currentSwapchain->hDC, WGL_SWAP_MAIN_PLANE);
+ SwapBuffers(context->currentSwapchain->hDC);
#else
-# ifdef VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT
- pwglSwapLayerBuffers(context->hdc, WGL_SWAP_MAIN_PLANE);
-# else
SwapBuffers(context->hdc); /* TODO: cycle through the swapchain buffers */
-# endif
#endif
TRACE("SwapBuffers called, Starting new frame\n");
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxext.c b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxext.c
index cb76f8b3..68348e11 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxext.c
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxext.c
@@ -3,7 +3,7 @@
*
* VBox extension to Wine D3D
*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxext.h b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxext.h
index 390f960e..0b3d1635 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxext.h
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxext.h
@@ -3,7 +3,7 @@
*
* VBox extension to Wine D3D
*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxsharedrc.h b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxsharedrc.h
index 6ea458b7..d028851c 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxsharedrc.h
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxsharedrc.h
@@ -3,7 +3,7 @@
*
* VBox extension to Wine D3D - shared resource
*
- * Copyright (C) 2010 Oracle Corporation
+ * Copyright (C) 2010-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_gl.h b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_gl.h
index c9a9b36c..5ed7e0fb 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_gl.h
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_gl.h
@@ -1380,8 +1380,35 @@ PROC (WINAPI *pwglGetProcAddress)(LPCSTR) DECLSPEC_HIDDEN;
BOOL (WINAPI *pwglMakeCurrent)(HDC, HGLRC) DECLSPEC_HIDDEN;
BOOL (WINAPI *pwglSwapLayerBuffers)(HDC, UINT) DECLSPEC_HIDDEN;
BOOL (WINAPI *pwglShareLists)(HGLRC, HGLRC) DECLSPEC_HIDDEN;
+BOOL (WINAPI *pwglChoosePixelFormat)(HDC, const PIXELFORMATDESCRIPTOR *) DECLSPEC_HIDDEN;
+int (WINAPI *pwglDescribePixelFormat)(HDC, int, UINT, LPPIXELFORMATDESCRIPTOR) DECLSPEC_HIDDEN;
+int (WINAPI *pwglGetPixelFormat)(HDC) DECLSPEC_HIDDEN;
+BOOL (WINAPI *pwglSetPixelFormat)(HDC, int, const PIXELFORMATDESCRIPTOR *) DECLSPEC_HIDDEN;
HGLRC (WINAPI *pVBoxCreateContext)(HDC, struct VBOXUHGSMI*) DECLSPEC_HIDDEN;
+void (WINAPI *pVBoxFlushToHost)(HGLRC) DECLSPEC_HIDDEN;
+
+#if defined(VBOX_WITH_WDDM) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+# define VBOX_WINE_WITH_DIRECT_VBOXOGL
+#endif
+
+#ifdef VBOX_WINE_WITH_DIRECT_VBOXOGL
+/* make sure we used stuff from VBoxOGL
+ * we do it this way to avoid extra modifications to Wine code */
+
+/* We're directly using wglMakeCurrent calls skipping GDI layer, which causes GDI SwapBuffers to fail trying to
+ * call glFinish, which doesn't have any context set. So we use wglSwapLayerBuffers directly as well.
+ */
+# define SwapBuffers(_hdc) pwglSwapLayerBuffers((_hdc), WGL_SWAP_MAIN_PLANE)
+
+/* we avoid using GDI32!*PixelFormat API and use VBoxOGL stuff directly
+ * because SetPixelFormat may eventually lead to opengl32 setting its own window proc via SetWindowLongPtr
+ * thus wined3d_[un]register_window stuff will become screwed up leading to infinite recursion or other misbehave */
+# define ChoosePixelFormat pwglChoosePixelFormat
+# define DescribePixelFormat pwglDescribePixelFormat
+# define GetPixelFormat pwglGetPixelFormat
+# define SetPixelFormat pwglSetPixelFormat
+#endif
#define GL_FUNCS_GEN \
USE_GL_FUNC(glAccum) \
@@ -1727,10 +1754,15 @@ HGLRC (WINAPI *pVBoxCreateContext)(HDC, struct VBOXUHGSMI*) DECLSPEC_HIDDEN;
USE_WGL_FUNC(wglGetProcAddress) \
USE_WGL_FUNC(wglMakeCurrent) \
USE_WGL_FUNC(wglShareLists) \
- USE_WGL_FUNC(wglSwapLayerBuffers)
+ USE_WGL_FUNC(wglSwapLayerBuffers) \
+ USE_WGL_FUNC(wglChoosePixelFormat) \
+ USE_WGL_FUNC(wglDescribePixelFormat) \
+ USE_WGL_FUNC(wglGetPixelFormat) \
+ USE_WGL_FUNC(wglSetPixelFormat)
#define VBOX_FUNCS_GEN \
- USE_WGL_FUNC(VBoxCreateContext)
+ USE_WGL_FUNC(VBoxCreateContext) \
+ USE_WGL_FUNC(VBoxFlushToHost)
/* OpenGL extensions. */
typedef enum wined3d_gl_extension
@@ -3785,7 +3817,7 @@ typedef BOOL (WINAPI *WINED3D_PFNWGLSETPIXELFORMATWINE)(HDC hdc, int iPixelForma
/*report that the shared resource is no longer used by this context, the parameter value is a texture name*/
#define GL_RCUSAGE_TEXTURE_CLEAR_CR 0x8B2A
/*configures host to create windows initially hidden*/
-#define GL_HOST_WND_CREATED_HIDDEN 0x8B2B
+#define GL_HOST_WND_CREATED_HIDDEN_CR 0x8B2B
typedef void (WINE_GLAPI *PGLFNCHROMIUMPARAMETERUCR)(GLenum param, GLint value);
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_main.c b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_main.c
index 8934dbe7..c2f36c11 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_main.c
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_main.c
@@ -464,6 +464,15 @@ BOOL wined3d_register_window(HWND window, IWineD3DDeviceImpl *device)
wined3d_mutex_lock();
+ entry = wined3d_find_wndproc(window);
+ if (entry)
+ {
+ ERR("window is registered already!");
+ entry->device = device;
+ wined3d_mutex_unlock();
+ return TRUE;
+ }
+
if (wndproc_table.size == wndproc_table.count)
{
unsigned int new_size = max(1, wndproc_table.size * 2);
@@ -487,13 +496,14 @@ BOOL wined3d_register_window(HWND window, IWineD3DDeviceImpl *device)
entry->window = window;
entry->proc = (WNDPROC)SetWindowLongPtrW(window, GWLP_WNDPROC, (LONG_PTR)wined3d_wndproc);
entry->device = device;
+ Assert(entry->proc != wined3d_wndproc);
wined3d_mutex_unlock();
return TRUE;
}
-void wined3d_unregister_window(HWND window)
+void wined3d_unregister_window(HWND window, struct IWineD3DDeviceImpl *device)
{
unsigned int i;
@@ -503,11 +513,19 @@ void wined3d_unregister_window(HWND window)
if (wndproc_table.entries[i].window == window)
{
struct wined3d_wndproc *entry = &wndproc_table.entries[i];
- struct wined3d_wndproc *last = &wndproc_table.entries[--wndproc_table.count];
- if (GetWindowLongPtrW(window, GWLP_WNDPROC) == (LONG_PTR)wined3d_wndproc)
- SetWindowLongPtrW(window, GWLP_WNDPROC, (LONG_PTR)entry->proc);
- if (entry != last) *entry = *last;
+ if (!device || device == entry->device)
+ {
+ struct wined3d_wndproc *last = &wndproc_table.entries[--wndproc_table.count];
+
+ if (GetWindowLongPtrW(window, GWLP_WNDPROC) == (LONG_PTR)wined3d_wndproc)
+ SetWindowLongPtrW(window, GWLP_WNDPROC, (LONG_PTR)entry->proc);
+ if (entry != last) *entry = *last;
+ }
+ else
+ {
+ ERR("request to unregister a window of a not-owning device");
+ }
wined3d_mutex_unlock();
return;
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_private.h b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_private.h
index 7c5a7c64..724f8acd 100644
--- a/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_private.h
+++ b/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_private.h
@@ -1664,7 +1664,7 @@ typedef struct IWineD3DImpl
HRESULT wined3d_init(IWineD3DImpl *wined3d, UINT version, IUnknown *parent) DECLSPEC_HIDDEN;
#ifndef VBOX_WITH_WDDM
BOOL wined3d_register_window(HWND window, struct IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN;
-void wined3d_unregister_window(HWND window) DECLSPEC_HIDDEN;
+void wined3d_unregister_window(HWND window, struct IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN;
#endif
/*****************************************************************************
@@ -1675,6 +1675,162 @@ void wined3d_unregister_window(HWND window) DECLSPEC_HIDDEN;
/* Multithreaded flag. Removed from the public header to signal that IWineD3D::CreateDevice ignores it */
#define WINED3DCREATE_MULTITHREADED 0x00000004
+#ifdef VBOX_WINE_WITH_PROFILE
+
+#include <iprt/time.h>
+
+#define VBOXWINEPROFILE_GET_TIME_NANO() RTTimeNanoTS()
+#define VBOXWINEPROFILE_GET_TIME_MILLI() RTTimeMilliTS()
+
+# define PRLOG(_m) do {\
+ vboxWDbgPrintF _m ; \
+ } while (0)
+
+typedef struct VBOXWINEPROFILE_ELEMENT
+{
+ uint64_t u64Time;
+ uint32_t cu32Calls;
+} VBOXWINEPROFILE_ELEMENT, *PVBOXWINEPROFILE_ELEMENT;
+
+typedef struct VBOXWINEPROFILE_HASHMAP_ELEMENT
+{
+ VBOXEXT_HASHMAP_ENTRY MapEntry;
+ VBOXWINEPROFILE_ELEMENT Data;
+} VBOXWINEPROFILE_HASHMAP_ELEMENT, *PVBOXWINEPROFILE_HASHMAP_ELEMENT;
+
+#define VBOXWINEPROFILE_HASHMAP_ELEMENT_FROMENTRY(_p) ((PVBOXWINEPROFILE_HASHMAP_ELEMENT)(((uint8_t*)(_p)) - RT_OFFSETOF(VBOXWINEPROFILE_HASHMAP_ELEMENT, MapEntry)))
+
+#define VBOXWINEPROFILE_ELEMENT_DUMP(_p, _pn) do { \
+ PRLOG(("%s: t(%u);c(%u)\n", \
+ (_pn), \
+ (uint32_t)((_p)->u64Time / 1000000), \
+ (_p)->cu32Calls \
+ )); \
+ } while (0)
+
+#define VBOXWINEPROFILE_ELEMENT_RESET(_p) do { \
+ memset(_p, 0, sizeof (*(_p))); \
+ } while (0)
+
+#define VBOXWINEPROFILE_ELEMENT_STEP(_p, _t) do { \
+ (_p)->u64Time += (_t); \
+ ++(_p)->cu32Calls; \
+ } while (0)
+
+#define VBOXWINEPROFILE_HASHMAP_ELEMENT_CREATE() ( (PVBOXWINEPROFILE_HASHMAP_ELEMENT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (VBOXWINEPROFILE_HASHMAP_ELEMENT)) )
+
+#define VBOXWINEPROFILE_HASHMAP_ELEMENT_TERM(_pe) do { \
+ HeapFree(GetProcessHeap(), 0, (_pe)); \
+ } while (0)
+
+DECLINLINE(PVBOXWINEPROFILE_HASHMAP_ELEMENT) vboxWineProfileHashMapElementGet(PVBOXEXT_HASHMAP pMap, void *pvKey)
+{
+ PVBOXEXT_HASHMAP_ENTRY pEntry = VBoxExtHashGet(pMap, pvKey);
+ if (pEntry)
+ {
+ return VBOXWINEPROFILE_HASHMAP_ELEMENT_FROMENTRY(pEntry);
+ }
+ else
+ {
+ PVBOXWINEPROFILE_HASHMAP_ELEMENT pElement = VBOXWINEPROFILE_HASHMAP_ELEMENT_CREATE();
+ Assert(pElement);
+ if (pElement)
+ VBoxExtHashPut(pMap, pvKey, &pElement->MapEntry);
+ return pElement;
+ }
+}
+
+#define VBOXWINEPROFILE_HASHMAP_ELEMENT_STEP(_pm, _pk, _t) do { \
+ PVBOXWINEPROFILE_HASHMAP_ELEMENT pElement = vboxWineProfileHashMapElementGet(_pm, _pk); \
+ VBOXWINEPROFILE_ELEMENT_STEP(&pElement->Data, _t); \
+ } while (0)
+
+static DECLCALLBACK(bool) vboxWineProfileElementResetCb(struct VBOXEXT_HASHMAP *pMap, void *pvKey, struct VBOXEXT_HASHMAP_ENTRY *pValue, void *pvVisitor)
+{
+ PVBOXWINEPROFILE_HASHMAP_ELEMENT pElement = VBOXWINEPROFILE_HASHMAP_ELEMENT_FROMENTRY(pValue);
+ VBOXWINEPROFILE_ELEMENT_RESET(&pElement->Data);
+ return true;
+}
+
+static DECLCALLBACK(bool) vboxWineProfileElementDumpCb(struct VBOXEXT_HASHMAP *pMap, void *pvKey, struct VBOXEXT_HASHMAP_ENTRY *pValue, void *pvVisitor)
+{
+ PVBOXWINEPROFILE_HASHMAP_ELEMENT pElement = VBOXWINEPROFILE_HASHMAP_ELEMENT_FROMENTRY(pValue);
+ char *pName = (char*)pvVisitor;
+ PRLOG(("%s[%d]:", pName, (uint32_t)pvKey));
+ VBOXWINEPROFILE_ELEMENT_DUMP(&pElement->Data, "");
+ return true;
+}
+
+#define VBOXWINEPROFILE_HASHMAP_RESET(_pm) do { \
+ VBoxExtHashVisit((_pm), vboxWineProfileElementResetCb, NULL); \
+ } while (0)
+
+#define VBOXWINEPROFILE_HASHMAP_DUMP(_pm, _pn) do { \
+ VBoxExtHashVisit((_pm), vboxWineProfileElementDumpCb, (_pn)); \
+ } while (0)
+
+static DECLCALLBACK(bool) vboxWineProfileElementCleanupCb(struct VBOXEXT_HASHMAP *pMap, void *pvKey, struct VBOXEXT_HASHMAP_ENTRY *pValue, void *pvVisitor)
+{
+ PVBOXWINEPROFILE_HASHMAP_ELEMENT pElement = VBOXWINEPROFILE_HASHMAP_ELEMENT_FROMENTRY(pValue);
+ VBOXWINEPROFILE_HASHMAP_ELEMENT_TERM(pElement);
+ return true;
+}
+
+#define VBOXWINEPROFILE_HASHMAP_TERM(_pm) do { \
+ VBoxExtHashCleanup((_pm), vboxWineProfileElementCleanupCb, NULL); \
+ VBoxExtHashVisit((_pm), vboxWineProfileElementResetCb, NULL); \
+ } while (0)
+
+typedef struct VBOXWINEPROFILE_DRAWPRIM
+{
+ uint64_t u64LoadLocationTime;
+ uint64_t u64CtxAcquireTime;
+ uint64_t u64PostProcess;
+ VBOXEXT_HASHMAP MapDrawPrimSlowVs;
+ VBOXEXT_HASHMAP MapDrawPrimSlow;
+ VBOXEXT_HASHMAP MapDrawPrimStrided;
+ VBOXEXT_HASHMAP MapDrawPrimFast;
+ uint32_t cu32Calls;
+} VBOXWINEPROFILE_DRAWPRIM, *PVBOXWINEPROFILE_DRAWPRIM;
+
+#define VBOXWINEPROFILE_DRAWPRIM_RESET_NEXT(_p) do { \
+ (_p)->u64LoadLocationTime = 0; \
+ (_p)->u64CtxAcquireTime = 0; \
+ (_p)->u64PostProcess = 0; \
+ VBOXWINEPROFILE_HASHMAP_RESET(&(_p)->MapDrawPrimSlowVs); \
+ VBOXWINEPROFILE_HASHMAP_RESET(&(_p)->MapDrawPrimSlow); \
+ VBOXWINEPROFILE_HASHMAP_RESET(&(_p)->MapDrawPrimStrided); \
+ VBOXWINEPROFILE_HASHMAP_RESET(&(_p)->MapDrawPrimFast); \
+ } while (0)
+
+static DECLCALLBACK(uint32_t) vboxWineProfileDrawPrimHashMapHash(void *pvKey)
+{
+ return (uint32_t)pvKey;
+}
+
+static DECLCALLBACK(bool) vboxWineProfileDrawPrimHashMapEqual(void *pvKey1, void *pvKey2)
+{
+ return ((uint32_t)pvKey1) == ((uint32_t)pvKey2);
+}
+
+#define VBOXWINEPROFILE_DRAWPRIM_INIT(_p) do { \
+ memset((_p), 0, sizeof (*(_p))); \
+ VBoxExtHashInit(&(_p)->MapDrawPrimSlowVs, vboxWineProfileDrawPrimHashMapHash, vboxWineProfileDrawPrimHashMapEqual); \
+ VBoxExtHashInit(&(_p)->MapDrawPrimSlow, vboxWineProfileDrawPrimHashMapHash, vboxWineProfileDrawPrimHashMapEqual); \
+ VBoxExtHashInit(&(_p)->MapDrawPrimStrided, vboxWineProfileDrawPrimHashMapHash, vboxWineProfileDrawPrimHashMapEqual); \
+ VBoxExtHashInit(&(_p)->MapDrawPrimFast, vboxWineProfileDrawPrimHashMapHash, vboxWineProfileDrawPrimHashMapEqual); \
+ } while (0)
+
+#define VBOXWINEPROFILE_DRAWPRIM_TERM(_p) do { \
+ memset((_p), 0, sizeof (*(_p))); \
+ VBOXWINEPROFILE_HASHMAP_TERM(&(_p)->MapDrawPrimSlowVs); \
+ VBOXWINEPROFILE_HASHMAP_TERM(&(_p)->MapDrawPrimSlow); \
+ VBOXWINEPROFILE_HASHMAP_TERM(&(_p)->MapDrawPrimStrided); \
+ VBOXWINEPROFILE_HASHMAP_TERM(&(_p)->MapDrawPrimFast); \
+ } while (0)
+#else
+# define PRLOG(_m) do {} while (0)
+#endif
struct IWineD3DDeviceImpl
{
/* IUnknown fields */
@@ -1813,6 +1969,10 @@ struct IWineD3DDeviceImpl
VBOXEXT_HASHCACHE pshaderCache;
#endif
+#ifdef VBOX_WINE_WITH_PROFILE
+ VBOXWINEPROFILE_DRAWPRIM DrawPrimProfile;
+#endif
+
/* High level patch management */
#define PATCHMAP_SIZE 43
#define PATCHMAP_HASHFUNC(x) ((x) % PATCHMAP_SIZE) /* Primitive and simple function */
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/Makefile.kmk b/src/VBox/Additions/WINNT/Graphics/Wine_new/Makefile.kmk
new file mode 100644
index 00000000..9ac7d42b
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/Makefile.kmk
@@ -0,0 +1,395 @@
+# $Id: Makefile.kmk $
+## @file
+# Makefile for the Wine D3D related dlls for VirtualBox.
+#
+
+#
+# Copyright (C) 2009-2012 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+
+SUB_DEPTH = ../../../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+#
+# Template for building wine stuff.
+#
+TEMPLATE_VBoxGuestWineDLL = Template for building a wine DLL.
+TEMPLATE_VBoxGuestWineDLL_EXTENDS = VBOXGUESTR3NPDLL
+TEMPLATE_VBoxGuestWineDLL_DEFS = $(TEMPLATE_VBOXGUESTR3NPDLL_DEFS) \
+ __WINESRC__ \
+ WINE_UNICODE_API="" \
+ _REENTRANT \
+ WINE_NOWINSOCK \
+ USE_WIN32_OPENGL \
+ DLLDIR=\"\" \
+ BINDIR=\"\" \
+ LIB_TO_BINDIR=\"\" \
+ LIB_TO_DLLDIR=\"\" \
+ BIN_TO_DLLDIR=\"\" \
+ LIB_TO_DATADIR=\"\" \
+ BIN_TO_DATADIR=\"\"
+
+TEMPLATE_VBoxGuestWineDLL_DEFS.x86 = __i386__
+
+#
+# Template for building the D3D[89] stuff.
+#
+TEMPLATE_VBoxGuestWineD3DxDLL = Template for building the D3D8/9 stuff.
+TEMPLATE_VBoxGuestWineD3DxDLL_EXTENDS = VBOXGUESTR3NPDLL
+TEMPLATE_VBoxGuestWineD3DxDLL_EXTENDS_BY = appending
+TEMPLATE_VBoxGuestWineD3DxDLL_SDKS = ReorderCompilerIncs $(VBOX_WINDDK_GST_WLH)
+TEMPLATE_VBoxGuestWineD3DxDLL_DEFS = VBOX_USING_WINDDK_W7_OR_LATER
+TEMPLATE_VBoxGuestWineD3DxDLL_DEFS.x86 = __i386__
+#TEMPLATE_VBoxGuestWineD3DxDLL_INCS.x86 = vbox/libWineStub/include
+TEMPLATE_VBoxGuestWineD3DxDLL_DEFS = VBOX_WINE_WITH_IPRT
+TEMPLATE_VBoxGuestWineD3DxDLL_LIBS = \
+ $(VBOX_LIB_IPRT_GUEST_R3) \
+ $(VBOX_LIB_VBGL_R3)
+
+
+if 0
+#
+# libWine - ???.
+#
+DLLS.x86 += libWine
+libWine_TEMPLATE = VBoxGuestWineDLL
+libWine_INCS = \
+ include
+libWine_SOURCES := \
+ libWine/wine.def \
+ libWine/casemap.c \
+ libWine/collation.c \
+ libWine/compose.c \
+ libWine/config.c \
+ libWine/cptable.c \
+ libWine/debug.c \
+ libWine/fold.c \
+ libWine/ldt.c \
+ libWine/loader.c \
+ libWine/mbtowc.c \
+ libWine/mmap.c \
+ libWine/port.c \
+ libWine/sortkey.c \
+ libWine/string.c \
+ libWine/utf8.c \
+ libWine/wctomb.c \
+ libWine/wctype.c \
+ libWine/c_037.c \
+ libWine/c_424.c \
+ libWine/c_437.c \
+ libWine/c_500.c \
+ libWine/c_737.c \
+ libWine/c_775.c \
+ libWine/c_850.c \
+ libWine/c_852.c \
+ libWine/c_855.c \
+ libWine/c_856.c \
+ libWine/c_857.c \
+ libWine/c_860.c \
+ libWine/c_861.c \
+ libWine/c_862.c \
+ libWine/c_863.c \
+ libWine/c_864.c \
+ libWine/c_865.c \
+ libWine/c_866.c \
+ libWine/c_869.c \
+ libWine/c_874.c \
+ libWine/c_875.c \
+ libWine/c_878.c \
+ libWine/c_932.c \
+ libWine/c_936.c \
+ libWine/c_949.c \
+ libWine/c_950.c \
+ libWine/c_1006.c \
+ libWine/c_1026.c \
+ libWine/c_1250.c \
+ libWine/c_1251.c \
+ libWine/c_1252.c \
+ libWine/c_1253.c \
+ libWine/c_1254.c \
+ libWine/c_1255.c \
+ libWine/c_1256.c \
+ libWine/c_1257.c \
+ libWine/c_1258.c \
+ libWine/c_1361.c \
+ libWine/c_10000.c \
+ libWine/c_10006.c \
+ libWine/c_10007.c \
+ libWine/c_10029.c \
+ libWine/c_10079.c \
+ libWine/c_10081.c \
+ libWine/c_20127.c \
+ libWine/c_20866.c \
+ libWine/c_20932.c \
+ libWine/c_21866.c \
+ libWine/c_28591.c \
+ libWine/c_28592.c \
+ libWine/c_28593.c \
+ libWine/c_28594.c \
+ libWine/c_28595.c \
+ libWine/c_28596.c \
+ libWine/c_28597.c \
+ libWine/c_28598.c \
+ libWine/c_28599.c \
+ libWine/c_28600.c \
+ libWine/c_28603.c \
+ libWine/c_28604.c \
+ libWine/c_28605.c \
+ libWine/c_28606.c \
+ libWine/version.c
+endif # 0
+
+#
+# wined3d - ???.
+#
+DLLS += wined3d
+wined3d_TEMPLATE = VBoxGuestWineDLL
+wined3d_SDKS = ReorderCompilerIncs $(VBOX_WINDDK_GST_WLH)
+wined3d_DEFS = \
+ _USE_MATH_DEFINES \
+ VBOX_USING_WINDDK_W7_OR_LATER \
+ VBOX_WINE_WITHOUT_LIBWINE \
+ VBOX_WINE_WITH_SINGLE_CONTEXT \
+ VBOX_WINE_WITH_IPRT
+# ^^^^ wined3d is now using iprt/asm.h, which includes iprt/assert.h, so iprt is required.
+if "$(KBUILD_TYPE)" != "debug" || defined(VBOX_WINE_NO_DEBUG_MSGS)
+ wined3d_DEFS += WINE_NO_DEBUG_MSGS
+endif
+wined3d_DEFS += \
+ VBOX_WITH_WINE_FIX_IBMTMR \
+ VBOX_WITH_WINE_FIX_BUFOFFSET \
+ VBOX_WITH_WINE_FIX_QUIRKS \
+ VBOX_WITH_WINE_FIX_PBOPSM \
+ VBOX_WITH_WINE_FIX_INITCLEAR \
+ VBOX_WITH_WINE_FIX_TEXCLEAR \
+ VBOX_WITH_WINE_FIX_STRINFOBUF \
+ VBOX_WITH_WINE_FIX_SHADERCLEANUP \
+ VBOX_WITH_WINE_FIX_SURFUPDATA \
+ VBOX_WITH_WINE_FIX_CURVBO \
+ VBOX_WITH_WINE_FIX_ZEROVERTATTR \
+ VBOX_WITH_WINE_DBG
+#wined3d_DEFS += VBOX_WITH_WINE_FIXES
+wined3d_INCS := \
+ vbox/libWineStub/include
+wined3d_SOURCES := \
+ wined3d/arb_program_shader.c \
+ wined3d/ati_fragment_shader.c \
+ wined3d/buffer.c \
+ wined3d/context.c \
+ wined3d/device.c \
+ wined3d/directx.c \
+ wined3d/drawprim.c \
+ wined3d/gl_compat.c \
+ wined3d/glsl_shader.c \
+ wined3d/nvidia_texture_shader.c \
+ wined3d/palette.c \
+ wined3d/query.c \
+ wined3d/resource.c \
+ wined3d/shader.c \
+ wined3d/shader_sm1.c \
+ wined3d/shader_sm4.c \
+ wined3d/state.c \
+ wined3d/stateblock.c \
+ wined3d/surface.c \
+ wined3d/swapchain.c \
+ wined3d/texture.c \
+ wined3d/utils.c \
+ wined3d/vertexdeclaration.c \
+ wined3d/view.c \
+ wined3d/volume.c \
+ wined3d/wined3d_main.c \
+ wined3d/vboxext.c \
+ wined3d/sampler.c \
+ vbox/libWineStub/debug.c \
+ vbox/VBoxDbgGl.c \
+ wined3d/wined3d.def
+wined3d_LIBS = \
+ $(VBOX_LIB_IPRT_GUEST_R3) \
+ $(VBOX_LIB_VBGL_R3) \
+ $(PATH_STAGE_LIB)/VBoxOGL$(VBOX_SUFF_LIB)
+
+ifdef VBOX_WITH_WDDM
+ #
+ # wined3dwddm - ???
+ #
+ DLLS += wined3dwddm
+ wined3dwddm_EXTENDS = wined3d
+ if defined(VBOX_SIGNING_MODE)
+ wined3dwddm_INSTTYPE.win = none
+ wined3dwddm_DEBUG_INSTTYPE.win = both
+ endif
+ wined3dwddm_DEFS = $(wined3d_DEFS) \
+ VBOX_WITH_WDDM \
+ IN_VBOXLIBWINE \
+ VBOX_WINE_WITH_SHADER_CACHE
+ifdef VBOX_WINE_WITH_PROFILE
+ wined3dwddm_DEFS += VBOX_WINE_WITH_PROFILE
+endif
+ wined3dwddm_INCS = $(wined3d_INCS) \
+ $(PATH_ROOT)/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm
+ wined3dwddm_SOURCES = $(subst wined3d.def,wined3dwddm.def,$(wined3d_SOURCES))
+ wined3dwddm_LIBS = $(wined3d_LIBS) \
+ $(VBOX_PATH_ADDITIONS_LIB)/VBoxDispMpLogger$(VBOX_SUFF_LIB) \
+ $(VBOX_PATH_ADDITIONS_LIB)/VBoxCrHgsmi$(VBOX_SUFF_LIB)
+
+ #
+ # wined3dwddm-x86 - ???.
+ #
+ DLLS.amd64 += wined3dwddm-x86
+ wined3dwddm-x86_EXTENDS = wined3dwddm
+ wined3dwddm-x86_BLD_TRG_ARCH = x86
+ wined3dwddm-x86_DEFS = $(wined3dwddm_DEFS) VBOX_WDDM_WOW64
+ wined3dwddm-x86_LIBS = \
+ $(VBOX_LIB_IPRT_GUEST_R3_X86) \
+ $(VBOX_LIB_VBGL_R3_X86) \
+ $(VBOX_PATH_ADDITIONS_LIB)/VBoxDispMpLogger-x86$(VBOX_SUFF_LIB) \
+ $(VBOX_PATH_ADDITIONS_LIB)/VBoxCrHgsmi-x86$(VBOX_SUFF_LIB) \
+ $(PATH_STAGE_LIB)/VBoxOGL-x86$(VBOX_SUFF_LIB)
+endif # ifdef VBOX_WITH_WDDM
+
+#
+# VBoxD3D8 - ???.
+#
+DLLS += VBoxD3D8
+VBoxD3D8_TEMPLATE = VBoxGuestWineDLL
+VBoxD3D8_SDKS = ReorderCompilerIncs $(VBOX_WINDDK_GST_WLH)
+VBoxD3D8_DEFS = _USE_MATH_DEFINES \
+ VBOX_USING_WINDDK \
+ VBOX_WINE_WITHOUT_LIBWINE
+if "$(KBUILD_TYPE)" != "debug" || defined(VBOX_WINE_NO_DEBUG_MSGS)
+ VBoxD3D8_DEFS += WINE_NO_DEBUG_MSGS
+endif
+VBoxD3D8_INCS := \
+ vbox/libWineStub/include
+VBoxD3D8_SOURCES := \
+ d3d8/d3d8_main.c \
+ d3d8/buffer.c \
+ d3d8/device.c \
+ d3d8/directx.c \
+ d3d8/shader.c \
+ d3d8/surface.c \
+ d3d8/swapchain.c \
+ d3d8/texture.c \
+ d3d8/vertexdeclaration.c \
+ d3d8/volume.c \
+ vbox/libWineStub/debug.c \
+ d3d8/d3d8.def
+VBoxD3D8_LIBS = \
+ $(PATH_STAGE_LIB)/wined3d$(VBOX_SUFF_LIB)
+VBoxD3D8_DEFS += VBOX_WINE_WITH_IPRT
+VBoxD3D8_LIBS += \
+ $(VBOX_LIB_IPRT_GUEST_R3) \
+ $(VBOX_LIB_VBGL_R3)
+
+#
+# VBoxD3D9 - ???.
+#
+DLLS += VBoxD3D9
+VBoxD3D9_TEMPLATE = VBoxGuestWineDLL
+VBoxD3D9_SDKS = ReorderCompilerIncs $(VBOX_WINDDK_GST_WLH)
+VBoxD3D9_DEFS = _USE_MATH_DEFINES \
+ VBOX_USING_WINDDK \
+ VBOX_WINE_WITHOUT_LIBWINE
+if "$(KBUILD_TYPE)" != "debug" || defined(VBOX_WINE_NO_DEBUG_MSGS)
+ VBoxD3D9_DEFS += WINE_NO_DEBUG_MSGS
+endif
+#@todo: do we actually need this?
+#VBoxD3D9_DEFS += VBOX_WITH_WINE_FIX_NO9EX
+VBoxD3D9_INCS := \
+ vbox/libWineStub/include
+VBoxD3D9_SOURCES := \
+ d3d9/d3d9_main.c \
+ d3d9/buffer.c \
+ d3d9/device.c \
+ d3d9/directx.c \
+ d3d9/query.c \
+ d3d9/shader.c \
+ d3d9/stateblock.c \
+ d3d9/surface.c \
+ d3d9/swapchain.c \
+ d3d9/texture.c \
+ d3d9/vertexdeclaration.c \
+ d3d9/volume.c \
+ vbox/libWineStub/debug.c \
+ d3d9/d3d9xpdm.def
+VBoxD3D9_SOURCES.amd64 = d3d9/vboxport.asm
+VBoxD3D9_LIBS = \
+ $(PATH_STAGE_LIB)/wined3d$(VBOX_SUFF_LIB)
+VBoxD3D9_DEFS += VBOX_WINE_WITH_IPRT
+VBoxD3D9_LIBS += \
+ $(VBOX_LIB_IPRT_GUEST_R3) \
+ $(VBOX_LIB_VBGL_R3)
+
+ifdef VBOX_WITH_WDDM
+ #
+ # VBoxD3D9wddm - ???.
+ #
+ DLLS += VBoxD3D9wddm
+ VBoxD3D9wddm_EXTENDS = VBoxD3D9
+ if defined(VBOX_SIGNING_MODE) && defined(VBOX_WITH_WDDM)
+ VBoxD3D9wddm_INSTTYPE = none
+ VBoxD3D9wddm_DEBUG_INSTTYPE = both
+ endif
+ VBoxD3D9wddm_INCS = $(VBoxD3D9_INCS) \
+ $(PATH_ROOT)/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm
+ VBoxD3D9wddm_DEFS += $(VBoxD3D9_DEFS) \
+ VBOX_WITH_WDDM \
+ IN_VBOXWINEEX \
+ VBOX_WINE_NO_LOCK
+ VBoxD3D9wddm_SOURCES = $(subst d3d9xpdm.def,d3d9wddm.def,$(VBoxD3D9_SOURCES))
+ VBoxD3D9wddm_LIBS = \
+ $(subst $(PATH_STAGE_LIB)/wined3d$(VBOX_SUFF_LIB),$(PATH_STAGE_LIB)/wined3dwddm$(VBOX_SUFF_LIB),$(VBoxD3D9_LIBS)) \
+ $(VBOX_PATH_ADDITIONS_LIB)/VBoxDispMpLogger$(VBOX_SUFF_LIB) \
+ $(VBOX_PATH_ADDITIONS_LIB)/VBoxCrHgsmi$(VBOX_SUFF_LIB)
+
+ #
+ # VBoxD3D9wddm-x86 - For WOW64.
+ #
+ DLLS.amd64 += VBoxD3D9wddm-x86
+ VBoxD3D9wddm-x86_EXTENDS = VBoxD3D9wddm
+ VBoxD3D9wddm-x86_BLD_TRG_ARCH = x86
+ VBoxD3D9wddm-x86_DEFS = $(VBoxD3D9wddm_DEFS) VBOX_WDDM_WOW64
+ VBoxD3D9wddm-x86_LIBS = $(PATH_STAGE_LIB)/wined3dwddm-x86$(VBOX_SUFF_LIB)
+ VBoxD3D9wddm-x86_LIBS += \
+ $(VBOX_LIB_IPRT_GUEST_R3_X86) \
+ $(VBOX_LIB_VBGL_R3_X86)
+ VBoxD3D9wddm-x86_LIBS += \
+ $(VBOX_PATH_ADDITIONS_LIB)/VBoxDispMpLogger-x86$(VBOX_SUFF_LIB) \
+ $(VBOX_PATH_ADDITIONS_LIB)/VBoxCrHgsmi-x86$(VBOX_SUFF_LIB)
+endif # VBOX_WITH_WDDM
+
+#
+# d3d8 - ???.
+#
+DLLS += d3d8
+d3d8_TEMPLATE = VBoxGuestWineD3DxDLL
+d3d8_SOURCES = \
+ switcher/d3d8_main.c \
+ switcher/sw_common.c \
+ switcher/sw_d3d8.def \
+ switcher/d3d8.rc
+
+#
+# d3d9 - ???.
+#
+DLLS += d3d9
+d3d9_TEMPLATE = VBoxGuestWineD3DxDLL
+d3d9_SOURCES = \
+ switcher/d3d9_main.c \
+ switcher/sw_common.c \
+ switcher/d3d9.rc
+d3d9_SOURCES.x86 = \
+ switcher/sw_d3d9.def
+d3d9_SOURCES.amd64 = \
+ switcher/sw_d3d9xpdm.def
+
+include $(FILE_KBUILD_SUB_FOOTER)
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/Makefile.kup b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/Makefile.kup
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/buffer.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/buffer.c
new file mode 100644
index 00000000..9599c9af
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/buffer.c
@@ -0,0 +1,620 @@
+/*
+ * Copyright 2005 Oliver Stieber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "d3d8_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
+
+static inline struct d3d8_vertexbuffer *impl_from_IDirect3DVertexBuffer8(IDirect3DVertexBuffer8 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d8_vertexbuffer, IDirect3DVertexBuffer8_iface);
+}
+
+static HRESULT WINAPI d3d8_vertexbuffer_QueryInterface(IDirect3DVertexBuffer8 *iface, REFIID riid, void **object)
+{
+ TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DVertexBuffer8)
+ || IsEqualGUID(riid, &IID_IDirect3DResource8)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DVertexBuffer8_AddRef(iface);
+ *object = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *object = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d8_vertexbuffer_AddRef(IDirect3DVertexBuffer8 *iface)
+{
+ struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
+ ULONG refcount = InterlockedIncrement(&buffer->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, refcount);
+
+ if (refcount == 1)
+ {
+ IDirect3DDevice8_AddRef(buffer->parent_device);
+ wined3d_mutex_lock();
+ wined3d_buffer_incref(buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+ }
+
+ return refcount;
+}
+
+static ULONG WINAPI d3d8_vertexbuffer_Release(IDirect3DVertexBuffer8 *iface)
+{
+ struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
+ ULONG refcount = InterlockedDecrement(&buffer->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ IDirect3DDevice8 *device = buffer->parent_device;
+
+ wined3d_mutex_lock();
+ wined3d_buffer_decref(buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+
+ /* Release the device last, as it may cause the device to be destroyed. */
+ IDirect3DDevice8_Release(device);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI d3d8_vertexbuffer_GetDevice(IDirect3DVertexBuffer8 *iface,
+ IDirect3DDevice8 **device)
+{
+ struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ *device = buffer->parent_device;
+ IDirect3DDevice8_AddRef(*device);
+
+ TRACE("Returning device %p.\n", *device);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_vertexbuffer_SetPrivateData(IDirect3DVertexBuffer8 *iface,
+ REFGUID guid, const void *data, DWORD data_size, DWORD flags)
+{
+ struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
+ iface, debugstr_guid(guid), data, data_size, flags);
+
+ wined3d_mutex_lock();
+ resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
+ hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_vertexbuffer_GetPrivateData(IDirect3DVertexBuffer8 *iface,
+ REFGUID guid, void *data, DWORD *data_size)
+{
+ struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %p.\n",
+ iface, debugstr_guid(guid), data, data_size);
+
+ wined3d_mutex_lock();
+ resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
+ hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_vertexbuffer_FreePrivateData(IDirect3DVertexBuffer8 *iface, REFGUID guid)
+{
+ struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
+
+ wined3d_mutex_lock();
+ resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
+ hr = wined3d_resource_free_private_data(resource, guid);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static DWORD WINAPI d3d8_vertexbuffer_SetPriority(IDirect3DVertexBuffer8 *iface, DWORD priority)
+{
+ struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
+ DWORD previous;
+
+ TRACE("iface %p, priority %u.\n", iface, priority);
+
+ wined3d_mutex_lock();
+ previous = wined3d_buffer_set_priority(buffer->wined3d_buffer, priority);
+ wined3d_mutex_unlock();
+
+ return previous;
+}
+
+static DWORD WINAPI d3d8_vertexbuffer_GetPriority(IDirect3DVertexBuffer8 *iface)
+{
+ struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
+ DWORD priority;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ priority = wined3d_buffer_get_priority(buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+
+ return priority;
+}
+
+static void WINAPI d3d8_vertexbuffer_PreLoad(IDirect3DVertexBuffer8 *iface)
+{
+ struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_buffer_preload(buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+}
+
+static D3DRESOURCETYPE WINAPI d3d8_vertexbuffer_GetType(IDirect3DVertexBuffer8 *iface)
+{
+ TRACE("iface %p.\n", iface);
+
+ return D3DRTYPE_VERTEXBUFFER;
+}
+
+static HRESULT WINAPI d3d8_vertexbuffer_Lock(IDirect3DVertexBuffer8 *iface, UINT offset, UINT size,
+ BYTE **data, DWORD flags)
+{
+ struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n",
+ iface, offset, size, data, flags);
+
+ wined3d_mutex_lock();
+ hr = wined3d_buffer_map(buffer->wined3d_buffer, offset, size, data, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_vertexbuffer_Unlock(IDirect3DVertexBuffer8 *iface)
+{
+ struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_buffer_unmap(buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_vertexbuffer_GetDesc(IDirect3DVertexBuffer8 *iface,
+ D3DVERTEXBUFFER_DESC *desc)
+{
+ struct d3d8_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer8(iface);
+ struct wined3d_resource_desc wined3d_desc;
+ struct wined3d_resource *wined3d_resource;
+
+ TRACE("iface %p, desc %p.\n", iface, desc);
+
+ wined3d_mutex_lock();
+ wined3d_resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
+ wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
+ wined3d_mutex_unlock();
+
+ desc->Type = D3DRTYPE_VERTEXBUFFER;
+ desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
+ desc->Pool = wined3d_desc.pool;
+ desc->Size = wined3d_desc.size;
+ desc->FVF = buffer->fvf;
+ desc->Format = D3DFMT_VERTEXDATA;
+
+ return D3D_OK;
+}
+
+static const IDirect3DVertexBuffer8Vtbl Direct3DVertexBuffer8_Vtbl =
+{
+ /* IUnknown */
+ d3d8_vertexbuffer_QueryInterface,
+ d3d8_vertexbuffer_AddRef,
+ d3d8_vertexbuffer_Release,
+ /* IDirect3DResource8 */
+ d3d8_vertexbuffer_GetDevice,
+ d3d8_vertexbuffer_SetPrivateData,
+ d3d8_vertexbuffer_GetPrivateData,
+ d3d8_vertexbuffer_FreePrivateData,
+ d3d8_vertexbuffer_SetPriority,
+ d3d8_vertexbuffer_GetPriority,
+ d3d8_vertexbuffer_PreLoad,
+ d3d8_vertexbuffer_GetType,
+ /* IDirect3DVertexBuffer8 */
+ d3d8_vertexbuffer_Lock,
+ d3d8_vertexbuffer_Unlock,
+ d3d8_vertexbuffer_GetDesc,
+};
+
+static void STDMETHODCALLTYPE d3d8_vertexbuffer_wined3d_object_destroyed(void *parent)
+{
+ HeapFree(GetProcessHeap(), 0, parent);
+}
+
+static const struct wined3d_parent_ops d3d8_vertexbuffer_wined3d_parent_ops =
+{
+ d3d8_vertexbuffer_wined3d_object_destroyed,
+};
+
+HRESULT vertexbuffer_init(struct d3d8_vertexbuffer *buffer, struct d3d8_device *device,
+ UINT size, DWORD usage, DWORD fvf, D3DPOOL pool)
+{
+ HRESULT hr;
+
+ buffer->IDirect3DVertexBuffer8_iface.lpVtbl = &Direct3DVertexBuffer8_Vtbl;
+ buffer->refcount = 1;
+ buffer->fvf = fvf;
+
+ wined3d_mutex_lock();
+ hr = wined3d_buffer_create_vb(device->wined3d_device, size, usage & WINED3DUSAGE_MASK,
+ (enum wined3d_pool)pool, buffer, &d3d8_vertexbuffer_wined3d_parent_ops, &buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
+ return hr;
+ }
+
+ buffer->parent_device = &device->IDirect3DDevice8_iface;
+ IDirect3DDevice8_AddRef(buffer->parent_device);
+
+ return D3D_OK;
+}
+
+struct d3d8_vertexbuffer *unsafe_impl_from_IDirect3DVertexBuffer8(IDirect3DVertexBuffer8 *iface)
+{
+ if (!iface)
+ return NULL;
+ assert(iface->lpVtbl == &Direct3DVertexBuffer8_Vtbl);
+
+ return impl_from_IDirect3DVertexBuffer8(iface);
+}
+
+static inline struct d3d8_indexbuffer *impl_from_IDirect3DIndexBuffer8(IDirect3DIndexBuffer8 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d8_indexbuffer, IDirect3DIndexBuffer8_iface);
+}
+
+static HRESULT WINAPI d3d8_indexbuffer_QueryInterface(IDirect3DIndexBuffer8 *iface, REFIID riid, void **object)
+{
+ TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DIndexBuffer8)
+ || IsEqualGUID(riid, &IID_IDirect3DResource8)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DIndexBuffer8_AddRef(iface);
+ *object = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *object = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d8_indexbuffer_AddRef(IDirect3DIndexBuffer8 *iface)
+{
+ struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
+ ULONG refcount = InterlockedIncrement(&buffer->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, refcount);
+
+ if (refcount == 1)
+ {
+ IDirect3DDevice8_AddRef(buffer->parent_device);
+ wined3d_mutex_lock();
+ wined3d_buffer_incref(buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+ }
+
+ return refcount;
+}
+
+static ULONG WINAPI d3d8_indexbuffer_Release(IDirect3DIndexBuffer8 *iface)
+{
+ struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
+ ULONG refcount = InterlockedDecrement(&buffer->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ IDirect3DDevice8 *device = buffer->parent_device;
+
+ wined3d_mutex_lock();
+ wined3d_buffer_decref(buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+
+ /* Release the device last, as it may cause the device to be destroyed. */
+ IDirect3DDevice8_Release(device);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI d3d8_indexbuffer_GetDevice(IDirect3DIndexBuffer8 *iface,
+ IDirect3DDevice8 **device)
+{
+ struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ *device = buffer->parent_device;
+ IDirect3DDevice8_AddRef(*device);
+
+ TRACE("Returning device %p.\n", *device);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_indexbuffer_SetPrivateData(IDirect3DIndexBuffer8 *iface,
+ REFGUID guid, const void *data, DWORD data_size, DWORD flags)
+{
+ struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
+ iface, debugstr_guid(guid), data, data_size, flags);
+
+ wined3d_mutex_lock();
+ resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
+ hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_indexbuffer_GetPrivateData(IDirect3DIndexBuffer8 *iface,
+ REFGUID guid, void *data, DWORD *data_size)
+{
+ struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %p.\n",
+ iface, debugstr_guid(guid), data, data_size);
+
+ wined3d_mutex_lock();
+ resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
+ hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_indexbuffer_FreePrivateData(IDirect3DIndexBuffer8 *iface, REFGUID guid)
+{
+ struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
+
+ wined3d_mutex_lock();
+ resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
+ hr = wined3d_resource_free_private_data(resource, guid);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static DWORD WINAPI d3d8_indexbuffer_SetPriority(IDirect3DIndexBuffer8 *iface, DWORD priority)
+{
+ struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
+ DWORD previous;
+
+ TRACE("iface %p, priority %u.\n", iface, priority);
+
+ wined3d_mutex_lock();
+ previous = wined3d_buffer_set_priority(buffer->wined3d_buffer, priority);
+ wined3d_mutex_unlock();
+
+ return previous;
+}
+
+static DWORD WINAPI d3d8_indexbuffer_GetPriority(IDirect3DIndexBuffer8 *iface)
+{
+ struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
+ DWORD priority;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ priority = wined3d_buffer_get_priority(buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+
+ return priority;
+}
+
+static void WINAPI d3d8_indexbuffer_PreLoad(IDirect3DIndexBuffer8 *iface)
+{
+ struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_buffer_preload(buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+}
+
+static D3DRESOURCETYPE WINAPI d3d8_indexbuffer_GetType(IDirect3DIndexBuffer8 *iface)
+{
+ TRACE("iface %p.\n", iface);
+
+ return D3DRTYPE_INDEXBUFFER;
+}
+
+static HRESULT WINAPI d3d8_indexbuffer_Lock(IDirect3DIndexBuffer8 *iface, UINT offset, UINT size,
+ BYTE **data, DWORD flags)
+{
+ struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n",
+ iface, offset, size, data, flags);
+
+ wined3d_mutex_lock();
+ hr = wined3d_buffer_map(buffer->wined3d_buffer, offset, size, data, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_indexbuffer_Unlock(IDirect3DIndexBuffer8 *iface)
+{
+ struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_buffer_unmap(buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_indexbuffer_GetDesc(IDirect3DIndexBuffer8 *iface,
+ D3DINDEXBUFFER_DESC *desc)
+{
+ struct d3d8_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer8(iface);
+ struct wined3d_resource_desc wined3d_desc;
+ struct wined3d_resource *wined3d_resource;
+
+ TRACE("iface %p, desc %p.\n", iface, desc);
+
+ wined3d_mutex_lock();
+ wined3d_resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
+ wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
+ wined3d_mutex_unlock();
+
+ desc->Format = d3dformat_from_wined3dformat(buffer->format);
+ desc->Type = D3DRTYPE_INDEXBUFFER;
+ desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
+ desc->Pool = wined3d_desc.pool;
+ desc->Size = wined3d_desc.size;
+
+ return D3D_OK;
+}
+
+static const IDirect3DIndexBuffer8Vtbl d3d8_indexbuffer_vtbl =
+{
+ /* IUnknown */
+ d3d8_indexbuffer_QueryInterface,
+ d3d8_indexbuffer_AddRef,
+ d3d8_indexbuffer_Release,
+ /* IDirect3DResource8 */
+ d3d8_indexbuffer_GetDevice,
+ d3d8_indexbuffer_SetPrivateData,
+ d3d8_indexbuffer_GetPrivateData,
+ d3d8_indexbuffer_FreePrivateData,
+ d3d8_indexbuffer_SetPriority,
+ d3d8_indexbuffer_GetPriority,
+ d3d8_indexbuffer_PreLoad,
+ d3d8_indexbuffer_GetType,
+ /* IDirect3DIndexBuffer8 */
+ d3d8_indexbuffer_Lock,
+ d3d8_indexbuffer_Unlock,
+ d3d8_indexbuffer_GetDesc,
+};
+
+static void STDMETHODCALLTYPE d3d8_indexbuffer_wined3d_object_destroyed(void *parent)
+{
+ HeapFree(GetProcessHeap(), 0, parent);
+}
+
+static const struct wined3d_parent_ops d3d8_indexbuffer_wined3d_parent_ops =
+{
+ d3d8_indexbuffer_wined3d_object_destroyed,
+};
+
+HRESULT indexbuffer_init(struct d3d8_indexbuffer *buffer, struct d3d8_device *device,
+ UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool)
+{
+ HRESULT hr;
+
+ buffer->IDirect3DIndexBuffer8_iface.lpVtbl = &d3d8_indexbuffer_vtbl;
+ buffer->refcount = 1;
+ buffer->format = wined3dformat_from_d3dformat(format);
+
+ wined3d_mutex_lock();
+ hr = wined3d_buffer_create_ib(device->wined3d_device, size, usage & WINED3DUSAGE_MASK,
+ (enum wined3d_pool)pool, buffer, &d3d8_indexbuffer_wined3d_parent_ops, &buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
+ return hr;
+ }
+
+ buffer->parent_device = &device->IDirect3DDevice8_iface;
+ IDirect3DDevice8_AddRef(buffer->parent_device);
+
+ return D3D_OK;
+}
+
+struct d3d8_indexbuffer *unsafe_impl_from_IDirect3DIndexBuffer8(IDirect3DIndexBuffer8 *iface)
+{
+ if (!iface)
+ return NULL;
+ assert(iface->lpVtbl == &d3d8_indexbuffer_vtbl);
+
+ return impl_from_IDirect3DIndexBuffer8(iface);
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/d3d8.def b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/d3d8.def
new file mode 100644
index 00000000..0a250b56
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/d3d8.def
@@ -0,0 +1,7 @@
+
+EXPORTS
+ D3D8GetSWInfo
+ DebugSetMute
+ Direct3DCreate8
+ ValidatePixelShader
+ ValidateVertexShader
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/d3d8_main.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/d3d8_main.c
new file mode 100644
index 00000000..dd562520
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/d3d8_main.c
@@ -0,0 +1,149 @@
+/*
+ * Direct3D 8
+ *
+ * Copyright 2005 Oliver Stieber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "initguid.h"
+#include "d3d8_private.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
+
+HRESULT WINAPI D3D8GetSWInfo(void) {
+ FIXME("(void): stub\n");
+ return 0;
+}
+
+void WINAPI DebugSetMute(void) {
+ /* nothing to do */
+}
+
+IDirect3D8 * WINAPI DECLSPEC_HOTPATCH Direct3DCreate8(UINT sdk_version)
+{
+ struct d3d8 *object;
+
+ TRACE("sdk_version %#x.\n", sdk_version);
+
+ if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+ return NULL;
+
+ if (!d3d8_init(object))
+ {
+ WARN("Failed to initialize d3d8.\n");
+ HeapFree(GetProcessHeap(), 0, object);
+ return NULL;
+ }
+
+ TRACE("Created d3d8 object %p.\n", object);
+
+ return &object->IDirect3D8_iface;
+}
+
+/* At process attach */
+BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
+{
+ TRACE("fdwReason=%d\n", fdwReason);
+ if (fdwReason == DLL_PROCESS_ATTACH)
+ DisableThreadLibraryCalls(hInstDLL);
+
+ return TRUE;
+}
+
+/***********************************************************************
+ * ValidateVertexShader (D3D8.@)
+ *
+ * I've seen reserved1 and reserved2 always passed as 0's
+ * bool seems always passed as 0 or 1, but other values work as well...
+ * toto result?
+ */
+HRESULT WINAPI ValidateVertexShader(DWORD* vertexshader, DWORD* reserved1, DWORD* reserved2, BOOL bool, DWORD* toto)
+{
+ HRESULT ret;
+ static BOOL warned;
+
+ if (TRACE_ON(d3d8) || !warned) {
+ FIXME("(%p %p %p %d %p): stub\n", vertexshader, reserved1, reserved2, bool, toto);
+ warned = TRUE;
+ }
+
+ if (!vertexshader)
+ return E_FAIL;
+
+ if (reserved1 || reserved2)
+ return E_FAIL;
+
+ switch(*vertexshader) {
+ case 0xFFFE0101:
+ case 0xFFFE0100:
+ ret=S_OK;
+ break;
+ default:
+ WARN("Invalid shader version token %#x.\n", *vertexshader);
+ ret=E_FAIL;
+ }
+
+ return ret;
+}
+
+/***********************************************************************
+ * ValidatePixelShader (D3D8.@)
+ *
+ * PARAMS
+ * toto result?
+ */
+HRESULT WINAPI ValidatePixelShader(DWORD* pixelshader, DWORD* reserved1, BOOL bool, DWORD* toto)
+{
+ HRESULT ret;
+ static BOOL warned;
+
+ if (TRACE_ON(d3d8) || !warned) {
+ FIXME("(%p %p %d %p): stub\n", pixelshader, reserved1, bool, toto);
+ warned = TRUE;
+ }
+
+ if (!pixelshader)
+ return E_FAIL;
+
+ if (reserved1)
+ return E_FAIL;
+
+ switch(*pixelshader) {
+ case 0xFFFF0100:
+ case 0xFFFF0101:
+ case 0xFFFF0102:
+ case 0xFFFF0103:
+ case 0xFFFF0104:
+ ret=S_OK;
+ break;
+ default:
+ WARN("Invalid shader version token %#x.\n", *pixelshader);
+ ret=E_FAIL;
+ }
+ return ret;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/d3d8_private.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/d3d8_private.h
new file mode 100644
index 00000000..4d17a1dc
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/d3d8_private.h
@@ -0,0 +1,311 @@
+/*
+ * Direct3D 8 private include file
+ *
+ * Copyright 2002-2004 Jason Edmeades
+ * Copyright 2003-2004 Raphael Junqueira
+ * Copyright 2004 Christian Costa
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#ifndef __WINE_D3D8_PRIVATE_H
+#define __WINE_D3D8_PRIVATE_H
+
+#include <assert.h>
+#include <stdarg.h>
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#define COBJMACROS
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "wine/debug.h"
+#include "d3d8.h"
+#include "wine/wined3d.h"
+
+/* CreateVertexShader can return > 0xFFFF */
+#define VS_HIGHESTFIXEDFXF 0xF0000000
+
+/* ===========================================================================
+ Macros
+ =========================================================================== */
+/* Not nice, but it lets wined3d support different versions of directx */
+#define WINECAPSTOD3D8CAPS(_pD3D8Caps, _pWineCaps) \
+ _pD3D8Caps->DeviceType = (D3DDEVTYPE) _pWineCaps->DeviceType; \
+ _pD3D8Caps->AdapterOrdinal = _pWineCaps->AdapterOrdinal; \
+ _pD3D8Caps->Caps = _pWineCaps->Caps; \
+ _pD3D8Caps->Caps2 = _pWineCaps->Caps2; \
+ _pD3D8Caps->Caps3 = _pWineCaps->Caps3; \
+ _pD3D8Caps->PresentationIntervals = _pWineCaps->PresentationIntervals; \
+ _pD3D8Caps->CursorCaps = _pWineCaps->CursorCaps; \
+ _pD3D8Caps->DevCaps = _pWineCaps->DevCaps; \
+ _pD3D8Caps->PrimitiveMiscCaps = _pWineCaps->PrimitiveMiscCaps; \
+ _pD3D8Caps->RasterCaps = _pWineCaps->RasterCaps; \
+ _pD3D8Caps->ZCmpCaps = _pWineCaps->ZCmpCaps; \
+ _pD3D8Caps->SrcBlendCaps = _pWineCaps->SrcBlendCaps; \
+ _pD3D8Caps->DestBlendCaps = _pWineCaps->DestBlendCaps; \
+ _pD3D8Caps->AlphaCmpCaps = _pWineCaps->AlphaCmpCaps; \
+ _pD3D8Caps->ShadeCaps = _pWineCaps->ShadeCaps; \
+ _pD3D8Caps->TextureCaps = _pWineCaps->TextureCaps; \
+ _pD3D8Caps->TextureFilterCaps = _pWineCaps->TextureFilterCaps; \
+ _pD3D8Caps->CubeTextureFilterCaps = _pWineCaps->CubeTextureFilterCaps; \
+ _pD3D8Caps->VolumeTextureFilterCaps = _pWineCaps->VolumeTextureFilterCaps; \
+ _pD3D8Caps->TextureAddressCaps = _pWineCaps->TextureAddressCaps; \
+ _pD3D8Caps->VolumeTextureAddressCaps = _pWineCaps->VolumeTextureAddressCaps; \
+ _pD3D8Caps->LineCaps = _pWineCaps->LineCaps; \
+ _pD3D8Caps->MaxTextureWidth = _pWineCaps->MaxTextureWidth; \
+ _pD3D8Caps->MaxTextureHeight = _pWineCaps->MaxTextureHeight; \
+ _pD3D8Caps->MaxVolumeExtent = _pWineCaps->MaxVolumeExtent; \
+ _pD3D8Caps->MaxTextureRepeat = _pWineCaps->MaxTextureRepeat; \
+ _pD3D8Caps->MaxTextureAspectRatio = _pWineCaps->MaxTextureAspectRatio; \
+ _pD3D8Caps->MaxAnisotropy = _pWineCaps->MaxAnisotropy; \
+ _pD3D8Caps->MaxVertexW = _pWineCaps->MaxVertexW; \
+ _pD3D8Caps->GuardBandLeft = _pWineCaps->GuardBandLeft; \
+ _pD3D8Caps->GuardBandTop = _pWineCaps->GuardBandTop; \
+ _pD3D8Caps->GuardBandRight = _pWineCaps->GuardBandRight; \
+ _pD3D8Caps->GuardBandBottom = _pWineCaps->GuardBandBottom; \
+ _pD3D8Caps->ExtentsAdjust = _pWineCaps->ExtentsAdjust; \
+ _pD3D8Caps->StencilCaps = _pWineCaps->StencilCaps; \
+ _pD3D8Caps->FVFCaps = _pWineCaps->FVFCaps; \
+ _pD3D8Caps->TextureOpCaps = _pWineCaps->TextureOpCaps; \
+ _pD3D8Caps->MaxTextureBlendStages = _pWineCaps->MaxTextureBlendStages; \
+ _pD3D8Caps->MaxSimultaneousTextures = _pWineCaps->MaxSimultaneousTextures; \
+ _pD3D8Caps->VertexProcessingCaps = _pWineCaps->VertexProcessingCaps; \
+ _pD3D8Caps->MaxActiveLights = _pWineCaps->MaxActiveLights; \
+ _pD3D8Caps->MaxUserClipPlanes = _pWineCaps->MaxUserClipPlanes; \
+ _pD3D8Caps->MaxVertexBlendMatrices = _pWineCaps->MaxVertexBlendMatrices; \
+ _pD3D8Caps->MaxVertexBlendMatrixIndex = _pWineCaps->MaxVertexBlendMatrixIndex; \
+ _pD3D8Caps->MaxPointSize = _pWineCaps->MaxPointSize; \
+ _pD3D8Caps->MaxPrimitiveCount = _pWineCaps->MaxPrimitiveCount; \
+ _pD3D8Caps->MaxVertexIndex = _pWineCaps->MaxVertexIndex; \
+ _pD3D8Caps->MaxStreams = _pWineCaps->MaxStreams; \
+ _pD3D8Caps->MaxStreamStride = _pWineCaps->MaxStreamStride; \
+ _pD3D8Caps->VertexShaderVersion = _pWineCaps->VertexShaderVersion; \
+ _pD3D8Caps->MaxVertexShaderConst = _pWineCaps->MaxVertexShaderConst; \
+ _pD3D8Caps->PixelShaderVersion = _pWineCaps->PixelShaderVersion; \
+ _pD3D8Caps->MaxPixelShaderValue = _pWineCaps->PixelShader1xMaxValue;
+
+void fixup_caps(WINED3DCAPS *pWineCaps) DECLSPEC_HIDDEN;
+
+struct d3d8
+{
+ IDirect3D8 IDirect3D8_iface;
+ LONG refcount;
+ struct wined3d *wined3d;
+};
+
+BOOL d3d8_init(struct d3d8 *d3d8) DECLSPEC_HIDDEN;
+
+/*****************************************************************************
+ * IDirect3DDevice8 implementation structure
+ */
+
+#define D3D8_INITIAL_HANDLE_TABLE_SIZE 64
+#define D3D8_INVALID_HANDLE ~0U
+
+enum d3d8_handle_type
+{
+ D3D8_HANDLE_FREE,
+ D3D8_HANDLE_VS,
+ D3D8_HANDLE_PS,
+ D3D8_HANDLE_SB,
+};
+
+struct d3d8_handle_entry
+{
+ void *object;
+ enum d3d8_handle_type type;
+};
+
+struct d3d8_handle_table
+{
+ struct d3d8_handle_entry *entries;
+ struct d3d8_handle_entry *free_entries;
+ UINT table_size;
+ UINT entry_count;
+};
+
+struct FvfToDecl
+{
+ DWORD fvf;
+ struct d3d8_vertex_declaration *declaration;
+};
+
+struct d3d8_device
+{
+ /* IUnknown fields */
+ IDirect3DDevice8 IDirect3DDevice8_iface;
+ struct wined3d_device_parent device_parent;
+ LONG ref;
+ struct wined3d_device *wined3d_device;
+ IDirect3D8 *d3d_parent;
+ struct d3d8_handle_table handle_table;
+
+ /* FVF management */
+ struct FvfToDecl *decls;
+ UINT numConvertedDecls, declArraySize;
+
+ /* User data draws */
+ struct wined3d_buffer *vertex_buffer;
+ UINT vertex_buffer_size;
+ UINT vertex_buffer_pos;
+ struct wined3d_buffer *index_buffer;
+ UINT index_buffer_size;
+ UINT index_buffer_pos;
+
+ /* Avoids recursion with nested ReleaseRef to 0 */
+ BOOL inDestruction;
+ BOOL lost;
+};
+
+HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wined3d *wined3d, UINT adapter,
+ D3DDEVTYPE device_type, HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters) DECLSPEC_HIDDEN;
+
+struct d3d8_volume
+{
+ IDirect3DVolume8 IDirect3DVolume8_iface;
+ LONG refcount;
+ struct wined3d_volume *wined3d_volume;
+ IUnknown *container;
+ IUnknown *forwardReference;
+};
+
+HRESULT volume_init(struct d3d8_volume *volume, struct d3d8_device *device, UINT width, UINT height,
+ UINT depth, DWORD usage, enum wined3d_format_id format, enum wined3d_pool pool) DECLSPEC_HIDDEN;
+
+struct d3d8_swapchain
+{
+ IDirect3DSwapChain8 IDirect3DSwapChain8_iface;
+ LONG refcount;
+ struct wined3d_swapchain *wined3d_swapchain;
+ IDirect3DDevice8 *parent_device;
+};
+
+HRESULT d3d8_swapchain_create(struct d3d8_device *device, struct wined3d_swapchain_desc *desc,
+ struct d3d8_swapchain **swapchain) DECLSPEC_HIDDEN;
+
+struct d3d8_surface
+{
+ IDirect3DSurface8 IDirect3DSurface8_iface;
+ LONG refcount;
+ struct wined3d_surface *wined3d_surface;
+ IDirect3DDevice8 *parent_device;
+
+ /* The surface container */
+ IUnknown *container;
+
+ /* If set forward refcounting to this object */
+ IUnknown *forwardReference;
+};
+
+HRESULT surface_init(struct d3d8_surface *surface, struct d3d8_device *device, UINT width, UINT height,
+ D3DFORMAT format, DWORD flags, DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type,
+ DWORD multisample_quality) DECLSPEC_HIDDEN;
+struct d3d8_surface *unsafe_impl_from_IDirect3DSurface8(IDirect3DSurface8 *iface) DECLSPEC_HIDDEN;
+
+struct d3d8_vertexbuffer
+{
+ IDirect3DVertexBuffer8 IDirect3DVertexBuffer8_iface;
+ LONG refcount;
+ struct wined3d_buffer *wined3d_buffer;
+ IDirect3DDevice8 *parent_device;
+ DWORD fvf;
+};
+
+HRESULT vertexbuffer_init(struct d3d8_vertexbuffer *buffer, struct d3d8_device *device,
+ UINT size, DWORD usage, DWORD fvf, D3DPOOL pool) DECLSPEC_HIDDEN;
+struct d3d8_vertexbuffer *unsafe_impl_from_IDirect3DVertexBuffer8(IDirect3DVertexBuffer8 *iface) DECLSPEC_HIDDEN;
+
+struct d3d8_indexbuffer
+{
+ IDirect3DIndexBuffer8 IDirect3DIndexBuffer8_iface;
+ LONG refcount;
+ struct wined3d_buffer *wined3d_buffer;
+ IDirect3DDevice8 *parent_device;
+ enum wined3d_format_id format;
+};
+
+HRESULT indexbuffer_init(struct d3d8_indexbuffer *buffer, struct d3d8_device *device,
+ UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool) DECLSPEC_HIDDEN;
+struct d3d8_indexbuffer *unsafe_impl_from_IDirect3DIndexBuffer8(IDirect3DIndexBuffer8 *iface) DECLSPEC_HIDDEN;
+
+struct d3d8_texture
+{
+ IDirect3DBaseTexture8 IDirect3DBaseTexture8_iface;
+ LONG refcount;
+ struct wined3d_texture *wined3d_texture;
+ IDirect3DDevice8 *parent_device;
+};
+
+HRESULT cubetexture_init(struct d3d8_texture *texture, struct d3d8_device *device,
+ UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) DECLSPEC_HIDDEN;
+HRESULT texture_init(struct d3d8_texture *texture, struct d3d8_device *device,
+ UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) DECLSPEC_HIDDEN;
+HRESULT volumetexture_init(struct d3d8_texture *texture, struct d3d8_device *device,
+ UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) DECLSPEC_HIDDEN;
+struct d3d8_texture *unsafe_impl_from_IDirect3DBaseTexture8(IDirect3DBaseTexture8 *iface) DECLSPEC_HIDDEN;
+
+struct d3d8_vertex_declaration
+{
+ DWORD *elements;
+ DWORD elements_size; /* Size of elements, in bytes */
+ struct wined3d_vertex_declaration *wined3d_vertex_declaration;
+ DWORD shader_handle;
+};
+
+void d3d8_vertex_declaration_destroy(struct d3d8_vertex_declaration *declaration) DECLSPEC_HIDDEN;
+HRESULT d3d8_vertex_declaration_init(struct d3d8_vertex_declaration *declaration,
+ struct d3d8_device *device, const DWORD *elements, DWORD shader_handle) DECLSPEC_HIDDEN;
+HRESULT d3d8_vertex_declaration_init_fvf(struct d3d8_vertex_declaration *declaration,
+ struct d3d8_device *device, DWORD fvf) DECLSPEC_HIDDEN;
+
+struct d3d8_vertex_shader
+{
+ struct d3d8_vertex_declaration *vertex_declaration;
+ struct wined3d_shader *wined3d_shader;
+};
+
+void d3d8_vertex_shader_destroy(struct d3d8_vertex_shader *shader) DECLSPEC_HIDDEN;
+HRESULT d3d8_vertex_shader_init(struct d3d8_vertex_shader *shader, struct d3d8_device *device,
+ const DWORD *declaration, const DWORD *byte_code, DWORD shader_handle, DWORD usage) DECLSPEC_HIDDEN;
+
+#define D3D8_MAX_VERTEX_SHADER_CONSTANTF 256
+
+struct d3d8_pixel_shader
+{
+ DWORD handle;
+ struct wined3d_shader *wined3d_shader;
+};
+
+void d3d8_pixel_shader_destroy(struct d3d8_pixel_shader *shader) DECLSPEC_HIDDEN;
+HRESULT d3d8_pixel_shader_init(struct d3d8_pixel_shader *shader, struct d3d8_device *device,
+ const DWORD *byte_code, DWORD shader_handle) DECLSPEC_HIDDEN;
+
+D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN;
+enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) DECLSPEC_HIDDEN;
+void load_local_constants(const DWORD *d3d8_elements, struct wined3d_shader *wined3d_vertex_shader) DECLSPEC_HIDDEN;
+size_t parse_token(const DWORD *pToken) DECLSPEC_HIDDEN;
+
+#endif /* __WINE_D3DX8_PRIVATE_H */
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/device.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/device.c
new file mode 100644
index 00000000..f1599ccd
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/device.c
@@ -0,0 +1,3163 @@
+/*
+ * IDirect3DDevice8 implementation
+ *
+ * Copyright 2002-2004 Jason Edmeades
+ * Copyright 2004 Christian Costa
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+
+#include <math.h>
+#include <stdarg.h>
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "wingdi.h"
+#include "wine/debug.h"
+
+#include "d3d8_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
+
+D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format)
+{
+ BYTE *c = (BYTE *)&format;
+
+ /* Don't translate FOURCC formats */
+ if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format;
+
+ switch(format)
+ {
+ case WINED3DFMT_UNKNOWN: return D3DFMT_UNKNOWN;
+ case WINED3DFMT_B8G8R8_UNORM: return D3DFMT_R8G8B8;
+ case WINED3DFMT_B8G8R8A8_UNORM: return D3DFMT_A8R8G8B8;
+ case WINED3DFMT_B8G8R8X8_UNORM: return D3DFMT_X8R8G8B8;
+ case WINED3DFMT_B5G6R5_UNORM: return D3DFMT_R5G6B5;
+ case WINED3DFMT_B5G5R5X1_UNORM: return D3DFMT_X1R5G5B5;
+ case WINED3DFMT_B5G5R5A1_UNORM: return D3DFMT_A1R5G5B5;
+ case WINED3DFMT_B4G4R4A4_UNORM: return D3DFMT_A4R4G4B4;
+ case WINED3DFMT_B2G3R3_UNORM: return D3DFMT_R3G3B2;
+ case WINED3DFMT_A8_UNORM: return D3DFMT_A8;
+ case WINED3DFMT_B2G3R3A8_UNORM: return D3DFMT_A8R3G3B2;
+ case WINED3DFMT_B4G4R4X4_UNORM: return D3DFMT_X4R4G4B4;
+ case WINED3DFMT_R10G10B10A2_UNORM: return D3DFMT_A2B10G10R10;
+ case WINED3DFMT_R16G16_UNORM: return D3DFMT_G16R16;
+ case WINED3DFMT_P8_UINT_A8_UNORM: return D3DFMT_A8P8;
+ case WINED3DFMT_P8_UINT: return D3DFMT_P8;
+ case WINED3DFMT_L8_UNORM: return D3DFMT_L8;
+ case WINED3DFMT_L8A8_UNORM: return D3DFMT_A8L8;
+ case WINED3DFMT_L4A4_UNORM: return D3DFMT_A4L4;
+ case WINED3DFMT_R8G8_SNORM: return D3DFMT_V8U8;
+ case WINED3DFMT_R5G5_SNORM_L6_UNORM: return D3DFMT_L6V5U5;
+ case WINED3DFMT_R8G8_SNORM_L8X8_UNORM: return D3DFMT_X8L8V8U8;
+ case WINED3DFMT_R8G8B8A8_SNORM: return D3DFMT_Q8W8V8U8;
+ case WINED3DFMT_R16G16_SNORM: return D3DFMT_V16U16;
+ case WINED3DFMT_R10G11B11_SNORM: return D3DFMT_W11V11U10;
+ case WINED3DFMT_R10G10B10_SNORM_A2_UNORM: return D3DFMT_A2W10V10U10;
+ case WINED3DFMT_D16_LOCKABLE: return D3DFMT_D16_LOCKABLE;
+ case WINED3DFMT_D32_UNORM: return D3DFMT_D32;
+ case WINED3DFMT_S1_UINT_D15_UNORM: return D3DFMT_D15S1;
+ case WINED3DFMT_D24_UNORM_S8_UINT: return D3DFMT_D24S8;
+ case WINED3DFMT_X8D24_UNORM: return D3DFMT_D24X8;
+ case WINED3DFMT_S4X4_UINT_D24_UNORM: return D3DFMT_D24X4S4;
+ case WINED3DFMT_D16_UNORM: return D3DFMT_D16;
+ case WINED3DFMT_VERTEXDATA: return D3DFMT_VERTEXDATA;
+ case WINED3DFMT_R16_UINT: return D3DFMT_INDEX16;
+ case WINED3DFMT_R32_UINT: return D3DFMT_INDEX32;
+ default:
+ FIXME("Unhandled wined3d format %#x.\n", format);
+ return D3DFMT_UNKNOWN;
+ }
+}
+
+enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format)
+{
+ BYTE *c = (BYTE *)&format;
+
+ /* Don't translate FOURCC formats */
+ if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format;
+
+ switch(format)
+ {
+ case D3DFMT_UNKNOWN: return WINED3DFMT_UNKNOWN;
+ case D3DFMT_R8G8B8: return WINED3DFMT_B8G8R8_UNORM;
+ case D3DFMT_A8R8G8B8: return WINED3DFMT_B8G8R8A8_UNORM;
+ case D3DFMT_X8R8G8B8: return WINED3DFMT_B8G8R8X8_UNORM;
+ case D3DFMT_R5G6B5: return WINED3DFMT_B5G6R5_UNORM;
+ case D3DFMT_X1R5G5B5: return WINED3DFMT_B5G5R5X1_UNORM;
+ case D3DFMT_A1R5G5B5: return WINED3DFMT_B5G5R5A1_UNORM;
+ case D3DFMT_A4R4G4B4: return WINED3DFMT_B4G4R4A4_UNORM;
+ case D3DFMT_R3G3B2: return WINED3DFMT_B2G3R3_UNORM;
+ case D3DFMT_A8: return WINED3DFMT_A8_UNORM;
+ case D3DFMT_A8R3G3B2: return WINED3DFMT_B2G3R3A8_UNORM;
+ case D3DFMT_X4R4G4B4: return WINED3DFMT_B4G4R4X4_UNORM;
+ case D3DFMT_A2B10G10R10: return WINED3DFMT_R10G10B10A2_UNORM;
+ case D3DFMT_G16R16: return WINED3DFMT_R16G16_UNORM;
+ case D3DFMT_A8P8: return WINED3DFMT_P8_UINT_A8_UNORM;
+ case D3DFMT_P8: return WINED3DFMT_P8_UINT;
+ case D3DFMT_L8: return WINED3DFMT_L8_UNORM;
+ case D3DFMT_A8L8: return WINED3DFMT_L8A8_UNORM;
+ case D3DFMT_A4L4: return WINED3DFMT_L4A4_UNORM;
+ case D3DFMT_V8U8: return WINED3DFMT_R8G8_SNORM;
+ case D3DFMT_L6V5U5: return WINED3DFMT_R5G5_SNORM_L6_UNORM;
+ case D3DFMT_X8L8V8U8: return WINED3DFMT_R8G8_SNORM_L8X8_UNORM;
+ case D3DFMT_Q8W8V8U8: return WINED3DFMT_R8G8B8A8_SNORM;
+ case D3DFMT_V16U16: return WINED3DFMT_R16G16_SNORM;
+ case D3DFMT_W11V11U10: return WINED3DFMT_R10G11B11_SNORM;
+ case D3DFMT_A2W10V10U10: return WINED3DFMT_R10G10B10_SNORM_A2_UNORM;
+ case D3DFMT_D16_LOCKABLE: return WINED3DFMT_D16_LOCKABLE;
+ case D3DFMT_D32: return WINED3DFMT_D32_UNORM;
+ case D3DFMT_D15S1: return WINED3DFMT_S1_UINT_D15_UNORM;
+ case D3DFMT_D24S8: return WINED3DFMT_D24_UNORM_S8_UINT;
+ case D3DFMT_D24X8: return WINED3DFMT_X8D24_UNORM;
+ case D3DFMT_D24X4S4: return WINED3DFMT_S4X4_UINT_D24_UNORM;
+ case D3DFMT_D16: return WINED3DFMT_D16_UNORM;
+ case D3DFMT_VERTEXDATA: return WINED3DFMT_VERTEXDATA;
+ case D3DFMT_INDEX16: return WINED3DFMT_R16_UINT;
+ case D3DFMT_INDEX32: return WINED3DFMT_R32_UINT;
+ default:
+ FIXME("Unhandled D3DFORMAT %#x\n", format);
+ return WINED3DFMT_UNKNOWN;
+ }
+}
+
+static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count)
+{
+ switch(primitive_type)
+ {
+ case D3DPT_POINTLIST:
+ return primitive_count;
+
+ case D3DPT_LINELIST:
+ return primitive_count * 2;
+
+ case D3DPT_LINESTRIP:
+ return primitive_count + 1;
+
+ case D3DPT_TRIANGLELIST:
+ return primitive_count * 3;
+
+ case D3DPT_TRIANGLESTRIP:
+ case D3DPT_TRIANGLEFAN:
+ return primitive_count + 2;
+
+ default:
+ FIXME("Unhandled primitive type %#x\n", primitive_type);
+ return 0;
+ }
+}
+
+static void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters,
+ const struct wined3d_swapchain_desc *swapchain_desc)
+{
+ present_parameters->BackBufferWidth = swapchain_desc->backbuffer_width;
+ present_parameters->BackBufferHeight = swapchain_desc->backbuffer_height;
+ present_parameters->BackBufferFormat = d3dformat_from_wined3dformat(swapchain_desc->backbuffer_format);
+ present_parameters->BackBufferCount = swapchain_desc->backbuffer_count;
+ present_parameters->MultiSampleType = swapchain_desc->multisample_type;
+ present_parameters->SwapEffect = swapchain_desc->swap_effect;
+ present_parameters->hDeviceWindow = swapchain_desc->device_window;
+ present_parameters->Windowed = swapchain_desc->windowed;
+ present_parameters->EnableAutoDepthStencil = swapchain_desc->enable_auto_depth_stencil;
+ present_parameters->AutoDepthStencilFormat
+ = d3dformat_from_wined3dformat(swapchain_desc->auto_depth_stencil_format);
+ present_parameters->Flags = swapchain_desc->flags;
+ present_parameters->FullScreen_RefreshRateInHz = swapchain_desc->refresh_rate;
+ present_parameters->FullScreen_PresentationInterval = swapchain_desc->swap_interval;
+}
+
+static void wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc,
+ const D3DPRESENT_PARAMETERS *present_parameters)
+{
+ swapchain_desc->backbuffer_width = present_parameters->BackBufferWidth;
+ swapchain_desc->backbuffer_height = present_parameters->BackBufferHeight;
+ swapchain_desc->backbuffer_format = wined3dformat_from_d3dformat(present_parameters->BackBufferFormat);
+ swapchain_desc->backbuffer_count = max(1, present_parameters->BackBufferCount);
+ swapchain_desc->multisample_type = present_parameters->MultiSampleType;
+ swapchain_desc->multisample_quality = 0; /* d3d9 only */
+ swapchain_desc->swap_effect = present_parameters->SwapEffect;
+ swapchain_desc->device_window = present_parameters->hDeviceWindow;
+ swapchain_desc->windowed = present_parameters->Windowed;
+ swapchain_desc->enable_auto_depth_stencil = present_parameters->EnableAutoDepthStencil;
+ swapchain_desc->auto_depth_stencil_format
+ = wined3dformat_from_d3dformat(present_parameters->AutoDepthStencilFormat);
+ swapchain_desc->flags = present_parameters->Flags;
+ swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz;
+ swapchain_desc->swap_interval = present_parameters->FullScreen_PresentationInterval;
+ swapchain_desc->auto_restore_display_mode = TRUE;
+}
+
+/* Handle table functions */
+static DWORD d3d8_allocate_handle(struct d3d8_handle_table *t, void *object, enum d3d8_handle_type type)
+{
+ struct d3d8_handle_entry *entry;
+
+ if (t->free_entries)
+ {
+ DWORD index = t->free_entries - t->entries;
+ /* Use a free handle */
+ entry = t->free_entries;
+ if (entry->type != D3D8_HANDLE_FREE)
+ {
+ ERR("Handle %u(%p) is in the free list, but has type %#x.\n", index, entry, entry->type);
+ return D3D8_INVALID_HANDLE;
+ }
+ t->free_entries = entry->object;
+ entry->object = object;
+ entry->type = type;
+
+ return index;
+ }
+
+ if (!(t->entry_count < t->table_size))
+ {
+ /* Grow the table */
+ UINT new_size = t->table_size + (t->table_size >> 1);
+ struct d3d8_handle_entry *new_entries = HeapReAlloc(GetProcessHeap(),
+ 0, t->entries, new_size * sizeof(*t->entries));
+ if (!new_entries)
+ {
+ ERR("Failed to grow the handle table.\n");
+ return D3D8_INVALID_HANDLE;
+ }
+ t->entries = new_entries;
+ t->table_size = new_size;
+ }
+
+ entry = &t->entries[t->entry_count];
+ entry->object = object;
+ entry->type = type;
+
+ return t->entry_count++;
+}
+
+static void *d3d8_free_handle(struct d3d8_handle_table *t, DWORD handle, enum d3d8_handle_type type)
+{
+ struct d3d8_handle_entry *entry;
+ void *object;
+
+ if (handle == D3D8_INVALID_HANDLE || handle >= t->entry_count)
+ {
+ WARN("Invalid handle %u passed.\n", handle);
+ return NULL;
+ }
+
+ entry = &t->entries[handle];
+ if (entry->type != type)
+ {
+ WARN("Handle %u(%p) is not of type %#x.\n", handle, entry, type);
+ return NULL;
+ }
+
+ object = entry->object;
+ entry->object = t->free_entries;
+ entry->type = D3D8_HANDLE_FREE;
+ t->free_entries = entry;
+
+ return object;
+}
+
+static void *d3d8_get_object(struct d3d8_handle_table *t, DWORD handle, enum d3d8_handle_type type)
+{
+ struct d3d8_handle_entry *entry;
+
+ if (handle == D3D8_INVALID_HANDLE || handle >= t->entry_count)
+ {
+ WARN("Invalid handle %u passed.\n", handle);
+ return NULL;
+ }
+
+ entry = &t->entries[handle];
+ if (entry->type != type)
+ {
+ WARN("Handle %u(%p) is not of type %#x.\n", handle, entry, type);
+ return NULL;
+ }
+
+ return entry->object;
+}
+
+static inline struct d3d8_device *impl_from_IDirect3DDevice8(IDirect3DDevice8 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d8_device, IDirect3DDevice8_iface);
+}
+
+static HRESULT WINAPI d3d8_device_QueryInterface(IDirect3DDevice8 *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n",
+ iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DDevice8)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DDevice8_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d8_device_AddRef(IDirect3DDevice8 *iface)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ ULONG ref = InterlockedIncrement(&device->ref);
+
+ TRACE("%p increasing refcount to %u.\n", iface, ref);
+
+ return ref;
+}
+
+static ULONG WINAPI d3d8_device_Release(IDirect3DDevice8 *iface)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ ULONG ref;
+
+ if (device->inDestruction)
+ return 0;
+
+ ref = InterlockedDecrement(&device->ref);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, ref);
+
+ if (!ref)
+ {
+ IDirect3D8 *parent = device->d3d_parent;
+ unsigned i;
+
+ TRACE("Releasing wined3d device %p.\n", device->wined3d_device);
+
+ wined3d_mutex_lock();
+
+ device->inDestruction = TRUE;
+
+ for (i = 0; i < device->numConvertedDecls; ++i)
+ {
+ d3d8_vertex_declaration_destroy(device->decls[i].declaration);
+ }
+ HeapFree(GetProcessHeap(), 0, device->decls);
+
+ if (device->vertex_buffer)
+ wined3d_buffer_decref(device->vertex_buffer);
+ if (device->index_buffer)
+ wined3d_buffer_decref(device->index_buffer);
+
+ wined3d_device_uninit_3d(device->wined3d_device);
+ wined3d_device_release_focus_window(device->wined3d_device);
+ wined3d_device_decref(device->wined3d_device);
+ HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
+ HeapFree(GetProcessHeap(), 0, device);
+
+ wined3d_mutex_unlock();
+
+ IDirect3D8_Release(parent);
+ }
+ return ref;
+}
+
+static HRESULT WINAPI d3d8_device_TestCooperativeLevel(IDirect3DDevice8 *iface)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ if (device->lost)
+ {
+ TRACE("Device is lost.\n");
+ return D3DERR_DEVICENOTRESET;
+ }
+
+ return D3D_OK;
+}
+
+static UINT WINAPI d3d8_device_GetAvailableTextureMem(IDirect3DDevice8 *iface)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_available_texture_mem(device->wined3d_device);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_ResourceManagerDiscardBytes(IDirect3DDevice8 *iface, DWORD byte_count)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+
+ TRACE("iface %p, byte_count %u.\n", iface, byte_count);
+
+ if (byte_count)
+ FIXME("Byte count ignored.\n");
+
+ wined3d_mutex_lock();
+ wined3d_device_evict_managed_resources(device->wined3d_device);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_GetDirect3D(IDirect3DDevice8 *iface, IDirect3D8 **d3d8)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+
+ TRACE("iface %p, d3d8 %p.\n", iface, d3d8);
+
+ if (!d3d8)
+ return D3DERR_INVALIDCALL;
+
+ return IDirect3D8_QueryInterface(device->d3d_parent, &IID_IDirect3D8, (void **)d3d8);
+}
+
+static HRESULT WINAPI d3d8_device_GetDeviceCaps(IDirect3DDevice8 *iface, D3DCAPS8 *caps)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ WINED3DCAPS *wined3d_caps;
+ HRESULT hr;
+
+ TRACE("iface %p, caps %p.\n", iface, caps);
+
+ if (!caps)
+ return D3DERR_INVALIDCALL;
+
+ if (!(wined3d_caps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wined3d_caps))))
+ return D3DERR_INVALIDCALL; /* well this is what MSDN says to return */
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_device_caps(device->wined3d_device, wined3d_caps);
+ wined3d_mutex_unlock();
+
+ fixup_caps(wined3d_caps);
+ WINECAPSTOD3D8CAPS(caps, wined3d_caps)
+ HeapFree(GetProcessHeap(), 0, wined3d_caps);
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_GetDisplayMode(IDirect3DDevice8 *iface, D3DDISPLAYMODE *mode)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct wined3d_display_mode wined3d_mode;
+ HRESULT hr;
+
+ TRACE("iface %p, mode %p.\n", iface, mode);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_display_mode(device->wined3d_device, 0, &wined3d_mode, NULL);
+ wined3d_mutex_unlock();
+
+ if (SUCCEEDED(hr))
+ {
+ mode->Width = wined3d_mode.width;
+ mode->Height = wined3d_mode.height;
+ mode->RefreshRate = wined3d_mode.refresh_rate;
+ mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id);
+ }
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_GetCreationParameters(IDirect3DDevice8 *iface,
+ D3DDEVICE_CREATION_PARAMETERS *parameters)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+
+ TRACE("iface %p, parameters %p.\n", iface, parameters);
+
+ wined3d_mutex_lock();
+ wined3d_device_get_creation_parameters(device->wined3d_device,
+ (struct wined3d_device_creation_parameters *)parameters);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_SetCursorProperties(IDirect3DDevice8 *iface,
+ UINT hotspot_x, UINT hotspot_y, IDirect3DSurface8 *bitmap)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_surface *bitmap_impl = unsafe_impl_from_IDirect3DSurface8(bitmap);
+ HRESULT hr;
+
+ TRACE("iface %p, hotspot_x %u, hotspot_y %u, bitmap %p.\n",
+ iface, hotspot_x, hotspot_y, bitmap);
+
+ if (!bitmap)
+ {
+ WARN("No cursor bitmap, returning D3DERR_INVALIDCALL.\n");
+ return D3DERR_INVALIDCALL;
+ }
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_cursor_properties(device->wined3d_device,
+ hotspot_x, hotspot_y, bitmap_impl->wined3d_surface);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static void WINAPI d3d8_device_SetCursorPosition(IDirect3DDevice8 *iface, UINT x, UINT y, DWORD flags)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+
+ TRACE("iface %p, x %u, y %u, flags %#x.\n", iface, x, y, flags);
+
+ wined3d_mutex_lock();
+ wined3d_device_set_cursor_position(device->wined3d_device, x, y, flags);
+ wined3d_mutex_unlock();
+}
+
+static BOOL WINAPI d3d8_device_ShowCursor(IDirect3DDevice8 *iface, BOOL show)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ BOOL ret;
+
+ TRACE("iface %p, show %#x.\n", iface, show);
+
+ wined3d_mutex_lock();
+ ret = wined3d_device_show_cursor(device->wined3d_device, show);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static HRESULT WINAPI d3d8_device_CreateAdditionalSwapChain(IDirect3DDevice8 *iface,
+ D3DPRESENT_PARAMETERS *present_parameters, IDirect3DSwapChain8 **swapchain)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct wined3d_swapchain_desc desc;
+ struct d3d8_swapchain *object;
+
+ TRACE("iface %p, present_parameters %p, swapchain %p.\n",
+ iface, present_parameters, swapchain);
+
+ wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters);
+ if (SUCCEEDED(d3d8_swapchain_create(device, &desc, &object)))
+ *swapchain = &object->IDirect3DSwapChain8_iface;
+ present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc);
+
+ return D3D_OK;
+}
+
+static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource)
+{
+ struct wined3d_resource_desc desc;
+
+ wined3d_resource_get_desc(resource, &desc);
+ if (desc.pool == WINED3D_POOL_DEFAULT)
+ {
+ struct d3d8_surface *surface;
+
+ if (desc.resource_type == WINED3D_RTYPE_TEXTURE)
+ {
+ IUnknown *parent = wined3d_resource_get_parent(resource);
+ IDirect3DBaseTexture8 *texture;
+
+ if (SUCCEEDED(IUnknown_QueryInterface(parent, &IID_IDirect3DBaseTexture8, (void **)&texture)))
+ {
+ IDirect3DBaseTexture8_Release(texture);
+ WARN("Texture %p (resource %p) in pool D3DPOOL_DEFAULT blocks the Reset call.\n", texture, resource);
+ return D3DERR_DEVICELOST;
+ }
+
+ return D3D_OK;
+ }
+
+ if (desc.resource_type != WINED3D_RTYPE_SURFACE)
+ {
+ WARN("Resource %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", resource);
+ return D3DERR_DEVICELOST;
+ }
+
+ surface = wined3d_resource_get_parent(resource);
+ if (surface->refcount)
+ {
+ WARN("Surface %p (resource %p) in pool D3DPOOL_DEFAULT blocks the Reset call.\n", surface, resource);
+ return D3DERR_DEVICELOST;
+ }
+
+ WARN("Surface %p (resource %p) is an implicit resource with ref 0.\n", surface, resource);
+ }
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_Reset(IDirect3DDevice8 *iface,
+ D3DPRESENT_PARAMETERS *present_parameters)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct wined3d_swapchain_desc swapchain_desc;
+ HRESULT hr;
+
+ TRACE("iface %p, present_parameters %p.\n", iface, present_parameters);
+
+ wined3d_mutex_lock();
+
+ if (device->vertex_buffer)
+ {
+ wined3d_buffer_decref(device->vertex_buffer);
+ device->vertex_buffer = NULL;
+ device->vertex_buffer_size = 0;
+ }
+ if (device->index_buffer)
+ {
+ wined3d_buffer_decref(device->index_buffer);
+ device->index_buffer = NULL;
+ device->index_buffer_size = 0;
+ }
+
+ wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, present_parameters);
+ if (SUCCEEDED(hr = wined3d_device_reset(device->wined3d_device, &swapchain_desc,
+ NULL, reset_enum_callback, TRUE)))
+ {
+ wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0);
+ device->lost = FALSE;
+ }
+ else
+ {
+ device->lost = TRUE;
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_Present(IDirect3DDevice8 *iface, const RECT *src_rect,
+ const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p.\n",
+ iface, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect), dst_window_override, dirty_region);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_present(device->wined3d_device, src_rect, dst_rect,
+ dst_window_override, dirty_region, 0);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_GetBackBuffer(IDirect3DDevice8 *iface,
+ UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface8 **backbuffer)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct wined3d_surface *wined3d_surface = NULL;
+ struct d3d8_surface *surface_impl;
+ HRESULT hr;
+
+ TRACE("iface %p, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n",
+ iface, backbuffer_idx, backbuffer_type, backbuffer);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_back_buffer(device->wined3d_device, 0, backbuffer_idx,
+ (enum wined3d_backbuffer_type)backbuffer_type, &wined3d_surface);
+ if (SUCCEEDED(hr) && wined3d_surface && backbuffer)
+ {
+ surface_impl = wined3d_surface_get_parent(wined3d_surface);
+ *backbuffer = &surface_impl->IDirect3DSurface8_iface;
+ IDirect3DSurface8_AddRef(*backbuffer);
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_GetRasterStatus(IDirect3DDevice8 *iface, D3DRASTER_STATUS *raster_status)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, raster_status %p.\n", iface, raster_status);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_raster_status(device->wined3d_device, 0, (struct wined3d_raster_status *)raster_status);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static void WINAPI d3d8_device_SetGammaRamp(IDirect3DDevice8 *iface, DWORD flags, const D3DGAMMARAMP *ramp)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+
+ TRACE("iface %p, flags %#x, ramp %p.\n", iface, flags, ramp);
+
+ /* Note: D3DGAMMARAMP is compatible with struct wined3d_gamma_ramp. */
+ wined3d_mutex_lock();
+ wined3d_device_set_gamma_ramp(device->wined3d_device, 0, flags, (const struct wined3d_gamma_ramp *)ramp);
+ wined3d_mutex_unlock();
+}
+
+static void WINAPI d3d8_device_GetGammaRamp(IDirect3DDevice8 *iface, D3DGAMMARAMP *ramp)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+
+ TRACE("iface %p, ramp %p.\n", iface, ramp);
+
+ /* Note: D3DGAMMARAMP is compatible with struct wined3d_gamma_ramp. */
+ wined3d_mutex_lock();
+ wined3d_device_get_gamma_ramp(device->wined3d_device, 0, (struct wined3d_gamma_ramp *)ramp);
+ wined3d_mutex_unlock();
+}
+
+static HRESULT WINAPI d3d8_device_CreateTexture(IDirect3DDevice8 *iface,
+ UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format,
+ D3DPOOL pool, IDirect3DTexture8 **texture)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_texture *object;
+ HRESULT hr;
+
+ TRACE("iface %p, width %u, height %u, levels %u, usage %#x, format %#x, pool %#x, texture %p.\n",
+ iface, width, height, levels, usage, format, pool, texture);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return D3DERR_OUTOFVIDEOMEMORY;
+
+ hr = texture_init(object, device, width, height, levels, usage, format, pool);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize texture, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created texture %p.\n", object);
+ *texture = (IDirect3DTexture8 *)&object->IDirect3DBaseTexture8_iface;
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_CreateVolumeTexture(IDirect3DDevice8 *iface,
+ UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format,
+ D3DPOOL pool, IDirect3DVolumeTexture8 **texture)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_texture *object;
+ HRESULT hr;
+
+ TRACE("iface %p, width %u, height %u, depth %u, levels %u, usage %#x, format %#x, pool %#x, texture %p.\n",
+ iface, width, height, depth, levels, usage, format, pool, texture);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return D3DERR_OUTOFVIDEOMEMORY;
+
+ hr = volumetexture_init(object, device, width, height, depth, levels, usage, format, pool);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize volume texture, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created volume texture %p.\n", object);
+ *texture = (IDirect3DVolumeTexture8 *)&object->IDirect3DBaseTexture8_iface;
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_CreateCubeTexture(IDirect3DDevice8 *iface, UINT edge_length,
+ UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool, IDirect3DCubeTexture8 **texture)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_texture *object;
+ HRESULT hr;
+
+ TRACE("iface %p, edge_length %u, levels %u, usage %#x, format %#x, pool %#x, texture %p.\n",
+ iface, edge_length, levels, usage, format, pool, texture);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return D3DERR_OUTOFVIDEOMEMORY;
+
+ hr = cubetexture_init(object, device, edge_length, levels, usage, format, pool);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize cube texture, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created cube texture %p.\n", object);
+ *texture = (IDirect3DCubeTexture8 *)&object->IDirect3DBaseTexture8_iface;
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_CreateVertexBuffer(IDirect3DDevice8 *iface, UINT size,
+ DWORD usage, DWORD fvf, D3DPOOL pool, IDirect3DVertexBuffer8 **buffer)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_vertexbuffer *object;
+ HRESULT hr;
+
+ TRACE("iface %p, size %u, usage %#x, fvf %#x, pool %#x, buffer %p.\n",
+ iface, size, usage, fvf, pool, buffer);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return D3DERR_OUTOFVIDEOMEMORY;
+
+ hr = vertexbuffer_init(object, device, size, usage, fvf, pool);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize vertex buffer, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created vertex buffer %p.\n", object);
+ *buffer = &object->IDirect3DVertexBuffer8_iface;
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_CreateIndexBuffer(IDirect3DDevice8 *iface, UINT size,
+ DWORD usage, D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer8 **buffer)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_indexbuffer *object;
+ HRESULT hr;
+
+ TRACE("iface %p, size %u, usage %#x, format %#x, pool %#x, buffer %p.\n",
+ iface, size, usage, format, pool, buffer);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return D3DERR_OUTOFVIDEOMEMORY;
+
+ hr = indexbuffer_init(object, device, size, usage, format, pool);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize index buffer, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created index buffer %p.\n", object);
+ *buffer = &object->IDirect3DIndexBuffer8_iface;
+
+ return D3D_OK;
+}
+
+static HRESULT d3d8_device_create_surface(struct d3d8_device *device, UINT width, UINT height,
+ D3DFORMAT format, DWORD flags, IDirect3DSurface8 **surface, UINT usage, D3DPOOL pool,
+ D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality)
+{
+ struct d3d8_surface *object;
+ HRESULT hr;
+
+ TRACE("device %p, width %u, height %u, format %#x, flags %#x, surface %p,\n"
+ "\tusage %#x, pool %#x, multisample_type %#x, multisample_quality %u.\n",
+ device, width, height, format, flags, surface,
+ usage, pool, multisample_type, multisample_quality);
+
+ if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+ {
+ FIXME("Failed to allocate surface memory.\n");
+ return D3DERR_OUTOFVIDEOMEMORY;
+ }
+
+ if (FAILED(hr = surface_init(object, device, width, height, format,
+ flags, usage, pool, multisample_type, multisample_quality)))
+ {
+ WARN("Failed to initialize surface, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created surface %p.\n", object);
+ *surface = &object->IDirect3DSurface8_iface;
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_CreateRenderTarget(IDirect3DDevice8 *iface, UINT width,
+ UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, BOOL lockable,
+ IDirect3DSurface8 **surface)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ DWORD flags = 0;
+
+ TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, lockable %#x, surface %p.\n",
+ iface, width, height, format, multisample_type, lockable, surface);
+
+ if (lockable)
+ flags |= WINED3D_SURFACE_MAPPABLE;
+
+ return d3d8_device_create_surface(device, width, height, format, flags, surface,
+ D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, multisample_type, 0);
+}
+
+static HRESULT WINAPI d3d8_device_CreateDepthStencilSurface(IDirect3DDevice8 *iface,
+ UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type,
+ IDirect3DSurface8 **surface)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+
+ TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, surface %p.\n",
+ iface, width, height, format, multisample_type, surface);
+
+ /* TODO: Verify that Discard is false */
+ return d3d8_device_create_surface(device, width, height, format, WINED3D_SURFACE_MAPPABLE,
+ surface, D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, multisample_type, 0);
+}
+
+/* IDirect3DDevice8Impl::CreateImageSurface returns surface with pool type SYSTEMMEM */
+static HRESULT WINAPI d3d8_device_CreateImageSurface(IDirect3DDevice8 *iface, UINT width,
+ UINT height, D3DFORMAT format, IDirect3DSurface8 **surface)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+
+ TRACE("iface %p, width %u, height %u, format %#x, surface %p.\n",
+ iface, width, height, format, surface);
+
+ return d3d8_device_create_surface(device, width, height, format, WINED3D_SURFACE_MAPPABLE,
+ surface, 0, D3DPOOL_SYSTEMMEM, D3DMULTISAMPLE_NONE, 0);
+}
+
+static HRESULT WINAPI d3d8_device_CopyRects(IDirect3DDevice8 *iface,
+ IDirect3DSurface8 *src_surface, const RECT *src_rects, UINT rect_count,
+ IDirect3DSurface8 *dst_surface, const POINT *dst_points)
+{
+ struct d3d8_surface *src = unsafe_impl_from_IDirect3DSurface8(src_surface);
+ struct d3d8_surface *dst = unsafe_impl_from_IDirect3DSurface8(dst_surface);
+ enum wined3d_format_id src_format, dst_format;
+ struct wined3d_resource_desc wined3d_desc;
+ struct wined3d_resource *wined3d_resource;
+ UINT src_w, src_h;
+ HRESULT hr;
+
+ TRACE("iface %p, src_surface %p, src_rects %p, rect_count %u, dst_surface %p, dst_points %p.\n",
+ iface, src_surface, src_rects, rect_count, dst_surface, dst_points);
+
+ /* Check that the source texture is in WINED3D_POOL_SYSTEM_MEM and the
+ * destination texture is in WINED3D_POOL_DEFAULT. */
+
+ wined3d_mutex_lock();
+ wined3d_resource = wined3d_surface_get_resource(src->wined3d_surface);
+ wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
+ if (wined3d_desc.usage & WINED3DUSAGE_DEPTHSTENCIL)
+ {
+ WARN("Source %p is a depth stencil surface, returning D3DERR_INVALIDCALL.\n", src_surface);
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
+ src_format = wined3d_desc.format;
+ src_w = wined3d_desc.width;
+ src_h = wined3d_desc.height;
+
+ wined3d_resource = wined3d_surface_get_resource(dst->wined3d_surface);
+ wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
+ if (wined3d_desc.usage & WINED3DUSAGE_DEPTHSTENCIL)
+ {
+ WARN("Destination %p is a depth stencil surface, returning D3DERR_INVALIDCALL.\n", dst_surface);
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
+ dst_format = wined3d_desc.format;
+
+ /* Check that the source and destination formats match */
+ if (src_format != dst_format && WINED3DFMT_UNKNOWN != dst_format)
+ {
+ WARN("Source %p format must match the destination %p format, returning D3DERR_INVALIDCALL.\n",
+ src_surface, dst_surface);
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
+ else if (WINED3DFMT_UNKNOWN == dst_format)
+ {
+ TRACE("Converting destination surface from WINED3DFMT_UNKNOWN to the source format.\n");
+ if (FAILED(hr = wined3d_surface_update_desc(dst->wined3d_surface, wined3d_desc.width, wined3d_desc.height,
+ src_format, wined3d_desc.multisample_type, wined3d_desc.multisample_quality)))
+ {
+ WARN("Failed to update surface desc, hr %#x.\n", hr);
+ wined3d_mutex_unlock();
+ return hr;
+ }
+ }
+
+ /* Quick if complete copy ... */
+ if (!rect_count && !src_rects && !dst_points)
+ {
+ RECT rect = {0, 0, src_w, src_h};
+ wined3d_surface_blt(dst->wined3d_surface, &rect,
+ src->wined3d_surface, &rect, 0, NULL, WINED3D_TEXF_POINT);
+ }
+ else
+ {
+ unsigned int i;
+ /* Copy rect by rect */
+ if (src_rects && dst_points)
+ {
+ for (i = 0; i < rect_count; ++i)
+ {
+ UINT w = src_rects[i].right - src_rects[i].left;
+ UINT h = src_rects[i].bottom - src_rects[i].top;
+ RECT dst_rect = {dst_points[i].x, dst_points[i].y,
+ dst_points[i].x + w, dst_points[i].y + h};
+
+ wined3d_surface_blt(dst->wined3d_surface, &dst_rect,
+ src->wined3d_surface, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT);
+ }
+ }
+ else
+ {
+ for (i = 0; i < rect_count; ++i)
+ {
+ UINT w = src_rects[i].right - src_rects[i].left;
+ UINT h = src_rects[i].bottom - src_rects[i].top;
+ RECT dst_rect = {0, 0, w, h};
+
+ wined3d_surface_blt(dst->wined3d_surface, &dst_rect,
+ src->wined3d_surface, &src_rects[i], 0, NULL, WINED3D_TEXF_POINT);
+ }
+ }
+ }
+ wined3d_mutex_unlock();
+
+ return WINED3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_UpdateTexture(IDirect3DDevice8 *iface,
+ IDirect3DBaseTexture8 *src_texture, IDirect3DBaseTexture8 *dst_texture)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_texture *src_impl, *dst_impl;
+ HRESULT hr;
+
+ TRACE("iface %p, src_texture %p, dst_texture %p.\n", iface, src_texture, dst_texture);
+
+ src_impl = unsafe_impl_from_IDirect3DBaseTexture8(src_texture);
+ dst_impl = unsafe_impl_from_IDirect3DBaseTexture8(dst_texture);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_update_texture(device->wined3d_device,
+ src_impl->wined3d_texture, dst_impl->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_GetFrontBuffer(IDirect3DDevice8 *iface, IDirect3DSurface8 *dst_surface)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_surface *dst_impl = unsafe_impl_from_IDirect3DSurface8(dst_surface);
+ HRESULT hr;
+
+ TRACE("iface %p, dst_surface %p.\n", iface, dst_surface);
+
+ if (!dst_surface)
+ {
+ WARN("Invalid destination surface passed.\n");
+ return D3DERR_INVALIDCALL;
+ }
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_front_buffer_data(device->wined3d_device, 0, dst_impl->wined3d_surface);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_SetRenderTarget(IDirect3DDevice8 *iface,
+ IDirect3DSurface8 *render_target, IDirect3DSurface8 *depth_stencil)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_surface *rt_impl = unsafe_impl_from_IDirect3DSurface8(render_target);
+ struct d3d8_surface *ds_impl = unsafe_impl_from_IDirect3DSurface8(depth_stencil);
+ struct wined3d_surface *original_ds = NULL;
+ HRESULT hr = D3D_OK;
+
+ TRACE("iface %p, render_target %p, depth_stencil %p.\n", iface, render_target, depth_stencil);
+
+ wined3d_mutex_lock();
+
+ if (ds_impl)
+ {
+ struct wined3d_resource_desc ds_desc, rt_desc;
+ struct wined3d_resource *wined3d_resource;
+ struct wined3d_surface *original_rt = NULL;
+
+ /* If no render target is passed in check the size against the current RT */
+ if (!render_target)
+ {
+ if (!(original_rt = wined3d_device_get_render_target(device->wined3d_device, 0)))
+ {
+ wined3d_mutex_unlock();
+ return D3DERR_NOTFOUND;
+ }
+ wined3d_resource = wined3d_surface_get_resource(original_rt);
+ }
+ else
+ wined3d_resource = wined3d_surface_get_resource(rt_impl->wined3d_surface);
+ wined3d_resource_get_desc(wined3d_resource, &rt_desc);
+
+ wined3d_resource = wined3d_surface_get_resource(ds_impl->wined3d_surface);
+ wined3d_resource_get_desc(wined3d_resource, &ds_desc);
+
+ if (ds_desc.width < rt_desc.width || ds_desc.height < rt_desc.height)
+ {
+ WARN("Depth stencil is smaller than the render target, returning D3DERR_INVALIDCALL\n");
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
+ }
+
+ original_ds = wined3d_device_get_depth_stencil(device->wined3d_device);
+ wined3d_device_set_depth_stencil(device->wined3d_device, ds_impl ? ds_impl->wined3d_surface : NULL);
+ if (render_target)
+ {
+ hr = wined3d_device_set_render_target(device->wined3d_device, 0, rt_impl->wined3d_surface, TRUE);
+ if (FAILED(hr))
+ wined3d_device_set_depth_stencil(device->wined3d_device, original_ds);
+ }
+
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_GetRenderTarget(IDirect3DDevice8 *iface, IDirect3DSurface8 **render_target)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct wined3d_surface *wined3d_surface;
+ struct d3d8_surface *surface_impl;
+ HRESULT hr;
+
+ TRACE("iface %p, render_target %p.\n", iface, render_target);
+
+ if (!render_target)
+ return D3DERR_INVALIDCALL;
+
+ wined3d_mutex_lock();
+ if ((wined3d_surface = wined3d_device_get_render_target(device->wined3d_device, 0)))
+ {
+ surface_impl = wined3d_surface_get_parent(wined3d_surface);
+ *render_target = &surface_impl->IDirect3DSurface8_iface;
+ IDirect3DSurface8_AddRef(*render_target);
+ hr = D3D_OK;
+ }
+ else
+ {
+ ERR("Failed to get wined3d render target.\n");
+ *render_target = NULL;
+ hr = D3DERR_NOTFOUND;
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_GetDepthStencilSurface(IDirect3DDevice8 *iface, IDirect3DSurface8 **depth_stencil)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct wined3d_surface *wined3d_surface;
+ struct d3d8_surface *surface_impl;
+ HRESULT hr = D3D_OK;
+
+ TRACE("iface %p, depth_stencil %p.\n", iface, depth_stencil);
+
+ if (!depth_stencil)
+ return D3DERR_INVALIDCALL;
+
+ wined3d_mutex_lock();
+ if ((wined3d_surface = wined3d_device_get_depth_stencil(device->wined3d_device)))
+ {
+ surface_impl = wined3d_surface_get_parent(wined3d_surface);
+ *depth_stencil = &surface_impl->IDirect3DSurface8_iface;
+ IDirect3DSurface8_AddRef(*depth_stencil);
+ }
+ else
+ {
+ hr = WINED3DERR_NOTFOUND;
+ *depth_stencil = NULL;
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_BeginScene(IDirect3DDevice8 *iface)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_begin_scene(device->wined3d_device);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI DECLSPEC_HOTPATCH d3d8_device_EndScene(IDirect3DDevice8 *iface)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_end_scene(device->wined3d_device);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_Clear(IDirect3DDevice8 *iface, DWORD rect_count,
+ const D3DRECT *rects, DWORD flags, D3DCOLOR color, float z, DWORD stencil)
+{
+ const struct wined3d_color c =
+ {
+ ((color >> 16) & 0xff) / 255.0f,
+ ((color >> 8) & 0xff) / 255.0f,
+ (color & 0xff) / 255.0f,
+ ((color >> 24) & 0xff) / 255.0f,
+ };
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, rect_count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %u.\n",
+ iface, rect_count, rects, flags, color, z, stencil);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_clear(device->wined3d_device, rect_count, (const RECT *)rects, flags, &c, z, stencil);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_SetTransform(IDirect3DDevice8 *iface,
+ D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+
+ TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix);
+
+ /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
+ wined3d_mutex_lock();
+ wined3d_device_set_transform(device->wined3d_device, state, (const struct wined3d_matrix *)matrix);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_GetTransform(IDirect3DDevice8 *iface,
+ D3DTRANSFORMSTATETYPE state, D3DMATRIX *matrix)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+
+ TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix);
+
+ /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
+ wined3d_mutex_lock();
+ wined3d_device_get_transform(device->wined3d_device, state, (struct wined3d_matrix *)matrix);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_MultiplyTransform(IDirect3DDevice8 *iface,
+ D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+
+ TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix);
+
+ /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
+ wined3d_mutex_lock();
+ wined3d_device_multiply_transform(device->wined3d_device, state, (const struct wined3d_matrix *)matrix);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_SetViewport(IDirect3DDevice8 *iface, const D3DVIEWPORT8 *viewport)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+
+ TRACE("iface %p, viewport %p.\n", iface, viewport);
+
+ /* Note: D3DVIEWPORT8 is compatible with struct wined3d_viewport. */
+ wined3d_mutex_lock();
+ wined3d_device_set_viewport(device->wined3d_device, (const struct wined3d_viewport *)viewport);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_GetViewport(IDirect3DDevice8 *iface, D3DVIEWPORT8 *viewport)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+
+ TRACE("iface %p, viewport %p.\n", iface, viewport);
+
+ /* Note: D3DVIEWPORT8 is compatible with struct wined3d_viewport. */
+ wined3d_mutex_lock();
+ wined3d_device_get_viewport(device->wined3d_device, (struct wined3d_viewport *)viewport);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_SetMaterial(IDirect3DDevice8 *iface, const D3DMATERIAL8 *material)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+
+ TRACE("iface %p, material %p.\n", iface, material);
+
+ /* Note: D3DMATERIAL8 is compatible with struct wined3d_material. */
+ wined3d_mutex_lock();
+ wined3d_device_set_material(device->wined3d_device, (const struct wined3d_material *)material);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_GetMaterial(IDirect3DDevice8 *iface, D3DMATERIAL8 *material)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+
+ TRACE("iface %p, material %p.\n", iface, material);
+
+ /* Note: D3DMATERIAL8 is compatible with struct wined3d_material. */
+ wined3d_mutex_lock();
+ wined3d_device_get_material(device->wined3d_device, (struct wined3d_material *)material);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_SetLight(IDirect3DDevice8 *iface, DWORD index, const D3DLIGHT8 *light)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, index %u, light %p.\n", iface, index, light);
+
+ /* Note: D3DLIGHT8 is compatible with struct wined3d_light. */
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_light(device->wined3d_device, index, (const struct wined3d_light *)light);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_GetLight(IDirect3DDevice8 *iface, DWORD index, D3DLIGHT8 *light)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, index %u, light %p.\n", iface, index, light);
+
+ /* Note: D3DLIGHT8 is compatible with struct wined3d_light. */
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_light(device->wined3d_device, index, (struct wined3d_light *)light);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_LightEnable(IDirect3DDevice8 *iface, DWORD index, BOOL enable)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, index %u, enable %#x.\n", iface, index, enable);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_light_enable(device->wined3d_device, index, enable);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_GetLightEnable(IDirect3DDevice8 *iface, DWORD index, BOOL *enable)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, index %u, enable %p.\n", iface, index, enable);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_light_enable(device->wined3d_device, index, enable);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_SetClipPlane(IDirect3DDevice8 *iface, DWORD index, const float *plane)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, index %u, plane %p.\n", iface, index, plane);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_clip_plane(device->wined3d_device, index, (const struct wined3d_vec4 *)plane);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_GetClipPlane(IDirect3DDevice8 *iface, DWORD index, float *plane)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, index %u, plane %p.\n", iface, index, plane);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_clip_plane(device->wined3d_device, index, (struct wined3d_vec4 *)plane);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_SetRenderState(IDirect3DDevice8 *iface,
+ D3DRENDERSTATETYPE state, DWORD value)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+
+ TRACE("iface %p, state %#x, value %#x.\n", iface, state, value);
+
+ wined3d_mutex_lock();
+ switch (state)
+ {
+ case D3DRS_ZBIAS:
+ wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_DEPTHBIAS, value);
+ break;
+
+ default:
+ wined3d_device_set_render_state(device->wined3d_device, state, value);
+ }
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_GetRenderState(IDirect3DDevice8 *iface,
+ D3DRENDERSTATETYPE state, DWORD *value)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+
+ TRACE("iface %p, state %#x, value %p.\n", iface, state, value);
+
+ wined3d_mutex_lock();
+ switch (state)
+ {
+ case D3DRS_ZBIAS:
+ *value = wined3d_device_get_render_state(device->wined3d_device, WINED3D_RS_DEPTHBIAS);
+ break;
+
+ default:
+ *value = wined3d_device_get_render_state(device->wined3d_device, state);
+ }
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_BeginStateBlock(IDirect3DDevice8 *iface)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_begin_stateblock(device->wined3d_device);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_EndStateBlock(IDirect3DDevice8 *iface, DWORD *token)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct wined3d_stateblock *stateblock;
+ HRESULT hr;
+
+ TRACE("iface %p, token %p.\n", iface, token);
+
+ /* Tell wineD3D to endstateblock before anything else (in case we run out
+ * of memory later and cause locking problems)
+ */
+ wined3d_mutex_lock();
+ hr = wined3d_device_end_stateblock(device->wined3d_device, &stateblock);
+ if (FAILED(hr))
+ {
+ WARN("IWineD3DDevice_EndStateBlock returned an error\n");
+ wined3d_mutex_unlock();
+ return hr;
+ }
+
+ *token = d3d8_allocate_handle(&device->handle_table, stateblock, D3D8_HANDLE_SB);
+ wined3d_mutex_unlock();
+
+ if (*token == D3D8_INVALID_HANDLE)
+ {
+ ERR("Failed to create a handle\n");
+ wined3d_mutex_lock();
+ wined3d_stateblock_decref(stateblock);
+ wined3d_mutex_unlock();
+ return E_FAIL;
+ }
+ ++*token;
+
+ TRACE("Returning %#x (%p).\n", *token, stateblock);
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_ApplyStateBlock(IDirect3DDevice8 *iface, DWORD token)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct wined3d_stateblock *stateblock;
+
+ TRACE("iface %p, token %#x.\n", iface, token);
+
+ if (!token)
+ return D3D_OK;
+
+ wined3d_mutex_lock();
+ stateblock = d3d8_get_object(&device->handle_table, token - 1, D3D8_HANDLE_SB);
+ if (!stateblock)
+ {
+ WARN("Invalid handle (%#x) passed.\n", token);
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
+ wined3d_stateblock_apply(stateblock);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_CaptureStateBlock(IDirect3DDevice8 *iface, DWORD token)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct wined3d_stateblock *stateblock;
+
+ TRACE("iface %p, token %#x.\n", iface, token);
+
+ wined3d_mutex_lock();
+ stateblock = d3d8_get_object(&device->handle_table, token - 1, D3D8_HANDLE_SB);
+ if (!stateblock)
+ {
+ WARN("Invalid handle (%#x) passed.\n", token);
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
+ wined3d_stateblock_capture(stateblock);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_DeleteStateBlock(IDirect3DDevice8 *iface, DWORD token)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct wined3d_stateblock *stateblock;
+
+ TRACE("iface %p, token %#x.\n", iface, token);
+
+ wined3d_mutex_lock();
+ stateblock = d3d8_free_handle(&device->handle_table, token - 1, D3D8_HANDLE_SB);
+
+ if (!stateblock)
+ {
+ WARN("Invalid handle (%#x) passed.\n", token);
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
+
+ if (wined3d_stateblock_decref(stateblock))
+ {
+ ERR("Stateblock %p has references left, this shouldn't happen.\n", stateblock);
+ }
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_CreateStateBlock(IDirect3DDevice8 *iface,
+ D3DSTATEBLOCKTYPE type, DWORD *handle)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct wined3d_stateblock *stateblock;
+ HRESULT hr;
+
+ TRACE("iface %p, type %#x, handle %p.\n", iface, type, handle);
+
+ if (type != D3DSBT_ALL
+ && type != D3DSBT_PIXELSTATE
+ && type != D3DSBT_VERTEXSTATE)
+ {
+ WARN("Unexpected stateblock type, returning D3DERR_INVALIDCALL\n");
+ return D3DERR_INVALIDCALL;
+ }
+
+ wined3d_mutex_lock();
+ hr = wined3d_stateblock_create(device->wined3d_device, (enum wined3d_stateblock_type)type, &stateblock);
+ if (FAILED(hr))
+ {
+ wined3d_mutex_unlock();
+ ERR("IWineD3DDevice_CreateStateBlock failed, hr %#x\n", hr);
+ return hr;
+ }
+
+ *handle = d3d8_allocate_handle(&device->handle_table, stateblock, D3D8_HANDLE_SB);
+ wined3d_mutex_unlock();
+
+ if (*handle == D3D8_INVALID_HANDLE)
+ {
+ ERR("Failed to allocate a handle.\n");
+ wined3d_mutex_lock();
+ wined3d_stateblock_decref(stateblock);
+ wined3d_mutex_unlock();
+ return E_FAIL;
+ }
+ ++*handle;
+
+ TRACE("Returning %#x (%p).\n", *handle, stateblock);
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_SetClipStatus(IDirect3DDevice8 *iface, const D3DCLIPSTATUS8 *clip_status)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, clip_status %p.\n", iface, clip_status);
+ /* FIXME: Verify that D3DCLIPSTATUS8 ~= struct wined3d_clip_status. */
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_clip_status(device->wined3d_device, (const struct wined3d_clip_status *)clip_status);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_GetClipStatus(IDirect3DDevice8 *iface, D3DCLIPSTATUS8 *clip_status)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, clip_status %p.\n", iface, clip_status);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_clip_status(device->wined3d_device, (struct wined3d_clip_status *)clip_status);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_GetTexture(IDirect3DDevice8 *iface, DWORD stage, IDirect3DBaseTexture8 **texture)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct wined3d_texture *wined3d_texture;
+ struct d3d8_texture *texture_impl;
+
+ TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture);
+
+ if (!texture)
+ return D3DERR_INVALIDCALL;
+
+ wined3d_mutex_lock();
+ if ((wined3d_texture = wined3d_device_get_texture(device->wined3d_device, stage)))
+ {
+ texture_impl = wined3d_texture_get_parent(wined3d_texture);
+ *texture = &texture_impl->IDirect3DBaseTexture8_iface;
+ IDirect3DBaseTexture8_AddRef(*texture);
+ }
+ else
+ {
+ *texture = NULL;
+ }
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_SetTexture(IDirect3DDevice8 *iface, DWORD stage, IDirect3DBaseTexture8 *texture)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_texture *texture_impl;
+ HRESULT hr;
+
+ TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture);
+
+ texture_impl = unsafe_impl_from_IDirect3DBaseTexture8(texture);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_texture(device->wined3d_device, stage,
+ texture_impl ? texture_impl->wined3d_texture : NULL);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static const struct tss_lookup
+{
+ BOOL sampler_state;
+ enum wined3d_texture_stage_state state;
+}
+tss_lookup[] =
+{
+ {FALSE, WINED3D_TSS_INVALID}, /* 0, unused */
+ {FALSE, WINED3D_TSS_COLOR_OP}, /* 1, D3DTSS_COLOROP */
+ {FALSE, WINED3D_TSS_COLOR_ARG1}, /* 2, D3DTSS_COLORARG1 */
+ {FALSE, WINED3D_TSS_COLOR_ARG2}, /* 3, D3DTSS_COLORARG2 */
+ {FALSE, WINED3D_TSS_ALPHA_OP}, /* 4, D3DTSS_ALPHAOP */
+ {FALSE, WINED3D_TSS_ALPHA_ARG1}, /* 5, D3DTSS_ALPHAARG1 */
+ {FALSE, WINED3D_TSS_ALPHA_ARG2}, /* 6, D3DTSS_ALPHAARG2 */
+ {FALSE, WINED3D_TSS_BUMPENV_MAT00}, /* 7, D3DTSS_BUMPENVMAT00 */
+ {FALSE, WINED3D_TSS_BUMPENV_MAT01}, /* 8, D3DTSS_BUMPENVMAT01 */
+ {FALSE, WINED3D_TSS_BUMPENV_MAT10}, /* 9, D3DTSS_BUMPENVMAT10 */
+ {FALSE, WINED3D_TSS_BUMPENV_MAT11}, /* 10, D3DTSS_BUMPENVMAT11 */
+ {FALSE, WINED3D_TSS_TEXCOORD_INDEX}, /* 11, D3DTSS_TEXCOORDINDEX */
+ {FALSE, WINED3D_TSS_INVALID}, /* 12, unused */
+ {TRUE, WINED3D_SAMP_ADDRESS_U}, /* 13, D3DTSS_ADDRESSU */
+ {TRUE, WINED3D_SAMP_ADDRESS_V}, /* 14, D3DTSS_ADDRESSV */
+ {TRUE, WINED3D_SAMP_BORDER_COLOR}, /* 15, D3DTSS_BORDERCOLOR */
+ {TRUE, WINED3D_SAMP_MAG_FILTER}, /* 16, D3DTSS_MAGFILTER */
+ {TRUE, WINED3D_SAMP_MIN_FILTER}, /* 17, D3DTSS_MINFILTER */
+ {TRUE, WINED3D_SAMP_MIP_FILTER}, /* 18, D3DTSS_MIPFILTER */
+ {TRUE, WINED3D_SAMP_MIPMAP_LOD_BIAS}, /* 19, D3DTSS_MIPMAPLODBIAS */
+ {TRUE, WINED3D_SAMP_MAX_MIP_LEVEL}, /* 20, D3DTSS_MAXMIPLEVEL */
+ {TRUE, WINED3D_SAMP_MAX_ANISOTROPY}, /* 21, D3DTSS_MAXANISOTROPY */
+ {FALSE, WINED3D_TSS_BUMPENV_LSCALE}, /* 22, D3DTSS_BUMPENVLSCALE */
+ {FALSE, WINED3D_TSS_BUMPENV_LOFFSET}, /* 23, D3DTSS_BUMPENVLOFFSET */
+ {FALSE, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
+ {TRUE, WINED3D_SAMP_ADDRESS_W}, /* 25, D3DTSS_ADDRESSW */
+ {FALSE, WINED3D_TSS_COLOR_ARG0}, /* 26, D3DTSS_COLORARG0 */
+ {FALSE, WINED3D_TSS_ALPHA_ARG0}, /* 27, D3DTSS_ALPHAARG0 */
+ {FALSE, WINED3D_TSS_RESULT_ARG}, /* 28, D3DTSS_RESULTARG */
+};
+
+static HRESULT WINAPI d3d8_device_GetTextureStageState(IDirect3DDevice8 *iface,
+ DWORD stage, D3DTEXTURESTAGESTATETYPE Type, DWORD *value)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ const struct tss_lookup *l;
+
+ TRACE("iface %p, stage %u, state %#x, value %p.\n", iface, stage, Type, value);
+
+ if (Type >= sizeof(tss_lookup) / sizeof(*tss_lookup))
+ {
+ WARN("Invalid Type %#x passed.\n", Type);
+ return D3D_OK;
+ }
+
+ l = &tss_lookup[Type];
+
+ wined3d_mutex_lock();
+ if (l->sampler_state)
+ *value = wined3d_device_get_sampler_state(device->wined3d_device, stage, l->state);
+ else
+ *value = wined3d_device_get_texture_stage_state(device->wined3d_device, stage, l->state);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_SetTextureStageState(IDirect3DDevice8 *iface,
+ DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ const struct tss_lookup *l;
+
+ TRACE("iface %p, stage %u, state %#x, value %#x.\n", iface, stage, type, value);
+
+ if (type >= sizeof(tss_lookup) / sizeof(*tss_lookup))
+ {
+ WARN("Invalid type %#x passed.\n", type);
+ return D3D_OK;
+ }
+
+ l = &tss_lookup[type];
+
+ wined3d_mutex_lock();
+ if (l->sampler_state)
+ wined3d_device_set_sampler_state(device->wined3d_device, stage, l->state, value);
+ else
+ wined3d_device_set_texture_stage_state(device->wined3d_device, stage, l->state, value);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_ValidateDevice(IDirect3DDevice8 *iface, DWORD *pass_count)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, pass_count %p.\n", iface, pass_count);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_validate_device(device->wined3d_device, pass_count);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_GetInfo(IDirect3DDevice8 *iface,
+ DWORD info_id, void *info, DWORD info_size)
+{
+ FIXME("iface %p, info_id %#x, info %p, info_size %u stub!\n", iface, info_id, info, info_size);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_SetPaletteEntries(IDirect3DDevice8 *iface,
+ UINT palette_idx, const PALETTEENTRY *entries)
+{
+ WARN("iface %p, palette_idx %u, entries %p unimplemented\n", iface, palette_idx, entries);
+
+ /* GPUs stopped supporting palettized textures with the Shader Model 1 generation. Wined3d
+ * does not have a d3d8/9-style palette API */
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_GetPaletteEntries(IDirect3DDevice8 *iface,
+ UINT palette_idx, PALETTEENTRY *entries)
+{
+ FIXME("iface %p, palette_idx %u, entries %p unimplemented.\n", iface, palette_idx, entries);
+
+ return D3DERR_INVALIDCALL;
+}
+
+static HRESULT WINAPI d3d8_device_SetCurrentTexturePalette(IDirect3DDevice8 *iface, UINT palette_idx)
+{
+ WARN("iface %p, palette_idx %u unimplemented.\n", iface, palette_idx);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_GetCurrentTexturePalette(IDirect3DDevice8 *iface, UINT *palette_idx)
+{
+ FIXME("iface %p, palette_idx %p unimplemented.\n", iface, palette_idx);
+
+ return D3DERR_INVALIDCALL;
+}
+
+static HRESULT WINAPI d3d8_device_DrawPrimitive(IDirect3DDevice8 *iface,
+ D3DPRIMITIVETYPE primitive_type, UINT start_vertex, UINT primitive_count)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, primitive_type %#x, start_vertex %u, primitive_count %u.\n",
+ iface, primitive_type, start_vertex, primitive_count);
+
+ wined3d_mutex_lock();
+ wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+ hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex,
+ vertex_count_from_primitive_count(primitive_type, primitive_count));
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_DrawIndexedPrimitive(IDirect3DDevice8 *iface,
+ D3DPRIMITIVETYPE primitive_type, UINT min_vertex_idx, UINT vertex_count,
+ UINT start_idx, UINT primitive_count)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, vertex_count %u, start_idx %u, primitive_count %u.\n",
+ iface, primitive_type, min_vertex_idx, vertex_count, start_idx, primitive_count);
+
+ wined3d_mutex_lock();
+ wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+ hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx,
+ vertex_count_from_primitive_count(primitive_type, primitive_count));
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static void STDMETHODCALLTYPE d3d8_null_wined3d_object_destroyed(void *parent) {}
+
+static const struct wined3d_parent_ops d3d8_null_wined3d_parent_ops =
+{
+ d3d8_null_wined3d_object_destroyed,
+};
+
+/* The caller is responsible for wined3d locking */
+static HRESULT d3d8_device_prepare_vertex_buffer(struct d3d8_device *device, UINT min_size)
+{
+ HRESULT hr;
+
+ if (device->vertex_buffer_size < min_size || !device->vertex_buffer)
+ {
+ UINT size = max(device->vertex_buffer_size * 2, min_size);
+ struct wined3d_buffer *buffer;
+
+ TRACE("Growing vertex buffer to %u bytes\n", size);
+
+ hr = wined3d_buffer_create_vb(device->wined3d_device, size, WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY,
+ WINED3D_POOL_DEFAULT, NULL, &d3d8_null_wined3d_parent_ops, &buffer);
+ if (FAILED(hr))
+ {
+ ERR("(%p) wined3d_buffer_create_vb failed with hr = %08x\n", device, hr);
+ return hr;
+ }
+
+ if (device->vertex_buffer)
+ wined3d_buffer_decref(device->vertex_buffer);
+
+ device->vertex_buffer = buffer;
+ device->vertex_buffer_size = size;
+ device->vertex_buffer_pos = 0;
+ }
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_DrawPrimitiveUP(IDirect3DDevice8 *iface,
+ D3DPRIMITIVETYPE primitive_type, UINT primitive_count, const void *data,
+ UINT stride)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+ UINT vtx_count = vertex_count_from_primitive_count(primitive_type, primitive_count);
+ UINT size = vtx_count * stride;
+ UINT vb_pos, align;
+ BYTE *buffer_data;
+
+ TRACE("iface %p, primitive_type %#x, primitive_count %u, data %p, stride %u.\n",
+ iface, primitive_type, primitive_count, data, stride);
+
+ if (!primitive_count)
+ {
+ WARN("primitive_count is 0, returning D3D_OK\n");
+ return D3D_OK;
+ }
+
+ wined3d_mutex_lock();
+ hr = d3d8_device_prepare_vertex_buffer(device, size);
+ if (FAILED(hr))
+ goto done;
+
+ vb_pos = device->vertex_buffer_pos;
+ align = vb_pos % stride;
+ if (align) align = stride - align;
+ if (vb_pos + size + align > device->vertex_buffer_size)
+ vb_pos = 0;
+ else
+ vb_pos += align;
+
+ hr = wined3d_buffer_map(device->vertex_buffer, vb_pos, size, &buffer_data,
+ vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD);
+ if (FAILED(hr))
+ goto done;
+ memcpy(buffer_data, data, size);
+ wined3d_buffer_unmap(device->vertex_buffer);
+ device->vertex_buffer_pos = vb_pos + size;
+
+ hr = wined3d_device_set_stream_source(device->wined3d_device, 0, device->vertex_buffer, 0, stride);
+ if (FAILED(hr))
+ goto done;
+
+ wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+ hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / stride, vtx_count);
+ wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0);
+
+done:
+ wined3d_mutex_unlock();
+ return hr;
+}
+
+/* The caller is responsible for wined3d locking */
+static HRESULT d3d8_device_prepare_index_buffer(struct d3d8_device *device, UINT min_size)
+{
+ HRESULT hr;
+
+ if (device->index_buffer_size < min_size || !device->index_buffer)
+ {
+ UINT size = max(device->index_buffer_size * 2, min_size);
+ struct wined3d_buffer *buffer;
+
+ TRACE("Growing index buffer to %u bytes\n", size);
+
+ hr = wined3d_buffer_create_ib(device->wined3d_device, size, WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY,
+ WINED3D_POOL_DEFAULT, NULL, &d3d8_null_wined3d_parent_ops, &buffer);
+ if (FAILED(hr))
+ {
+ ERR("(%p) wined3d_buffer_create_ib failed with hr = %08x\n", device, hr);
+ return hr;
+ }
+
+ if (device->index_buffer)
+ wined3d_buffer_decref(device->index_buffer);
+
+ device->index_buffer = buffer;
+ device->index_buffer_size = size;
+ device->index_buffer_pos = 0;
+ }
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_DrawIndexedPrimitiveUP(IDirect3DDevice8 *iface,
+ D3DPRIMITIVETYPE primitive_type, UINT min_vertex_idx, UINT vertex_count,
+ UINT primitive_count, const void *index_data, D3DFORMAT index_format,
+ const void *vertex_data, UINT vertex_stride)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+ BYTE *buffer_data;
+
+ UINT idx_count = vertex_count_from_primitive_count(primitive_type, primitive_count);
+ UINT idx_fmt_size = index_format == D3DFMT_INDEX16 ? 2 : 4;
+ UINT idx_size = idx_count * idx_fmt_size;
+ UINT ib_pos;
+
+ UINT vtx_size = vertex_count * vertex_stride;
+ UINT vb_pos, align;
+
+ TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, vertex_count %u, primitive_count %u,\n"
+ "index_data %p, index_format %#x, vertex_data %p, vertex_stride %u.\n",
+ iface, primitive_type, min_vertex_idx, vertex_count, primitive_count,
+ index_data, index_format, vertex_data, vertex_stride);
+
+ if (!primitive_count)
+ {
+ WARN("primitive_count is 0, returning D3D_OK\n");
+ return D3D_OK;
+ }
+
+ wined3d_mutex_lock();
+
+ hr = d3d8_device_prepare_vertex_buffer(device, vtx_size);
+ if (FAILED(hr))
+ goto done;
+
+ vb_pos = device->vertex_buffer_pos;
+ align = vb_pos % vertex_stride;
+ if (align) align = vertex_stride - align;
+ if (vb_pos + vtx_size + align > device->vertex_buffer_size)
+ vb_pos = 0;
+ else
+ vb_pos += align;
+
+ hr = wined3d_buffer_map(device->vertex_buffer, vb_pos, vtx_size, &buffer_data,
+ vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD);
+ if (FAILED(hr))
+ goto done;
+ memcpy(buffer_data, vertex_data, vtx_size);
+ wined3d_buffer_unmap(device->vertex_buffer);
+ device->vertex_buffer_pos = vb_pos + vtx_size;
+
+ hr = d3d8_device_prepare_index_buffer(device, idx_size);
+ if (FAILED(hr))
+ goto done;
+
+ ib_pos = device->index_buffer_pos;
+ align = ib_pos % idx_fmt_size;
+ if (align) align = idx_fmt_size - align;
+ if (ib_pos + idx_size + align > device->index_buffer_size)
+ ib_pos = 0;
+ else
+ ib_pos += align;
+
+ hr = wined3d_buffer_map(device->index_buffer, ib_pos, idx_size, &buffer_data,
+ ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD);
+ if (FAILED(hr))
+ goto done;
+ memcpy(buffer_data, index_data, idx_size);
+ wined3d_buffer_unmap(device->index_buffer);
+ device->index_buffer_pos = ib_pos + idx_size;
+
+ hr = wined3d_device_set_stream_source(device->wined3d_device, 0, device->vertex_buffer, 0, vertex_stride);
+ if (FAILED(hr))
+ goto done;
+
+ wined3d_device_set_index_buffer(device->wined3d_device, device->index_buffer,
+ wined3dformat_from_d3dformat(index_format));
+ wined3d_device_set_base_vertex_index(device->wined3d_device, vb_pos / vertex_stride);
+
+ wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+ hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / idx_fmt_size, idx_count);
+
+ wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0);
+ wined3d_device_set_index_buffer(device->wined3d_device, NULL, WINED3DFMT_UNKNOWN);
+ wined3d_device_set_base_vertex_index(device->wined3d_device, 0);
+
+done:
+ wined3d_mutex_unlock();
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_ProcessVertices(IDirect3DDevice8 *iface, UINT src_start_idx,
+ UINT dst_idx, UINT vertex_count, IDirect3DVertexBuffer8 *dst_buffer, DWORD flags)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_vertexbuffer *dst = unsafe_impl_from_IDirect3DVertexBuffer8(dst_buffer);
+ HRESULT hr;
+
+ TRACE("iface %p, src_start_idx %u, dst_idx %u, vertex_count %u, dst_buffer %p, flags %#x.\n",
+ iface, src_start_idx, dst_idx, vertex_count, dst_buffer, flags);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_process_vertices(device->wined3d_device, src_start_idx, dst_idx,
+ vertex_count, dst->wined3d_buffer, NULL, flags, dst->fvf);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_CreateVertexShader(IDirect3DDevice8 *iface,
+ const DWORD *declaration, const DWORD *byte_code, DWORD *shader, DWORD usage)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_vertex_shader *object;
+ DWORD shader_handle;
+ DWORD handle;
+ HRESULT hr;
+
+ TRACE("iface %p, declaration %p, byte_code %p, shader %p, usage %#x.\n",
+ iface, declaration, byte_code, shader, usage);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ {
+ *shader = 0;
+ return E_OUTOFMEMORY;
+ }
+
+ wined3d_mutex_lock();
+ handle = d3d8_allocate_handle(&device->handle_table, object, D3D8_HANDLE_VS);
+ wined3d_mutex_unlock();
+ if (handle == D3D8_INVALID_HANDLE)
+ {
+ ERR("Failed to allocate vertex shader handle.\n");
+ HeapFree(GetProcessHeap(), 0, object);
+ *shader = 0;
+ return E_OUTOFMEMORY;
+ }
+
+ shader_handle = handle + VS_HIGHESTFIXEDFXF + 1;
+
+ hr = d3d8_vertex_shader_init(object, device, declaration, byte_code, shader_handle, usage);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
+ wined3d_mutex_lock();
+ d3d8_free_handle(&device->handle_table, handle, D3D8_HANDLE_VS);
+ wined3d_mutex_unlock();
+ HeapFree(GetProcessHeap(), 0, object);
+ *shader = 0;
+ return hr;
+ }
+
+ TRACE("Created vertex shader %p (handle %#x).\n", object, shader_handle);
+ *shader = shader_handle;
+
+ return D3D_OK;
+}
+
+static struct d3d8_vertex_declaration *d3d8_device_get_fvf_declaration(struct d3d8_device *device, DWORD fvf)
+{
+ struct d3d8_vertex_declaration *d3d8_declaration;
+ struct FvfToDecl *convertedDecls = device->decls;
+ int p, low, high; /* deliberately signed */
+ HRESULT hr;
+
+ TRACE("Searching for declaration for fvf %08x... ", fvf);
+
+ low = 0;
+ high = device->numConvertedDecls - 1;
+ while (low <= high)
+ {
+ p = (low + high) >> 1;
+ TRACE("%d ", p);
+
+ if (convertedDecls[p].fvf == fvf)
+ {
+ TRACE("found %p\n", convertedDecls[p].declaration);
+ return convertedDecls[p].declaration;
+ }
+
+ if (convertedDecls[p].fvf < fvf)
+ low = p + 1;
+ else
+ high = p - 1;
+ }
+ TRACE("not found. Creating and inserting at position %d.\n", low);
+
+ if (!(d3d8_declaration = HeapAlloc(GetProcessHeap(), 0, sizeof(*d3d8_declaration))))
+ return NULL;
+
+ if (FAILED(hr = d3d8_vertex_declaration_init_fvf(d3d8_declaration, device, fvf)))
+ {
+ WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, d3d8_declaration);
+ return NULL;
+ }
+
+ if (device->declArraySize == device->numConvertedDecls)
+ {
+ UINT grow = device->declArraySize / 2;
+
+ convertedDecls = HeapReAlloc(GetProcessHeap(), 0, convertedDecls,
+ sizeof(*convertedDecls) * (device->numConvertedDecls + grow));
+ if (!convertedDecls)
+ {
+ d3d8_vertex_declaration_destroy(d3d8_declaration);
+ return NULL;
+ }
+ device->decls = convertedDecls;
+ device->declArraySize += grow;
+ }
+
+ memmove(convertedDecls + low + 1, convertedDecls + low,
+ sizeof(*convertedDecls) * (device->numConvertedDecls - low));
+ convertedDecls[low].declaration = d3d8_declaration;
+ convertedDecls[low].fvf = fvf;
+ ++device->numConvertedDecls;
+
+ TRACE("Returning %p. %u decls in array.\n", d3d8_declaration, device->numConvertedDecls);
+
+ return d3d8_declaration;
+}
+
+static HRESULT WINAPI d3d8_device_SetVertexShader(IDirect3DDevice8 *iface, DWORD shader)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_vertex_shader *shader_impl;
+
+ TRACE("iface %p, shader %#x.\n", iface, shader);
+
+ if (VS_HIGHESTFIXEDFXF >= shader)
+ {
+ TRACE("Setting FVF, %#x\n", shader);
+
+ wined3d_mutex_lock();
+ wined3d_device_set_vertex_declaration(device->wined3d_device,
+ d3d8_device_get_fvf_declaration(device, shader)->wined3d_vertex_declaration);
+ wined3d_device_set_vertex_shader(device->wined3d_device, NULL);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+ }
+
+ TRACE("Setting shader\n");
+
+ wined3d_mutex_lock();
+ if (!(shader_impl = d3d8_get_object(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS)))
+ {
+ WARN("Invalid handle (%#x) passed.\n", shader);
+ wined3d_mutex_unlock();
+
+ return D3DERR_INVALIDCALL;
+ }
+
+ wined3d_device_set_vertex_declaration(device->wined3d_device,
+ shader_impl->vertex_declaration->wined3d_vertex_declaration);
+ wined3d_device_set_vertex_shader(device->wined3d_device, shader_impl->wined3d_shader);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_GetVertexShader(IDirect3DDevice8 *iface, DWORD *shader)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct wined3d_vertex_declaration *wined3d_declaration;
+ struct d3d8_vertex_declaration *d3d8_declaration;
+
+ TRACE("iface %p, shader %p.\n", iface, shader);
+
+ wined3d_mutex_lock();
+ if ((wined3d_declaration = wined3d_device_get_vertex_declaration(device->wined3d_device)))
+ {
+ d3d8_declaration = wined3d_vertex_declaration_get_parent(wined3d_declaration);
+ *shader = d3d8_declaration->shader_handle;
+ }
+ else
+ {
+ *shader = 0;
+ }
+ wined3d_mutex_unlock();
+
+ TRACE("Returning %#x.\n", *shader);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_DeleteVertexShader(IDirect3DDevice8 *iface, DWORD shader)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_vertex_shader *shader_impl;
+
+ TRACE("iface %p, shader %#x.\n", iface, shader);
+
+ wined3d_mutex_lock();
+ if (!(shader_impl = d3d8_free_handle(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS)))
+ {
+ WARN("Invalid handle (%#x) passed.\n", shader);
+ wined3d_mutex_unlock();
+
+ return D3DERR_INVALIDCALL;
+ }
+
+ if (shader_impl->wined3d_shader
+ && wined3d_device_get_vertex_shader(device->wined3d_device) == shader_impl->wined3d_shader)
+ IDirect3DDevice8_SetVertexShader(iface, 0);
+
+ wined3d_mutex_unlock();
+
+ d3d8_vertex_shader_destroy(shader_impl);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_SetVertexShaderConstant(IDirect3DDevice8 *iface,
+ DWORD start_register, const void *data, DWORD count)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, start_register %u, data %p, count %u.\n",
+ iface, start_register, data, count);
+
+ if (start_register + count > D3D8_MAX_VERTEX_SHADER_CONSTANTF)
+ {
+ WARN("Trying to access %u constants, but d3d8 only supports %u\n",
+ start_register + count, D3D8_MAX_VERTEX_SHADER_CONSTANTF);
+ return D3DERR_INVALIDCALL;
+ }
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_vs_consts_f(device->wined3d_device, start_register, data, count);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_GetVertexShaderConstant(IDirect3DDevice8 *iface,
+ DWORD start_register, void *data, DWORD count)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, start_register %u, data %p, count %u.\n",
+ iface, start_register, data, count);
+
+ if (start_register + count > D3D8_MAX_VERTEX_SHADER_CONSTANTF)
+ {
+ WARN("Trying to access %u constants, but d3d8 only supports %u\n",
+ start_register + count, D3D8_MAX_VERTEX_SHADER_CONSTANTF);
+ return D3DERR_INVALIDCALL;
+ }
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_vs_consts_f(device->wined3d_device, start_register, data, count);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_GetVertexShaderDeclaration(IDirect3DDevice8 *iface,
+ DWORD shader, void *data, DWORD *data_size)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_vertex_declaration *declaration;
+ struct d3d8_vertex_shader *shader_impl;
+
+ TRACE("iface %p, shader %#x, data %p, data_size %p.\n",
+ iface, shader, data, data_size);
+
+ wined3d_mutex_lock();
+ shader_impl = d3d8_get_object(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS);
+ wined3d_mutex_unlock();
+
+ if (!shader_impl)
+ {
+ WARN("Invalid handle (%#x) passed.\n", shader);
+ return D3DERR_INVALIDCALL;
+ }
+ declaration = shader_impl->vertex_declaration;
+
+ if (!data)
+ {
+ *data_size = declaration->elements_size;
+ return D3D_OK;
+ }
+
+ /* MSDN claims that if *data_size is smaller than the required size
+ * we should write the required size and return D3DERR_MOREDATA.
+ * That's not actually true. */
+ if (*data_size < declaration->elements_size)
+ return D3DERR_INVALIDCALL;
+
+ memcpy(data, declaration->elements, declaration->elements_size);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_GetVertexShaderFunction(IDirect3DDevice8 *iface,
+ DWORD shader, void *data, DWORD *data_size)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_vertex_shader *shader_impl = NULL;
+ HRESULT hr;
+
+ TRACE("iface %p, shader %#x, data %p, data_size %p.\n",
+ iface, shader, data, data_size);
+
+ wined3d_mutex_lock();
+ if (!(shader_impl = d3d8_get_object(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_VS)))
+ {
+ WARN("Invalid handle (%#x) passed.\n", shader);
+ wined3d_mutex_unlock();
+
+ return D3DERR_INVALIDCALL;
+ }
+
+ if (!shader_impl->wined3d_shader)
+ {
+ wined3d_mutex_unlock();
+ *data_size = 0;
+ return D3D_OK;
+ }
+
+ hr = wined3d_shader_get_byte_code(shader_impl->wined3d_shader, data, data_size);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_SetIndices(IDirect3DDevice8 *iface,
+ IDirect3DIndexBuffer8 *buffer, UINT base_vertex_idx)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_indexbuffer *ib = unsafe_impl_from_IDirect3DIndexBuffer8(buffer);
+
+ TRACE("iface %p, buffer %p, base_vertex_idx %u.\n", iface, buffer, base_vertex_idx);
+
+ /* WineD3D takes an INT(due to d3d9), but d3d8 uses UINTs. Do I have to add a check here that
+ * the UINT doesn't cause an overflow in the INT? It seems rather unlikely because such large
+ * vertex buffers can't be created to address them with an index that requires the 32nd bit
+ * (4 Byte minimum vertex size * 2^31-1 -> 8 gb buffer. The index sign would be the least
+ * problem)
+ */
+ wined3d_mutex_lock();
+ wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_idx);
+ wined3d_device_set_index_buffer(device->wined3d_device,
+ ib ? ib->wined3d_buffer : NULL,
+ ib ? ib->format : WINED3DFMT_UNKNOWN);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_GetIndices(IDirect3DDevice8 *iface,
+ IDirect3DIndexBuffer8 **buffer, UINT *base_vertex_index)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ enum wined3d_format_id wined3d_format;
+ struct wined3d_buffer *wined3d_buffer;
+ struct d3d8_indexbuffer *buffer_impl;
+
+ TRACE("iface %p, buffer %p, base_vertex_index %p.\n", iface, buffer, base_vertex_index);
+
+ if (!buffer)
+ return D3DERR_INVALIDCALL;
+
+ /* The case from UINT to INT is safe because d3d8 will never set negative values */
+ wined3d_mutex_lock();
+ *base_vertex_index = wined3d_device_get_base_vertex_index(device->wined3d_device);
+ if ((wined3d_buffer = wined3d_device_get_index_buffer(device->wined3d_device, &wined3d_format)))
+ {
+ buffer_impl = wined3d_buffer_get_parent(wined3d_buffer);
+ *buffer = &buffer_impl->IDirect3DIndexBuffer8_iface;
+ IDirect3DIndexBuffer8_AddRef(*buffer);
+ }
+ else
+ {
+ *buffer = NULL;
+ }
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_CreatePixelShader(IDirect3DDevice8 *iface,
+ const DWORD *byte_code, DWORD *shader)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_pixel_shader *object;
+ DWORD shader_handle;
+ DWORD handle;
+ HRESULT hr;
+
+ TRACE("iface %p, byte_code %p, shader %p.\n", iface, byte_code, shader);
+
+ if (!shader)
+ return D3DERR_INVALIDCALL;
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ wined3d_mutex_lock();
+ handle = d3d8_allocate_handle(&device->handle_table, object, D3D8_HANDLE_PS);
+ wined3d_mutex_unlock();
+ if (handle == D3D8_INVALID_HANDLE)
+ {
+ ERR("Failed to allocate pixel shader handle.\n");
+ HeapFree(GetProcessHeap(), 0, object);
+ return E_OUTOFMEMORY;
+ }
+
+ shader_handle = handle + VS_HIGHESTFIXEDFXF + 1;
+
+ hr = d3d8_pixel_shader_init(object, device, byte_code, shader_handle);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
+ wined3d_mutex_lock();
+ d3d8_free_handle(&device->handle_table, handle, D3D8_HANDLE_PS);
+ wined3d_mutex_unlock();
+ HeapFree(GetProcessHeap(), 0, object);
+ *shader = 0;
+ return hr;
+ }
+
+ TRACE("Created pixel shader %p (handle %#x).\n", object, shader_handle);
+ *shader = shader_handle;
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_SetPixelShader(IDirect3DDevice8 *iface, DWORD shader)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_pixel_shader *shader_impl;
+
+ TRACE("iface %p, shader %#x.\n", iface, shader);
+
+ wined3d_mutex_lock();
+
+ if (!shader)
+ {
+ wined3d_device_set_pixel_shader(device->wined3d_device, NULL);
+ wined3d_mutex_unlock();
+ return D3D_OK;
+ }
+
+ if (!(shader_impl = d3d8_get_object(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_PS)))
+ {
+ WARN("Invalid handle (%#x) passed.\n", shader);
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
+
+ TRACE("Setting shader %p.\n", shader_impl);
+ wined3d_device_set_pixel_shader(device->wined3d_device, shader_impl->wined3d_shader);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_GetPixelShader(IDirect3DDevice8 *iface, DWORD *shader)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct wined3d_shader *object;
+
+ TRACE("iface %p, shader %p.\n", iface, shader);
+
+ if (!shader)
+ return D3DERR_INVALIDCALL;
+
+ wined3d_mutex_lock();
+ if ((object = wined3d_device_get_pixel_shader(device->wined3d_device)))
+ {
+ struct d3d8_pixel_shader *d3d8_shader;
+ d3d8_shader = wined3d_shader_get_parent(object);
+ *shader = d3d8_shader->handle;
+ }
+ else
+ {
+ *shader = 0;
+ }
+ wined3d_mutex_unlock();
+
+ TRACE("Returning %#x.\n", *shader);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_DeletePixelShader(IDirect3DDevice8 *iface, DWORD shader)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_pixel_shader *shader_impl;
+
+ TRACE("iface %p, shader %#x.\n", iface, shader);
+
+ wined3d_mutex_lock();
+
+ if (!(shader_impl = d3d8_free_handle(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_PS)))
+ {
+ WARN("Invalid handle (%#x) passed.\n", shader);
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
+
+ if (wined3d_device_get_pixel_shader(device->wined3d_device) == shader_impl->wined3d_shader)
+ IDirect3DDevice8_SetPixelShader(iface, 0);
+
+ wined3d_mutex_unlock();
+
+ d3d8_pixel_shader_destroy(shader_impl);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_SetPixelShaderConstant(IDirect3DDevice8 *iface,
+ DWORD start_register, const void *data, DWORD count)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, start_register %u, data %p, count %u.\n",
+ iface, start_register, data, count);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_ps_consts_f(device->wined3d_device, start_register, data, count);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_GetPixelShaderConstant(IDirect3DDevice8 *iface,
+ DWORD start_register, void *data, DWORD count)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, start_register %u, data %p, count %u.\n",
+ iface, start_register, data, count);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_ps_consts_f(device->wined3d_device, start_register, data, count);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_GetPixelShaderFunction(IDirect3DDevice8 *iface,
+ DWORD shader, void *data, DWORD *data_size)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_pixel_shader *shader_impl = NULL;
+ HRESULT hr;
+
+ TRACE("iface %p, shader %#x, data %p, data_size %p.\n",
+ iface, shader, data, data_size);
+
+ wined3d_mutex_lock();
+ if (!(shader_impl = d3d8_get_object(&device->handle_table, shader - (VS_HIGHESTFIXEDFXF + 1), D3D8_HANDLE_PS)))
+ {
+ WARN("Invalid handle (%#x) passed.\n", shader);
+ wined3d_mutex_unlock();
+
+ return D3DERR_INVALIDCALL;
+ }
+
+ hr = wined3d_shader_get_byte_code(shader_impl->wined3d_shader, data, data_size);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_DrawRectPatch(IDirect3DDevice8 *iface, UINT handle,
+ const float *segment_count, const D3DRECTPATCH_INFO *patch_info)
+{
+ FIXME("iface %p, handle %#x, segment_count %p, patch_info %p unimplemented.\n",
+ iface, handle, segment_count, patch_info);
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_DrawTriPatch(IDirect3DDevice8 *iface, UINT handle,
+ const float *segment_count, const D3DTRIPATCH_INFO *patch_info)
+{
+ FIXME("iface %p, handle %#x, segment_count %p, patch_info %p unimplemented.\n",
+ iface, handle, segment_count, patch_info);
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_device_DeletePatch(IDirect3DDevice8 *iface, UINT handle)
+{
+ FIXME("iface %p, handle %#x unimplemented.\n", iface, handle);
+ return D3DERR_INVALIDCALL;
+}
+
+static HRESULT WINAPI d3d8_device_SetStreamSource(IDirect3DDevice8 *iface,
+ UINT stream_idx, IDirect3DVertexBuffer8 *buffer, UINT stride)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_vertexbuffer *buffer_impl = unsafe_impl_from_IDirect3DVertexBuffer8(buffer);
+ HRESULT hr;
+
+ TRACE("iface %p, stream_idx %u, buffer %p, stride %u.\n",
+ iface, stream_idx, buffer, stride);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_stream_source(device->wined3d_device, stream_idx,
+ buffer_impl ? buffer_impl->wined3d_buffer : NULL, 0, stride);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_device_GetStreamSource(IDirect3DDevice8 *iface,
+ UINT stream_idx, IDirect3DVertexBuffer8 **buffer, UINT *stride)
+{
+ struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+ struct d3d8_vertexbuffer *buffer_impl;
+ struct wined3d_buffer *wined3d_buffer = NULL;
+ HRESULT hr;
+
+ TRACE("iface %p, stream_idx %u, buffer %p, stride %p.\n",
+ iface, stream_idx, buffer, stride);
+
+ if (!buffer)
+ return D3DERR_INVALIDCALL;
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_stream_source(device->wined3d_device, stream_idx, &wined3d_buffer, 0, stride);
+ if (SUCCEEDED(hr) && wined3d_buffer)
+ {
+ buffer_impl = wined3d_buffer_get_parent(wined3d_buffer);
+ *buffer = &buffer_impl->IDirect3DVertexBuffer8_iface;
+ IDirect3DVertexBuffer8_AddRef(*buffer);
+ wined3d_buffer_decref(wined3d_buffer);
+ }
+ else
+ {
+ if (FAILED(hr))
+ ERR("Failed to get wined3d stream source, hr %#x.\n", hr);
+ *buffer = NULL;
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static const struct IDirect3DDevice8Vtbl d3d8_device_vtbl =
+{
+ d3d8_device_QueryInterface,
+ d3d8_device_AddRef,
+ d3d8_device_Release,
+ d3d8_device_TestCooperativeLevel,
+ d3d8_device_GetAvailableTextureMem,
+ d3d8_device_ResourceManagerDiscardBytes,
+ d3d8_device_GetDirect3D,
+ d3d8_device_GetDeviceCaps,
+ d3d8_device_GetDisplayMode,
+ d3d8_device_GetCreationParameters,
+ d3d8_device_SetCursorProperties,
+ d3d8_device_SetCursorPosition,
+ d3d8_device_ShowCursor,
+ d3d8_device_CreateAdditionalSwapChain,
+ d3d8_device_Reset,
+ d3d8_device_Present,
+ d3d8_device_GetBackBuffer,
+ d3d8_device_GetRasterStatus,
+ d3d8_device_SetGammaRamp,
+ d3d8_device_GetGammaRamp,
+ d3d8_device_CreateTexture,
+ d3d8_device_CreateVolumeTexture,
+ d3d8_device_CreateCubeTexture,
+ d3d8_device_CreateVertexBuffer,
+ d3d8_device_CreateIndexBuffer,
+ d3d8_device_CreateRenderTarget,
+ d3d8_device_CreateDepthStencilSurface,
+ d3d8_device_CreateImageSurface,
+ d3d8_device_CopyRects,
+ d3d8_device_UpdateTexture,
+ d3d8_device_GetFrontBuffer,
+ d3d8_device_SetRenderTarget,
+ d3d8_device_GetRenderTarget,
+ d3d8_device_GetDepthStencilSurface,
+ d3d8_device_BeginScene,
+ d3d8_device_EndScene,
+ d3d8_device_Clear,
+ d3d8_device_SetTransform,
+ d3d8_device_GetTransform,
+ d3d8_device_MultiplyTransform,
+ d3d8_device_SetViewport,
+ d3d8_device_GetViewport,
+ d3d8_device_SetMaterial,
+ d3d8_device_GetMaterial,
+ d3d8_device_SetLight,
+ d3d8_device_GetLight,
+ d3d8_device_LightEnable,
+ d3d8_device_GetLightEnable,
+ d3d8_device_SetClipPlane,
+ d3d8_device_GetClipPlane,
+ d3d8_device_SetRenderState,
+ d3d8_device_GetRenderState,
+ d3d8_device_BeginStateBlock,
+ d3d8_device_EndStateBlock,
+ d3d8_device_ApplyStateBlock,
+ d3d8_device_CaptureStateBlock,
+ d3d8_device_DeleteStateBlock,
+ d3d8_device_CreateStateBlock,
+ d3d8_device_SetClipStatus,
+ d3d8_device_GetClipStatus,
+ d3d8_device_GetTexture,
+ d3d8_device_SetTexture,
+ d3d8_device_GetTextureStageState,
+ d3d8_device_SetTextureStageState,
+ d3d8_device_ValidateDevice,
+ d3d8_device_GetInfo,
+ d3d8_device_SetPaletteEntries,
+ d3d8_device_GetPaletteEntries,
+ d3d8_device_SetCurrentTexturePalette,
+ d3d8_device_GetCurrentTexturePalette,
+ d3d8_device_DrawPrimitive,
+ d3d8_device_DrawIndexedPrimitive,
+ d3d8_device_DrawPrimitiveUP,
+ d3d8_device_DrawIndexedPrimitiveUP,
+ d3d8_device_ProcessVertices,
+ d3d8_device_CreateVertexShader,
+ d3d8_device_SetVertexShader,
+ d3d8_device_GetVertexShader,
+ d3d8_device_DeleteVertexShader,
+ d3d8_device_SetVertexShaderConstant,
+ d3d8_device_GetVertexShaderConstant,
+ d3d8_device_GetVertexShaderDeclaration,
+ d3d8_device_GetVertexShaderFunction,
+ d3d8_device_SetStreamSource,
+ d3d8_device_GetStreamSource,
+ d3d8_device_SetIndices,
+ d3d8_device_GetIndices,
+ d3d8_device_CreatePixelShader,
+ d3d8_device_SetPixelShader,
+ d3d8_device_GetPixelShader,
+ d3d8_device_DeletePixelShader,
+ d3d8_device_SetPixelShaderConstant,
+ d3d8_device_GetPixelShaderConstant,
+ d3d8_device_GetPixelShaderFunction,
+ d3d8_device_DrawRectPatch,
+ d3d8_device_DrawTriPatch,
+ d3d8_device_DeletePatch,
+};
+
+static inline struct d3d8_device *device_from_device_parent(struct wined3d_device_parent *device_parent)
+{
+ return CONTAINING_RECORD(device_parent, struct d3d8_device, device_parent);
+}
+
+static void CDECL device_parent_wined3d_device_created(struct wined3d_device_parent *device_parent,
+ struct wined3d_device *device)
+{
+ TRACE("device_parent %p, device %p\n", device_parent, device);
+}
+
+static void CDECL device_parent_mode_changed(struct wined3d_device_parent *device_parent)
+{
+ TRACE("device_parent %p.\n", device_parent);
+}
+
+static HRESULT CDECL device_parent_create_texture_surface(struct wined3d_device_parent *device_parent,
+ void *container_parent, const struct wined3d_resource_desc *desc, UINT sub_resource_idx,
+ DWORD flags, struct wined3d_surface **surface)
+{
+ struct d3d8_device *device = device_from_device_parent(device_parent);
+ struct d3d8_surface *d3d_surface;
+ HRESULT hr;
+
+ TRACE("device_parent %p, container_parent %p, desc %p, sub_resource_idx %u, flags %#x, surface %p.\n",
+ device_parent, container_parent, desc, sub_resource_idx, flags, surface);
+
+ if (FAILED(hr = d3d8_device_create_surface(device, desc->width, desc->height,
+ d3dformat_from_wined3dformat(desc->format), flags, (IDirect3DSurface8 **)&d3d_surface,
+ desc->usage, desc->pool, desc->multisample_type, desc->multisample_quality)))
+ {
+ WARN("Failed to create surface, hr %#x.\n", hr);
+ return hr;
+ }
+
+ *surface = d3d_surface->wined3d_surface;
+ wined3d_surface_incref(*surface);
+
+ d3d_surface->container = container_parent;
+ IDirect3DDevice8_Release(d3d_surface->parent_device);
+ d3d_surface->parent_device = NULL;
+
+ IDirect3DSurface8_Release(&d3d_surface->IDirect3DSurface8_iface);
+ d3d_surface->forwardReference = container_parent;
+
+ return hr;
+}
+
+static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_device_parent *device_parent,
+ void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_surface **surface)
+{
+ struct d3d8_device *device = device_from_device_parent(device_parent);
+ struct wined3d_resource_desc texture_desc;
+ struct d3d8_surface *d3d_surface;
+ struct wined3d_texture *texture;
+ HRESULT hr;
+
+ TRACE("device_parent %p, container_parent %p, desc %p, surface %p.\n",
+ device_parent, container_parent, desc, surface);
+
+ texture_desc = *desc;
+ texture_desc.resource_type = WINED3D_RTYPE_TEXTURE;
+ if (FAILED(hr = wined3d_texture_create_2d(device->wined3d_device, &texture_desc, 1,
+ WINED3D_SURFACE_MAPPABLE, &device->IDirect3DDevice8_iface, &d3d8_null_wined3d_parent_ops, &texture)))
+ {
+ WARN("Failed to create texture, hr %#x.\n", hr);
+ return hr;
+ }
+
+ *surface = wined3d_surface_from_resource(wined3d_texture_get_sub_resource(texture, 0));
+ wined3d_surface_incref(*surface);
+ wined3d_texture_decref(texture);
+
+ d3d_surface = wined3d_surface_get_parent(*surface);
+ d3d_surface->forwardReference = NULL;
+ d3d_surface->parent_device = &device->IDirect3DDevice8_iface;
+
+ return hr;
+}
+
+static HRESULT CDECL device_parent_create_volume(struct wined3d_device_parent *device_parent,
+ void *container_parent, UINT width, UINT height, UINT depth, enum wined3d_format_id format,
+ enum wined3d_pool pool, DWORD usage, struct wined3d_volume **volume)
+{
+ struct d3d8_device *device = device_from_device_parent(device_parent);
+ struct d3d8_volume *object;
+ HRESULT hr;
+
+ TRACE("device_parent %p, container_parent %p, width %u, height %u, depth %u, "
+ "format %#x, pool %#x, usage %#x, volume %p.\n",
+ device_parent, container_parent, width, height, depth,
+ format, pool, usage, volume);
+
+ /* Allocate the storage for the device */
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ {
+ FIXME("Allocation of memory failed\n");
+ *volume = NULL;
+ return D3DERR_OUTOFVIDEOMEMORY;
+ }
+
+ hr = volume_init(object, device, width, height, depth, usage, format, pool);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize volume, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ *volume = object->wined3d_volume;
+ wined3d_volume_incref(*volume);
+ IDirect3DVolume8_Release(&object->IDirect3DVolume8_iface);
+
+ object->container = container_parent;
+ object->forwardReference = container_parent;
+
+ TRACE("Created volume %p.\n", object);
+
+ return hr;
+}
+
+static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent *device_parent,
+ struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain)
+{
+ struct d3d8_device *device = device_from_device_parent(device_parent);
+ struct d3d8_swapchain *d3d_swapchain;
+ HRESULT hr;
+
+ TRACE("device_parent %p, desc %p, swapchain %p.\n", device_parent, desc, swapchain);
+
+ if (FAILED(hr = d3d8_swapchain_create(device, desc, &d3d_swapchain)))
+ {
+ WARN("Failed to create swapchain, hr %#x.\n", hr);
+ *swapchain = NULL;
+ return hr;
+ }
+
+ *swapchain = d3d_swapchain->wined3d_swapchain;
+ wined3d_swapchain_incref(*swapchain);
+ IDirect3DSwapChain8_Release(&d3d_swapchain->IDirect3DSwapChain8_iface);
+
+ return hr;
+}
+
+static const struct wined3d_device_parent_ops d3d8_wined3d_device_parent_ops =
+{
+ device_parent_wined3d_device_created,
+ device_parent_mode_changed,
+ device_parent_create_swapchain_surface,
+ device_parent_create_texture_surface,
+ device_parent_create_volume,
+ device_parent_create_swapchain,
+};
+
+static void setup_fpu(void)
+{
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+ WORD cw;
+ __asm__ volatile ("fnstcw %0" : "=m" (cw));
+ cw = (cw & ~0xf3f) | 0x3f;
+ __asm__ volatile ("fldcw %0" : : "m" (cw));
+#elif defined(__i386__) && defined(_MSC_VER)
+ WORD cw;
+ __asm fnstcw cw;
+ cw = (cw & ~0xf3f) | 0x3f;
+ __asm fldcw cw;
+#elif defined(RT_ARCH_AMD64)
+ unsigned int currentControl = 0;
+ _controlfp_s(&currentControl, 0x3f, 0xf3f);
+#else
+ FIXME("FPU setup not implemented for this platform.\n");
+#endif
+}
+
+HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wined3d *wined3d, UINT adapter,
+ D3DDEVTYPE device_type, HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters)
+{
+ struct wined3d_swapchain_desc swapchain_desc;
+ HRESULT hr;
+
+ device->IDirect3DDevice8_iface.lpVtbl = &d3d8_device_vtbl;
+ device->device_parent.ops = &d3d8_wined3d_device_parent_ops;
+ device->ref = 1;
+ device->handle_table.entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ D3D8_INITIAL_HANDLE_TABLE_SIZE * sizeof(*device->handle_table.entries));
+ if (!device->handle_table.entries)
+ {
+ ERR("Failed to allocate handle table memory.\n");
+ return E_OUTOFMEMORY;
+ }
+ device->handle_table.table_size = D3D8_INITIAL_HANDLE_TABLE_SIZE;
+
+ if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu();
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_create(wined3d, adapter, device_type, focus_window, flags, 4,
+ &device->device_parent, &device->wined3d_device);
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d device, hr %#x.\n", hr);
+ wined3d_mutex_unlock();
+ HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
+ return hr;
+ }
+
+ if (!parameters->Windowed)
+ {
+ HWND device_window = parameters->hDeviceWindow;
+
+ if (!focus_window)
+ focus_window = device_window;
+ if (FAILED(hr = wined3d_device_acquire_focus_window(device->wined3d_device, focus_window)))
+ {
+ ERR("Failed to acquire focus window, hr %#x.\n", hr);
+ wined3d_device_decref(device->wined3d_device);
+ wined3d_mutex_unlock();
+ HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
+ return hr;
+ }
+
+ if (!device_window)
+ device_window = focus_window;
+ wined3d_device_setup_fullscreen_window(device->wined3d_device, device_window,
+ parameters->BackBufferWidth,
+ parameters->BackBufferHeight);
+ }
+
+ if (flags & D3DCREATE_MULTITHREADED)
+ wined3d_device_set_multithreaded(device->wined3d_device);
+
+ wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, parameters);
+
+ hr = wined3d_device_init_3d(device->wined3d_device, &swapchain_desc);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize 3D, hr %#x.\n", hr);
+ wined3d_device_release_focus_window(device->wined3d_device);
+ wined3d_device_decref(device->wined3d_device);
+ wined3d_mutex_unlock();
+ HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
+ return hr;
+ }
+
+ wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0);
+ wined3d_mutex_unlock();
+
+ present_parameters_from_wined3d_swapchain_desc(parameters, &swapchain_desc);
+
+ device->declArraySize = 16;
+ device->decls = HeapAlloc(GetProcessHeap(), 0, device->declArraySize * sizeof(*device->decls));
+ if (!device->decls)
+ {
+ ERR("Failed to allocate FVF vertex declaration map memory.\n");
+ hr = E_OUTOFMEMORY;
+ goto err;
+ }
+
+ device->d3d_parent = &parent->IDirect3D8_iface;
+ IDirect3D8_AddRef(device->d3d_parent);
+
+ return D3D_OK;
+
+err:
+ wined3d_mutex_lock();
+ wined3d_device_uninit_3d(device->wined3d_device);
+ wined3d_device_release_focus_window(device->wined3d_device);
+ wined3d_device_decref(device->wined3d_device);
+ wined3d_mutex_unlock();
+ HeapFree(GetProcessHeap(), 0, device->handle_table.entries);
+ return hr;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/directx.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/directx.c
new file mode 100644
index 00000000..4e3175e4
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/directx.c
@@ -0,0 +1,428 @@
+/*
+ * IDirect3D8 implementation
+ *
+ * Copyright 2002-2004 Jason Edmeades
+ * Copyright 2003-2004 Raphael Junqueira
+ * Copyright 2004 Christian Costa
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+#include "d3d8_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
+
+static inline struct d3d8 *impl_from_IDirect3D8(IDirect3D8 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d8, IDirect3D8_iface);
+}
+
+static HRESULT WINAPI d3d8_QueryInterface(IDirect3D8 *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3D8)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3D8_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d8_AddRef(IDirect3D8 *iface)
+{
+ struct d3d8 *d3d8 = impl_from_IDirect3D8(iface);
+ ULONG refcount = InterlockedIncrement(&d3d8->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, refcount);
+
+ return refcount;
+}
+
+static ULONG WINAPI d3d8_Release(IDirect3D8 *iface)
+{
+ struct d3d8 *d3d8 = impl_from_IDirect3D8(iface);
+ ULONG refcount = InterlockedDecrement(&d3d8->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ wined3d_mutex_lock();
+ wined3d_decref(d3d8->wined3d);
+ wined3d_mutex_unlock();
+
+ HeapFree(GetProcessHeap(), 0, d3d8);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI d3d8_RegisterSoftwareDevice(IDirect3D8 *iface, void *init_function)
+{
+ struct d3d8 *d3d8 = impl_from_IDirect3D8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, init_function %p.\n", iface, init_function);
+
+ wined3d_mutex_lock();
+ hr = wined3d_register_software_device(d3d8->wined3d, init_function);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static UINT WINAPI d3d8_GetAdapterCount(IDirect3D8 *iface)
+{
+ struct d3d8 *d3d8 = impl_from_IDirect3D8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ hr = wined3d_get_adapter_count(d3d8->wined3d);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_GetAdapterIdentifier(IDirect3D8 *iface, UINT adapter,
+ DWORD flags, D3DADAPTER_IDENTIFIER8 *identifier)
+{
+ struct d3d8 *d3d8 = impl_from_IDirect3D8(iface);
+ struct wined3d_adapter_identifier adapter_id;
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, flags %#x, identifier %p.\n",
+ iface, adapter, flags, identifier);
+
+ adapter_id.driver = identifier->Driver;
+ adapter_id.driver_size = sizeof(identifier->Driver);
+ adapter_id.description = identifier->Description;
+ adapter_id.description_size = sizeof(identifier->Description);
+ adapter_id.device_name = NULL; /* d3d9 only */
+ adapter_id.device_name_size = 0; /* d3d9 only */
+
+ wined3d_mutex_lock();
+ hr = wined3d_get_adapter_identifier(d3d8->wined3d, adapter, flags, &adapter_id);
+ wined3d_mutex_unlock();
+
+ identifier->DriverVersion = adapter_id.driver_version;
+ identifier->VendorId = adapter_id.vendor_id;
+ identifier->DeviceId = adapter_id.device_id;
+ identifier->SubSysId = adapter_id.subsystem_id;
+ identifier->Revision = adapter_id.revision;
+ memcpy(&identifier->DeviceIdentifier, &adapter_id.device_identifier, sizeof(identifier->DeviceIdentifier));
+ identifier->WHQLLevel = adapter_id.whql_level;
+
+ return hr;
+}
+
+static UINT WINAPI d3d8_GetAdapterModeCount(IDirect3D8 *iface, UINT adapter)
+{
+ struct d3d8 *d3d8 = impl_from_IDirect3D8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u.\n", iface, adapter);
+
+ wined3d_mutex_lock();
+ hr = wined3d_get_adapter_mode_count(d3d8->wined3d, adapter,
+ WINED3DFMT_UNKNOWN, WINED3D_SCANLINE_ORDERING_UNKNOWN);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_EnumAdapterModes(IDirect3D8 *iface, UINT adapter, UINT mode_idx, D3DDISPLAYMODE *mode)
+{
+ struct d3d8 *d3d8 = impl_from_IDirect3D8(iface);
+ struct wined3d_display_mode wined3d_mode;
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, mode_idx %u, mode %p.\n",
+ iface, adapter, mode_idx, mode);
+
+ wined3d_mutex_lock();
+ hr = wined3d_enum_adapter_modes(d3d8->wined3d, adapter, WINED3DFMT_UNKNOWN,
+ WINED3D_SCANLINE_ORDERING_UNKNOWN, mode_idx, &wined3d_mode);
+ wined3d_mutex_unlock();
+
+ if (SUCCEEDED(hr))
+ {
+ mode->Width = wined3d_mode.width;
+ mode->Height = wined3d_mode.height;
+ mode->RefreshRate = wined3d_mode.refresh_rate;
+ mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id);
+ }
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_GetAdapterDisplayMode(IDirect3D8 *iface, UINT adapter, D3DDISPLAYMODE *mode)
+{
+ struct d3d8 *d3d8 = impl_from_IDirect3D8(iface);
+ struct wined3d_display_mode wined3d_mode;
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, mode %p.\n",
+ iface, adapter, mode);
+
+ wined3d_mutex_lock();
+ hr = wined3d_get_adapter_display_mode(d3d8->wined3d, adapter, &wined3d_mode, NULL);
+ wined3d_mutex_unlock();
+
+ if (SUCCEEDED(hr))
+ {
+ mode->Width = wined3d_mode.width;
+ mode->Height = wined3d_mode.height;
+ mode->RefreshRate = wined3d_mode.refresh_rate;
+ mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id);
+ }
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_CheckDeviceType(IDirect3D8 *iface, UINT adapter, D3DDEVTYPE device_type,
+ D3DFORMAT display_format, D3DFORMAT backbuffer_format, BOOL windowed)
+{
+ struct d3d8 *d3d8 = impl_from_IDirect3D8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, device_type %#x, display_format %#x, backbuffer_format %#x, windowed %#x.\n",
+ iface, adapter, device_type, display_format, backbuffer_format, windowed);
+
+ wined3d_mutex_lock();
+ hr = wined3d_check_device_type(d3d8->wined3d, adapter, device_type, wined3dformat_from_d3dformat(display_format),
+ wined3dformat_from_d3dformat(backbuffer_format), windowed);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_CheckDeviceFormat(IDirect3D8 *iface, UINT adapter, D3DDEVTYPE device_type,
+ D3DFORMAT adapter_format, DWORD usage, D3DRESOURCETYPE resource_type, D3DFORMAT format)
+{
+ struct d3d8 *d3d8 = impl_from_IDirect3D8(iface);
+ enum wined3d_resource_type wined3d_rtype;
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, device_type %#x, adapter_format %#x, usage %#x, resource_type %#x, format %#x.\n",
+ iface, adapter, device_type, adapter_format, usage, resource_type, format);
+
+ switch (resource_type)
+ {
+ case D3DRTYPE_VERTEXBUFFER:
+ case D3DRTYPE_INDEXBUFFER:
+ wined3d_rtype = WINED3D_RTYPE_BUFFER;
+ break;
+
+ default:
+ wined3d_rtype = resource_type;
+ break;
+ }
+
+ wined3d_mutex_lock();
+ hr = wined3d_check_device_format(d3d8->wined3d, adapter, device_type, wined3dformat_from_d3dformat(adapter_format),
+ usage, wined3d_rtype, wined3dformat_from_d3dformat(format));
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_CheckDeviceMultiSampleType(IDirect3D8 *iface, UINT adapter, D3DDEVTYPE device_type,
+ D3DFORMAT format, BOOL windowed, D3DMULTISAMPLE_TYPE multisample_type)
+{
+ struct d3d8 *d3d8 = impl_from_IDirect3D8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, device_type %#x, format %#x, windowed %#x, multisample_type %#x.\n",
+ iface, adapter, device_type, format, windowed, multisample_type);
+
+ wined3d_mutex_lock();
+ hr = wined3d_check_device_multisample_type(d3d8->wined3d, adapter, device_type,
+ wined3dformat_from_d3dformat(format), windowed,
+ (enum wined3d_multisample_type)multisample_type, NULL);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_CheckDepthStencilMatch(IDirect3D8 *iface, UINT adapter, D3DDEVTYPE device_type,
+ D3DFORMAT adapter_format, D3DFORMAT rt_format, D3DFORMAT ds_format)
+{
+ struct d3d8 *d3d8 = impl_from_IDirect3D8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, device_type %#x, adapter_format %#x, rt_format %#x, ds_format %#x.\n",
+ iface, adapter, device_type, adapter_format, rt_format, ds_format);
+
+ wined3d_mutex_lock();
+ hr = wined3d_check_depth_stencil_match(d3d8->wined3d, adapter, device_type,
+ wined3dformat_from_d3dformat(adapter_format), wined3dformat_from_d3dformat(rt_format),
+ wined3dformat_from_d3dformat(ds_format));
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+void fixup_caps(WINED3DCAPS *caps)
+{
+ /* D3D8 doesn't support SM 2.0 or higher, so clamp to 1.x */
+ if (caps->PixelShaderVersion)
+ caps->PixelShaderVersion = D3DPS_VERSION(1,4);
+ else
+ caps->PixelShaderVersion = D3DPS_VERSION(0,0);
+ if (caps->VertexShaderVersion)
+ caps->VertexShaderVersion = D3DVS_VERSION(1,1);
+ else
+ caps->VertexShaderVersion = D3DVS_VERSION(0,0);
+ caps->MaxVertexShaderConst = min(D3D8_MAX_VERTEX_SHADER_CONSTANTF, caps->MaxVertexShaderConst);
+
+ caps->StencilCaps &= ~WINED3DSTENCILCAPS_TWOSIDED;
+}
+
+static HRESULT WINAPI d3d8_GetDeviceCaps(IDirect3D8 *iface, UINT adapter, D3DDEVTYPE device_type, D3DCAPS8 *caps)
+{
+ struct d3d8 *d3d8 = impl_from_IDirect3D8(iface);
+ WINED3DCAPS *wined3d_caps;
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, device_type %#x, caps %p.\n", iface, adapter, device_type, caps);
+
+ if (!caps)
+ return D3DERR_INVALIDCALL;
+
+ if (!(wined3d_caps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wined3d_caps))))
+ return D3DERR_INVALIDCALL;
+
+ wined3d_mutex_lock();
+ hr = wined3d_get_device_caps(d3d8->wined3d, adapter, device_type, wined3d_caps);
+ wined3d_mutex_unlock();
+
+ fixup_caps(wined3d_caps);
+ WINECAPSTOD3D8CAPS(caps, wined3d_caps)
+ HeapFree(GetProcessHeap(), 0, wined3d_caps);
+
+ return hr;
+}
+
+static HMONITOR WINAPI d3d8_GetAdapterMonitor(IDirect3D8 *iface, UINT adapter)
+{
+ struct d3d8 *d3d8 = impl_from_IDirect3D8(iface);
+ HMONITOR ret;
+
+ TRACE("iface %p, adapter %u.\n", iface, adapter);
+
+ wined3d_mutex_lock();
+ ret = wined3d_get_adapter_monitor(d3d8->wined3d, adapter);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static HRESULT WINAPI d3d8_CreateDevice(IDirect3D8 *iface, UINT adapter,
+ D3DDEVTYPE device_type, HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters,
+ IDirect3DDevice8 **device)
+{
+ struct d3d8 *d3d8 = impl_from_IDirect3D8(iface);
+ struct d3d8_device *object;
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, device_type %#x, focus_window %p, flags %#x, parameters %p, device %p.\n",
+ iface, adapter, device_type, focus_window, flags, parameters, device);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ hr = device_init(object, d3d8, d3d8->wined3d, adapter, device_type, focus_window, flags, parameters);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize device, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created device %p.\n", object);
+ *device = &object->IDirect3DDevice8_iface;
+
+ return D3D_OK;
+}
+
+static const struct IDirect3D8Vtbl d3d8_vtbl =
+{
+ /* IUnknown */
+ d3d8_QueryInterface,
+ d3d8_AddRef,
+ d3d8_Release,
+ /* IDirect3D8 */
+ d3d8_RegisterSoftwareDevice,
+ d3d8_GetAdapterCount,
+ d3d8_GetAdapterIdentifier,
+ d3d8_GetAdapterModeCount,
+ d3d8_EnumAdapterModes,
+ d3d8_GetAdapterDisplayMode,
+ d3d8_CheckDeviceType,
+ d3d8_CheckDeviceFormat,
+ d3d8_CheckDeviceMultiSampleType,
+ d3d8_CheckDepthStencilMatch,
+ d3d8_GetDeviceCaps,
+ d3d8_GetAdapterMonitor,
+ d3d8_CreateDevice,
+};
+
+BOOL d3d8_init(struct d3d8 *d3d8)
+{
+ DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING;
+
+ d3d8->IDirect3D8_iface.lpVtbl = &d3d8_vtbl;
+ d3d8->refcount = 1;
+
+ wined3d_mutex_lock();
+ d3d8->wined3d = wined3d_create(8, flags);
+ wined3d_mutex_unlock();
+ if (!d3d8->wined3d)
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/shader.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/shader.c
new file mode 100644
index 00000000..e9c5340b
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/shader.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2002-2003 Jason Edmeades
+ * Raphael Junqueira
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "d3d8_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
+
+static void STDMETHODCALLTYPE d3d8_vertexshader_wined3d_object_destroyed(void *parent)
+{
+ struct d3d8_vertex_shader *shader = parent;
+ d3d8_vertex_declaration_destroy(shader->vertex_declaration);
+ HeapFree(GetProcessHeap(), 0, shader);
+}
+
+void d3d8_vertex_shader_destroy(struct d3d8_vertex_shader *shader)
+{
+ TRACE("shader %p.\n", shader);
+
+ if (shader->wined3d_shader)
+ {
+ wined3d_mutex_lock();
+ wined3d_shader_decref(shader->wined3d_shader);
+ wined3d_mutex_unlock();
+ }
+ else
+ {
+ d3d8_vertexshader_wined3d_object_destroyed(shader);
+ }
+}
+
+static const struct wined3d_parent_ops d3d8_vertexshader_wined3d_parent_ops =
+{
+ d3d8_vertexshader_wined3d_object_destroyed,
+};
+
+static HRESULT d3d8_vertexshader_create_vertexdeclaration(struct d3d8_device *device,
+ const DWORD *declaration, DWORD shader_handle, struct d3d8_vertex_declaration **decl_ptr)
+{
+ struct d3d8_vertex_declaration *object;
+ HRESULT hr;
+
+ TRACE("device %p, declaration %p, shader_handle %#x, decl_ptr %p.\n",
+ device, declaration, shader_handle, decl_ptr);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ hr = d3d8_vertex_declaration_init(object, device, declaration, shader_handle);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created vertex declaration %p.\n", object);
+ *decl_ptr = object;
+
+ return D3D_OK;
+}
+
+HRESULT d3d8_vertex_shader_init(struct d3d8_vertex_shader *shader, struct d3d8_device *device,
+ const DWORD *declaration, const DWORD *byte_code, DWORD shader_handle, DWORD usage)
+{
+ const DWORD *token = declaration;
+ HRESULT hr;
+
+ /* Test if the vertex declaration is valid. */
+ while (D3DVSD_END() != *token)
+ {
+ D3DVSD_TOKENTYPE token_type = ((*token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT);
+
+ if (token_type == D3DVSD_TOKEN_STREAMDATA && !(token_type & 0x10000000))
+ {
+ DWORD type = ((*token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
+ DWORD reg = ((*token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
+
+ if (reg == D3DVSDE_NORMAL && type != D3DVSDT_FLOAT3 && !byte_code)
+ {
+ WARN("Attempt to use a non-FLOAT3 normal with the fixed function function\n");
+ return D3DERR_INVALIDCALL;
+ }
+ }
+ token += parse_token(token);
+ }
+
+ hr = d3d8_vertexshader_create_vertexdeclaration(device, declaration, shader_handle, &shader->vertex_declaration);
+ if (FAILED(hr))
+ {
+ WARN("Failed to create vertex declaration, hr %#x.\n", hr);
+ return hr;
+ }
+
+ if (byte_code)
+ {
+ if (usage) FIXME("Usage %#x not implemented.\n", usage);
+
+ wined3d_mutex_lock();
+ hr = wined3d_shader_create_vs(device->wined3d_device, byte_code, NULL /* output signature */,
+ shader, &d3d8_vertexshader_wined3d_parent_ops, &shader->wined3d_shader, 1);
+ wined3d_mutex_unlock();
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d vertex shader, hr %#x.\n", hr);
+ d3d8_vertex_declaration_destroy(shader->vertex_declaration);
+ return hr;
+ }
+
+ load_local_constants(declaration, shader->wined3d_shader);
+ }
+
+ return D3D_OK;
+}
+
+static void STDMETHODCALLTYPE d3d8_pixelshader_wined3d_object_destroyed(void *parent)
+{
+ HeapFree(GetProcessHeap(), 0, parent);
+}
+
+void d3d8_pixel_shader_destroy(struct d3d8_pixel_shader *shader)
+{
+ TRACE("shader %p.\n", shader);
+
+ wined3d_mutex_lock();
+ wined3d_shader_decref(shader->wined3d_shader);
+ wined3d_mutex_unlock();
+}
+
+static const struct wined3d_parent_ops d3d8_pixelshader_wined3d_parent_ops =
+{
+ d3d8_pixelshader_wined3d_object_destroyed,
+};
+
+HRESULT d3d8_pixel_shader_init(struct d3d8_pixel_shader *shader, struct d3d8_device *device,
+ const DWORD *byte_code, DWORD shader_handle)
+{
+ HRESULT hr;
+
+ shader->handle = shader_handle;
+
+ wined3d_mutex_lock();
+ hr = wined3d_shader_create_ps(device->wined3d_device, byte_code, NULL, shader,
+ &d3d8_pixelshader_wined3d_parent_ops, &shader->wined3d_shader, 1);
+ wined3d_mutex_unlock();
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d pixel shader, hr %#x.\n", hr);
+ return hr;
+ }
+
+ return D3D_OK;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/surface.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/surface.c
new file mode 100644
index 00000000..1a36e04e
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/surface.c
@@ -0,0 +1,377 @@
+/*
+ * IDirect3DSurface8 implementation
+ *
+ * Copyright 2005 Oliver Stieber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "d3d8_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
+
+static inline struct d3d8_surface *impl_from_IDirect3DSurface8(IDirect3DSurface8 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d8_surface, IDirect3DSurface8_iface);
+}
+
+static HRESULT WINAPI d3d8_surface_QueryInterface(IDirect3DSurface8 *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DSurface8)
+ || IsEqualGUID(riid, &IID_IDirect3DResource8)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DSurface8_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d8_surface_AddRef(IDirect3DSurface8 *iface)
+{
+ struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ if (surface->forwardReference)
+ {
+ /* Forward refcounting */
+ TRACE("Forwarding to %p.\n", surface->forwardReference);
+ return IUnknown_AddRef(surface->forwardReference);
+ }
+ else
+ {
+ /* No container, handle our own refcounting */
+ ULONG ref = InterlockedIncrement(&surface->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, ref);
+
+ if (ref == 1)
+ {
+ if (surface->parent_device)
+ IDirect3DDevice8_AddRef(surface->parent_device);
+ wined3d_mutex_lock();
+ wined3d_surface_incref(surface->wined3d_surface);
+ wined3d_mutex_unlock();
+ }
+
+ return ref;
+ }
+}
+
+static ULONG WINAPI d3d8_surface_Release(IDirect3DSurface8 *iface)
+{
+ struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ if (surface->forwardReference)
+ {
+ /* Forward refcounting */
+ TRACE("Forwarding to %p.\n", surface->forwardReference);
+ return IUnknown_Release(surface->forwardReference);
+ }
+ else
+ {
+ /* No container, handle our own refcounting */
+ ULONG ref = InterlockedDecrement(&surface->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, ref);
+
+ if (!ref)
+ {
+ IDirect3DDevice8 *parent_device = surface->parent_device;
+
+ /* Implicit surfaces are destroyed with the device, not if refcount reaches 0. */
+ wined3d_mutex_lock();
+ wined3d_surface_decref(surface->wined3d_surface);
+ wined3d_mutex_unlock();
+
+ if (parent_device)
+ IDirect3DDevice8_Release(parent_device);
+ }
+
+ return ref;
+ }
+}
+
+static HRESULT WINAPI d3d8_surface_GetDevice(IDirect3DSurface8 *iface, IDirect3DDevice8 **device)
+{
+ struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ if (surface->forwardReference)
+ {
+ IDirect3DResource8 *resource;
+ HRESULT hr;
+
+ hr = IUnknown_QueryInterface(surface->forwardReference, &IID_IDirect3DResource8, (void **)&resource);
+ if (SUCCEEDED(hr))
+ {
+ hr = IDirect3DResource8_GetDevice(resource, device);
+ IDirect3DResource8_Release(resource);
+
+ TRACE("Returning device %p.\n", *device);
+ }
+
+ return hr;
+ }
+
+ *device = surface->parent_device;
+ IDirect3DDevice8_AddRef(*device);
+
+ TRACE("Returning device %p.\n", *device);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_surface_SetPrivateData(IDirect3DSurface8 *iface, REFGUID guid,
+ const void *data, DWORD data_size, DWORD flags)
+{
+ struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
+ iface, debugstr_guid(guid), data, data_size, flags);
+
+ wined3d_mutex_lock();
+ resource = wined3d_surface_get_resource(surface->wined3d_surface);
+ hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_surface_GetPrivateData(IDirect3DSurface8 *iface, REFGUID guid,
+ void *data, DWORD *data_size)
+{
+ struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %p.\n",
+ iface, debugstr_guid(guid), data, data_size);
+
+ wined3d_mutex_lock();
+ resource = wined3d_surface_get_resource(surface->wined3d_surface);
+ hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_surface_FreePrivateData(IDirect3DSurface8 *iface, REFGUID guid)
+{
+ struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
+
+ wined3d_mutex_lock();
+ resource = wined3d_surface_get_resource(surface->wined3d_surface);
+ hr = wined3d_resource_free_private_data(resource, guid);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_surface_GetContainer(IDirect3DSurface8 *iface, REFIID riid, void **container)
+{
+ struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, riid %s, container %p.\n", iface, debugstr_guid(riid), container);
+
+ if (!surface->container)
+ return E_NOINTERFACE;
+
+ hr = IUnknown_QueryInterface(surface->container, riid, container);
+
+ TRACE("Returning %p.\n", *container);
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_surface_GetDesc(IDirect3DSurface8 *iface, D3DSURFACE_DESC *desc)
+{
+ struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
+ struct wined3d_resource_desc wined3d_desc;
+ struct wined3d_resource *wined3d_resource;
+
+ TRACE("iface %p, desc %p.\n", iface, desc);
+
+ wined3d_mutex_lock();
+ wined3d_resource = wined3d_surface_get_resource(surface->wined3d_surface);
+ wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
+ wined3d_mutex_unlock();
+
+ desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
+ desc->Type = wined3d_desc.resource_type;
+ desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
+ desc->Pool = wined3d_desc.pool;
+ desc->Size = wined3d_desc.size;
+ desc->MultiSampleType = wined3d_desc.multisample_type;
+ desc->Width = wined3d_desc.width;
+ desc->Height = wined3d_desc.height;
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_surface_LockRect(IDirect3DSurface8 *iface,
+ D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
+{
+ struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
+ struct wined3d_map_desc map_desc;
+ HRESULT hr;
+
+ TRACE("iface %p, locked_rect %p, rect %s, flags %#x.\n",
+ iface, locked_rect, wine_dbgstr_rect(rect), flags);
+
+ wined3d_mutex_lock();
+ if (rect)
+ {
+ D3DSURFACE_DESC desc;
+ IDirect3DSurface8_GetDesc(iface, &desc);
+
+ if ((rect->left < 0)
+ || (rect->top < 0)
+ || (rect->left >= rect->right)
+ || (rect->top >= rect->bottom)
+ || (rect->right > desc.Width)
+ || (rect->bottom > desc.Height))
+ {
+ WARN("Trying to lock an invalid rectangle, returning D3DERR_INVALIDCALL\n");
+ wined3d_mutex_unlock();
+
+ return D3DERR_INVALIDCALL;
+ }
+ }
+
+ hr = wined3d_surface_map(surface->wined3d_surface, &map_desc, rect, flags);
+ wined3d_mutex_unlock();
+
+ locked_rect->Pitch = map_desc.row_pitch;
+ locked_rect->pBits = map_desc.data;
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_surface_UnlockRect(IDirect3DSurface8 *iface)
+{
+ struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ hr = wined3d_surface_unmap(surface->wined3d_surface);
+ wined3d_mutex_unlock();
+
+ switch(hr)
+ {
+ case WINEDDERR_NOTLOCKED: return D3DERR_INVALIDCALL;
+ default: return hr;
+ }
+}
+
+static const IDirect3DSurface8Vtbl d3d8_surface_vtbl =
+{
+ /* IUnknown */
+ d3d8_surface_QueryInterface,
+ d3d8_surface_AddRef,
+ d3d8_surface_Release,
+ /* IDirect3DResource8 */
+ d3d8_surface_GetDevice,
+ d3d8_surface_SetPrivateData,
+ d3d8_surface_GetPrivateData,
+ d3d8_surface_FreePrivateData,
+ /* IDirect3DSurface8 */
+ d3d8_surface_GetContainer,
+ d3d8_surface_GetDesc,
+ d3d8_surface_LockRect,
+ d3d8_surface_UnlockRect,
+};
+
+static void STDMETHODCALLTYPE surface_wined3d_object_destroyed(void *parent)
+{
+ HeapFree(GetProcessHeap(), 0, parent);
+}
+
+static const struct wined3d_parent_ops d3d8_surface_wined3d_parent_ops =
+{
+ surface_wined3d_object_destroyed,
+};
+
+HRESULT surface_init(struct d3d8_surface *surface, struct d3d8_device *device, UINT width, UINT height,
+ D3DFORMAT format, DWORD flags, DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type,
+ DWORD multisample_quality)
+{
+ HRESULT hr;
+
+ surface->IDirect3DSurface8_iface.lpVtbl = &d3d8_surface_vtbl;
+ surface->refcount = 1;
+
+ /* FIXME: Check MAX bounds of MultisampleQuality. */
+ if (multisample_quality > 0)
+ {
+ FIXME("Multisample quality set to %u, substituting 0.\n", multisample_quality);
+ multisample_quality = 0;
+ }
+
+ wined3d_mutex_lock();
+ hr = wined3d_surface_create(device->wined3d_device, width, height, wined3dformat_from_d3dformat(format),
+ usage & WINED3DUSAGE_MASK, (enum wined3d_pool)pool, multisample_type, multisample_quality,
+ flags, surface, &d3d8_surface_wined3d_parent_ops, &surface->wined3d_surface);
+ wined3d_mutex_unlock();
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d surface, hr %#x.\n", hr);
+ return hr;
+ }
+
+ surface->parent_device = &device->IDirect3DDevice8_iface;
+ IDirect3DDevice8_AddRef(surface->parent_device);
+
+ return D3D_OK;
+}
+
+struct d3d8_surface *unsafe_impl_from_IDirect3DSurface8(IDirect3DSurface8 *iface)
+{
+ if (!iface)
+ return NULL;
+ assert(iface->lpVtbl == &d3d8_surface_vtbl);
+
+ return impl_from_IDirect3DSurface8(iface);
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/swapchain.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/swapchain.c
new file mode 100644
index 00000000..c172d5c1
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/swapchain.c
@@ -0,0 +1,208 @@
+/*
+ * IDirect3DSwapChain8 implementation
+ *
+ * Copyright 2005 Oliver Stieber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "d3d8_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
+
+static inline struct d3d8_swapchain *impl_from_IDirect3DSwapChain8(IDirect3DSwapChain8 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d8_swapchain, IDirect3DSwapChain8_iface);
+}
+
+static HRESULT WINAPI d3d8_swapchain_QueryInterface(IDirect3DSwapChain8 *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DSwapChain8)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DSwapChain8_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d8_swapchain_AddRef(IDirect3DSwapChain8 *iface)
+{
+ struct d3d8_swapchain *swapchain = impl_from_IDirect3DSwapChain8(iface);
+ ULONG ref = InterlockedIncrement(&swapchain->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, ref);
+
+ if (ref == 1)
+ {
+ if (swapchain->parent_device)
+ IDirect3DDevice8_AddRef(swapchain->parent_device);
+ wined3d_mutex_lock();
+ wined3d_swapchain_incref(swapchain->wined3d_swapchain);
+ wined3d_mutex_unlock();
+ }
+
+ return ref;
+}
+
+static ULONG WINAPI d3d8_swapchain_Release(IDirect3DSwapChain8 *iface)
+{
+ struct d3d8_swapchain *swapchain = impl_from_IDirect3DSwapChain8(iface);
+ ULONG ref = InterlockedDecrement(&swapchain->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, ref);
+
+ if (!ref)
+ {
+ IDirect3DDevice8 *parent_device = swapchain->parent_device;
+
+ wined3d_mutex_lock();
+ wined3d_swapchain_decref(swapchain->wined3d_swapchain);
+ wined3d_mutex_unlock();
+
+ if (parent_device)
+ IDirect3DDevice8_Release(parent_device);
+ }
+ return ref;
+}
+
+static HRESULT WINAPI d3d8_swapchain_Present(IDirect3DSwapChain8 *iface,
+ const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
+ const RGNDATA *dirty_region)
+{
+ struct d3d8_swapchain *swapchain = impl_from_IDirect3DSwapChain8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p.\n",
+ iface, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect), dst_window_override, dirty_region);
+
+ wined3d_mutex_lock();
+ hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, src_rect,
+ dst_rect, dst_window_override, dirty_region, 0);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_swapchain_GetBackBuffer(IDirect3DSwapChain8 *iface,
+ UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface8 **backbuffer)
+{
+ struct d3d8_swapchain *swapchain = impl_from_IDirect3DSwapChain8(iface);
+ struct wined3d_surface *wined3d_surface = NULL;
+ struct d3d8_surface *surface_impl;
+ HRESULT hr = D3D_OK;
+
+ TRACE("iface %p, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n",
+ iface, backbuffer_idx, backbuffer_type, backbuffer);
+
+ wined3d_mutex_lock();
+ if ((wined3d_surface = wined3d_swapchain_get_back_buffer(swapchain->wined3d_swapchain,
+ backbuffer_idx, (enum wined3d_backbuffer_type)backbuffer_type)))
+ {
+ surface_impl = wined3d_surface_get_parent(wined3d_surface);
+ *backbuffer = &surface_impl->IDirect3DSurface8_iface;
+ IDirect3DSurface8_AddRef(*backbuffer);
+ }
+ else
+ {
+ hr = D3DERR_INVALIDCALL;
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static const IDirect3DSwapChain8Vtbl d3d8_swapchain_vtbl =
+{
+ d3d8_swapchain_QueryInterface,
+ d3d8_swapchain_AddRef,
+ d3d8_swapchain_Release,
+ d3d8_swapchain_Present,
+ d3d8_swapchain_GetBackBuffer
+};
+
+static void STDMETHODCALLTYPE d3d8_swapchain_wined3d_object_released(void *parent)
+{
+ HeapFree(GetProcessHeap(), 0, parent);
+}
+
+static const struct wined3d_parent_ops d3d8_swapchain_wined3d_parent_ops =
+{
+ d3d8_swapchain_wined3d_object_released,
+};
+
+static HRESULT swapchain_init(struct d3d8_swapchain *swapchain, struct d3d8_device *device,
+ struct wined3d_swapchain_desc *desc)
+{
+ HRESULT hr;
+
+ swapchain->refcount = 1;
+ swapchain->IDirect3DSwapChain8_iface.lpVtbl = &d3d8_swapchain_vtbl;
+
+ wined3d_mutex_lock();
+ hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain,
+ &d3d8_swapchain_wined3d_parent_ops, &swapchain->wined3d_swapchain);
+ wined3d_mutex_unlock();
+
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d swapchain, hr %#x.\n", hr);
+ return hr;
+ }
+
+ swapchain->parent_device = &device->IDirect3DDevice8_iface;
+ IDirect3DDevice8_AddRef(swapchain->parent_device);
+
+ return D3D_OK;
+}
+
+HRESULT d3d8_swapchain_create(struct d3d8_device *device, struct wined3d_swapchain_desc *desc,
+ struct d3d8_swapchain **swapchain)
+{
+ struct d3d8_swapchain *object;
+ HRESULT hr;
+
+ if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+ return E_OUTOFMEMORY;
+
+ if (FAILED(hr = swapchain_init(object, device, desc)))
+ {
+ WARN("Failed to initialize swapchain, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created swapchain %p.\n", object);
+ *swapchain = object;
+
+ return D3D_OK;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/texture.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/texture.c
new file mode 100644
index 00000000..1a87636e
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/texture.c
@@ -0,0 +1,1308 @@
+/*
+ * Copyright 2005 Oliver Stieber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "d3d8_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
+
+static inline struct d3d8_texture *impl_from_IDirect3DTexture8(IDirect3DTexture8 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface);
+}
+
+static inline struct d3d8_texture *impl_from_IDirect3DCubeTexture8(IDirect3DCubeTexture8 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface);
+}
+
+static inline struct d3d8_texture *impl_from_IDirect3DVolumeTexture8(IDirect3DVolumeTexture8 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface);
+}
+
+static HRESULT WINAPI d3d8_texture_2d_QueryInterface(IDirect3DTexture8 *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DTexture8)
+ || IsEqualGUID(riid, &IID_IDirect3DBaseTexture8)
+ || IsEqualGUID(riid, &IID_IDirect3DResource8)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DTexture8_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d8_texture_2d_AddRef(IDirect3DTexture8 *iface)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
+ ULONG ref = InterlockedIncrement(&texture->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, ref);
+
+ if (ref == 1)
+ {
+ IDirect3DDevice8_AddRef(texture->parent_device);
+ wined3d_mutex_lock();
+ wined3d_texture_incref(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+ }
+
+ return ref;
+}
+
+static ULONG WINAPI d3d8_texture_2d_Release(IDirect3DTexture8 *iface)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
+ ULONG ref = InterlockedDecrement(&texture->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, ref);
+
+ if (!ref)
+ {
+ IDirect3DDevice8 *parent_device = texture->parent_device;
+
+ wined3d_mutex_lock();
+ wined3d_texture_decref(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ /* Release the device last, as it may cause the device to be destroyed. */
+ IDirect3DDevice8_Release(parent_device);
+ }
+ return ref;
+}
+
+static HRESULT WINAPI d3d8_texture_2d_GetDevice(IDirect3DTexture8 *iface, IDirect3DDevice8 **device)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ *device = texture->parent_device;
+ IDirect3DDevice8_AddRef(*device);
+
+ TRACE("Returning device %p.\n", *device);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_texture_2d_SetPrivateData(IDirect3DTexture8 *iface,
+ REFGUID guid, const void *data, DWORD data_size, DWORD flags)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
+ iface, debugstr_guid(guid), data, data_size, flags);
+
+ wined3d_mutex_lock();
+ resource = wined3d_texture_get_resource(texture->wined3d_texture);
+ hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_texture_2d_GetPrivateData(IDirect3DTexture8 *iface,
+ REFGUID guid, void *data, DWORD *data_size)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %p.\n",
+ iface, debugstr_guid(guid), data, data_size);
+
+ wined3d_mutex_lock();
+ resource = wined3d_texture_get_resource(texture->wined3d_texture);
+ hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_texture_2d_FreePrivateData(IDirect3DTexture8 *iface, REFGUID guid)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
+
+ wined3d_mutex_lock();
+ resource = wined3d_texture_get_resource(texture->wined3d_texture);
+ hr = wined3d_resource_free_private_data(resource, guid);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static DWORD WINAPI d3d8_texture_2d_SetPriority(IDirect3DTexture8 *iface, DWORD priority)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
+ DWORD ret;
+
+ TRACE("iface %p, priority %u.\n", iface, priority);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_set_priority(texture->wined3d_texture, priority);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static DWORD WINAPI d3d8_texture_2d_GetPriority(IDirect3DTexture8 *iface)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
+ DWORD ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_get_priority(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static void WINAPI d3d8_texture_2d_PreLoad(IDirect3DTexture8 *iface)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_texture_preload(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+}
+
+static D3DRESOURCETYPE WINAPI d3d8_texture_2d_GetType(IDirect3DTexture8 *iface)
+{
+ TRACE("iface %p.\n", iface);
+
+ return D3DRTYPE_TEXTURE;
+}
+
+static DWORD WINAPI d3d8_texture_2d_SetLOD(IDirect3DTexture8 *iface, DWORD lod)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
+ DWORD ret;
+
+ TRACE("iface %p, lod %u.\n", iface, lod);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static DWORD WINAPI d3d8_texture_2d_GetLOD(IDirect3DTexture8 *iface)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
+ DWORD ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_get_lod(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static DWORD WINAPI d3d8_texture_2d_GetLevelCount(IDirect3DTexture8 *iface)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
+ DWORD ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_get_level_count(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static HRESULT WINAPI d3d8_texture_2d_GetLevelDesc(IDirect3DTexture8 *iface, UINT level, D3DSURFACE_DESC *desc)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
+ struct wined3d_resource *sub_resource;
+ HRESULT hr = D3D_OK;
+
+ TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
+
+ wined3d_mutex_lock();
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+ hr = D3DERR_INVALIDCALL;
+ else
+ {
+ struct wined3d_resource_desc wined3d_desc;
+
+ wined3d_resource_get_desc(sub_resource, &wined3d_desc);
+ desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
+ desc->Type = wined3d_desc.resource_type;
+ desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
+ desc->Pool = wined3d_desc.pool;
+ desc->Size = wined3d_desc.size;
+ desc->MultiSampleType = wined3d_desc.multisample_type;
+ desc->Width = wined3d_desc.width;
+ desc->Height = wined3d_desc.height;
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_texture_2d_GetSurfaceLevel(IDirect3DTexture8 *iface,
+ UINT level, IDirect3DSurface8 **surface)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
+ struct wined3d_resource *sub_resource;
+ struct d3d8_surface *surface_impl;
+
+ TRACE("iface %p, level %u, surface %p.\n", iface, level, surface);
+
+ wined3d_mutex_lock();
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+ {
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
+
+ surface_impl = wined3d_resource_get_parent(sub_resource);
+ *surface = &surface_impl->IDirect3DSurface8_iface;
+ IDirect3DSurface8_AddRef(*surface);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_texture_2d_LockRect(IDirect3DTexture8 *iface, UINT level,
+ D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
+ struct wined3d_resource *sub_resource;
+ struct d3d8_surface *surface_impl;
+ HRESULT hr;
+
+ TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#x.\n",
+ iface, level, locked_rect, rect, flags);
+
+ wined3d_mutex_lock();
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+ hr = D3DERR_INVALIDCALL;
+ else
+ {
+ surface_impl = wined3d_resource_get_parent(sub_resource);
+ hr = IDirect3DSurface8_LockRect(&surface_impl->IDirect3DSurface8_iface, locked_rect, rect, flags);
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_texture_2d_UnlockRect(IDirect3DTexture8 *iface, UINT level)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
+ struct wined3d_resource *sub_resource;
+ struct d3d8_surface *surface_impl;
+ HRESULT hr;
+
+ TRACE("iface %p, level %u.\n", iface, level);
+
+ wined3d_mutex_lock();
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+ hr = D3DERR_INVALIDCALL;
+ else
+ {
+ surface_impl = wined3d_resource_get_parent(sub_resource);
+ hr = IDirect3DSurface8_UnlockRect(&surface_impl->IDirect3DSurface8_iface);
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_texture_2d_AddDirtyRect(IDirect3DTexture8 *iface, const RECT *dirty_rect)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, dirty_rect %s.\n",
+ iface, wine_dbgstr_rect(dirty_rect));
+
+ wined3d_mutex_lock();
+ if (!dirty_rect)
+ hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, NULL);
+ else
+ {
+ struct wined3d_box dirty_region;
+
+ dirty_region.left = dirty_rect->left;
+ dirty_region.top = dirty_rect->top;
+ dirty_region.right = dirty_rect->right;
+ dirty_region.bottom = dirty_rect->bottom;
+ dirty_region.front = 0;
+ dirty_region.back = 1;
+ hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, &dirty_region);
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static const IDirect3DTexture8Vtbl Direct3DTexture8_Vtbl =
+{
+ /* IUnknown */
+ d3d8_texture_2d_QueryInterface,
+ d3d8_texture_2d_AddRef,
+ d3d8_texture_2d_Release,
+ /* IDirect3DResource8 */
+ d3d8_texture_2d_GetDevice,
+ d3d8_texture_2d_SetPrivateData,
+ d3d8_texture_2d_GetPrivateData,
+ d3d8_texture_2d_FreePrivateData,
+ d3d8_texture_2d_SetPriority,
+ d3d8_texture_2d_GetPriority,
+ d3d8_texture_2d_PreLoad,
+ d3d8_texture_2d_GetType,
+ /* IDirect3dBaseTexture8 */
+ d3d8_texture_2d_SetLOD,
+ d3d8_texture_2d_GetLOD,
+ d3d8_texture_2d_GetLevelCount,
+ /* IDirect3DTexture8 */
+ d3d8_texture_2d_GetLevelDesc,
+ d3d8_texture_2d_GetSurfaceLevel,
+ d3d8_texture_2d_LockRect,
+ d3d8_texture_2d_UnlockRect,
+ d3d8_texture_2d_AddDirtyRect,
+};
+
+static HRESULT WINAPI d3d8_texture_cube_QueryInterface(IDirect3DCubeTexture8 *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DCubeTexture8)
+ || IsEqualGUID(riid, &IID_IDirect3DBaseTexture8)
+ || IsEqualGUID(riid, &IID_IDirect3DResource8)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DCubeTexture8_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d8_texture_cube_AddRef(IDirect3DCubeTexture8 *iface)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
+ ULONG ref = InterlockedIncrement(&texture->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, ref);
+
+ if (ref == 1)
+ {
+ IDirect3DDevice8_AddRef(texture->parent_device);
+ wined3d_mutex_lock();
+ wined3d_texture_incref(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+ }
+
+ return ref;
+}
+
+static ULONG WINAPI d3d8_texture_cube_Release(IDirect3DCubeTexture8 *iface)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
+ ULONG ref = InterlockedDecrement(&texture->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, ref);
+
+ if (!ref)
+ {
+ IDirect3DDevice8 *parent_device = texture->parent_device;
+
+ TRACE("Releasing child %p.\n", texture->wined3d_texture);
+
+ wined3d_mutex_lock();
+ wined3d_texture_decref(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ /* Release the device last, as it may cause the device to be destroyed. */
+ IDirect3DDevice8_Release(parent_device);
+ }
+ return ref;
+}
+
+static HRESULT WINAPI d3d8_texture_cube_GetDevice(IDirect3DCubeTexture8 *iface, IDirect3DDevice8 **device)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ *device = texture->parent_device;
+ IDirect3DDevice8_AddRef(*device);
+
+ TRACE("Returning device %p.\n", *device);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_texture_cube_SetPrivateData(IDirect3DCubeTexture8 *iface,
+ REFGUID guid, const void *data, DWORD data_size, DWORD flags)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
+ iface, debugstr_guid(guid), data, data_size, flags);
+
+ wined3d_mutex_lock();
+ resource = wined3d_texture_get_resource(texture->wined3d_texture);
+ hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_texture_cube_GetPrivateData(IDirect3DCubeTexture8 *iface,
+ REFGUID guid, void *data, DWORD *data_size)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %p.\n",
+ iface, debugstr_guid(guid), data, data_size);
+
+ wined3d_mutex_lock();
+ resource = wined3d_texture_get_resource(texture->wined3d_texture);
+ hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_texture_cube_FreePrivateData(IDirect3DCubeTexture8 *iface, REFGUID guid)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
+
+ wined3d_mutex_lock();
+ resource = wined3d_texture_get_resource(texture->wined3d_texture);
+ hr = wined3d_resource_free_private_data(resource, guid);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static DWORD WINAPI d3d8_texture_cube_SetPriority(IDirect3DCubeTexture8 *iface, DWORD priority)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
+ DWORD ret;
+
+ TRACE("iface %p, priority %u.\n", iface, priority);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_set_priority(texture->wined3d_texture, priority);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static DWORD WINAPI d3d8_texture_cube_GetPriority(IDirect3DCubeTexture8 *iface)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
+ DWORD ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_get_priority(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static void WINAPI d3d8_texture_cube_PreLoad(IDirect3DCubeTexture8 *iface)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_texture_preload(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+}
+
+static D3DRESOURCETYPE WINAPI d3d8_texture_cube_GetType(IDirect3DCubeTexture8 *iface)
+{
+ TRACE("iface %p.\n", iface);
+
+ return D3DRTYPE_CUBETEXTURE;
+}
+
+static DWORD WINAPI d3d8_texture_cube_SetLOD(IDirect3DCubeTexture8 *iface, DWORD lod)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
+ DWORD ret;
+
+ TRACE("iface %p, lod %u.\n", iface, lod);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static DWORD WINAPI d3d8_texture_cube_GetLOD(IDirect3DCubeTexture8 *iface)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
+ DWORD ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_get_lod(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static DWORD WINAPI d3d8_texture_cube_GetLevelCount(IDirect3DCubeTexture8 *iface)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
+ DWORD ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_get_level_count(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static HRESULT WINAPI d3d8_texture_cube_GetLevelDesc(IDirect3DCubeTexture8 *iface, UINT level, D3DSURFACE_DESC *desc)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
+ struct wined3d_resource *sub_resource;
+ HRESULT hr = D3D_OK;
+
+ TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
+
+ wined3d_mutex_lock();
+ if (level >= wined3d_texture_get_level_count(texture->wined3d_texture))
+ {
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
+
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+ hr = D3DERR_INVALIDCALL;
+ else
+ {
+ struct wined3d_resource_desc wined3d_desc;
+
+ wined3d_resource_get_desc(sub_resource, &wined3d_desc);
+ desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
+ desc->Type = wined3d_desc.resource_type;
+ desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
+ desc->Pool = wined3d_desc.pool;
+ desc->Size = wined3d_desc.size;
+ desc->MultiSampleType = wined3d_desc.multisample_type;
+ desc->Width = wined3d_desc.width;
+ desc->Height = wined3d_desc.height;
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture8 *iface,
+ D3DCUBEMAP_FACES face, UINT level, IDirect3DSurface8 **surface)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
+ struct wined3d_resource *sub_resource;
+ struct d3d8_surface *surface_impl;
+ UINT sub_resource_idx;
+ DWORD level_count;
+
+ TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, face, level, surface);
+
+ wined3d_mutex_lock();
+ level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
+ if (level >= level_count)
+ {
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
+
+ sub_resource_idx = level_count * face + level;
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx)))
+ {
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
+
+ surface_impl = wined3d_resource_get_parent(sub_resource);
+ *surface = &surface_impl->IDirect3DSurface8_iface;
+ IDirect3DSurface8_AddRef(*surface);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_texture_cube_LockRect(IDirect3DCubeTexture8 *iface,
+ D3DCUBEMAP_FACES face, UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect,
+ DWORD flags)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
+ struct wined3d_resource *sub_resource;
+ struct d3d8_surface *surface_impl;
+ UINT sub_resource_idx;
+ HRESULT hr;
+
+ TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#x.\n",
+ iface, face, level, locked_rect, rect, flags);
+
+ wined3d_mutex_lock();
+ sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx)))
+ hr = D3DERR_INVALIDCALL;
+ else
+ {
+ surface_impl = wined3d_resource_get_parent(sub_resource);
+ hr = IDirect3DSurface8_LockRect(&surface_impl->IDirect3DSurface8_iface, locked_rect, rect, flags);
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_texture_cube_UnlockRect(IDirect3DCubeTexture8 *iface,
+ D3DCUBEMAP_FACES face, UINT level)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
+ struct wined3d_resource *sub_resource;
+ struct d3d8_surface *surface_impl;
+ UINT sub_resource_idx;
+ HRESULT hr;
+
+ TRACE("iface %p, face %#x, level %u.\n", iface, face, level);
+
+ wined3d_mutex_lock();
+ sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx)))
+ hr = D3DERR_INVALIDCALL;
+ else
+ {
+ surface_impl = wined3d_resource_get_parent(sub_resource);
+ hr = IDirect3DSurface8_UnlockRect(&surface_impl->IDirect3DSurface8_iface);
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_texture_cube_AddDirtyRect(IDirect3DCubeTexture8 *iface,
+ D3DCUBEMAP_FACES face, const RECT *dirty_rect)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, face %#x, dirty_rect %s.\n",
+ iface, face, wine_dbgstr_rect(dirty_rect));
+
+ wined3d_mutex_lock();
+ if (!dirty_rect)
+ hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, NULL);
+ else
+ {
+ struct wined3d_box dirty_region;
+
+ dirty_region.left = dirty_rect->left;
+ dirty_region.top = dirty_rect->top;
+ dirty_region.right = dirty_rect->right;
+ dirty_region.bottom = dirty_rect->bottom;
+ dirty_region.front = 0;
+ dirty_region.back = 1;
+ hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, &dirty_region);
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static const IDirect3DCubeTexture8Vtbl Direct3DCubeTexture8_Vtbl =
+{
+ /* IUnknown */
+ d3d8_texture_cube_QueryInterface,
+ d3d8_texture_cube_AddRef,
+ d3d8_texture_cube_Release,
+ /* IDirect3DResource8 */
+ d3d8_texture_cube_GetDevice,
+ d3d8_texture_cube_SetPrivateData,
+ d3d8_texture_cube_GetPrivateData,
+ d3d8_texture_cube_FreePrivateData,
+ d3d8_texture_cube_SetPriority,
+ d3d8_texture_cube_GetPriority,
+ d3d8_texture_cube_PreLoad,
+ d3d8_texture_cube_GetType,
+ /* IDirect3DBaseTexture8 */
+ d3d8_texture_cube_SetLOD,
+ d3d8_texture_cube_GetLOD,
+ d3d8_texture_cube_GetLevelCount,
+ /* IDirect3DCubeTexture8 */
+ d3d8_texture_cube_GetLevelDesc,
+ d3d8_texture_cube_GetCubeMapSurface,
+ d3d8_texture_cube_LockRect,
+ d3d8_texture_cube_UnlockRect,
+ d3d8_texture_cube_AddDirtyRect,
+};
+
+static HRESULT WINAPI d3d8_texture_3d_QueryInterface(IDirect3DVolumeTexture8 *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DVolumeTexture8)
+ || IsEqualGUID(riid, &IID_IDirect3DBaseTexture8)
+ || IsEqualGUID(riid, &IID_IDirect3DResource8)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DVolumeTexture8_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d8_texture_3d_AddRef(IDirect3DVolumeTexture8 *iface)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
+ ULONG ref = InterlockedIncrement(&texture->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, ref);
+
+ if (ref == 1)
+ {
+ IDirect3DDevice8_AddRef(texture->parent_device);
+ wined3d_mutex_lock();
+ wined3d_texture_incref(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+ }
+
+ return ref;
+}
+
+static ULONG WINAPI d3d8_texture_3d_Release(IDirect3DVolumeTexture8 *iface)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
+ ULONG ref = InterlockedDecrement(&texture->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, ref);
+
+ if (!ref)
+ {
+ IDirect3DDevice8 *parent_device = texture->parent_device;
+
+ wined3d_mutex_lock();
+ wined3d_texture_decref(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ /* Release the device last, as it may cause the device to be destroyed. */
+ IDirect3DDevice8_Release(parent_device);
+ }
+ return ref;
+}
+
+static HRESULT WINAPI d3d8_texture_3d_GetDevice(IDirect3DVolumeTexture8 *iface, IDirect3DDevice8 **device)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ *device = texture->parent_device;
+ IDirect3DDevice8_AddRef(*device);
+
+ TRACE("Returning device %p.\n", *device);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_texture_3d_SetPrivateData(IDirect3DVolumeTexture8 *iface,
+ REFGUID guid, const void *data, DWORD data_size, DWORD flags)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
+ iface, debugstr_guid(guid), data, data_size, flags);
+
+ wined3d_mutex_lock();
+ resource = wined3d_texture_get_resource(texture->wined3d_texture);
+ hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_texture_3d_GetPrivateData(IDirect3DVolumeTexture8 *iface,
+ REFGUID guid, void *data, DWORD *data_size)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %p.\n",
+ iface, debugstr_guid(guid), data, data_size);
+
+ wined3d_mutex_lock();
+ resource = wined3d_texture_get_resource(texture->wined3d_texture);
+ hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_texture_3d_FreePrivateData(IDirect3DVolumeTexture8 *iface, REFGUID guid)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
+
+ wined3d_mutex_lock();
+ resource = wined3d_texture_get_resource(texture->wined3d_texture);
+ hr = wined3d_resource_free_private_data(resource, guid);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static DWORD WINAPI d3d8_texture_3d_SetPriority(IDirect3DVolumeTexture8 *iface, DWORD priority)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
+ DWORD ret;
+
+ TRACE("iface %p, priority %u.\n", iface, priority);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_set_priority(texture->wined3d_texture, priority);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static DWORD WINAPI d3d8_texture_3d_GetPriority(IDirect3DVolumeTexture8 *iface)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
+ DWORD ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_get_priority(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static void WINAPI d3d8_texture_3d_PreLoad(IDirect3DVolumeTexture8 *iface)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_texture_preload(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+}
+
+static D3DRESOURCETYPE WINAPI d3d8_texture_3d_GetType(IDirect3DVolumeTexture8 *iface)
+{
+ TRACE("iface %p.\n", iface);
+
+ return D3DRTYPE_VOLUMETEXTURE;
+}
+
+static DWORD WINAPI d3d8_texture_3d_SetLOD(IDirect3DVolumeTexture8 *iface, DWORD lod)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
+ DWORD ret;
+
+ TRACE("iface %p, lod %u.\n", iface, lod);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static DWORD WINAPI d3d8_texture_3d_GetLOD(IDirect3DVolumeTexture8 *iface)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
+ DWORD ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_get_lod(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static DWORD WINAPI d3d8_texture_3d_GetLevelCount(IDirect3DVolumeTexture8 *iface)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
+ DWORD ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_get_level_count(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static HRESULT WINAPI d3d8_texture_3d_GetLevelDesc(IDirect3DVolumeTexture8 *iface, UINT level, D3DVOLUME_DESC *desc)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
+ struct wined3d_resource *sub_resource;
+ HRESULT hr = D3D_OK;
+
+ TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
+
+ wined3d_mutex_lock();
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+ hr = D3DERR_INVALIDCALL;
+ else
+ {
+ struct wined3d_resource_desc wined3d_desc;
+
+ wined3d_resource_get_desc(sub_resource, &wined3d_desc);
+ desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
+ desc->Type = wined3d_desc.resource_type;
+ desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
+ desc->Pool = wined3d_desc.pool;
+ desc->Size = wined3d_desc.size;
+ desc->Width = wined3d_desc.width;
+ desc->Height = wined3d_desc.height;
+ desc->Depth = wined3d_desc.depth;
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture8 *iface,
+ UINT level, IDirect3DVolume8 **volume)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
+ struct wined3d_resource *sub_resource;
+ struct d3d8_volume *volume_impl;
+
+ TRACE("iface %p, level %u, volume %p.\n", iface, level, volume);
+
+ wined3d_mutex_lock();
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+ {
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
+
+ volume_impl = wined3d_resource_get_parent(sub_resource);
+ *volume = &volume_impl->IDirect3DVolume8_iface;
+ IDirect3DVolume8_AddRef(*volume);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_texture_3d_LockBox(IDirect3DVolumeTexture8 *iface,
+ UINT level, D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
+ struct wined3d_resource *sub_resource;
+ struct d3d8_volume *volume_impl;
+ HRESULT hr;
+
+ TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n",
+ iface, level, locked_box, box, flags);
+
+ wined3d_mutex_lock();
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+ hr = D3DERR_INVALIDCALL;
+ else
+ {
+ volume_impl = wined3d_resource_get_parent(sub_resource);
+ hr = IDirect3DVolume8_LockBox(&volume_impl->IDirect3DVolume8_iface, locked_box, box, flags);
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_texture_3d_UnlockBox(IDirect3DVolumeTexture8 *iface, UINT level)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
+ struct wined3d_resource *sub_resource;
+ struct d3d8_volume *volume_impl;
+ HRESULT hr;
+
+ TRACE("iface %p, level %u.\n", iface, level);
+
+ wined3d_mutex_lock();
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+ hr = D3DERR_INVALIDCALL;
+ else
+ {
+ volume_impl = wined3d_resource_get_parent(sub_resource);
+ hr = IDirect3DVolume8_UnlockBox(&volume_impl->IDirect3DVolume8_iface);
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_texture_3d_AddDirtyBox(IDirect3DVolumeTexture8 *iface, const D3DBOX *dirty_box)
+{
+ struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, dirty_box %p.\n", iface, dirty_box);
+
+ wined3d_mutex_lock();
+ hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, (const struct wined3d_box *)dirty_box);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static const IDirect3DVolumeTexture8Vtbl Direct3DVolumeTexture8_Vtbl =
+{
+ /* IUnknown */
+ d3d8_texture_3d_QueryInterface,
+ d3d8_texture_3d_AddRef,
+ d3d8_texture_3d_Release,
+ /* IDirect3DResource8 */
+ d3d8_texture_3d_GetDevice,
+ d3d8_texture_3d_SetPrivateData,
+ d3d8_texture_3d_GetPrivateData,
+ d3d8_texture_3d_FreePrivateData,
+ d3d8_texture_3d_SetPriority,
+ d3d8_texture_3d_GetPriority,
+ d3d8_texture_3d_PreLoad,
+ d3d8_texture_3d_GetType,
+ /* IDirect3DBaseTexture8 */
+ d3d8_texture_3d_SetLOD,
+ d3d8_texture_3d_GetLOD,
+ d3d8_texture_3d_GetLevelCount,
+ /* IDirect3DVolumeTexture8 */
+ d3d8_texture_3d_GetLevelDesc,
+ d3d8_texture_3d_GetVolumeLevel,
+ d3d8_texture_3d_LockBox,
+ d3d8_texture_3d_UnlockBox,
+ d3d8_texture_3d_AddDirtyBox
+};
+
+struct d3d8_texture *unsafe_impl_from_IDirect3DBaseTexture8(IDirect3DBaseTexture8 *iface)
+{
+ if (!iface)
+ return NULL;
+
+ /* SetTexture() in particular doesn't do a lot of validation on the pointer
+ * that gets passed in, and passing an invalid pointer works as long as the
+ * application doesn't try to actually render anything with it, so we print
+ * a WARN and return NULL instead of having the usual assert() here.
+ * One application affected by this is Fishdom 2. */
+ if (iface->lpVtbl != (const IDirect3DBaseTexture8Vtbl *)&Direct3DTexture8_Vtbl
+ && iface->lpVtbl != (const IDirect3DBaseTexture8Vtbl *)&Direct3DCubeTexture8_Vtbl
+ && iface->lpVtbl != (const IDirect3DBaseTexture8Vtbl *)&Direct3DVolumeTexture8_Vtbl)
+ {
+ WARN("%p is not a valid IDirect3DBaseTexture8 interface.\n", iface);
+ return NULL;
+ }
+
+ return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface);
+}
+
+static void STDMETHODCALLTYPE d3d8_texture_wined3d_object_destroyed(void *parent)
+{
+ HeapFree(GetProcessHeap(), 0, parent);
+}
+
+static const struct wined3d_parent_ops d3d8_texture_wined3d_parent_ops =
+{
+ d3d8_texture_wined3d_object_destroyed,
+};
+
+HRESULT texture_init(struct d3d8_texture *texture, struct d3d8_device *device,
+ UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
+{
+ struct wined3d_resource_desc desc;
+ DWORD surface_flags = 0;
+ HRESULT hr;
+
+ texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DTexture8_Vtbl;
+ texture->refcount = 1;
+
+ desc.resource_type = WINED3D_RTYPE_TEXTURE;
+ desc.format = wined3dformat_from_d3dformat(format);
+ desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
+ desc.multisample_quality = 0;
+ desc.usage = usage & WINED3DUSAGE_MASK;
+ desc.pool = pool;
+ desc.width = width;
+ desc.height = height;
+ desc.depth = 1;
+ desc.size = 0;
+
+ if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
+ surface_flags |= WINED3D_SURFACE_MAPPABLE;
+
+ wined3d_mutex_lock();
+ hr = wined3d_texture_create_2d(device->wined3d_device, &desc, levels, surface_flags,
+ texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
+ wined3d_mutex_unlock();
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d texture, hr %#x.\n", hr);
+ return hr;
+ }
+
+ texture->parent_device = &device->IDirect3DDevice8_iface;
+ IDirect3DDevice8_AddRef(texture->parent_device);
+
+ return D3D_OK;
+}
+
+HRESULT cubetexture_init(struct d3d8_texture *texture, struct d3d8_device *device,
+ UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
+{
+ struct wined3d_resource_desc desc;
+ DWORD surface_flags = 0;
+ HRESULT hr;
+
+ texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DCubeTexture8_Vtbl;
+ texture->refcount = 1;
+
+ desc.resource_type = WINED3D_RTYPE_CUBE_TEXTURE;
+ desc.format = wined3dformat_from_d3dformat(format);
+ desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
+ desc.multisample_quality = 0;
+ desc.usage = usage & WINED3DUSAGE_MASK;
+ desc.pool = pool;
+ desc.width = edge_length;
+ desc.height = edge_length;
+ desc.depth = 1;
+ desc.size = 0;
+
+ if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
+ surface_flags |= WINED3D_SURFACE_MAPPABLE;
+
+ wined3d_mutex_lock();
+ hr = wined3d_texture_create_cube(device->wined3d_device, &desc, levels, surface_flags,
+ texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
+ wined3d_mutex_unlock();
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d cube texture, hr %#x.\n", hr);
+ return hr;
+ }
+
+ texture->parent_device = &device->IDirect3DDevice8_iface;
+ IDirect3DDevice8_AddRef(texture->parent_device);
+
+ return D3D_OK;
+}
+
+HRESULT volumetexture_init(struct d3d8_texture *texture, struct d3d8_device *device,
+ UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
+{
+ struct wined3d_resource_desc desc;
+ HRESULT hr;
+
+ texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DVolumeTexture8_Vtbl;
+ texture->refcount = 1;
+
+ desc.resource_type = WINED3D_RTYPE_VOLUME_TEXTURE;
+ desc.format = wined3dformat_from_d3dformat(format);
+ desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
+ desc.multisample_quality = 0;
+ desc.usage = usage & WINED3DUSAGE_MASK;
+ desc.pool = pool;
+ desc.width = width;
+ desc.height = height;
+ desc.depth = depth;
+ desc.size = 0;
+
+ wined3d_mutex_lock();
+ hr = wined3d_texture_create_3d(device->wined3d_device, &desc, levels,
+ texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
+ wined3d_mutex_unlock();
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d volume texture, hr %#x.\n", hr);
+ return hr;
+ }
+
+ texture->parent_device = &device->IDirect3DDevice8_iface;
+ IDirect3DDevice8_AddRef(texture->parent_device);
+
+ return D3D_OK;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/version.rc b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/version.rc
new file mode 100644
index 00000000..c30a7b17
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/version.rc
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2001 Ove Kaaven
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#define WINE_FILEDESCRIPTION_STR "Wine Direct3D"
+#define WINE_FILENAME_STR "d3d8.dll"
+#define WINE_FILEVERSION 5,3,1,904
+#define WINE_FILEVERSION_STR "5.3.1.904"
+#define WINE_PRODUCTVERSION 5,3,1,904
+#define WINE_PRODUCTVERSION_STR "5.3.1.904"
+
+#include "wine/wine_common_ver.rc"
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/vertexdeclaration.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/vertexdeclaration.c
new file mode 100644
index 00000000..9934ca39
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/vertexdeclaration.c
@@ -0,0 +1,400 @@
+/*
+ * IDirect3DVertexDeclaration8 implementation
+ *
+ * Copyright 2007 Henri Verbeet
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+/* IDirect3DVertexDeclaration8 is internal to our implementation.
+ * It's not visible in the API. */
+
+#include "config.h"
+#include "d3d8_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
+
+#ifdef VBOX_WINE_WITHOUT_LIBWINE
+typedef DWORD D3DVSDT_TYPE;
+typedef DWORD D3DVSDE_REGISTER;
+#endif
+
+static const char *debug_d3dvsdt_type(D3DVSDT_TYPE d3dvsdt_type)
+{
+ switch (d3dvsdt_type)
+ {
+#define D3DVSDT_TYPE_TO_STR(u) case u: return #u
+ D3DVSDT_TYPE_TO_STR(D3DVSDT_FLOAT1);
+ D3DVSDT_TYPE_TO_STR(D3DVSDT_FLOAT2);
+ D3DVSDT_TYPE_TO_STR(D3DVSDT_FLOAT3);
+ D3DVSDT_TYPE_TO_STR(D3DVSDT_FLOAT4);
+ D3DVSDT_TYPE_TO_STR(D3DVSDT_D3DCOLOR);
+ D3DVSDT_TYPE_TO_STR(D3DVSDT_UBYTE4);
+ D3DVSDT_TYPE_TO_STR(D3DVSDT_SHORT2);
+ D3DVSDT_TYPE_TO_STR(D3DVSDT_SHORT4);
+#undef D3DVSDT_TYPE_TO_STR
+ default:
+ FIXME("Unrecognized D3DVSDT_TYPE %#x\n", d3dvsdt_type);
+ return "unrecognized";
+ }
+}
+
+static const char *debug_d3dvsde_register(D3DVSDE_REGISTER d3dvsde_register)
+{
+ switch (d3dvsde_register)
+ {
+#define D3DVSDE_REGISTER_TO_STR(u) case u: return #u
+ D3DVSDE_REGISTER_TO_STR(D3DVSDE_POSITION);
+ D3DVSDE_REGISTER_TO_STR(D3DVSDE_BLENDWEIGHT);
+ D3DVSDE_REGISTER_TO_STR(D3DVSDE_BLENDINDICES);
+ D3DVSDE_REGISTER_TO_STR(D3DVSDE_NORMAL);
+ D3DVSDE_REGISTER_TO_STR(D3DVSDE_PSIZE);
+ D3DVSDE_REGISTER_TO_STR(D3DVSDE_DIFFUSE);
+ D3DVSDE_REGISTER_TO_STR(D3DVSDE_SPECULAR);
+ D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD0);
+ D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD1);
+ D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD2);
+ D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD3);
+ D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD4);
+ D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD5);
+ D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD6);
+ D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD7);
+ D3DVSDE_REGISTER_TO_STR(D3DVSDE_POSITION2);
+ D3DVSDE_REGISTER_TO_STR(D3DVSDE_NORMAL2);
+#undef D3DVSDE_REGISTER_TO_STR
+ default:
+ FIXME("Unrecognized D3DVSDE_REGISTER %#x\n", d3dvsde_register);
+ return "unrecognized";
+ }
+}
+
+size_t parse_token(const DWORD* pToken)
+{
+ const DWORD token = *pToken;
+ size_t tokenlen = 1;
+
+ switch ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT) { /* maybe a macro to inverse ... */
+ case D3DVSD_TOKEN_NOP:
+ TRACE(" 0x%08x NOP()\n", token);
+ break;
+
+ case D3DVSD_TOKEN_STREAM:
+ if (token & D3DVSD_STREAMTESSMASK)
+ {
+ TRACE(" 0x%08x STREAM_TESS()\n", token);
+ } else {
+ TRACE(" 0x%08x STREAM(%u)\n", token, ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT));
+ }
+ break;
+
+ case D3DVSD_TOKEN_STREAMDATA:
+ if (token & 0x10000000)
+ {
+ TRACE(" 0x%08x SKIP(%u)\n", token, ((token & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT));
+ } else {
+ DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
+ DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
+ TRACE(" 0x%08x REG(%s, %s)\n", token, debug_d3dvsde_register(reg), debug_d3dvsdt_type(type));
+ }
+ break;
+
+ case D3DVSD_TOKEN_TESSELLATOR:
+ if (token & 0x10000000)
+ {
+ DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
+ DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
+ TRACE(" 0x%08x TESSUV(%s) as %s\n", token, debug_d3dvsde_register(reg), debug_d3dvsdt_type(type));
+ } else {
+ DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
+ DWORD regout = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
+ DWORD regin = ((token & D3DVSD_VERTEXREGINMASK) >> D3DVSD_VERTEXREGINSHIFT);
+ TRACE(" 0x%08x TESSNORMAL(%s, %s) as %s\n", token, debug_d3dvsde_register(regin),
+ debug_d3dvsde_register(regout), debug_d3dvsdt_type(type));
+ }
+ break;
+
+ case D3DVSD_TOKEN_CONSTMEM:
+ {
+ DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT);
+ tokenlen = (4 * count) + 1;
+ }
+ break;
+
+ case D3DVSD_TOKEN_EXT:
+ {
+ DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT);
+ DWORD extinfo = ((token & D3DVSD_EXTINFOMASK) >> D3DVSD_EXTINFOSHIFT);
+ TRACE(" 0x%08x EXT(%u, %u)\n", token, count, extinfo);
+ /* todo ... print extension */
+ tokenlen = count + 1;
+ }
+ break;
+
+ case D3DVSD_TOKEN_END:
+ TRACE(" 0x%08x END()\n", token);
+ break;
+
+ default:
+ TRACE(" 0x%08x UNKNOWN\n", token);
+ /* arg error */
+ }
+
+ return tokenlen;
+}
+
+void load_local_constants(const DWORD *d3d8_elements, struct wined3d_shader *wined3d_vertex_shader)
+{
+ const DWORD *token = d3d8_elements;
+
+ while (*token != D3DVSD_END())
+ {
+ if (((*token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT) == D3DVSD_TOKEN_CONSTMEM)
+ {
+ DWORD count = ((*token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT);
+ DWORD constant_idx = ((*token & D3DVSD_CONSTADDRESSMASK) >> D3DVSD_CONSTADDRESSSHIFT);
+ HRESULT hr;
+
+ if (TRACE_ON(d3d8))
+ {
+ DWORD i;
+ for (i = 0; i < count; ++i)
+ {
+ TRACE("c[%u] = (%8f, %8f, %8f, %8f)\n",
+ constant_idx,
+ *(const float *)(token + i * 4 + 1),
+ *(const float *)(token + i * 4 + 2),
+ *(const float *)(token + i * 4 + 3),
+ *(const float *)(token + i * 4 + 4));
+ }
+ }
+ hr = wined3d_shader_set_local_constants_float(wined3d_vertex_shader,
+ constant_idx, (const float *)token + 1, count);
+ if (FAILED(hr)) ERR("Failed setting shader constants\n");
+ }
+
+ token += parse_token(token);
+ }
+}
+
+/* NOTE: Make sure these are in the correct numerical order. (see /include/wined3d_types.h) */
+static const size_t wined3d_type_sizes[] =
+{
+ /*WINED3DDECLTYPE_FLOAT1*/ 1 * sizeof(float),
+ /*WINED3DDECLTYPE_FLOAT2*/ 2 * sizeof(float),
+ /*WINED3DDECLTYPE_FLOAT3*/ 3 * sizeof(float),
+ /*WINED3DDECLTYPE_FLOAT4*/ 4 * sizeof(float),
+ /*WINED3DDECLTYPE_D3DCOLOR*/ 4 * sizeof(BYTE),
+ /*WINED3DDECLTYPE_UBYTE4*/ 4 * sizeof(BYTE),
+ /*WINED3DDECLTYPE_SHORT2*/ 2 * sizeof(short int),
+ /*WINED3DDECLTYPE_SHORT4*/ 4 * sizeof(short int),
+ /*WINED3DDECLTYPE_UBYTE4N*/ 4 * sizeof(BYTE),
+ /*WINED3DDECLTYPE_SHORT2N*/ 2 * sizeof(short int),
+ /*WINED3DDECLTYPE_SHORT4N*/ 4 * sizeof(short int),
+ /*WINED3DDECLTYPE_USHORT2N*/ 2 * sizeof(short int),
+ /*WINED3DDECLTYPE_USHORT4N*/ 4 * sizeof(short int),
+ /*WINED3DDECLTYPE_UDEC3*/ 3 * sizeof(short int),
+ /*WINED3DDECLTYPE_DEC3N*/ 3 * sizeof(short int),
+ /*WINED3DDECLTYPE_FLOAT16_2*/ 2 * sizeof(short int),
+ /*WINED3DDECLTYPE_FLOAT16_4*/ 4 * sizeof(short int)
+};
+
+static const enum wined3d_format_id wined3d_format_lookup[] =
+{
+ /*WINED3DDECLTYPE_FLOAT1*/ WINED3DFMT_R32_FLOAT,
+ /*WINED3DDECLTYPE_FLOAT2*/ WINED3DFMT_R32G32_FLOAT,
+ /*WINED3DDECLTYPE_FLOAT3*/ WINED3DFMT_R32G32B32_FLOAT,
+ /*WINED3DDECLTYPE_FLOAT4*/ WINED3DFMT_R32G32B32A32_FLOAT,
+ /*WINED3DDECLTYPE_D3DCOLOR*/ WINED3DFMT_B8G8R8A8_UNORM,
+ /*WINED3DDECLTYPE_UBYTE4*/ WINED3DFMT_R8G8B8A8_UINT,
+ /*WINED3DDECLTYPE_SHORT2*/ WINED3DFMT_R16G16_SINT,
+ /*WINED3DDECLTYPE_SHORT4*/ WINED3DFMT_R16G16B16A16_SINT,
+ /*WINED3DDECLTYPE_UBYTE4N*/ WINED3DFMT_R8G8B8A8_UNORM,
+ /*WINED3DDECLTYPE_SHORT2N*/ WINED3DFMT_R16G16_SNORM,
+ /*WINED3DDECLTYPE_SHORT4N*/ WINED3DFMT_R16G16B16A16_SNORM,
+ /*WINED3DDECLTYPE_USHORT2N*/ WINED3DFMT_R16G16_UNORM,
+ /*WINED3DDECLTYPE_USHORT4N*/ WINED3DFMT_R16G16B16A16_UNORM,
+ /*WINED3DDECLTYPE_UDEC3*/ WINED3DFMT_R10G10B10A2_UINT,
+ /*WINED3DDECLTYPE_DEC3N*/ WINED3DFMT_R10G10B10A2_SNORM,
+ /*WINED3DDECLTYPE_FLOAT16_2*/ WINED3DFMT_R16G16_FLOAT,
+ /*WINED3DDECLTYPE_FLOAT16_4*/ WINED3DFMT_R16G16B16A16_FLOAT,
+};
+
+static const struct
+{
+ BYTE usage;
+ BYTE usage_idx;
+}
+wined3d_usage_lookup[] =
+{
+ /* D3DVSDE_POSITION */ {WINED3D_DECL_USAGE_POSITION, 0},
+ /* D3DVSDE_BLENDWEIGHT */ {WINED3D_DECL_USAGE_BLEND_WEIGHT, 0},
+ /* D3DVSDE_BLENDINDICES */ {WINED3D_DECL_USAGE_BLEND_INDICES, 0},
+ /* D3DVSDE_NORMAL */ {WINED3D_DECL_USAGE_NORMAL, 0},
+ /* D3DVSDE_PSIZE */ {WINED3D_DECL_USAGE_PSIZE, 0},
+ /* D3DVSDE_DIFFUSE */ {WINED3D_DECL_USAGE_COLOR, 0},
+ /* D3DVSDE_SPECULAR */ {WINED3D_DECL_USAGE_COLOR, 1},
+ /* D3DVSDE_TEXCOORD0 */ {WINED3D_DECL_USAGE_TEXCOORD, 0},
+ /* D3DVSDE_TEXCOORD1 */ {WINED3D_DECL_USAGE_TEXCOORD, 1},
+ /* D3DVSDE_TEXCOORD2 */ {WINED3D_DECL_USAGE_TEXCOORD, 2},
+ /* D3DVSDE_TEXCOORD3 */ {WINED3D_DECL_USAGE_TEXCOORD, 3},
+ /* D3DVSDE_TEXCOORD4 */ {WINED3D_DECL_USAGE_TEXCOORD, 4},
+ /* D3DVSDE_TEXCOORD5 */ {WINED3D_DECL_USAGE_TEXCOORD, 5},
+ /* D3DVSDE_TEXCOORD6 */ {WINED3D_DECL_USAGE_TEXCOORD, 6},
+ /* D3DVSDE_TEXCOORD7 */ {WINED3D_DECL_USAGE_TEXCOORD, 7},
+ /* D3DVSDE_POSITION2 */ {WINED3D_DECL_USAGE_POSITION, 1},
+ /* D3DVSDE_NORMAL2 */ {WINED3D_DECL_USAGE_NORMAL, 1},
+};
+
+/* TODO: find out where rhw (or positionT) is for declaration8 */
+static UINT convert_to_wined3d_declaration(const DWORD *d3d8_elements, DWORD *d3d8_elements_size,
+ struct wined3d_vertex_element **wined3d_elements)
+{
+ struct wined3d_vertex_element *element;
+ const DWORD *token = d3d8_elements;
+ D3DVSD_TOKENTYPE token_type;
+ unsigned int element_count = 0;
+ WORD stream = 0;
+ int offset = 0;
+
+ TRACE("d3d8_elements %p, wined3d_elements %p\n", d3d8_elements, wined3d_elements);
+
+ /* 128 should be enough for anyone... */
+ *wined3d_elements = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 128 * sizeof(**wined3d_elements));
+ while (D3DVSD_END() != *token)
+ {
+ token_type = ((*token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT);
+
+ if (token_type == D3DVSD_TOKEN_STREAM && !(*token & D3DVSD_STREAMTESSMASK))
+ {
+ stream = ((*token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT);
+ offset = 0;
+ } else if (token_type == D3DVSD_TOKEN_STREAMDATA && !(token_type & 0x10000000)) {
+ DWORD type = ((*token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
+ DWORD reg = ((*token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
+
+ TRACE("Adding element %d:\n", element_count);
+
+ element = *wined3d_elements + element_count++;
+ element->format = wined3d_format_lookup[type];
+ element->input_slot = stream;
+ element->offset = offset;
+ element->output_slot = reg;
+ element->method = WINED3D_DECL_METHOD_DEFAULT;
+ element->usage = wined3d_usage_lookup[reg].usage;
+ element->usage_idx = wined3d_usage_lookup[reg].usage_idx;
+
+ offset += wined3d_type_sizes[type];
+ } else if (token_type == D3DVSD_TOKEN_STREAMDATA && (token_type & 0x10000000)) {
+ TRACE(" 0x%08x SKIP(%u)\n", token_type, ((token_type & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT));
+ offset += sizeof(DWORD) * ((token_type & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT);
+ }
+
+ if (element_count >= 127) {
+ ERR("More than 127 elements?\n");
+ break;
+ }
+
+ token += parse_token(token);
+ }
+
+ *d3d8_elements_size = (++token - d3d8_elements) * sizeof(DWORD);
+
+ return element_count;
+}
+
+static void STDMETHODCALLTYPE d3d8_vertexdeclaration_wined3d_object_destroyed(void *parent)
+{
+ struct d3d8_vertex_declaration *declaration = parent;
+ HeapFree(GetProcessHeap(), 0, declaration->elements);
+ HeapFree(GetProcessHeap(), 0, declaration);
+}
+
+void d3d8_vertex_declaration_destroy(struct d3d8_vertex_declaration *declaration)
+{
+ TRACE("declaration %p.\n", declaration);
+
+ wined3d_mutex_lock();
+ wined3d_vertex_declaration_decref(declaration->wined3d_vertex_declaration);
+ wined3d_mutex_unlock();
+}
+
+static const struct wined3d_parent_ops d3d8_vertexdeclaration_wined3d_parent_ops =
+{
+ d3d8_vertexdeclaration_wined3d_object_destroyed,
+};
+
+HRESULT d3d8_vertex_declaration_init(struct d3d8_vertex_declaration *declaration,
+ struct d3d8_device *device, const DWORD *elements, DWORD shader_handle)
+{
+ struct wined3d_vertex_element *wined3d_elements;
+ UINT wined3d_element_count;
+ HRESULT hr;
+
+ declaration->shader_handle = shader_handle;
+
+ wined3d_element_count = convert_to_wined3d_declaration(elements, &declaration->elements_size, &wined3d_elements);
+ declaration->elements = HeapAlloc(GetProcessHeap(), 0, declaration->elements_size);
+ if (!declaration->elements)
+ {
+ ERR("Failed to allocate vertex declaration elements memory.\n");
+ HeapFree(GetProcessHeap(), 0, wined3d_elements);
+ return E_OUTOFMEMORY;
+ }
+
+ memcpy(declaration->elements, elements, declaration->elements_size);
+
+ wined3d_mutex_lock();
+ hr = wined3d_vertex_declaration_create(device->wined3d_device, wined3d_elements, wined3d_element_count,
+ declaration, &d3d8_vertexdeclaration_wined3d_parent_ops, &declaration->wined3d_vertex_declaration);
+ wined3d_mutex_unlock();
+ HeapFree(GetProcessHeap(), 0, wined3d_elements);
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d vertex declaration, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, declaration->elements);
+ return hr;
+ }
+
+ return D3D_OK;
+}
+
+HRESULT d3d8_vertex_declaration_init_fvf(struct d3d8_vertex_declaration *declaration,
+ struct d3d8_device *device, DWORD fvf)
+{
+ HRESULT hr;
+
+ declaration->elements = NULL;
+ declaration->elements_size = 0;
+ declaration->shader_handle = fvf;
+
+ hr = wined3d_vertex_declaration_create_from_fvf(device->wined3d_device, fvf, declaration,
+ &d3d8_vertexdeclaration_wined3d_parent_ops, &declaration->wined3d_vertex_declaration);
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d vertex declaration, hr %#x.\n", hr);
+ return hr;
+ }
+
+ return D3D_OK;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/volume.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/volume.c
new file mode 100644
index 00000000..6955d5ca
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d8/volume.c
@@ -0,0 +1,312 @@
+/*
+ * IDirect3DVolume8 implementation
+ *
+ * Copyright 2005 Oliver Stieber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "d3d8_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
+
+static inline struct d3d8_volume *impl_from_IDirect3DVolume8(IDirect3DVolume8 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d8_volume, IDirect3DVolume8_iface);
+}
+
+static HRESULT WINAPI d3d8_volume_QueryInterface(IDirect3DVolume8 *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DVolume8)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DVolume8_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d8_volume_AddRef(IDirect3DVolume8 *iface)
+{
+ struct d3d8_volume *volume = impl_from_IDirect3DVolume8(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ if (volume->forwardReference)
+ {
+ /* Forward to the containerParent */
+ TRACE("Forwarding to %p,\n", volume->forwardReference);
+ return IUnknown_AddRef(volume->forwardReference);
+ }
+ else
+ {
+ /* No container, handle our own refcounting */
+ ULONG ref = InterlockedIncrement(&volume->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, ref);
+
+ if (ref == 1)
+ {
+ wined3d_mutex_lock();
+ wined3d_volume_incref(volume->wined3d_volume);
+ wined3d_mutex_unlock();
+ }
+
+ return ref;
+ }
+}
+
+static ULONG WINAPI d3d8_volume_Release(IDirect3DVolume8 *iface)
+{
+ struct d3d8_volume *volume = impl_from_IDirect3DVolume8(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ if (volume->forwardReference)
+ {
+ /* Forward to the containerParent */
+ TRACE("Forwarding to %p.\n", volume->forwardReference);
+ return IUnknown_Release(volume->forwardReference);
+ }
+ else
+ {
+ /* No container, handle our own refcounting */
+ ULONG ref = InterlockedDecrement(&volume->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, ref);
+
+ if (!ref)
+ {
+ wined3d_mutex_lock();
+ wined3d_volume_decref(volume->wined3d_volume);
+ wined3d_mutex_unlock();
+ }
+
+ return ref;
+ }
+}
+
+static HRESULT WINAPI d3d8_volume_GetDevice(IDirect3DVolume8 *iface, IDirect3DDevice8 **device)
+{
+ struct d3d8_volume *volume = impl_from_IDirect3DVolume8(iface);
+ IDirect3DResource8 *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ hr = IUnknown_QueryInterface(volume->forwardReference, &IID_IDirect3DResource8, (void **)&resource);
+ if (SUCCEEDED(hr))
+ {
+ hr = IDirect3DResource8_GetDevice(resource, device);
+ IDirect3DResource8_Release(resource);
+
+ TRACE("Returning device %p.\n", *device);
+ }
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_volume_SetPrivateData(IDirect3DVolume8 *iface, REFGUID guid,
+ const void *data, DWORD data_size, DWORD flags)
+{
+ struct d3d8_volume *volume = impl_from_IDirect3DVolume8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
+ iface, debugstr_guid(guid), data, data_size, flags);
+
+ wined3d_mutex_lock();
+ resource = wined3d_volume_get_resource(volume->wined3d_volume);
+ hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_volume_GetPrivateData(IDirect3DVolume8 *iface, REFGUID guid,
+ void *data, DWORD *data_size)
+{
+ struct d3d8_volume *volume = impl_from_IDirect3DVolume8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %p.\n",
+ iface, debugstr_guid(guid), data, data_size);
+
+ wined3d_mutex_lock();
+ resource = wined3d_volume_get_resource(volume->wined3d_volume);
+ hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_volume_FreePrivateData(IDirect3DVolume8 *iface, REFGUID guid)
+{
+ struct d3d8_volume *volume = impl_from_IDirect3DVolume8(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
+
+ wined3d_mutex_lock();
+ resource = wined3d_volume_get_resource(volume->wined3d_volume);
+ hr = wined3d_resource_free_private_data(resource, guid);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_volume_GetContainer(IDirect3DVolume8 *iface, REFIID riid, void **container)
+{
+ struct d3d8_volume *volume = impl_from_IDirect3DVolume8(iface);
+ HRESULT res;
+
+ TRACE("iface %p, riid %s, container %p.\n",
+ iface, debugstr_guid(riid), container);
+
+ if (!volume->container)
+ return E_NOINTERFACE;
+
+ res = IUnknown_QueryInterface(volume->container, riid, container);
+
+ TRACE("Returning %p.\n", *container);
+
+ return res;
+}
+
+static HRESULT WINAPI d3d8_volume_GetDesc(IDirect3DVolume8 *iface, D3DVOLUME_DESC *desc)
+{
+ struct d3d8_volume *volume = impl_from_IDirect3DVolume8(iface);
+ struct wined3d_resource_desc wined3d_desc;
+ struct wined3d_resource *wined3d_resource;
+
+ TRACE("iface %p, desc %p.\n", iface, desc);
+
+ wined3d_mutex_lock();
+ wined3d_resource = wined3d_volume_get_resource(volume->wined3d_volume);
+ wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
+ wined3d_mutex_unlock();
+
+ desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
+ desc->Type = wined3d_desc.resource_type;
+ desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
+ desc->Pool = wined3d_desc.pool;
+ desc->Size = wined3d_desc.size;
+ desc->Width = wined3d_desc.width;
+ desc->Height = wined3d_desc.height;
+ desc->Depth = wined3d_desc.depth;
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d8_volume_LockBox(IDirect3DVolume8 *iface,
+ D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags)
+{
+ struct d3d8_volume *volume = impl_from_IDirect3DVolume8(iface);
+ struct wined3d_map_desc map_desc;
+ HRESULT hr;
+
+ TRACE("iface %p, locked_box %p, box %p, flags %#x.\n",
+ iface, locked_box, box, flags);
+
+ wined3d_mutex_lock();
+ hr = wined3d_volume_map(volume->wined3d_volume, &map_desc, (const struct wined3d_box *)box, flags);
+ wined3d_mutex_unlock();
+
+ locked_box->RowPitch = map_desc.row_pitch;
+ locked_box->SlicePitch = map_desc.slice_pitch;
+ locked_box->pBits = map_desc.data;
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d8_volume_UnlockBox(IDirect3DVolume8 *iface)
+{
+ struct d3d8_volume *volume = impl_from_IDirect3DVolume8(iface);
+ HRESULT hr;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ hr = wined3d_volume_unmap(volume->wined3d_volume);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static const IDirect3DVolume8Vtbl d3d8_volume_vtbl =
+{
+ /* IUnknown */
+ d3d8_volume_QueryInterface,
+ d3d8_volume_AddRef,
+ d3d8_volume_Release,
+ /* IDirect3DVolume8 */
+ d3d8_volume_GetDevice,
+ d3d8_volume_SetPrivateData,
+ d3d8_volume_GetPrivateData,
+ d3d8_volume_FreePrivateData,
+ d3d8_volume_GetContainer,
+ d3d8_volume_GetDesc,
+ d3d8_volume_LockBox,
+ d3d8_volume_UnlockBox,
+};
+
+static void STDMETHODCALLTYPE volume_wined3d_object_destroyed(void *parent)
+{
+ HeapFree(GetProcessHeap(), 0, parent);
+}
+
+static const struct wined3d_parent_ops d3d8_volume_wined3d_parent_ops =
+{
+ volume_wined3d_object_destroyed,
+};
+
+HRESULT volume_init(struct d3d8_volume *volume, struct d3d8_device *device, UINT width, UINT height,
+ UINT depth, DWORD usage, enum wined3d_format_id format, enum wined3d_pool pool)
+{
+ HRESULT hr;
+
+ volume->IDirect3DVolume8_iface.lpVtbl = &d3d8_volume_vtbl;
+ volume->refcount = 1;
+
+ hr = wined3d_volume_create(device->wined3d_device, width, height, depth, usage,
+ format, pool, volume, &d3d8_volume_wined3d_parent_ops, &volume->wined3d_volume);
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d volume, hr %#x.\n", hr);
+ return hr;
+ }
+
+ return D3D_OK;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/Makefile.kup b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/Makefile.kup
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/buffer.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/buffer.c
new file mode 100644
index 00000000..bc6ae326
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/buffer.c
@@ -0,0 +1,619 @@
+/*
+ * Copyright 2002-2004 Jason Edmeades
+ * Copyright 2002-2004 Raphael Junqueira
+ * Copyright 2005 Oliver Stieber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "d3d9_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
+static inline struct d3d9_vertexbuffer *impl_from_IDirect3DVertexBuffer9(IDirect3DVertexBuffer9 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d9_vertexbuffer, IDirect3DVertexBuffer9_iface);
+}
+
+static HRESULT WINAPI d3d9_vertexbuffer_QueryInterface(IDirect3DVertexBuffer9 *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DVertexBuffer9)
+ || IsEqualGUID(riid, &IID_IDirect3DResource9)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DVertexBuffer9_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d9_vertexbuffer_AddRef(IDirect3DVertexBuffer9 *iface)
+{
+ struct d3d9_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer9(iface);
+ ULONG refcount = InterlockedIncrement(&buffer->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, refcount);
+
+ if (refcount == 1)
+ {
+ IDirect3DDevice9Ex_AddRef(buffer->parent_device);
+ wined3d_mutex_lock();
+ wined3d_buffer_incref(buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+ }
+
+ return refcount;
+}
+
+static ULONG WINAPI d3d9_vertexbuffer_Release(IDirect3DVertexBuffer9 *iface)
+{
+ struct d3d9_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer9(iface);
+ ULONG refcount = InterlockedDecrement(&buffer->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ IDirect3DDevice9Ex *device = buffer->parent_device;
+
+ wined3d_mutex_lock();
+ wined3d_buffer_decref(buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+
+ /* Release the device last, as it may cause the device to be destroyed. */
+ IDirect3DDevice9Ex_Release(device);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI d3d9_vertexbuffer_GetDevice(IDirect3DVertexBuffer9 *iface, IDirect3DDevice9 **device)
+{
+ struct d3d9_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer9(iface);
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ *device = (IDirect3DDevice9 *)buffer->parent_device;
+ IDirect3DDevice9_AddRef(*device);
+
+ TRACE("Returning device %p.\n", *device);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_vertexbuffer_SetPrivateData(IDirect3DVertexBuffer9 *iface,
+ REFGUID guid, const void *data, DWORD data_size, DWORD flags)
+{
+ struct d3d9_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
+ iface, debugstr_guid(guid), data, data_size, flags);
+
+ wined3d_mutex_lock();
+ resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
+ hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_vertexbuffer_GetPrivateData(IDirect3DVertexBuffer9 *iface,
+ REFGUID guid, void *data, DWORD *data_size)
+{
+ struct d3d9_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %p.\n",
+ iface, debugstr_guid(guid), data, data_size);
+
+ wined3d_mutex_lock();
+ resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
+ hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_vertexbuffer_FreePrivateData(IDirect3DVertexBuffer9 *iface, REFGUID guid)
+{
+ struct d3d9_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
+
+ wined3d_mutex_lock();
+ resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
+ hr = wined3d_resource_free_private_data(resource, guid);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static DWORD WINAPI d3d9_vertexbuffer_SetPriority(IDirect3DVertexBuffer9 *iface, DWORD priority)
+{
+ struct d3d9_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer9(iface);
+ DWORD previous;
+
+ TRACE("iface %p, priority %u.\n", iface, priority);
+
+ wined3d_mutex_lock();
+ previous = wined3d_buffer_set_priority(buffer->wined3d_buffer, priority);
+ wined3d_mutex_unlock();
+
+ return previous;
+}
+
+static DWORD WINAPI d3d9_vertexbuffer_GetPriority(IDirect3DVertexBuffer9 *iface)
+{
+ struct d3d9_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer9(iface);
+ DWORD priority;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ priority = wined3d_buffer_get_priority(buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+
+ return priority;
+}
+
+static void WINAPI d3d9_vertexbuffer_PreLoad(IDirect3DVertexBuffer9 *iface)
+{
+ struct d3d9_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer9(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_buffer_preload(buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+}
+
+static D3DRESOURCETYPE WINAPI d3d9_vertexbuffer_GetType(IDirect3DVertexBuffer9 *iface)
+{
+ TRACE("iface %p.\n", iface);
+
+ return D3DRTYPE_VERTEXBUFFER;
+}
+
+static HRESULT WINAPI d3d9_vertexbuffer_Lock(IDirect3DVertexBuffer9 *iface, UINT offset, UINT size,
+ void **data, DWORD flags)
+{
+ struct d3d9_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer9(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n",
+ iface, offset, size, data, flags);
+
+ wined3d_mutex_lock();
+ hr = wined3d_buffer_map(buffer->wined3d_buffer, offset, size, (BYTE **)data, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_vertexbuffer_Unlock(IDirect3DVertexBuffer9 *iface)
+{
+ struct d3d9_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer9(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_buffer_unmap(buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_vertexbuffer_GetDesc(IDirect3DVertexBuffer9 *iface,
+ D3DVERTEXBUFFER_DESC *desc)
+{
+ struct d3d9_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer9(iface);
+ struct wined3d_resource_desc wined3d_desc;
+ struct wined3d_resource *wined3d_resource;
+
+ TRACE("iface %p, desc %p.\n", iface, desc);
+
+ wined3d_mutex_lock();
+ wined3d_resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
+ wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
+ wined3d_mutex_unlock();
+
+ desc->Format = D3DFMT_VERTEXDATA;
+ desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
+ desc->Pool = wined3d_desc.pool;
+ desc->Size = wined3d_desc.size;
+ desc->Type = D3DRTYPE_VERTEXBUFFER;
+ desc->FVF = buffer->fvf;
+
+ return D3D_OK;
+}
+
+static const IDirect3DVertexBuffer9Vtbl d3d9_vertexbuffer_vtbl =
+{
+ /* IUnknown */
+ d3d9_vertexbuffer_QueryInterface,
+ d3d9_vertexbuffer_AddRef,
+ d3d9_vertexbuffer_Release,
+ /* IDirect3DResource9 */
+ d3d9_vertexbuffer_GetDevice,
+ d3d9_vertexbuffer_SetPrivateData,
+ d3d9_vertexbuffer_GetPrivateData,
+ d3d9_vertexbuffer_FreePrivateData,
+ d3d9_vertexbuffer_SetPriority,
+ d3d9_vertexbuffer_GetPriority,
+ d3d9_vertexbuffer_PreLoad,
+ d3d9_vertexbuffer_GetType,
+ /* IDirect3DVertexBuffer9 */
+ d3d9_vertexbuffer_Lock,
+ d3d9_vertexbuffer_Unlock,
+ d3d9_vertexbuffer_GetDesc,
+};
+
+static void STDMETHODCALLTYPE d3d9_vertexbuffer_wined3d_object_destroyed(void *parent)
+{
+ HeapFree(GetProcessHeap(), 0, parent);
+}
+
+static const struct wined3d_parent_ops d3d9_vertexbuffer_wined3d_parent_ops =
+{
+ d3d9_vertexbuffer_wined3d_object_destroyed,
+};
+
+HRESULT vertexbuffer_init(struct d3d9_vertexbuffer *buffer, struct d3d9_device *device,
+ UINT size, UINT usage, DWORD fvf, D3DPOOL pool)
+{
+ HRESULT hr;
+
+ buffer->IDirect3DVertexBuffer9_iface.lpVtbl = &d3d9_vertexbuffer_vtbl;
+ buffer->refcount = 1;
+ buffer->fvf = fvf;
+
+ wined3d_mutex_lock();
+ hr = wined3d_buffer_create_vb(device->wined3d_device, size, usage & WINED3DUSAGE_MASK,
+ (enum wined3d_pool)pool, buffer, &d3d9_vertexbuffer_wined3d_parent_ops, &buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
+ return hr;
+ }
+
+ buffer->parent_device = &device->IDirect3DDevice9Ex_iface;
+ IDirect3DDevice9Ex_AddRef(buffer->parent_device);
+
+ return D3D_OK;
+}
+
+struct d3d9_vertexbuffer *unsafe_impl_from_IDirect3DVertexBuffer9(IDirect3DVertexBuffer9 *iface)
+{
+ if (!iface)
+ return NULL;
+ assert(iface->lpVtbl == &d3d9_vertexbuffer_vtbl);
+
+ return impl_from_IDirect3DVertexBuffer9(iface);
+}
+
+static inline struct d3d9_indexbuffer *impl_from_IDirect3DIndexBuffer9(IDirect3DIndexBuffer9 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d9_indexbuffer, IDirect3DIndexBuffer9_iface);
+}
+
+static HRESULT WINAPI d3d9_indexbuffer_QueryInterface(IDirect3DIndexBuffer9 *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DIndexBuffer9)
+ || IsEqualGUID(riid, &IID_IDirect3DResource9)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DIndexBuffer9_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d9_indexbuffer_AddRef(IDirect3DIndexBuffer9 *iface)
+{
+ struct d3d9_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer9(iface);
+ ULONG refcount = InterlockedIncrement(&buffer->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, refcount);
+
+ if (refcount == 1)
+ {
+ IDirect3DDevice9Ex_AddRef(buffer->parent_device);
+ wined3d_mutex_lock();
+ wined3d_buffer_incref(buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+ }
+
+ return refcount;
+}
+
+static ULONG WINAPI d3d9_indexbuffer_Release(IDirect3DIndexBuffer9 *iface)
+{
+ struct d3d9_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer9(iface);
+ ULONG refcount = InterlockedDecrement(&buffer->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ IDirect3DDevice9Ex *device = buffer->parent_device;
+
+ wined3d_mutex_lock();
+ wined3d_buffer_decref(buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+
+ /* Release the device last, as it may cause the device to be destroyed. */
+ IDirect3DDevice9Ex_Release(device);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI d3d9_indexbuffer_GetDevice(IDirect3DIndexBuffer9 *iface, IDirect3DDevice9 **device)
+{
+ struct d3d9_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer9(iface);
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ *device = (IDirect3DDevice9 *)buffer->parent_device;
+ IDirect3DDevice9_AddRef(*device);
+
+ TRACE("Returning device %p.\n", *device);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_indexbuffer_SetPrivateData(IDirect3DIndexBuffer9 *iface,
+ REFGUID guid, const void *data, DWORD data_size, DWORD flags)
+{
+ struct d3d9_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
+ iface, debugstr_guid(guid), data, data_size, flags);
+
+ wined3d_mutex_lock();
+ resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
+ hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_indexbuffer_GetPrivateData(IDirect3DIndexBuffer9 *iface,
+ REFGUID guid, void *data, DWORD *data_size)
+{
+ struct d3d9_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %p.\n",
+ iface, debugstr_guid(guid), data, data_size);
+
+ wined3d_mutex_lock();
+ resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
+ hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_indexbuffer_FreePrivateData(IDirect3DIndexBuffer9 *iface, REFGUID guid)
+{
+ struct d3d9_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
+
+ wined3d_mutex_lock();
+ resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
+ hr = wined3d_resource_free_private_data(resource, guid);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static DWORD WINAPI d3d9_indexbuffer_SetPriority(IDirect3DIndexBuffer9 *iface, DWORD priority)
+{
+ struct d3d9_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer9(iface);
+ DWORD previous;
+
+ TRACE("iface %p, priority %u.\n", iface, priority);
+
+ wined3d_mutex_lock();
+ previous = wined3d_buffer_set_priority(buffer->wined3d_buffer, priority);
+ wined3d_mutex_unlock();
+
+ return previous;
+}
+
+static DWORD WINAPI d3d9_indexbuffer_GetPriority(IDirect3DIndexBuffer9 *iface)
+{
+ struct d3d9_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer9(iface);
+ DWORD priority;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ priority = wined3d_buffer_get_priority(buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+
+ return priority;
+}
+
+static void WINAPI d3d9_indexbuffer_PreLoad(IDirect3DIndexBuffer9 *iface)
+{
+ struct d3d9_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer9(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_buffer_preload(buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+}
+
+static D3DRESOURCETYPE WINAPI d3d9_indexbuffer_GetType(IDirect3DIndexBuffer9 *iface)
+{
+ TRACE("iface %p.\n", iface);
+
+ return D3DRTYPE_INDEXBUFFER;
+}
+
+static HRESULT WINAPI d3d9_indexbuffer_Lock(IDirect3DIndexBuffer9 *iface,
+ UINT offset, UINT size, void **data, DWORD flags)
+{
+ struct d3d9_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer9(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n",
+ iface, offset, size, data, flags);
+
+ wined3d_mutex_lock();
+ hr = wined3d_buffer_map(buffer->wined3d_buffer, offset, size, (BYTE **)data, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_indexbuffer_Unlock(IDirect3DIndexBuffer9 *iface)
+{
+ struct d3d9_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer9(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_buffer_unmap(buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_indexbuffer_GetDesc(IDirect3DIndexBuffer9 *iface, D3DINDEXBUFFER_DESC *desc)
+{
+ struct d3d9_indexbuffer *buffer = impl_from_IDirect3DIndexBuffer9(iface);
+ struct wined3d_resource_desc wined3d_desc;
+ struct wined3d_resource *wined3d_resource;
+
+ TRACE("iface %p, desc %p.\n", iface, desc);
+
+ wined3d_mutex_lock();
+ wined3d_resource = wined3d_buffer_get_resource(buffer->wined3d_buffer);
+ wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
+ wined3d_mutex_unlock();
+
+ desc->Format = d3dformat_from_wined3dformat(buffer->format);
+ desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
+ desc->Pool = wined3d_desc.pool;
+ desc->Size = wined3d_desc.size;
+ desc->Type = D3DRTYPE_INDEXBUFFER;
+
+ return D3D_OK;
+}
+
+static const IDirect3DIndexBuffer9Vtbl d3d9_indexbuffer_vtbl =
+{
+ /* IUnknown */
+ d3d9_indexbuffer_QueryInterface,
+ d3d9_indexbuffer_AddRef,
+ d3d9_indexbuffer_Release,
+ /* IDirect3DResource9 */
+ d3d9_indexbuffer_GetDevice,
+ d3d9_indexbuffer_SetPrivateData,
+ d3d9_indexbuffer_GetPrivateData,
+ d3d9_indexbuffer_FreePrivateData,
+ d3d9_indexbuffer_SetPriority,
+ d3d9_indexbuffer_GetPriority,
+ d3d9_indexbuffer_PreLoad,
+ d3d9_indexbuffer_GetType,
+ /* IDirect3DIndexBuffer9 */
+ d3d9_indexbuffer_Lock,
+ d3d9_indexbuffer_Unlock,
+ d3d9_indexbuffer_GetDesc,
+};
+
+static void STDMETHODCALLTYPE d3d9_indexbuffer_wined3d_object_destroyed(void *parent)
+{
+ HeapFree(GetProcessHeap(), 0, parent);
+}
+
+static const struct wined3d_parent_ops d3d9_indexbuffer_wined3d_parent_ops =
+{
+ d3d9_indexbuffer_wined3d_object_destroyed,
+};
+
+HRESULT indexbuffer_init(struct d3d9_indexbuffer *buffer, struct d3d9_device *device,
+ UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool)
+{
+ HRESULT hr;
+
+ buffer->IDirect3DIndexBuffer9_iface.lpVtbl = &d3d9_indexbuffer_vtbl;
+ buffer->refcount = 1;
+ buffer->format = wined3dformat_from_d3dformat(format);
+
+ wined3d_mutex_lock();
+ hr = wined3d_buffer_create_ib(device->wined3d_device, size, usage & WINED3DUSAGE_MASK,
+ (enum wined3d_pool)pool, buffer, &d3d9_indexbuffer_wined3d_parent_ops, &buffer->wined3d_buffer);
+ wined3d_mutex_unlock();
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
+ return hr;
+ }
+
+ buffer->parent_device = &device->IDirect3DDevice9Ex_iface;
+ IDirect3DDevice9Ex_AddRef(buffer->parent_device);
+
+ return D3D_OK;
+}
+
+struct d3d9_indexbuffer *unsafe_impl_from_IDirect3DIndexBuffer9(IDirect3DIndexBuffer9 *iface)
+{
+ if (!iface)
+ return NULL;
+ assert(iface->lpVtbl == &d3d9_indexbuffer_vtbl);
+
+ return impl_from_IDirect3DIndexBuffer9(iface);
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/d3d9_main.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/d3d9_main.c
new file mode 100644
index 00000000..42d6e337
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/d3d9_main.c
@@ -0,0 +1,179 @@
+/*
+ * Direct3D 9
+ *
+ * Copyright 2002-2003 Jason Edmeades
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2005 Oliver Stieber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "initguid.h"
+#include "d3d9_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
+static int D3DPERF_event_level = 0;
+
+void WINAPI DebugSetMute(void) {
+ /* nothing to do */
+}
+
+IDirect3D9 * WINAPI DECLSPEC_HOTPATCH Direct3DCreate9(UINT sdk_version)
+{
+ struct d3d9 *object;
+
+ TRACE("sdk_version %#x.\n", sdk_version);
+
+ if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+ return NULL;
+
+ if (!d3d9_init(object, FALSE))
+ {
+ WARN("Failed to initialize d3d9.\n");
+ HeapFree(GetProcessHeap(), 0, object);
+ return NULL;
+ }
+
+ TRACE("Created d3d9 object %p.\n", object);
+
+ return (IDirect3D9 *)&object->IDirect3D9Ex_iface;
+}
+
+HRESULT WINAPI DECLSPEC_HOTPATCH Direct3DCreate9Ex(UINT sdk_version, IDirect3D9Ex **d3d9ex)
+{
+#if defined(VBOX_WITH_WINE_FIX_NO9EX) && !defined(VBOX_WITH_WDDM)
+ /* real D3D lib does not allow 9Ex creation if no WDDM driver is installed,
+ * the Direct3DCreate9Ex should return D3DERR_NOTAVAILABLE in that case.
+ * do it that way for our XPDM case */
+ return D3DERR_NOTAVAILABLE;
+#else
+ struct d3d9 *object;
+
+ TRACE("sdk_version %#x, d3d9ex %p.\n", sdk_version, d3d9ex);
+
+ if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+ return E_OUTOFMEMORY;
+
+ if (!d3d9_init(object, TRUE))
+ {
+ WARN("Failed to initialize d3d9.\n");
+ HeapFree(GetProcessHeap(), 0, object);
+ return D3DERR_NOTAVAILABLE;
+ }
+
+ TRACE("Created d3d9 object %p.\n", object);
+ *d3d9ex = &object->IDirect3D9Ex_iface;
+
+ return D3D_OK;
+#endif
+}
+
+/*******************************************************************
+ * Direct3DShaderValidatorCreate9 (D3D9.@)
+ *
+ * No documentation available for this function.
+ * SDK only says it is internal and shouldn't be used.
+ */
+void* WINAPI Direct3DShaderValidatorCreate9(void)
+{
+ static int once;
+
+ if (!once++) FIXME("stub\n");
+ return NULL;
+}
+
+/*******************************************************************
+ * DllMain
+ */
+BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
+{
+ /* At process attach */
+ TRACE("fdwReason=%d\n", fdwReason);
+ if (fdwReason == DLL_PROCESS_ATTACH)
+ DisableThreadLibraryCalls(hInstDLL);
+
+ return TRUE;
+}
+
+/***********************************************************************
+ * D3DPERF_BeginEvent (D3D9.@)
+ */
+int WINAPI D3DPERF_BeginEvent(D3DCOLOR color, LPCWSTR name) {
+ TRACE("(color %#x, name %s) : stub\n", color, debugstr_w(name));
+
+ return D3DPERF_event_level++;
+}
+
+/***********************************************************************
+ * D3DPERF_EndEvent (D3D9.@)
+ */
+int WINAPI D3DPERF_EndEvent(void) {
+ TRACE("(void) : stub\n");
+
+ return --D3DPERF_event_level;
+}
+
+/***********************************************************************
+ * D3DPERF_GetStatus (D3D9.@)
+ */
+DWORD WINAPI D3DPERF_GetStatus(void) {
+ FIXME("(void) : stub\n");
+
+ return 0;
+}
+
+/***********************************************************************
+ * D3DPERF_SetOptions (D3D9.@)
+ *
+ */
+void WINAPI D3DPERF_SetOptions(DWORD options)
+{
+ FIXME("(%#x) : stub\n", options);
+}
+
+/***********************************************************************
+ * D3DPERF_QueryRepeatFrame (D3D9.@)
+ */
+BOOL WINAPI D3DPERF_QueryRepeatFrame(void) {
+ FIXME("(void) : stub\n");
+
+ return FALSE;
+}
+
+/***********************************************************************
+ * D3DPERF_SetMarker (D3D9.@)
+ */
+void WINAPI D3DPERF_SetMarker(D3DCOLOR color, LPCWSTR name) {
+ FIXME("(color %#x, name %s) : stub\n", color, debugstr_w(name));
+}
+
+/***********************************************************************
+ * D3DPERF_SetRegion (D3D9.@)
+ */
+void WINAPI D3DPERF_SetRegion(D3DCOLOR color, LPCWSTR name) {
+ FIXME("(color %#x, name %s) : stub\n", color, debugstr_w(name));
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/d3d9_private.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/d3d9_private.h
new file mode 100644
index 00000000..1849e3bf
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/d3d9_private.h
@@ -0,0 +1,361 @@
+/*
+ * Direct3D 9 private include file
+ *
+ * Copyright 2002-2003 Jason Edmeades
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2005 Oliver Stieber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#ifndef __WINE_D3D9_PRIVATE_H
+#define __WINE_D3D9_PRIVATE_H
+
+#include <assert.h>
+#include <stdarg.h>
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#define COBJMACROS
+#ifndef VBOX_WINE_WITHOUT_LIBWINE
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#else
+#include <windows.h>
+#endif
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+#include "d3d9.h"
+#include "wine/wined3d.h"
+
+extern HRESULT vdecl_convert_fvf(DWORD FVF, D3DVERTEXELEMENT9 **ppVertexElements) DECLSPEC_HIDDEN;
+D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN;
+enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) DECLSPEC_HIDDEN;
+void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters,
+ const struct wined3d_swapchain_desc *swapchain_desc) DECLSPEC_HIDDEN;
+
+#define WINECAPSTOD3D9CAPS(_pD3D9Caps, _pWineCaps) \
+ _pD3D9Caps->DeviceType = (D3DDEVTYPE) _pWineCaps->DeviceType; \
+ _pD3D9Caps->AdapterOrdinal = _pWineCaps->AdapterOrdinal; \
+ _pD3D9Caps->Caps = _pWineCaps->Caps; \
+ _pD3D9Caps->Caps2 = _pWineCaps->Caps2; \
+ _pD3D9Caps->Caps3 = _pWineCaps->Caps3; \
+ _pD3D9Caps->PresentationIntervals = _pWineCaps->PresentationIntervals; \
+ _pD3D9Caps->CursorCaps = _pWineCaps->CursorCaps; \
+ _pD3D9Caps->DevCaps = _pWineCaps->DevCaps; \
+ _pD3D9Caps->PrimitiveMiscCaps = _pWineCaps->PrimitiveMiscCaps; \
+ _pD3D9Caps->RasterCaps = _pWineCaps->RasterCaps; \
+ _pD3D9Caps->ZCmpCaps = _pWineCaps->ZCmpCaps; \
+ _pD3D9Caps->SrcBlendCaps = _pWineCaps->SrcBlendCaps; \
+ _pD3D9Caps->DestBlendCaps = _pWineCaps->DestBlendCaps; \
+ _pD3D9Caps->AlphaCmpCaps = _pWineCaps->AlphaCmpCaps; \
+ _pD3D9Caps->ShadeCaps = _pWineCaps->ShadeCaps; \
+ _pD3D9Caps->TextureCaps = _pWineCaps->TextureCaps; \
+ _pD3D9Caps->TextureFilterCaps = _pWineCaps->TextureFilterCaps; \
+ _pD3D9Caps->CubeTextureFilterCaps = _pWineCaps->CubeTextureFilterCaps; \
+ _pD3D9Caps->VolumeTextureFilterCaps = _pWineCaps->VolumeTextureFilterCaps; \
+ _pD3D9Caps->TextureAddressCaps = _pWineCaps->TextureAddressCaps; \
+ _pD3D9Caps->VolumeTextureAddressCaps = _pWineCaps->VolumeTextureAddressCaps; \
+ _pD3D9Caps->LineCaps = _pWineCaps->LineCaps; \
+ _pD3D9Caps->MaxTextureWidth = _pWineCaps->MaxTextureWidth; \
+ _pD3D9Caps->MaxTextureHeight = _pWineCaps->MaxTextureHeight; \
+ _pD3D9Caps->MaxVolumeExtent = _pWineCaps->MaxVolumeExtent; \
+ _pD3D9Caps->MaxTextureRepeat = _pWineCaps->MaxTextureRepeat; \
+ _pD3D9Caps->MaxTextureAspectRatio = _pWineCaps->MaxTextureAspectRatio; \
+ _pD3D9Caps->MaxAnisotropy = _pWineCaps->MaxAnisotropy; \
+ _pD3D9Caps->MaxVertexW = _pWineCaps->MaxVertexW; \
+ _pD3D9Caps->GuardBandLeft = _pWineCaps->GuardBandLeft; \
+ _pD3D9Caps->GuardBandTop = _pWineCaps->GuardBandTop; \
+ _pD3D9Caps->GuardBandRight = _pWineCaps->GuardBandRight; \
+ _pD3D9Caps->GuardBandBottom = _pWineCaps->GuardBandBottom; \
+ _pD3D9Caps->ExtentsAdjust = _pWineCaps->ExtentsAdjust; \
+ _pD3D9Caps->StencilCaps = _pWineCaps->StencilCaps; \
+ _pD3D9Caps->FVFCaps = _pWineCaps->FVFCaps; \
+ _pD3D9Caps->TextureOpCaps = _pWineCaps->TextureOpCaps; \
+ _pD3D9Caps->MaxTextureBlendStages = _pWineCaps->MaxTextureBlendStages; \
+ _pD3D9Caps->MaxSimultaneousTextures = _pWineCaps->MaxSimultaneousTextures; \
+ _pD3D9Caps->VertexProcessingCaps = _pWineCaps->VertexProcessingCaps; \
+ _pD3D9Caps->MaxActiveLights = _pWineCaps->MaxActiveLights; \
+ _pD3D9Caps->MaxUserClipPlanes = _pWineCaps->MaxUserClipPlanes; \
+ _pD3D9Caps->MaxVertexBlendMatrices = _pWineCaps->MaxVertexBlendMatrices; \
+ _pD3D9Caps->MaxVertexBlendMatrixIndex = _pWineCaps->MaxVertexBlendMatrixIndex; \
+ _pD3D9Caps->MaxPointSize = _pWineCaps->MaxPointSize; \
+ _pD3D9Caps->MaxPrimitiveCount = _pWineCaps->MaxPrimitiveCount; \
+ _pD3D9Caps->MaxVertexIndex = _pWineCaps->MaxVertexIndex; \
+ _pD3D9Caps->MaxStreams = _pWineCaps->MaxStreams; \
+ _pD3D9Caps->MaxStreamStride = _pWineCaps->MaxStreamStride; \
+ _pD3D9Caps->VertexShaderVersion = _pWineCaps->VertexShaderVersion; \
+ _pD3D9Caps->MaxVertexShaderConst = _pWineCaps->MaxVertexShaderConst; \
+ _pD3D9Caps->PixelShaderVersion = _pWineCaps->PixelShaderVersion; \
+ _pD3D9Caps->PixelShader1xMaxValue = _pWineCaps->PixelShader1xMaxValue; \
+ _pD3D9Caps->DevCaps2 = _pWineCaps->DevCaps2; \
+ _pD3D9Caps->MaxNpatchTessellationLevel = _pWineCaps->MaxNpatchTessellationLevel; \
+ _pD3D9Caps->MasterAdapterOrdinal = _pWineCaps->MasterAdapterOrdinal; \
+ _pD3D9Caps->AdapterOrdinalInGroup = _pWineCaps->AdapterOrdinalInGroup; \
+ _pD3D9Caps->NumberOfAdaptersInGroup = _pWineCaps->NumberOfAdaptersInGroup; \
+ _pD3D9Caps->DeclTypes = _pWineCaps->DeclTypes; \
+ _pD3D9Caps->NumSimultaneousRTs = _pWineCaps->NumSimultaneousRTs; \
+ _pD3D9Caps->StretchRectFilterCaps = _pWineCaps->StretchRectFilterCaps; \
+ _pD3D9Caps->VS20Caps.Caps = _pWineCaps->VS20Caps.caps; \
+ _pD3D9Caps->VS20Caps.DynamicFlowControlDepth = _pWineCaps->VS20Caps.dynamic_flow_control_depth; \
+ _pD3D9Caps->VS20Caps.NumTemps = _pWineCaps->VS20Caps.temp_count; \
+ _pD3D9Caps->VS20Caps.StaticFlowControlDepth = _pWineCaps->VS20Caps.static_flow_control_depth; \
+ _pD3D9Caps->PS20Caps.Caps = _pWineCaps->PS20Caps.caps; \
+ _pD3D9Caps->PS20Caps.DynamicFlowControlDepth = _pWineCaps->PS20Caps.dynamic_flow_control_depth; \
+ _pD3D9Caps->PS20Caps.NumTemps = _pWineCaps->PS20Caps.temp_count; \
+ _pD3D9Caps->PS20Caps.StaticFlowControlDepth = _pWineCaps->PS20Caps.static_flow_control_depth; \
+ _pD3D9Caps->PS20Caps.NumInstructionSlots = _pWineCaps->PS20Caps.instruction_slot_count; \
+ _pD3D9Caps->VertexTextureFilterCaps = _pWineCaps->VertexTextureFilterCaps; \
+ _pD3D9Caps->MaxVShaderInstructionsExecuted = _pWineCaps->MaxVShaderInstructionsExecuted; \
+ _pD3D9Caps->MaxPShaderInstructionsExecuted = _pWineCaps->MaxPShaderInstructionsExecuted; \
+ _pD3D9Caps->MaxVertexShader30InstructionSlots = _pWineCaps->MaxVertexShader30InstructionSlots; \
+ _pD3D9Caps->MaxPixelShader30InstructionSlots = _pWineCaps->MaxPixelShader30InstructionSlots;
+
+struct d3d9
+{
+ IDirect3D9Ex IDirect3D9Ex_iface;
+ LONG refcount;
+ struct wined3d *wined3d;
+ BOOL extended;
+};
+
+BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended) DECLSPEC_HIDDEN;
+void filter_caps(D3DCAPS9* pCaps) DECLSPEC_HIDDEN;
+
+struct fvf_declaration
+{
+ struct wined3d_vertex_declaration *decl;
+ DWORD fvf;
+};
+
+struct d3d9_device
+{
+ IDirect3DDevice9Ex IDirect3DDevice9Ex_iface;
+ struct wined3d_device_parent device_parent;
+ LONG refcount;
+ struct wined3d_device *wined3d_device;
+ struct d3d9 *d3d_parent;
+
+ struct fvf_declaration *fvf_decls;
+ UINT fvf_decl_count, fvf_decl_size;
+
+ struct wined3d_buffer *vertex_buffer;
+ UINT vertex_buffer_size;
+ UINT vertex_buffer_pos;
+ struct wined3d_buffer *index_buffer;
+ UINT index_buffer_size;
+ UINT index_buffer_pos;
+
+ BOOL in_destruction;
+ BOOL not_reset;
+ BOOL in_scene;
+};
+
+HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wined3d *wined3d,
+ UINT adapter, D3DDEVTYPE device_type, HWND focus_window, DWORD flags
+#ifdef VBOX_WITH_WDDM
+ , VBOXWINEEX_D3DPRESENT_PARAMETERS *parameters
+#else
+ , D3DPRESENT_PARAMETERS *parameters
+#endif
+ , D3DDISPLAYMODEEX *mode) DECLSPEC_HIDDEN;
+
+struct d3d9_volume
+{
+ IDirect3DVolume9 IDirect3DVolume9_iface;
+ LONG refcount;
+ struct wined3d_volume *wined3d_volume;
+ IUnknown *container;
+ IUnknown *forwardReference;
+};
+
+HRESULT volume_init(struct d3d9_volume *volume, struct d3d9_device *device, UINT width, UINT height,
+ UINT depth, DWORD usage, enum wined3d_format_id format, enum wined3d_pool pool
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void *pvClientMem
+#endif
+ ) DECLSPEC_HIDDEN;
+
+struct d3d9_swapchain
+{
+ IDirect3DSwapChain9 IDirect3DSwapChain9_iface;
+ LONG refcount;
+ struct wined3d_swapchain *wined3d_swapchain;
+ IDirect3DDevice9Ex *parent_device;
+};
+
+HRESULT d3d9_swapchain_create(struct d3d9_device *device, struct wined3d_swapchain_desc *desc,
+ struct d3d9_swapchain **swapchain) DECLSPEC_HIDDEN;
+
+struct d3d9_surface
+{
+ IDirect3DSurface9 IDirect3DSurface9_iface;
+ LONG refcount;
+ struct wined3d_surface *wined3d_surface;
+ IDirect3DDevice9Ex *parent_device;
+ IUnknown *container;
+ IUnknown *forwardReference;
+ BOOL getdc_supported;
+};
+
+HRESULT surface_init(struct d3d9_surface *surface, struct d3d9_device *device, UINT width, UINT height,
+ D3DFORMAT format, DWORD flags, DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type,
+ DWORD multisample_quality
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void *pvClientMem
+#endif
+ ) DECLSPEC_HIDDEN;
+struct d3d9_surface *unsafe_impl_from_IDirect3DSurface9(IDirect3DSurface9 *iface) DECLSPEC_HIDDEN;
+
+struct d3d9_vertexbuffer
+{
+ IDirect3DVertexBuffer9 IDirect3DVertexBuffer9_iface;
+ LONG refcount;
+ struct wined3d_buffer *wined3d_buffer;
+ IDirect3DDevice9Ex *parent_device;
+ DWORD fvf;
+};
+
+HRESULT vertexbuffer_init(struct d3d9_vertexbuffer *buffer, struct d3d9_device *device,
+ UINT size, UINT usage, DWORD fvf, D3DPOOL pool) DECLSPEC_HIDDEN;
+struct d3d9_vertexbuffer *unsafe_impl_from_IDirect3DVertexBuffer9(IDirect3DVertexBuffer9 *iface) DECLSPEC_HIDDEN;
+
+struct d3d9_indexbuffer
+{
+ IDirect3DIndexBuffer9 IDirect3DIndexBuffer9_iface;
+ LONG refcount;
+ struct wined3d_buffer *wined3d_buffer;
+ IDirect3DDevice9Ex *parent_device;
+ enum wined3d_format_id format;
+};
+
+HRESULT indexbuffer_init(struct d3d9_indexbuffer *buffer, struct d3d9_device *device,
+ UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool) DECLSPEC_HIDDEN;
+struct d3d9_indexbuffer *unsafe_impl_from_IDirect3DIndexBuffer9(IDirect3DIndexBuffer9 *iface) DECLSPEC_HIDDEN;
+
+struct d3d9_texture
+{
+ IDirect3DBaseTexture9 IDirect3DBaseTexture9_iface;
+ LONG refcount;
+ struct wined3d_texture *wined3d_texture;
+ IDirect3DDevice9Ex *parent_device;
+};
+
+HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,
+ UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void **pavClientMem
+#endif
+ ) DECLSPEC_HIDDEN;
+HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
+ UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void **pavClientMem
+#endif
+ ) DECLSPEC_HIDDEN;
+HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,
+ UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void **pavClientMem
+#endif
+ ) DECLSPEC_HIDDEN;
+struct d3d9_texture *unsafe_impl_from_IDirect3DBaseTexture9(IDirect3DBaseTexture9 *iface) DECLSPEC_HIDDEN;
+
+struct d3d9_stateblock
+{
+ IDirect3DStateBlock9 IDirect3DStateBlock9_iface;
+ LONG refcount;
+ struct wined3d_stateblock *wined3d_stateblock;
+ IDirect3DDevice9Ex *parent_device;
+};
+
+HRESULT stateblock_init(struct d3d9_stateblock *stateblock, struct d3d9_device *device,
+ D3DSTATEBLOCKTYPE type, struct wined3d_stateblock *wined3d_stateblock) DECLSPEC_HIDDEN;
+
+struct d3d9_vertex_declaration
+{
+ IDirect3DVertexDeclaration9 IDirect3DVertexDeclaration9_iface;
+ LONG refcount;
+ D3DVERTEXELEMENT9 *elements;
+ UINT element_count;
+ struct wined3d_vertex_declaration *wined3d_declaration;
+ DWORD fvf;
+ IDirect3DDevice9Ex *parent_device;
+};
+
+HRESULT d3d9_vertex_declaration_create(struct d3d9_device *device,
+ const D3DVERTEXELEMENT9 *elements, struct d3d9_vertex_declaration **declaration) DECLSPEC_HIDDEN;
+struct d3d9_vertex_declaration *unsafe_impl_from_IDirect3DVertexDeclaration9(
+ IDirect3DVertexDeclaration9 *iface) DECLSPEC_HIDDEN;
+
+struct d3d9_vertexshader
+{
+ IDirect3DVertexShader9 IDirect3DVertexShader9_iface;
+ LONG refcount;
+ struct wined3d_shader *wined3d_shader;
+ IDirect3DDevice9Ex *parent_device;
+};
+
+HRESULT vertexshader_init(struct d3d9_vertexshader *shader,
+ struct d3d9_device *device, const DWORD *byte_code) DECLSPEC_HIDDEN;
+struct d3d9_vertexshader *unsafe_impl_from_IDirect3DVertexShader9(IDirect3DVertexShader9 *iface) DECLSPEC_HIDDEN;
+
+#define D3D9_MAX_VERTEX_SHADER_CONSTANTF 256
+#define D3D9_MAX_SIMULTANEOUS_RENDERTARGETS 4
+
+struct d3d9_pixelshader
+{
+ IDirect3DPixelShader9 IDirect3DPixelShader9_iface;
+ LONG refcount;
+ struct wined3d_shader *wined3d_shader;
+ IDirect3DDevice9Ex *parent_device;
+};
+
+HRESULT pixelshader_init(struct d3d9_pixelshader *shader,
+ struct d3d9_device *device, const DWORD *byte_code) DECLSPEC_HIDDEN;
+struct d3d9_pixelshader *unsafe_impl_from_IDirect3DPixelShader9(IDirect3DPixelShader9 *iface) DECLSPEC_HIDDEN;
+
+struct d3d9_query
+{
+ IDirect3DQuery9 IDirect3DQuery9_iface;
+ LONG refcount;
+ struct wined3d_query *wined3d_query;
+ IDirect3DDevice9Ex *parent_device;
+};
+
+HRESULT query_init(struct d3d9_query *query, struct d3d9_device *device, D3DQUERYTYPE type) DECLSPEC_HIDDEN;
+
+#ifdef VBOX_WITH_WDDM
+struct d3d9_volume *unsafe_impl_from_IDirect3DVolume9(IDirect3DVolume9 *iface) DECLSPEC_HIDDEN;
+#endif
+
+#endif /* __WINE_D3D9_PRIVATE_H */
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/d3d9wddm.def b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/d3d9wddm.def
new file mode 100644
index 00000000..41ff1fde
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/d3d9wddm.def
@@ -0,0 +1,27 @@
+
+EXPORTS
+ Direct3DShaderValidatorCreate9
+ D3DPERF_BeginEvent
+ D3DPERF_EndEvent
+ D3DPERF_GetStatus
+ D3DPERF_QueryRepeatFrame
+ D3DPERF_SetMarker
+ D3DPERF_SetOptions
+ D3DPERF_SetRegion
+ DebugSetMute
+ Direct3DCreate9
+ Direct3DCreate9Ex
+ VBoxWineExD3DDev9Flush
+ VBoxWineExD3DDev9GetHostId
+ VBoxWineExD3DDev9Finish
+ VBoxWineExD3DDev9CreateTexture
+ VBoxWineExD3DDev9CreateCubeTexture
+ VBoxWineExD3DDev9CreateVolumeTexture
+ VBoxWineExD3DDev9Term
+ VBoxWineExD3DSwapchain9Present
+ VBoxWineExD3DDev9VolBlt
+ VBoxWineExD3DDev9VolTexBlt
+ VBoxWineExD3DSurf9GetHostId
+ VBoxWineExD3DSwapchain9GetHostWinID
+ VBoxWineExD3DSurf9SyncToHost
+ VBoxWineExD3DDev9FlushToHost
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/d3d9xpdm.def b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/d3d9xpdm.def
new file mode 100644
index 00000000..1ef868de
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/d3d9xpdm.def
@@ -0,0 +1,13 @@
+
+EXPORTS
+ Direct3DShaderValidatorCreate9
+ D3DPERF_BeginEvent
+ D3DPERF_EndEvent
+ D3DPERF_GetStatus
+ D3DPERF_QueryRepeatFrame
+ D3DPERF_SetMarker
+ D3DPERF_SetOptions
+ D3DPERF_SetRegion
+ DebugSetMute
+ Direct3DCreate9
+ Direct3DCreate9Ex
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/device.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/device.c
new file mode 100644
index 00000000..2bdea740
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/device.c
@@ -0,0 +1,3964 @@
+/*
+ * IDirect3DDevice9 implementation
+ *
+ * Copyright 2002-2005 Jason Edmeades
+ * Copyright 2002-2005 Raphael Junqueira
+ * Copyright 2005 Oliver Stieber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "d3d9_private.h"
+
+#ifdef VBOX_WITH_WDDM
+# include <iprt/assert.h>
+# include "../../common/VBoxVideoTools.h"
+#endif
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
+D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format)
+{
+ BYTE *c = (BYTE *)&format;
+
+ /* Don't translate FOURCC formats */
+ if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format;
+
+ switch(format)
+ {
+ case WINED3DFMT_UNKNOWN: return D3DFMT_UNKNOWN;
+ case WINED3DFMT_B8G8R8_UNORM: return D3DFMT_R8G8B8;
+ case WINED3DFMT_B8G8R8A8_UNORM: return D3DFMT_A8R8G8B8;
+ case WINED3DFMT_B8G8R8X8_UNORM: return D3DFMT_X8R8G8B8;
+ case WINED3DFMT_B5G6R5_UNORM: return D3DFMT_R5G6B5;
+ case WINED3DFMT_B5G5R5X1_UNORM: return D3DFMT_X1R5G5B5;
+ case WINED3DFMT_B5G5R5A1_UNORM: return D3DFMT_A1R5G5B5;
+ case WINED3DFMT_B4G4R4A4_UNORM: return D3DFMT_A4R4G4B4;
+ case WINED3DFMT_B2G3R3_UNORM: return D3DFMT_R3G3B2;
+ case WINED3DFMT_A8_UNORM: return D3DFMT_A8;
+ case WINED3DFMT_B2G3R3A8_UNORM: return D3DFMT_A8R3G3B2;
+ case WINED3DFMT_B4G4R4X4_UNORM: return D3DFMT_X4R4G4B4;
+ case WINED3DFMT_R10G10B10A2_UNORM: return D3DFMT_A2B10G10R10;
+ case WINED3DFMT_R8G8B8A8_UNORM: return D3DFMT_A8B8G8R8;
+ case WINED3DFMT_R8G8B8X8_UNORM: return D3DFMT_X8B8G8R8;
+ case WINED3DFMT_R16G16_UNORM: return D3DFMT_G16R16;
+ case WINED3DFMT_B10G10R10A2_UNORM: return D3DFMT_A2R10G10B10;
+ case WINED3DFMT_R16G16B16A16_UNORM: return D3DFMT_A16B16G16R16;
+ case WINED3DFMT_P8_UINT_A8_UNORM: return D3DFMT_A8P8;
+ case WINED3DFMT_P8_UINT: return D3DFMT_P8;
+ case WINED3DFMT_L8_UNORM: return D3DFMT_L8;
+ case WINED3DFMT_L8A8_UNORM: return D3DFMT_A8L8;
+ case WINED3DFMT_L4A4_UNORM: return D3DFMT_A4L4;
+ case WINED3DFMT_R8G8_SNORM: return D3DFMT_V8U8;
+ case WINED3DFMT_R5G5_SNORM_L6_UNORM: return D3DFMT_L6V5U5;
+ case WINED3DFMT_R8G8_SNORM_L8X8_UNORM: return D3DFMT_X8L8V8U8;
+ case WINED3DFMT_R8G8B8A8_SNORM: return D3DFMT_Q8W8V8U8;
+ case WINED3DFMT_R16G16_SNORM: return D3DFMT_V16U16;
+ case WINED3DFMT_R10G10B10_SNORM_A2_UNORM: return D3DFMT_A2W10V10U10;
+ case WINED3DFMT_D16_LOCKABLE: return D3DFMT_D16_LOCKABLE;
+ case WINED3DFMT_D32_UNORM: return D3DFMT_D32;
+ case WINED3DFMT_S1_UINT_D15_UNORM: return D3DFMT_D15S1;
+ case WINED3DFMT_D24_UNORM_S8_UINT: return D3DFMT_D24S8;
+ case WINED3DFMT_X8D24_UNORM: return D3DFMT_D24X8;
+ case WINED3DFMT_S4X4_UINT_D24_UNORM: return D3DFMT_D24X4S4;
+ case WINED3DFMT_D16_UNORM: return D3DFMT_D16;
+ case WINED3DFMT_L16_UNORM: return D3DFMT_L16;
+ case WINED3DFMT_D32_FLOAT: return D3DFMT_D32F_LOCKABLE;
+ case WINED3DFMT_S8_UINT_D24_FLOAT: return D3DFMT_D24FS8;
+ case WINED3DFMT_VERTEXDATA: return D3DFMT_VERTEXDATA;
+ case WINED3DFMT_R16_UINT: return D3DFMT_INDEX16;
+ case WINED3DFMT_R32_UINT: return D3DFMT_INDEX32;
+ case WINED3DFMT_R16G16B16A16_SNORM: return D3DFMT_Q16W16V16U16;
+ case WINED3DFMT_R16_FLOAT: return D3DFMT_R16F;
+ case WINED3DFMT_R16G16_FLOAT: return D3DFMT_G16R16F;
+ case WINED3DFMT_R16G16B16A16_FLOAT: return D3DFMT_A16B16G16R16F;
+ case WINED3DFMT_R32_FLOAT: return D3DFMT_R32F;
+ case WINED3DFMT_R32G32_FLOAT: return D3DFMT_G32R32F;
+ case WINED3DFMT_R32G32B32A32_FLOAT: return D3DFMT_A32B32G32R32F;
+ case WINED3DFMT_R8G8_SNORM_Cx: return D3DFMT_CxV8U8;
+ default:
+ FIXME("Unhandled wined3d format %#x.\n", format);
+ return D3DFMT_UNKNOWN;
+ }
+}
+
+enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format)
+{
+ BYTE *c = (BYTE *)&format;
+
+ /* Don't translate FOURCC formats */
+ if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format;
+
+ switch(format)
+ {
+ case D3DFMT_UNKNOWN: return WINED3DFMT_UNKNOWN;
+ case D3DFMT_R8G8B8: return WINED3DFMT_B8G8R8_UNORM;
+ case D3DFMT_A8R8G8B8: return WINED3DFMT_B8G8R8A8_UNORM;
+ case D3DFMT_X8R8G8B8: return WINED3DFMT_B8G8R8X8_UNORM;
+ case D3DFMT_R5G6B5: return WINED3DFMT_B5G6R5_UNORM;
+ case D3DFMT_X1R5G5B5: return WINED3DFMT_B5G5R5X1_UNORM;
+ case D3DFMT_A1R5G5B5: return WINED3DFMT_B5G5R5A1_UNORM;
+ case D3DFMT_A4R4G4B4: return WINED3DFMT_B4G4R4A4_UNORM;
+ case D3DFMT_R3G3B2: return WINED3DFMT_B2G3R3_UNORM;
+ case D3DFMT_A8: return WINED3DFMT_A8_UNORM;
+ case D3DFMT_A8R3G3B2: return WINED3DFMT_B2G3R3A8_UNORM;
+ case D3DFMT_X4R4G4B4: return WINED3DFMT_B4G4R4X4_UNORM;
+ case D3DFMT_A2B10G10R10: return WINED3DFMT_R10G10B10A2_UNORM;
+ case D3DFMT_A8B8G8R8: return WINED3DFMT_R8G8B8A8_UNORM;
+ case D3DFMT_X8B8G8R8: return WINED3DFMT_R8G8B8X8_UNORM;
+ case D3DFMT_G16R16: return WINED3DFMT_R16G16_UNORM;
+ case D3DFMT_A2R10G10B10: return WINED3DFMT_B10G10R10A2_UNORM;
+ case D3DFMT_A16B16G16R16: return WINED3DFMT_R16G16B16A16_UNORM;
+ case D3DFMT_A8P8: return WINED3DFMT_P8_UINT_A8_UNORM;
+ case D3DFMT_P8: return WINED3DFMT_P8_UINT;
+ case D3DFMT_L8: return WINED3DFMT_L8_UNORM;
+ case D3DFMT_A8L8: return WINED3DFMT_L8A8_UNORM;
+ case D3DFMT_A4L4: return WINED3DFMT_L4A4_UNORM;
+ case D3DFMT_V8U8: return WINED3DFMT_R8G8_SNORM;
+ case D3DFMT_L6V5U5: return WINED3DFMT_R5G5_SNORM_L6_UNORM;
+ case D3DFMT_X8L8V8U8: return WINED3DFMT_R8G8_SNORM_L8X8_UNORM;
+ case D3DFMT_Q8W8V8U8: return WINED3DFMT_R8G8B8A8_SNORM;
+ case D3DFMT_V16U16: return WINED3DFMT_R16G16_SNORM;
+ case D3DFMT_A2W10V10U10: return WINED3DFMT_R10G10B10_SNORM_A2_UNORM;
+ case D3DFMT_D16_LOCKABLE: return WINED3DFMT_D16_LOCKABLE;
+ case D3DFMT_D32: return WINED3DFMT_D32_UNORM;
+ case D3DFMT_D15S1: return WINED3DFMT_S1_UINT_D15_UNORM;
+ case D3DFMT_D24S8: return WINED3DFMT_D24_UNORM_S8_UINT;
+ case D3DFMT_D24X8: return WINED3DFMT_X8D24_UNORM;
+ case D3DFMT_D24X4S4: return WINED3DFMT_S4X4_UINT_D24_UNORM;
+ case D3DFMT_D16: return WINED3DFMT_D16_UNORM;
+ case D3DFMT_L16: return WINED3DFMT_L16_UNORM;
+ case D3DFMT_D32F_LOCKABLE: return WINED3DFMT_D32_FLOAT;
+ case D3DFMT_D24FS8: return WINED3DFMT_S8_UINT_D24_FLOAT;
+ case D3DFMT_VERTEXDATA: return WINED3DFMT_VERTEXDATA;
+ case D3DFMT_INDEX16: return WINED3DFMT_R16_UINT;
+ case D3DFMT_INDEX32: return WINED3DFMT_R32_UINT;
+ case D3DFMT_Q16W16V16U16: return WINED3DFMT_R16G16B16A16_SNORM;
+ case D3DFMT_R16F: return WINED3DFMT_R16_FLOAT;
+ case D3DFMT_G16R16F: return WINED3DFMT_R16G16_FLOAT;
+ case D3DFMT_A16B16G16R16F: return WINED3DFMT_R16G16B16A16_FLOAT;
+ case D3DFMT_R32F: return WINED3DFMT_R32_FLOAT;
+ case D3DFMT_G32R32F: return WINED3DFMT_R32G32_FLOAT;
+ case D3DFMT_A32B32G32R32F: return WINED3DFMT_R32G32B32A32_FLOAT;
+ case D3DFMT_CxV8U8: return WINED3DFMT_R8G8_SNORM_Cx;
+ default:
+ FIXME("Unhandled D3DFORMAT %#x\n", format);
+ return WINED3DFMT_UNKNOWN;
+ }
+}
+
+static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count)
+{
+ switch(primitive_type)
+ {
+ case D3DPT_POINTLIST:
+ return primitive_count;
+
+ case D3DPT_LINELIST:
+ return primitive_count * 2;
+
+ case D3DPT_LINESTRIP:
+ return primitive_count + 1;
+
+ case D3DPT_TRIANGLELIST:
+ return primitive_count * 3;
+
+ case D3DPT_TRIANGLESTRIP:
+ case D3DPT_TRIANGLEFAN:
+ return primitive_count + 2;
+
+ default:
+ FIXME("Unhandled primitive type %#x\n", primitive_type);
+ return 0;
+ }
+}
+
+void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters,
+ const struct wined3d_swapchain_desc *swapchain_desc)
+{
+ present_parameters->BackBufferWidth = swapchain_desc->backbuffer_width;
+ present_parameters->BackBufferHeight = swapchain_desc->backbuffer_height;
+ present_parameters->BackBufferFormat = d3dformat_from_wined3dformat(swapchain_desc->backbuffer_format);
+ present_parameters->BackBufferCount = swapchain_desc->backbuffer_count;
+ present_parameters->MultiSampleType = swapchain_desc->multisample_type;
+ present_parameters->MultiSampleQuality = swapchain_desc->multisample_quality;
+ present_parameters->SwapEffect = swapchain_desc->swap_effect;
+ present_parameters->hDeviceWindow = swapchain_desc->device_window;
+ present_parameters->Windowed = swapchain_desc->windowed;
+ present_parameters->EnableAutoDepthStencil = swapchain_desc->enable_auto_depth_stencil;
+ present_parameters->AutoDepthStencilFormat
+ = d3dformat_from_wined3dformat(swapchain_desc->auto_depth_stencil_format);
+ present_parameters->Flags = swapchain_desc->flags;
+ present_parameters->FullScreen_RefreshRateInHz = swapchain_desc->refresh_rate;
+ present_parameters->PresentationInterval = swapchain_desc->swap_interval;
+}
+
+static void wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc,
+ const D3DPRESENT_PARAMETERS *present_parameters)
+{
+ swapchain_desc->backbuffer_width = present_parameters->BackBufferWidth;
+ swapchain_desc->backbuffer_height = present_parameters->BackBufferHeight;
+ swapchain_desc->backbuffer_format = wined3dformat_from_d3dformat(present_parameters->BackBufferFormat);
+ swapchain_desc->backbuffer_count = max(1, present_parameters->BackBufferCount);
+ swapchain_desc->multisample_type = present_parameters->MultiSampleType;
+ swapchain_desc->multisample_quality = present_parameters->MultiSampleQuality;
+ swapchain_desc->swap_effect = present_parameters->SwapEffect;
+ swapchain_desc->device_window = present_parameters->hDeviceWindow;
+ swapchain_desc->windowed = present_parameters->Windowed;
+ swapchain_desc->enable_auto_depth_stencil = present_parameters->EnableAutoDepthStencil;
+ swapchain_desc->auto_depth_stencil_format
+ = wined3dformat_from_d3dformat(present_parameters->AutoDepthStencilFormat);
+ swapchain_desc->flags = present_parameters->Flags;
+ swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz;
+ swapchain_desc->swap_interval = present_parameters->PresentationInterval;
+ swapchain_desc->auto_restore_display_mode = TRUE;
+#ifdef VBOX_WITH_WDDM
+ swapchain_desc->pHgsmi = NULL;
+#endif
+
+}
+
+static inline struct d3d9_device *impl_from_IDirect3DDevice9Ex(IDirect3DDevice9Ex *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d9_device, IDirect3DDevice9Ex_iface);
+}
+
+static HRESULT WINAPI d3d9_device_QueryInterface(IDirect3DDevice9Ex *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DDevice9)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DDevice9Ex_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ if (IsEqualGUID(riid, &IID_IDirect3DDevice9Ex))
+ {
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ /* Find out if the creating d3d9 interface was created with Direct3DCreate9Ex.
+ * It doesn't matter with which function the device was created. */
+ if (!device->d3d_parent->extended)
+ {
+ WARN("IDirect3D9 instance wasn't created with CreateDirect3D9Ex, returning E_NOINTERFACE.\n");
+ *out = NULL;
+ return E_NOINTERFACE;
+ }
+
+ IDirect3DDevice9Ex_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d9_device_AddRef(IDirect3DDevice9Ex *iface)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ ULONG refcount = InterlockedIncrement(&device->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, refcount);
+
+ return refcount;
+}
+
+#ifdef VBOX
+static LONG d3d9_device_Term(struct d3d9_device *device)
+{
+ unsigned i;
+ LONG refs = device->refcount;
+ LONG wined3d_refs;
+ device->in_destruction = TRUE;
+
+ if (refs != 1)
+ {
+ WARN("unexpected ref count %d, destroying in anyway", refs);
+ }
+
+ wined3d_mutex_lock();
+ for (i = 0; i < device->fvf_decl_count; ++i)
+ {
+ wined3d_vertex_declaration_decref(device->fvf_decls[i].decl);
+ }
+ HeapFree(GetProcessHeap(), 0, device->fvf_decls);
+
+ if (device->vertex_buffer)
+ wined3d_buffer_decref(device->vertex_buffer);
+ if (device->index_buffer)
+ wined3d_buffer_decref(device->index_buffer);
+
+ wined3d_device_uninit_3d(device->wined3d_device);
+# ifndef VBOX_WITH_WDDM
+ wined3d_device_release_focus_window(device->wined3d_device);
+# endif
+ wined3d_refs = wined3d_device_decref(device->wined3d_device);
+ wined3d_mutex_unlock();
+
+ IDirect3D9Ex_Release(&device->d3d_parent->IDirect3D9Ex_iface);
+
+ HeapFree(GetProcessHeap(), 0, device);
+
+ return wined3d_refs;
+}
+#endif
+
+static ULONG WINAPI DECLSPEC_HOTPATCH d3d9_device_Release(IDirect3DDevice9Ex *iface)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ ULONG refcount;
+
+ if (device->in_destruction)
+ return 0;
+
+ refcount = InterlockedDecrement(&device->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+#ifdef VBOX
+ d3d9_device_Term(device);
+#else
+ unsigned i;
+ device->in_destruction = TRUE;
+
+ wined3d_mutex_lock();
+ for (i = 0; i < device->fvf_decl_count; ++i)
+ {
+ wined3d_vertex_declaration_decref(device->fvf_decls[i].decl);
+ }
+ HeapFree(GetProcessHeap(), 0, device->fvf_decls);
+
+ if (device->vertex_buffer)
+ wined3d_buffer_decref(device->vertex_buffer);
+ if (device->index_buffer)
+ wined3d_buffer_decref(device->index_buffer);
+
+ wined3d_device_uninit_3d(device->wined3d_device);
+ wined3d_device_release_focus_window(device->wined3d_device);
+ wined3d_device_decref(device->wined3d_device);
+ wined3d_mutex_unlock();
+
+ IDirect3D9Ex_Release(&device->d3d_parent->IDirect3D9Ex_iface);
+
+ HeapFree(GetProcessHeap(), 0, device);
+#endif
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI d3d9_device_TestCooperativeLevel(IDirect3DDevice9Ex *iface)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ if (device->not_reset)
+ {
+ TRACE("D3D9 device is marked not reset.\n");
+ return D3DERR_DEVICENOTRESET;
+ }
+
+ return D3D_OK;
+}
+
+static UINT WINAPI d3d9_device_GetAvailableTextureMem(IDirect3DDevice9Ex *iface)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_available_texture_mem(device->wined3d_device);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_EvictManagedResources(IDirect3DDevice9Ex *iface)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_device_evict_managed_resources(device->wined3d_device);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_GetDirect3D(IDirect3DDevice9Ex *iface, IDirect3D9 **d3d9)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, d3d9 %p.\n", iface, d3d9);
+
+ if (!d3d9)
+ return D3DERR_INVALIDCALL;
+
+ return IDirect3D9Ex_QueryInterface(&device->d3d_parent->IDirect3D9Ex_iface, &IID_IDirect3D9, (void **)d3d9);
+}
+
+static HRESULT WINAPI d3d9_device_GetDeviceCaps(IDirect3DDevice9Ex *iface, D3DCAPS9 *caps)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ WINED3DCAPS *wined3d_caps;
+ HRESULT hr;
+
+ TRACE("iface %p, caps %p.\n", iface, caps);
+
+ if (!caps)
+ return D3DERR_INVALIDCALL;
+
+ if (!(wined3d_caps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wined3d_caps))))
+ return D3DERR_INVALIDCALL; /* well this is what MSDN says to return */
+
+ memset(caps, 0, sizeof(*caps));
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_device_caps(device->wined3d_device, wined3d_caps);
+ wined3d_mutex_unlock();
+
+ WINECAPSTOD3D9CAPS(caps, wined3d_caps)
+ HeapFree(GetProcessHeap(), 0, wined3d_caps);
+
+ /* Some functionality is implemented in d3d9.dll, not wined3d.dll. Add the needed caps */
+ caps->DevCaps2 |= D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES;
+
+ filter_caps(caps);
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetDisplayMode(IDirect3DDevice9Ex *iface, UINT swapchain, D3DDISPLAYMODE *mode)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct wined3d_display_mode wined3d_mode;
+ HRESULT hr;
+
+ TRACE("iface %p, swapchain %u, mode %p.\n", iface, swapchain, mode);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_display_mode(device->wined3d_device, swapchain, &wined3d_mode, NULL);
+ wined3d_mutex_unlock();
+
+ if (SUCCEEDED(hr))
+ {
+ mode->Width = wined3d_mode.width;
+ mode->Height = wined3d_mode.height;
+ mode->RefreshRate = wined3d_mode.refresh_rate;
+ mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id);
+ }
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetCreationParameters(IDirect3DDevice9Ex *iface,
+ D3DDEVICE_CREATION_PARAMETERS *parameters)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, parameters %p.\n", iface, parameters);
+
+ wined3d_mutex_lock();
+ wined3d_device_get_creation_parameters(device->wined3d_device,
+ (struct wined3d_device_creation_parameters *)parameters);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_SetCursorProperties(IDirect3DDevice9Ex *iface,
+ UINT hotspot_x, UINT hotspot_y, IDirect3DSurface9 *bitmap)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_surface *bitmap_impl = unsafe_impl_from_IDirect3DSurface9(bitmap);
+ HRESULT hr;
+
+ TRACE("iface %p, hotspot_x %u, hotspot_y %u, bitmap %p.\n",
+ iface, hotspot_x, hotspot_y, bitmap);
+
+ if (!bitmap)
+ {
+ WARN("No cursor bitmap, returning D3DERR_INVALIDCALL.\n");
+ return D3DERR_INVALIDCALL;
+ }
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_cursor_properties(device->wined3d_device,
+ hotspot_x, hotspot_y, bitmap_impl->wined3d_surface);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static void WINAPI d3d9_device_SetCursorPosition(IDirect3DDevice9Ex *iface, int x, int y, DWORD flags)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, x %u, y %u, flags %#x.\n", iface, x, y, flags);
+
+ wined3d_mutex_lock();
+ wined3d_device_set_cursor_position(device->wined3d_device, x, y, flags);
+ wined3d_mutex_unlock();
+}
+
+static BOOL WINAPI d3d9_device_ShowCursor(IDirect3DDevice9Ex *iface, BOOL show)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ BOOL ret;
+
+ TRACE("iface %p, show %#x.\n", iface, show);
+
+ wined3d_mutex_lock();
+ ret = wined3d_device_show_cursor(device->wined3d_device, show);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_CreateAdditionalSwapChain(IDirect3DDevice9Ex *iface,
+ D3DPRESENT_PARAMETERS *present_parameters, IDirect3DSwapChain9 **swapchain)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct wined3d_swapchain_desc desc;
+ struct d3d9_swapchain *object;
+ HRESULT hr;
+
+ TRACE("iface %p, present_parameters %p, swapchain %p.\n",
+ iface, present_parameters, swapchain);
+
+ wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters);
+ if (SUCCEEDED(hr = d3d9_swapchain_create(device, &desc, &object)))
+ *swapchain = &object->IDirect3DSwapChain9_iface;
+ present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc);
+
+ return hr;
+}
+
+static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_GetSwapChain(IDirect3DDevice9Ex *iface,
+ UINT swapchain_idx, IDirect3DSwapChain9 **swapchain)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct wined3d_swapchain *wined3d_swapchain;
+ struct d3d9_swapchain *swapchain_impl;
+ HRESULT hr;
+
+ TRACE("iface %p, swapchain_idx %u, swapchain %p.\n", iface, swapchain_idx, swapchain);
+
+ wined3d_mutex_lock();
+ if ((wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, swapchain_idx)))
+ {
+ swapchain_impl = wined3d_swapchain_get_parent(wined3d_swapchain);
+ *swapchain = &swapchain_impl->IDirect3DSwapChain9_iface;
+ IDirect3DSwapChain9_AddRef(*swapchain);
+ hr = D3D_OK;
+ }
+ else
+ {
+ *swapchain = NULL;
+ hr = D3DERR_INVALIDCALL;
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static UINT WINAPI d3d9_device_GetNumberOfSwapChains(IDirect3DDevice9Ex *iface)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ UINT count;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ count = wined3d_device_get_swapchain_count(device->wined3d_device);
+ wined3d_mutex_unlock();
+
+ return count;
+}
+
+static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource)
+{
+ struct wined3d_resource_desc desc;
+
+ wined3d_resource_get_desc(resource, &desc);
+ if (desc.pool == WINED3D_POOL_DEFAULT)
+ {
+ struct d3d9_surface *surface;
+
+ if (desc.resource_type == WINED3D_RTYPE_TEXTURE)
+ {
+ IUnknown *parent = wined3d_resource_get_parent(resource);
+ IDirect3DBaseTexture9 *texture;
+
+ if (SUCCEEDED(IUnknown_QueryInterface(parent, &IID_IDirect3DBaseTexture9, (void **)&texture)))
+ {
+ IDirect3DBaseTexture9_Release(texture);
+ WARN("Texture %p (resource %p) in pool D3DPOOL_DEFAULT blocks the Reset call.\n", texture, resource);
+ return D3DERR_INVALIDCALL;
+ }
+
+ return D3D_OK;
+ }
+
+ if (desc.resource_type != WINED3D_RTYPE_SURFACE)
+ {
+ WARN("Resource %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", resource);
+ return D3DERR_INVALIDCALL;
+ }
+
+ surface = wined3d_resource_get_parent(resource);
+ if (surface->refcount)
+ {
+ WARN("Surface %p (resource %p) in pool D3DPOOL_DEFAULT blocks the Reset call.\n", surface, resource);
+ return D3DERR_INVALIDCALL;
+ }
+
+ WARN("Surface %p (resource %p) is an implicit resource with ref 0.\n", surface, resource);
+ }
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_Reset(IDirect3DDevice9Ex *iface,
+ D3DPRESENT_PARAMETERS *present_parameters)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct wined3d_swapchain_desc swapchain_desc;
+ HRESULT hr;
+
+ TRACE("iface %p, present_parameters %p.\n", iface, present_parameters);
+
+ wined3d_mutex_lock();
+
+ if (device->vertex_buffer)
+ {
+ wined3d_buffer_decref(device->vertex_buffer);
+ device->vertex_buffer = NULL;
+ device->vertex_buffer_size = 0;
+ }
+ if (device->index_buffer)
+ {
+ wined3d_buffer_decref(device->index_buffer);
+ device->index_buffer = NULL;
+ device->index_buffer_size = 0;
+ }
+
+ wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, present_parameters);
+ hr = wined3d_device_reset(device->wined3d_device, &swapchain_desc,
+ NULL, reset_enum_callback, !device->d3d_parent->extended);
+ if (FAILED(hr) && !device->d3d_parent->extended)
+ device->not_reset = TRUE;
+ else
+ device->not_reset = FALSE;
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_Present(IDirect3DDevice9Ex *iface,
+ const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, src_rect %p, dst_rect %p, dst_window_override %p, dirty_region %p.\n",
+ iface, src_rect, dst_rect, dst_window_override, dirty_region);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_present(device->wined3d_device, src_rect, dst_rect,
+ dst_window_override, dirty_region, 0);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetBackBuffer(IDirect3DDevice9Ex *iface, UINT swapchain,
+ UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface9 **backbuffer)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct wined3d_surface *wined3d_surface = NULL;
+ struct d3d9_surface *surface_impl;
+ HRESULT hr;
+
+ TRACE("iface %p, swapchain %u, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n",
+ iface, swapchain, backbuffer_idx, backbuffer_type, backbuffer);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_back_buffer(device->wined3d_device, swapchain,
+ backbuffer_idx, (enum wined3d_backbuffer_type)backbuffer_type, &wined3d_surface);
+ if (SUCCEEDED(hr) && wined3d_surface && backbuffer)
+ {
+ surface_impl = wined3d_surface_get_parent(wined3d_surface);
+ *backbuffer = &surface_impl->IDirect3DSurface9_iface;
+ IDirect3DSurface9_AddRef(*backbuffer);
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+static HRESULT WINAPI d3d9_device_GetRasterStatus(IDirect3DDevice9Ex *iface,
+ UINT swapchain, D3DRASTER_STATUS *raster_status)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, swapchain %u, raster_status %p.\n", iface, swapchain, raster_status);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_raster_status(device->wined3d_device,
+ swapchain, (struct wined3d_raster_status *)raster_status);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_SetDialogBoxMode(IDirect3DDevice9Ex *iface, BOOL enable)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, enable %#x.\n", iface, enable);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_dialog_box_mode(device->wined3d_device, enable);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static void WINAPI d3d9_device_SetGammaRamp(IDirect3DDevice9Ex *iface,
+ UINT swapchain, DWORD flags, const D3DGAMMARAMP *ramp)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, swapchain %u, flags %#x, ramp %p.\n", iface, swapchain, flags, ramp);
+
+ /* Note: D3DGAMMARAMP is compatible with struct wined3d_gamma_ramp. */
+ wined3d_mutex_lock();
+ wined3d_device_set_gamma_ramp(device->wined3d_device, swapchain, flags, (const struct wined3d_gamma_ramp *)ramp);
+ wined3d_mutex_unlock();
+}
+
+static void WINAPI d3d9_device_GetGammaRamp(IDirect3DDevice9Ex *iface, UINT swapchain, D3DGAMMARAMP *ramp)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, swapchain %u, ramp %p.\n", iface, swapchain, ramp);
+
+ /* Note: D3DGAMMARAMP is compatible with struct wined3d_gamma_ramp. */
+ wined3d_mutex_lock();
+ wined3d_device_get_gamma_ramp(device->wined3d_device, swapchain, (struct wined3d_gamma_ramp *)ramp);
+ wined3d_mutex_unlock();
+}
+
+#ifdef VBOX_WITH_WDDM
+//#pragma comment(linker, "/export:VBoxWineExD3DDev9Flush=_VBoxWineExD3DDev9Flush@4")
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9Flush(IDirect3DDevice9Ex *iface)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, Flush\n", iface);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_flush(device->wined3d_device);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9FlushToHost(IDirect3DDevice9Ex *iface)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, FlushToHost\n", iface);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_flush_to_host(device->wined3d_device);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9Finish(IDirect3DDevice9Ex *iface)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, FlushToHost\n", iface);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_finish(device->wined3d_device);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9GetHostId(IDirect3DDevice9Ex *iface, int32_t *pi32Id)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, FlushToHost\n", iface);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_host_id(device->wined3d_device, pi32Id);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+//#pragma comment(linker, "/export:VBoxWineExD3DDev9CreateTexture=_VBoxWineExD3DDev9CreateTexture@40")
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9CreateTexture(IDirect3DDevice9Ex *iface,
+ UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format,
+ D3DPOOL pool, IDirect3DTexture9 **texture, HANDLE *shared_handle,
+ void **pavClientMem) /* <- extension arg to pass in the client memory buffer,
+ * applicable ONLY for SYSMEM textures */
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_texture *object;
+ HRESULT hr;
+
+ TRACE("iface %p, width %u, height %u, levels %u, usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n",
+ iface, width, height, levels, usage, format, pool, texture, shared_handle);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return D3DERR_OUTOFVIDEOMEMORY;
+
+ hr = texture_init(object, device, width, height, levels, usage, format, pool, shared_handle, pavClientMem);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize texture, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created texture %p.\n", object);
+ *texture = (IDirect3DTexture9 *)&object->IDirect3DBaseTexture9_iface;
+
+ return D3D_OK;
+}
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9CreateVolumeTexture(IDirect3DDevice9Ex *iface,
+ UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format,
+ D3DPOOL pool, IDirect3DVolumeTexture9 **texture, HANDLE *shared_handle,
+ void **pavClientMem)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_texture *object;
+ HRESULT hr;
+
+ TRACE("iface %p, width %u, height %u, depth %u, levels %u\n",
+ iface, width, height, depth, levels);
+ TRACE("usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n",
+ usage, format, pool, texture, shared_handle);
+
+ if (shared_handle)
+ FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return D3DERR_OUTOFVIDEOMEMORY;
+
+ hr = volumetexture_init(object, device, width, height, depth, levels, usage, format, pool, shared_handle, pavClientMem);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize volume texture, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created volume texture %p.\n", object);
+ *texture = (IDirect3DVolumeTexture9 *)&object->IDirect3DBaseTexture9_iface;
+
+ return D3D_OK;
+}
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9CreateCubeTexture(IDirect3DDevice9Ex *iface,
+ UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format,
+ D3DPOOL pool, IDirect3DCubeTexture9 **texture, HANDLE *shared_handle,
+ void **pavClientMem) /* <- extension arg to pass in the client memory buffer,
+ * applicable ONLY for SYSMEM textures */
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_texture *object;
+ HRESULT hr;
+
+ TRACE("iface %p, edge_length %u, levels %u, usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n",
+ iface, edge_length, levels, usage, format, pool, texture, shared_handle);
+
+ if (shared_handle)
+ FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return D3DERR_OUTOFVIDEOMEMORY;
+
+ hr = cubetexture_init(object, device, edge_length, levels, usage, format, pool, shared_handle, pavClientMem);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize cube texture, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created cube texture %p.\n", object);
+ *texture = (IDirect3DCubeTexture9 *)&object->IDirect3DBaseTexture9_iface;
+
+ return D3D_OK;
+}
+
+#endif
+
+static HRESULT WINAPI d3d9_device_CreateTexture(IDirect3DDevice9Ex *iface,
+ UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format,
+ D3DPOOL pool, IDirect3DTexture9 **texture, HANDLE *shared_handle)
+{
+#ifdef VBOX_WITH_WDDM
+ return VBoxWineExD3DDev9CreateTexture(iface, width, height, levels, usage, format,
+ pool, texture, shared_handle,
+ NULL);
+#else
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_texture *object;
+ BOOL set_mem = FALSE;
+ HRESULT hr;
+
+ TRACE("iface %p, width %u, height %u, levels %u, usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n",
+ iface, width, height, levels, usage, format, pool, texture, shared_handle);
+
+ if (shared_handle)
+ {
+ if (pool == D3DPOOL_SYSTEMMEM)
+ {
+ if (levels != 1)
+ return D3DERR_INVALIDCALL;
+ set_mem = TRUE;
+ }
+ else
+ FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
+ }
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return D3DERR_OUTOFVIDEOMEMORY;
+
+ hr = texture_init(object, device, width, height, levels, usage, format, pool);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize texture, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ if (set_mem)
+ {
+ struct wined3d_resource *resource;
+ struct d3d9_surface *surface;
+
+ resource = wined3d_texture_get_sub_resource(object->wined3d_texture, 0);
+ surface = wined3d_resource_get_parent(resource);
+ wined3d_surface_set_mem(surface->wined3d_surface, *shared_handle, 0);
+ }
+
+ TRACE("Created texture %p.\n", object);
+ *texture = (IDirect3DTexture9 *)&object->IDirect3DBaseTexture9_iface;
+
+ return D3D_OK;
+#endif
+}
+
+static HRESULT WINAPI d3d9_device_CreateVolumeTexture(IDirect3DDevice9Ex *iface,
+ UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format,
+ D3DPOOL pool, IDirect3DVolumeTexture9 **texture, HANDLE *shared_handle)
+{
+#ifdef VBOX_WITH_WDDM
+ return VBoxWineExD3DDev9CreateVolumeTexture(iface, width, height, depth, levels, usage, format,
+ pool, texture, shared_handle, NULL);
+#else
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_texture *object;
+ HRESULT hr;
+
+ TRACE("iface %p, width %u, height %u, depth %u, levels %u\n",
+ iface, width, height, depth, levels);
+ TRACE("usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n",
+ usage, format, pool, texture, shared_handle);
+
+ if (shared_handle)
+ FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return D3DERR_OUTOFVIDEOMEMORY;
+
+ hr = volumetexture_init(object, device, width, height, depth, levels, usage, format, pool);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize volume texture, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created volume texture %p.\n", object);
+ *texture = (IDirect3DVolumeTexture9 *)&object->IDirect3DBaseTexture9_iface;
+
+ return D3D_OK;
+#endif
+}
+
+static HRESULT WINAPI d3d9_device_CreateCubeTexture(IDirect3DDevice9Ex *iface,
+ UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool,
+ IDirect3DCubeTexture9 **texture, HANDLE *shared_handle)
+{
+#ifdef VBOX_WITH_WDDM
+ return VBoxWineExD3DDev9CreateCubeTexture(iface, edge_length, levels, usage, format,
+ pool, texture, shared_handle, NULL);
+#else
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_texture *object;
+ HRESULT hr;
+
+ TRACE("iface %p, edge_length %u, levels %u, usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n",
+ iface, edge_length, levels, usage, format, pool, texture, shared_handle);
+
+ if (shared_handle)
+ FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return D3DERR_OUTOFVIDEOMEMORY;
+
+ hr = cubetexture_init(object, device, edge_length, levels, usage, format, pool);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize cube texture, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created cube texture %p.\n", object);
+ *texture = (IDirect3DCubeTexture9 *)&object->IDirect3DBaseTexture9_iface;
+
+ return D3D_OK;
+#endif
+}
+
+static HRESULT WINAPI d3d9_device_CreateVertexBuffer(IDirect3DDevice9Ex *iface, UINT size,
+ DWORD usage, DWORD fvf, D3DPOOL pool, IDirect3DVertexBuffer9 **buffer,
+ HANDLE *shared_handle)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_vertexbuffer *object;
+ HRESULT hr;
+
+ TRACE("iface %p, size %u, usage %#x, fvf %#x, pool %#x, buffer %p, shared_handle %p.\n",
+ iface, size, usage, fvf, pool, buffer, shared_handle);
+
+ if (shared_handle)
+ FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return D3DERR_OUTOFVIDEOMEMORY;
+
+ hr = vertexbuffer_init(object, device, size, usage, fvf, pool);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize vertex buffer, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created vertex buffer %p.\n", object);
+ *buffer = &object->IDirect3DVertexBuffer9_iface;
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_CreateIndexBuffer(IDirect3DDevice9Ex *iface, UINT size,
+ DWORD usage, D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer9 **buffer,
+ HANDLE *shared_handle)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_indexbuffer *object;
+ HRESULT hr;
+
+ TRACE("iface %p, size %u, usage %#x, format %#x, pool %#x, buffer %p, shared_handle %p.\n",
+ iface, size, usage, format, pool, buffer, shared_handle);
+
+ if (shared_handle)
+ FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return D3DERR_OUTOFVIDEOMEMORY;
+
+ hr = indexbuffer_init(object, device, size, usage, format, pool);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize index buffer, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created index buffer %p.\n", object);
+ *buffer = &object->IDirect3DIndexBuffer9_iface;
+
+ return D3D_OK;
+}
+
+static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width, UINT height,
+ D3DFORMAT format, DWORD flags, IDirect3DSurface9 **surface, UINT usage, D3DPOOL pool,
+ D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void *pvClientMem
+#endif
+ )
+{
+ struct d3d9_surface *object;
+ HRESULT hr;
+
+ TRACE("device %p, width %u, height %u, format %#x, flags %#x, surface %p.\n"
+ "usage %#x, pool %#x, multisample_type %#x, multisample_quality %u.\n",
+ device, width, height, format, flags, surface, usage, pool,
+ multisample_type, multisample_quality);
+
+ if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+ {
+ FIXME("Failed to allocate surface memory.\n");
+ return D3DERR_OUTOFVIDEOMEMORY;
+ }
+
+#ifdef VBOX_WITH_WDDM
+ if (FAILED(hr = surface_init(object, device, width, height, format,
+ flags, usage, pool, multisample_type, multisample_quality
+ , shared_handle
+ , pvClientMem
+ )))
+#else
+ if (FAILED(hr = surface_init(object, device, width, height, format,
+ flags, usage, pool, multisample_type, multisample_quality)))
+#endif
+ {
+ WARN("Failed to initialize surface, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created surface %p.\n", object);
+ *surface = &object->IDirect3DSurface9_iface;
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_CreateRenderTarget(IDirect3DDevice9Ex *iface, UINT width, UINT height,
+ D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality,
+ BOOL lockable, IDirect3DSurface9 **surface, HANDLE *shared_handle)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ DWORD flags = 0;
+
+ TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u.\n"
+ "lockable %#x, surface %p, shared_handle %p.\n",
+ iface, width, height, format, multisample_type, multisample_quality,
+ lockable, surface, shared_handle);
+
+ if (shared_handle)
+ FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
+
+ if (lockable)
+ flags |= WINED3D_SURFACE_MAPPABLE;
+
+ return d3d9_device_create_surface(device, width, height, format, flags, surface,
+ D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, multisample_type, multisample_quality
+#ifdef VBOX_WITH_WDDM
+ , shared_handle
+ , NULL
+#endif
+ );
+}
+
+static HRESULT WINAPI d3d9_device_CreateDepthStencilSurface(IDirect3DDevice9Ex *iface, UINT width, UINT height,
+ D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality,
+ BOOL discard, IDirect3DSurface9 **surface, HANDLE *shared_handle)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ DWORD flags = WINED3D_SURFACE_MAPPABLE;
+
+ TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u.\n"
+ "discard %#x, surface %p, shared_handle %p.\n",
+ iface, width, height, format, multisample_type, multisample_quality,
+ discard, surface, shared_handle);
+
+ if (shared_handle)
+ FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
+
+ if (discard)
+ flags |= WINED3D_SURFACE_DISCARD;
+
+ return d3d9_device_create_surface(device, width, height, format, flags, surface,
+ D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, multisample_type, multisample_quality
+#ifdef VBOX_WITH_WDDM
+ , shared_handle
+ , NULL
+#endif
+ );
+}
+
+
+static HRESULT WINAPI d3d9_device_UpdateSurface(IDirect3DDevice9Ex *iface,
+ IDirect3DSurface9 *src_surface, const RECT *src_rect,
+ IDirect3DSurface9 *dst_surface, const POINT *dst_point)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_surface *src = unsafe_impl_from_IDirect3DSurface9(src_surface);
+ struct d3d9_surface *dst = unsafe_impl_from_IDirect3DSurface9(dst_surface);
+ HRESULT hr;
+
+ TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_point %p.\n",
+ iface, src_surface, src_rect, dst_surface, dst_point);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_update_surface(device->wined3d_device, src->wined3d_surface, src_rect,
+ dst->wined3d_surface, dst_point);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_UpdateTexture(IDirect3DDevice9Ex *iface,
+ IDirect3DBaseTexture9 *src_texture, IDirect3DBaseTexture9 *dst_texture)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_texture *src_impl, *dst_impl;
+ HRESULT hr;
+
+ TRACE("iface %p, src_texture %p, dst_texture %p.\n", iface, src_texture, dst_texture);
+
+ src_impl = unsafe_impl_from_IDirect3DBaseTexture9(src_texture);
+ dst_impl = unsafe_impl_from_IDirect3DBaseTexture9(dst_texture);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_update_texture(device->wined3d_device,
+ src_impl->wined3d_texture, dst_impl->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetRenderTargetData(IDirect3DDevice9Ex *iface,
+ IDirect3DSurface9 *render_target, IDirect3DSurface9 *dst_surface)
+{
+ struct d3d9_surface *rt_impl = unsafe_impl_from_IDirect3DSurface9(render_target);
+ struct d3d9_surface *dst_impl = unsafe_impl_from_IDirect3DSurface9(dst_surface);
+ HRESULT hr;
+
+ TRACE("iface %p, render_target %p, dst_surface %p.\n", iface, render_target, dst_surface);
+
+ wined3d_mutex_lock();
+ hr = wined3d_surface_get_render_target_data(dst_impl->wined3d_surface, rt_impl->wined3d_surface);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetFrontBufferData(IDirect3DDevice9Ex *iface,
+ UINT swapchain, IDirect3DSurface9 *dst_surface)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_surface *dst_impl = unsafe_impl_from_IDirect3DSurface9(dst_surface);
+ HRESULT hr;
+
+ TRACE("iface %p, swapchain %u, dst_surface %p.\n", iface, swapchain, dst_surface);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_front_buffer_data(device->wined3d_device, swapchain, dst_impl->wined3d_surface);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_StretchRect(IDirect3DDevice9Ex *iface, IDirect3DSurface9 *src_surface,
+ const RECT *src_rect, IDirect3DSurface9 *dst_surface, const RECT *dst_rect, D3DTEXTUREFILTERTYPE filter)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_surface *src = unsafe_impl_from_IDirect3DSurface9(src_surface);
+ struct d3d9_surface *dst = unsafe_impl_from_IDirect3DSurface9(dst_surface);
+ HRESULT hr = D3DERR_INVALIDCALL;
+ struct wined3d_resource_desc src_desc, dst_desc;
+ struct wined3d_resource *wined3d_resource;
+
+ TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %#x.\n",
+ iface, src_surface, src_rect, dst_surface, dst_rect, filter);
+
+ wined3d_mutex_lock();
+ wined3d_resource = wined3d_surface_get_resource(dst->wined3d_surface);
+ wined3d_resource_get_desc(wined3d_resource, &dst_desc);
+
+ wined3d_resource = wined3d_surface_get_resource(src->wined3d_surface);
+ wined3d_resource_get_desc(wined3d_resource, &src_desc);
+
+ if (src_desc.usage & WINED3DUSAGE_DEPTHSTENCIL)
+ {
+ if (device->in_scene)
+ {
+ WARN("Rejecting depth / stencil blit while in scene.\n");
+ goto done;
+ }
+
+ if (src_rect)
+ {
+ if (src_rect->left || src_rect->top || src_rect->right != src_desc.width
+ || src_rect->bottom != src_desc.height)
+ {
+ WARN("Rejecting depth / stencil blit with invalid source rect %s.\n",
+ wine_dbgstr_rect(src_rect));
+ goto done;
+ }
+ }
+ if (dst_rect)
+ {
+ if (dst_rect->left || dst_rect->top || dst_rect->right != dst_desc.width
+ || dst_rect->bottom != dst_desc.height)
+ {
+ WARN("Rejecting depth / stencil blit with invalid destination rect %s.\n",
+ wine_dbgstr_rect(dst_rect));
+ goto done;
+ }
+ }
+ if (src_desc.width != dst_desc.width || src_desc.height != dst_desc.height)
+ {
+ WARN("Rejecting depth / stencil blit with mismatched surface sizes.\n");
+ goto done;
+ }
+ }
+
+ hr = wined3d_surface_blt(dst->wined3d_surface, dst_rect, src->wined3d_surface, src_rect, 0, NULL, filter);
+ if (hr == WINEDDERR_INVALIDRECT)
+ hr = D3DERR_INVALIDCALL;
+
+done:
+ wined3d_mutex_unlock();
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_ColorFill(IDirect3DDevice9Ex *iface,
+ IDirect3DSurface9 *surface, const RECT *rect, D3DCOLOR color)
+{
+ const struct wined3d_color c =
+ {
+ ((color >> 16) & 0xff) / 255.0f,
+ ((color >> 8) & 0xff) / 255.0f,
+ (color & 0xff) / 255.0f,
+ ((color >> 24) & 0xff) / 255.0f,
+ };
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_surface *surface_impl = unsafe_impl_from_IDirect3DSurface9(surface);
+ struct wined3d_resource *wined3d_resource;
+ struct wined3d_resource_desc desc;
+ HRESULT hr;
+
+ TRACE("iface %p, surface %p, rect %p, color 0x%08x.\n", iface, surface, rect, color);
+
+ wined3d_mutex_lock();
+
+ wined3d_resource = wined3d_surface_get_resource(surface_impl->wined3d_surface);
+ wined3d_resource_get_desc(wined3d_resource, &desc);
+
+ /* This method is only allowed with surfaces that are render targets, or
+ * offscreen plain surfaces in D3DPOOL_DEFAULT. */
+ if (!(desc.usage & WINED3DUSAGE_RENDERTARGET) && desc.pool != WINED3D_POOL_DEFAULT)
+ {
+ wined3d_mutex_unlock();
+ WARN("Surface is not a render target, or not a stand-alone D3DPOOL_DEFAULT surface\n");
+ return D3DERR_INVALIDCALL;
+ }
+
+ /* Colorfill can only be used on rendertarget surfaces, or offscreen plain surfaces in D3DPOOL_DEFAULT */
+ hr = wined3d_device_color_fill(device->wined3d_device, surface_impl->wined3d_surface, rect, &c);
+
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_CreateOffscreenPlainSurface(IDirect3DDevice9Ex *iface,
+ UINT width, UINT height, D3DFORMAT format, D3DPOOL pool, IDirect3DSurface9 **surface,
+ HANDLE *shared_handle)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, width %u, height %u, format %#x, pool %#x, surface %p, shared_handle %p.\n",
+ iface, width, height, format, pool, surface, shared_handle);
+
+ if (shared_handle)
+ FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
+
+ if (pool == D3DPOOL_MANAGED)
+ {
+ WARN("Attempting to create a managed offscreen plain surface.\n");
+ return D3DERR_INVALIDCALL;
+ }
+ /* FIXME: Offscreen surfaces are supposed to be always lockable,
+ * regardless of the pool they're created in. Should we set dynamic usage
+ * here? */
+ return d3d9_device_create_surface(device, width, height, format,
+ WINED3D_SURFACE_MAPPABLE, surface, 0, pool, D3DMULTISAMPLE_NONE, 0
+#ifdef VBOX_WITH_WDDM
+ , shared_handle
+ , NULL
+#endif
+ );
+}
+
+static HRESULT WINAPI d3d9_device_SetRenderTarget(IDirect3DDevice9Ex *iface, DWORD idx, IDirect3DSurface9 *surface)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_surface *surface_impl = unsafe_impl_from_IDirect3DSurface9(surface);
+ HRESULT hr;
+
+ TRACE("iface %p, idx %u, surface %p.\n", iface, idx, surface);
+
+ if (idx >= D3D9_MAX_SIMULTANEOUS_RENDERTARGETS)
+ {
+ WARN("Invalid index %u specified.\n", idx);
+ return D3DERR_INVALIDCALL;
+ }
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_render_target(device->wined3d_device, idx,
+ surface_impl ? surface_impl->wined3d_surface : NULL,
+#ifdef VBOX_WITH_WDDM
+ FALSE
+#else
+ TRUE
+#endif
+ );
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetRenderTarget(IDirect3DDevice9Ex *iface, DWORD idx, IDirect3DSurface9 **surface)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct wined3d_surface *wined3d_surface;
+ struct d3d9_surface *surface_impl;
+ HRESULT hr = D3D_OK;
+
+ TRACE("iface %p, idx %u, surface %p.\n", iface, idx, surface);
+
+ if (!surface)
+ return D3DERR_INVALIDCALL;
+
+ if (idx >= D3D9_MAX_SIMULTANEOUS_RENDERTARGETS)
+ {
+ WARN("Invalid index %u specified.\n", idx);
+ return D3DERR_INVALIDCALL;
+ }
+
+ wined3d_mutex_lock();
+ if ((wined3d_surface = wined3d_device_get_render_target(device->wined3d_device, idx)))
+ {
+ surface_impl = wined3d_surface_get_parent(wined3d_surface);
+ *surface = &surface_impl->IDirect3DSurface9_iface;
+ IDirect3DSurface9_AddRef(*surface);
+ }
+ else
+ {
+ hr = WINED3DERR_NOTFOUND;
+ *surface = NULL;
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_SetDepthStencilSurface(IDirect3DDevice9Ex *iface, IDirect3DSurface9 *depth_stencil)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_surface *ds_impl = unsafe_impl_from_IDirect3DSurface9(depth_stencil);
+
+ TRACE("iface %p, depth_stencil %p.\n", iface, depth_stencil);
+
+ wined3d_mutex_lock();
+ wined3d_device_set_depth_stencil(device->wined3d_device, ds_impl ? ds_impl->wined3d_surface : NULL);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_GetDepthStencilSurface(IDirect3DDevice9Ex *iface, IDirect3DSurface9 **depth_stencil)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct wined3d_surface *wined3d_surface;
+ struct d3d9_surface *surface_impl;
+ HRESULT hr = D3D_OK;
+
+ TRACE("iface %p, depth_stencil %p.\n", iface, depth_stencil);
+
+ if (!depth_stencil)
+ return D3DERR_INVALIDCALL;
+
+ wined3d_mutex_lock();
+ if ((wined3d_surface = wined3d_device_get_depth_stencil(device->wined3d_device)))
+ {
+ surface_impl = wined3d_surface_get_parent(wined3d_surface);
+ *depth_stencil = &surface_impl->IDirect3DSurface9_iface;
+ IDirect3DSurface9_AddRef(*depth_stencil);
+ }
+ else
+ {
+ hr = WINED3DERR_NOTFOUND;
+ *depth_stencil = NULL;
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_BeginScene(IDirect3DDevice9Ex *iface)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ if (SUCCEEDED(hr = wined3d_device_begin_scene(device->wined3d_device)))
+ device->in_scene = TRUE;
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_EndScene(IDirect3DDevice9Ex *iface)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ if (SUCCEEDED(hr = wined3d_device_end_scene(device->wined3d_device)))
+ device->in_scene = FALSE;
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_Clear(IDirect3DDevice9Ex *iface, DWORD rect_count,
+ const D3DRECT *rects, DWORD flags, D3DCOLOR color, float z, DWORD stencil)
+{
+ const struct wined3d_color c =
+ {
+ ((color >> 16) & 0xff) / 255.0f,
+ ((color >> 8) & 0xff) / 255.0f,
+ (color & 0xff) / 255.0f,
+ ((color >> 24) & 0xff) / 255.0f,
+ };
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, rect_count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %u.\n",
+ iface, rect_count, rects, flags, color, z, stencil);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_clear(device->wined3d_device, rect_count, (const RECT *)rects, flags, &c, z, stencil);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_SetTransform(IDirect3DDevice9Ex *iface,
+ D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix);
+
+ /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
+ wined3d_mutex_lock();
+ wined3d_device_set_transform(device->wined3d_device, state, (const struct wined3d_matrix *)matrix);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_GetTransform(IDirect3DDevice9Ex *iface,
+ D3DTRANSFORMSTATETYPE state, D3DMATRIX *matrix)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix);
+
+ /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
+ wined3d_mutex_lock();
+ wined3d_device_get_transform(device->wined3d_device, state, (struct wined3d_matrix *)matrix);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_MultiplyTransform(IDirect3DDevice9Ex *iface,
+ D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, state %#x, matrix %p.\n", iface, state, matrix);
+
+ /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
+ wined3d_mutex_lock();
+ wined3d_device_multiply_transform(device->wined3d_device, state, (const struct wined3d_matrix *)matrix);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_SetViewport(IDirect3DDevice9Ex *iface, const D3DVIEWPORT9 *viewport)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, viewport %p.\n", iface, viewport);
+
+ /* Note: D3DVIEWPORT9 is compatible with struct wined3d_viewport. */
+ wined3d_mutex_lock();
+ wined3d_device_set_viewport(device->wined3d_device, (const struct wined3d_viewport *)viewport);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_GetViewport(IDirect3DDevice9Ex *iface, D3DVIEWPORT9 *viewport)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, viewport %p.\n", iface, viewport);
+
+ /* Note: D3DVIEWPORT9 is compatible with struct wined3d_viewport. */
+ wined3d_mutex_lock();
+ wined3d_device_get_viewport(device->wined3d_device, (struct wined3d_viewport *)viewport);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_SetMaterial(IDirect3DDevice9Ex *iface, const D3DMATERIAL9 *material)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, material %p.\n", iface, material);
+
+ /* Note: D3DMATERIAL9 is compatible with struct wined3d_material. */
+ wined3d_mutex_lock();
+ wined3d_device_set_material(device->wined3d_device, (const struct wined3d_material *)material);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_GetMaterial(IDirect3DDevice9Ex *iface, D3DMATERIAL9 *material)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, material %p.\n", iface, material);
+
+ /* Note: D3DMATERIAL9 is compatible with struct wined3d_material. */
+ wined3d_mutex_lock();
+ wined3d_device_get_material(device->wined3d_device, (struct wined3d_material *)material);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_SetLight(IDirect3DDevice9Ex *iface, DWORD index, const D3DLIGHT9 *light)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, index %u, light %p.\n", iface, index, light);
+
+ /* Note: D3DLIGHT9 is compatible with struct wined3d_light. */
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_light(device->wined3d_device, index, (const struct wined3d_light *)light);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetLight(IDirect3DDevice9Ex *iface, DWORD index, D3DLIGHT9 *light)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, index %u, light %p.\n", iface, index, light);
+
+ /* Note: D3DLIGHT9 is compatible with struct wined3d_light. */
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_light(device->wined3d_device, index, (struct wined3d_light *)light);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_LightEnable(IDirect3DDevice9Ex *iface, DWORD index, BOOL enable)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, index %u, enable %#x.\n", iface, index, enable);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_light_enable(device->wined3d_device, index, enable);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetLightEnable(IDirect3DDevice9Ex *iface, DWORD index, BOOL *enable)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, index %u, enable %p.\n", iface, index, enable);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_light_enable(device->wined3d_device, index, enable);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_SetClipPlane(IDirect3DDevice9Ex *iface, DWORD index, const float *plane)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, index %u, plane %p.\n", iface, index, plane);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_clip_plane(device->wined3d_device, index, (const struct wined3d_vec4 *)plane);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetClipPlane(IDirect3DDevice9Ex *iface, DWORD index, float *plane)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, index %u, plane %p.\n", iface, index, plane);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_clip_plane(device->wined3d_device, index, (struct wined3d_vec4 *)plane);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_SetRenderState(IDirect3DDevice9Ex *iface,
+ D3DRENDERSTATETYPE state, DWORD value)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, state %#x, value %#x.\n", iface, state, value);
+
+ wined3d_mutex_lock();
+ wined3d_device_set_render_state(device->wined3d_device, state, value);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_GetRenderState(IDirect3DDevice9Ex *iface,
+ D3DRENDERSTATETYPE state, DWORD *value)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, state %#x, value %p.\n", iface, state, value);
+
+ wined3d_mutex_lock();
+ *value = wined3d_device_get_render_state(device->wined3d_device, state);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_CreateStateBlock(IDirect3DDevice9Ex *iface,
+ D3DSTATEBLOCKTYPE type, IDirect3DStateBlock9 **stateblock)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_stateblock *object;
+ HRESULT hr;
+
+ TRACE("iface %p, type %#x, stateblock %p.\n", iface, type, stateblock);
+
+ if (type != D3DSBT_ALL && type != D3DSBT_PIXELSTATE && type != D3DSBT_VERTEXSTATE)
+ {
+ WARN("Unexpected stateblock type, returning D3DERR_INVALIDCALL.\n");
+ return D3DERR_INVALIDCALL;
+ }
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ hr = stateblock_init(object, device, type, NULL);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize stateblock, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created stateblock %p.\n", object);
+ *stateblock = &object->IDirect3DStateBlock9_iface;
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_BeginStateBlock(IDirect3DDevice9Ex *iface)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_begin_stateblock(device->wined3d_device);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_EndStateBlock(IDirect3DDevice9Ex *iface, IDirect3DStateBlock9 **stateblock)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct wined3d_stateblock *wined3d_stateblock;
+ struct d3d9_stateblock *object;
+ HRESULT hr;
+
+ TRACE("iface %p, stateblock %p.\n", iface, stateblock);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_end_stateblock(device->wined3d_device, &wined3d_stateblock);
+ wined3d_mutex_unlock();
+ if (FAILED(hr))
+ {
+ WARN("IWineD3DDevice_EndStateBlock() failed, hr %#x.\n", hr);
+ return hr;
+ }
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ {
+ wined3d_mutex_lock();
+ wined3d_stateblock_decref(wined3d_stateblock);
+ wined3d_mutex_unlock();
+ return E_OUTOFMEMORY;
+ }
+
+ hr = stateblock_init(object, device, 0, wined3d_stateblock);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize stateblock, hr %#x.\n", hr);
+ wined3d_mutex_lock();
+ wined3d_stateblock_decref(wined3d_stateblock);
+ wined3d_mutex_unlock();
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created stateblock %p.\n", object);
+ *stateblock = &object->IDirect3DStateBlock9_iface;
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_SetClipStatus(IDirect3DDevice9Ex *iface, const D3DCLIPSTATUS9 *clip_status)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, clip_status %p.\n", iface, clip_status);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_clip_status(device->wined3d_device, (const struct wined3d_clip_status *)clip_status);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetClipStatus(IDirect3DDevice9Ex *iface, D3DCLIPSTATUS9 *clip_status)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, clip_status %p.\n", iface, clip_status);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_clip_status(device->wined3d_device, (struct wined3d_clip_status *)clip_status);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetTexture(IDirect3DDevice9Ex *iface, DWORD stage, IDirect3DBaseTexture9 **texture)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct wined3d_texture *wined3d_texture = NULL;
+ struct d3d9_texture *texture_impl;
+
+ TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture);
+
+ if (!texture)
+ return D3DERR_INVALIDCALL;
+
+ wined3d_mutex_lock();
+ if ((wined3d_texture = wined3d_device_get_texture(device->wined3d_device, stage)))
+ {
+ texture_impl = wined3d_texture_get_parent(wined3d_texture);
+ *texture = &texture_impl->IDirect3DBaseTexture9_iface;
+ IDirect3DBaseTexture9_AddRef(*texture);
+ }
+ else
+ {
+ *texture = NULL;
+ }
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_SetTexture(IDirect3DDevice9Ex *iface, DWORD stage, IDirect3DBaseTexture9 *texture)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_texture *texture_impl;
+ HRESULT hr;
+
+ TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture);
+
+ texture_impl = unsafe_impl_from_IDirect3DBaseTexture9(texture);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_texture(device->wined3d_device, stage,
+ texture_impl ? texture_impl->wined3d_texture : NULL);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static const enum wined3d_texture_stage_state tss_lookup[] =
+{
+ WINED3D_TSS_INVALID, /* 0, unused */
+ WINED3D_TSS_COLOR_OP, /* 1, D3DTSS_COLOROP */
+ WINED3D_TSS_COLOR_ARG1, /* 2, D3DTSS_COLORARG1 */
+ WINED3D_TSS_COLOR_ARG2, /* 3, D3DTSS_COLORARG2 */
+ WINED3D_TSS_ALPHA_OP, /* 4, D3DTSS_ALPHAOP */
+ WINED3D_TSS_ALPHA_ARG1, /* 5, D3DTSS_ALPHAARG1 */
+ WINED3D_TSS_ALPHA_ARG2, /* 6, D3DTSS_ALPHAARG2 */
+ WINED3D_TSS_BUMPENV_MAT00, /* 7, D3DTSS_BUMPENVMAT00 */
+ WINED3D_TSS_BUMPENV_MAT01, /* 8, D3DTSS_BUMPENVMAT01 */
+ WINED3D_TSS_BUMPENV_MAT10, /* 9, D3DTSS_BUMPENVMAT10 */
+ WINED3D_TSS_BUMPENV_MAT11, /* 10, D3DTSS_BUMPENVMAT11 */
+ WINED3D_TSS_TEXCOORD_INDEX, /* 11, D3DTSS_TEXCOORDINDEX */
+ WINED3D_TSS_INVALID, /* 12, unused */
+ WINED3D_TSS_INVALID, /* 13, unused */
+ WINED3D_TSS_INVALID, /* 14, unused */
+ WINED3D_TSS_INVALID, /* 15, unused */
+ WINED3D_TSS_INVALID, /* 16, unused */
+ WINED3D_TSS_INVALID, /* 17, unused */
+ WINED3D_TSS_INVALID, /* 18, unused */
+ WINED3D_TSS_INVALID, /* 19, unused */
+ WINED3D_TSS_INVALID, /* 20, unused */
+ WINED3D_TSS_INVALID, /* 21, unused */
+ WINED3D_TSS_BUMPENV_LSCALE, /* 22, D3DTSS_BUMPENVLSCALE */
+ WINED3D_TSS_BUMPENV_LOFFSET, /* 23, D3DTSS_BUMPENVLOFFSET */
+ WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
+ WINED3D_TSS_INVALID, /* 25, unused */
+ WINED3D_TSS_COLOR_ARG0, /* 26, D3DTSS_COLORARG0 */
+ WINED3D_TSS_ALPHA_ARG0, /* 27, D3DTSS_ALPHAARG0 */
+ WINED3D_TSS_RESULT_ARG, /* 28, D3DTSS_RESULTARG */
+ WINED3D_TSS_INVALID, /* 29, unused */
+ WINED3D_TSS_INVALID, /* 30, unused */
+ WINED3D_TSS_INVALID, /* 31, unused */
+ WINED3D_TSS_CONSTANT, /* 32, D3DTSS_CONSTANT */
+};
+
+static HRESULT WINAPI d3d9_device_GetTextureStageState(IDirect3DDevice9Ex *iface,
+ DWORD stage, D3DTEXTURESTAGESTATETYPE state, DWORD *value)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, stage %u, state %#x, value %p.\n", iface, stage, state, value);
+
+ if (state >= sizeof(tss_lookup) / sizeof(*tss_lookup))
+ {
+ WARN("Invalid state %#x passed.\n", state);
+ return D3D_OK;
+ }
+
+ wined3d_mutex_lock();
+ *value = wined3d_device_get_texture_stage_state(device->wined3d_device, stage, tss_lookup[state]);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_SetTextureStageState(IDirect3DDevice9Ex *iface,
+ DWORD stage, D3DTEXTURESTAGESTATETYPE state, DWORD value)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, stage %u, state %#x, value %#x.\n", iface, stage, state, value);
+
+ if (state >= sizeof(tss_lookup) / sizeof(*tss_lookup))
+ {
+ WARN("Invalid state %#x passed.\n", state);
+ return D3D_OK;
+ }
+
+ wined3d_mutex_lock();
+ wined3d_device_set_texture_stage_state(device->wined3d_device, stage, tss_lookup[state], value);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_GetSamplerState(IDirect3DDevice9Ex *iface,
+ DWORD sampler, D3DSAMPLERSTATETYPE state, DWORD *value)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, sampler %u, state %#x, value %p.\n", iface, sampler, state, value);
+
+ wined3d_mutex_lock();
+ *value = wined3d_device_get_sampler_state(device->wined3d_device, sampler, state);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_SetSamplerState(IDirect3DDevice9Ex *iface,
+ DWORD sampler, D3DSAMPLERSTATETYPE state, DWORD value)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, sampler %u, state %#x, value %#x.\n", iface, sampler, state, value);
+
+ wined3d_mutex_lock();
+ wined3d_device_set_sampler_state(device->wined3d_device, sampler, state, value);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_ValidateDevice(IDirect3DDevice9Ex *iface, DWORD *pass_count)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, pass_count %p.\n", iface, pass_count);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_validate_device(device->wined3d_device, pass_count);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_SetPaletteEntries(IDirect3DDevice9Ex *iface,
+ UINT palette_idx, const PALETTEENTRY *entries)
+{
+ WARN("iface %p, palette_idx %u, entries %p unimplemented.\n", iface, palette_idx, entries);
+
+ /* The d3d9 palette API is non-functional on Windows. Getters and setters are implemented,
+ * and some drivers allow the creation of P8 surfaces. These surfaces can be copied to
+ * other P8 surfaces with StretchRect, but cannot be converted to (A)RGB.
+ *
+ * Some older(dx7) cards may have support for P8 textures, but games cannot rely on this. */
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_GetPaletteEntries(IDirect3DDevice9Ex *iface,
+ UINT palette_idx, PALETTEENTRY *entries)
+{
+ FIXME("iface %p, palette_idx %u, entries %p unimplemented.\n", iface, palette_idx, entries);
+
+ return D3DERR_INVALIDCALL;
+}
+
+static HRESULT WINAPI d3d9_device_SetCurrentTexturePalette(IDirect3DDevice9Ex *iface, UINT palette_idx)
+{
+ WARN("iface %p, palette_idx %u unimplemented.\n", iface, palette_idx);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_GetCurrentTexturePalette(IDirect3DDevice9Ex *iface, UINT *palette_idx)
+{
+ FIXME("iface %p, palette_idx %p.\n", iface, palette_idx);
+
+ return D3DERR_INVALIDCALL;
+}
+
+static HRESULT WINAPI d3d9_device_SetScissorRect(IDirect3DDevice9Ex *iface, const RECT *rect)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, rect %p.\n", iface, rect);
+
+ wined3d_mutex_lock();
+ wined3d_device_set_scissor_rect(device->wined3d_device, rect);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_GetScissorRect(IDirect3DDevice9Ex *iface, RECT *rect)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, rect %p.\n", iface, rect);
+
+ wined3d_mutex_lock();
+ wined3d_device_get_scissor_rect(device->wined3d_device, rect);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_SetSoftwareVertexProcessing(IDirect3DDevice9Ex *iface, BOOL software)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+
+ TRACE("iface %p, software %#x.\n", iface, software);
+
+ wined3d_mutex_lock();
+ wined3d_device_set_software_vertex_processing(device->wined3d_device, software);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static BOOL WINAPI d3d9_device_GetSoftwareVertexProcessing(IDirect3DDevice9Ex *iface)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ BOOL ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_device_get_software_vertex_processing(device->wined3d_device);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static HRESULT WINAPI d3d9_device_SetNPatchMode(IDirect3DDevice9Ex *iface, float segment_count)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, segment_count %.8e.\n", iface, segment_count);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_npatch_mode(device->wined3d_device, segment_count);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static float WINAPI d3d9_device_GetNPatchMode(IDirect3DDevice9Ex *iface)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ float ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_device_get_npatch_mode(device->wined3d_device);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface,
+ D3DPRIMITIVETYPE primitive_type, UINT start_vertex, UINT primitive_count)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, primitive_type %#x, start_vertex %u, primitive_count %u.\n",
+ iface, primitive_type, start_vertex, primitive_count);
+
+ wined3d_mutex_lock();
+ wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+ hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex,
+ vertex_count_from_primitive_count(primitive_type, primitive_count));
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface,
+ D3DPRIMITIVETYPE primitive_type, INT base_vertex_idx, UINT min_vertex_idx,
+ UINT vertex_count, UINT start_idx, UINT primitive_count)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, primitive_type %#x, base_vertex_idx %u, min_vertex_idx %u,\n"
+ "vertex_count %u, start_idx %u, primitive_count %u.\n",
+ iface, primitive_type, base_vertex_idx, min_vertex_idx,
+ vertex_count, start_idx, primitive_count);
+
+ wined3d_mutex_lock();
+ wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_idx);
+ wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+ hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx,
+ vertex_count_from_primitive_count(primitive_type, primitive_count));
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static void STDMETHODCALLTYPE d3d9_null_wined3d_object_destroyed(void *parent) {}
+
+static const struct wined3d_parent_ops d3d9_null_wined3d_parent_ops =
+{
+ d3d9_null_wined3d_object_destroyed,
+};
+
+/* The caller is responsible for wined3d locking */
+static HRESULT d3d9_device_prepare_vertex_buffer(struct d3d9_device *device, UINT min_size)
+{
+ HRESULT hr;
+
+ if (device->vertex_buffer_size < min_size || !device->vertex_buffer)
+ {
+ UINT size = max(device->vertex_buffer_size * 2, min_size);
+ struct wined3d_buffer *buffer;
+
+ TRACE("Growing vertex buffer to %u bytes\n", size);
+
+ hr = wined3d_buffer_create_vb(device->wined3d_device, size, WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY,
+ WINED3D_POOL_DEFAULT, NULL, &d3d9_null_wined3d_parent_ops, &buffer);
+ if (FAILED(hr))
+ {
+ ERR("(%p) wined3d_buffer_create_vb failed with hr = %08x\n", device, hr);
+ return hr;
+ }
+
+ if (device->vertex_buffer)
+ wined3d_buffer_decref(device->vertex_buffer);
+
+ device->vertex_buffer = buffer;
+ device->vertex_buffer_size = size;
+ device->vertex_buffer_pos = 0;
+ }
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_DrawPrimitiveUP(IDirect3DDevice9Ex *iface,
+ D3DPRIMITIVETYPE primitive_type, UINT primitive_count, const void *data, UINT stride)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+ UINT vtx_count = vertex_count_from_primitive_count(primitive_type, primitive_count);
+ UINT size = vtx_count * stride;
+ UINT vb_pos, align;
+ BYTE *buffer_data;
+
+ TRACE("iface %p, primitive_type %#x, primitive_count %u, data %p, stride %u.\n",
+ iface, primitive_type, primitive_count, data, stride);
+
+ if (!primitive_count)
+ {
+ WARN("primitive_count is 0, returning D3D_OK\n");
+ return D3D_OK;
+ }
+
+ wined3d_mutex_lock();
+
+ hr = d3d9_device_prepare_vertex_buffer(device, size);
+ if (FAILED(hr))
+ goto done;
+
+ vb_pos = device->vertex_buffer_pos;
+ align = vb_pos % stride;
+ if (align) align = stride - align;
+ if (vb_pos + size + align > device->vertex_buffer_size)
+ vb_pos = 0;
+ else
+ vb_pos += align;
+
+ hr = wined3d_buffer_map(device->vertex_buffer, vb_pos, size, &buffer_data,
+ vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD);
+ if (FAILED(hr))
+ goto done;
+ memcpy(buffer_data, data, size);
+ wined3d_buffer_unmap(device->vertex_buffer);
+ device->vertex_buffer_pos = vb_pos + size;
+
+ hr = wined3d_device_set_stream_source(device->wined3d_device, 0, device->vertex_buffer, 0, stride);
+ if (FAILED(hr))
+ goto done;
+
+ wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+ hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / stride, vtx_count);
+ wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0);
+
+done:
+ wined3d_mutex_unlock();
+ return hr;
+}
+
+/* The caller is responsible for wined3d locking */
+static HRESULT d3d9_device_prepare_index_buffer(struct d3d9_device *device, UINT min_size)
+{
+ HRESULT hr;
+
+ if (device->index_buffer_size < min_size || !device->index_buffer)
+ {
+ UINT size = max(device->index_buffer_size * 2, min_size);
+ struct wined3d_buffer *buffer;
+
+ TRACE("Growing index buffer to %u bytes\n", size);
+
+ hr = wined3d_buffer_create_ib(device->wined3d_device, size, WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_WRITEONLY,
+ WINED3D_POOL_DEFAULT, NULL, &d3d9_null_wined3d_parent_ops, &buffer);
+ if (FAILED(hr))
+ {
+ ERR("(%p) wined3d_buffer_create_ib failed with hr = %08x\n", device, hr);
+ return hr;
+ }
+
+ if (device->index_buffer)
+ wined3d_buffer_decref(device->index_buffer);
+
+ device->index_buffer = buffer;
+ device->index_buffer_size = size;
+ device->index_buffer_pos = 0;
+ }
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *iface,
+ D3DPRIMITIVETYPE primitive_type, UINT min_vertex_idx, UINT vertex_count,
+ UINT primitive_count, const void *index_data, D3DFORMAT index_format,
+ const void *vertex_data, UINT vertex_stride)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+ BYTE *buffer_data;
+
+ UINT idx_count = vertex_count_from_primitive_count(primitive_type, primitive_count);
+ UINT idx_fmt_size = index_format == D3DFMT_INDEX16 ? 2 : 4;
+ UINT idx_size = idx_count * idx_fmt_size;
+ UINT ib_pos;
+
+ UINT vtx_size = vertex_count * vertex_stride;
+ UINT vb_pos, align;
+
+ TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, vertex_count %u, primitive_count %u,\n"
+ "index_data %p, index_format %#x, vertex_data %p, vertex_stride %u.\n",
+ iface, primitive_type, min_vertex_idx, vertex_count, primitive_count,
+ index_data, index_format, vertex_data, vertex_stride);
+
+ if (!primitive_count)
+ {
+ WARN("primitive_count is 0, returning D3D_OK\n");
+ return D3D_OK;
+ }
+
+ wined3d_mutex_lock();
+
+ hr = d3d9_device_prepare_vertex_buffer(device, vtx_size);
+ if (FAILED(hr))
+ goto done;
+
+ vb_pos = device->vertex_buffer_pos;
+ align = vb_pos % vertex_stride;
+ if (align) align = vertex_stride - align;
+ if (vb_pos + vtx_size + align > device->vertex_buffer_size)
+ vb_pos = 0;
+ else
+ vb_pos += align;
+
+ hr = wined3d_buffer_map(device->vertex_buffer, vb_pos, vtx_size, &buffer_data,
+ vb_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD);
+ if (FAILED(hr))
+ goto done;
+ memcpy(buffer_data, vertex_data, vtx_size);
+ wined3d_buffer_unmap(device->vertex_buffer);
+ device->vertex_buffer_pos = vb_pos + vtx_size;
+
+ hr = d3d9_device_prepare_index_buffer(device, idx_size);
+ if (FAILED(hr))
+ goto done;
+
+ ib_pos = device->index_buffer_pos;
+ align = ib_pos % idx_fmt_size;
+ if (align) align = idx_fmt_size - align;
+ if (ib_pos + idx_size + align > device->index_buffer_size)
+ ib_pos = 0;
+ else
+ ib_pos += align;
+
+ hr = wined3d_buffer_map(device->index_buffer, ib_pos, idx_size, &buffer_data,
+ ib_pos ? WINED3D_MAP_NOOVERWRITE : WINED3D_MAP_DISCARD);
+ if (FAILED(hr))
+ goto done;
+ memcpy(buffer_data, index_data, idx_size);
+ wined3d_buffer_unmap(device->index_buffer);
+ device->index_buffer_pos = ib_pos + idx_size;
+
+ hr = wined3d_device_set_stream_source(device->wined3d_device, 0, device->vertex_buffer, 0, vertex_stride);
+ if (FAILED(hr))
+ goto done;
+
+ wined3d_device_set_index_buffer(device->wined3d_device, device->index_buffer,
+ wined3dformat_from_d3dformat(index_format));
+ wined3d_device_set_base_vertex_index(device->wined3d_device, vb_pos / vertex_stride);
+
+ wined3d_device_set_primitive_type(device->wined3d_device, primitive_type);
+ hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, ib_pos / idx_fmt_size, idx_count);
+
+ wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0);
+ wined3d_device_set_index_buffer(device->wined3d_device, NULL, WINED3DFMT_UNKNOWN);
+ wined3d_device_set_base_vertex_index(device->wined3d_device, 0);
+
+done:
+ wined3d_mutex_unlock();
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_ProcessVertices(IDirect3DDevice9Ex *iface,
+ UINT src_start_idx, UINT dst_idx, UINT vertex_count, IDirect3DVertexBuffer9 *dst_buffer,
+ IDirect3DVertexDeclaration9 *declaration, DWORD flags)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_vertexbuffer *dst_impl = unsafe_impl_from_IDirect3DVertexBuffer9(dst_buffer);
+ struct d3d9_vertex_declaration *decl_impl = unsafe_impl_from_IDirect3DVertexDeclaration9(declaration);
+ HRESULT hr;
+
+ TRACE("iface %p, src_start_idx %u, dst_idx %u, vertex_count %u, dst_buffer %p, declaration %p, flags %#x.\n",
+ iface, src_start_idx, dst_idx, vertex_count, dst_buffer, declaration, flags);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_process_vertices(device->wined3d_device, src_start_idx, dst_idx, vertex_count,
+ dst_impl->wined3d_buffer, decl_impl ? decl_impl->wined3d_declaration : NULL,
+ flags, dst_impl->fvf);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_CreateVertexDeclaration(IDirect3DDevice9Ex *iface,
+ const D3DVERTEXELEMENT9 *elements, IDirect3DVertexDeclaration9 **declaration)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_vertex_declaration *object;
+ HRESULT hr;
+
+ TRACE("iface %p, elements %p, declaration %p.\n", iface, elements, declaration);
+
+ if (!declaration)
+ {
+ WARN("Caller passed a NULL declaration, returning D3DERR_INVALIDCALL.\n");
+ return D3DERR_INVALIDCALL;
+ }
+
+ if (SUCCEEDED(hr = d3d9_vertex_declaration_create(device, elements, &object)))
+ *declaration = &object->IDirect3DVertexDeclaration9_iface;
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_SetVertexDeclaration(IDirect3DDevice9Ex *iface,
+ IDirect3DVertexDeclaration9 *declaration)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_vertex_declaration *decl_impl = unsafe_impl_from_IDirect3DVertexDeclaration9(declaration);
+
+ TRACE("iface %p, declaration %p.\n", iface, declaration);
+
+ wined3d_mutex_lock();
+ wined3d_device_set_vertex_declaration(device->wined3d_device,
+ decl_impl ? decl_impl->wined3d_declaration : NULL);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_GetVertexDeclaration(IDirect3DDevice9Ex *iface,
+ IDirect3DVertexDeclaration9 **declaration)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct wined3d_vertex_declaration *wined3d_declaration;
+ struct d3d9_vertex_declaration *declaration_impl;
+
+ TRACE("iface %p, declaration %p.\n", iface, declaration);
+
+ if (!declaration) return D3DERR_INVALIDCALL;
+
+ wined3d_mutex_lock();
+ if ((wined3d_declaration = wined3d_device_get_vertex_declaration(device->wined3d_device)))
+ {
+ declaration_impl = wined3d_vertex_declaration_get_parent(wined3d_declaration);
+ *declaration = &declaration_impl->IDirect3DVertexDeclaration9_iface;
+ IDirect3DVertexDeclaration9_AddRef(*declaration);
+ }
+ else
+ {
+ *declaration = NULL;
+ }
+ wined3d_mutex_unlock();
+
+ TRACE("Returning %p.\n", *declaration);
+ return D3D_OK;
+}
+
+static struct wined3d_vertex_declaration *device_get_fvf_declaration(struct d3d9_device *device, DWORD fvf)
+{
+ struct wined3d_vertex_declaration *wined3d_declaration;
+ struct fvf_declaration *fvf_decls = device->fvf_decls;
+ struct d3d9_vertex_declaration *d3d9_declaration;
+ D3DVERTEXELEMENT9 *elements;
+ int p, low, high; /* deliberately signed */
+ HRESULT hr;
+
+ TRACE("Searching for declaration for fvf %08x... ", fvf);
+
+ low = 0;
+ high = device->fvf_decl_count - 1;
+ while (low <= high)
+ {
+ p = (low + high) >> 1;
+ TRACE("%d ", p);
+
+ if (fvf_decls[p].fvf == fvf)
+ {
+ TRACE("found %p.\n", fvf_decls[p].decl);
+ return fvf_decls[p].decl;
+ }
+
+ if (fvf_decls[p].fvf < fvf)
+ low = p + 1;
+ else
+ high = p - 1;
+ }
+ TRACE("not found. Creating and inserting at position %d.\n", low);
+
+ if (FAILED(hr = vdecl_convert_fvf(fvf, &elements)))
+ return NULL;
+
+ hr = d3d9_vertex_declaration_create(device, elements, &d3d9_declaration);
+ HeapFree(GetProcessHeap(), 0, elements);
+ if (FAILED(hr))
+ return NULL;
+
+ if (device->fvf_decl_size == device->fvf_decl_count)
+ {
+ UINT grow = max(device->fvf_decl_size / 2, 8);
+
+ fvf_decls = HeapReAlloc(GetProcessHeap(), 0, fvf_decls, sizeof(*fvf_decls) * (device->fvf_decl_size + grow));
+ if (!fvf_decls)
+ {
+ IDirect3DVertexDeclaration9_Release(&d3d9_declaration->IDirect3DVertexDeclaration9_iface);
+ return NULL;
+ }
+ device->fvf_decls = fvf_decls;
+ device->fvf_decl_size += grow;
+ }
+
+ d3d9_declaration->fvf = fvf;
+ wined3d_declaration = d3d9_declaration->wined3d_declaration;
+ wined3d_vertex_declaration_incref(wined3d_declaration);
+ IDirect3DVertexDeclaration9_Release(&d3d9_declaration->IDirect3DVertexDeclaration9_iface);
+
+ memmove(fvf_decls + low + 1, fvf_decls + low, sizeof(*fvf_decls) * (device->fvf_decl_count - low));
+ fvf_decls[low].decl = wined3d_declaration;
+ fvf_decls[low].fvf = fvf;
+ ++device->fvf_decl_count;
+
+ TRACE("Returning %p. %u declatations in array.\n", wined3d_declaration, device->fvf_decl_count);
+
+ return wined3d_declaration;
+}
+
+static HRESULT WINAPI d3d9_device_SetFVF(IDirect3DDevice9Ex *iface, DWORD fvf)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct wined3d_vertex_declaration *decl;
+
+ TRACE("iface %p, fvf %#x.\n", iface, fvf);
+
+ if (!fvf)
+ {
+ WARN("%#x is not a valid FVF.\n", fvf);
+ return D3D_OK;
+ }
+
+ wined3d_mutex_lock();
+ if (!(decl = device_get_fvf_declaration(device, fvf)))
+ {
+ wined3d_mutex_unlock();
+ ERR("Failed to create a vertex declaration for fvf %#x.\n", fvf);
+ return D3DERR_DRIVERINTERNALERROR;
+ }
+
+ wined3d_device_set_vertex_declaration(device->wined3d_device, decl);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_GetFVF(IDirect3DDevice9Ex *iface, DWORD *fvf)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct wined3d_vertex_declaration *wined3d_declaration;
+ struct d3d9_vertex_declaration *d3d9_declaration;
+
+ TRACE("iface %p, fvf %p.\n", iface, fvf);
+
+ wined3d_mutex_lock();
+ if ((wined3d_declaration = wined3d_device_get_vertex_declaration(device->wined3d_device)))
+ {
+ d3d9_declaration = wined3d_vertex_declaration_get_parent(wined3d_declaration);
+ *fvf = d3d9_declaration->fvf;
+ }
+ else
+ {
+ *fvf = 0;
+ }
+ wined3d_mutex_unlock();
+
+ TRACE("Returning FVF %#x.\n", *fvf);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_CreateVertexShader(IDirect3DDevice9Ex *iface,
+ const DWORD *byte_code, IDirect3DVertexShader9 **shader)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_vertexshader *object;
+ HRESULT hr;
+
+ TRACE("iface %p, byte_code %p, shader %p.\n", iface, byte_code, shader);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ hr = vertexshader_init(object, device, byte_code);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created vertex shader %p.\n", object);
+ *shader = &object->IDirect3DVertexShader9_iface;
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_SetVertexShader(IDirect3DDevice9Ex *iface, IDirect3DVertexShader9 *shader)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_vertexshader *shader_obj = unsafe_impl_from_IDirect3DVertexShader9(shader);
+
+ TRACE("iface %p, shader %p.\n", iface, shader);
+
+ wined3d_mutex_lock();
+ wined3d_device_set_vertex_shader(device->wined3d_device,
+ shader_obj ? shader_obj->wined3d_shader : NULL);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_GetVertexShader(IDirect3DDevice9Ex *iface, IDirect3DVertexShader9 **shader)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_vertexshader *shader_impl;
+ struct wined3d_shader *wined3d_shader;
+
+ TRACE("iface %p, shader %p.\n", iface, shader);
+
+ wined3d_mutex_lock();
+ if ((wined3d_shader = wined3d_device_get_vertex_shader(device->wined3d_device)))
+ {
+ shader_impl = wined3d_shader_get_parent(wined3d_shader);
+ *shader = &shader_impl->IDirect3DVertexShader9_iface;
+ IDirect3DVertexShader9_AddRef(*shader);
+ }
+ else
+ {
+ *shader = NULL;
+ }
+ wined3d_mutex_unlock();
+
+ TRACE("Returning %p.\n", *shader);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_SetVertexShaderConstantF(IDirect3DDevice9Ex *iface,
+ UINT reg_idx, const float *data, UINT count)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
+
+ if (reg_idx + count > D3D9_MAX_VERTEX_SHADER_CONSTANTF)
+ {
+ WARN("Trying to access %u constants, but d3d9 only supports %u\n",
+ reg_idx + count, D3D9_MAX_VERTEX_SHADER_CONSTANTF);
+ return D3DERR_INVALIDCALL;
+ }
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_vs_consts_f(device->wined3d_device, reg_idx, data, count);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetVertexShaderConstantF(IDirect3DDevice9Ex *iface,
+ UINT reg_idx, float *data, UINT count)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
+
+ if (reg_idx + count > D3D9_MAX_VERTEX_SHADER_CONSTANTF)
+ {
+ WARN("Trying to access %u constants, but d3d9 only supports %u\n",
+ reg_idx + count, D3D9_MAX_VERTEX_SHADER_CONSTANTF);
+ return D3DERR_INVALIDCALL;
+ }
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_vs_consts_f(device->wined3d_device, reg_idx, data, count);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_SetVertexShaderConstantI(IDirect3DDevice9Ex *iface,
+ UINT reg_idx, const int *data, UINT count)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_vs_consts_i(device->wined3d_device, reg_idx, data, count);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetVertexShaderConstantI(IDirect3DDevice9Ex *iface,
+ UINT reg_idx, int *data, UINT count)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_vs_consts_i(device->wined3d_device, reg_idx, data, count);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_SetVertexShaderConstantB(IDirect3DDevice9Ex *iface,
+ UINT reg_idx, const BOOL *data, UINT count)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_vs_consts_b(device->wined3d_device, reg_idx, data, count);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetVertexShaderConstantB(IDirect3DDevice9Ex *iface,
+ UINT reg_idx, BOOL *data, UINT count)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_vs_consts_b(device->wined3d_device, reg_idx, data, count);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_SetStreamSource(IDirect3DDevice9Ex *iface,
+ UINT stream_idx, IDirect3DVertexBuffer9 *buffer, UINT offset, UINT stride)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_vertexbuffer *buffer_impl = unsafe_impl_from_IDirect3DVertexBuffer9(buffer);
+ HRESULT hr;
+
+ TRACE("iface %p, stream_idx %u, buffer %p, offset %u, stride %u.\n",
+ iface, stream_idx, buffer, offset, stride);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_stream_source(device->wined3d_device, stream_idx,
+ buffer_impl ? buffer_impl->wined3d_buffer : NULL, offset, stride);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetStreamSource(IDirect3DDevice9Ex *iface,
+ UINT stream_idx, IDirect3DVertexBuffer9 **buffer, UINT *offset, UINT *stride)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_vertexbuffer *buffer_impl;
+ struct wined3d_buffer *wined3d_buffer;
+ HRESULT hr;
+
+ TRACE("iface %p, stream_idx %u, buffer %p, offset %p, stride %p.\n",
+ iface, stream_idx, buffer, offset, stride);
+
+ if (!buffer)
+ return D3DERR_INVALIDCALL;
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_stream_source(device->wined3d_device, stream_idx, &wined3d_buffer, offset, stride);
+ if (SUCCEEDED(hr) && wined3d_buffer)
+ {
+ buffer_impl = wined3d_buffer_get_parent(wined3d_buffer);
+ *buffer = &buffer_impl->IDirect3DVertexBuffer9_iface;
+ IDirect3DVertexBuffer9_AddRef(*buffer);
+ wined3d_buffer_decref(wined3d_buffer);
+ }
+ else
+ {
+ if (FAILED(hr))
+ FIXME("Call to GetStreamSource failed %p %p\n", offset, stride);
+ *buffer = NULL;
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_SetStreamSourceFreq(IDirect3DDevice9Ex *iface, UINT stream_idx, UINT freq)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, stream_idx %u, freq %u.\n", iface, stream_idx, freq);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_stream_source_freq(device->wined3d_device, stream_idx, freq);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetStreamSourceFreq(IDirect3DDevice9Ex *iface, UINT stream_idx, UINT *freq)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, stream_idx %u, freq %p.\n", iface, stream_idx, freq);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_stream_source_freq(device->wined3d_device, stream_idx, freq);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_SetIndices(IDirect3DDevice9Ex *iface, IDirect3DIndexBuffer9 *buffer)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_indexbuffer *ib = unsafe_impl_from_IDirect3DIndexBuffer9(buffer);
+
+ TRACE("iface %p, buffer %p.\n", iface, buffer);
+
+ wined3d_mutex_lock();
+ wined3d_device_set_index_buffer(device->wined3d_device,
+ ib ? ib->wined3d_buffer : NULL,
+ ib ? ib->format : WINED3DFMT_UNKNOWN);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_GetIndices(IDirect3DDevice9Ex *iface, IDirect3DIndexBuffer9 **buffer)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ enum wined3d_format_id wined3d_format;
+ struct wined3d_buffer *wined3d_buffer;
+ struct d3d9_indexbuffer *buffer_impl;
+
+ TRACE("iface %p, buffer %p.\n", iface, buffer);
+
+ if (!buffer)
+ return D3DERR_INVALIDCALL;
+
+ wined3d_mutex_lock();
+ if ((wined3d_buffer = wined3d_device_get_index_buffer(device->wined3d_device, &wined3d_format)))
+ {
+ buffer_impl = wined3d_buffer_get_parent(wined3d_buffer);
+ *buffer = &buffer_impl->IDirect3DIndexBuffer9_iface;
+ IDirect3DIndexBuffer9_AddRef(*buffer);
+ }
+ else
+ {
+ *buffer = NULL;
+ }
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_CreatePixelShader(IDirect3DDevice9Ex *iface,
+ const DWORD *byte_code, IDirect3DPixelShader9 **shader)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_pixelshader *object;
+ HRESULT hr;
+
+ TRACE("iface %p, byte_code %p, shader %p.\n", iface, byte_code, shader);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ {
+ FIXME("Failed to allocate pixel shader memory.\n");
+ return E_OUTOFMEMORY;
+ }
+
+ hr = pixelshader_init(object, device, byte_code);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created pixel shader %p.\n", object);
+ *shader = &object->IDirect3DPixelShader9_iface;
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_SetPixelShader(IDirect3DDevice9Ex *iface, IDirect3DPixelShader9 *shader)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_pixelshader *shader_obj = unsafe_impl_from_IDirect3DPixelShader9(shader);
+
+ TRACE("iface %p, shader %p.\n", iface, shader);
+
+ wined3d_mutex_lock();
+ wined3d_device_set_pixel_shader(device->wined3d_device,
+ shader_obj ? shader_obj->wined3d_shader : NULL);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_GetPixelShader(IDirect3DDevice9Ex *iface, IDirect3DPixelShader9 **shader)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_pixelshader *shader_impl;
+ struct wined3d_shader *wined3d_shader;
+
+ TRACE("iface %p, shader %p.\n", iface, shader);
+
+ if (!shader) return D3DERR_INVALIDCALL;
+
+ wined3d_mutex_lock();
+ if ((wined3d_shader = wined3d_device_get_pixel_shader(device->wined3d_device)))
+ {
+ shader_impl = wined3d_shader_get_parent(wined3d_shader);
+ *shader = &shader_impl->IDirect3DPixelShader9_iface;
+ IDirect3DPixelShader9_AddRef(*shader);
+ }
+ else
+ {
+ *shader = NULL;
+ }
+ wined3d_mutex_unlock();
+
+ TRACE("Returning %p.\n", *shader);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_SetPixelShaderConstantF(IDirect3DDevice9Ex *iface,
+ UINT reg_idx, const float *data, UINT count)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_ps_consts_f(device->wined3d_device, reg_idx, data, count);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetPixelShaderConstantF(IDirect3DDevice9Ex *iface,
+ UINT reg_idx, float *data, UINT count)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_ps_consts_f(device->wined3d_device, reg_idx, data, count);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_SetPixelShaderConstantI(IDirect3DDevice9Ex *iface,
+ UINT reg_idx, const int *data, UINT count)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_ps_consts_i(device->wined3d_device, reg_idx, data, count);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetPixelShaderConstantI(IDirect3DDevice9Ex *iface,
+ UINT reg_idx, int *data, UINT count)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_ps_consts_i(device->wined3d_device, reg_idx, data, count);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_SetPixelShaderConstantB(IDirect3DDevice9Ex *iface,
+ UINT reg_idx, const BOOL *data, UINT count)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_set_ps_consts_b(device->wined3d_device, reg_idx, data, count);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetPixelShaderConstantB(IDirect3DDevice9Ex *iface,
+ UINT reg_idx, BOOL *data, UINT count)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_ps_consts_b(device->wined3d_device, reg_idx, data, count);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_DrawRectPatch(IDirect3DDevice9Ex *iface, UINT handle,
+ const float *segment_count, const D3DRECTPATCH_INFO *patch_info)
+{
+ FIXME("iface %p, handle %#x, segment_count %p, patch_info %p unimplemented.\n",
+ iface, handle, segment_count, patch_info);
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_DrawTriPatch(IDirect3DDevice9Ex *iface, UINT handle,
+ const float *segment_count, const D3DTRIPATCH_INFO *patch_info)
+{
+ FIXME("iface %p, handle %#x, segment_count %p, patch_info %p unimplemented.\n",
+ iface, handle, segment_count, patch_info);
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_DeletePatch(IDirect3DDevice9Ex *iface, UINT handle)
+{
+ FIXME("iface %p, handle %#x unimplemented.\n", iface, handle);
+ return D3DERR_INVALIDCALL;
+}
+
+static HRESULT WINAPI d3d9_device_CreateQuery(IDirect3DDevice9Ex *iface, D3DQUERYTYPE type, IDirect3DQuery9 **query)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_query *object;
+ HRESULT hr;
+
+ TRACE("iface %p, type %#x, query %p.\n", iface, type, query);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ hr = query_init(object, device, type);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize query, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created query %p.\n", object);
+ if (query) *query = &object->IDirect3DQuery9_iface;
+ else IDirect3DQuery9_Release(&object->IDirect3DQuery9_iface);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_SetConvolutionMonoKernel(IDirect3DDevice9Ex *iface,
+ UINT width, UINT height, float *rows, float *columns)
+{
+ FIXME("iface %p, width %u, height %u, rows %p, columns %p stub!\n",
+ iface, width, height, rows, columns);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3d9_device_ComposeRects(IDirect3DDevice9Ex *iface,
+ IDirect3DSurface9 *src_surface, IDirect3DSurface9 *dst_surface, IDirect3DVertexBuffer9 *src_descs,
+ UINT rect_count, IDirect3DVertexBuffer9 *dst_descs, D3DCOMPOSERECTSOP operation, INT offset_x, INT offset_y)
+{
+ FIXME("iface %p, src_surface %p, dst_surface %p, src_descs %p, rect_count %u,\n"
+ "dst_descs %p, operation %#x, offset_x %u, offset_y %u stub!\n",
+ iface, src_surface, dst_surface, src_descs, rect_count,
+ dst_descs, operation, offset_x, offset_y);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3d9_device_PresentEx(IDirect3DDevice9Ex *iface,
+ const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
+ const RGNDATA *dirty_region, DWORD flags)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p, flags %#x.\n",
+ iface, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect),
+ dst_window_override, dirty_region, flags);
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_present(device->wined3d_device, src_rect, dst_rect,
+ dst_window_override, dirty_region, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetGPUThreadPriority(IDirect3DDevice9Ex *iface, INT *priority)
+{
+ FIXME("iface %p, priority %p stub!\n", iface, priority);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3d9_device_SetGPUThreadPriority(IDirect3DDevice9Ex *iface, INT priority)
+{
+ FIXME("iface %p, priority %d stub!\n", iface, priority);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3d9_device_WaitForVBlank(IDirect3DDevice9Ex *iface, UINT swapchain_idx)
+{
+ FIXME("iface %p, swapchain_idx %u stub!\n", iface, swapchain_idx);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3d9_device_CheckResourceResidency(IDirect3DDevice9Ex *iface,
+ IDirect3DResource9 **resources, UINT32 resource_count)
+{
+ FIXME("iface %p, resources %p, resource_count %u stub!\n",
+ iface, resources, resource_count);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3d9_device_SetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT max_latency)
+{
+ FIXME("iface %p, max_latency %u stub!\n", iface, max_latency);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3d9_device_GetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT *max_latency)
+{
+ FIXME("iface %p, max_latency %p stub!\n", iface, max_latency);
+
+ *max_latency = 2;
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3d9_device_CheckDeviceState(IDirect3DDevice9Ex *iface, HWND dst_window)
+{
+ static int i;
+
+ TRACE("iface %p, dst_window %p stub!\n", iface, dst_window);
+
+ if (!i++)
+ FIXME("iface %p, dst_window %p stub!\n", iface, dst_window);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_device_CreateRenderTargetEx(IDirect3DDevice9Ex *iface,
+ UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality,
+ BOOL lockable, IDirect3DSurface9 **surface, HANDLE *shared_handle, DWORD usage)
+{
+ FIXME("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u,\n"
+ "lockable %#x, surface %p, shared_handle %p, usage %#x stub!\n",
+ iface, width, height, format, multisample_type, multisample_quality,
+ lockable, surface, shared_handle, usage);
+
+ if (shared_handle)
+ FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3d9_device_CreateOffscreenPlainSurfaceEx(IDirect3DDevice9Ex *iface,
+ UINT width, UINT height, D3DFORMAT format, D3DPOOL pool, IDirect3DSurface9 **surface,
+ HANDLE *shared_handle, DWORD usage)
+{
+ FIXME("iface %p, width %u, height %u, format %#x, pool %#x, surface %p, shared_handle %p, usage %#x stub!\n",
+ iface, width, height, format, pool, surface, shared_handle, usage);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3d9_device_CreateDepthStencilSurfaceEx(IDirect3DDevice9Ex *iface,
+ UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality,
+ BOOL discard, IDirect3DSurface9 **surface, HANDLE *shared_handle, DWORD usage)
+{
+ FIXME("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u,\n"
+ "discard %#x, surface %p, shared_handle %p, usage %#x stub!\n",
+ iface, width, height, format, multisample_type, multisample_quality,
+ discard, surface, shared_handle, usage);
+
+ if (shared_handle)
+ FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3d9_device_ResetEx(IDirect3DDevice9Ex *iface,
+ D3DPRESENT_PARAMETERS *present_parameters, D3DDISPLAYMODEEX *mode)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct wined3d_swapchain_desc swapchain_desc;
+ struct wined3d_display_mode wined3d_mode;
+ HRESULT hr;
+
+ TRACE("iface %p, present_parameters %p, mode %p.\n", iface, present_parameters, mode);
+
+ if (mode)
+ {
+ wined3d_mode.width = mode->Width;
+ wined3d_mode.height = mode->Height;
+ wined3d_mode.refresh_rate = mode->RefreshRate;
+ wined3d_mode.format_id = wined3dformat_from_d3dformat(mode->Format);
+ wined3d_mode.scanline_ordering = mode->ScanLineOrdering;
+ }
+
+ wined3d_mutex_lock();
+
+ if (device->vertex_buffer)
+ {
+ wined3d_buffer_decref(device->vertex_buffer);
+ device->vertex_buffer = NULL;
+ device->vertex_buffer_size = 0;
+ }
+ if (device->index_buffer)
+ {
+ wined3d_buffer_decref(device->index_buffer);
+ device->index_buffer = NULL;
+ device->index_buffer_size = 0;
+ }
+
+ wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, present_parameters);
+ hr = wined3d_device_reset(device->wined3d_device, &swapchain_desc,
+ mode ? &wined3d_mode : NULL, reset_enum_callback, FALSE);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_device_GetDisplayModeEx(IDirect3DDevice9Ex *iface,
+ UINT swapchain_idx, D3DDISPLAYMODEEX *mode, D3DDISPLAYROTATION *rotation)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct wined3d_display_mode wined3d_mode;
+ HRESULT hr;
+
+ TRACE("iface %p, swapchain_idx %u, mode %p, rotation %p.\n",
+ iface, swapchain_idx, mode, rotation);
+
+ if (mode->Size != sizeof(*mode))
+ return D3DERR_INVALIDCALL;
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_get_display_mode(device->wined3d_device, swapchain_idx, &wined3d_mode,
+ (enum wined3d_display_rotation *)rotation);
+ wined3d_mutex_unlock();
+
+ if (SUCCEEDED(hr))
+ {
+ mode->Width = wined3d_mode.width;
+ mode->Height = wined3d_mode.height;
+ mode->RefreshRate = wined3d_mode.refresh_rate;
+ mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id);
+ mode->ScanLineOrdering = wined3d_mode.scanline_ordering;
+ }
+
+ return hr;
+}
+
+static const struct IDirect3DDevice9ExVtbl d3d9_device_vtbl =
+{
+ /* IUnknown */
+ d3d9_device_QueryInterface,
+ d3d9_device_AddRef,
+ d3d9_device_Release,
+ /* IDirect3DDevice9 */
+ d3d9_device_TestCooperativeLevel,
+ d3d9_device_GetAvailableTextureMem,
+ d3d9_device_EvictManagedResources,
+ d3d9_device_GetDirect3D,
+ d3d9_device_GetDeviceCaps,
+ d3d9_device_GetDisplayMode,
+ d3d9_device_GetCreationParameters,
+ d3d9_device_SetCursorProperties,
+ d3d9_device_SetCursorPosition,
+ d3d9_device_ShowCursor,
+ d3d9_device_CreateAdditionalSwapChain,
+ d3d9_device_GetSwapChain,
+ d3d9_device_GetNumberOfSwapChains,
+ d3d9_device_Reset,
+ d3d9_device_Present,
+ d3d9_device_GetBackBuffer,
+ d3d9_device_GetRasterStatus,
+ d3d9_device_SetDialogBoxMode,
+ d3d9_device_SetGammaRamp,
+ d3d9_device_GetGammaRamp,
+ d3d9_device_CreateTexture,
+ d3d9_device_CreateVolumeTexture,
+ d3d9_device_CreateCubeTexture,
+ d3d9_device_CreateVertexBuffer,
+ d3d9_device_CreateIndexBuffer,
+ d3d9_device_CreateRenderTarget,
+ d3d9_device_CreateDepthStencilSurface,
+ d3d9_device_UpdateSurface,
+ d3d9_device_UpdateTexture,
+ d3d9_device_GetRenderTargetData,
+ d3d9_device_GetFrontBufferData,
+ d3d9_device_StretchRect,
+ d3d9_device_ColorFill,
+ d3d9_device_CreateOffscreenPlainSurface,
+ d3d9_device_SetRenderTarget,
+ d3d9_device_GetRenderTarget,
+ d3d9_device_SetDepthStencilSurface,
+ d3d9_device_GetDepthStencilSurface,
+ d3d9_device_BeginScene,
+ d3d9_device_EndScene,
+ d3d9_device_Clear,
+ d3d9_device_SetTransform,
+ d3d9_device_GetTransform,
+ d3d9_device_MultiplyTransform,
+ d3d9_device_SetViewport,
+ d3d9_device_GetViewport,
+ d3d9_device_SetMaterial,
+ d3d9_device_GetMaterial,
+ d3d9_device_SetLight,
+ d3d9_device_GetLight,
+ d3d9_device_LightEnable,
+ d3d9_device_GetLightEnable,
+ d3d9_device_SetClipPlane,
+ d3d9_device_GetClipPlane,
+ d3d9_device_SetRenderState,
+ d3d9_device_GetRenderState,
+ d3d9_device_CreateStateBlock,
+ d3d9_device_BeginStateBlock,
+ d3d9_device_EndStateBlock,
+ d3d9_device_SetClipStatus,
+ d3d9_device_GetClipStatus,
+ d3d9_device_GetTexture,
+ d3d9_device_SetTexture,
+ d3d9_device_GetTextureStageState,
+ d3d9_device_SetTextureStageState,
+ d3d9_device_GetSamplerState,
+ d3d9_device_SetSamplerState,
+ d3d9_device_ValidateDevice,
+ d3d9_device_SetPaletteEntries,
+ d3d9_device_GetPaletteEntries,
+ d3d9_device_SetCurrentTexturePalette,
+ d3d9_device_GetCurrentTexturePalette,
+ d3d9_device_SetScissorRect,
+ d3d9_device_GetScissorRect,
+ d3d9_device_SetSoftwareVertexProcessing,
+ d3d9_device_GetSoftwareVertexProcessing,
+ d3d9_device_SetNPatchMode,
+ d3d9_device_GetNPatchMode,
+ d3d9_device_DrawPrimitive,
+ d3d9_device_DrawIndexedPrimitive,
+ d3d9_device_DrawPrimitiveUP,
+ d3d9_device_DrawIndexedPrimitiveUP,
+ d3d9_device_ProcessVertices,
+ d3d9_device_CreateVertexDeclaration,
+ d3d9_device_SetVertexDeclaration,
+ d3d9_device_GetVertexDeclaration,
+ d3d9_device_SetFVF,
+ d3d9_device_GetFVF,
+ d3d9_device_CreateVertexShader,
+ d3d9_device_SetVertexShader,
+ d3d9_device_GetVertexShader,
+ d3d9_device_SetVertexShaderConstantF,
+ d3d9_device_GetVertexShaderConstantF,
+ d3d9_device_SetVertexShaderConstantI,
+ d3d9_device_GetVertexShaderConstantI,
+ d3d9_device_SetVertexShaderConstantB,
+ d3d9_device_GetVertexShaderConstantB,
+ d3d9_device_SetStreamSource,
+ d3d9_device_GetStreamSource,
+ d3d9_device_SetStreamSourceFreq,
+ d3d9_device_GetStreamSourceFreq,
+ d3d9_device_SetIndices,
+ d3d9_device_GetIndices,
+ d3d9_device_CreatePixelShader,
+ d3d9_device_SetPixelShader,
+ d3d9_device_GetPixelShader,
+ d3d9_device_SetPixelShaderConstantF,
+ d3d9_device_GetPixelShaderConstantF,
+ d3d9_device_SetPixelShaderConstantI,
+ d3d9_device_GetPixelShaderConstantI,
+ d3d9_device_SetPixelShaderConstantB,
+ d3d9_device_GetPixelShaderConstantB,
+ d3d9_device_DrawRectPatch,
+ d3d9_device_DrawTriPatch,
+ d3d9_device_DeletePatch,
+ d3d9_device_CreateQuery,
+ /* IDirect3DDevice9Ex */
+ d3d9_device_SetConvolutionMonoKernel,
+ d3d9_device_ComposeRects,
+ d3d9_device_PresentEx,
+ d3d9_device_GetGPUThreadPriority,
+ d3d9_device_SetGPUThreadPriority,
+ d3d9_device_WaitForVBlank,
+ d3d9_device_CheckResourceResidency,
+ d3d9_device_SetMaximumFrameLatency,
+ d3d9_device_GetMaximumFrameLatency,
+ d3d9_device_CheckDeviceState,
+ d3d9_device_CreateRenderTargetEx,
+ d3d9_device_CreateOffscreenPlainSurfaceEx,
+ d3d9_device_CreateDepthStencilSurfaceEx,
+ d3d9_device_ResetEx,
+ d3d9_device_GetDisplayModeEx,
+};
+
+static inline struct d3d9_device *device_from_device_parent(struct wined3d_device_parent *device_parent)
+{
+ return CONTAINING_RECORD(device_parent, struct d3d9_device, device_parent);
+}
+
+static void CDECL device_parent_wined3d_device_created(struct wined3d_device_parent *device_parent,
+ struct wined3d_device *device)
+{
+ TRACE("device_parent %p, device %p.\n", device_parent, device);
+}
+
+static void CDECL device_parent_mode_changed(struct wined3d_device_parent *device_parent)
+{
+ TRACE("device_parent %p.\n", device_parent);
+}
+
+static HRESULT CDECL device_parent_create_texture_surface(struct wined3d_device_parent *device_parent,
+ void *container_parent, const struct wined3d_resource_desc *desc, UINT sub_resource_idx,
+ DWORD flags, struct wined3d_surface **surface
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void *pvClientMem
+#endif
+ )
+{
+ struct d3d9_device *device = device_from_device_parent(device_parent);
+ struct d3d9_surface *d3d_surface;
+ HRESULT hr;
+
+ TRACE("device_parent %p, container_parent %p, desc %p, sub_resource_idx %u, flags %#x, surface %p.\n",
+ device_parent, container_parent, desc, sub_resource_idx, flags, surface);
+
+#ifdef VBOX_WITH_WDDM
+ if (FAILED(hr = d3d9_device_create_surface(device, desc->width, desc->height,
+ d3dformat_from_wined3dformat(desc->format), flags, (IDirect3DSurface9 **)&d3d_surface,
+ desc->usage, desc->pool, desc->multisample_type, desc->multisample_quality
+ , shared_handle
+ , pvClientMem
+ )))
+#else
+ if (FAILED(hr = d3d9_device_create_surface(device, desc->width, desc->height,
+ d3dformat_from_wined3dformat(desc->format), flags, (IDirect3DSurface9 **)&d3d_surface,
+ desc->usage, desc->pool, desc->multisample_type, desc->multisample_quality)))
+#endif
+ {
+ WARN("Failed to create surface, hr %#x.\n", hr);
+ return hr;
+ }
+
+ *surface = d3d_surface->wined3d_surface;
+ wined3d_surface_incref(*surface);
+
+ d3d_surface->container = container_parent;
+ IDirect3DDevice9Ex_Release(d3d_surface->parent_device);
+ d3d_surface->parent_device = NULL;
+
+ IDirect3DSurface9_Release(&d3d_surface->IDirect3DSurface9_iface);
+ d3d_surface->forwardReference = container_parent;
+
+ return hr;
+}
+
+static HRESULT CDECL device_parent_create_swapchain_surface(struct wined3d_device_parent *device_parent,
+ void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_surface **surface)
+{
+ struct d3d9_device *device = device_from_device_parent(device_parent);
+ struct wined3d_resource_desc texture_desc;
+ struct d3d9_surface *d3d_surface;
+ struct wined3d_texture *texture;
+ HRESULT hr;
+
+ TRACE("device_parent %p, container_parent %p, desc %p, surface %p.\n",
+ device_parent, container_parent, desc, surface);
+
+ if (container_parent == device_parent)
+ container_parent = &device->IDirect3DDevice9Ex_iface;
+
+ texture_desc = *desc;
+ texture_desc.resource_type = WINED3D_RTYPE_TEXTURE;
+#ifdef VBOX_WITH_WDDM
+ if (FAILED(hr = wined3d_texture_create_2d(device->wined3d_device, &texture_desc, 1,
+ WINED3D_SURFACE_MAPPABLE, container_parent, &d3d9_null_wined3d_parent_ops, &texture
+ , NULL, NULL)))
+#else
+ if (FAILED(hr = wined3d_texture_create_2d(device->wined3d_device, &texture_desc, 1,
+ WINED3D_SURFACE_MAPPABLE, container_parent, &d3d9_null_wined3d_parent_ops, &texture)))
+#endif
+ {
+ WARN("Failed to create texture, hr %#x.\n", hr);
+ return hr;
+ }
+
+ *surface = wined3d_surface_from_resource(wined3d_texture_get_sub_resource(texture, 0));
+ wined3d_surface_incref(*surface);
+ wined3d_texture_decref(texture);
+
+ d3d_surface = wined3d_surface_get_parent(*surface);
+ d3d_surface->forwardReference = NULL;
+ d3d_surface->parent_device = &device->IDirect3DDevice9Ex_iface;
+ return hr;
+}
+
+static HRESULT CDECL device_parent_create_volume(struct wined3d_device_parent *device_parent,
+ void *container_parent, UINT width, UINT height, UINT depth, enum wined3d_format_id format,
+ enum wined3d_pool pool, DWORD usage, struct wined3d_volume **volume
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void *pvClientMem
+#endif
+ )
+{
+ struct d3d9_device *device = device_from_device_parent(device_parent);
+ struct d3d9_volume *object;
+ HRESULT hr;
+
+ TRACE("device_parent %p, container_parent %p, width %u, height %u, depth %u, "
+ "format %#x, pool %#x, usage %#x, volume %p\n",
+ device_parent, container_parent, width, height, depth,
+ format, pool, usage, volume);
+
+ /* Allocate the storage for the device */
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ {
+ FIXME("Allocation of memory failed\n");
+ *volume = NULL;
+ return D3DERR_OUTOFVIDEOMEMORY;
+ }
+
+ hr = volume_init(object, device, width, height, depth, usage, format, pool
+#ifdef VBOX_WITH_WDDM
+ , shared_handle
+ , pvClientMem
+#endif
+ );
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize volume, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ *volume = object->wined3d_volume;
+ wined3d_volume_incref(*volume);
+ IDirect3DVolume9_Release(&object->IDirect3DVolume9_iface);
+
+ object->container = container_parent;
+ object->forwardReference = container_parent;
+
+ TRACE("Created volume %p.\n", object);
+
+ return hr;
+}
+
+static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent *device_parent,
+ struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain)
+{
+ struct d3d9_device *device = device_from_device_parent(device_parent);
+ struct d3d9_swapchain *d3d_swapchain;
+ HRESULT hr;
+
+ TRACE("device_parent %p, desc %p, swapchain %p\n", device_parent, desc, swapchain);
+
+ hr = d3d9_swapchain_create(device, desc, &d3d_swapchain);
+ if (FAILED(hr))
+ {
+ WARN("Failed to create swapchain, hr %#x.\n", hr);
+ *swapchain = NULL;
+ return hr;
+ }
+
+ *swapchain = d3d_swapchain->wined3d_swapchain;
+ wined3d_swapchain_incref(*swapchain);
+ IDirect3DSwapChain9_Release(&d3d_swapchain->IDirect3DSwapChain9_iface);
+
+ return hr;
+}
+
+static const struct wined3d_device_parent_ops d3d9_wined3d_device_parent_ops =
+{
+ device_parent_wined3d_device_created,
+ device_parent_mode_changed,
+ device_parent_create_swapchain_surface,
+ device_parent_create_texture_surface,
+ device_parent_create_volume,
+ device_parent_create_swapchain,
+};
+
+#if defined(VBOX) && defined(RT_ARCH_AMD64)
+DECLASM(uint16_t) VBoxAsmFpuFCWGet();
+DECLASM(void) VBoxAsmFpuFCWSet(uint16_t u16FCW);
+#endif
+
+static void setup_fpu(void)
+{
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+ WORD cw;
+ __asm__ volatile ("fnstcw %0" : "=m" (cw));
+ cw = (cw & ~0xf3f) | 0x3f;
+ __asm__ volatile ("fldcw %0" : : "m" (cw));
+#elif defined(__i386__) && defined(_MSC_VER)
+ WORD cw;
+ __asm fnstcw cw;
+ cw = (cw & ~0xf3f) | 0x3f;
+ __asm fldcw cw;
+#elif defined(VBOX) && defined(RT_ARCH_AMD64)
+ uint16_t cw = VBoxAsmFpuFCWGet();
+ cw = (cw & ~0xf3f) | 0x3f;
+ VBoxAsmFpuFCWSet(cw);
+#else
+ FIXME("FPU setup not implemented for this platform.\n");
+#endif
+}
+
+HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wined3d *wined3d,
+ UINT adapter, D3DDEVTYPE device_type, HWND focus_window, DWORD flags
+#ifdef VBOX_WITH_WDDM
+ , VBOXWINEEX_D3DPRESENT_PARAMETERS *parameters
+#else
+ , D3DPRESENT_PARAMETERS *parameters
+#endif
+ , D3DDISPLAYMODEEX *mode)
+{
+ struct wined3d_swapchain_desc *swapchain_desc;
+ UINT i, count = 1;
+ HRESULT hr;
+
+ if (mode)
+ FIXME("Ignoring display mode.\n");
+
+ device->IDirect3DDevice9Ex_iface.lpVtbl = &d3d9_device_vtbl;
+ device->device_parent.ops = &d3d9_wined3d_device_parent_ops;
+ device->refcount = 1;
+
+ if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu();
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_create(wined3d, adapter, device_type, focus_window, flags, 4,
+ &device->device_parent, &device->wined3d_device);
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d device, hr %#x.\n", hr);
+ wined3d_mutex_unlock();
+ return hr;
+ }
+
+ if (flags & D3DCREATE_ADAPTERGROUP_DEVICE)
+ {
+ WINED3DCAPS caps;
+
+ wined3d_get_device_caps(wined3d, adapter, device_type, &caps);
+ count = caps.NumberOfAdaptersInGroup;
+ }
+
+ if (flags & D3DCREATE_MULTITHREADED)
+ wined3d_device_set_multithreaded(device->wined3d_device);
+
+#ifndef VBOX_WITH_WDDM
+ if (!parameters->Windowed)
+ {
+ if (!focus_window)
+ focus_window = parameters->hDeviceWindow;
+ if (FAILED(hr = wined3d_device_acquire_focus_window(device->wined3d_device, focus_window)))
+ {
+ ERR("Failed to acquire focus window, hr %#x.\n", hr);
+ wined3d_device_decref(device->wined3d_device);
+ wined3d_mutex_unlock();
+ return hr;
+ }
+
+ for (i = 0; i < count; ++i)
+ {
+ HWND device_window = parameters[i].hDeviceWindow;
+
+ if (!device_window) device_window = focus_window;
+ wined3d_device_setup_fullscreen_window(device->wined3d_device, device_window,
+ parameters[i].BackBufferWidth,
+ parameters[i].BackBufferHeight);
+ }
+ }
+#else
+ if (!parameters->Base.Windowed)
+ {
+ ERR("non-windowed mode unsupported!");
+ parameters->Base.Windowed = TRUE;
+ }
+#endif
+
+ swapchain_desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain_desc) * count);
+ if (!swapchain_desc)
+ {
+ ERR("Failed to allocate wined3d parameters.\n");
+ wined3d_device_decref(device->wined3d_device);
+ wined3d_mutex_unlock();
+ return E_OUTOFMEMORY;
+ }
+
+ for (i = 0; i < count; ++i)
+ {
+#ifdef VBOX_WITH_WDDM
+ wined3d_swapchain_desc_from_present_parameters(&swapchain_desc[i], &parameters[i].Base);
+ swapchain_desc[i].pHgsmi = parameters[i].pHgsmi;
+#else
+ wined3d_swapchain_desc_from_present_parameters(&swapchain_desc[i], &parameters[i]);
+#endif
+ }
+
+ hr = wined3d_device_init_3d(device->wined3d_device, swapchain_desc);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize 3D, hr %#x.\n", hr);
+#ifndef VBOX_WITH_WDDM
+ wined3d_device_release_focus_window(device->wined3d_device);
+#endif
+ HeapFree(GetProcessHeap(), 0, swapchain_desc);
+ wined3d_device_decref(device->wined3d_device);
+ wined3d_mutex_unlock();
+ return hr;
+ }
+
+ wined3d_mutex_unlock();
+
+ for (i = 0; i < count; ++i)
+ {
+#ifndef VBOX_WITH_WDDM
+ present_parameters_from_wined3d_swapchain_desc(&parameters[i], &swapchain_desc[i]);
+#else
+ present_parameters_from_wined3d_swapchain_desc(&parameters[i].Base, &swapchain_desc[i]);
+#endif
+ }
+ HeapFree(GetProcessHeap(), 0, swapchain_desc);
+
+ /* Initialize the converted declaration array. This creates a valid pointer
+ * and when adding decls HeapReAlloc() can be used without further checking. */
+ device->fvf_decls = HeapAlloc(GetProcessHeap(), 0, 0);
+ if (!device->fvf_decls)
+ {
+ ERR("Failed to allocate FVF vertex declaration map memory.\n");
+ wined3d_mutex_lock();
+ wined3d_device_uninit_3d(device->wined3d_device);
+#ifndef VBOX_WITH_WDDM
+ wined3d_device_release_focus_window(device->wined3d_device);
+#endif
+ wined3d_device_decref(device->wined3d_device);
+ wined3d_mutex_unlock();
+ return E_OUTOFMEMORY;
+ }
+
+ IDirect3D9Ex_AddRef(&parent->IDirect3D9Ex_iface);
+ device->d3d_parent = parent;
+
+ return D3D_OK;
+}
+
+#ifdef VBOX_WITH_WDDM
+AssertCompile(sizeof (struct wined3d_box) == sizeof (VBOXBOX3D));
+AssertCompile(RT_SIZEOFMEMB(struct wined3d_box, left) == RT_SIZEOFMEMB(VBOXBOX3D, Left));
+AssertCompile(RT_SIZEOFMEMB(struct wined3d_box, top) == RT_SIZEOFMEMB(VBOXBOX3D, Top));
+AssertCompile(RT_SIZEOFMEMB(struct wined3d_box, right) == RT_SIZEOFMEMB(VBOXBOX3D, Right));
+AssertCompile(RT_SIZEOFMEMB(struct wined3d_box, bottom) == RT_SIZEOFMEMB(VBOXBOX3D, Bottom));
+AssertCompile(RT_SIZEOFMEMB(struct wined3d_box, front) == RT_SIZEOFMEMB(VBOXBOX3D, Front));
+AssertCompile(RT_SIZEOFMEMB(struct wined3d_box, back) == RT_SIZEOFMEMB(VBOXBOX3D, Back));
+
+AssertCompile(RT_OFFSETOF(struct wined3d_box, left) == RT_OFFSETOF(VBOXBOX3D, Left));
+AssertCompile(RT_OFFSETOF(struct wined3d_box, top) == RT_OFFSETOF(VBOXBOX3D, Top));
+AssertCompile(RT_OFFSETOF(struct wined3d_box, right) == RT_OFFSETOF(VBOXBOX3D, Right));
+AssertCompile(RT_OFFSETOF(struct wined3d_box, bottom) == RT_OFFSETOF(VBOXBOX3D, Bottom));
+AssertCompile(RT_OFFSETOF(struct wined3d_box, front) == RT_OFFSETOF(VBOXBOX3D, Front));
+AssertCompile(RT_OFFSETOF(struct wined3d_box, back) == RT_OFFSETOF(VBOXBOX3D, Back));
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9VolBlt(IDirect3DDevice9Ex *iface,
+ IDirect3DVolume9 *pSourceVolume, IDirect3DVolume9 *pDestinationVolume,
+ const VBOXBOX3D *pSrcBoxArg,
+ const VBOXPOINT3D *pDstPoin3D)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_volume *src = unsafe_impl_from_IDirect3DVolume9(pSourceVolume);
+ struct d3d9_volume *dst = unsafe_impl_from_IDirect3DVolume9(pDestinationVolume);
+ HRESULT hr;
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_blt_vol(device->wined3d_device, src->wined3d_volume, dst->wined3d_volume, (struct wined3d_box*)pSrcBoxArg, pDstPoin3D);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9VolTexBlt(IDirect3DDevice9Ex *iface,
+ IDirect3DVolumeTexture9 *pSourceTexture, IDirect3DVolumeTexture9 *pDestinationTexture,
+ const VBOXBOX3D *pSrcBoxArg,
+ const VBOXPOINT3D *pDstPoin3D)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct d3d9_texture *src = unsafe_impl_from_IDirect3DBaseTexture9((IDirect3DBaseTexture9*)pSourceTexture);
+ struct d3d9_texture *dst = unsafe_impl_from_IDirect3DBaseTexture9((IDirect3DBaseTexture9*)pDestinationTexture);
+ HRESULT hr;
+
+ wined3d_mutex_lock();
+ hr = wined3d_device_blt_voltex(device->wined3d_device, src->wined3d_texture, dst->wined3d_texture, (struct wined3d_box*)pSrcBoxArg, pDstPoin3D);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9Term(IDirect3DDevice9Ex *iface)
+{
+ struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+ struct wined3d_device *wined3d_device = device->wined3d_device;
+ LONG wined3d_refs;
+ if (device->refcount != 1)
+ {
+ WARN("unexpected ref count %d, destroying in anyway", device->refcount);
+ }
+ wined3d_refs = d3d9_device_Term(device);
+ if (wined3d_refs)
+ {
+ ERR("unexpected wined3dRefs %d, destroying in anyway", wined3d_refs);
+ while (wined3d_device_decref(wined3d_device)) {}
+ }
+ return D3D_OK;
+}
+#endif
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/directx.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/directx.c
new file mode 100644
index 00000000..f3fc3ec8
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/directx.c
@@ -0,0 +1,664 @@
+/*
+ * IDirect3D9 implementation
+ *
+ * Copyright 2002 Jason Edmeades
+ * Copyright 2005 Oliver Stieber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "d3d9_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
+static inline struct d3d9 *impl_from_IDirect3D9Ex(IDirect3D9Ex *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d9, IDirect3D9Ex_iface);
+}
+
+static HRESULT WINAPI d3d9_QueryInterface(IDirect3D9Ex *iface, REFIID riid, void **out)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3D9)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3D9Ex_AddRef(&d3d9->IDirect3D9Ex_iface);
+ *out = &d3d9->IDirect3D9Ex_iface;
+ return S_OK;
+ }
+
+ if (IsEqualGUID(riid, &IID_IDirect3D9Ex))
+ {
+ if (!d3d9->extended)
+ {
+ WARN("Application asks for IDirect3D9Ex, but this instance wasn't created with Direct3DCreate9Ex.\n");
+ *out = NULL;
+ return E_NOINTERFACE;
+ }
+
+ IDirect3D9Ex_AddRef(&d3d9->IDirect3D9Ex_iface);
+ *out = &d3d9->IDirect3D9Ex_iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d9_AddRef(IDirect3D9Ex *iface)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ ULONG refcount = InterlockedIncrement(&d3d9->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, refcount);
+
+ return refcount;
+}
+
+static ULONG WINAPI d3d9_Release(IDirect3D9Ex *iface)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ ULONG refcount = InterlockedDecrement(&d3d9->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ wined3d_mutex_lock();
+ wined3d_decref(d3d9->wined3d);
+ wined3d_mutex_unlock();
+
+ HeapFree(GetProcessHeap(), 0, d3d9);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI d3d9_RegisterSoftwareDevice(IDirect3D9Ex *iface, void *init_function)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, init_function %p.\n", iface, init_function);
+
+ wined3d_mutex_lock();
+ hr = wined3d_register_software_device(d3d9->wined3d, init_function);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static UINT WINAPI d3d9_GetAdapterCount(IDirect3D9Ex *iface)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ UINT ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_get_adapter_count(d3d9->wined3d);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static HRESULT WINAPI d3d9_GetAdapterIdentifier(IDirect3D9Ex *iface, UINT adapter,
+ DWORD flags, D3DADAPTER_IDENTIFIER9 *identifier)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ struct wined3d_adapter_identifier adapter_id;
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, flags %#x, identifier %p.\n",
+ iface, adapter, flags, identifier);
+
+ adapter_id.driver = identifier->Driver;
+ adapter_id.driver_size = sizeof(identifier->Driver);
+ adapter_id.description = identifier->Description;
+ adapter_id.description_size = sizeof(identifier->Description);
+ adapter_id.device_name = identifier->DeviceName;
+ adapter_id.device_name_size = sizeof(identifier->DeviceName);
+
+ wined3d_mutex_lock();
+ hr = wined3d_get_adapter_identifier(d3d9->wined3d, adapter, flags, &adapter_id);
+ wined3d_mutex_unlock();
+
+ identifier->DriverVersion = adapter_id.driver_version;
+ identifier->VendorId = adapter_id.vendor_id;
+ identifier->DeviceId = adapter_id.device_id;
+ identifier->SubSysId = adapter_id.subsystem_id;
+ identifier->Revision = adapter_id.revision;
+ memcpy(&identifier->DeviceIdentifier, &adapter_id.device_identifier, sizeof(identifier->DeviceIdentifier));
+ identifier->WHQLLevel = adapter_id.whql_level;
+
+ return hr;
+}
+
+static UINT WINAPI d3d9_GetAdapterModeCount(IDirect3D9Ex *iface, UINT adapter, D3DFORMAT format)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ UINT ret;
+
+ TRACE("iface %p, adapter %u, format %#x.\n", iface, adapter, format);
+
+ /* Others than that not supported by d3d9, but reported by wined3d for ddraw. Filter them out. */
+ if (format != D3DFMT_X8R8G8B8 && format != D3DFMT_R5G6B5)
+ return 0;
+
+ wined3d_mutex_lock();
+ ret = wined3d_get_adapter_mode_count(d3d9->wined3d, adapter,
+ wined3dformat_from_d3dformat(format), WINED3D_SCANLINE_ORDERING_UNKNOWN);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static HRESULT WINAPI d3d9_EnumAdapterModes(IDirect3D9Ex *iface, UINT adapter,
+ D3DFORMAT format, UINT mode_idx, D3DDISPLAYMODE *mode)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ struct wined3d_display_mode wined3d_mode;
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, format %#x, mode_idx %u, mode %p.\n",
+ iface, adapter, format, mode_idx, mode);
+
+ if (format != D3DFMT_X8R8G8B8 && format != D3DFMT_R5G6B5)
+ return D3DERR_INVALIDCALL;
+
+ wined3d_mutex_lock();
+ hr = wined3d_enum_adapter_modes(d3d9->wined3d, adapter, wined3dformat_from_d3dformat(format),
+ WINED3D_SCANLINE_ORDERING_UNKNOWN, mode_idx, &wined3d_mode);
+ wined3d_mutex_unlock();
+
+ if (SUCCEEDED(hr))
+ {
+ mode->Width = wined3d_mode.width;
+ mode->Height = wined3d_mode.height;
+ mode->RefreshRate = wined3d_mode.refresh_rate;
+ mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id);
+ }
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_GetAdapterDisplayMode(IDirect3D9Ex *iface, UINT adapter, D3DDISPLAYMODE *mode)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ struct wined3d_display_mode wined3d_mode;
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, mode %p.\n", iface, adapter, mode);
+
+ wined3d_mutex_lock();
+ hr = wined3d_get_adapter_display_mode(d3d9->wined3d, adapter, &wined3d_mode, NULL);
+ wined3d_mutex_unlock();
+
+ if (SUCCEEDED(hr))
+ {
+ mode->Width = wined3d_mode.width;
+ mode->Height = wined3d_mode.height;
+ mode->RefreshRate = wined3d_mode.refresh_rate;
+ mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id);
+ }
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_CheckDeviceType(IDirect3D9Ex *iface, UINT adapter, D3DDEVTYPE device_type,
+ D3DFORMAT display_format, D3DFORMAT backbuffer_format, BOOL windowed)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, device_type %#x, display_format %#x, backbuffer_format %#x, windowed %#x.\n",
+ iface, adapter, device_type, display_format, backbuffer_format, windowed);
+
+ wined3d_mutex_lock();
+ hr = wined3d_check_device_type(d3d9->wined3d, adapter, device_type, wined3dformat_from_d3dformat(display_format),
+ wined3dformat_from_d3dformat(backbuffer_format), windowed);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_CheckDeviceFormat(IDirect3D9Ex *iface, UINT adapter, D3DDEVTYPE device_type,
+ D3DFORMAT adapter_format, DWORD usage, D3DRESOURCETYPE resource_type, D3DFORMAT format)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ enum wined3d_resource_type wined3d_rtype;
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, device_type %#x, adapter_format %#x, usage %#x, resource_type %#x, format %#x.\n",
+ iface, adapter, device_type, adapter_format, usage, resource_type, format);
+
+ switch (resource_type)
+ {
+ case D3DRTYPE_VERTEXBUFFER:
+ case D3DRTYPE_INDEXBUFFER:
+ wined3d_rtype = WINED3D_RTYPE_BUFFER;
+ break;
+
+ default:
+ wined3d_rtype = resource_type;
+ break;
+ }
+
+ wined3d_mutex_lock();
+ hr = wined3d_check_device_format(d3d9->wined3d, adapter, device_type, wined3dformat_from_d3dformat(adapter_format),
+ usage, wined3d_rtype, wined3dformat_from_d3dformat(format));
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_CheckDeviceMultiSampleType(IDirect3D9Ex *iface, UINT adapter, D3DDEVTYPE device_type,
+ D3DFORMAT format, BOOL windowed, D3DMULTISAMPLE_TYPE multisample_type, DWORD *levels)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, device_type %#x, format %#x, windowed %#x, multisample_type %#x, levels %p.\n",
+ iface, adapter, device_type, format, windowed, multisample_type, levels);
+
+ wined3d_mutex_lock();
+ hr = wined3d_check_device_multisample_type(d3d9->wined3d, adapter, device_type,
+ wined3dformat_from_d3dformat(format), windowed, multisample_type, levels);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_CheckDepthStencilMatch(IDirect3D9Ex *iface, UINT adapter, D3DDEVTYPE device_type,
+ D3DFORMAT adapter_format, D3DFORMAT rt_format, D3DFORMAT ds_format)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, device_type %#x, adapter_format %#x, rt_format %#x, ds_format %#x.\n",
+ iface, adapter, device_type, adapter_format, rt_format, ds_format);
+
+ wined3d_mutex_lock();
+ hr = wined3d_check_depth_stencil_match(d3d9->wined3d, adapter, device_type,
+ wined3dformat_from_d3dformat(adapter_format), wined3dformat_from_d3dformat(rt_format),
+ wined3dformat_from_d3dformat(ds_format));
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_CheckDeviceFormatConversion(IDirect3D9Ex *iface, UINT adapter,
+ D3DDEVTYPE device_type, D3DFORMAT src_format, D3DFORMAT dst_format)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, device_type %#x, src_format %#x, dst_format %#x.\n",
+ iface, adapter, device_type, src_format, dst_format);
+
+ wined3d_mutex_lock();
+ hr = wined3d_check_device_format_conversion(d3d9->wined3d, adapter, device_type,
+ wined3dformat_from_d3dformat(src_format), wined3dformat_from_d3dformat(dst_format));
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+void filter_caps(D3DCAPS9* pCaps)
+{
+ DWORD ps_minor_version[] = {0, 4, 0, 0};
+ DWORD vs_minor_version[] = {0, 1, 0, 0};
+ DWORD textureFilterCaps =
+ D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MINFLINEAR | D3DPTFILTERCAPS_MINFANISOTROPIC |
+ D3DPTFILTERCAPS_MINFPYRAMIDALQUAD | D3DPTFILTERCAPS_MINFGAUSSIANQUAD|
+ D3DPTFILTERCAPS_MIPFPOINT | D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MAGFPOINT |
+ D3DPTFILTERCAPS_MAGFLINEAR |D3DPTFILTERCAPS_MAGFANISOTROPIC|D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD|
+ D3DPTFILTERCAPS_MAGFGAUSSIANQUAD;
+ pCaps->TextureFilterCaps &= textureFilterCaps;
+ pCaps->CubeTextureFilterCaps &= textureFilterCaps;
+ pCaps->VolumeTextureFilterCaps &= textureFilterCaps;
+
+ pCaps->DevCaps &=
+ D3DDEVCAPS_EXECUTESYSTEMMEMORY | D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY |
+ D3DDEVCAPS_TLVERTEXVIDEOMEMORY | D3DDEVCAPS_TEXTURESYSTEMMEMORY| D3DDEVCAPS_TEXTUREVIDEOMEMORY |
+ D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_TEXTURENONLOCALVIDMEM|
+ D3DDEVCAPS_DRAWPRIMITIVES2 | D3DDEVCAPS_SEPARATETEXTUREMEMORIES |
+ D3DDEVCAPS_DRAWPRIMITIVES2EX | D3DDEVCAPS_HWTRANSFORMANDLIGHT| D3DDEVCAPS_CANBLTSYSTONONLOCAL |
+ D3DDEVCAPS_HWRASTERIZATION | D3DDEVCAPS_PUREDEVICE | D3DDEVCAPS_QUINTICRTPATCHES |
+ D3DDEVCAPS_RTPATCHES | D3DDEVCAPS_RTPATCHHANDLEZERO | D3DDEVCAPS_NPATCHES;
+
+ pCaps->ShadeCaps &=
+ D3DPSHADECAPS_COLORGOURAUDRGB | D3DPSHADECAPS_SPECULARGOURAUDRGB |
+ D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_FOGGOURAUD;
+
+ pCaps->RasterCaps &=
+ D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_FOGVERTEX |
+ D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_ZBUFFERLESSHSR |
+ D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_ANISOTROPY | D3DPRASTERCAPS_WBUFFER |
+ D3DPRASTERCAPS_WFOG | D3DPRASTERCAPS_ZFOG | D3DPRASTERCAPS_COLORPERSPECTIVE |
+ D3DPRASTERCAPS_SCISSORTEST | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
+ D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_MULTISAMPLE_TOGGLE;
+
+ pCaps->DevCaps2 &=
+ D3DDEVCAPS2_STREAMOFFSET | D3DDEVCAPS2_DMAPNPATCH | D3DDEVCAPS2_ADAPTIVETESSRTPATCH |
+ D3DDEVCAPS2_ADAPTIVETESSNPATCH | D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES |
+ D3DDEVCAPS2_PRESAMPLEDDMAPNPATCH| D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET;
+
+ pCaps->Caps2 &=
+ D3DCAPS2_FULLSCREENGAMMA | D3DCAPS2_CANCALIBRATEGAMMA | D3DCAPS2_RESERVED |
+ D3DCAPS2_CANMANAGERESOURCE | D3DCAPS2_DYNAMICTEXTURES | D3DCAPS2_CANAUTOGENMIPMAP;
+
+ pCaps->VertexProcessingCaps &=
+ D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_DIRECTIONALLIGHTS |
+ D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER | D3DVTXPCAPS_TWEENING |
+ D3DVTXPCAPS_TEXGEN_SPHEREMAP | D3DVTXPCAPS_NO_TEXGEN_NONLOCALVIEWER;
+
+ pCaps->TextureCaps &=
+ D3DPTEXTURECAPS_PERSPECTIVE | D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_ALPHA |
+ D3DPTEXTURECAPS_SQUAREONLY | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE |
+ D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_NONPOW2CONDITIONAL |
+ D3DPTEXTURECAPS_PROJECTED | D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_VOLUMEMAP |
+ D3DPTEXTURECAPS_MIPMAP | D3DPTEXTURECAPS_MIPVOLUMEMAP | D3DPTEXTURECAPS_MIPCUBEMAP |
+ D3DPTEXTURECAPS_CUBEMAP_POW2 | D3DPTEXTURECAPS_VOLUMEMAP_POW2| D3DPTEXTURECAPS_NOPROJECTEDBUMPENV;
+
+ pCaps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF, pCaps->MaxVertexShaderConst);
+ pCaps->NumSimultaneousRTs = min(D3D9_MAX_SIMULTANEOUS_RENDERTARGETS, pCaps->NumSimultaneousRTs);
+
+ if (pCaps->PixelShaderVersion > 3)
+ pCaps->PixelShaderVersion = D3DPS_VERSION(3,0);
+ else
+ {
+ DWORD major = pCaps->PixelShaderVersion;
+ pCaps->PixelShaderVersion = D3DPS_VERSION(major,ps_minor_version[major]);
+ }
+
+ if (pCaps->VertexShaderVersion > 3)
+ pCaps->VertexShaderVersion = D3DVS_VERSION(3,0);
+ else
+ {
+ DWORD major = pCaps->VertexShaderVersion;
+ pCaps->VertexShaderVersion = D3DVS_VERSION(major,vs_minor_version[major]);
+ }
+}
+
+static HRESULT WINAPI d3d9_GetDeviceCaps(IDirect3D9Ex *iface, UINT adapter, D3DDEVTYPE device_type, D3DCAPS9 *caps)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ WINED3DCAPS *wined3d_caps;
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, device_type %#x, caps %p.\n", iface, adapter, device_type, caps);
+
+ if (!caps)
+ return D3DERR_INVALIDCALL;
+
+ if (!(wined3d_caps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINED3DCAPS))))
+ return D3DERR_INVALIDCALL; /*well this is what MSDN says to return*/
+ memset(caps, 0, sizeof(*caps));
+
+ wined3d_mutex_lock();
+ hr = wined3d_get_device_caps(d3d9->wined3d, adapter, device_type, wined3d_caps);
+ wined3d_mutex_unlock();
+
+ WINECAPSTOD3D9CAPS(caps, wined3d_caps)
+ HeapFree(GetProcessHeap(), 0, wined3d_caps);
+
+ /* Some functionality is implemented in d3d9.dll, not wined3d.dll. Add the needed caps */
+ caps->DevCaps2 |= D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES;
+
+ filter_caps(caps);
+
+ return hr;
+}
+
+static HMONITOR WINAPI d3d9_GetAdapterMonitor(IDirect3D9Ex *iface, UINT adapter)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ HMONITOR ret;
+
+ TRACE("iface %p, adapter %u.\n", iface, adapter);
+
+ wined3d_mutex_lock();
+ ret = wined3d_get_adapter_monitor(d3d9->wined3d, adapter);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_CreateDevice(IDirect3D9Ex *iface, UINT adapter,
+ D3DDEVTYPE device_type, HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters,
+ IDirect3DDevice9 **device)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ struct d3d9_device *object;
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, device_type %#x, focus_window %p, flags %#x, parameters %p, device %p.\n",
+ iface, adapter, device_type, focus_window, flags, parameters, device);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ hr = device_init(object, d3d9, d3d9->wined3d, adapter, device_type, focus_window, flags,
+#ifdef VBOX_WITH_WDDM
+ (VBOXWINEEX_D3DPRESENT_PARAMETERS *)
+#endif
+ parameters, NULL);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize device, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created device %p.\n", object);
+ *device = (IDirect3DDevice9 *)object;
+
+ return D3D_OK;
+}
+
+static UINT WINAPI d3d9_GetAdapterModeCountEx(IDirect3D9Ex *iface,
+ UINT adapter, const D3DDISPLAYMODEFILTER *filter)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ UINT ret;
+
+ TRACE("iface %p, adapter %u, filter %p.\n", iface, adapter, filter);
+
+ if (filter->Format != D3DFMT_X8R8G8B8 && filter->Format != D3DFMT_R5G6B5)
+ return 0;
+
+ wined3d_mutex_lock();
+ ret = wined3d_get_adapter_mode_count(d3d9->wined3d, adapter,
+ wined3dformat_from_d3dformat(filter->Format), filter->ScanLineOrdering);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static HRESULT WINAPI d3d9_EnumAdapterModesEx(IDirect3D9Ex *iface,
+ UINT adapter, const D3DDISPLAYMODEFILTER *filter, UINT mode_idx, D3DDISPLAYMODEEX *mode)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ struct wined3d_display_mode wined3d_mode;
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, filter %p, mode_idx %u, mode %p.\n",
+ iface, adapter, filter, mode_idx, mode);
+
+ if (filter->Format != D3DFMT_X8R8G8B8 && filter->Format != D3DFMT_R5G6B5)
+ return D3DERR_INVALIDCALL;
+
+ wined3d_mutex_lock();
+ hr = wined3d_enum_adapter_modes(d3d9->wined3d, adapter, wined3dformat_from_d3dformat(filter->Format),
+ filter->ScanLineOrdering, mode_idx, &wined3d_mode);
+ wined3d_mutex_unlock();
+
+ if (SUCCEEDED(hr))
+ {
+ mode->Width = wined3d_mode.width;
+ mode->Height = wined3d_mode.height;
+ mode->RefreshRate = wined3d_mode.refresh_rate;
+ mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id);
+ mode->ScanLineOrdering = wined3d_mode.scanline_ordering;
+ }
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_GetAdapterDisplayModeEx(IDirect3D9Ex *iface,
+ UINT adapter, D3DDISPLAYMODEEX *mode, D3DDISPLAYROTATION *rotation)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ struct wined3d_display_mode wined3d_mode;
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, mode %p, rotation %p.\n",
+ iface, adapter, mode, rotation);
+
+ if (mode->Size != sizeof(*mode))
+ return D3DERR_INVALIDCALL;
+
+ wined3d_mutex_lock();
+ hr = wined3d_get_adapter_display_mode(d3d9->wined3d, adapter, &wined3d_mode,
+ (enum wined3d_display_rotation *)rotation);
+ wined3d_mutex_unlock();
+
+ if (SUCCEEDED(hr))
+ {
+ mode->Width = wined3d_mode.width;
+ mode->Height = wined3d_mode.height;
+ mode->RefreshRate = wined3d_mode.refresh_rate;
+ mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id);
+ mode->ScanLineOrdering = wined3d_mode.scanline_ordering;
+ }
+
+ return hr;
+}
+
+static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_CreateDeviceEx(IDirect3D9Ex *iface,
+ UINT adapter, D3DDEVTYPE device_type, HWND focus_window, DWORD flags,
+ D3DPRESENT_PARAMETERS *parameters, D3DDISPLAYMODEEX *mode, IDirect3DDevice9Ex **device)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ struct d3d9_device *object;
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, device_type %#x, focus_window %p, flags %#x, parameters %p, mode %p, device %p.\n",
+ iface, adapter, device_type, focus_window, flags, parameters, mode, device);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ hr = device_init(object, d3d9, d3d9->wined3d, adapter, device_type, focus_window, flags,
+#ifdef VBOX_WITH_WDDM
+ (VBOXWINEEX_D3DPRESENT_PARAMETERS *)
+#endif
+ parameters, mode);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize device, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created device %p.\n", object);
+ *device = &object->IDirect3DDevice9Ex_iface;
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_GetAdapterLUID(IDirect3D9Ex *iface, UINT adapter, LUID *luid)
+{
+ struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
+ struct wined3d_adapter_identifier adapter_id;
+ HRESULT hr;
+
+ TRACE("iface %p, adapter %u, luid %p.\n", iface, adapter, luid);
+
+ adapter_id.driver_size = 0;
+ adapter_id.description_size = 0;
+ adapter_id.device_name_size = 0;
+
+ wined3d_mutex_lock();
+ hr = wined3d_get_adapter_identifier(d3d9->wined3d, adapter, 0, &adapter_id);
+ wined3d_mutex_unlock();
+
+ memcpy(luid, &adapter_id.adapter_luid, sizeof(*luid));
+
+ return hr;
+}
+
+static const struct IDirect3D9ExVtbl d3d9_vtbl =
+{
+ /* IUnknown */
+ d3d9_QueryInterface,
+ d3d9_AddRef,
+ d3d9_Release,
+ /* IDirect3D9 */
+ d3d9_RegisterSoftwareDevice,
+ d3d9_GetAdapterCount,
+ d3d9_GetAdapterIdentifier,
+ d3d9_GetAdapterModeCount,
+ d3d9_EnumAdapterModes,
+ d3d9_GetAdapterDisplayMode,
+ d3d9_CheckDeviceType,
+ d3d9_CheckDeviceFormat,
+ d3d9_CheckDeviceMultiSampleType,
+ d3d9_CheckDepthStencilMatch,
+ d3d9_CheckDeviceFormatConversion,
+ d3d9_GetDeviceCaps,
+ d3d9_GetAdapterMonitor,
+ d3d9_CreateDevice,
+ /* IDirect3D9Ex */
+ d3d9_GetAdapterModeCountEx,
+ d3d9_EnumAdapterModesEx,
+ d3d9_GetAdapterDisplayModeEx,
+ d3d9_CreateDeviceEx,
+ d3d9_GetAdapterLUID,
+};
+
+BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended)
+{
+ DWORD flags = extended ? 0 : WINED3D_VIDMEM_ACCOUNTING;
+ d3d9->IDirect3D9Ex_iface.lpVtbl = &d3d9_vtbl;
+ d3d9->refcount = 1;
+
+ wined3d_mutex_lock();
+ d3d9->wined3d = wined3d_create(9, flags);
+ wined3d_mutex_unlock();
+ if (!d3d9->wined3d)
+ return FALSE;
+ d3d9->extended = extended;
+
+ return TRUE;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/query.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/query.c
new file mode 100644
index 00000000..4236ca79
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/query.c
@@ -0,0 +1,193 @@
+/*
+ * IDirect3DQuery9 implementation
+ *
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2002-2003 Jason Edmeades
+ * Copyright 2005 Oliver Stieber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "d3d9_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
+static inline struct d3d9_query *impl_from_IDirect3DQuery9(IDirect3DQuery9 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d9_query, IDirect3DQuery9_iface);
+}
+
+static HRESULT WINAPI d3d9_query_QueryInterface(IDirect3DQuery9 *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DQuery9)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DQuery9_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d9_query_AddRef(IDirect3DQuery9 *iface)
+{
+ struct d3d9_query *query = impl_from_IDirect3DQuery9(iface);
+ ULONG refcount = InterlockedIncrement(&query->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, refcount);
+
+ return refcount;
+}
+
+static ULONG WINAPI d3d9_query_Release(IDirect3DQuery9 *iface)
+{
+ struct d3d9_query *query = impl_from_IDirect3DQuery9(iface);
+ ULONG refcount = InterlockedDecrement(&query->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ wined3d_mutex_lock();
+ wined3d_query_decref(query->wined3d_query);
+ wined3d_mutex_unlock();
+
+ IDirect3DDevice9Ex_Release(query->parent_device);
+ HeapFree(GetProcessHeap(), 0, query);
+ }
+ return refcount;
+}
+
+static HRESULT WINAPI d3d9_query_GetDevice(IDirect3DQuery9 *iface, IDirect3DDevice9 **device)
+{
+ struct d3d9_query *query = impl_from_IDirect3DQuery9(iface);
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ *device = (IDirect3DDevice9 *)query->parent_device;
+ IDirect3DDevice9_AddRef(*device);
+
+ TRACE("Returning device %p.\n", *device);
+
+ return D3D_OK;
+}
+
+static D3DQUERYTYPE WINAPI d3d9_query_GetType(IDirect3DQuery9 *iface)
+{
+ struct d3d9_query *query = impl_from_IDirect3DQuery9(iface);
+ D3DQUERYTYPE type;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ type = wined3d_query_get_type(query->wined3d_query);
+ wined3d_mutex_unlock();
+
+ return type;
+}
+
+static DWORD WINAPI d3d9_query_GetDataSize(IDirect3DQuery9 *iface)
+{
+ struct d3d9_query *query = impl_from_IDirect3DQuery9(iface);
+ DWORD ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_query_get_data_size(query->wined3d_query);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static HRESULT WINAPI d3d9_query_Issue(IDirect3DQuery9 *iface, DWORD flags)
+{
+ struct d3d9_query *query = impl_from_IDirect3DQuery9(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, flags %#x.\n", iface, flags);
+
+ wined3d_mutex_lock();
+ hr = wined3d_query_issue(query->wined3d_query, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_query_GetData(IDirect3DQuery9 *iface, void *data, DWORD size, DWORD flags)
+{
+ struct d3d9_query *query = impl_from_IDirect3DQuery9(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, data %p, size %u, flags %#x.\n",
+ iface, data, size, flags);
+
+ wined3d_mutex_lock();
+ hr = wined3d_query_get_data(query->wined3d_query, data, size, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+
+static const struct IDirect3DQuery9Vtbl d3d9_query_vtbl =
+{
+ d3d9_query_QueryInterface,
+ d3d9_query_AddRef,
+ d3d9_query_Release,
+ d3d9_query_GetDevice,
+ d3d9_query_GetType,
+ d3d9_query_GetDataSize,
+ d3d9_query_Issue,
+ d3d9_query_GetData,
+};
+
+HRESULT query_init(struct d3d9_query *query, struct d3d9_device *device, D3DQUERYTYPE type)
+{
+ HRESULT hr;
+
+ query->IDirect3DQuery9_iface.lpVtbl = &d3d9_query_vtbl;
+ query->refcount = 1;
+
+ wined3d_mutex_lock();
+ hr = wined3d_query_create(device->wined3d_device, type, &query->wined3d_query);
+ wined3d_mutex_unlock();
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d query, hr %#x.\n", hr);
+ return hr;
+ }
+
+ query->parent_device = &device->IDirect3DDevice9Ex_iface;
+ IDirect3DDevice9Ex_AddRef(query->parent_device);
+
+ return D3D_OK;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/shader.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/shader.c
new file mode 100644
index 00000000..df7484a9
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/shader.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright 2002-2003 Jason Edmeades
+ * Raphael Junqueira
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "d3d9_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
+static inline struct d3d9_vertexshader *impl_from_IDirect3DVertexShader9(IDirect3DVertexShader9 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d9_vertexshader, IDirect3DVertexShader9_iface);
+}
+
+static HRESULT WINAPI d3d9_vertexshader_QueryInterface(IDirect3DVertexShader9 *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DVertexShader9)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DVertexShader9_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d9_vertexshader_AddRef(IDirect3DVertexShader9 *iface)
+{
+ struct d3d9_vertexshader *shader = impl_from_IDirect3DVertexShader9(iface);
+ ULONG refcount = InterlockedIncrement(&shader->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, refcount);
+
+ if (refcount == 1)
+ {
+ IDirect3DDevice9Ex_AddRef(shader->parent_device);
+ wined3d_mutex_lock();
+ wined3d_shader_incref(shader->wined3d_shader);
+ wined3d_mutex_unlock();
+ }
+
+ return refcount;
+}
+
+static ULONG WINAPI d3d9_vertexshader_Release(IDirect3DVertexShader9 *iface)
+{
+ struct d3d9_vertexshader *shader = impl_from_IDirect3DVertexShader9(iface);
+ ULONG refcount = InterlockedDecrement(&shader->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ IDirect3DDevice9Ex *device = shader->parent_device;
+
+ wined3d_mutex_lock();
+ wined3d_shader_decref(shader->wined3d_shader);
+ wined3d_mutex_unlock();
+
+ /* Release the device last, as it may cause the device to be destroyed. */
+ IDirect3DDevice9Ex_Release(device);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI d3d9_vertexshader_GetDevice(IDirect3DVertexShader9 *iface, IDirect3DDevice9 **device)
+{
+ struct d3d9_vertexshader *shader = impl_from_IDirect3DVertexShader9(iface);
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ *device = (IDirect3DDevice9 *)shader->parent_device;
+ IDirect3DDevice9_AddRef(*device);
+
+ TRACE("Returning device %p.\n", *device);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_vertexshader_GetFunction(IDirect3DVertexShader9 *iface, void *data, UINT *data_size)
+{
+ struct d3d9_vertexshader *shader = impl_from_IDirect3DVertexShader9(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, data %p, data_size %p.\n", iface, data, data_size);
+
+ wined3d_mutex_lock();
+ hr = wined3d_shader_get_byte_code(shader->wined3d_shader, data, data_size);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static const IDirect3DVertexShader9Vtbl d3d9_vertexshader_vtbl =
+{
+ /* IUnknown */
+ d3d9_vertexshader_QueryInterface,
+ d3d9_vertexshader_AddRef,
+ d3d9_vertexshader_Release,
+ /* IDirect3DVertexShader9 */
+ d3d9_vertexshader_GetDevice,
+ d3d9_vertexshader_GetFunction,
+};
+
+static void STDMETHODCALLTYPE d3d9_vertexshader_wined3d_object_destroyed(void *parent)
+{
+ HeapFree(GetProcessHeap(), 0, parent);
+}
+
+static const struct wined3d_parent_ops d3d9_vertexshader_wined3d_parent_ops =
+{
+ d3d9_vertexshader_wined3d_object_destroyed,
+};
+
+HRESULT vertexshader_init(struct d3d9_vertexshader *shader, struct d3d9_device *device, const DWORD *byte_code)
+{
+ HRESULT hr;
+
+ shader->refcount = 1;
+ shader->IDirect3DVertexShader9_iface.lpVtbl = &d3d9_vertexshader_vtbl;
+
+ wined3d_mutex_lock();
+ hr = wined3d_shader_create_vs(device->wined3d_device, byte_code, NULL,
+ shader, &d3d9_vertexshader_wined3d_parent_ops, &shader->wined3d_shader, 3);
+ wined3d_mutex_unlock();
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d vertex shader, hr %#x.\n", hr);
+ return hr;
+ }
+
+ shader->parent_device = &device->IDirect3DDevice9Ex_iface;
+ IDirect3DDevice9Ex_AddRef(shader->parent_device);
+
+ return D3D_OK;
+}
+
+struct d3d9_vertexshader *unsafe_impl_from_IDirect3DVertexShader9(IDirect3DVertexShader9 *iface)
+{
+ if (!iface)
+ return NULL;
+ assert(iface->lpVtbl == &d3d9_vertexshader_vtbl);
+
+ return impl_from_IDirect3DVertexShader9(iface);
+}
+
+static inline struct d3d9_pixelshader *impl_from_IDirect3DPixelShader9(IDirect3DPixelShader9 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d9_pixelshader, IDirect3DPixelShader9_iface);
+}
+
+static HRESULT WINAPI d3d9_pixelshader_QueryInterface(IDirect3DPixelShader9 *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DPixelShader9)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DPixelShader9_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d9_pixelshader_AddRef(IDirect3DPixelShader9 *iface)
+{
+ struct d3d9_pixelshader *shader = impl_from_IDirect3DPixelShader9(iface);
+ ULONG refcount = InterlockedIncrement(&shader->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, refcount);
+
+ if (refcount == 1)
+ {
+ IDirect3DDevice9Ex_AddRef(shader->parent_device);
+ wined3d_mutex_lock();
+ wined3d_shader_incref(shader->wined3d_shader);
+ wined3d_mutex_unlock();
+ }
+
+ return refcount;
+}
+
+static ULONG WINAPI d3d9_pixelshader_Release(IDirect3DPixelShader9 *iface)
+{
+ struct d3d9_pixelshader *shader = impl_from_IDirect3DPixelShader9(iface);
+ ULONG refcount = InterlockedDecrement(&shader->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ IDirect3DDevice9Ex *device = shader->parent_device;
+
+ wined3d_mutex_lock();
+ wined3d_shader_decref(shader->wined3d_shader);
+ wined3d_mutex_unlock();
+
+ /* Release the device last, as it may cause the device to be destroyed. */
+ IDirect3DDevice9Ex_Release(device);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI d3d9_pixelshader_GetDevice(IDirect3DPixelShader9 *iface, IDirect3DDevice9 **device)
+{
+ struct d3d9_pixelshader *shader = impl_from_IDirect3DPixelShader9(iface);
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ *device = (IDirect3DDevice9 *)shader->parent_device;
+ IDirect3DDevice9_AddRef(*device);
+
+ TRACE("Returning device %p.\n", *device);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_pixelshader_GetFunction(IDirect3DPixelShader9 *iface, void *data, UINT *data_size)
+{
+ struct d3d9_pixelshader *shader = impl_from_IDirect3DPixelShader9(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, data %p, data_size %p.\n", iface, data, data_size);
+
+ wined3d_mutex_lock();
+ hr = wined3d_shader_get_byte_code(shader->wined3d_shader, data, data_size);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static const IDirect3DPixelShader9Vtbl d3d9_pixelshader_vtbl =
+{
+ /* IUnknown */
+ d3d9_pixelshader_QueryInterface,
+ d3d9_pixelshader_AddRef,
+ d3d9_pixelshader_Release,
+ /* IDirect3DPixelShader9 */
+ d3d9_pixelshader_GetDevice,
+ d3d9_pixelshader_GetFunction,
+};
+
+static void STDMETHODCALLTYPE d3d9_pixelshader_wined3d_object_destroyed(void *parent)
+{
+ HeapFree(GetProcessHeap(), 0, parent);
+}
+
+static const struct wined3d_parent_ops d3d9_pixelshader_wined3d_parent_ops =
+{
+ d3d9_pixelshader_wined3d_object_destroyed,
+};
+
+HRESULT pixelshader_init(struct d3d9_pixelshader *shader, struct d3d9_device *device, const DWORD *byte_code)
+{
+ HRESULT hr;
+
+ shader->refcount = 1;
+ shader->IDirect3DPixelShader9_iface.lpVtbl = &d3d9_pixelshader_vtbl;
+
+ wined3d_mutex_lock();
+ hr = wined3d_shader_create_ps(device->wined3d_device, byte_code, NULL, shader,
+ &d3d9_pixelshader_wined3d_parent_ops, &shader->wined3d_shader, 3);
+ wined3d_mutex_unlock();
+ if (FAILED(hr))
+ {
+ WARN("Failed to created wined3d pixel shader, hr %#x.\n", hr);
+ return hr;
+ }
+
+ shader->parent_device = &device->IDirect3DDevice9Ex_iface;
+ IDirect3DDevice9Ex_AddRef(shader->parent_device);
+
+ return D3D_OK;
+}
+
+struct d3d9_pixelshader *unsafe_impl_from_IDirect3DPixelShader9(IDirect3DPixelShader9 *iface)
+{
+ if (!iface)
+ return NULL;
+ assert(iface->lpVtbl == &d3d9_pixelshader_vtbl);
+
+ return impl_from_IDirect3DPixelShader9(iface);
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/stateblock.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/stateblock.c
new file mode 100644
index 00000000..1625aaae
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/stateblock.c
@@ -0,0 +1,172 @@
+/*
+ * IDirect3DStateBlock9 implementation
+ *
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2002-2003 Jason Edmeades
+ * Copyright 2005 Oliver Stieber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "d3d9_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
+static inline struct d3d9_stateblock *impl_from_IDirect3DStateBlock9(IDirect3DStateBlock9 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d9_stateblock, IDirect3DStateBlock9_iface);
+}
+
+static HRESULT WINAPI d3d9_stateblock_QueryInterface(IDirect3DStateBlock9 *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DStateBlock9)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DStateBlock9_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d9_stateblock_AddRef(IDirect3DStateBlock9 *iface)
+{
+ struct d3d9_stateblock *stateblock = impl_from_IDirect3DStateBlock9(iface);
+ ULONG refcount = InterlockedIncrement(&stateblock->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, refcount);
+
+ return refcount;
+}
+
+static ULONG WINAPI d3d9_stateblock_Release(IDirect3DStateBlock9 *iface)
+{
+ struct d3d9_stateblock *stateblock = impl_from_IDirect3DStateBlock9(iface);
+ ULONG refcount = InterlockedDecrement(&stateblock->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ wined3d_mutex_lock();
+ wined3d_stateblock_decref(stateblock->wined3d_stateblock);
+ wined3d_mutex_unlock();
+
+ IDirect3DDevice9Ex_Release(stateblock->parent_device);
+ HeapFree(GetProcessHeap(), 0, stateblock);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI d3d9_stateblock_GetDevice(IDirect3DStateBlock9 *iface, IDirect3DDevice9 **device)
+{
+ struct d3d9_stateblock *stateblock = impl_from_IDirect3DStateBlock9(iface);
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ *device = (IDirect3DDevice9 *)stateblock->parent_device;
+ IDirect3DDevice9_AddRef(*device);
+
+ TRACE("Returning device %p.\n", *device);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_stateblock_Capture(IDirect3DStateBlock9 *iface)
+{
+ struct d3d9_stateblock *stateblock = impl_from_IDirect3DStateBlock9(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_stateblock_capture(stateblock->wined3d_stateblock);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_stateblock_Apply(IDirect3DStateBlock9 *iface)
+{
+ struct d3d9_stateblock *stateblock = impl_from_IDirect3DStateBlock9(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_stateblock_apply(stateblock->wined3d_stateblock);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+
+static const struct IDirect3DStateBlock9Vtbl d3d9_stateblock_vtbl =
+{
+ /* IUnknown */
+ d3d9_stateblock_QueryInterface,
+ d3d9_stateblock_AddRef,
+ d3d9_stateblock_Release,
+ /* IDirect3DStateBlock9 */
+ d3d9_stateblock_GetDevice,
+ d3d9_stateblock_Capture,
+ d3d9_stateblock_Apply,
+};
+
+HRESULT stateblock_init(struct d3d9_stateblock *stateblock, struct d3d9_device *device,
+ D3DSTATEBLOCKTYPE type, struct wined3d_stateblock *wined3d_stateblock)
+{
+ HRESULT hr;
+
+ stateblock->IDirect3DStateBlock9_iface.lpVtbl = &d3d9_stateblock_vtbl;
+ stateblock->refcount = 1;
+
+ if (wined3d_stateblock)
+ {
+ stateblock->wined3d_stateblock = wined3d_stateblock;
+ }
+ else
+ {
+ wined3d_mutex_lock();
+ hr = wined3d_stateblock_create(device->wined3d_device,
+ (enum wined3d_stateblock_type)type, &stateblock->wined3d_stateblock);
+ wined3d_mutex_unlock();
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d stateblock, hr %#x.\n", hr);
+ return hr;
+ }
+ }
+
+ stateblock->parent_device = &device->IDirect3DDevice9Ex_iface;
+ IDirect3DDevice9Ex_AddRef(stateblock->parent_device);
+
+ return D3D_OK;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/surface.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/surface.c
new file mode 100644
index 00000000..40ba7897
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/surface.c
@@ -0,0 +1,490 @@
+/*
+ * IDirect3DSurface9 implementation
+ *
+ * Copyright 2002-2005 Jason Edmeades
+ * Raphael Junqueira
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "d3d9_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
+static inline struct d3d9_surface *impl_from_IDirect3DSurface9(IDirect3DSurface9 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d9_surface, IDirect3DSurface9_iface);
+}
+
+static HRESULT WINAPI d3d9_surface_QueryInterface(IDirect3DSurface9 *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DSurface9)
+ || IsEqualGUID(riid, &IID_IDirect3DResource9)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DSurface9_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d9_surface_AddRef(IDirect3DSurface9 *iface)
+{
+ struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+ ULONG refcount;
+
+ TRACE("iface %p.\n", iface);
+
+ if (surface->forwardReference)
+ {
+ TRACE("Forwarding to %p.\n", surface->forwardReference);
+ return IUnknown_AddRef(surface->forwardReference);
+ }
+
+ refcount = InterlockedIncrement(&surface->refcount);
+ TRACE("%p increasing refcount to %u.\n", iface, refcount);
+
+ if (refcount == 1)
+ {
+ if (surface->parent_device)
+ IDirect3DDevice9Ex_AddRef(surface->parent_device);
+ wined3d_mutex_lock();
+ wined3d_surface_incref(surface->wined3d_surface);
+ wined3d_mutex_unlock();
+ }
+
+ return refcount;
+}
+
+static ULONG WINAPI d3d9_surface_Release(IDirect3DSurface9 *iface)
+{
+ struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+ ULONG refcount;
+
+ TRACE("iface %p.\n", iface);
+
+ if (surface->forwardReference)
+ {
+ TRACE("Forwarding to %p.\n", surface->forwardReference);
+ return IUnknown_Release(surface->forwardReference);
+ }
+
+ refcount = InterlockedDecrement(&surface->refcount);
+ TRACE("%p decreasing refcount to %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ IDirect3DDevice9Ex *parent_device = surface->parent_device;
+
+ wined3d_mutex_lock();
+ wined3d_surface_decref(surface->wined3d_surface);
+ wined3d_mutex_unlock();
+
+ /* Release the device last, as it may cause the device to be destroyed. */
+ if (parent_device)
+ IDirect3DDevice9Ex_Release(parent_device);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI d3d9_surface_GetDevice(IDirect3DSurface9 *iface, IDirect3DDevice9 **device)
+{
+ struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ if (surface->forwardReference)
+ {
+ IDirect3DResource9 *resource;
+ HRESULT hr;
+
+ hr = IUnknown_QueryInterface(surface->forwardReference, &IID_IDirect3DResource9, (void **)&resource);
+ if (SUCCEEDED(hr))
+ {
+ hr = IDirect3DResource9_GetDevice(resource, device);
+ IDirect3DResource9_Release(resource);
+
+ TRACE("Returning device %p.\n", *device);
+ }
+
+ return hr;
+ }
+
+ *device = (IDirect3DDevice9 *)surface->parent_device;
+ IDirect3DDevice9_AddRef(*device);
+
+ TRACE("Returning device %p.\n", *device);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_surface_SetPrivateData(IDirect3DSurface9 *iface, REFGUID guid,
+ const void *data, DWORD data_size, DWORD flags)
+{
+ struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
+ iface, debugstr_guid(guid), data, data_size, flags);
+
+ wined3d_mutex_lock();
+ resource = wined3d_surface_get_resource(surface->wined3d_surface);
+ hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_surface_GetPrivateData(IDirect3DSurface9 *iface, REFGUID guid,
+ void *data, DWORD *data_size)
+{
+ struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %p.\n",
+ iface, debugstr_guid(guid), data, data_size);
+
+ wined3d_mutex_lock();
+ resource = wined3d_surface_get_resource(surface->wined3d_surface);
+ hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_surface_FreePrivateData(IDirect3DSurface9 *iface, REFGUID guid)
+{
+ struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
+
+ wined3d_mutex_lock();
+ resource = wined3d_surface_get_resource(surface->wined3d_surface);
+ hr = wined3d_resource_free_private_data(resource, guid);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static DWORD WINAPI d3d9_surface_SetPriority(IDirect3DSurface9 *iface, DWORD priority)
+{
+ struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+ DWORD ret;
+
+ TRACE("iface %p, priority %u.\n", iface, priority);
+
+ wined3d_mutex_lock();
+ ret = wined3d_surface_set_priority(surface->wined3d_surface, priority);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static DWORD WINAPI d3d9_surface_GetPriority(IDirect3DSurface9 *iface)
+{
+ struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+ DWORD ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_surface_get_priority(surface->wined3d_surface);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static void WINAPI d3d9_surface_PreLoad(IDirect3DSurface9 *iface)
+{
+ struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_surface_preload(surface->wined3d_surface);
+ wined3d_mutex_unlock();
+}
+
+static D3DRESOURCETYPE WINAPI d3d9_surface_GetType(IDirect3DSurface9 *iface)
+{
+ TRACE("iface %p.\n", iface);
+
+ return D3DRTYPE_SURFACE;
+}
+
+static HRESULT WINAPI d3d9_surface_GetContainer(IDirect3DSurface9 *iface, REFIID riid, void **container)
+{
+ struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, riid %s, container %p.\n", iface, debugstr_guid(riid), container);
+
+ if (!surface->container)
+ return E_NOINTERFACE;
+
+ hr = IUnknown_QueryInterface(surface->container, riid, container);
+
+ TRACE("Returning %p.\n", *container);
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_surface_GetDesc(IDirect3DSurface9 *iface, D3DSURFACE_DESC *desc)
+{
+ struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+ struct wined3d_resource_desc wined3d_desc;
+ struct wined3d_resource *wined3d_resource;
+
+ TRACE("iface %p, desc %p.\n", iface, desc);
+
+ wined3d_mutex_lock();
+ wined3d_resource = wined3d_surface_get_resource(surface->wined3d_surface);
+ wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
+ wined3d_mutex_unlock();
+
+ desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
+ desc->Type = wined3d_desc.resource_type;
+ desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
+ desc->Pool = wined3d_desc.pool;
+ desc->MultiSampleType = wined3d_desc.multisample_type;
+ desc->MultiSampleQuality = wined3d_desc.multisample_quality;
+ desc->Width = wined3d_desc.width;
+ desc->Height = wined3d_desc.height;
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_surface_LockRect(IDirect3DSurface9 *iface,
+ D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
+{
+ struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+ struct wined3d_map_desc map_desc;
+ HRESULT hr;
+
+ TRACE("iface %p, locked_rect %p, rect %s, flags %#x.\n",
+ iface, locked_rect, wine_dbgstr_rect(rect), flags);
+
+ wined3d_mutex_lock();
+ hr = wined3d_surface_map(surface->wined3d_surface, &map_desc, rect, flags);
+ wined3d_mutex_unlock();
+
+ locked_rect->Pitch = map_desc.row_pitch;
+ locked_rect->pBits = map_desc.data;
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_surface_UnlockRect(IDirect3DSurface9 *iface)
+{
+ struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+ HRESULT hr;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ hr = wined3d_surface_unmap(surface->wined3d_surface);
+ wined3d_mutex_unlock();
+
+ switch(hr)
+ {
+ case WINEDDERR_NOTLOCKED: return D3DERR_INVALIDCALL;
+ default: return hr;
+ }
+}
+
+static HRESULT WINAPI d3d9_surface_GetDC(IDirect3DSurface9 *iface, HDC *dc)
+{
+ struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, dc %p.\n", iface, dc);
+
+ if (!surface->getdc_supported)
+ {
+ WARN("Surface does not support GetDC, returning D3DERR_INVALIDCALL\n");
+ /* Don't touch the DC */
+ return D3DERR_INVALIDCALL;
+ }
+
+ wined3d_mutex_lock();
+ hr = wined3d_surface_getdc(surface->wined3d_surface, dc);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_surface_ReleaseDC(IDirect3DSurface9 *iface, HDC dc)
+{
+ struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, dc %p.\n", iface, dc);
+
+ wined3d_mutex_lock();
+ hr = wined3d_surface_releasedc(surface->wined3d_surface, dc);
+ wined3d_mutex_unlock();
+
+ switch (hr)
+ {
+ case WINEDDERR_NODC: return D3DERR_INVALIDCALL;
+ default: return hr;
+ }
+}
+
+static const struct IDirect3DSurface9Vtbl d3d9_surface_vtbl =
+{
+ /* IUnknown */
+ d3d9_surface_QueryInterface,
+ d3d9_surface_AddRef,
+ d3d9_surface_Release,
+ /* IDirect3DResource9 */
+ d3d9_surface_GetDevice,
+ d3d9_surface_SetPrivateData,
+ d3d9_surface_GetPrivateData,
+ d3d9_surface_FreePrivateData,
+ d3d9_surface_SetPriority,
+ d3d9_surface_GetPriority,
+ d3d9_surface_PreLoad,
+ d3d9_surface_GetType,
+ /* IDirect3DSurface9 */
+ d3d9_surface_GetContainer,
+ d3d9_surface_GetDesc,
+ d3d9_surface_LockRect,
+ d3d9_surface_UnlockRect,
+ d3d9_surface_GetDC,
+ d3d9_surface_ReleaseDC,
+};
+
+static void STDMETHODCALLTYPE surface_wined3d_object_destroyed(void *parent)
+{
+ HeapFree(GetProcessHeap(), 0, parent);
+}
+
+static const struct wined3d_parent_ops d3d9_surface_wined3d_parent_ops =
+{
+ surface_wined3d_object_destroyed,
+};
+
+HRESULT surface_init(struct d3d9_surface *surface, struct d3d9_device *device, UINT width, UINT height,
+ D3DFORMAT format, DWORD flags, DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type,
+ DWORD multisample_quality
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void *pvClientMem
+#endif
+ )
+{
+ HRESULT hr;
+
+ surface->IDirect3DSurface9_iface.lpVtbl = &d3d9_surface_vtbl;
+ surface->refcount = 1;
+
+ switch (format)
+ {
+ case D3DFMT_A8R8G8B8:
+ case D3DFMT_X8R8G8B8:
+ case D3DFMT_R5G6B5:
+ case D3DFMT_X1R5G5B5:
+ case D3DFMT_A1R5G5B5:
+ case D3DFMT_R8G8B8:
+ surface->getdc_supported = TRUE;
+ break;
+
+ default:
+ surface->getdc_supported = FALSE;
+ break;
+ }
+
+ /* FIXME: Check MAX bounds of MultisampleQuality. */
+ if (multisample_quality > 0)
+ {
+ FIXME("Multisample quality set to %u, substituting 0.\n", multisample_quality);
+ multisample_quality = 0;
+ }
+
+ wined3d_mutex_lock();
+ hr = wined3d_surface_create(device->wined3d_device, width, height, wined3dformat_from_d3dformat(format),
+ usage & WINED3DUSAGE_MASK, (enum wined3d_pool)pool, multisample_type, multisample_quality,
+ flags, surface, &d3d9_surface_wined3d_parent_ops, &surface->wined3d_surface
+#ifdef VBOX_WITH_WDDM
+ , shared_handle
+ , pvClientMem
+#endif
+ );
+ wined3d_mutex_unlock();
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d surface, hr %#x.\n", hr);
+ return hr;
+ }
+
+ surface->parent_device = &device->IDirect3DDevice9Ex_iface;
+ IDirect3DDevice9Ex_AddRef(surface->parent_device);
+
+ return D3D_OK;
+}
+
+struct d3d9_surface *unsafe_impl_from_IDirect3DSurface9(IDirect3DSurface9 *iface)
+{
+ if (!iface)
+ return NULL;
+ assert(iface->lpVtbl == &d3d9_surface_vtbl);
+
+ return impl_from_IDirect3DSurface9(iface);
+}
+
+#ifdef VBOX_WITH_WDDM
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DSurf9GetHostId(IDirect3DSurface9 *iface, uint32_t *pu32Id)
+{
+ struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+ HRESULT hr;
+ wined3d_mutex_lock();
+ hr = wined3d_surface_get_host_id(surface->wined3d_surface, pu32Id);
+ wined3d_mutex_unlock();
+ return hr;
+}
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DSurf9SyncToHost(IDirect3DSurface9 *iface)
+{
+ struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface);
+ HRESULT hr;
+ wined3d_mutex_lock();
+ hr = wined3d_surface_sync_to_host(surface->wined3d_surface);
+ wined3d_mutex_unlock();
+ return hr;
+}
+#endif
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/swapchain.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/swapchain.c
new file mode 100644
index 00000000..9690df07
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/swapchain.c
@@ -0,0 +1,327 @@
+/*
+ * IDirect3DSwapChain9 implementation
+ *
+ * Copyright 2002-2003 Jason Edmeades
+ * Raphael Junqueira
+ * Copyright 2005 Oliver Stieber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "d3d9_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
+static inline struct d3d9_swapchain *impl_from_IDirect3DSwapChain9(IDirect3DSwapChain9 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d9_swapchain, IDirect3DSwapChain9_iface);
+}
+
+static HRESULT WINAPI d3d9_swapchain_QueryInterface(IDirect3DSwapChain9 *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DSwapChain9)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DSwapChain9_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d9_swapchain_AddRef(IDirect3DSwapChain9 *iface)
+{
+ struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+ ULONG refcount = InterlockedIncrement(&swapchain->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, refcount);
+
+ if (refcount == 1)
+ {
+ if (swapchain->parent_device)
+ IDirect3DDevice9Ex_AddRef(swapchain->parent_device);
+
+ wined3d_mutex_lock();
+ wined3d_swapchain_incref(swapchain->wined3d_swapchain);
+ wined3d_mutex_unlock();
+ }
+
+ return refcount;
+}
+
+static ULONG WINAPI d3d9_swapchain_Release(IDirect3DSwapChain9 *iface)
+{
+ struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+ ULONG refcount = InterlockedDecrement(&swapchain->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ IDirect3DDevice9Ex *parent_device = swapchain->parent_device;
+
+ wined3d_mutex_lock();
+ wined3d_swapchain_decref(swapchain->wined3d_swapchain);
+ wined3d_mutex_unlock();
+
+ /* Release the device last, as it may cause the device to be destroyed. */
+ if (parent_device)
+ IDirect3DDevice9Ex_Release(parent_device);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_swapchain_Present(IDirect3DSwapChain9 *iface,
+ const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
+ const RGNDATA *dirty_region, DWORD flags)
+{
+ struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p, flags %#x.\n",
+ iface, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect),
+ dst_window_override, dirty_region, flags);
+
+ wined3d_mutex_lock();
+ hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, src_rect,
+ dst_rect, dst_window_override, dirty_region, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_swapchain_GetFrontBufferData(IDirect3DSwapChain9 *iface, IDirect3DSurface9 *surface)
+{
+ struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+ struct d3d9_surface *dst = unsafe_impl_from_IDirect3DSurface9(surface);
+ HRESULT hr;
+
+ TRACE("iface %p, surface %p.\n", iface, surface);
+
+ wined3d_mutex_lock();
+ hr = wined3d_swapchain_get_front_buffer_data(swapchain->wined3d_swapchain, dst->wined3d_surface);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_swapchain_GetBackBuffer(IDirect3DSwapChain9 *iface,
+ UINT backbuffer_idx, D3DBACKBUFFER_TYPE backbuffer_type, IDirect3DSurface9 **backbuffer)
+{
+ struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+ struct wined3d_surface *wined3d_surface = NULL;
+ struct d3d9_surface *surface_impl;
+ HRESULT hr = D3D_OK;
+
+ TRACE("iface %p, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n",
+ iface, backbuffer_idx, backbuffer_type, backbuffer);
+
+ wined3d_mutex_lock();
+ if ((wined3d_surface = wined3d_swapchain_get_back_buffer(swapchain->wined3d_swapchain,
+ backbuffer_idx, (enum wined3d_backbuffer_type)backbuffer_type)))
+ {
+ surface_impl = wined3d_surface_get_parent(wined3d_surface);
+ *backbuffer = &surface_impl->IDirect3DSurface9_iface;
+ IDirect3DSurface9_AddRef(*backbuffer);
+ }
+ else
+ {
+ hr = D3DERR_INVALIDCALL;
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_swapchain_GetRasterStatus(IDirect3DSwapChain9 *iface, D3DRASTER_STATUS *raster_status)
+{
+ struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, raster_status %p.\n", iface, raster_status);
+
+ wined3d_mutex_lock();
+ hr = wined3d_swapchain_get_raster_status(swapchain->wined3d_swapchain,
+ (struct wined3d_raster_status *)raster_status);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_swapchain_GetDisplayMode(IDirect3DSwapChain9 *iface, D3DDISPLAYMODE *mode)
+{
+ struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+ struct wined3d_display_mode wined3d_mode;
+ HRESULT hr;
+
+ TRACE("iface %p, mode %p.\n", iface, mode);
+
+ wined3d_mutex_lock();
+ hr = wined3d_swapchain_get_display_mode(swapchain->wined3d_swapchain, &wined3d_mode, NULL);
+ wined3d_mutex_unlock();
+
+ if (SUCCEEDED(hr))
+ {
+ mode->Width = wined3d_mode.width;
+ mode->Height = wined3d_mode.height;
+ mode->RefreshRate = wined3d_mode.refresh_rate;
+ mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id);
+ }
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_swapchain_GetDevice(IDirect3DSwapChain9 *iface, IDirect3DDevice9 **device)
+{
+ struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ *device = (IDirect3DDevice9 *)swapchain->parent_device;
+ IDirect3DDevice9_AddRef(*device);
+
+ TRACE("Returning device %p.\n", *device);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_swapchain_GetPresentParameters(IDirect3DSwapChain9 *iface,
+ D3DPRESENT_PARAMETERS *parameters)
+{
+ struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+ struct wined3d_swapchain_desc desc;
+
+ TRACE("iface %p, parameters %p.\n", iface, parameters);
+
+ wined3d_mutex_lock();
+ wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &desc);
+ wined3d_mutex_unlock();
+ present_parameters_from_wined3d_swapchain_desc(parameters, &desc);
+
+ return D3D_OK;
+}
+
+
+static const struct IDirect3DSwapChain9Vtbl d3d9_swapchain_vtbl =
+{
+ d3d9_swapchain_QueryInterface,
+ d3d9_swapchain_AddRef,
+ d3d9_swapchain_Release,
+ d3d9_swapchain_Present,
+ d3d9_swapchain_GetFrontBufferData,
+ d3d9_swapchain_GetBackBuffer,
+ d3d9_swapchain_GetRasterStatus,
+ d3d9_swapchain_GetDisplayMode,
+ d3d9_swapchain_GetDevice,
+ d3d9_swapchain_GetPresentParameters,
+};
+
+static void STDMETHODCALLTYPE d3d9_swapchain_wined3d_object_released(void *parent)
+{
+ HeapFree(GetProcessHeap(), 0, parent);
+}
+
+static const struct wined3d_parent_ops d3d9_swapchain_wined3d_parent_ops =
+{
+ d3d9_swapchain_wined3d_object_released,
+};
+
+static HRESULT swapchain_init(struct d3d9_swapchain *swapchain, struct d3d9_device *device,
+ struct wined3d_swapchain_desc *desc)
+{
+ HRESULT hr;
+
+ swapchain->refcount = 1;
+ swapchain->IDirect3DSwapChain9_iface.lpVtbl = &d3d9_swapchain_vtbl;
+
+ wined3d_mutex_lock();
+ hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain,
+ &d3d9_swapchain_wined3d_parent_ops, &swapchain->wined3d_swapchain);
+ wined3d_mutex_unlock();
+
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d swapchain, hr %#x.\n", hr);
+ return hr;
+ }
+
+ swapchain->parent_device = &device->IDirect3DDevice9Ex_iface;
+ IDirect3DDevice9Ex_AddRef(swapchain->parent_device);
+
+ return D3D_OK;
+}
+
+HRESULT d3d9_swapchain_create(struct d3d9_device *device, struct wined3d_swapchain_desc *desc,
+ struct d3d9_swapchain **swapchain)
+{
+ struct d3d9_swapchain *object;
+ HRESULT hr;
+
+ if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+ return E_OUTOFMEMORY;
+
+ if (FAILED(hr = swapchain_init(object, device, desc)))
+ {
+ WARN("Failed to initialize swapchain, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created swapchain %p.\n", object);
+ *swapchain = object;
+
+ return D3D_OK;
+}
+
+#ifdef VBOX_WITH_WDDM
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DSwapchain9Present(IDirect3DSwapChain9 *iface,
+ IDirect3DSurface9 *surf) /* use the given surface as a frontbuffer content source */
+{
+ struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+ struct d3d9_surface *rt = unsafe_impl_from_IDirect3DSurface9(surf);
+ HRESULT hr;
+ wined3d_mutex_lock();
+ hr = wined3d_swapchain_present_rt(swapchain->wined3d_swapchain, rt->wined3d_surface);
+ wined3d_mutex_unlock();
+ return hr;
+}
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DSwapchain9GetHostWinID(IDirect3DSwapChain9 *iface, int32_t *pi32Id)
+{
+ struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9(iface);
+ HRESULT hr;
+ wined3d_mutex_lock();
+ hr = wined3d_swapchain_get_host_win_id(swapchain->wined3d_swapchain, pi32Id);
+ wined3d_mutex_unlock();
+ return hr;
+}
+#endif
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/texture.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/texture.c
new file mode 100644
index 00000000..160fbca4
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/texture.c
@@ -0,0 +1,1462 @@
+/*
+ * Copyright 2002-2005 Jason Edmeades
+ * Copyright 2002-2005 Raphael Junqueira
+ * Copyright 2005 Oliver Stieber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "d3d9_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
+static inline struct d3d9_texture *impl_from_IDirect3DTexture9(IDirect3DTexture9 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
+}
+
+static inline struct d3d9_texture *impl_from_IDirect3DCubeTexture9(IDirect3DCubeTexture9 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
+}
+
+static inline struct d3d9_texture *impl_from_IDirect3DVolumeTexture9(IDirect3DVolumeTexture9 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
+}
+
+static HRESULT WINAPI d3d9_texture_2d_QueryInterface(IDirect3DTexture9 *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DTexture9)
+ || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
+ || IsEqualGUID(riid, &IID_IDirect3DResource9)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DTexture9_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d9_texture_2d_AddRef(IDirect3DTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+ ULONG ref = InterlockedIncrement(&texture->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, ref);
+
+ if (ref == 1)
+ {
+ IDirect3DDevice9Ex_AddRef(texture->parent_device);
+ wined3d_mutex_lock();
+ wined3d_texture_incref(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+ }
+
+ return ref;
+}
+
+static ULONG WINAPI d3d9_texture_2d_Release(IDirect3DTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+ ULONG ref = InterlockedDecrement(&texture->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, ref);
+
+ if (!ref)
+ {
+ IDirect3DDevice9Ex *parent_device = texture->parent_device;
+
+ wined3d_mutex_lock();
+ wined3d_texture_decref(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ /* Release the device last, as it may cause the device to be destroyed. */
+ IDirect3DDevice9Ex_Release(parent_device);
+ }
+ return ref;
+}
+
+static HRESULT WINAPI d3d9_texture_2d_GetDevice(IDirect3DTexture9 *iface, IDirect3DDevice9 **device)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ *device = (IDirect3DDevice9 *)texture->parent_device;
+ IDirect3DDevice9_AddRef(*device);
+
+ TRACE("Returning device %p.\n", *device);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_texture_2d_SetPrivateData(IDirect3DTexture9 *iface,
+ REFGUID guid, const void *data, DWORD data_size, DWORD flags)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
+ iface, debugstr_guid(guid), data, data_size, flags);
+
+ wined3d_mutex_lock();
+ resource = wined3d_texture_get_resource(texture->wined3d_texture);
+ hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_texture_2d_GetPrivateData(IDirect3DTexture9 *iface,
+ REFGUID guid, void *data, DWORD *data_size)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %p.\n",
+ iface, debugstr_guid(guid), data, data_size);
+
+ wined3d_mutex_lock();
+ resource = wined3d_texture_get_resource(texture->wined3d_texture);
+ hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_texture_2d_FreePrivateData(IDirect3DTexture9 *iface, REFGUID guid)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
+
+ wined3d_mutex_lock();
+ resource = wined3d_texture_get_resource(texture->wined3d_texture);
+ hr = wined3d_resource_free_private_data(resource, guid);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static DWORD WINAPI d3d9_texture_2d_SetPriority(IDirect3DTexture9 *iface, DWORD priority)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+ DWORD ret;
+
+ TRACE("iface %p, priority %u.\n", iface, priority);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_set_priority(texture->wined3d_texture, priority);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static DWORD WINAPI d3d9_texture_2d_GetPriority(IDirect3DTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+ DWORD ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_get_priority(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static void WINAPI d3d9_texture_2d_PreLoad(IDirect3DTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_texture_preload(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+}
+
+static D3DRESOURCETYPE WINAPI d3d9_texture_2d_GetType(IDirect3DTexture9 *iface)
+{
+ TRACE("iface %p.\n", iface);
+
+ return D3DRTYPE_TEXTURE;
+}
+
+static DWORD WINAPI d3d9_texture_2d_SetLOD(IDirect3DTexture9 *iface, DWORD lod)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+ DWORD ret;
+
+ TRACE("iface %p, lod %u.\n", iface, lod);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static DWORD WINAPI d3d9_texture_2d_GetLOD(IDirect3DTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+ DWORD ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_get_lod(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static DWORD WINAPI d3d9_texture_2d_GetLevelCount(IDirect3DTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+ DWORD ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_get_level_count(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static HRESULT WINAPI d3d9_texture_2d_SetAutoGenFilterType(IDirect3DTexture9 *iface, D3DTEXTUREFILTERTYPE filter_type)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
+
+ wined3d_mutex_lock();
+ hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture,
+ (enum wined3d_texture_filter_type)filter_type);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_2d_GetAutoGenFilterType(IDirect3DTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+ D3DTEXTUREFILTERTYPE ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static void WINAPI d3d9_texture_2d_GenerateMipSubLevels(IDirect3DTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_texture_generate_mipmaps(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+}
+
+static HRESULT WINAPI d3d9_texture_2d_GetLevelDesc(IDirect3DTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+ struct wined3d_resource *sub_resource;
+ HRESULT hr = D3D_OK;
+
+ TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
+
+ wined3d_mutex_lock();
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+ hr = D3DERR_INVALIDCALL;
+ else
+ {
+ struct wined3d_resource_desc wined3d_desc;
+
+ wined3d_resource_get_desc(sub_resource, &wined3d_desc);
+ desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
+ desc->Type = wined3d_desc.resource_type;
+ desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
+ desc->Pool = wined3d_desc.pool;
+ desc->MultiSampleType = wined3d_desc.multisample_type;
+ desc->MultiSampleQuality = wined3d_desc.multisample_quality;
+ desc->Width = wined3d_desc.width;
+ desc->Height = wined3d_desc.height;
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_texture_2d_GetSurfaceLevel(IDirect3DTexture9 *iface,
+ UINT level, IDirect3DSurface9 **surface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+ struct wined3d_resource *sub_resource;
+ struct d3d9_surface *surface_impl;
+
+ TRACE("iface %p, level %u, surface %p.\n", iface, level, surface);
+
+ wined3d_mutex_lock();
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+ {
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
+
+ surface_impl = wined3d_resource_get_parent(sub_resource);
+ *surface = &surface_impl->IDirect3DSurface9_iface;
+ IDirect3DSurface9_AddRef(*surface);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_texture_2d_LockRect(IDirect3DTexture9 *iface,
+ UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+ struct wined3d_resource *sub_resource;
+ struct d3d9_surface *surface_impl;
+ HRESULT hr;
+
+ TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#x.\n",
+ iface, level, locked_rect, rect, flags);
+
+ wined3d_mutex_lock();
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+ hr = D3DERR_INVALIDCALL;
+ else
+ {
+ surface_impl = wined3d_resource_get_parent(sub_resource);
+ hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags);
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_texture_2d_UnlockRect(IDirect3DTexture9 *iface, UINT level)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+ struct wined3d_resource *sub_resource;
+ struct d3d9_surface *surface_impl;
+ HRESULT hr;
+
+ TRACE("iface %p, level %u.\n", iface, level);
+
+ wined3d_mutex_lock();
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+ hr = D3DERR_INVALIDCALL;
+ else
+ {
+ surface_impl = wined3d_resource_get_parent(sub_resource);
+ hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface);
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_texture_2d_AddDirtyRect(IDirect3DTexture9 *iface, const RECT *dirty_rect)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, dirty_rect %s.\n",
+ iface, wine_dbgstr_rect(dirty_rect));
+
+ wined3d_mutex_lock();
+ if (!dirty_rect)
+ hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, NULL);
+ else
+ {
+ struct wined3d_box dirty_region;
+
+ dirty_region.left = dirty_rect->left;
+ dirty_region.top = dirty_rect->top;
+ dirty_region.right = dirty_rect->right;
+ dirty_region.bottom = dirty_rect->bottom;
+ dirty_region.front = 0;
+ dirty_region.back = 1;
+ hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, &dirty_region);
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static const IDirect3DTexture9Vtbl d3d9_texture_2d_vtbl =
+{
+ /* IUnknown */
+ d3d9_texture_2d_QueryInterface,
+ d3d9_texture_2d_AddRef,
+ d3d9_texture_2d_Release,
+ /* IDirect3DResource9 */
+ d3d9_texture_2d_GetDevice,
+ d3d9_texture_2d_SetPrivateData,
+ d3d9_texture_2d_GetPrivateData,
+ d3d9_texture_2d_FreePrivateData,
+ d3d9_texture_2d_SetPriority,
+ d3d9_texture_2d_GetPriority,
+ d3d9_texture_2d_PreLoad,
+ d3d9_texture_2d_GetType,
+ /* IDirect3dBaseTexture9 */
+ d3d9_texture_2d_SetLOD,
+ d3d9_texture_2d_GetLOD,
+ d3d9_texture_2d_GetLevelCount,
+ d3d9_texture_2d_SetAutoGenFilterType,
+ d3d9_texture_2d_GetAutoGenFilterType,
+ d3d9_texture_2d_GenerateMipSubLevels,
+ /* IDirect3DTexture9 */
+ d3d9_texture_2d_GetLevelDesc,
+ d3d9_texture_2d_GetSurfaceLevel,
+ d3d9_texture_2d_LockRect,
+ d3d9_texture_2d_UnlockRect,
+ d3d9_texture_2d_AddDirtyRect,
+};
+
+static HRESULT WINAPI d3d9_texture_cube_QueryInterface(IDirect3DCubeTexture9 *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DCubeTexture9)
+ || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
+ || IsEqualGUID(riid, &IID_IDirect3DResource9)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DCubeTexture9_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d9_texture_cube_AddRef(IDirect3DCubeTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+ ULONG ref = InterlockedIncrement(&texture->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, ref);
+
+ if (ref == 1)
+ {
+ IDirect3DDevice9Ex_AddRef(texture->parent_device);
+ wined3d_mutex_lock();
+ wined3d_texture_incref(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+ }
+
+ return ref;
+}
+
+static ULONG WINAPI d3d9_texture_cube_Release(IDirect3DCubeTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+ ULONG ref = InterlockedDecrement(&texture->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, ref);
+
+ if (!ref)
+ {
+ IDirect3DDevice9Ex *parent_device = texture->parent_device;
+
+ TRACE("Releasing child %p.\n", texture->wined3d_texture);
+
+ wined3d_mutex_lock();
+ wined3d_texture_decref(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ /* Release the device last, as it may cause the device to be destroyed. */
+ IDirect3DDevice9Ex_Release(parent_device);
+ }
+ return ref;
+}
+
+static HRESULT WINAPI d3d9_texture_cube_GetDevice(IDirect3DCubeTexture9 *iface, IDirect3DDevice9 **device)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ *device = (IDirect3DDevice9 *)texture->parent_device;
+ IDirect3DDevice9_AddRef(*device);
+
+ TRACE("Returning device %p.\n", *device);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_texture_cube_SetPrivateData(IDirect3DCubeTexture9 *iface,
+ REFGUID guid, const void *data, DWORD data_size, DWORD flags)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
+ iface, debugstr_guid(guid), data, data_size, flags);
+
+ wined3d_mutex_lock();
+ resource = wined3d_texture_get_resource(texture->wined3d_texture);
+ hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_texture_cube_GetPrivateData(IDirect3DCubeTexture9 *iface,
+ REFGUID guid, void *data, DWORD *data_size)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %p.\n",
+ iface, debugstr_guid(guid), data, data_size);
+
+ wined3d_mutex_lock();
+ resource = wined3d_texture_get_resource(texture->wined3d_texture);
+ hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_texture_cube_FreePrivateData(IDirect3DCubeTexture9 *iface, REFGUID guid)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
+
+ wined3d_mutex_lock();
+ resource = wined3d_texture_get_resource(texture->wined3d_texture);
+ hr = wined3d_resource_free_private_data(resource, guid);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static DWORD WINAPI d3d9_texture_cube_SetPriority(IDirect3DCubeTexture9 *iface, DWORD priority)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+ DWORD ret;
+
+ TRACE("iface %p, priority %u.\n", iface, priority);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_set_priority(texture->wined3d_texture, priority);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static DWORD WINAPI d3d9_texture_cube_GetPriority(IDirect3DCubeTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+ DWORD ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_get_priority(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static void WINAPI d3d9_texture_cube_PreLoad(IDirect3DCubeTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_texture_preload(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+}
+
+static D3DRESOURCETYPE WINAPI d3d9_texture_cube_GetType(IDirect3DCubeTexture9 *iface)
+{
+ TRACE("iface %p.\n", iface);
+
+ return D3DRTYPE_CUBETEXTURE;
+}
+
+static DWORD WINAPI d3d9_texture_cube_SetLOD(IDirect3DCubeTexture9 *iface, DWORD lod)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+ DWORD ret;
+
+ TRACE("iface %p, lod %u.\n", iface, lod);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static DWORD WINAPI d3d9_texture_cube_GetLOD(IDirect3DCubeTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+ DWORD ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_get_lod(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static DWORD WINAPI d3d9_texture_cube_GetLevelCount(IDirect3DCubeTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+ DWORD ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_get_level_count(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static HRESULT WINAPI d3d9_texture_cube_SetAutoGenFilterType(IDirect3DCubeTexture9 *iface,
+ D3DTEXTUREFILTERTYPE filter_type)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
+
+ wined3d_mutex_lock();
+ hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture,
+ (enum wined3d_texture_filter_type)filter_type);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_cube_GetAutoGenFilterType(IDirect3DCubeTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+ D3DTEXTUREFILTERTYPE ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static void WINAPI d3d9_texture_cube_GenerateMipSubLevels(IDirect3DCubeTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_texture_generate_mipmaps(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+}
+
+static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+ struct wined3d_resource *sub_resource;
+ HRESULT hr = D3D_OK;
+ DWORD level_count;
+
+ TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
+
+ wined3d_mutex_lock();
+ level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
+ if (level >= level_count)
+ {
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
+
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+ hr = D3DERR_INVALIDCALL;
+ else
+ {
+ struct wined3d_resource_desc wined3d_desc;
+
+ wined3d_resource_get_desc(sub_resource, &wined3d_desc);
+ desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
+ desc->Type = wined3d_desc.resource_type;
+ desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
+ desc->Pool = wined3d_desc.pool;
+ desc->MultiSampleType = wined3d_desc.multisample_type;
+ desc->MultiSampleQuality = wined3d_desc.multisample_quality;
+ desc->Width = wined3d_desc.width;
+ desc->Height = wined3d_desc.height;
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture9 *iface,
+ D3DCUBEMAP_FACES face, UINT level, IDirect3DSurface9 **surface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+ struct wined3d_resource *sub_resource;
+ struct d3d9_surface *surface_impl;
+ UINT sub_resource_idx;
+ DWORD level_count;
+
+ TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, face, level, surface);
+
+ wined3d_mutex_lock();
+ level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
+ if (level >= level_count)
+ {
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
+
+ sub_resource_idx = level_count * face + level;
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx)))
+ {
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
+
+ surface_impl = wined3d_resource_get_parent(sub_resource);
+ *surface = &surface_impl->IDirect3DSurface9_iface;
+ IDirect3DSurface9_AddRef(*surface);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_texture_cube_LockRect(IDirect3DCubeTexture9 *iface,
+ D3DCUBEMAP_FACES face, UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect,
+ DWORD flags)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+ struct wined3d_resource *sub_resource;
+ struct d3d9_surface *surface_impl;
+ UINT sub_resource_idx;
+ HRESULT hr;
+
+ TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#x.\n",
+ iface, face, level, locked_rect, rect, flags);
+
+ wined3d_mutex_lock();
+ sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx)))
+ hr = D3DERR_INVALIDCALL;
+ else
+ {
+ surface_impl = wined3d_resource_get_parent(sub_resource);
+ hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags);
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_texture_cube_UnlockRect(IDirect3DCubeTexture9 *iface,
+ D3DCUBEMAP_FACES face, UINT level)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+ struct wined3d_resource *sub_resource;
+ struct d3d9_surface *surface_impl;
+ UINT sub_resource_idx;
+ HRESULT hr;
+
+ TRACE("iface %p, face %#x, level %u.\n", iface, face, level);
+
+ wined3d_mutex_lock();
+ sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx)))
+ hr = D3DERR_INVALIDCALL;
+ else
+ {
+ surface_impl = wined3d_resource_get_parent(sub_resource);
+ hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface);
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_texture_cube_AddDirtyRect(IDirect3DCubeTexture9 *iface,
+ D3DCUBEMAP_FACES face, const RECT *dirty_rect)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, face %#x, dirty_rect %s.\n",
+ iface, face, wine_dbgstr_rect(dirty_rect));
+
+ wined3d_mutex_lock();
+ if (!dirty_rect)
+ hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, NULL);
+ else
+ {
+ struct wined3d_box dirty_region;
+
+ dirty_region.left = dirty_rect->left;
+ dirty_region.top = dirty_rect->top;
+ dirty_region.right = dirty_rect->right;
+ dirty_region.bottom = dirty_rect->bottom;
+ dirty_region.front = 0;
+ dirty_region.back = 1;
+ hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, &dirty_region);
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static const IDirect3DCubeTexture9Vtbl d3d9_texture_cube_vtbl =
+{
+ /* IUnknown */
+ d3d9_texture_cube_QueryInterface,
+ d3d9_texture_cube_AddRef,
+ d3d9_texture_cube_Release,
+ /* IDirect3DResource9 */
+ d3d9_texture_cube_GetDevice,
+ d3d9_texture_cube_SetPrivateData,
+ d3d9_texture_cube_GetPrivateData,
+ d3d9_texture_cube_FreePrivateData,
+ d3d9_texture_cube_SetPriority,
+ d3d9_texture_cube_GetPriority,
+ d3d9_texture_cube_PreLoad,
+ d3d9_texture_cube_GetType,
+ /* IDirect3DBaseTexture9 */
+ d3d9_texture_cube_SetLOD,
+ d3d9_texture_cube_GetLOD,
+ d3d9_texture_cube_GetLevelCount,
+ d3d9_texture_cube_SetAutoGenFilterType,
+ d3d9_texture_cube_GetAutoGenFilterType,
+ d3d9_texture_cube_GenerateMipSubLevels,
+ /* IDirect3DCubeTexture9 */
+ d3d9_texture_cube_GetLevelDesc,
+ d3d9_texture_cube_GetCubeMapSurface,
+ d3d9_texture_cube_LockRect,
+ d3d9_texture_cube_UnlockRect,
+ d3d9_texture_cube_AddDirtyRect,
+};
+
+static HRESULT WINAPI d3d9_texture_3d_QueryInterface(IDirect3DVolumeTexture9 *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DVolumeTexture9)
+ || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
+ || IsEqualGUID(riid, &IID_IDirect3DResource9)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DVolumeTexture9_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d9_texture_3d_AddRef(IDirect3DVolumeTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+ ULONG ref = InterlockedIncrement(&texture->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, ref);
+
+ if (ref == 1)
+ {
+ IDirect3DDevice9Ex_AddRef(texture->parent_device);
+ wined3d_mutex_lock();
+ wined3d_texture_incref(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+ }
+
+ return ref;
+}
+
+static ULONG WINAPI d3d9_texture_3d_Release(IDirect3DVolumeTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+ ULONG ref = InterlockedDecrement(&texture->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, ref);
+
+ if (!ref)
+ {
+ IDirect3DDevice9Ex *parent_device = texture->parent_device;
+
+ wined3d_mutex_lock();
+ wined3d_texture_decref(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ /* Release the device last, as it may cause the device to be destroyed. */
+ IDirect3DDevice9Ex_Release(parent_device);
+ }
+ return ref;
+}
+
+static HRESULT WINAPI d3d9_texture_3d_GetDevice(IDirect3DVolumeTexture9 *iface, IDirect3DDevice9 **device)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ *device = (IDirect3DDevice9 *)texture->parent_device;
+ IDirect3DDevice9_AddRef(*device);
+
+ TRACE("Returning device %p.\n", *device);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_texture_3d_SetPrivateData(IDirect3DVolumeTexture9 *iface,
+ REFGUID guid, const void *data, DWORD data_size, DWORD flags)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
+ iface, debugstr_guid(guid), data, data_size, flags);
+
+ wined3d_mutex_lock();
+ resource = wined3d_texture_get_resource(texture->wined3d_texture);
+ hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_texture_3d_GetPrivateData(IDirect3DVolumeTexture9 *iface,
+ REFGUID guid, void *data, DWORD *data_size)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %p.\n",
+ iface, debugstr_guid(guid), data, data_size);
+
+ wined3d_mutex_lock();
+ resource = wined3d_texture_get_resource(texture->wined3d_texture);
+ hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_texture_3d_FreePrivateData(IDirect3DVolumeTexture9 *iface, REFGUID guid)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
+
+ wined3d_mutex_lock();
+ resource = wined3d_texture_get_resource(texture->wined3d_texture);
+ hr = wined3d_resource_free_private_data(resource, guid);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static DWORD WINAPI d3d9_texture_3d_SetPriority(IDirect3DVolumeTexture9 *iface, DWORD priority)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+ DWORD ret;
+
+ TRACE("iface %p, priority %u.\n", iface, priority);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_set_priority(texture->wined3d_texture, priority);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static DWORD WINAPI d3d9_texture_3d_GetPriority(IDirect3DVolumeTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+ DWORD ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_get_priority(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static void WINAPI d3d9_texture_3d_PreLoad(IDirect3DVolumeTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_texture_preload(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+}
+
+static D3DRESOURCETYPE WINAPI d3d9_texture_3d_GetType(IDirect3DVolumeTexture9 *iface)
+{
+ TRACE("iface %p.\n", iface);
+
+ return D3DRTYPE_VOLUMETEXTURE;
+}
+
+static DWORD WINAPI d3d9_texture_3d_SetLOD(IDirect3DVolumeTexture9 *iface, DWORD lod)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+ DWORD ret;
+
+ TRACE("iface %p, lod %u.\n", iface, lod);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static DWORD WINAPI d3d9_texture_3d_GetLOD(IDirect3DVolumeTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+ DWORD ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_get_lod(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static DWORD WINAPI d3d9_texture_3d_GetLevelCount(IDirect3DVolumeTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+ DWORD ret;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ ret = wined3d_texture_get_level_count(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return ret;
+}
+
+static HRESULT WINAPI d3d9_texture_3d_SetAutoGenFilterType(IDirect3DVolumeTexture9 *iface,
+ D3DTEXTUREFILTERTYPE filter_type)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
+
+ wined3d_mutex_lock();
+ hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture,
+ (enum wined3d_texture_filter_type)filter_type);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_3d_GetAutoGenFilterType(IDirect3DVolumeTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+ D3DTEXTUREFILTERTYPE filter_type;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ filter_type = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+
+ return filter_type;
+}
+
+static void WINAPI d3d9_texture_3d_GenerateMipSubLevels(IDirect3DVolumeTexture9 *iface)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ wined3d_texture_generate_mipmaps(texture->wined3d_texture);
+ wined3d_mutex_unlock();
+}
+
+static HRESULT WINAPI d3d9_texture_3d_GetLevelDesc(IDirect3DVolumeTexture9 *iface, UINT level, D3DVOLUME_DESC *desc)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+ struct wined3d_resource *sub_resource;
+ HRESULT hr = D3D_OK;
+
+ TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
+
+ wined3d_mutex_lock();
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+ hr = D3DERR_INVALIDCALL;
+ else
+ {
+ struct wined3d_resource_desc wined3d_desc;
+
+ wined3d_resource_get_desc(sub_resource, &wined3d_desc);
+ desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
+ desc->Type = wined3d_desc.resource_type;
+ desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
+ desc->Pool = wined3d_desc.pool;
+ desc->Width = wined3d_desc.width;
+ desc->Height = wined3d_desc.height;
+ desc->Depth = wined3d_desc.depth;
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture9 *iface,
+ UINT level, IDirect3DVolume9 **volume)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+ struct wined3d_resource *sub_resource;
+ struct d3d9_volume *volume_impl;
+
+ TRACE("iface %p, level %u, volume %p.\n", iface, level, volume);
+
+ wined3d_mutex_lock();
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+ {
+ wined3d_mutex_unlock();
+ return D3DERR_INVALIDCALL;
+ }
+
+ volume_impl = wined3d_resource_get_parent(sub_resource);
+ *volume = &volume_impl->IDirect3DVolume9_iface;
+ IDirect3DVolume9_AddRef(*volume);
+ wined3d_mutex_unlock();
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_texture_3d_LockBox(IDirect3DVolumeTexture9 *iface,
+ UINT level, D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+ struct wined3d_resource *sub_resource;
+ struct d3d9_volume *volume_impl;
+ HRESULT hr;
+
+ TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n",
+ iface, level, locked_box, box, flags);
+
+ wined3d_mutex_lock();
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+ hr = D3DERR_INVALIDCALL;
+ else
+ {
+ volume_impl = wined3d_resource_get_parent(sub_resource);
+ hr = IDirect3DVolume9_LockBox(&volume_impl->IDirect3DVolume9_iface, locked_box, box, flags);
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_texture_3d_UnlockBox(IDirect3DVolumeTexture9 *iface, UINT level)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+ struct wined3d_resource *sub_resource;
+ struct d3d9_volume *volume_impl;
+ HRESULT hr;
+
+ TRACE("iface %p, level %u.\n", iface, level);
+
+ wined3d_mutex_lock();
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
+ hr = D3DERR_INVALIDCALL;
+ else
+ {
+ volume_impl = wined3d_resource_get_parent(sub_resource);
+ hr = IDirect3DVolume9_UnlockBox(&volume_impl->IDirect3DVolume9_iface);
+ }
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_texture_3d_AddDirtyBox(IDirect3DVolumeTexture9 *iface, const D3DBOX *dirty_box)
+{
+ struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, dirty_box %p.\n", iface, dirty_box);
+
+ wined3d_mutex_lock();
+ hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, (const struct wined3d_box *)dirty_box);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+
+static const IDirect3DVolumeTexture9Vtbl d3d9_texture_3d_vtbl =
+{
+ /* IUnknown */
+ d3d9_texture_3d_QueryInterface,
+ d3d9_texture_3d_AddRef,
+ d3d9_texture_3d_Release,
+ /* IDirect3DResource9 */
+ d3d9_texture_3d_GetDevice,
+ d3d9_texture_3d_SetPrivateData,
+ d3d9_texture_3d_GetPrivateData,
+ d3d9_texture_3d_FreePrivateData,
+ d3d9_texture_3d_SetPriority,
+ d3d9_texture_3d_GetPriority,
+ d3d9_texture_3d_PreLoad,
+ d3d9_texture_3d_GetType,
+ /* IDirect3DBaseTexture9 */
+ d3d9_texture_3d_SetLOD,
+ d3d9_texture_3d_GetLOD,
+ d3d9_texture_3d_GetLevelCount,
+ d3d9_texture_3d_SetAutoGenFilterType,
+ d3d9_texture_3d_GetAutoGenFilterType,
+ d3d9_texture_3d_GenerateMipSubLevels,
+ /* IDirect3DVolumeTexture9 */
+ d3d9_texture_3d_GetLevelDesc,
+ d3d9_texture_3d_GetVolumeLevel,
+ d3d9_texture_3d_LockBox,
+ d3d9_texture_3d_UnlockBox,
+ d3d9_texture_3d_AddDirtyBox,
+};
+
+struct d3d9_texture *unsafe_impl_from_IDirect3DBaseTexture9(IDirect3DBaseTexture9 *iface)
+{
+ if (!iface)
+ return NULL;
+ assert(iface->lpVtbl == (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl
+ || iface->lpVtbl == (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl
+ || iface->lpVtbl == (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl);
+ return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
+}
+
+static void STDMETHODCALLTYPE d3d9_texture_wined3d_object_destroyed(void *parent)
+{
+ HeapFree(GetProcessHeap(), 0, parent);
+}
+
+static const struct wined3d_parent_ops d3d9_texture_wined3d_parent_ops =
+{
+ d3d9_texture_wined3d_object_destroyed,
+};
+
+HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
+ UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void **pavClientMem
+#endif
+ )
+{
+ struct wined3d_resource_desc desc;
+ DWORD surface_flags = 0;
+ HRESULT hr;
+
+ texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl;
+ texture->refcount = 1;
+
+ desc.resource_type = WINED3D_RTYPE_TEXTURE;
+ desc.format = wined3dformat_from_d3dformat(format);
+ desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
+ desc.multisample_quality = 0;
+ desc.usage = usage & WINED3DUSAGE_MASK;
+ desc.pool = pool;
+ desc.width = width;
+ desc.height = height;
+ desc.depth = 1;
+ desc.size = 0;
+
+ if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
+ surface_flags |= WINED3D_SURFACE_MAPPABLE;
+
+ wined3d_mutex_lock();
+ hr = wined3d_texture_create_2d(device->wined3d_device, &desc, levels, surface_flags,
+ texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture
+#ifdef VBOX_WITH_WDDM
+ , shared_handle
+ , pavClientMem
+#endif
+ );
+ wined3d_mutex_unlock();
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d texture, hr %#x.\n", hr);
+ return hr;
+ }
+
+ texture->parent_device = &device->IDirect3DDevice9Ex_iface;
+ IDirect3DDevice9Ex_AddRef(texture->parent_device);
+
+ return D3D_OK;
+}
+
+HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,
+ UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void **pavClientMem
+#endif
+ )
+{
+ struct wined3d_resource_desc desc;
+ DWORD surface_flags = 0;
+ HRESULT hr;
+
+ texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl;
+ texture->refcount = 1;
+
+ desc.resource_type = WINED3D_RTYPE_CUBE_TEXTURE;
+ desc.format = wined3dformat_from_d3dformat(format);
+ desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
+ desc.multisample_quality = 0;
+ desc.usage = usage & WINED3DUSAGE_MASK;
+ desc.pool = pool;
+ desc.width = edge_length;
+ desc.height = edge_length;
+ desc.depth = 1;
+ desc.size = 0;
+
+ if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
+ surface_flags |= WINED3D_SURFACE_MAPPABLE;
+
+ wined3d_mutex_lock();
+ hr = wined3d_texture_create_cube(device->wined3d_device, &desc, levels, surface_flags,
+ texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture
+#ifdef VBOX_WITH_WDDM
+ , shared_handle
+ , pavClientMem
+#endif
+ );
+ wined3d_mutex_unlock();
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d cube texture, hr %#x.\n", hr);
+ return hr;
+ }
+
+ texture->parent_device = &device->IDirect3DDevice9Ex_iface;
+ IDirect3DDevice9Ex_AddRef(texture->parent_device);
+
+ return D3D_OK;
+}
+
+HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,
+ UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void **pavClientMem
+#endif
+ )
+{
+ struct wined3d_resource_desc desc;
+ HRESULT hr;
+
+ texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl;
+ texture->refcount = 1;
+
+ desc.resource_type = WINED3D_RTYPE_VOLUME_TEXTURE;
+ desc.format = wined3dformat_from_d3dformat(format);
+ desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
+ desc.multisample_quality = 0;
+ desc.usage = usage & WINED3DUSAGE_MASK;
+ desc.pool = pool;
+ desc.width = width;
+ desc.height = height;
+ desc.depth = depth;
+ desc.size = 0;
+
+ wined3d_mutex_lock();
+ hr = wined3d_texture_create_3d(device->wined3d_device, &desc, levels,
+ texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture
+#ifdef VBOX_WITH_WDDM
+ , shared_handle
+ , pavClientMem
+#endif
+ );
+ wined3d_mutex_unlock();
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d volume texture, hr %#x.\n", hr);
+ return hr;
+ }
+
+ texture->parent_device = &device->IDirect3DDevice9Ex_iface;
+ IDirect3DDevice9Ex_AddRef(texture->parent_device);
+
+ return D3D_OK;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/vboxport.asm b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/vboxport.asm
new file mode 100644
index 00000000..d1b0d6f0
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/vboxport.asm
@@ -0,0 +1,47 @@
+; $Id: vboxport.asm $
+;; @file
+; asm specifics
+;
+
+;
+; Copyright (C) 2013 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; you can redistribute it and/or modify it under the terms of the GNU
+; General Public License (GPL) as published by the Free Software
+; Foundation, in version 2 as it comes in the "COPYING" file of the
+; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+;
+
+;*******************************************************************************
+;* Header Files *
+;*******************************************************************************
+%include "iprt/asmdefs.mac"
+
+BEGINCODE
+
+;;
+; Get the FPU control word
+;
+align 16
+BEGINPROC VBoxAsmFpuFCWGet
+ fnstcw [xSP - 8]
+ mov ax, word [xSP - 8]
+ ret
+ENDPROC VBoxAsmFpuFCWGet
+
+;;
+; Set the FPU control word
+;
+; @param u16FCW New FPU control word
+align 16
+BEGINPROC VBoxAsmFpuFCWSet
+ mov xAX, rcx
+ push xAX
+ fldcw [xSP]
+ pop xAX
+ ret
+ENDPROC VBoxAsmFpuFCWSet
+
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/version.rc b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/version.rc
new file mode 100644
index 00000000..3570e5ef
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/version.rc
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2001 Ove Kaaven
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#define WINE_FILEDESCRIPTION_STR "Wine Direct3D"
+#define WINE_FILENAME_STR "d3d9.dll"
+#define WINE_FILEVERSION 5,3,1,904
+#define WINE_FILEVERSION_STR "5.3.1.904"
+#define WINE_PRODUCTVERSION 5,3,1,904
+#define WINE_PRODUCTVERSION_STR "5.3.1.904"
+
+#include "wine/wine_common_ver.rc"
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/vertexdeclaration.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/vertexdeclaration.c
new file mode 100644
index 00000000..450c1136
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/vertexdeclaration.c
@@ -0,0 +1,445 @@
+/*
+ * IDirect3DVertexDeclaration9 implementation
+ *
+ * Copyright 2002-2003 Raphael Junqueira
+ * Jason Edmeades
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "d3d9_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
+static const struct
+{
+ enum wined3d_format_id format;
+ unsigned int component_count;
+ unsigned int component_size;
+}
+d3d_dtype_lookup[] =
+{
+ /* D3DDECLTYPE_FLOAT1 */ {WINED3DFMT_R32_FLOAT, 1, sizeof(float)},
+ /* D3DDECLTYPE_FLOAT2 */ {WINED3DFMT_R32G32_FLOAT, 2, sizeof(float)},
+ /* D3DDECLTYPE_FLOAT3 */ {WINED3DFMT_R32G32B32_FLOAT, 3, sizeof(float)},
+ /* D3DDECLTYPE_FLOAT4 */ {WINED3DFMT_R32G32B32A32_FLOAT, 4, sizeof(float)},
+ /* D3DDECLTYPE_D3DCOLOR */ {WINED3DFMT_B8G8R8A8_UNORM, 4, sizeof(BYTE)},
+ /* D3DDECLTYPE_UBYTE4 */ {WINED3DFMT_R8G8B8A8_UINT, 4, sizeof(BYTE)},
+ /* D3DDECLTYPE_SHORT2 */ {WINED3DFMT_R16G16_SINT, 2, sizeof(short int)},
+ /* D3DDECLTYPE_SHORT4 */ {WINED3DFMT_R16G16B16A16_SINT, 4, sizeof(short int)},
+ /* D3DDECLTYPE_UBYTE4N */ {WINED3DFMT_R8G8B8A8_UNORM, 4, sizeof(BYTE)},
+ /* D3DDECLTYPE_SHORT2N */ {WINED3DFMT_R16G16_SNORM, 2, sizeof(short int)},
+ /* D3DDECLTYPE_SHORT4N */ {WINED3DFMT_R16G16B16A16_SNORM, 4, sizeof(short int)},
+ /* D3DDECLTYPE_USHORT2N */ {WINED3DFMT_R16G16_UNORM, 2, sizeof(short int)},
+ /* D3DDECLTYPE_USHORT4N */ {WINED3DFMT_R16G16B16A16_UNORM, 4, sizeof(short int)},
+ /* D3DDECLTYPE_UDEC3 */ {WINED3DFMT_R10G10B10A2_UINT, 3, sizeof(short int)},
+ /* D3DDECLTYPE_DEC3N */ {WINED3DFMT_R10G10B10A2_SNORM, 3, sizeof(short int)},
+ /* D3DDECLTYPE_FLOAT16_2 */ {WINED3DFMT_R16G16_FLOAT, 2, sizeof(short int)},
+ /* D3DDECLTYPE_FLOAT16_4 */ {WINED3DFMT_R16G16B16A16_FLOAT, 4, sizeof(short int)}
+};
+
+static inline struct d3d9_vertex_declaration *impl_from_IDirect3DVertexDeclaration9(IDirect3DVertexDeclaration9 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d9_vertex_declaration, IDirect3DVertexDeclaration9_iface);
+}
+
+HRESULT vdecl_convert_fvf(
+ DWORD fvf,
+ D3DVERTEXELEMENT9** ppVertexElements) {
+
+ unsigned int idx, idx2;
+ unsigned int offset;
+ BOOL has_pos = (fvf & D3DFVF_POSITION_MASK) != 0;
+ BOOL has_blend = (fvf & D3DFVF_XYZB5) > D3DFVF_XYZRHW;
+ BOOL has_blend_idx = has_blend &&
+ (((fvf & D3DFVF_XYZB5) == D3DFVF_XYZB5) ||
+ (fvf & D3DFVF_LASTBETA_D3DCOLOR) ||
+ (fvf & D3DFVF_LASTBETA_UBYTE4));
+ BOOL has_normal = (fvf & D3DFVF_NORMAL) != 0;
+ BOOL has_psize = (fvf & D3DFVF_PSIZE) != 0;
+
+ BOOL has_diffuse = (fvf & D3DFVF_DIFFUSE) != 0;
+ BOOL has_specular = (fvf & D3DFVF_SPECULAR) !=0;
+
+ DWORD num_textures = (fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
+ DWORD texcoords = (fvf & 0xFFFF0000) >> 16;
+
+ D3DVERTEXELEMENT9 end_element = D3DDECL_END();
+ D3DVERTEXELEMENT9 *elements = NULL;
+
+ unsigned int size;
+ DWORD num_blends = 1 + (((fvf & D3DFVF_XYZB5) - D3DFVF_XYZB1) >> 1);
+ if (has_blend_idx) num_blends--;
+
+ /* Compute declaration size */
+ size = has_pos + (has_blend && num_blends > 0) + has_blend_idx + has_normal +
+ has_psize + has_diffuse + has_specular + num_textures + 1;
+
+ /* convert the declaration */
+ elements = HeapAlloc(GetProcessHeap(), 0, size * sizeof(D3DVERTEXELEMENT9));
+ if (!elements) return D3DERR_OUTOFVIDEOMEMORY;
+
+ elements[size-1] = end_element;
+ idx = 0;
+ if (has_pos) {
+ if (!has_blend && (fvf & D3DFVF_XYZRHW)) {
+ elements[idx].Type = D3DDECLTYPE_FLOAT4;
+ elements[idx].Usage = D3DDECLUSAGE_POSITIONT;
+ }
+ else if (!has_blend && (fvf & D3DFVF_XYZW) == D3DFVF_XYZW) {
+ elements[idx].Type = D3DDECLTYPE_FLOAT4;
+ elements[idx].Usage = D3DDECLUSAGE_POSITION;
+ }
+ else {
+ elements[idx].Type = D3DDECLTYPE_FLOAT3;
+ elements[idx].Usage = D3DDECLUSAGE_POSITION;
+ }
+ elements[idx].UsageIndex = 0;
+ idx++;
+ }
+ if (has_blend && (num_blends > 0)) {
+ if (((fvf & D3DFVF_XYZB5) == D3DFVF_XYZB2) && (fvf & D3DFVF_LASTBETA_D3DCOLOR))
+ elements[idx].Type = D3DDECLTYPE_D3DCOLOR;
+ else {
+ switch(num_blends) {
+ case 1: elements[idx].Type = D3DDECLTYPE_FLOAT1; break;
+ case 2: elements[idx].Type = D3DDECLTYPE_FLOAT2; break;
+ case 3: elements[idx].Type = D3DDECLTYPE_FLOAT3; break;
+ case 4: elements[idx].Type = D3DDECLTYPE_FLOAT4; break;
+ default:
+ ERR("Unexpected amount of blend values: %u\n", num_blends);
+ }
+ }
+ elements[idx].Usage = D3DDECLUSAGE_BLENDWEIGHT;
+ elements[idx].UsageIndex = 0;
+ idx++;
+ }
+ if (has_blend_idx) {
+ if (fvf & D3DFVF_LASTBETA_UBYTE4 ||
+ (((fvf & D3DFVF_XYZB5) == D3DFVF_XYZB2) && (fvf & D3DFVF_LASTBETA_D3DCOLOR)))
+ elements[idx].Type = D3DDECLTYPE_UBYTE4;
+ else if (fvf & D3DFVF_LASTBETA_D3DCOLOR)
+ elements[idx].Type = D3DDECLTYPE_D3DCOLOR;
+ else
+ elements[idx].Type = D3DDECLTYPE_FLOAT1;
+ elements[idx].Usage = D3DDECLUSAGE_BLENDINDICES;
+ elements[idx].UsageIndex = 0;
+ idx++;
+ }
+ if (has_normal) {
+ elements[idx].Type = D3DDECLTYPE_FLOAT3;
+ elements[idx].Usage = D3DDECLUSAGE_NORMAL;
+ elements[idx].UsageIndex = 0;
+ idx++;
+ }
+ if (has_psize) {
+ elements[idx].Type = D3DDECLTYPE_FLOAT1;
+ elements[idx].Usage = D3DDECLUSAGE_PSIZE;
+ elements[idx].UsageIndex = 0;
+ idx++;
+ }
+ if (has_diffuse) {
+ elements[idx].Type = D3DDECLTYPE_D3DCOLOR;
+ elements[idx].Usage = D3DDECLUSAGE_COLOR;
+ elements[idx].UsageIndex = 0;
+ idx++;
+ }
+ if (has_specular) {
+ elements[idx].Type = D3DDECLTYPE_D3DCOLOR;
+ elements[idx].Usage = D3DDECLUSAGE_COLOR;
+ elements[idx].UsageIndex = 1;
+ idx++;
+ }
+ for (idx2 = 0; idx2 < num_textures; idx2++) {
+ unsigned int numcoords = (texcoords >> (idx2*2)) & 0x03;
+ switch (numcoords) {
+ case D3DFVF_TEXTUREFORMAT1:
+ elements[idx].Type = D3DDECLTYPE_FLOAT1;
+ break;
+ case D3DFVF_TEXTUREFORMAT2:
+ elements[idx].Type = D3DDECLTYPE_FLOAT2;
+ break;
+ case D3DFVF_TEXTUREFORMAT3:
+ elements[idx].Type = D3DDECLTYPE_FLOAT3;
+ break;
+ case D3DFVF_TEXTUREFORMAT4:
+ elements[idx].Type = D3DDECLTYPE_FLOAT4;
+ break;
+ }
+ elements[idx].Usage = D3DDECLUSAGE_TEXCOORD;
+ elements[idx].UsageIndex = idx2;
+ idx++;
+ }
+
+ /* Now compute offsets, and initialize the rest of the fields */
+ for (idx = 0, offset = 0; idx < size-1; idx++) {
+ elements[idx].Stream = 0;
+ elements[idx].Method = D3DDECLMETHOD_DEFAULT;
+ elements[idx].Offset = offset;
+ offset += d3d_dtype_lookup[elements[idx].Type].component_count
+ * d3d_dtype_lookup[elements[idx].Type].component_size;
+ }
+
+ *ppVertexElements = elements;
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_vertex_declaration_QueryInterface(IDirect3DVertexDeclaration9 *iface,
+ REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DVertexDeclaration9)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DVertexDeclaration9_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d9_vertex_declaration_AddRef(IDirect3DVertexDeclaration9 *iface)
+{
+ struct d3d9_vertex_declaration *declaration = impl_from_IDirect3DVertexDeclaration9(iface);
+ ULONG refcount = InterlockedIncrement(&declaration->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", iface, refcount);
+
+ if (refcount == 1)
+ {
+ IDirect3DDevice9Ex_AddRef(declaration->parent_device);
+ wined3d_mutex_lock();
+ wined3d_vertex_declaration_incref(declaration->wined3d_declaration);
+ wined3d_mutex_unlock();
+ }
+
+ return refcount;
+}
+
+static ULONG WINAPI d3d9_vertex_declaration_Release(IDirect3DVertexDeclaration9 *iface)
+{
+ struct d3d9_vertex_declaration *declaration = impl_from_IDirect3DVertexDeclaration9(iface);
+ ULONG refcount = InterlockedDecrement(&declaration->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ IDirect3DDevice9Ex *parent_device = declaration->parent_device;
+ wined3d_mutex_lock();
+ wined3d_vertex_declaration_decref(declaration->wined3d_declaration);
+ wined3d_mutex_unlock();
+
+ /* Release the device last, as it may cause the device to be destroyed. */
+ IDirect3DDevice9Ex_Release(parent_device);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI d3d9_vertex_declaration_GetDevice(IDirect3DVertexDeclaration9 *iface, IDirect3DDevice9 **device)
+{
+ struct d3d9_vertex_declaration *declaration = impl_from_IDirect3DVertexDeclaration9(iface);
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ *device = (IDirect3DDevice9 *)declaration->parent_device;
+ IDirect3DDevice9_AddRef(*device);
+
+ TRACE("Returning device %p.\n", *device);
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_vertex_declaration_GetDeclaration(IDirect3DVertexDeclaration9 *iface,
+ D3DVERTEXELEMENT9 *elements, UINT *element_count)
+{
+ struct d3d9_vertex_declaration *declaration = impl_from_IDirect3DVertexDeclaration9(iface);
+
+ TRACE("iface %p, elements %p, element_count %p.\n", iface, elements, element_count);
+
+ *element_count = declaration->element_count;
+
+ /* Passing a NULL elements is used to just retrieve the number of elements */
+ if (!elements)
+ return D3D_OK;
+
+ TRACE("Copying %p to %p.\n", declaration->elements, elements);
+ memcpy(elements, declaration->elements, sizeof(*declaration->elements) * declaration->element_count);
+
+ return D3D_OK;
+}
+
+static const struct IDirect3DVertexDeclaration9Vtbl d3d9_vertex_declaration_vtbl =
+{
+ /* IUnknown */
+ d3d9_vertex_declaration_QueryInterface,
+ d3d9_vertex_declaration_AddRef,
+ d3d9_vertex_declaration_Release,
+ /* IDirect3DVertexDeclaration9 */
+ d3d9_vertex_declaration_GetDevice,
+ d3d9_vertex_declaration_GetDeclaration,
+};
+
+struct d3d9_vertex_declaration *unsafe_impl_from_IDirect3DVertexDeclaration9(IDirect3DVertexDeclaration9 *iface)
+{
+ if (!iface)
+ return NULL;
+ assert(iface->lpVtbl == &d3d9_vertex_declaration_vtbl);
+ return CONTAINING_RECORD(iface, struct d3d9_vertex_declaration, IDirect3DVertexDeclaration9_iface);
+}
+
+static void STDMETHODCALLTYPE d3d9_vertexdeclaration_wined3d_object_destroyed(void *parent)
+{
+ struct d3d9_vertex_declaration *declaration = parent;
+ HeapFree(GetProcessHeap(), 0, declaration->elements);
+ HeapFree(GetProcessHeap(), 0, declaration);
+}
+
+static const struct wined3d_parent_ops d3d9_vertexdeclaration_wined3d_parent_ops =
+{
+ d3d9_vertexdeclaration_wined3d_object_destroyed,
+};
+
+static HRESULT convert_to_wined3d_declaration(const D3DVERTEXELEMENT9 *d3d9_elements,
+ struct wined3d_vertex_element **wined3d_elements, UINT *element_count)
+{
+ const D3DVERTEXELEMENT9* element;
+ UINT count = 1;
+ UINT i;
+
+ TRACE("d3d9_elements %p, wined3d_elements %p\n", d3d9_elements, wined3d_elements);
+
+ element = d3d9_elements;
+ while (element++->Stream != 0xff && count++ < 128);
+
+ if (count == 128) return E_FAIL;
+
+ /* Skip the END element */
+ --count;
+
+ *wined3d_elements = HeapAlloc(GetProcessHeap(), 0, count * sizeof(**wined3d_elements));
+ if (!*wined3d_elements) {
+ FIXME("Memory allocation failed\n");
+ return D3DERR_OUTOFVIDEOMEMORY;
+ }
+
+ for (i = 0; i < count; ++i)
+ {
+ if (d3d9_elements[i].Type >= (sizeof(d3d_dtype_lookup) / sizeof(*d3d_dtype_lookup)))
+ {
+ WARN("Invalid element type %#x.\n", d3d9_elements[i].Type);
+ HeapFree(GetProcessHeap(), 0, *wined3d_elements);
+ return E_FAIL;
+ }
+ (*wined3d_elements)[i].format = d3d_dtype_lookup[d3d9_elements[i].Type].format;
+ (*wined3d_elements)[i].input_slot = d3d9_elements[i].Stream;
+ (*wined3d_elements)[i].offset = d3d9_elements[i].Offset;
+ (*wined3d_elements)[i].output_slot = ~0U;
+ (*wined3d_elements)[i].method = d3d9_elements[i].Method;
+ (*wined3d_elements)[i].usage = d3d9_elements[i].Usage;
+ (*wined3d_elements)[i].usage_idx = d3d9_elements[i].UsageIndex;
+ }
+
+ *element_count = count;
+
+ return D3D_OK;
+}
+
+static HRESULT vertexdeclaration_init(struct d3d9_vertex_declaration *declaration,
+ struct d3d9_device *device, const D3DVERTEXELEMENT9 *elements)
+{
+ struct wined3d_vertex_element *wined3d_elements;
+ UINT wined3d_element_count;
+ UINT element_count;
+ HRESULT hr;
+
+ hr = convert_to_wined3d_declaration(elements, &wined3d_elements, &wined3d_element_count);
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d vertex declaration elements, hr %#x.\n", hr);
+ return hr;
+ }
+
+ declaration->IDirect3DVertexDeclaration9_iface.lpVtbl = &d3d9_vertex_declaration_vtbl;
+ declaration->refcount = 1;
+
+ element_count = wined3d_element_count + 1;
+ declaration->elements = HeapAlloc(GetProcessHeap(), 0, element_count * sizeof(*declaration->elements));
+ if (!declaration->elements)
+ {
+ HeapFree(GetProcessHeap(), 0, wined3d_elements);
+ ERR("Failed to allocate vertex declaration elements memory.\n");
+ return D3DERR_OUTOFVIDEOMEMORY;
+ }
+ memcpy(declaration->elements, elements, element_count * sizeof(*elements));
+ declaration->element_count = element_count;
+
+ wined3d_mutex_lock();
+ hr = wined3d_vertex_declaration_create(device->wined3d_device, wined3d_elements, wined3d_element_count,
+ declaration, &d3d9_vertexdeclaration_wined3d_parent_ops, &declaration->wined3d_declaration);
+ wined3d_mutex_unlock();
+ HeapFree(GetProcessHeap(), 0, wined3d_elements);
+ if (FAILED(hr))
+ {
+ HeapFree(GetProcessHeap(), 0, declaration->elements);
+ WARN("Failed to create wined3d vertex declaration, hr %#x.\n", hr);
+ return hr;
+ }
+
+ declaration->parent_device = &device->IDirect3DDevice9Ex_iface;
+ IDirect3DDevice9Ex_AddRef(declaration->parent_device);
+
+ return D3D_OK;
+}
+
+HRESULT d3d9_vertex_declaration_create(struct d3d9_device *device,
+ const D3DVERTEXELEMENT9 *elements, struct d3d9_vertex_declaration **declaration)
+{
+ struct d3d9_vertex_declaration *object;
+ HRESULT hr;
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ hr = vertexdeclaration_init(object, device, elements);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created vertex declaration %p.\n", object);
+ *declaration = object;
+
+ return D3D_OK;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/volume.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/volume.c
new file mode 100644
index 00000000..f61c44ce
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/d3d9/volume.c
@@ -0,0 +1,323 @@
+/*
+ * IDirect3DVolume9 implementation
+ *
+ * Copyright 2002-2005 Jason Edmeades
+ * Raphael Junqueira
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "d3d9_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
+
+static inline struct d3d9_volume *impl_from_IDirect3DVolume9(IDirect3DVolume9 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d9_volume, IDirect3DVolume9_iface);
+}
+
+static HRESULT WINAPI d3d9_volume_QueryInterface(IDirect3DVolume9 *iface, REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
+
+ if (IsEqualGUID(riid, &IID_IDirect3DVolume9)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IDirect3DVolume9_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3d9_volume_AddRef(IDirect3DVolume9 *iface)
+{
+ struct d3d9_volume *volume = impl_from_IDirect3DVolume9(iface);
+ ULONG refcount;
+
+ TRACE("iface %p.\n", iface);
+
+ if (volume->forwardReference)
+ {
+ TRACE("Forwarding to %p.\n", volume->forwardReference);
+ return IUnknown_AddRef(volume->forwardReference);
+ }
+
+ refcount = InterlockedIncrement(&volume->refcount);
+ TRACE("%p increasing refcount to %u.\n", iface, refcount);
+
+ if (refcount == 1)
+ {
+ wined3d_mutex_lock();
+ wined3d_volume_incref(volume->wined3d_volume);
+ wined3d_mutex_unlock();
+ }
+
+ return refcount;
+}
+
+static ULONG WINAPI d3d9_volume_Release(IDirect3DVolume9 *iface)
+{
+ struct d3d9_volume *volume = impl_from_IDirect3DVolume9(iface);
+ ULONG refcount;
+
+ TRACE("iface %p.\n", iface);
+
+ if (volume->forwardReference)
+ {
+ TRACE("Forwarding to %p.\n", volume->forwardReference);
+ return IUnknown_Release(volume->forwardReference);
+ }
+
+ refcount = InterlockedDecrement(&volume->refcount);
+ TRACE("%p decreasing refcount to %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ wined3d_mutex_lock();
+ wined3d_volume_decref(volume->wined3d_volume);
+ wined3d_mutex_unlock();
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI d3d9_volume_GetDevice(IDirect3DVolume9 *iface, IDirect3DDevice9 **device)
+{
+ struct d3d9_volume *volume = impl_from_IDirect3DVolume9(iface);
+ IDirect3DResource9 *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, device %p.\n", iface, device);
+
+ hr = IUnknown_QueryInterface(volume->forwardReference, &IID_IDirect3DResource9, (void **)&resource);
+ if (SUCCEEDED(hr))
+ {
+ hr = IDirect3DResource9_GetDevice(resource, device);
+ IDirect3DResource9_Release(resource);
+
+ TRACE("Returning device %p.\n", *device);
+ }
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_volume_SetPrivateData(IDirect3DVolume9 *iface, REFGUID guid,
+ const void *data, DWORD data_size, DWORD flags)
+{
+ struct d3d9_volume *volume = impl_from_IDirect3DVolume9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
+ iface, debugstr_guid(guid), data, data_size, flags);
+
+ wined3d_mutex_lock();
+ resource = wined3d_volume_get_resource(volume->wined3d_volume);
+ hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_volume_GetPrivateData(IDirect3DVolume9 *iface, REFGUID guid,
+ void *data, DWORD *data_size)
+{
+ struct d3d9_volume *volume = impl_from_IDirect3DVolume9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, data %p, data_size %p.\n",
+ iface, debugstr_guid(guid), data, data_size);
+
+ wined3d_mutex_lock();
+ resource = wined3d_volume_get_resource(volume->wined3d_volume);
+ hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_volume_FreePrivateData(IDirect3DVolume9 *iface, REFGUID guid)
+{
+ struct d3d9_volume *volume = impl_from_IDirect3DVolume9(iface);
+ struct wined3d_resource *resource;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
+
+ wined3d_mutex_lock();
+ resource = wined3d_volume_get_resource(volume->wined3d_volume);
+ hr = wined3d_resource_free_private_data(resource, guid);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_volume_GetContainer(IDirect3DVolume9 *iface, REFIID riid, void **container)
+{
+ struct d3d9_volume *volume = impl_from_IDirect3DVolume9(iface);
+ HRESULT hr;
+
+ TRACE("iface %p, riid %s, container %p.\n", iface, debugstr_guid(riid), container);
+
+ if (!volume->container)
+ return E_NOINTERFACE;
+
+ hr = IUnknown_QueryInterface(volume->container, riid, container);
+
+ TRACE("Returning %p,\n", *container);
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_volume_GetDesc(IDirect3DVolume9 *iface, D3DVOLUME_DESC *desc)
+{
+ struct d3d9_volume *volume = impl_from_IDirect3DVolume9(iface);
+ struct wined3d_resource_desc wined3d_desc;
+ struct wined3d_resource *wined3d_resource;
+
+ TRACE("iface %p, desc %p.\n", iface, desc);
+
+ wined3d_mutex_lock();
+ wined3d_resource = wined3d_volume_get_resource(volume->wined3d_volume);
+ wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
+ wined3d_mutex_unlock();
+
+ desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
+ desc->Type = wined3d_desc.resource_type;
+ desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
+ desc->Pool = wined3d_desc.pool;
+ desc->Width = wined3d_desc.width;
+ desc->Height = wined3d_desc.height;
+ desc->Depth = wined3d_desc.depth;
+
+ return D3D_OK;
+}
+
+static HRESULT WINAPI d3d9_volume_LockBox(IDirect3DVolume9 *iface,
+ D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags)
+{
+ struct d3d9_volume *volume = impl_from_IDirect3DVolume9(iface);
+ struct wined3d_map_desc map_desc;
+ HRESULT hr;
+
+ TRACE("iface %p, locked_box %p, box %p, flags %#x.\n",
+ iface, locked_box, box, flags);
+
+ wined3d_mutex_lock();
+ hr = wined3d_volume_map(volume->wined3d_volume, &map_desc, (const struct wined3d_box *)box, flags);
+ wined3d_mutex_unlock();
+
+ locked_box->RowPitch = map_desc.row_pitch;
+ locked_box->SlicePitch = map_desc.slice_pitch;
+ locked_box->pBits = map_desc.data;
+
+ return hr;
+}
+
+static HRESULT WINAPI d3d9_volume_UnlockBox(IDirect3DVolume9 *iface)
+{
+ struct d3d9_volume *volume = impl_from_IDirect3DVolume9(iface);
+ HRESULT hr;
+
+ TRACE("iface %p.\n", iface);
+
+ wined3d_mutex_lock();
+ hr = wined3d_volume_unmap(volume->wined3d_volume);
+ wined3d_mutex_unlock();
+
+ return hr;
+}
+
+static const struct IDirect3DVolume9Vtbl d3d9_volume_vtbl =
+{
+ /* IUnknown */
+ d3d9_volume_QueryInterface,
+ d3d9_volume_AddRef,
+ d3d9_volume_Release,
+ /* IDirect3DVolume9 */
+ d3d9_volume_GetDevice,
+ d3d9_volume_SetPrivateData,
+ d3d9_volume_GetPrivateData,
+ d3d9_volume_FreePrivateData,
+ d3d9_volume_GetContainer,
+ d3d9_volume_GetDesc,
+ d3d9_volume_LockBox,
+ d3d9_volume_UnlockBox,
+};
+
+static void STDMETHODCALLTYPE volume_wined3d_object_destroyed(void *parent)
+{
+ HeapFree(GetProcessHeap(), 0, parent);
+}
+
+static const struct wined3d_parent_ops d3d9_volume_wined3d_parent_ops =
+{
+ volume_wined3d_object_destroyed,
+};
+
+HRESULT volume_init(struct d3d9_volume *volume, struct d3d9_device *device, UINT width, UINT height,
+ UINT depth, DWORD usage, enum wined3d_format_id format, enum wined3d_pool pool
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void *pvClientMem
+#endif
+)
+{
+ HRESULT hr;
+
+ volume->IDirect3DVolume9_iface.lpVtbl = &d3d9_volume_vtbl;
+ volume->refcount = 1;
+
+ hr = wined3d_volume_create(device->wined3d_device, width, height, depth, usage & WINED3DUSAGE_MASK,
+ format, pool, volume, &d3d9_volume_wined3d_parent_ops, &volume->wined3d_volume
+#ifdef VBOX_WITH_WDDM
+ , shared_handle
+ , pvClientMem
+#endif
+ );
+ if (FAILED(hr))
+ {
+ WARN("Failed to create wined3d volume, hr %#x.\n", hr);
+ return hr;
+ }
+
+ return D3D_OK;
+}
+
+#ifdef VBOX_WITH_WDDM
+struct d3d9_volume *unsafe_impl_from_IDirect3DVolume9(IDirect3DVolume9 *iface)
+{
+ if (!iface)
+ return NULL;
+ assert(iface->lpVtbl == (const IDirect3DVolume9Vtbl *)&d3d9_volume_vtbl);
+ return CONTAINING_RECORD(iface, struct d3d9_volume, IDirect3DVolume9_iface);
+}
+#endif
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/Makefile.kup b/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/Makefile.kup
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/d3d8.rc b/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/d3d8.rc
new file mode 100644
index 00000000..6829279d
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/d3d8.rc
@@ -0,0 +1,64 @@
+/* $Id: d3d8.rc $ */
+/** @file
+ * VBoxD3D8 - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2009-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE 0x09, 0x01
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK 0x3fL
+ FILEFLAGS 0x0L
+ FILEOS 0x40004L
+ FILETYPE 0x3L
+ FILESUBTYPE 0x4L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox D3D8 switcher\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "D3D8\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "D3D8.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT " Guest Additions\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+1 RCDATA
+BEGIN
+// Machine dependent parameters
+ 17, // Height of vertical thumb
+ 17, // Width of horizontal thumb
+ 2, // Icon horiz compression factor
+ 2, // Icon vert compression factor
+ 1, // Cursor horz compression factor
+ 1, // Cursor vert compression factor
+ 0, // Kanji window height
+ 1, // cxBorder (thickness of vertical lines)
+ 1 // cyBorder (thickness of horizontal lines)
+END
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/d3d8_main.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/d3d8_main.c
new file mode 100644
index 00000000..cff6129d
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/d3d8_main.c
@@ -0,0 +1,104 @@
+/* $Id: d3d8_main.c $ */
+
+/** @file
+ * VBox D3D8 dll switcher
+ */
+
+/*
+ * Copyright (C) 2009 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "d3d8.h"
+#include "switcher.h"
+
+typedef HRESULT (WINAPI *D3D8GetSWInfoProc)(void);
+typedef void (WINAPI *DebugSetMuteProc)(void);
+typedef IDirect3D8* (WINAPI *Direct3DCreate8Proc)(UINT SDKVersion);
+typedef HRESULT (WINAPI *ValidatePixelShaderProc)(DWORD* pixelshader, DWORD* reserved1, BOOL bool, DWORD* toto);
+typedef HRESULT (WINAPI *ValidateVertexShaderProc)(DWORD* vertexshader, DWORD* reserved1, DWORD* reserved2, BOOL bool, DWORD* toto);
+
+static HRESULT WINAPI vboxD3D8GetSWInfoStub(void)
+{
+ return E_FAIL;
+}
+
+static void WINAPI vboxDebugSetMuteStub(void)
+{
+
+}
+
+static IDirect3D8* WINAPI vboxDirect3DCreate8Stub(UINT SDKVersion)
+{
+ return NULL;
+}
+
+static HRESULT WINAPI vboxValidatePixelShaderStub(DWORD* pixelshader, DWORD* reserved1, BOOL bool, DWORD* toto)
+{
+ return E_FAIL;
+}
+
+static HRESULT WINAPI vboxValidateVertexShaderStub(DWORD* vertexshader, DWORD* reserved1, DWORD* reserved2, BOOL bool, DWORD* toto)
+{
+ return E_FAIL;
+}
+
+typedef struct _D3D8ExTag
+{
+ int initialized;
+ const char *vboxName;
+ const char *msName;
+ D3D8GetSWInfoProc pD3D8GetSWInfo;
+ DebugSetMuteProc pDebugSetMute;
+ Direct3DCreate8Proc pDirect3DCreate8;
+ ValidatePixelShaderProc pValidatePixelShader;
+ ValidateVertexShaderProc pValidateVertexShader;
+} D3D8Export;
+
+static D3D8Export g_swd3d8 = {0, "VBoxD3D8.dll", "MSD3D8.dll",};
+
+void FillD3DExports(HANDLE hDLL)
+{
+ SW_FILLPROC(g_swd3d8, hDLL, D3D8GetSWInfo);
+ SW_FILLPROC(g_swd3d8, hDLL, DebugSetMute);
+ SW_FILLPROC(g_swd3d8, hDLL, Direct3DCreate8);
+ SW_FILLPROC(g_swd3d8, hDLL, ValidatePixelShader);
+ SW_FILLPROC(g_swd3d8, hDLL, ValidateVertexShader);
+}
+
+HRESULT WINAPI D3D8GetSWInfo(void)
+{
+ SW_CHECKRET(g_swd3d8, D3D8GetSWInfo, E_FAIL);
+ return g_swd3d8.pD3D8GetSWInfo();
+}
+
+void WINAPI DebugSetMute(void)
+{
+ SW_CHECKCALL(g_swd3d8, DebugSetMute);
+ g_swd3d8.pDebugSetMute();
+}
+
+IDirect3D8* WINAPI Direct3DCreate8(UINT SDKVersion)
+{
+ SW_CHECKRET(g_swd3d8, Direct3DCreate8, NULL);
+ return g_swd3d8.pDirect3DCreate8(SDKVersion);
+}
+
+HRESULT WINAPI ValidatePixelShader(DWORD* pixelshader, DWORD* reserved1, BOOL bool, DWORD* toto)
+{
+ SW_CHECKRET(g_swd3d8, ValidatePixelShader, E_FAIL);
+ return g_swd3d8.pValidatePixelShader(pixelshader, reserved1, bool, toto);
+}
+
+HRESULT WINAPI ValidateVertexShader(DWORD* vertexshader, DWORD* reserved1, DWORD* reserved2, BOOL bool, DWORD* toto)
+{
+ SW_CHECKRET(g_swd3d8, ValidateVertexShader, E_FAIL)
+ return g_swd3d8.pValidateVertexShader(vertexshader, reserved1, reserved2, bool, toto);
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/d3d9.rc b/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/d3d9.rc
new file mode 100644
index 00000000..4387c618
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/d3d9.rc
@@ -0,0 +1,64 @@
+/* $Id: d3d9.rc $ */
+/** @file
+ * VBoxD3D9 - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2009-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE 0x09, 0x01
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK 0x3fL
+ FILEFLAGS 0x0L
+ FILEOS 0x40004L
+ FILETYPE 0x3L
+ FILESUBTYPE 0x4L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox D3D9 switcher\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "D3D9\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "D3D9.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT " Guest Additions\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+1 RCDATA
+BEGIN
+// Machine dependent parameters
+ 17, // Height of vertical thumb
+ 17, // Width of horizontal thumb
+ 2, // Icon horiz compression factor
+ 2, // Icon vert compression factor
+ 1, // Cursor horz compression factor
+ 1, // Cursor vert compression factor
+ 0, // Kanji window height
+ 1, // cxBorder (thickness of vertical lines)
+ 1 // cyBorder (thickness of horizontal lines)
+END
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/d3d9_main.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/d3d9_main.c
new file mode 100644
index 00000000..f3df1756
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/d3d9_main.c
@@ -0,0 +1,195 @@
+/* $Id: d3d9_main.c $ */
+
+/** @file
+ * VBox D3D8 dll switcher
+ */
+
+/*
+ * Copyright (C) 2009 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "d3d9.h"
+#include "switcher.h"
+
+typedef void (WINAPI *DebugSetMuteProc)(void);
+typedef IDirect3D9* (WINAPI *Direct3DCreate9Proc)(UINT SDKVersion);
+typedef HRESULT (WINAPI *Direct3DCreate9ExProc)(UINT SDKVersion, IDirect3D9Ex **direct3d9ex);
+/* @todo: this does not return a value according to MSDN */
+typedef void* (WINAPI *Direct3DShaderValidatorCreate9Proc)(void);
+typedef int (WINAPI *D3DPERF_BeginEventProc)(D3DCOLOR color, LPCWSTR name);
+typedef int (WINAPI *D3DPERF_EndEventProc)(void);
+typedef DWORD (WINAPI *D3DPERF_GetStatusProc)(void);
+typedef void (WINAPI *D3DPERF_SetOptionsProc)(DWORD options);
+typedef BOOL (WINAPI *D3DPERF_QueryRepeatFrameProc)(void);
+typedef void (WINAPI *D3DPERF_SetMarkerProc)(D3DCOLOR color, LPCWSTR name);
+typedef void (WINAPI *D3DPERF_SetRegionProc)(D3DCOLOR color, LPCWSTR name);
+
+static void WINAPI vboxDebugSetMuteStub(void)
+{
+}
+
+static IDirect3D9* WINAPI vboxDirect3DCreate9Stub(UINT SDKVersion)
+{
+ return NULL;
+}
+
+static HRESULT WINAPI vboxDirect3DCreate9ExStub(UINT SDKVersion, IDirect3D9Ex **direct3d9ex)
+{
+ if (direct3d9ex)
+ *direct3d9ex = NULL;
+ return E_FAIL;
+}
+
+static void* WINAPI vboxDirect3DShaderValidatorCreate9Stub(void)
+{
+ return NULL;
+}
+
+static int WINAPI vboxD3DPERF_BeginEventStub(D3DCOLOR color, LPCWSTR name)
+{
+ return 0;
+}
+
+static int WINAPI vboxD3DPERF_EndEventStub(void)
+{
+ return 0;
+}
+
+static DWORD WINAPI vboxD3DPERF_GetStatusStub(void)
+{
+ return 0;
+}
+
+static void WINAPI vboxD3DPERF_SetOptionsStub(DWORD options)
+{
+
+}
+
+static BOOL WINAPI vboxD3DPERF_QueryRepeatFrameStub(void)
+{
+ return 0;
+}
+
+static void WINAPI vboxD3DPERF_SetMarkerStub(D3DCOLOR color, LPCWSTR name)
+{
+
+}
+
+static void WINAPI vboxD3DPERF_SetRegionStub(D3DCOLOR color, LPCWSTR name)
+{
+
+}
+
+
+typedef struct _D3D9ExTag
+{
+ int initialized;
+ const char *vboxName;
+ const char *msName;
+ DebugSetMuteProc pDebugSetMute;
+ Direct3DCreate9Proc pDirect3DCreate9;
+ Direct3DCreate9ExProc pDirect3DCreate9Ex;
+ Direct3DShaderValidatorCreate9Proc pDirect3DShaderValidatorCreate9;
+ D3DPERF_BeginEventProc pD3DPERF_BeginEvent;
+ D3DPERF_EndEventProc pD3DPERF_EndEvent;
+ D3DPERF_GetStatusProc pD3DPERF_GetStatus;
+ D3DPERF_SetOptionsProc pD3DPERF_SetOptions;
+ D3DPERF_QueryRepeatFrameProc pD3DPERF_QueryRepeatFrame;
+ D3DPERF_SetMarkerProc pD3DPERF_SetMarker;
+ D3DPERF_SetRegionProc pD3DPERF_SetRegion;
+} D3D9Export;
+
+#ifdef VBOX_WDDM_WOW64
+static D3D9Export g_swd3d9 = {0, "VBoxD3D9-x86.dll", "MSD3D9.dll",};
+#else
+static D3D9Export g_swd3d9 = {0, "VBoxD3D9.dll", "MSD3D9.dll",};
+#endif
+
+void FillD3DExports(HANDLE hDLL)
+{
+ SW_FILLPROC(g_swd3d9, hDLL, DebugSetMute);
+ SW_FILLPROC(g_swd3d9, hDLL, Direct3DCreate9);
+ SW_FILLPROC(g_swd3d9, hDLL, Direct3DCreate9Ex);
+ SW_FILLPROC(g_swd3d9, hDLL, Direct3DShaderValidatorCreate9);
+ SW_FILLPROC(g_swd3d9, hDLL, D3DPERF_BeginEvent);
+ SW_FILLPROC(g_swd3d9, hDLL, D3DPERF_EndEvent);
+ SW_FILLPROC(g_swd3d9, hDLL, D3DPERF_GetStatus);
+ SW_FILLPROC(g_swd3d9, hDLL, D3DPERF_SetOptions);
+ SW_FILLPROC(g_swd3d9, hDLL, D3DPERF_QueryRepeatFrame);
+ SW_FILLPROC(g_swd3d9, hDLL, D3DPERF_SetMarker);
+ SW_FILLPROC(g_swd3d9, hDLL, D3DPERF_SetRegion);
+}
+
+void WINAPI DebugSetMute(void)
+{
+ SW_CHECKCALL(g_swd3d9, DebugSetMute);
+ g_swd3d9.pDebugSetMute();
+}
+
+IDirect3D9* WINAPI Direct3DCreate9(UINT SDKVersion)
+{
+ SW_CHECKRET(g_swd3d9, Direct3DCreate9, NULL);
+ return g_swd3d9.pDirect3DCreate9(SDKVersion);
+}
+
+HRESULT WINAPI Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex **direct3d9ex)
+{
+ SW_CHECKRET(g_swd3d9, Direct3DCreate9Ex, E_FAIL);
+ return g_swd3d9.pDirect3DCreate9Ex(SDKVersion, direct3d9ex);
+}
+
+void* WINAPI Direct3DShaderValidatorCreate9(void)
+{
+ SW_CHECKRET(g_swd3d9, Direct3DShaderValidatorCreate9, NULL);
+ return g_swd3d9.pDirect3DShaderValidatorCreate9();
+}
+
+int WINAPI D3DPERF_BeginEvent(D3DCOLOR color, LPCWSTR name)
+{
+ SW_CHECKRET(g_swd3d9, D3DPERF_BeginEvent, -1);
+ return g_swd3d9.pD3DPERF_BeginEvent(color, name);
+}
+
+int WINAPI D3DPERF_EndEvent(void)
+{
+ SW_CHECKRET(g_swd3d9, D3DPERF_EndEvent, -1);
+ return g_swd3d9.pD3DPERF_EndEvent();
+}
+
+DWORD WINAPI D3DPERF_GetStatus(void)
+{
+ SW_CHECKRET(g_swd3d9, D3DPERF_EndEvent, 0);
+ return g_swd3d9.pD3DPERF_GetStatus();
+}
+
+void WINAPI D3DPERF_SetOptions(DWORD options)
+{
+ SW_CHECKCALL(g_swd3d9, D3DPERF_SetOptions);
+ g_swd3d9.pD3DPERF_SetOptions(options);
+}
+
+BOOL WINAPI D3DPERF_QueryRepeatFrame(void)
+{
+ SW_CHECKRET(g_swd3d9, D3DPERF_QueryRepeatFrame, FALSE);
+ return g_swd3d9.pD3DPERF_QueryRepeatFrame();
+}
+
+void WINAPI D3DPERF_SetMarker(D3DCOLOR color, LPCWSTR name)
+{
+ SW_CHECKCALL(g_swd3d9, D3DPERF_SetMarker);
+ g_swd3d9.pD3DPERF_SetMarker(color, name);
+}
+
+void WINAPI D3DPERF_SetRegion(D3DCOLOR color, LPCWSTR name)
+{
+ SW_CHECKCALL(g_swd3d9, D3DPERF_SetRegion);
+ g_swd3d9.pD3DPERF_SetRegion(color, name);
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/sw_common.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/sw_common.c
new file mode 100644
index 00000000..0c26a5d9
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/sw_common.c
@@ -0,0 +1,134 @@
+/* $Id: sw_common.c $ */
+/** @file
+ * VBox D3D8/9 dll switcher
+ */
+
+/*
+ * Copyright (C) 2009-2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include "switcher.h"
+
+static char* gsBlackListExe[] = {"Dwm.exe", "java.exe", "javaw.exe", "javaws.exe"/*, "taskeng.exe"*/, NULL};
+static char* gsBlackListDll[] = {"awt.dll", "wpfgfx_v0400.dll", "wpfgfx_v0300.dll", NULL};
+
+/**
+ * Loads a system DLL.
+ *
+ * @returns Module handle or NULL
+ * @param pszName The DLL name.
+ */
+static HMODULE loadSystemDll(const char *pszName)
+{
+ char szPath[MAX_PATH];
+ UINT cchPath = GetSystemDirectoryA(szPath, sizeof(szPath));
+ size_t cbName = strlen(pszName) + 1;
+ if (cchPath + 1 + cbName > sizeof(szPath))
+ return NULL;
+ szPath[cchPath] = '\\';
+ memcpy(&szPath[cchPath + 1], pszName, cbName);
+ return LoadLibraryA(szPath);
+}
+
+/* Checks if 3D is enabled for VM and it works on host machine */
+BOOL isVBox3DEnabled(void)
+{
+ DrvValidateVersionProc pDrvValidateVersion;
+ HANDLE hDLL;
+ BOOL result = FALSE;
+
+#ifdef VBOX_WDDM_WOW64
+ hDLL = loadSystemDll("VBoxOGL-x86.dll");
+#else
+ hDLL = loadSystemDll("VBoxOGL.dll");
+#endif
+
+ /* note: this isn't really needed as our library will refuse to load if it can't connect to host.
+ so it's in case we'd change it one day.
+ */
+ pDrvValidateVersion = (DrvValidateVersionProc) GetProcAddress(hDLL, "DrvValidateVersion");
+ if (pDrvValidateVersion)
+ {
+ result = pDrvValidateVersion(0);
+ }
+ FreeLibrary(hDLL);
+ return result;
+}
+
+BOOL checkOptionsDll(void)
+{
+ int i;
+ for (i=0; gsBlackListDll[i]; ++i)
+ {
+ if (GetModuleHandleA(gsBlackListDll[i]))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOL checkOptionsExe(void)
+{
+ char name[1000];
+ char *filename = name, *pName;
+ int i;
+
+ if (!GetModuleFileName(NULL, name, 1000))
+ return TRUE;
+
+ /*Extract filename*/
+ for (pName=name; *pName; ++pName)
+ {
+ switch (*pName)
+ {
+ case ':':
+ case '\\':
+ case '/':
+ filename = pName + 1;
+ break;
+ }
+ }
+
+ for (i=0; gsBlackListExe[i]; ++i)
+ {
+ if (!stricmp(filename, gsBlackListExe[i]))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOL checkOptions(void)
+{
+ if (!checkOptionsDll())
+ return FALSE;
+
+ if (!checkOptionsExe())
+ return FALSE;
+
+ return TRUE;
+}
+
+void InitD3DExports(const char *vboxName, const char *msName)
+{
+ const char *dllName;
+ HANDLE hDLL;
+
+ if (isVBox3DEnabled() && checkOptions())
+ dllName = vboxName;
+ else
+ dllName = msName;
+
+ hDLL = loadSystemDll(dllName);
+ FillD3DExports(hDLL);
+}
+
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/sw_d3d8.def b/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/sw_d3d8.def
new file mode 100644
index 00000000..09e43604
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/sw_d3d8.def
@@ -0,0 +1,6 @@
+EXPORTS
+ D3D8GetSWInfo
+ DebugSetMute
+ Direct3DCreate8
+ ValidatePixelShader
+ ValidateVertexShader
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/sw_d3d9.def b/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/sw_d3d9.def
new file mode 100644
index 00000000..de7f89d4
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/sw_d3d9.def
@@ -0,0 +1,12 @@
+EXPORTS
+ Direct3DShaderValidatorCreate9@0=Direct3DShaderValidatorCreate9
+ D3DPERF_BeginEvent@8=D3DPERF_BeginEvent
+ D3DPERF_EndEvent@0=D3DPERF_EndEvent
+ D3DPERF_GetStatus@0=D3DPERF_GetStatus
+ D3DPERF_QueryRepeatFrame@0=D3DPERF_QueryRepeatFrame
+ D3DPERF_SetMarker@8=D3DPERF_SetMarker
+ D3DPERF_SetOptions@4=D3DPERF_SetOptions
+ D3DPERF_SetRegion@8=D3DPERF_SetRegion
+ DebugSetMute@0=DebugSetMute
+ Direct3DCreate9@4=Direct3DCreate9
+ Direct3DCreate9Ex@8=Direct3DCreate9Ex
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/sw_d3d9xpdm.def b/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/sw_d3d9xpdm.def
new file mode 100644
index 00000000..454c51b7
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/sw_d3d9xpdm.def
@@ -0,0 +1,12 @@
+EXPORTS
+ Direct3DShaderValidatorCreate9
+ D3DPERF_BeginEvent
+ D3DPERF_EndEvent
+ D3DPERF_GetStatus
+ D3DPERF_QueryRepeatFrame
+ D3DPERF_SetMarker
+ D3DPERF_SetOptions
+ D3DPERF_SetRegion
+ DebugSetMute
+ Direct3DCreate9
+ Direct3DCreate9Ex
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/switcher.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/switcher.h
new file mode 100644
index 00000000..45e18efc
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/switcher/switcher.h
@@ -0,0 +1,54 @@
+/* $Id: switcher.h $ */
+
+/** @file
+ * VBox D3D8/9 dll switcher
+ */
+
+/*
+ * Copyright (C) 2009 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef ___CROPENGL_SWITCHER_H_
+#define ___CROPENGL_SWITCHER_H_
+
+typedef BOOL (APIENTRY *DrvValidateVersionProc)(DWORD version);
+
+#define SW_FILLPROC(dispatch, hdll, name) \
+ dispatch.p##name = ((hdll) != NULL) ? (name##Proc) GetProcAddress((hdll), #name) : vbox##name##Stub;
+
+#define SW_DISPINIT(dispatch) \
+ { \
+ if (!dispatch.initialized) \
+ { \
+ InitD3DExports(dispatch.vboxName, dispatch.msName); \
+ dispatch.initialized = 1; \
+ } \
+ }
+
+#define SW_CHECKRET(dispatch, func, failret) \
+ { \
+ SW_DISPINIT(dispatch) \
+ if (!dispatch.p##func) \
+ return failret; \
+ }
+
+#define SW_CHECKCALL(dispatch, func) \
+ { \
+ SW_DISPINIT(dispatch) \
+ if (!dispatch.p##func) return; \
+ }
+
+extern BOOL IsVBox3DEnabled(void);
+extern BOOL CheckOptions(void);
+extern void FillD3DExports(HANDLE hDLL);
+extern void InitD3DExports(const char *vboxName, const char *msName);
+
+#endif /* #ifndef ___CROPENGL_SWITCHER_H_ */
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/Makefile.kup b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/Makefile.kup
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/VBoxDbgGl.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/VBoxDbgGl.c
new file mode 100644
index 00000000..f183c2e1
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/VBoxDbgGl.c
@@ -0,0 +1,389 @@
+/* $Id: VBoxDbgGl.c $ */
+
+/** @file
+ * VBox wine & ogl debugging stuff
+ */
+
+/*
+ * Copyright (C) 2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
+#ifdef HAVE_FLOAT_H
+# include <float.h>
+#endif
+
+#include "../wined3d/wined3d_private.h"
+
+#include "VBoxDbgGl.h"
+
+#include <iprt/ctype.h>
+
+
+DWORD g_VBoxDbgGlFCheckDrawPrim = 0;
+DWORD g_VBoxDbgGlFBreakDrawPrimIfCanNotMatch = 0;
+
+void dbglFree(void *pvData)
+{
+ HeapFree(GetProcessHeap(), 0, pvData);
+}
+
+void* dbglAlloc(DWORD cbSize)
+{
+ return HeapAlloc(GetProcessHeap(), 0, cbSize);
+}
+
+GLint dbglFmtGetNumComponents(GLenum format)
+{
+ switch(format)
+ {
+ case GL_COLOR_INDEX:
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ case GL_ALPHA:
+ return 1;
+ case GL_RGB:
+ case GL_BGR:
+ return 3;
+ case GL_RGBA:
+ case GL_BGRA:
+ return 4;
+ case GL_LUMINANCE:
+ return 1;
+ case GL_LUMINANCE_ALPHA:
+ return 2;
+ default:
+ Assert(0);
+ return 1;
+ }
+}
+
+GLint dbglFmtGetBpp(GLenum format, GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE_3_3_2:
+ return 8;
+ case GL_UNSIGNED_BYTE_2_3_3_REV:
+ return 8;
+ case GL_UNSIGNED_SHORT_5_6_5:
+ return 16;
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ return 16;
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ return 16;
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+ return 16;
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ return 16;
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ return 16;
+ case GL_UNSIGNED_INT_8_8_8_8:
+ return 32;
+ case GL_UNSIGNED_INT_8_8_8_8_REV:
+ return 32;
+ case GL_UNSIGNED_INT_10_10_10_2:
+ return 32;
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ return 32;
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ return dbglFmtGetNumComponents(format) * 8;
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ return dbglFmtGetNumComponents(format) * 16;
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_FLOAT:
+ return dbglFmtGetNumComponents(format) * 32;
+ case GL_DOUBLE:
+ return dbglFmtGetNumComponents(format) * 64;
+ case GL_2_BYTES:
+ return dbglFmtGetNumComponents(format) * 16;
+ case GL_3_BYTES:
+ return dbglFmtGetNumComponents(format) * 24;
+ case GL_4_BYTES:
+ return dbglFmtGetNumComponents(format) * 32;
+ default:
+ Assert(0);
+ return 8;
+ }
+}
+
+#define DBGL_OP(_op) gl##_op
+#define DBGL_FBO_OP(_op) (gl_info->fbo_ops.gl##_op)
+#define DBGL_EXT_OP(_op) (gl_info->gl_ops.ext.p_gl##_op)
+
+void dbglGetTexImage2D(const struct wined3d_gl_info *gl_info, GLint texTarget, GLint texName, GLint level, GLvoid **ppvImage, GLint *pw, GLint *ph, GLenum format, GLenum type)
+{
+ GLint ppb, pub, dstw, dsth, otex;
+ GLint pa, pr, psp, psr, ua, ur, usp, usr;
+ GLvoid *pvImage;
+ GLint rfb, dfb, rb, db;
+ GLint bpp = dbglFmtGetBpp(format, type);
+
+ DBGL_OP(GetIntegerv(GL_READ_FRAMEBUFFER_BINDING_EXT, &rfb));
+ DBGL_OP(GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, &dfb));
+ DBGL_OP(GetIntegerv(GL_READ_BUFFER, &rb));
+ DBGL_OP(GetIntegerv(GL_DRAW_BUFFER, &db));
+
+ DBGL_FBO_OP(BindFramebuffer)(GL_READ_FRAMEBUFFER_BINDING_EXT, 0);
+ DBGL_FBO_OP(BindFramebuffer)(GL_DRAW_FRAMEBUFFER_BINDING_EXT, 0);
+ DBGL_OP(ReadBuffer(GL_BACK));
+ DBGL_OP(DrawBuffer(GL_BACK));
+
+ DBGL_OP(GetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING_ARB, &ppb));
+ DBGL_OP(GetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING_ARB, &pub));
+ DBGL_OP(GetIntegerv(GL_TEXTURE_BINDING_2D, &otex));
+
+ DBGL_OP(GetIntegerv(GL_PACK_ROW_LENGTH, &pr));
+ DBGL_OP(GetIntegerv(GL_PACK_ALIGNMENT, &pa));
+ DBGL_OP(GetIntegerv(GL_PACK_SKIP_PIXELS, &psp));
+ DBGL_OP(GetIntegerv(GL_PACK_SKIP_ROWS, &psr));
+
+ DBGL_OP(GetIntegerv(GL_UNPACK_ROW_LENGTH, &ur));
+ DBGL_OP(GetIntegerv(GL_UNPACK_ALIGNMENT, &ua));
+ DBGL_OP(GetIntegerv(GL_UNPACK_SKIP_PIXELS, &usp));
+ DBGL_OP(GetIntegerv(GL_UNPACK_SKIP_ROWS, &usr));
+
+ DBGL_OP(BindTexture(texTarget, texName));
+ DBGL_OP(GetTexLevelParameteriv(texTarget, level, GL_TEXTURE_WIDTH, &dstw));
+ DBGL_OP(GetTexLevelParameteriv(texTarget, level, GL_TEXTURE_HEIGHT, &dsth));
+
+ DBGL_OP(PixelStorei(GL_PACK_ROW_LENGTH, 0));
+ DBGL_OP(PixelStorei(GL_PACK_ALIGNMENT, 1));
+ DBGL_OP(PixelStorei(GL_PACK_SKIP_PIXELS, 0));
+ DBGL_OP(PixelStorei(GL_PACK_SKIP_ROWS, 0));
+
+ DBGL_OP(PixelStorei(GL_UNPACK_ROW_LENGTH, 0));
+ DBGL_OP(PixelStorei(GL_UNPACK_ALIGNMENT, 1));
+ DBGL_OP(PixelStorei(GL_UNPACK_SKIP_PIXELS, 0));
+ DBGL_OP(PixelStorei(GL_UNPACK_SKIP_ROWS, 0));
+
+ DBGL_EXT_OP(BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
+ DBGL_EXT_OP(BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+
+ pvImage = dbglAlloc(((bpp*dstw + 7) >> 3)*dsth);
+ DBGL_OP(GetTexImage(texTarget, level, format, type, pvImage));
+
+ DBGL_OP(BindTexture(texTarget, otex));
+
+ DBGL_OP(PixelStorei(GL_PACK_ROW_LENGTH, pr));
+ DBGL_OP(PixelStorei(GL_PACK_ALIGNMENT, pa));
+ DBGL_OP(PixelStorei(GL_PACK_SKIP_PIXELS, psp));
+ DBGL_OP(PixelStorei(GL_PACK_SKIP_ROWS, psr));
+
+ DBGL_OP(PixelStorei(GL_UNPACK_ROW_LENGTH, ur));
+ DBGL_OP(PixelStorei(GL_UNPACK_ALIGNMENT, ua));
+ DBGL_OP(PixelStorei(GL_UNPACK_SKIP_PIXELS, usp));
+ DBGL_OP(PixelStorei(GL_UNPACK_SKIP_ROWS, usr));
+
+ DBGL_EXT_OP(BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ppb));
+ DBGL_EXT_OP(BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pub));
+
+ DBGL_FBO_OP(BindFramebuffer)(GL_READ_FRAMEBUFFER_BINDING_EXT, rfb);
+ DBGL_FBO_OP(BindFramebuffer)(GL_DRAW_FRAMEBUFFER_BINDING_EXT, dfb);
+ DBGL_OP(ReadBuffer(rb));
+ DBGL_OP(DrawBuffer(db));
+
+ *ppvImage = pvImage;
+ *pw = dstw;
+ *ph = dsth;
+}
+
+DECLEXPORT(void) dbglPrint(const char *format, ... )
+{
+ va_list args;
+ static char txt[8092];
+
+ va_start( args, format );
+ vsprintf( txt, format, args );
+
+ OutputDebugString(txt);
+}
+
+void dbglDumpImage2D(const char* pszDesc, const void *pvData, uint32_t width, uint32_t height, uint32_t bpp, uint32_t pitch)
+{
+ dbglPrint("<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">%s</exec>, ( !vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d )\n",
+ pvData, width, height, bpp, pitch,
+ pszDesc,
+ pvData, width, height, bpp, pitch);
+}
+
+void dbglDumpTexImage2D(const struct wined3d_gl_info *gl_info, const char* pszDesc, GLint texTarget, GLint texName, GLint level, GLboolean fBreak)
+{
+ GLvoid *pvImage;
+ GLint w, h;
+ dbglGetTexImage2D(gl_info, texTarget, texName, level, &pvImage, &w, &h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV);
+ dbglPrint("%s target(%d), name(%d), width(%d), height(%d)\n", pszDesc, texTarget, texName, w, h);
+ dbglDumpImage2D("texture data", pvImage, w, h, 32, (32 * w)/8);
+ if (fBreak)
+ {
+ Assert(0);
+ }
+ dbglFree(pvImage);
+}
+
+void dbglCmpTexImage2D(const struct wined3d_gl_info *gl_info, const char* pszDesc, GLint texTarget, GLint texName, GLint level, void *pvImage,
+ GLint width, GLint height, GLenum format, GLenum type)
+{
+ GLvoid *pvTexImg;
+ GLint w, h;
+ GLint bpp = dbglFmtGetBpp(format, type);
+ GLint pitch, texPitch;
+
+ dbglGetTexImage2D(gl_info, texTarget, texName, level, &pvTexImg, &w, &h, format, type);
+
+ pitch = ((bpp * width + 7) >> 3)/8;
+ texPitch = ((bpp * w + 7) >> 3)/8;
+
+ if (w != width)
+ {
+ dbglPrint("width mismatch was %d, but expected %d\n", w, width);
+ dbglDumpImage2D("expected texture data:", pvImage, width, height, bpp, pitch);
+ dbglDumpImage2D("stored texture data:", pvTexImg, w, h, bpp, texPitch);
+
+ Assert(0);
+
+ dbglFree(pvTexImg);
+ return;
+ }
+ if (h != height)
+ {
+ dbglPrint("height mismatch was %d, but expected %d\n", h, height);
+ dbglDumpImage2D("expected texture data:", pvImage, width, height, bpp, pitch);
+ dbglDumpImage2D("stored texture data:", pvTexImg, w, h, bpp, texPitch);
+
+ Assert(0);
+
+ dbglFree(pvTexImg);
+ return;
+ }
+
+ if (memcmp(pvImage, pvTexImg, w * h * 4))
+ {
+ dbglPrint("tex data mismatch\n");
+ dbglDumpImage2D("expected texture data:", pvImage, width, height, bpp, pitch);
+ dbglDumpImage2D("stored texture data:", pvTexImg, w, h, bpp, texPitch);
+
+ Assert(0);
+ }
+
+ dbglFree(pvTexImg);
+}
+
+void dbglCheckTexUnits(const struct wined3d_gl_info *gl_info, struct wined3d_device *pDevice, BOOL fBreakIfCanNotMatch)
+{
+ int iStage;
+ GLint ActiveTexUnit = 0;
+ GLint CheckTexUnit = 0;
+ DBGL_OP(GetIntegerv(GL_ACTIVE_TEXTURE, &ActiveTexUnit));
+
+ Assert(ActiveTexUnit >= GL_TEXTURE0);
+ Assert(gl_info->limits.combined_samplers <= RT_ELEMENTS(pDevice->stateBlock->state.textures));
+ Assert(ActiveTexUnit < GL_TEXTURE0 + gl_info->limits.combined_samplers);
+
+ CheckTexUnit = ActiveTexUnit;
+
+ Assert(ActiveTexUnit == pDevice->contexts[0]->active_texture + GL_TEXTURE0);
+
+ for (iStage = 0; iStage < gl_info->limits.combined_samplers; ++iStage)
+ {
+ GLint curTex = 0;
+ int iLevel;
+ struct gl_texture *pGlTex;
+ const struct wined3d_texture *pTexture = (const struct wined3d_texture*)pDevice->stateBlock->state.textures[iStage];
+
+ if (CheckTexUnit != iStage + GL_TEXTURE0)
+ {
+ DBGL_EXT_OP(ActiveTextureARB(iStage + GL_TEXTURE0));
+ CheckTexUnit = iStage + GL_TEXTURE0;
+ }
+
+ DBGL_OP(GetIntegerv(GL_TEXTURE_BINDING_2D, &curTex));
+
+ if (!pTexture)
+ {
+ Assert(curTex == 0 || curTex == pDevice->dummy_texture_2d[iStage]);
+ continue;
+ }
+
+ if(pTexture->flags & WINED3D_TEXTURE_IS_SRGB)
+ {
+ Assert(0);
+ pGlTex = &pTexture->texture_srgb;
+ }
+ else
+ pGlTex = &pTexture->texture_rgb;
+
+ /* not implemented */
+ Assert(pTexture->target == GL_TEXTURE_2D);
+ Assert(curTex);
+ Assert(pGlTex->name);
+ Assert(pGlTex->name == curTex);
+ Assert(DBGL_OP(IsEnabled(pTexture->target)));
+
+ /* not implemented */
+ Assert(pTexture->layer_count == 1);
+
+ for (iLevel = 0; iLevel < (int)pTexture->level_count; ++iLevel)
+ {
+ struct wined3d_surface *surface = (struct wined3d_surface *)pTexture->sub_resources[iLevel];
+ Assert(surface);
+
+ Assert(surface->flags & SFLAG_INTEXTURE);
+
+ Assert(surface->texture_target == pTexture->target);
+ Assert(surface->texture_name == (pTexture->flags & WINED3D_TEXTURE_IS_SRGB) ? pTexture->texture_srgb.name : pTexture->texture_rgb.name);
+#if 0
+ if (pSurf->flags & SFLAG_INSYSMEM && !pSurf->Flags & SFLAG_PBO)
+ {
+ Assert(pSurf->resource.allocatedMemory);
+ /* we can match GPU & our state */
+ dbglCmpTexImage2D(gl_info, "matching tex data state", pSurf->texture_target, pSurf->texture_name, iLevel, pSurf->resource.allocatedMemory,
+ pSurf->currentDesc.Width, pSurf->currentDesc.Height, pSurf->resource.format_desc->glFormat, pSurf->resource.format_desc->glType);
+ }
+ else
+ {
+ GLint w,h;
+ if (fBreakIfCanNotMatch)
+ {
+ GLvoid* pvImage;
+ dbglGetTexImage2D(gl_info, pSurf->texture_target, pSurf->texture_name, iLevel, &pvImage, &w, &h, GL_BGRA, GL_UNSIGNED_BYTE);
+ Assert(w == pSurf->currentDesc.Width);
+ Assert(h == pSurf->currentDesc.Height);
+ dbglDumpImage2D("matching texture data", pvImage, w, h, 32, (32 * w)/8);
+ Assert(0);
+ dbglFree(pvImage);
+ }
+ else
+ {
+ /* just check width & height */
+ /* since we already asserted current texture binding, we can just quiry its parameters */
+ DBGL_OP(GetTexLevelParameteriv(pSurf->texture_target, iLevel, GL_TEXTURE_WIDTH, &w));
+ DBGL_OP(GetTexLevelParameteriv(pSurf->texture_target, iLevel, GL_TEXTURE_HEIGHT, &h));
+ Assert(w == pSurf->currentDesc.Width);
+ Assert(h == pSurf->currentDesc.Height);
+ }
+ }
+#endif
+ }
+ }
+
+ if (CheckTexUnit != ActiveTexUnit)
+ {
+ DBGL_EXT_OP(ActiveTextureARB(ActiveTexUnit));
+ }
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/VBoxDbgGl.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/VBoxDbgGl.h
new file mode 100644
index 00000000..d334cd7e
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/VBoxDbgGl.h
@@ -0,0 +1,43 @@
+/* $Id: VBoxDbgGl.h $ */
+
+/** @file
+ * VBox wine & ogl debugging stuff
+ */
+
+/*
+ * Copyright (C) 2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef ___VBoxDbgGl_h__
+#define ___VBoxDbgGl_h__
+
+//#include <windows.h>
+//#include "../wined3d/wined3d_gl.h"
+
+void dbglGetTexImage2D(const struct wined3d_gl_info *gl_info, GLint texTarget, GLint texName, GLint level, GLvoid **ppvImage, GLint *pw, GLint *ph, GLenum format, GLenum type);
+void dbglDumpTexImage2D(const struct wined3d_gl_info *gl_info, const char* pszDesc, GLint texTarget, GLint texName, GLint level, GLboolean fBreak);
+void dbglCmpTexImage2D(const struct wined3d_gl_info *gl_info, const char* pszDesc, GLint texTarget, GLint texName, GLint level, void *pvImage, GLint width, GLint height, GLenum format, GLenum type);
+void dbglCheckTexUnits(const struct wined3d_gl_info *gl_info, struct wined3d_device *pDevice, BOOL fBreakIfCanNotMatch);
+
+#ifdef DEBUG_misha
+#define DBGL_CHECK_DRAWPRIM(_gl_info, _pDevice) do { \
+ if (g_VBoxDbgGlFCheckDrawPrim) { \
+ dbglCheckTexUnits((_gl_info), (_pDevice), g_VBoxDbgGlFBreakDrawPrimIfCanNotMatch); \
+ } \
+ } while (0)
+#else
+#define DBGL_CHECK_DRAWPRIM(_gl_info, _pDevice) do {} while (0)
+#endif
+
+extern DWORD g_VBoxDbgGlFCheckDrawPrim;
+extern DWORD g_VBoxDbgGlFBreakDrawPrimIfCanNotMatch;
+
+#endif /* #ifndef ___VBoxDbgGl_h__ */
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/VBoxWineEx.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/VBoxWineEx.h
new file mode 100644
index 00000000..01a1573a
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/VBoxWineEx.h
@@ -0,0 +1,159 @@
+/** @file
+ *
+ * VBox extension to Wine D3D
+ *
+ * Copyright (C) 2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+#ifndef ___VBoxWineEx_h__
+#define ___VBoxWineEx_h__
+
+typedef enum
+{
+ VBOXWINEEX_SHRC_STATE_UNDEFINED = 0,
+ /* the underlying GL resource can not be used because it can be removed concurrently by other SHRC client */
+ VBOXWINEEX_SHRC_STATE_GL_DISABLE,
+ /* the given client is requested to delete the underlying GL resource on SHRC termination */
+ VBOXWINEEX_SHRC_STATE_GL_DELETE
+} VBOXWINEEX_SHRC_STATE;
+
+
+#ifndef IN_VBOXLIBWINE
+
+#define VBOXWINEEX_VERSION 1
+
+#ifndef IN_VBOXWINEEX
+# define VBOXWINEEX_DECL(_type) __declspec(dllimport) _type WINAPI
+# else
+# define VBOXWINEEX_DECL(_type) __declspec(dllexport) _type WINAPI
+#endif
+
+typedef VBOXWINEEX_DECL(HRESULT) FNVBOXWINEEXD3DDEV9_CREATETEXTURE(IDirect3DDevice9Ex *iface,
+ UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format,
+ D3DPOOL pool, IDirect3DTexture9 **texture, HANDLE *shared_handle,
+ void **pavClientMem);
+typedef FNVBOXWINEEXD3DDEV9_CREATETEXTURE *PFNVBOXWINEEXD3DDEV9_CREATETEXTURE;
+
+typedef VBOXWINEEX_DECL(HRESULT) FNVBOXWINEEXD3DDEV9_CREATECUBETEXTURE(IDirect3DDevice9Ex *iface,
+ UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format,
+ D3DPOOL pool, IDirect3DCubeTexture9 **texture, HANDLE *shared_handle,
+ void **pavClientMem);
+typedef FNVBOXWINEEXD3DDEV9_CREATECUBETEXTURE *PFNVBOXWINEEXD3DDEV9_CREATECUBETEXTURE;
+
+typedef VBOXWINEEX_DECL(HRESULT) FNVBOXWINEEXD3DDEV9_CREATEVOLUMETEXTURE(IDirect3DDevice9Ex *iface,
+ UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT Format, D3DPOOL Pool,
+ IDirect3DVolumeTexture9 **ppVolumeTexture, HANDLE *pSharedHandle,
+ void **pavClientMem);
+typedef FNVBOXWINEEXD3DDEV9_CREATEVOLUMETEXTURE *PFNVBOXWINEEXD3DDEV9_CREATEVOLUMETEXTURE;
+
+typedef VBOXWINEEX_DECL(HRESULT) FNVBOXWINEEXD3DDEV9_VOLBLT(IDirect3DDevice9Ex *iface,
+ IDirect3DVolume9 *pSourceVolume, IDirect3DVolume9 *pDestinationVolume,
+ const struct VBOXBOX3D *pSrcBoxArg,
+ const struct VBOXPOINT3D *pDstPoin3D);
+typedef FNVBOXWINEEXD3DDEV9_VOLBLT *PFNVBOXWINEEXD3DDEV9_VOLBLT;
+
+typedef VBOXWINEEX_DECL(HRESULT) FNVBOXWINEEXD3DDEV9_VOLTEXBLT(IDirect3DDevice9Ex *iface,
+ IDirect3DVolumeTexture9 *pSourceTexture, IDirect3DVolumeTexture9 *pDestinationTexture,
+ const struct VBOXBOX3D *pSrcBoxArg,
+ const struct VBOXPOINT3D *pDstPoin3D);
+typedef FNVBOXWINEEXD3DDEV9_VOLTEXBLT *PFNVBOXWINEEXD3DDEV9_VOLTEXBLT;
+
+typedef VBOXWINEEX_DECL(HRESULT) FNVBOXWINEEXD3DDEV9_FLUSH(IDirect3DDevice9Ex *iface);
+typedef FNVBOXWINEEXD3DDEV9_FLUSH *PFNVBOXWINEEXD3DDEV9_FLUSH;
+
+typedef VBOXWINEEX_DECL(HRESULT) FNVBOXWINEEXD3DDEV9_FLUSHTOHOST(IDirect3DDevice9Ex *iface);
+typedef FNVBOXWINEEXD3DDEV9_FLUSHTOHOST *PFNVBOXWINEEXD3DDEV9_FLUSHTOHOST;
+
+typedef VBOXWINEEX_DECL(HRESULT) FNVBOXWINEEXD3DDEV9_GETHOSTID(IDirect3DDevice9Ex *iface, int32_t *pi32Id);
+typedef FNVBOXWINEEXD3DDEV9_GETHOSTID *PFNVBOXWINEEXD3DDEV9_GETHOSTID;
+
+typedef VBOXWINEEX_DECL(HRESULT) FNVBOXWINEEXD3DDEV9_FINISH(IDirect3DDevice9Ex *iface);
+typedef FNVBOXWINEEXD3DDEV9_FINISH *PFNVBOXWINEEXD3DDEV9_FINISH;
+
+typedef VBOXWINEEX_DECL(HRESULT) FNVBOXWINEEXD3DDEV9_TERM(IDirect3DDevice9Ex *iface);
+typedef FNVBOXWINEEXD3DDEV9_TERM *PFNVBOXWINEEXD3DDEV9_TERM;
+
+typedef VBOXWINEEX_DECL(HRESULT) FNVBOXWINEEXD3DSURF9_GETHOSTID(IDirect3DSurface9 *iface, uint32_t *pu32Id);
+typedef FNVBOXWINEEXD3DSURF9_GETHOSTID *PFNVBOXWINEEXD3DSURF9_GETHOSTID;
+
+typedef VBOXWINEEX_DECL(HRESULT) FNVBOXWINEEXD3DSURF9_SYNCTOHOST(IDirect3DSurface9 *iface);
+typedef FNVBOXWINEEXD3DSURF9_SYNCTOHOST *PFNVBOXWINEEXD3DSURF9_SYNCTOHOST;
+
+typedef VBOXWINEEX_DECL(HRESULT) FNVBOXWINEEXD3DSWAPCHAIN9_PRESENT(IDirect3DSwapChain9 *iface, IDirect3DSurface9 *surf);
+typedef FNVBOXWINEEXD3DSWAPCHAIN9_PRESENT *PFNVBOXWINEEXD3DSWAPCHAIN9_PRESENT;
+
+typedef VBOXWINEEX_DECL(HRESULT) FNVBOXWINEEXD3DSWAPCHAIN9_GETHOSTWINID(IDirect3DSwapChain9 *iface, int32_t *pID);
+typedef FNVBOXWINEEXD3DSWAPCHAIN9_GETHOSTWINID *PFNVBOXWINEEXD3DSWAPCHAIN9_GETHOSTWINID;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9CreateTexture(IDirect3DDevice9Ex *iface,
+ UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format,
+ D3DPOOL pool, IDirect3DTexture9 **texture, HANDLE *shared_handle,
+ void **pavClientMem); /* <- extension arg to pass in the client memory buffer,
+ * applicable ONLY for SYSMEM textures */
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9CreateCubeTexture(IDirect3DDevice9Ex *iface,
+ UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format,
+ D3DPOOL pool, IDirect3DCubeTexture9 **texture, HANDLE *shared_handle,
+ void **pavClientMem); /* <- extension arg to pass in the client memory buffer,
+ * applicable ONLY for SYSMEM textures */
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9CreateVolumeTexture(IDirect3DDevice9Ex *iface,
+ UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT Format, D3DPOOL Pool,
+ IDirect3DVolumeTexture9 **ppVolumeTexture, HANDLE *pSharedHandle,
+ void **pavClientMem);
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9VolBlt(IDirect3DDevice9Ex *iface,
+ IDirect3DVolume9 *pSourceVolume, IDirect3DVolume9 *pDestinationVolume,
+ const struct VBOXBOX3D *pSrcBoxArg,
+ const struct VBOXPOINT3D *pDstPoin3D);
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9VolTexBlt(IDirect3DDevice9Ex *iface,
+ IDirect3DVolumeTexture9 *pSourceTexture, IDirect3DVolumeTexture9 *pDestinationTexture,
+ const struct VBOXBOX3D *pSrcBoxArg,
+ const struct VBOXPOINT3D *pDstPoin3D);
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9Flush(IDirect3DDevice9Ex *iface); /* perform glFlush */
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9Finish(IDirect3DDevice9Ex *iface); /* perform glFinish */
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9FlushToHost(IDirect3DDevice9Ex *iface); /* flash data to host */
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9GetHostId(IDirect3DDevice9Ex *iface, int32_t *pi32Id);
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9Term(IDirect3DDevice9Ex *iface);
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DSurf9GetHostId(IDirect3DSurface9 *iface, uint32_t *pu32Id);
+
+/* makes the surface contents to be synched with host,
+ * i.e. typically in case wine surface's location is in sysmem, puts it to texture*/
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DSurf9SyncToHost(IDirect3DSurface9 *iface);
+
+/* used for backwards compatibility purposes only with older host versions not supportgin new present mechanism */
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DSwapchain9Present(IDirect3DSwapChain9 *iface,
+ IDirect3DSurface9 *surf); /* use the given surface as a frontbuffer content source */
+
+VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DSwapchain9GetHostWinID(IDirect3DSwapChain9 *iface, int32_t *pi32Id);
+
+typedef struct VBOXWINEEX_D3DPRESENT_PARAMETERS
+{
+ D3DPRESENT_PARAMETERS Base;
+ struct VBOXUHGSMI *pHgsmi;
+} VBOXWINEEX_D3DPRESENT_PARAMETERS, *PVBOXWINEEX_D3DPRESENT_PARAMETERS;
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* #ifndef IN_VBOXLIBWINE */
+
+#endif
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/Makefile.kup b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/Makefile.kup
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/debug.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/debug.c
new file mode 100644
index 00000000..6d5b4be1
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/debug.c
@@ -0,0 +1,498 @@
+/*
+ * Management of the debugging channels
+ *
+ * Copyright 2000 Alexandre Julliard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include <windows.h>
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "wine/debug.h"
+//#include "wine/library.h"
+
+#ifdef VBOX_WITH_WDDM
+#include <VBoxDispMpLogger.h>
+#include <iprt/err.h>
+#else
+#include <iprt/log.h>
+#endif
+
+static const char * const debug_classes[] = { "fixme", "err", "warn", "trace" };
+
+#define MAX_DEBUG_OPTIONS 256
+
+typedef DECLCALLBACK(void) FNVBOXWINELOGBACKDOOR(char* pcszStr);
+typedef FNVBOXWINELOGBACKDOOR *PFNVBOXWINELOGBACKDOOR;
+static PFNVBOXWINELOGBACKDOOR vbox_log_backdoor = NULL;
+static unsigned char default_flags = (1 << __WINE_DBCL_ERR) | (1 << __WINE_DBCL_FIXME) | (1 << __WINE_DBCL_WARN);
+static int nb_debug_options = -1;
+static struct __wine_debug_channel debug_options[MAX_DEBUG_OPTIONS];
+
+static struct __wine_debug_functions funcs;
+
+static void debug_init(void);
+
+static int cmp_name( const void *p1, const void *p2 )
+{
+ const char *name = p1;
+ const struct __wine_debug_channel *chan = p2;
+ return strcmp( name, chan->name );
+}
+
+/* get the flags to use for a given channel, possibly setting them too in case of lazy init */
+unsigned char __wine_dbg_get_channel_flags( struct __wine_debug_channel *channel )
+{
+ if (nb_debug_options == -1) debug_init();
+
+ if (nb_debug_options)
+ {
+ struct __wine_debug_channel *opt = bsearch( channel->name, debug_options, nb_debug_options,
+ sizeof(debug_options[0]), cmp_name );
+ if (opt) return opt->flags;
+ }
+ /* no option for this channel */
+ if (channel->flags & (1 << __WINE_DBCL_INIT)) channel->flags = default_flags;
+ return default_flags;
+}
+
+/* set the flags to use for a given channel; return 0 if the channel is not available to set */
+int __wine_dbg_set_channel_flags( struct __wine_debug_channel *channel,
+ unsigned char set, unsigned char clear )
+{
+ if (nb_debug_options == -1) debug_init();
+
+ if (nb_debug_options)
+ {
+ struct __wine_debug_channel *opt = bsearch( channel->name, debug_options, nb_debug_options,
+ sizeof(debug_options[0]), cmp_name );
+ if (opt)
+ {
+ opt->flags = (opt->flags & ~clear) | set;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* add a new debug option at the end of the option list */
+static void add_option( const char *name, unsigned char set, unsigned char clear )
+{
+ int min = 0, max = nb_debug_options - 1, pos, res;
+
+ if (!name[0]) /* "all" option */
+ {
+ default_flags = (default_flags & ~clear) | set;
+ return;
+ }
+ if (strlen(name) >= sizeof(debug_options[0].name)) return;
+
+ while (min <= max)
+ {
+ pos = (min + max) / 2;
+ res = strcmp( name, debug_options[pos].name );
+ if (!res)
+ {
+ debug_options[pos].flags = (debug_options[pos].flags & ~clear) | set;
+ return;
+ }
+ if (res < 0) max = pos - 1;
+ else min = pos + 1;
+ }
+ if (nb_debug_options >= MAX_DEBUG_OPTIONS) return;
+
+ pos = min;
+ if (pos < nb_debug_options) memmove( &debug_options[pos + 1], &debug_options[pos],
+ (nb_debug_options - pos) * sizeof(debug_options[0]) );
+ strcpy( debug_options[pos].name, name );
+ debug_options[pos].flags = (default_flags & ~clear) | set;
+ nb_debug_options++;
+}
+
+/* parse a set of debugging option specifications and add them to the option list */
+static void parse_options( const char *str )
+{
+ char *opt, *next, *options;
+ unsigned int i;
+
+ if (!(options = strdup(str))) return;
+ for (opt = options; opt; opt = next)
+ {
+ const char *p;
+ unsigned char set = 0, clear = 0;
+
+ if ((next = strchr( opt, ',' ))) *next++ = 0;
+
+ p = opt + strcspn( opt, "+-" );
+ if (!p[0]) p = opt; /* assume it's a debug channel name */
+
+ if (p > opt)
+ {
+ for (i = 0; i < sizeof(debug_classes)/sizeof(debug_classes[0]); i++)
+ {
+ int len = strlen(debug_classes[i]);
+ if (len != (p - opt)) continue;
+ if (!memcmp( opt, debug_classes[i], len )) /* found it */
+ {
+ if (*p == '+') set |= 1 << i;
+ else clear |= 1 << i;
+ break;
+ }
+ }
+ if (i == sizeof(debug_classes)/sizeof(debug_classes[0])) /* bad class name, skip it */
+ continue;
+ }
+ else
+ {
+ if (*p == '-') clear = ~0;
+ else set = ~0;
+ }
+ if (*p == '+' || *p == '-') p++;
+ if (!p[0]) continue;
+
+ if (!strcmp( p, "all" ))
+ default_flags = (default_flags & ~clear) | set;
+ else
+ add_option( p, set, clear );
+ }
+ free( options );
+}
+
+
+/* print the usage message */
+static void debug_usage(void)
+{
+ static const char usage[] =
+ "Syntax of the WINEDEBUG variable:\n"
+ " WINEDEBUG=[class]+xxx,[class]-yyy,...\n\n"
+ "Example: WINEDEBUG=+all,warn-heap\n"
+ " turns on all messages except warning heap messages\n"
+ "Available message classes: err, warn, fixme, trace\n";
+ write( 2, usage, sizeof(usage) - 1 );
+ exit(1);
+}
+
+#ifndef VBOX_WITH_WDDM
+static DECLCALLBACK(void) vbox_log_backdoor_rt(char* pcszStr)
+{
+ RTLogBackdoorPrintf("%s", pcszStr);
+}
+#else
+static DECLCALLBACK(void) vbox_log_backdoor_dispmp(char* pcszStr)
+{
+ VBoxDispMpLoggerLog(pcszStr);
+}
+#endif
+static void vbox_log_v(const char *pszFormat, va_list args)
+{
+ if (vbox_log_backdoor)
+ {
+ static char buf[8092];
+ int offset = sprintf(buf, "[0x%lx.0x%lx] Wine Debug: ", GetCurrentProcessId(), GetCurrentThreadId());
+ vsprintf(buf + offset, pszFormat, args);
+ vbox_log_backdoor(buf);
+ }
+}
+
+/* initialize all options at startup */
+static void debug_init(void)
+{
+ char *wine_debug;
+
+ if (nb_debug_options != -1) return; /* already initialized */
+ nb_debug_options = 0;
+ if ((wine_debug = getenv("WINEDEBUG")))
+ {
+ Assert(0);
+ if (!strcmp( wine_debug, "help" ))
+ debug_usage();
+ else if (getenv("WINEDEBUG_BACKDOOR"))
+ {
+#ifdef VBOX_WITH_WDDM
+ int rc = VBoxDispMpLoggerInit();
+ if (RT_SUCCESS(rc))
+ vbox_log_backdoor = vbox_log_backdoor_dispmp;
+// else
+#else
+ vbox_log_backdoor = vbox_log_backdoor_rt;
+#endif
+ }
+ parse_options( wine_debug );
+ }
+}
+
+/* varargs wrapper for funcs.dbg_vprintf */
+int wine_dbg_printf( const char *format, ... )
+{
+ int ret;
+ va_list valist;
+
+ va_start(valist, format);
+ ret = funcs.dbg_vprintf( format, valist );
+ va_end(valist);
+ return ret;
+}
+
+/* printf with temp buffer allocation */
+const char *wine_dbg_sprintf( const char *format, ... )
+{
+ static const int max_size = 200;
+ char *ret;
+ int len;
+ va_list valist;
+
+ va_start(valist, format);
+ ret = funcs.get_temp_buffer( max_size );
+ len = vsnprintf( ret, max_size, format, valist );
+ if (len == -1 || len >= max_size) ret[max_size-1] = 0;
+ else funcs.release_temp_buffer( ret, len + 1 );
+ va_end(valist);
+ return ret;
+}
+
+
+/* varargs wrapper for funcs.dbg_vlog */
+int wine_dbg_log( enum __wine_debug_class cls, struct __wine_debug_channel *channel,
+ const char *func, const char *format, ... )
+{
+ int ret;
+ va_list valist;
+
+ if (!(__wine_dbg_get_channel_flags( channel ) & (1 << cls))) return -1;
+
+ va_start(valist, format);
+ ret = funcs.dbg_vlog( cls, channel, func, format, valist );
+ va_end(valist);
+ return ret;
+}
+
+int interlocked_xchg_add( int *dest, int incr )
+{
+ return InterlockedExchangeAdd(dest, incr);
+}
+
+/* allocate some tmp string space */
+/* FIXME: this is not 100% thread-safe */
+static char *get_temp_buffer( size_t size )
+{
+ static char *list[32];
+ static int pos;
+ char *ret;
+ int idx;
+
+ idx = interlocked_xchg_add( &pos, 1 ) % (sizeof(list)/sizeof(list[0]));
+ if ((ret = realloc( list[idx], size ))) list[idx] = ret;
+ return ret;
+}
+
+
+/* release unused part of the buffer */
+static void release_temp_buffer( char *buffer, size_t size )
+{
+ /* don't bother doing anything */
+}
+
+
+/* default implementation of wine_dbgstr_an */
+static const char *default_dbgstr_an( const char *str, int n )
+{
+ static const char hex[16] = "0123456789abcdef";
+ char *dst, *res;
+ size_t size;
+
+ if (!((ULONG_PTR)str >> 16))
+ {
+ if (!str) return "(null)";
+ res = funcs.get_temp_buffer( 6 );
+ sprintf( res, "#%04x", LOWORD(str) );
+ return res;
+ }
+ if (n == -1) n = strlen(str);
+ if (n < 0) n = 0;
+ size = 10 + min( 300, n * 4 );
+ dst = res = funcs.get_temp_buffer( size );
+ *dst++ = '"';
+ while (n-- > 0 && dst <= res + size - 9)
+ {
+ unsigned char c = *str++;
+ switch (c)
+ {
+ case '\n': *dst++ = '\\'; *dst++ = 'n'; break;
+ case '\r': *dst++ = '\\'; *dst++ = 'r'; break;
+ case '\t': *dst++ = '\\'; *dst++ = 't'; break;
+ case '"': *dst++ = '\\'; *dst++ = '"'; break;
+ case '\\': *dst++ = '\\'; *dst++ = '\\'; break;
+ default:
+ if (c >= ' ' && c <= 126)
+ *dst++ = c;
+ else
+ {
+ *dst++ = '\\';
+ *dst++ = 'x';
+ *dst++ = hex[(c >> 4) & 0x0f];
+ *dst++ = hex[c & 0x0f];
+ }
+ }
+ }
+ *dst++ = '"';
+ if (n > 0)
+ {
+ *dst++ = '.';
+ *dst++ = '.';
+ *dst++ = '.';
+ }
+ *dst++ = 0;
+ funcs.release_temp_buffer( res, dst - res );
+ return res;
+}
+
+
+/* default implementation of wine_dbgstr_wn */
+static const char *default_dbgstr_wn( const WCHAR *str, int n )
+{
+ char *dst, *res;
+ size_t size;
+
+ if (!((ULONG_PTR)str >> 16))
+ {
+ if (!str) return "(null)";
+ res = funcs.get_temp_buffer( 6 );
+ sprintf( res, "#%04x", LOWORD(str) );
+ return res;
+ }
+ if (n == -1)
+ {
+ const WCHAR *end = str;
+ while (*end) end++;
+ n = end - str;
+ }
+ if (n < 0) n = 0;
+ size = 12 + min( 300, n * 5 );
+ dst = res = funcs.get_temp_buffer( size );
+ *dst++ = 'L';
+ *dst++ = '"';
+ while (n-- > 0 && dst <= res + size - 10)
+ {
+ WCHAR c = *str++;
+ switch (c)
+ {
+ case '\n': *dst++ = '\\'; *dst++ = 'n'; break;
+ case '\r': *dst++ = '\\'; *dst++ = 'r'; break;
+ case '\t': *dst++ = '\\'; *dst++ = 't'; break;
+ case '"': *dst++ = '\\'; *dst++ = '"'; break;
+ case '\\': *dst++ = '\\'; *dst++ = '\\'; break;
+ default:
+ if (c >= ' ' && c <= 126)
+ *dst++ = c;
+ else
+ {
+ *dst++ = '\\';
+ sprintf(dst,"%04x",c);
+ dst+=4;
+ }
+ }
+ }
+ *dst++ = '"';
+ if (n > 0)
+ {
+ *dst++ = '.';
+ *dst++ = '.';
+ *dst++ = '.';
+ }
+ *dst++ = 0;
+ funcs.release_temp_buffer( res, dst - res );
+ return res;
+}
+
+
+/* default implementation of wine_dbg_vprintf */
+static int default_dbg_vprintf( const char *format, va_list args )
+{
+ vbox_log_v(format, args);
+#ifdef DEBUG_leo
+ static FILE *output=NULL;
+ static int first_time = 1;
+
+ if (first_time)
+ {
+ first_time = 0;
+ output = fopen( "winelog.txt", "w" );
+ }
+
+ if (output) vfprintf( output, format, args );
+#endif
+ return vfprintf( stdout, format, args );
+}
+
+
+/* default implementation of wine_dbg_vlog */
+static int default_dbg_vlog( enum __wine_debug_class cls, struct __wine_debug_channel *channel,
+ const char *func, const char *format, va_list args )
+{
+ int ret = 0;
+
+ if (cls < sizeof(debug_classes)/sizeof(debug_classes[0]))
+ ret += wine_dbg_printf( "%s:[%#x]:%s:%s ", debug_classes[cls], GetCurrentThreadId(), channel->name, func );
+ if (format)
+ ret += funcs.dbg_vprintf( format, args );
+ return ret;
+}
+
+/* wrappers to use the function pointers */
+
+const char *wine_dbgstr_an( const char * s, int n )
+{
+ return funcs.dbgstr_an(s, n);
+}
+
+const char *wine_dbgstr_wn( const WCHAR *s, int n )
+{
+ return funcs.dbgstr_wn(s, n);
+}
+
+void __wine_dbg_set_functions( const struct __wine_debug_functions *new_funcs,
+ struct __wine_debug_functions *old_funcs, size_t size )
+{
+ if (old_funcs) memcpy( old_funcs, &funcs, min(sizeof(funcs),size) );
+ if (new_funcs) memcpy( &funcs, new_funcs, min(sizeof(funcs),size) );
+}
+
+static struct __wine_debug_functions funcs =
+{
+ get_temp_buffer,
+ release_temp_buffer,
+ default_dbgstr_an,
+ default_dbgstr_wn,
+ default_dbg_vprintf,
+ default_dbg_vlog
+};
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/config.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/config.h
new file mode 100644
index 00000000..a639e36f
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/config.h
@@ -0,0 +1,1275 @@
+/* include/config.h. Generated from config.h.in by configure. */
+/* include/config.h.in. Generated from configure.ac by autoheader. */
+
+#include <stddef.h>
+
+#define __WINE_CONFIG_H
+
+/* Define to a function attribute for Microsoft hotpatch assembly prefix. */
+#define DECLSPEC_HOTPATCH /* */
+
+/* Define to the file extension for executables. */
+#define EXEEXT ".exe"
+
+/* Define to 1 if you have the <alias.h> header file. */
+/* #undef HAVE_ALIAS_H */
+
+/* Define if you have ALSA 1.x including devel headers */
+/* #undef HAVE_ALSA */
+
+/* Define to 1 if you have the <alsa/asoundlib.h> header file. */
+/* #undef HAVE_ALSA_ASOUNDLIB_H */
+
+/* Define to 1 if you have the <AL/al.h> header file. */
+/* #undef HAVE_AL_AL_H */
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <arpa/nameser.h> header file. */
+/* #undef HAVE_ARPA_NAMESER_H */
+
+/* Define to 1 if you have the `asctime_r' function. */
+#define HAVE_ASCTIME_R 1
+
+/* Define to 1 if you have the <asm/types.h> header file. */
+#define HAVE_ASM_TYPES_H 1
+
+/* Define to 1 if you have the <AudioUnit/AudioUnit.h> header file. */
+/* #undef HAVE_AUDIOUNIT_AUDIOUNIT_H */
+
+/* Define to 1 if you have the <audio/audiolib.h> header file. */
+/* #undef HAVE_AUDIO_AUDIOLIB_H */
+
+/* Define to 1 if you have the <audio/soundlib.h> header file. */
+/* #undef HAVE_AUDIO_SOUNDLIB_H */
+
+/* Define to 1 if you have the <capi20.h> header file. */
+/* #undef HAVE_CAPI20_H */
+
+/* Define to 1 if you have the <Carbon/Carbon.h> header file. */
+/* #undef HAVE_CARBON_CARBON_H */
+
+/* Define to 1 if you have the `chsize' function. */
+/* #undef HAVE_CHSIZE */
+
+/* Define to 1 if you have the <CoreAudio/CoreAudio.h> header file. */
+/* #undef HAVE_COREAUDIO_COREAUDIO_H */
+
+/* Define to 1 if you have the <cups/cups.h> header file. */
+/* #undef HAVE_CUPS_CUPS_H */
+
+/* Define to 1 if you have the <curses.h> header file. */
+/* #undef HAVE_CURSES_H */
+
+/* Define if you have the daylight variable */
+/* #undef HAVE_DAYLIGHT*/
+
+/* Define to 1 if you have the <dbus/dbus.h> header file. */
+/* #undef HAVE_DBUS_DBUS_H */
+
+/* Define to 1 if you have the <direct.h> header file. */
+/* #undef HAVE_DIRECT_H */
+
+/* Define to 1 if you have the <dirent.h> header file. */
+#define HAVE_DIRENT_H 1
+
+/* Define to 1 if you have the <DiskArbitration/DiskArbitration.h> header
+ file. */
+/* #undef HAVE_DISKARBITRATION_DISKARBITRATION_H */
+
+/* Define to 1 if you have the `dladdr' function. */
+/* #undef HAVE_DLADDR */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+/* #undef HAVE_DLFCN_H*/
+
+/* Define to 1 if you have the `dlopen' function. */
+/* #undef HAVE_DLOPEN*/
+
+/* Define to 1 if you have the <elf.h> header file. */
+/* #undef HAVE_ELF_H*/
+
+/* Define to 1 if you have the `epoll_create' function. */
+/* #undef HAVE_EPOLL_CREATE */
+
+/* Define if you have EsounD sound server */
+/* #undef HAVE_ESD */
+
+/* Define to 1 if you have the `ffs' function. */
+#define HAVE_FFS 1
+
+/* Define to 1 if you have the `finite' function. */
+#define HAVE_FINITE 1
+
+/* Define to 1 if you have the <float.h> header file. */
+#define HAVE_FLOAT_H 1
+
+/* Define to 1 if you have the `fnmatch' function. */
+#define HAVE_FNMATCH 1
+
+/* Define to 1 if you have the <fnmatch.h> header file. */
+#define HAVE_FNMATCH_H 1
+
+/* Define to 1 if you have the <fontconfig/fontconfig.h> header file. */
+/* #undef HAVE_FONTCONFIG_FONTCONFIG_H */
+
+/* Define to 1 if you have the `fork' function. */
+#define HAVE_FORK 1
+
+/* Define to 1 if you have the `fpclass' function. */
+/* #undef HAVE_FPCLASS */
+
+/* Define if FreeType 2 is installed */
+/* #undef HAVE_FREETYPE */
+
+/* Define to 1 if you have the <freetype/freetype.h> header file. */
+/* #undef HAVE_FREETYPE_FREETYPE_H */
+
+/* Define to 1 if you have the <freetype/ftglyph.h> header file. */
+/* #undef HAVE_FREETYPE_FTGLYPH_H */
+
+/* Define to 1 if you have the <freetype/ftlcdfil.h> header file. */
+/* #undef HAVE_FREETYPE_FTLCDFIL_H */
+
+/* Define to 1 if you have the <freetype/ftmodapi.h> header file. */
+/* #undef HAVE_FREETYPE_FTMODAPI_H */
+
+/* Define to 1 if you have the <freetype/ftoutln.h> header file. */
+/* #undef HAVE_FREETYPE_FTOUTLN_H */
+
+/* Define to 1 if you have the <freetype/ftsnames.h> header file. */
+/* #undef HAVE_FREETYPE_FTSNAMES_H */
+
+/* Define if you have the <freetype/fttrigon.h> header file. */
+/* #undef HAVE_FREETYPE_FTTRIGON_H */
+
+/* Define to 1 if you have the <freetype/fttypes.h> header file. */
+/* #undef HAVE_FREETYPE_FTTYPES_H */
+
+/* Define to 1 if you have the <freetype/ftwinfnt.h> header file. */
+/* #undef HAVE_FREETYPE_FTWINFNT_H */
+
+/* Define to 1 if you have the <freetype/internal/sfnt.h> header file. */
+/* #undef HAVE_FREETYPE_INTERNAL_SFNT_H */
+
+/* Define to 1 if you have the <freetype/ttnameid.h> header file. */
+/* #undef HAVE_FREETYPE_TTNAMEID_H */
+
+/* Define to 1 if you have the <freetype/tttables.h> header file. */
+/* #undef HAVE_FREETYPE_TTTABLES_H */
+
+/* Define to 1 if the system has the type `fsblkcnt_t'. */
+#define HAVE_FSBLKCNT_T 1
+
+/* Define to 1 if the system has the type `fsfilcnt_t'. */
+#define HAVE_FSFILCNT_T 1
+
+/* Define to 1 if you have the `fstatfs' function. */
+#define HAVE_FSTATFS 1
+
+/* Define to 1 if you have the `fstatvfs' function. */
+#define HAVE_FSTATVFS 1
+
+/* Define to 1 if you have the <ft2build.h> header file. */
+/* #undef HAVE_FT2BUILD_H */
+
+/* Define to 1 if you have the `ftruncate' function. */
+#define HAVE_FTRUNCATE 1
+
+/* Define to 1 if you have the `FT_Load_Sfnt_Table' function. */
+/* #undef HAVE_FT_LOAD_SFNT_TABLE */
+
+/* Define to 1 if the system has the type `FT_TrueTypeEngineType'. */
+/* #undef HAVE_FT_TRUETYPEENGINETYPE */
+
+/* Define to 1 if you have the `futimes' function. */
+#define HAVE_FUTIMES 1
+
+/* Define to 1 if you have the `futimesat' function. */
+/* #undef HAVE_FUTIMESAT */
+
+/* Define to 1 if you have the `getaddrinfo' function. */
+/* #undef HAVE_GETADDRINFO */
+
+/* Define to 1 if you have the `getdirentries' function. */
+/* #undef HAVE_GETDIRENTRIES */
+
+/* Define to 1 if you have the `getnameinfo' function. */
+/* #undef HAVE_GETNAMEINFO */
+
+/* Define to 1 if you have the `getnetbyname' function. */
+/* #undef HAVE_GETNETBYNAME */
+
+/* Define to 1 if you have the <getopt.h> header file. */
+#define HAVE_GETOPT_H 1
+
+/* Define to 1 if you have the `getopt_long' function. */
+#define HAVE_GETOPT_LONG 1
+
+/* Define to 1 if you have the `getpagesize' function. */
+/* #undef HAVE_GETPAGESIZE */
+
+/* Define to 1 if you have the `getprotobyname' function. */
+#define HAVE_GETPROTOBYNAME 1
+
+/* Define to 1 if you have the `getprotobynumber' function. */
+#define HAVE_GETPROTOBYNUMBER 1
+
+/* Define to 1 if you have the `getpwuid' function. */
+/* #undef HAVE_GETPWUID */
+
+/* Define to 1 if you have the `getservbyport' function. */
+#define HAVE_GETSERVBYPORT 1
+
+/* Define to 1 if you have the `gettid' function. */
+/* #undef HAVE_GETTID */
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define to 1 if you have the `getuid' function. */
+/* #undef HAVE_GETUID */
+
+/* Define to 1 if you have the <GL/glu.h> header file. */
+/* #undef HAVE_GL_GLU_H */
+
+/* Define to 1 if you have the <GL/glx.h> header file. */
+/* #undef HAVE_GL_GLX_H */
+
+/* Define to 1 if you have the <GL/gl.h> header file. */
+/* #undef HAVE_GL_GL_H */
+
+/* Define if we have libgphoto2 development environment */
+/* #undef HAVE_GPHOTO2 */
+
+/* Define to 1 if you have the <grp.h> header file. */
+/* #undef HAVE_GRP_H */
+
+/* Define to 1 if you have the <gsm/gsm.h> header file. */
+/* #undef HAVE_GSM_GSM_H */
+
+/* Define to 1 if you have the <gsm.h> header file. */
+/* #undef HAVE_GSM_H */
+
+/* Define to 1 if you have the <hal/libhal.h> header file. */
+/* #undef HAVE_HAL_LIBHAL_H */
+
+/* Define to 1 if you have the <ieeefp.h> header file. */
+#define HAVE_IEEEFP_H 1
+
+/* Define to 1 if you have the <inet/mib2.h> header file. */
+/* #undef HAVE_INET_MIB2_H */
+
+/* Define to 1 if you have the `inet_network' function. */
+#define HAVE_INET_NETWORK 1
+
+/* Define to 1 if you have the `inet_ntop' function. */
+#define HAVE_INET_NTOP 1
+
+/* Define to 1 if you have the `inet_pton' function. */
+#define HAVE_INET_PTON 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `IOHIDManagerCreate' function. */
+/* #undef HAVE_IOHIDMANAGERCREATE */
+
+/* Define to 1 if you have the <IOKit/hid/IOHIDLib.h> header file. */
+/* #undef HAVE_IOKIT_HID_IOHIDLIB_H */
+
+/* Define to 1 if you have the <IOKit/IOKitLib.h> header file. */
+/* #undef HAVE_IOKIT_IOKITLIB_H */
+
+/* Define to 1 if you have the <io.h> header file. */
+#define HAVE_IO_H 1
+
+/* Define to 1 if you have the `isinf' function. */
+/* #undef HAVE_ISINF */
+
+/* Define to 1 if you have the `isnan' function. */
+/* #undef HAVE_ISNAN */
+
+/* Define to 1 if you have the <jack/jack.h> header file. */
+/* #undef HAVE_JACK_JACK_H */
+
+/* Define to 1 if you have the <jpeglib.h> header file. */
+/* #undef HAVE_JPEGLIB_H */
+
+/* Define to 1 if you have the `kqueue' function. */
+/* #undef HAVE_KQUEUE */
+
+/* Define to 1 if you have the <kstat.h> header file. */
+/* #undef HAVE_KSTAT_H */
+
+/* Define to 1 if you have the <lber.h> header file. */
+/* #undef HAVE_LBER_H */
+
+/* Define if you have the LittleCMS development environment */
+/* #undef HAVE_LCMS */
+
+/* Define to 1 if you have the <lcms.h> header file. */
+/* #undef HAVE_LCMS_H */
+
+/* Define to 1 if you have the <lcms/lcms.h> header file. */
+/* #undef HAVE_LCMS_LCMS_H */
+
+/* Define if you have the OpenLDAP development environment */
+/* #undef HAVE_LDAP */
+
+/* Define to 1 if you have the `ldap_count_references' function. */
+/* #undef HAVE_LDAP_COUNT_REFERENCES */
+
+/* Define to 1 if you have the `ldap_first_reference' function. */
+/* #undef HAVE_LDAP_FIRST_REFERENCE */
+
+/* Define to 1 if you have the <ldap.h> header file. */
+/* #undef HAVE_LDAP_H */
+
+/* Define to 1 if you have the `ldap_next_reference' function. */
+/* #undef HAVE_LDAP_NEXT_REFERENCE */
+
+/* Define to 1 if you have the `ldap_parse_reference' function. */
+/* #undef HAVE_LDAP_PARSE_REFERENCE */
+
+/* Define to 1 if you have the `ldap_parse_sortresponse_control' function. */
+/* #undef HAVE_LDAP_PARSE_SORTRESPONSE_CONTROL */
+
+/* Define to 1 if you have the `ldap_parse_sort_control' function. */
+/* #undef HAVE_LDAP_PARSE_SORT_CONTROL */
+
+/* Define to 1 if you have the `ldap_parse_vlvresponse_control' function. */
+/* #undef HAVE_LDAP_PARSE_VLVRESPONSE_CONTROL */
+
+/* Define to 1 if you have the `ldap_parse_vlv_control' function. */
+/* #undef HAVE_LDAP_PARSE_VLV_CONTROL */
+
+/* Define if you have libaudioIO */
+/* #undef HAVE_LIBAUDIOIO */
+
+/* Define to 1 if you have the <libaudioio.h> header file. */
+/* #undef HAVE_LIBAUDIOIO_H */
+
+/* Define to 1 if you have the `i386' library (-li386). */
+/* #undef HAVE_LIBI386 */
+
+/* Define to 1 if you have the `kstat' library (-lkstat). */
+/* #undef HAVE_LIBKSTAT */
+
+/* Define to 1 if you have the `ossaudio' library (-lossaudio). */
+/* #undef HAVE_LIBOSSAUDIO */
+
+/* Define if you have the libxml2 library */
+/* #undef HAVE_LIBXML2 */
+
+/* Define to 1 if you have the <libxml/parser.h> header file. */
+/* #undef HAVE_LIBXML_PARSER_H */
+
+/* Define if you have the X Shape extension */
+/* #undef HAVE_LIBXSHAPE */
+
+/* Define to 1 if you have the <libxslt/pattern.h> header file. */
+/* #undef HAVE_LIBXSLT_PATTERN_H */
+
+/* Define to 1 if you have the <libxslt/transform.h> header file. */
+/* #undef HAVE_LIBXSLT_TRANSFORM_H */
+
+/* Define if you have the X Shm extension */
+/* #undef HAVE_LIBXXSHM */
+
+/* Define to 1 if you have the <link.h> header file. */
+/* #undef HAVE_LINK_H */
+
+/* Define if <linux/joystick.h> defines the Linux 2.2 joystick API */
+/* #undef HAVE_LINUX_22_JOYSTICK_API */
+
+/* Define to 1 if you have the <linux/capi.h> header file. */
+/* #undef HAVE_LINUX_CAPI_H */
+
+/* Define to 1 if you have the <linux/cdrom.h> header file. */
+/* #undef HAVE_LINUX_CDROM_H */
+
+/* Define to 1 if you have the <linux/compiler.h> header file. */
+/* #undef HAVE_LINUX_COMPILER_H */
+
+/* Define if Linux-style gethostbyname_r and gethostbyaddr_r are available */
+/* #undef HAVE_LINUX_GETHOSTBYNAME_R_6 */
+
+/* Define to 1 if you have the <linux/hdreg.h> header file. */
+/* #undef HAVE_LINUX_HDREG_H */
+
+/* Define to 1 if you have the <linux/input.h> header file. */
+/* #undef HAVE_LINUX_INPUT_H */
+
+/* Define to 1 if you have the <linux/ioctl.h> header file. */
+/* #undef HAVE_LINUX_IOCTL_H */
+
+/* Define to 1 if you have the <linux/ipx.h> header file. */
+/* #undef HAVE_LINUX_IPX_H */
+
+/* Define to 1 if you have the <linux/irda.h> header file. */
+/* #undef HAVE_LINUX_IRDA_H */
+
+/* Define to 1 if you have the <linux/joystick.h> header file. */
+/* #undef HAVE_LINUX_JOYSTICK_H */
+
+/* Define to 1 if you have the <linux/major.h> header file. */
+/* #undef HAVE_LINUX_MAJOR_H */
+
+/* Define to 1 if you have the <linux/param.h> header file. */
+/* #undef HAVE_LINUX_PARAM_H */
+
+/* Define to 1 if you have the <linux/serial.h> header file. */
+/* #undef HAVE_LINUX_SERIAL_H */
+
+/* Define to 1 if you have the <linux/types.h> header file. */
+/* #undef HAVE_LINUX_TYPES_H */
+
+/* Define to 1 if you have the <linux/ucdrom.h> header file. */
+/* #undef HAVE_LINUX_UCDROM_H */
+
+/* Define to 1 if you have the <linux/videodev.h> header file. */
+/* #undef HAVE_LINUX_VIDEODEV_H */
+
+/* Define to 1 if the system has the type `long long'. */
+#define HAVE_LONG_LONG 1
+
+/* Define to 1 if you have the `lstat' function. */
+#define HAVE_LSTAT 1
+
+/* Define to 1 if you have the <machine/cpu.h> header file. */
+/* #undef HAVE_MACHINE_CPU_H */
+
+/* Define to 1 if you have the <machine/limits.h> header file. */
+/* #undef HAVE_MACHINE_LIMITS_H */
+
+/* Define to 1 if you have the <machine/soundcard.h> header file. */
+/* #undef HAVE_MACHINE_SOUNDCARD_H */
+
+/* Define to 1 if you have the <mach/machine.h> header file. */
+/* #undef HAVE_MACH_MACHINE_H */
+
+/* Define to 1 if you have the <mach/mach.h> header file. */
+/* #undef HAVE_MACH_MACH_H */
+
+/* Define to 1 if you have the <mach-o/dyld_images.h> header file. */
+/* #undef HAVE_MACH_O_DYLD_IMAGES_H */
+
+/* Define to 1 if you have the <mach-o/nlist.h> header file. */
+/* #undef HAVE_MACH_O_NLIST_H */
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `mmap' function. */
+/* #undef HAVE_MMAP */
+
+/* Define to 1 if you have the <mntent.h> header file. */
+#define HAVE_MNTENT_H 1
+
+/* Define to 1 if the system has the type `mode_t'. */
+#define HAVE_MODE_T 1
+
+/* Define to 1 if you have the `mousemask' function. */
+/* #undef HAVE_MOUSEMASK */
+
+/* Define to 1 if you have the <mpg123.h> header file. */
+/* #undef HAVE_MPG123_H */
+
+/* Define if you have NAS including devel headers */
+/* #undef HAVE_NAS */
+
+/* Define to 1 if you have the <ncurses.h> header file. */
+/* #undef HAVE_NCURSES_H */
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/icmp_var.h> header file. */
+/* #undef HAVE_NETINET_ICMP_VAR_H */
+
+/* Define to 1 if you have the <netinet/if_ether.h> header file. */
+/* #undef HAVE_NETINET_IF_ETHER_H */
+
+/* Define to 1 if you have the <netinet/if_inarp.h> header file. */
+/* #undef HAVE_NETINET_IF_INARP_H */
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+/* #undef HAVE_NETINET_IN_H */
+
+/* Define to 1 if you have the <netinet/in_pcb.h> header file. */
+/* #undef HAVE_NETINET_IN_PCB_H */
+
+/* Define to 1 if you have the <netinet/in_systm.h> header file. */
+/* #undef HAVE_NETINET_IN_SYSTM_H */
+
+/* Define to 1 if you have the <netinet/ip.h> header file. */
+/* #undef HAVE_NETINET_IP_H */
+
+/* Define to 1 if you have the <netinet/ip_icmp.h> header file. */
+/* #undef HAVE_NETINET_IP_ICMP_H */
+
+/* Define to 1 if you have the <netinet/ip_var.h> header file. */
+/* #undef HAVE_NETINET_IP_VAR_H */
+
+/* Define to 1 if you have the <netinet/tcp_fsm.h> header file. */
+/* #undef HAVE_NETINET_TCP_FSM_H */
+
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+/* #undef HAVE_NETINET_TCP_H */
+
+/* Define to 1 if you have the <netinet/tcp_timer.h> header file. */
+/* #undef HAVE_NETINET_TCP_TIMER_H */
+
+/* Define to 1 if you have the <netinet/tcp_var.h> header file. */
+/* #undef HAVE_NETINET_TCP_VAR_H */
+
+/* Define to 1 if you have the <netinet/udp.h> header file. */
+/* #undef HAVE_NETINET_UDP_H */
+
+/* Define to 1 if you have the <netinet/udp_var.h> header file. */
+/* #undef HAVE_NETINET_UDP_VAR_H */
+
+/* Define to 1 if you have the <netipx/ipx.h> header file. */
+/* #undef HAVE_NETIPX_IPX_H */
+
+/* Define to 1 if you have the <net/if_arp.h> header file. */
+/* #undef HAVE_NET_IF_ARP_H */
+
+/* Define to 1 if you have the <net/if_dl.h> header file. */
+/* #undef HAVE_NET_IF_DL_H */
+
+/* Define to 1 if you have the <net/if.h> header file. */
+/* #undef HAVE_NET_IF_H */
+
+/* Define to 1 if you have the <net/if_types.h> header file. */
+/* #undef HAVE_NET_IF_TYPES_H */
+
+/* Define to 1 if you have the <net/route.h> header file. */
+/* #undef HAVE_NET_ROUTE_H */
+
+/* Define to 1 if `_msg_ptr' is a member of `ns_msg'. */
+/* #undef HAVE_NS_MSG__MSG_PTR */
+
+/* Define to 1 if the system has the type `off_t'. */
+#define HAVE_OFF_T 1
+
+/* Define if mkdir takes only one argument */
+/* #undef HAVE_ONE_ARG_MKDIR */
+
+/* Define to 1 if you have the <OpenAL/al.h> header file. */
+/* #undef HAVE_OPENAL_AL_H */
+
+/* Define if OpenGL is present on the system */
+/* #undef HAVE_OPENGL */
+
+/* Define to 1 if you have the <openssl/err.h> header file. */
+/* #undef HAVE_OPENSSL_ERR_H */
+
+/* Define to 1 if you have the <openssl/ssl.h> header file. */
+/* #undef HAVE_OPENSSL_SSL_H */
+
+/* Define to 1 if you have the `pclose' function. */
+#define HAVE_PCLOSE 1
+
+/* Define to 1 if the system has the type `pid_t'. */
+/* #undef HAVE_PID_T */
+
+/* Define to 1 if you have the `pipe2' function. */
+/* #undef HAVE_PIPE2 */
+
+/* Define to 1 if you have the <png.h> header file. */
+/* #undef HAVE_PNG_H */
+
+/* Define to 1 if you have the `poll' function. */
+#define HAVE_POLL 1
+
+/* Define to 1 if you have the <poll.h> header file. */
+#define HAVE_POLL_H 1
+
+/* Define to 1 if you have the `popen' function. */
+#define HAVE_POPEN 1
+
+/* Define to 1 if you have the `port_create' function. */
+/* #undef HAVE_PORT_CREATE */
+
+/* Define to 1 if you have the <port.h> header file. */
+/* #undef HAVE_PORT_H */
+
+/* Define if we can use ppdev.h for parallel port access */
+/* #undef HAVE_PPDEV */
+
+/* Define to 1 if you have the `prctl' function. */
+/* #undef HAVE_PRCTL */
+
+/* Define to 1 if you have the `pread' function. */
+#define HAVE_PREAD 1
+
+/* Define to 1 if you have the <process.h> header file. */
+#define HAVE_PROCESS_H 1
+
+/* Define to 1 if you have the `pthread_attr_get_np' function. */
+/* #undef HAVE_PTHREAD_ATTR_GET_NP */
+
+/* Define to 1 if you have the `pthread_getattr_np' function. */
+/* #undef HAVE_PTHREAD_GETATTR_NP */
+
+/* Define to 1 if you have the `pthread_get_stackaddr_np' function. */
+/* #undef HAVE_PTHREAD_GET_STACKADDR_NP */
+
+/* Define to 1 if you have the `pthread_get_stacksize_np' function. */
+/* #undef HAVE_PTHREAD_GET_STACKSIZE_NP */
+
+/* Define to 1 if you have the <pthread.h> header file. */
+/* #undef HAVE_PTHREAD_H */
+
+/* Define to 1 if you have the <pthread_np.h> header file. */
+/* #undef HAVE_PTHREAD_NP_H */
+
+/* Define to 1 if you have the <pwd.h> header file. */
+/* #undef HAVE_PWD_H */
+
+/* Define to 1 if you have the `pwrite' function. */
+#define HAVE_PWRITE 1
+
+/* Define to 1 if you have the `readdir' function. */
+#define HAVE_READDIR 1
+
+/* Define to 1 if you have the `readlink' function. */
+#define HAVE_READLINK 1
+
+/* Define to 1 if you have the <regex.h> header file. */
+#define HAVE_REGEX_H 1
+
+/* Define to 1 if the system has the type `request_sense'. */
+/* #undef HAVE_REQUEST_SENSE */
+
+/* Define if you have the resolver library and header */
+/* #undef HAVE_RESOLV */
+
+/* Define to 1 if you have the <resolv.h> header file. */
+/* #undef HAVE_RESOLV_H */
+
+/* Define to 1 if you have the <sched.h> header file. */
+#define HAVE_SCHED_H 1
+
+/* Define to 1 if you have the `sched_setaffinity' function. */
+/* #undef HAVE_SCHED_SETAFFINITY */
+
+/* Define to 1 if you have the `sched_yield' function. */
+#define HAVE_SCHED_YIELD 1
+
+/* Define to 1 if `cmd' is a member of `scsireq_t'. */
+/* #undef HAVE_SCSIREQ_T_CMD */
+
+/* Define to 1 if you have the <scsi/scsi.h> header file. */
+/* #undef HAVE_SCSI_SCSI_H */
+
+/* Define to 1 if you have the <scsi/scsi_ioctl.h> header file. */
+/* #undef HAVE_SCSI_SCSI_IOCTL_H */
+
+/* Define to 1 if you have the <scsi/sg.h> header file. */
+/* #undef HAVE_SCSI_SG_H */
+
+/* Define to 1 if you have the `select' function. */
+#define HAVE_SELECT 1
+
+/* Define to 1 if you have the `sendmsg' function. */
+#define HAVE_SENDMSG 1
+
+/* Define to 1 if you have the `setproctitle' function. */
+/* #undef HAVE_SETPROCTITLE */
+
+/* Define to 1 if you have the `setrlimit' function. */
+/* #undef HAVE_SETRLIMIT */
+
+/* Define to 1 if you have the `settimeofday' function. */
+#define HAVE_SETTIMEOFDAY 1
+
+/* Define to 1 if `interface_id' is a member of `sg_io_hdr_t'. */
+/* #undef HAVE_SG_IO_HDR_T_INTERFACE_ID */
+
+/* Define if sigaddset is supported */
+#define HAVE_SIGADDSET 1
+
+/* Define to 1 if you have the `sigaltstack' function. */
+/* #undef HAVE_SIGALTSTACK */
+
+/* Define to 1 if `si_fd' is a member of `siginfo_t'. */
+/* #undef HAVE_SIGINFO_T_SI_FD */
+
+/* Define to 1 if you have the `sigprocmask' function. */
+#define HAVE_SIGPROCMASK 1
+
+/* Define to 1 if the system has the type `sigset_t'. */
+#define HAVE_SIGSET_T 1
+
+/* Define to 1 if the system has the type `size_t'. */
+#define HAVE_SIZE_T 1
+
+/* Define to 1 if you have the `snprintf' function. */
+/* #undef HAVE_SNPRINTF */
+
+/* Define to 1 if you have the `socketpair' function. */
+#define HAVE_SOCKETPAIR 1
+
+/* Define to 1 if you have the <soundcard.h> header file. */
+/* #undef HAVE_SOUNDCARD_H */
+
+/* Define to 1 if you have the `spawnvp' function. */
+#define HAVE_SPAWNVP 1
+
+/* Define to 1 if the system has the type `ssize_t'. */
+#define HAVE_SSIZE_T 1
+
+/* Define to 1 if you have the `statfs' function. */
+#define HAVE_STATFS 1
+
+/* Define to 1 if you have the `statvfs' function. */
+#define HAVE_STATVFS 1
+
+/* Define to 1 if you have the <stdbool.h> header file. */
+#define HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+/* #undef HAVE_STDINT_H */
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#define HAVE_STRNCASECMP 1
+
+/* Define to 1 if you have the <stropts.h> header file. */
+/* #undef HAVE_STROPTS_H */
+
+/* Define to 1 if you have the `strtold' function. */
+/* #undef HAVE_STRTOLD */
+
+/* Define to 1 if you have the `strtoll' function. */
+#define HAVE_STRTOLL 1
+
+/* Define to 1 if you have the `strtoull' function. */
+#define HAVE_STRTOULL 1
+
+/* Define to 1 if `direction' is a member of `struct ff_effect'. */
+/* #undef HAVE_STRUCT_FF_EFFECT_DIRECTION */
+
+/* Define to 1 if `icps_outhist' is a member of `struct icmpstat'. */
+/* #undef HAVE_STRUCT_ICMPSTAT_ICPS_OUTHIST */
+
+/* Define to 1 if `msg_accrights' is a member of `struct msghdr'. */
+/* #undef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
+
+/* Define to 1 if `mt_blkno' is a member of `struct mtget'. */
+#define HAVE_STRUCT_MTGET_MT_BLKNO 1
+
+/* Define to 1 if `mt_blksiz' is a member of `struct mtget'. */
+/* #undef HAVE_STRUCT_MTGET_MT_BLKSIZ */
+
+/* Define to 1 if `mt_gstat' is a member of `struct mtget'. */
+#define HAVE_STRUCT_MTGET_MT_GSTAT 1
+
+/* Define to 1 if `name' is a member of `struct option'. */
+#define HAVE_STRUCT_OPTION_NAME 1
+
+/* Define to 1 if `sin6_scope_id' is a member of `struct sockaddr_in6'. */
+/* #undef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID */
+
+/* Define to 1 if `sa_len' is a member of `struct sockaddr'. */
+/* #undef HAVE_STRUCT_SOCKADDR_SA_LEN */
+
+/* Define to 1 if `sun_len' is a member of `struct sockaddr_un'. */
+/* #undef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
+
+/* Define to 1 if `f_bavail' is a member of `struct statfs'. */
+#define HAVE_STRUCT_STATFS_F_BAVAIL 1
+
+/* Define to 1 if `f_bfree' is a member of `struct statfs'. */
+#define HAVE_STRUCT_STATFS_F_BFREE 1
+
+/* Define to 1 if `f_favail' is a member of `struct statfs'. */
+/* #undef HAVE_STRUCT_STATFS_F_FAVAIL */
+
+/* Define to 1 if `f_ffree' is a member of `struct statfs'. */
+#define HAVE_STRUCT_STATFS_F_FFREE 1
+
+/* Define to 1 if `f_frsize' is a member of `struct statfs'. */
+/* #undef HAVE_STRUCT_STATFS_F_FRSIZE */
+
+/* Define to 1 if `f_namelen' is a member of `struct statfs'. */
+#define HAVE_STRUCT_STATFS_F_NAMELEN 1
+
+/* Define to 1 if `f_blocks' is a member of `struct statvfs'. */
+#define HAVE_STRUCT_STATVFS_F_BLOCKS 1
+
+/* Define to 1 if `st_atim' is a member of `struct stat'. */
+#define HAVE_STRUCT_STAT_ST_ATIM 1
+
+/* Define to 1 if `st_blocks' is a member of `struct stat'. */
+#define HAVE_STRUCT_STAT_ST_BLOCKS 1
+
+/* Define to 1 if `st_ctim' is a member of `struct stat'. */
+#define HAVE_STRUCT_STAT_ST_CTIM 1
+
+/* Define to 1 if `st_mtim' is a member of `struct stat'. */
+#define HAVE_STRUCT_STAT_ST_MTIM 1
+
+/* Define to 1 if the system has the type `struct xinpgen'. */
+/* #undef HAVE_STRUCT_XINPGEN */
+
+/* Define to 1 if you have the `symlink' function. */
+/* #undef HAVE_SYMLINK */
+
+/* Define to 1 if you have the <syscall.h> header file. */
+/* #undef HAVE_SYSCALL_H */
+
+/* Define to 1 if you have the <sys/asoundlib.h> header file. */
+/* #undef HAVE_SYS_ASOUNDLIB_H */
+
+/* Define to 1 if you have the <sys/cdio.h> header file. */
+/* #undef HAVE_SYS_CDIO_H */
+
+/* Define to 1 if you have the <sys/elf32.h> header file. */
+#define HAVE_SYS_ELF32_H 1
+
+/* Define to 1 if you have the <sys/epoll.h> header file. */
+/* #undef HAVE_SYS_EPOLL_H */
+
+/* Define to 1 if you have the <sys/errno.h> header file. */
+#define HAVE_SYS_ERRNO_H 1
+
+/* Define to 1 if you have the <sys/event.h> header file. */
+/* #undef HAVE_SYS_EVENT_H */
+
+/* Define to 1 if you have the <sys/exec_elf.h> header file. */
+/* #undef HAVE_SYS_EXEC_ELF_H */
+
+/* Define to 1 if you have the <sys/filio.h> header file. */
+/* #undef HAVE_SYS_FILIO_H */
+
+/* Define to 1 if you have the <sys/inotify.h> header file. */
+/* #undef HAVE_SYS_INOTIFY_H */
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/ipc.h> header file. */
+#define HAVE_SYS_IPC_H 1
+
+/* Define to 1 if you have the <sys/limits.h> header file. */
+/* #undef HAVE_SYS_LIMITS_H */
+
+/* Define to 1 if you have the <sys/link.h> header file. */
+/* #undef HAVE_SYS_LINK_H */
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+/* #undef HAVE_SYS_MMAN_H */
+
+/* Define to 1 if you have the <sys/modem.h> header file. */
+/* #undef HAVE_SYS_MODEM_H */
+
+/* Define to 1 if you have the <sys/mount.h> header file. */
+#define HAVE_SYS_MOUNT_H 1
+
+/* Define to 1 if you have the <sys/msg.h> header file. */
+#define HAVE_SYS_MSG_H 1
+
+/* Define to 1 if you have the <sys/mtio.h> header file. */
+#define HAVE_SYS_MTIO_H 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+#define HAVE_SYS_POLL_H 1
+
+/* Define to 1 if you have the <sys/prctl.h> header file. */
+/* #undef HAVE_SYS_PRCTL_H */
+
+/* Define to 1 if you have the <sys/protosw.h> header file. */
+/* #undef HAVE_SYS_PROTOSW_H */
+
+/* Define to 1 if you have the <sys/ptrace.h> header file. */
+/* #undef HAVE_SYS_PTRACE_H */
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+/* #undef HAVE_SYS_RESOURCE_H */
+
+/* Define to 1 if you have the <sys/scsiio.h> header file. */
+/* #undef HAVE_SYS_SCSIIO_H */
+
+/* Define to 1 if you have the <sys/shm.h> header file. */
+/* #undef HAVE_SYS_SHM_H */
+
+/* Define to 1 if you have the <sys/signal.h> header file. */
+/* #undef HAVE_SYS_SIGNAL_H */
+
+/* Define to 1 if you have the <sys/socketvar.h> header file. */
+/* #undef HAVE_SYS_SOCKETVAR_H */
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/sockio.h> header file. */
+/* #undef HAVE_SYS_SOCKIO_H */
+
+/* Define to 1 if you have the <sys/soundcard.h> header file. */
+#define HAVE_SYS_SOUNDCARD_H 1
+
+/* Define to 1 if you have the <sys/statfs.h> header file. */
+#define HAVE_SYS_STATFS_H 1
+
+/* Define to 1 if you have the <sys/statvfs.h> header file. */
+#define HAVE_SYS_STATVFS_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/strtio.h> header file. */
+/* #undef HAVE_SYS_STRTIO_H */
+
+/* Define to 1 if you have the <sys/syscall.h> header file. */
+/* #undef HAVE_SYS_SYSCALL_H */
+
+/* Define to 1 if you have the <sys/sysctl.h> header file. */
+/* #undef HAVE_SYS_SYSCTL_H */
+
+/* Define to 1 if you have the <sys/thr.h> header file. */
+/* #undef HAVE_SYS_THR_H */
+
+/* Define to 1 if you have the <sys/tihdr.h> header file. */
+/* #undef HAVE_SYS_TIHDR_H */
+
+/* Define to 1 if you have the <sys/timeout.h> header file. */
+/* #undef HAVE_SYS_TIMEOUT_H */
+
+/* Define to 1 if you have the <sys/times.h> header file. */
+#define HAVE_SYS_TIMES_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#define HAVE_SYS_UIO_H 1
+
+/* Define to 1 if you have the <sys/un.h> header file. */
+#define HAVE_SYS_UN_H 1
+
+/* Define to 1 if you have the <sys/user.h> header file. */
+/* #undef HAVE_SYS_USER_H */
+
+/* Define to 1 if you have the <sys/utsname.h> header file. */
+/* #undef HAVE_SYS_UTSNAME_H */
+
+/* Define to 1 if you have the <sys/vfs.h> header file. */
+#define HAVE_SYS_VFS_H 1
+
+/* Define to 1 if you have the <sys/vm86.h> header file. */
+/* #undef HAVE_SYS_VM86_H */
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define to 1 if you have the `tcgetattr' function. */
+#define HAVE_TCGETATTR 1
+
+/* Define to 1 if you have the <termios.h> header file. */
+#define HAVE_TERMIOS_H 1
+
+/* Define to 1 if you have the `thr_kill2' function. */
+/* #undef HAVE_THR_KILL2 */
+
+/* Define to 1 if you have the `timegm' function. */
+#define HAVE_TIMEGM 1
+
+/* Define if you have the timezone variable */
+#define HAVE_TIMEZONE 1
+
+/* Define to 1 if you have the <ucontext.h> header file. */
+/* #undef HAVE_UCONTEXT_H */
+
+/* Define to 1 if you have the <unistd.h> header file. */
+/* #undef HAVE_UNISTD_H */
+
+/* Define to 1 if you have the `usleep' function. */
+#define HAVE_USLEEP 1
+
+/* Define to 1 if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* Define to 1 if you have the <valgrind/memcheck.h> header file. */
+/* #undef HAVE_VALGRIND_MEMCHECK_H */
+
+/* Define to 1 if you have the <valgrind/valgrind.h> header file. */
+/* #undef HAVE_VALGRIND_VALGRIND_H */
+
+/* Define to 1 if you have the `vsnprintf' function. */
+/* #undef HAVE_VSNPRINTF */
+
+/* Define to 1 if you have the `wait4' function. */
+#define HAVE_WAIT4 1
+
+/* Define to 1 if you have the `waitpid' function. */
+#define HAVE_WAITPID 1
+
+/* Define to 1 if you have the <X11/extensions/shape.h> header file. */
+/* #undef HAVE_X11_EXTENSIONS_SHAPE_H */
+
+/* Define to 1 if you have the <X11/extensions/Xcomposite.h> header file. */
+/* #undef HAVE_X11_EXTENSIONS_XCOMPOSITE_H */
+
+/* Define to 1 if you have the <X11/extensions/xf86vmode.h> header file. */
+/* #undef HAVE_X11_EXTENSIONS_XF86VMODE_H */
+
+/* Define to 1 if you have the <X11/extensions/xf86vmproto.h> header file. */
+/* #undef HAVE_X11_EXTENSIONS_XF86VMPROTO_H */
+
+/* Define to 1 if you have the <X11/extensions/Xinerama.h> header file. */
+/* #undef HAVE_X11_EXTENSIONS_XINERAMA_H */
+
+/* Define to 1 if you have the <X11/extensions/XInput.h> header file. */
+/* #undef HAVE_X11_EXTENSIONS_XINPUT_H */
+
+/* Define to 1 if you have the <X11/extensions/Xrandr.h> header file. */
+/* #undef HAVE_X11_EXTENSIONS_XRANDR_H */
+
+/* Define to 1 if you have the <X11/extensions/Xrender.h> header file. */
+/* #undef HAVE_X11_EXTENSIONS_XRENDER_H */
+
+/* Define to 1 if you have the <X11/extensions/XShm.h> header file. */
+/* #undef HAVE_X11_EXTENSIONS_XSHM_H */
+
+/* Define to 1 if you have the <X11/Xcursor/Xcursor.h> header file. */
+/* #undef HAVE_X11_XCURSOR_XCURSOR_H */
+
+/* Define to 1 if you have the <X11/XKBlib.h> header file. */
+/* #undef HAVE_X11_XKBLIB_H */
+
+/* Define to 1 if you have the <X11/Xlib.h> header file. */
+/* #undef HAVE_X11_XLIB_H */
+
+/* Define to 1 if you have the <X11/Xutil.h> header file. */
+/* #undef HAVE_X11_XUTIL_H */
+
+/* Define to 1 if `callback' is a member of `XICCallback'. */
+/* #undef HAVE_XICCALLBACK_CALLBACK */
+
+/* Define if you have the XKB extension */
+/* #undef HAVE_XKB */
+
+/* Define if libxml2 has the xmlNewDocPI function */
+/* #undef HAVE_XMLNEWDOCPI */
+
+/* Define if libxml2 has the xmlReadMemory function */
+/* #undef HAVE_XMLREADMEMORY */
+
+/* Define if Xrender has the XRenderSetPictureTransform function */
+/* #undef HAVE_XRENDERSETPICTURETRANSFORM */
+
+/* Define to 1 if you have the `z' library (-lz). */
+#define HAVE_ZLIB 1
+
+/* Define to 1 if you have the <zlib.h> header file. */
+#define HAVE_ZLIB_H 1
+
+/* Define to 1 if you have the `_pclose' function. */
+#define HAVE__PCLOSE 1
+
+/* Define to 1 if you have the `_popen' function. */
+#define HAVE__POPEN 1
+
+/* Define to 1 if you have the `_snprintf' function. */
+#define HAVE__SNPRINTF 1
+
+/* Define to 1 if you have the `_spawnvp' function. */
+#define HAVE__SPAWNVP 1
+
+/* Define to 1 if you have the `_strdup' function. */
+#define HAVE__STRDUP 1
+
+/* Define to 1 if you have the `_stricmp' function. */
+/* #undef HAVE__STRICMP */
+
+/* Define to 1 if you have the `_strnicmp' function. */
+/* #undef HAVE__STRNICMP */
+
+/* Define to 1 if you have the `_strtoi64' function. */
+/* #undef HAVE__STRTOI64 */
+
+/* Define to 1 if you have the `_strtoui64' function. */
+/* #undef HAVE__STRTOUI64 */
+
+/* Define to 1 if you have the `_vsnprintf' function. */
+#define HAVE__VSNPRINTF 1
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "wine-devel@winehq.org"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "Wine"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "Wine 1.1.36"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "wine"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL "http://www.winehq.org"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.1.36"
+
+/* Define to the soname of the libcapi20 library. */
+/* #undef SONAME_LIBCAPI20 */
+
+/* Define to the soname of the libcrypto library. */
+/* #undef SONAME_LIBCRYPTO */
+
+/* Define to the soname of the libcups library. */
+/* #undef SONAME_LIBCUPS */
+
+/* Define to the soname of the libcurses library. */
+/* #undef SONAME_LIBCURSES */
+
+/* Define to the soname of the libfontconfig library. */
+/* #undef SONAME_LIBFONTCONFIG */
+
+/* Define to the soname of the libfreetype library. */
+/* #undef SONAME_LIBFREETYPE */
+
+/* Define to the soname of the libGL library. */
+/* #undef SONAME_LIBGL */
+
+/* Define to the soname of the libGLU library. */
+/* #undef SONAME_LIBGLU */
+
+/* Define to the soname of the libgnutls library. */
+/* #undef SONAME_LIBGNUTLS */
+
+/* Define to the soname of the libgsm library. */
+/* #undef SONAME_LIBGSM */
+
+/* Define to the soname of the libhal library. */
+/* #undef SONAME_LIBHAL */
+
+/* Define to the soname of the libjack library. */
+/* #undef SONAME_LIBJACK */
+
+/* Define to the soname of the libjpeg library. */
+/* #undef SONAME_LIBJPEG */
+
+/* Define to the soname of the libncurses library. */
+/* #undef SONAME_LIBNCURSES */
+
+/* Define to the soname of the libodbc library. */
+#define SONAME_LIBODBC "libodbc.dll"
+
+/* Define to the soname of the libpng library. */
+/* #undef SONAME_LIBPNG */
+
+/* Define to the soname of the libsane library. */
+/* #undef SONAME_LIBSANE */
+
+/* Define to the soname of the libssl library. */
+/* #undef SONAME_LIBSSL */
+
+/* Define to the soname of the libX11 library. */
+/* #undef SONAME_LIBX11 */
+
+/* Define to the soname of the libXcomposite library. */
+/* #undef SONAME_LIBXCOMPOSITE */
+
+/* Define to the soname of the libXcursor library. */
+/* #undef SONAME_LIBXCURSOR */
+
+/* Define to the soname of the libXext library. */
+/* #undef SONAME_LIBXEXT */
+
+/* Define to the soname of the libXi library. */
+/* #undef SONAME_LIBXI */
+
+/* Define to the soname of the libXinerama library. */
+/* #undef SONAME_LIBXINERAMA */
+
+/* Define to the soname of the libXrandr library. */
+/* #undef SONAME_LIBXRANDR */
+
+/* Define to the soname of the libXrender library. */
+/* #undef SONAME_LIBXRENDER */
+
+/* Define to the soname of the libxslt library. */
+/* #undef SONAME_LIBXSLT */
+
+/* Define to the soname of the libXxf86vm library. */
+/* #undef SONAME_LIBXXF86VM */
+
+/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+/* #undef STAT_MACROS_BROKEN */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if the X Window System is missing or not being used. */
+#define X_DISPLAY_MISSING 1
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to a macro to output a .cfi assembly pseudo-op */
+#define __ASM_CFI(str) str
+
+/* Define to a macro to define an assembly function */
+#define __ASM_DEFINE_FUNC(name,suffix,code) asm(".text\n\t.align 4\n\t.globl _" #name suffix "\n\t.def _" #name suffix "; .scl 2; .type 32; .endef\n_" #name suffix ":\n\t.cfi_startproc\n\t" code "\n\t.cfi_endproc");
+
+/* Define to a macro to generate an assembly function directive */
+#define __ASM_FUNC(name) ".def " __ASM_NAME(name) "; .scl 2; .type 32; .endef"
+
+/* Define to a macro to generate an assembly function with C calling
+ convention */
+#define __ASM_GLOBAL_FUNC(name,code) __ASM_DEFINE_FUNC(name,"",code)
+
+/* Define to a macro to generate an assembly name from a C symbol */
+#define __ASM_NAME(name) "_" name
+
+/* Define to a macro to generate an stdcall suffix */
+#define __ASM_STDCALL(args) "@" #args
+
+/* Define to a macro to generate an assembly function with stdcall calling
+ convention */
+#define __ASM_STDCALL_FUNC(name,args,code) __ASM_DEFINE_FUNC(name,__ASM_STDCALL(args),code)
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/d3d8.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/d3d8.h
new file mode 100644
index 00000000..16c694bd
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/d3d8.h
@@ -0,0 +1,1153 @@
+/*
+ * Copyright (C) 2002 Jason Edmeades
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#ifndef __WINE_D3D8_H
+#define __WINE_D3D8_H
+
+#ifndef DIRECT3D_VERSION
+#define DIRECT3D_VERSION 0x0800
+#endif
+
+#include <stdlib.h>
+
+#define COM_NO_WINDOWS_H
+#include <objbase.h>
+#include <windows.h>
+#include <d3d8types.h>
+#include <d3d8caps.h>
+
+#define __MSABI_LONG(_n) _n##L
+
+/*****************************************************************************
+ * Behavior Flags for IDirect3D8::CreateDevice
+ */
+#define D3DCREATE_FPU_PRESERVE __MSABI_LONG(0x00000002)
+#define D3DCREATE_MULTITHREADED __MSABI_LONG(0x00000004)
+#define D3DCREATE_PUREDEVICE __MSABI_LONG(0x00000010)
+#define D3DCREATE_SOFTWARE_VERTEXPROCESSING __MSABI_LONG(0x00000020)
+#define D3DCREATE_HARDWARE_VERTEXPROCESSING __MSABI_LONG(0x00000040)
+#define D3DCREATE_MIXED_VERTEXPROCESSING __MSABI_LONG(0x00000080)
+
+/*****************************************************************************
+ * Flags for SetPrivateData
+ */
+#define D3DSPD_IUNKNOWN __MSABI_LONG(0x00000001)
+
+/*****************************************************************************
+ * #defines and error codes
+ */
+#define D3D_SDK_VERSION 220
+#define D3DADAPTER_DEFAULT 0
+#define D3DENUM_NO_WHQL_LEVEL 2
+
+#define _FACD3D 0x876
+#define MAKE_D3DHRESULT( code ) MAKE_HRESULT( 1, _FACD3D, code )
+
+/*
+ * Direct3D Errors
+ */
+#define D3D_OK S_OK
+#define D3DERR_WRONGTEXTUREFORMAT MAKE_D3DHRESULT(2072)
+#define D3DERR_UNSUPPORTEDCOLOROPERATION MAKE_D3DHRESULT(2073)
+#define D3DERR_UNSUPPORTEDCOLORARG MAKE_D3DHRESULT(2074)
+#define D3DERR_UNSUPPORTEDALPHAOPERATION MAKE_D3DHRESULT(2075)
+#define D3DERR_UNSUPPORTEDALPHAARG MAKE_D3DHRESULT(2076)
+#define D3DERR_TOOMANYOPERATIONS MAKE_D3DHRESULT(2077)
+#define D3DERR_CONFLICTINGTEXTUREFILTER MAKE_D3DHRESULT(2078)
+#define D3DERR_UNSUPPORTEDFACTORVALUE MAKE_D3DHRESULT(2079)
+#define D3DERR_CONFLICTINGRENDERSTATE MAKE_D3DHRESULT(2081)
+#define D3DERR_UNSUPPORTEDTEXTUREFILTER MAKE_D3DHRESULT(2082)
+#define D3DERR_CONFLICTINGTEXTUREPALETTE MAKE_D3DHRESULT(2086)
+#define D3DERR_DRIVERINTERNALERROR MAKE_D3DHRESULT(2087)
+
+#define D3DERR_NOTFOUND MAKE_D3DHRESULT(2150)
+#define D3DERR_MOREDATA MAKE_D3DHRESULT(2151)
+#define D3DERR_DEVICELOST MAKE_D3DHRESULT(2152)
+#define D3DERR_DEVICENOTRESET MAKE_D3DHRESULT(2153)
+#define D3DERR_NOTAVAILABLE MAKE_D3DHRESULT(2154)
+#define D3DERR_OUTOFVIDEOMEMORY MAKE_D3DHRESULT(380)
+#define D3DERR_INVALIDDEVICE MAKE_D3DHRESULT(2155)
+#define D3DERR_INVALIDCALL MAKE_D3DHRESULT(2156)
+#define D3DERR_DRIVERINVALIDCALL MAKE_D3DHRESULT(2157)
+
+/*****************************************************************************
+ * Predeclare the interfaces
+ */
+DEFINE_GUID(IID_IDirect3D8, 0x1DD9E8DA,0x1C77,0x4D40,0xB0,0xCF,0x98,0xFE,0xFD,0xFF,0x95,0x12);
+typedef struct IDirect3D8 *LPDIRECT3D8;
+
+DEFINE_GUID(IID_IDirect3DDevice8, 0x7385E5DF,0x8FE8,0x41D5,0x86,0xB6,0xD7,0xB4,0x85,0x47,0xB6,0xCF);
+typedef struct IDirect3DDevice8 *LPDIRECT3DDEVICE8;
+
+DEFINE_GUID(IID_IDirect3DResource8, 0x1B36BB7B,0x09B7,0x410A,0xB4,0x45,0x7D,0x14,0x30,0xD7,0xB3,0x3F);
+typedef struct IDirect3DResource8 *LPDIRECT3DRESOURCE8, *PDIRECT3DRESOURCE8;
+
+DEFINE_GUID(IID_IDirect3DVertexBuffer8, 0x8AEEEAC7,0x05F9,0x44D4,0xB5,0x91,0x00,0x0B,0x0D,0xF1,0xCB,0x95);
+typedef struct IDirect3DVertexBuffer8 *LPDIRECT3DVERTEXBUFFER8, *PDIRECT3DVERTEXBUFFER8;
+
+DEFINE_GUID(IID_IDirect3DVolume8, 0xBD7349F5,0x14F1,0x42E4,0x9C,0x79,0x97,0x23,0x80,0xDB,0x40,0xC0);
+typedef struct IDirect3DVolume8 *LPDIRECT3DVOLUME8, *PDIRECT3DVOLUME8;
+
+DEFINE_GUID(IID_IDirect3DSwapChain8, 0x928C088B,0x76B9,0x4C6B,0xA5,0x36,0xA5,0x90,0x85,0x38,0x76,0xCD);
+typedef struct IDirect3DSwapChain8 *LPDIRECT3DSWAPCHAIN8, *PDIRECT3DSWAPCHAIN8;
+
+DEFINE_GUID(IID_IDirect3DSurface8, 0xB96EEBCA,0xB326,0x4EA5,0x88,0x2F,0x2F,0xF5,0xBA,0xE0,0x21,0xDD);
+typedef struct IDirect3DSurface8 *LPDIRECT3DSURFACE8, *PDIRECT3DSURFACE8;
+
+DEFINE_GUID(IID_IDirect3DIndexBuffer8, 0x0E689C9A,0x053D,0x44A0,0x9D,0x92,0xDB,0x0E,0x3D,0x75,0x0F,0x86);
+typedef struct IDirect3DIndexBuffer8 *LPDIRECT3DINDEXBUFFER8, *PDIRECT3DINDEXBUFFER8;
+
+DEFINE_GUID(IID_IDirect3DBaseTexture8, 0xB4211CFA,0x51B9,0x4A9F,0xAB,0x78,0xDB,0x99,0xB2,0xBB,0x67,0x8E);
+typedef struct IDirect3DBaseTexture8 *LPDIRECT3DBASETEXTURE8, *PDIRECT3DBASETEXTURE8;
+
+DEFINE_GUID(IID_IDirect3DTexture8, 0xE4CDD575,0x2866,0x4F01,0xB1,0x2E,0x7E,0xEC,0xE1,0xEC,0x93,0x58);
+typedef struct IDirect3DTexture8 *LPDIRECT3DTEXTURE8, *PDIRECT3DTEXTURE8;
+
+DEFINE_GUID(IID_IDirect3DCubeTexture8, 0x3EE5B968,0x2ACA,0x4C34,0x8B,0xB5,0x7E,0x0C,0x3D,0x19,0xB7,0x50);
+typedef struct IDirect3DCubeTexture8 *LPDIRECT3DCUBETEXTURE8, *PDIRECT3DCUBETEXTURE8;
+
+DEFINE_GUID(IID_IDirect3DVolumeTexture8, 0x4B8AAAFA,0x140F,0x42BA,0x91,0x31,0x59,0x7E,0xAF,0xAA,0x2E,0xAD);
+typedef struct IDirect3DVolumeTexture8 *LPDIRECT3DVOLUMETEXTURE8, *PDIRECT3DVOLUMETEXTURE8;
+
+/*****************************************************************************
+ * IDirect3D8 interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirect3D8
+DECLARE_INTERFACE_(IDirect3D8,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3D8 methods ***/
+ STDMETHOD(RegisterSoftwareDevice)(THIS_ void * pInitializeFunction) PURE;
+ STDMETHOD_(UINT,GetAdapterCount )(THIS) PURE;
+ STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER8 * pIdentifier) PURE;
+ STDMETHOD_(UINT,GetAdapterModeCount)(THIS_ UINT Adapter) PURE;
+ STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter, UINT Mode, D3DDISPLAYMODE * pMode) PURE;
+ STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT Adapter, D3DDISPLAYMODE * pMode) PURE;
+ STDMETHOD(CheckDeviceType)(THIS_ UINT Adapter, D3DDEVTYPE CheckType, D3DFORMAT DisplayFormat, D3DFORMAT BackBufferFormat, BOOL Windowed) PURE;
+ STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) PURE;
+ STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType) PURE;
+ STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) PURE;
+ STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS8 * pCaps) PURE;
+ STDMETHOD_(HMONITOR,GetAdapterMonitor)(THIS_ UINT Adapter) PURE;
+ STDMETHOD(CreateDevice)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType,HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS * pPresentationParameters, struct IDirect3DDevice8 ** ppReturnedDeviceInterface) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3D8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3D8_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3D8_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3D8 methods ***/
+#define IDirect3D8_RegisterSoftwareDevice(p,a) (p)->lpVtbl->RegisterSoftwareDevice(p,a)
+#define IDirect3D8_GetAdapterCount(p) (p)->lpVtbl->GetAdapterCount(p)
+#define IDirect3D8_GetAdapterIdentifier(p,a,b,c) (p)->lpVtbl->GetAdapterIdentifier(p,a,b,c)
+#define IDirect3D8_GetAdapterModeCount(p,a) (p)->lpVtbl->GetAdapterModeCount(p,a)
+#define IDirect3D8_EnumAdapterModes(p,a,b,c) (p)->lpVtbl->EnumAdapterModes(p,a,b,c)
+#define IDirect3D8_GetAdapterDisplayMode(p,a,b) (p)->lpVtbl->GetAdapterDisplayMode(p,a,b)
+#define IDirect3D8_CheckDeviceType(p,a,b,c,d,e) (p)->lpVtbl->CheckDeviceType(p,a,b,c,d,e)
+#define IDirect3D8_CheckDeviceFormat(p,a,b,c,d,e,f) (p)->lpVtbl->CheckDeviceFormat(p,a,b,c,d,e,f)
+#define IDirect3D8_CheckDeviceMultiSampleType(p,a,b,c,d,e) (p)->lpVtbl->CheckDeviceMultiSampleType(p,a,b,c,d,e)
+#define IDirect3D8_CheckDepthStencilMatch(p,a,b,c,d,e) (p)->lpVtbl->CheckDepthStencilMatch(p,a,b,c,d,e)
+#define IDirect3D8_GetDeviceCaps(p,a,b,c) (p)->lpVtbl->GetDeviceCaps(p,a,b,c)
+#define IDirect3D8_GetAdapterMonitor(p,a) (p)->lpVtbl->GetAdapterMonitor(p,a)
+#define IDirect3D8_CreateDevice(p,a,b,c,d,e,f) (p)->lpVtbl->CreateDevice(p,a,b,c,d,e,f)
+#else
+/*** IUnknown methods ***/
+#define IDirect3D8_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3D8_AddRef(p) (p)->AddRef()
+#define IDirect3D8_Release(p) (p)->Release()
+/*** IDirect3D8 methods ***/
+#define IDirect3D8_RegisterSoftwareDevice(p,a) (p)->RegisterSoftwareDevice(a)
+#define IDirect3D8_GetAdapterCount(p) (p)->GetAdapterCount()
+#define IDirect3D8_GetAdapterIdentifier(p,a,b,c) (p)->GetAdapterIdentifier(a,b,c)
+#define IDirect3D8_GetAdapterModeCount(p,a) (p)->GetAdapterModeCount(a)
+#define IDirect3D8_EnumAdapterModes(p,a,b,c) (p)->EnumAdapterModes(a,b,c)
+#define IDirect3D8_GetAdapterDisplayMode(p,a,b) (p)->GetAdapterDisplayMode(a,b)
+#define IDirect3D8_CheckDeviceType(p,a,b,c,d,e) (p)->CheckDeviceType(a,b,c,d,e)
+#define IDirect3D8_CheckDeviceFormat(p,a,b,c,d,e,f) (p)->CheckDeviceFormat(a,b,c,d,e,f)
+#define IDirect3D8_CheckDeviceMultiSampleType(p,a,b,c,d,e) (p)->CheckDeviceMultiSampleType(a,b,c,d,e)
+#define IDirect3D8_CheckDepthStencilMatch(p,a,b,c,d,e) (p)->CheckDepthStencilMatch(a,b,c,d,e)
+#define IDirect3D8_GetDeviceCaps(p,a,b,c) (p)->GetDeviceCaps(a,b,c)
+#define IDirect3D8_GetAdapterMonitor(p,a) (p)->GetAdapterMonitor(a)
+#define IDirect3D8_CreateDevice(p,a,b,c,d,e,f) (p)->CreateDevice(a,b,c,d,e,f)
+#endif
+
+/*****************************************************************************
+ * IDirect3DVolume8 interface
+ */
+#define INTERFACE IDirect3DVolume8
+DECLARE_INTERFACE_(IDirect3DVolume8,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DVolume8 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice8 ** ppDevice) PURE;
+ STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void * pData, DWORD SizeOfData, DWORD Flags) PURE;
+ STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void * pData, DWORD * pSizeOfData) PURE;
+ STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+ STDMETHOD(GetContainer)(THIS_ REFIID riid, void ** ppContainer) PURE;
+ STDMETHOD(GetDesc)(THIS_ D3DVOLUME_DESC * pDesc) PURE;
+ STDMETHOD(LockBox)(THIS_ D3DLOCKED_BOX * pLockedVolume,CONST D3DBOX * pBox, DWORD Flags) PURE;
+ STDMETHOD(UnlockBox)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DVolume8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DVolume8_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DVolume8_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DVolume8 methods ***/
+#define IDirect3DVolume8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DVolume8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DVolume8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DVolume8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DVolume8_GetContainer(p,a,b) (p)->lpVtbl->GetContainer(p,a,b)
+#define IDirect3DVolume8_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a)
+#define IDirect3DVolume8_LockBox(p,a,b,c) (p)->lpVtbl->LockBox(p,a,b,c)
+#define IDirect3DVolume8_UnlockBox(p) (p)->lpVtbl->UnlockBox(p)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DVolume8_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DVolume8_AddRef(p) (p)->AddRef()
+#define IDirect3DVolume8_Release(p) (p)->Release()
+/*** IDirect3DVolume8 methods ***/
+#define IDirect3DVolume8_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DVolume8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DVolume8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirect3DVolume8_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirect3DVolume8_GetContainer(p,a,b) (p)->GetContainer(a,b)
+#define IDirect3DVolume8_GetDesc(p,a) (p)->GetDesc(a)
+#define IDirect3DVolume8_LockBox(p,a,b,c) (p)->LockBox(a,b,c)
+#define IDirect3DVolume8_UnlockBox(p) (p)->UnlockBox()
+#endif
+
+/*****************************************************************************
+ * IDirect3DSwapChain8 interface
+ */
+#define INTERFACE IDirect3DSwapChain8
+DECLARE_INTERFACE_(IDirect3DSwapChain8,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DSwapChain8 methods ***/
+ STDMETHOD(Present)(THIS_ CONST RECT * pSourceRect, CONST RECT * pDestRect, HWND hDestWindowOverride,CONST RGNDATA * pDirtyRegion) PURE;
+ STDMETHOD(GetBackBuffer)(THIS_ UINT BackBuffer, D3DBACKBUFFER_TYPE Type, struct IDirect3DSurface8 ** ppBackBuffer) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DSwapChain8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DSwapChain8_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DSwapChain8_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DSwapChain8 methods ***/
+#define IDirect3DSwapChain8_Present(p,a,b,c) (p)->lpVtbl->Present(p,a,b,c)
+#define IDirect3DSwapChain8_GetBackBuffer(p,a,b,c) (p)->lpVtbl->GetBackBuffer(p,a,b,c)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DSwapChain8_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DSwapChain8_AddRef(p) (p)->AddRef()
+#define IDirect3DSwapChain8_Release(p) (p)->Release()
+/*** IDirect3DSwapChain8 methods ***/
+#define IDirect3DSwapChain8_Present(p,a,b,c) (p)->Present(a,b,c)
+#define IDirect3DSwapChain8_GetBackBuffer(p,a,b,c) (p)->GetBackBuffer(a,b,c)
+#endif
+
+/*****************************************************************************
+ * IDirect3DSurface8 interface
+ */
+#define INTERFACE IDirect3DSurface8
+DECLARE_INTERFACE_(IDirect3DSurface8,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DSurface8 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice8 ** ppDevice) PURE;
+ STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void * pData,DWORD SizeOfData,DWORD Flags) PURE;
+ STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void * pData,DWORD * pSizeOfData) PURE;
+ STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+ STDMETHOD(GetContainer)(THIS_ REFIID riid, void ** ppContainer) PURE;
+ STDMETHOD(GetDesc)(THIS_ D3DSURFACE_DESC * pDesc) PURE;
+ STDMETHOD(LockRect)(THIS_ D3DLOCKED_RECT * pLockedRect, CONST RECT * pRect,DWORD Flags) PURE;
+ STDMETHOD(UnlockRect)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DSurface8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DSurface8_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DSurface8_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DSurface8 methods ***/
+#define IDirect3DSurface8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DSurface8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DSurface8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DSurface8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DSurface8_GetContainer(p,a,b) (p)->lpVtbl->GetContainer(p,a,b)
+#define IDirect3DSurface8_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a)
+#define IDirect3DSurface8_LockRect(p,a,b,c) (p)->lpVtbl->LockRect(p,a,b,c)
+#define IDirect3DSurface8_UnlockRect(p) (p)->lpVtbl->UnlockRect(p)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DSurface8_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DSurface8_AddRef(p) (p)->AddRef()
+#define IDirect3DSurface8_Release(p) (p)->Release()
+/*** IDirect3DSurface8 methods ***/
+#define IDirect3DSurface8_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DSurface8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DSurface8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirect3DSurface8_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirect3DSurface8_GetContainer(p,a,b) (p)->GetContainer(a,b)
+#define IDirect3DSurface8_GetDesc(p,a) (p)->GetDesc(a)
+#define IDirect3DSurface8_LockRect(p,a,b,c) (p)->LockRect(a,b,c)
+#define IDirect3DSurface8_UnlockRect(p) (p)->UnlockRect()
+#endif
+
+/*****************************************************************************
+ * IDirect3DResource8 interface
+ */
+#define INTERFACE IDirect3DResource8
+DECLARE_INTERFACE_(IDirect3DResource8,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DResource8 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice8 ** ppDevice) PURE;
+ STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void * pData, DWORD SizeOfData, DWORD Flags) PURE;
+ STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void * pData, DWORD * pSizeOfData) PURE;
+ STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+ STDMETHOD_(DWORD,SetPriority)(THIS_ DWORD PriorityNew) PURE;
+ STDMETHOD_(DWORD,GetPriority)(THIS) PURE;
+ STDMETHOD_(void,PreLoad)(THIS) PURE;
+ STDMETHOD_(D3DRESOURCETYPE,GetType)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DResource8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DResource8_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DResource8_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DResource8 methods ***/
+#define IDirect3DResource8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DResource8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DResource8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DResource8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DResource8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DResource8_GetPriority(p) (p)->lpVtbl->GetPriority(p)
+#define IDirect3DResource8_PreLoad(p) (p)->lpVtbl->PreLoad(p)
+#define IDirect3DResource8_GetType(p) (p)->lpVtbl->GetType(p)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DResource8_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DResource8_AddRef(p) (p)->AddRef()
+#define IDirect3DResource8_Release(p) (p)->Release()
+/*** IDirect3DResource8 methods ***/
+#define IDirect3DResource8_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DResource8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DResource8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirect3DResource8_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirect3DResource8_SetPriority(p,a) (p)->SetPriority(a)
+#define IDirect3DResource8_GetPriority(p) (p)->GetPriority()
+#define IDirect3DResource8_PreLoad(p) (p)->PreLoad()
+#define IDirect3DResource8_GetType(p) (p)->GetType()
+#endif
+
+/*****************************************************************************
+ * IDirect3DVertexBuffer8 interface
+ */
+#define INTERFACE IDirect3DVertexBuffer8
+DECLARE_INTERFACE_(IDirect3DVertexBuffer8,IDirect3DResource8)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DResource8 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice8 ** ppDevice) PURE;
+ STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void * pData, DWORD SizeOfData, DWORD Flags) PURE;
+ STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void * pData, DWORD * pSizeOfData) PURE;
+ STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+ STDMETHOD_(DWORD,SetPriority)(THIS_ DWORD PriorityNew) PURE;
+ STDMETHOD_(DWORD,GetPriority)(THIS) PURE;
+ STDMETHOD_(void,PreLoad)(THIS) PURE;
+ STDMETHOD_(D3DRESOURCETYPE,GetType)(THIS) PURE;
+ /*** IDirect3DVertexBuffer8 methods ***/
+ STDMETHOD(Lock)(THIS_ UINT OffsetToLock, UINT SizeToLock, BYTE ** ppbData, DWORD Flags) PURE;
+ STDMETHOD(Unlock)(THIS) PURE;
+ STDMETHOD(GetDesc)(THIS_ D3DVERTEXBUFFER_DESC * pDesc) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DVertexBuffer8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DVertexBuffer8_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DVertexBuffer8_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DVertexBuffer8 methods: IDirect3DResource8 ***/
+#define IDirect3DVertexBuffer8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DVertexBuffer8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DVertexBuffer8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DVertexBuffer8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DVertexBuffer8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DVertexBuffer8_GetPriority(p) (p)->lpVtbl->GetPriority(p)
+#define IDirect3DVertexBuffer8_PreLoad(p) (p)->lpVtbl->PreLoad(p)
+#define IDirect3DVertexBuffer8_GetType(p) (p)->lpVtbl->GetType(p)
+/*** IDirect3DVertexBuffer8 methods ***/
+#define IDirect3DVertexBuffer8_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d)
+#define IDirect3DVertexBuffer8_Unlock(p) (p)->lpVtbl->Unlock(p)
+#define IDirect3DVertexBuffer8_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DVertexBuffer8_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DVertexBuffer8_AddRef(p) (p)->AddRef()
+#define IDirect3DVertexBuffer8_Release(p) (p)->Release()
+/*** IDirect3DVertexBuffer8 methods: IDirect3DResource8 ***/
+#define IDirect3DVertexBuffer8_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DVertexBuffer8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DVertexBuffer8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirect3DVertexBuffer8_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirect3DVertexBuffer8_SetPriority(p,a) (p)->SetPriority(a)
+#define IDirect3DVertexBuffer8_GetPriority(p) (p)->GetPriority()
+#define IDirect3DVertexBuffer8_PreLoad(p) (p)->PreLoad()
+#define IDirect3DVertexBuffer8_GetType(p) (p)->GetType()
+/*** IDirect3DVertexBuffer8 methods ***/
+#define IDirect3DVertexBuffer8_Lock(p,a,b,c,d) (p)->Lock(a,b,c,d)
+#define IDirect3DVertexBuffer8_Unlock(p) (p)->Unlock()
+#define IDirect3DVertexBuffer8_GetDesc(p,a) (p)->GetDesc(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DIndexBuffer8 interface
+ */
+#define INTERFACE IDirect3DIndexBuffer8
+DECLARE_INTERFACE_(IDirect3DIndexBuffer8,IDirect3DResource8)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DResource8 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice8 ** ppDevice) PURE;
+ STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void * pData, DWORD SizeOfData, DWORD Flags) PURE;
+ STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void * pData, DWORD * pSizeOfData) PURE;
+ STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+ STDMETHOD_(DWORD,SetPriority)(THIS_ DWORD PriorityNew) PURE;
+ STDMETHOD_(DWORD,GetPriority)(THIS) PURE;
+ STDMETHOD_(void,PreLoad)(THIS) PURE;
+ STDMETHOD_(D3DRESOURCETYPE,GetType)(THIS) PURE;
+ /*** IDirect3DIndexBuffer8 methods ***/
+ STDMETHOD(Lock)(THIS_ UINT OffsetToLock, UINT SizeToLock, BYTE ** ppbData, DWORD Flags) PURE;
+ STDMETHOD(Unlock)(THIS) PURE;
+ STDMETHOD(GetDesc)(THIS_ D3DINDEXBUFFER_DESC * pDesc) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DIndexBuffer8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DIndexBuffer8_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DIndexBuffer8_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DIndexBuffer8 methods: IDirect3DResource8 ***/
+#define IDirect3DIndexBuffer8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DIndexBuffer8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DIndexBuffer8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DIndexBuffer8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DIndexBuffer8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DIndexBuffer8_GetPriority(p) (p)->lpVtbl->GetPriority(p)
+#define IDirect3DIndexBuffer8_PreLoad(p) (p)->lpVtbl->PreLoad(p)
+#define IDirect3DIndexBuffer8_GetType(p) (p)->lpVtbl->GetType(p)
+/*** IDirect3DIndexBuffer8 methods ***/
+#define IDirect3DIndexBuffer8_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d)
+#define IDirect3DIndexBuffer8_Unlock(p) (p)->lpVtbl->Unlock(p)
+#define IDirect3DIndexBuffer8_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DIndexBuffer8_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DIndexBuffer8_AddRef(p) (p)->AddRef()
+#define IDirect3DIndexBuffer8_Release(p) (p)->Release()
+/*** IDirect3DIndexBuffer8 methods: IDirect3DResource8 ***/
+#define IDirect3DIndexBuffer8_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DIndexBuffer8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DIndexBuffer8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirect3DIndexBuffer8_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirect3DIndexBuffer8_SetPriority(p,a) (p)->SetPriority(a)
+#define IDirect3DIndexBuffer8_GetPriority(p) (p)->GetPriority()
+#define IDirect3DIndexBuffer8_PreLoad(p) (p)->PreLoad()
+#define IDirect3DIndexBuffer8_GetType(p) (p)->GetType()
+/*** IDirect3DIndexBuffer8 methods ***/
+#define IDirect3DIndexBuffer8_Lock(p,a,b,c,d) (p)->Lock(a,b,c,d)
+#define IDirect3DIndexBuffer8_Unlock(p) (p)->Unlock()
+#define IDirect3DIndexBuffer8_GetDesc(p,a) (p)->GetDesc(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DBaseTexture8 interface
+ */
+#define INTERFACE IDirect3DBaseTexture8
+DECLARE_INTERFACE_(IDirect3DBaseTexture8,IDirect3DResource8)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DResource8 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice8 ** ppDevice) PURE;
+ STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void * pData, DWORD SizeOfData, DWORD Flags) PURE;
+ STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void * pData, DWORD * pSizeOfData) PURE;
+ STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+ STDMETHOD_(DWORD,SetPriority)(THIS_ DWORD PriorityNew) PURE;
+ STDMETHOD_(DWORD,GetPriority)(THIS) PURE;
+ STDMETHOD_(void,PreLoad)(THIS) PURE;
+ STDMETHOD_(D3DRESOURCETYPE,GetType)(THIS) PURE;
+ /*** IDirect3DBaseTexture8 methods ***/
+ STDMETHOD_(DWORD,SetLOD)(THIS_ DWORD LODNew) PURE;
+ STDMETHOD_(DWORD,GetLOD)(THIS) PURE;
+ STDMETHOD_(DWORD,GetLevelCount)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DBaseTexture8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DBaseTexture8_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DBaseTexture8_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DBaseTexture8 methods: IDirect3DResource8 ***/
+#define IDirect3DBaseTexture8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DBaseTexture8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DBaseTexture8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DBaseTexture8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DBaseTexture8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DBaseTexture8_GetPriority(p) (p)->lpVtbl->GetPriority(p)
+#define IDirect3DBaseTexture8_PreLoad(p) (p)->lpVtbl->PreLoad(p)
+#define IDirect3DBaseTexture8_GetType(p) (p)->lpVtbl->GetType(p)
+/*** IDirect3DBaseTexture8 methods ***/
+#define IDirect3DBaseTexture8_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a)
+#define IDirect3DBaseTexture8_GetLOD(p) (p)->lpVtbl->GetLOD(p)
+#define IDirect3DBaseTexture8_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DBaseTexture8_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DBaseTexture8_AddRef(p) (p)->AddRef()
+#define IDirect3DBaseTexture8_Release(p) (p)->Release()
+/*** IDirect3DBaseTexture8 methods: IDirect3DResource8 ***/
+#define IDirect3DBaseTexture8_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DBaseTexture8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DBaseTexture8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirect3DBaseTexture8_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirect3DBaseTexture8_SetPriority(p,a) (p)->SetPriority(a)
+#define IDirect3DBaseTexture8_GetPriority(p) (p)->GetPriority()
+#define IDirect3DBaseTexture8_PreLoad(p) (p)->PreLoad()
+#define IDirect3DBaseTexture8_GetType(p) (p)->GetType()
+/*** IDirect3DBaseTexture8 methods ***/
+#define IDirect3DBaseTexture8_SetLOD(p,a) (p)->SetLOD(a)
+#define IDirect3DBaseTexture8_GetLOD(p) (p)->GetLOD()
+#define IDirect3DBaseTexture8_GetLevelCount(p) (p)->GetLevelCount()
+#endif
+
+/*****************************************************************************
+ * IDirect3DCubeTexture8 interface
+ */
+#define INTERFACE IDirect3DCubeTexture8
+DECLARE_INTERFACE_(IDirect3DCubeTexture8,IDirect3DBaseTexture8)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DResource8 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice8 ** ppDevice) PURE;
+ STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void * pData, DWORD SizeOfData, DWORD Flags) PURE;
+ STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void * pData, DWORD * pSizeOfData) PURE;
+ STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+ STDMETHOD_(DWORD,SetPriority)(THIS_ DWORD PriorityNew) PURE;
+ STDMETHOD_(DWORD,GetPriority)(THIS) PURE;
+ STDMETHOD_(void,PreLoad)(THIS) PURE;
+ STDMETHOD_(D3DRESOURCETYPE,GetType)(THIS) PURE;
+ /*** IDirect3DBaseTexture8 methods ***/
+ STDMETHOD_(DWORD,SetLOD)(THIS_ DWORD LODNew) PURE;
+ STDMETHOD_(DWORD,GetLOD)(THIS) PURE;
+ STDMETHOD_(DWORD,GetLevelCount)(THIS) PURE;
+ /*** IDirect3DCubeTexture8 methods ***/
+ STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DSURFACE_DESC * pDesc) PURE;
+ STDMETHOD(GetCubeMapSurface)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level,IDirect3DSurface8 ** ppCubeMapSurface) PURE;
+ STDMETHOD(LockRect)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level,D3DLOCKED_RECT * pLockedRect,CONST RECT * pRect,DWORD Flags) PURE;
+ STDMETHOD(UnlockRect)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level) PURE;
+ STDMETHOD(AddDirtyRect)(THIS_ D3DCUBEMAP_FACES FaceType,CONST RECT * pDirtyRect) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DCubeTexture8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DCubeTexture8_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DCubeTexture8_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DCubeTexture8 methods: IDirect3DResource8 ***/
+#define IDirect3DCubeTexture8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DCubeTexture8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DCubeTexture8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DCubeTexture8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DCubeTexture8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DCubeTexture8_GetPriority(p) (p)->lpVtbl->GetPriority(p)
+#define IDirect3DCubeTexture8_PreLoad(p) (p)->lpVtbl->PreLoad(p)
+#define IDirect3DCubeTexture8_GetType(p) (p)->lpVtbl->GetType(p)
+/*** IDirect3DCubeTexture8 methods: IDirect3DBaseTexture8 ***/
+#define IDirect3DCubeTexture8_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a)
+#define IDirect3DCubeTexture8_GetLOD(p) (p)->lpVtbl->GetLOD(p)
+#define IDirect3DCubeTexture8_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p)
+/*** IDirect3DCubeTexture8 methods ***/
+#define IDirect3DCubeTexture8_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b)
+#define IDirect3DCubeTexture8_GetCubeMapSurface(p,a,b,c) (p)->lpVtbl->GetCubeMapSurface(p,a,b,c)
+#define IDirect3DCubeTexture8_LockRect(p,a,b,c,d,e) (p)->lpVtbl->LockRect(p,a,b,c,d,e)
+#define IDirect3DCubeTexture8_UnlockRect(p,a,b) (p)->lpVtbl->UnlockRect(p,a,b)
+#define IDirect3DCubeTexture8_AddDirtyRect(p,a,b) (p)->lpVtbl->AddDirtyRect(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DCubeTexture8_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DCubeTexture8_AddRef(p) (p)->AddRef()
+#define IDirect3DCubeTexture8_Release(p) (p)->Release()
+/*** IDirect3DCubeTexture8 methods: IDirect3DResource8 ***/
+#define IDirect3DCubeTexture8_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DCubeTexture8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DCubeTexture8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirect3DCubeTexture8_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirect3DCubeTexture8_SetPriority(p,a) (p)->SetPriority(a)
+#define IDirect3DCubeTexture8_GetPriority(p) (p)->GetPriority()
+#define IDirect3DCubeTexture8_PreLoad(p) (p)->PreLoad()
+#define IDirect3DCubeTexture8_GetType(p) (p)->GetType()
+/*** IDirect3DCubeTexture8 methods: IDirect3DBaseTexture8 ***/
+#define IDirect3DCubeTexture8_SetLOD(p,a) (p)->SetLOD(a)
+#define IDirect3DCubeTexture8_GetLOD(p) (p)->GetLOD()
+#define IDirect3DCubeTexture8_GetLevelCount(p) (p)->GetLevelCount()
+/*** IDirect3DCubeTexture8 methods ***/
+#define IDirect3DCubeTexture8_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b)
+#define IDirect3DCubeTexture8_GetCubeMapSurface(p,a,b,c) (p)->GetCubeMapSurface(a,b,c)
+#define IDirect3DCubeTexture8_LockRect(p,a,b,c,d,e) (p)->LockRect(a,b,c,d,e)
+#define IDirect3DCubeTexture8_UnlockRect(p,a,b) (p)->UnlockRect(a,b)
+#define IDirect3DCubeTexture8_AddDirtyRect(p,a,b) (p)->AddDirtyRect(a,b)
+#endif
+
+/*****************************************************************************
+ * IDirect3DTexture8 interface
+ */
+#define INTERFACE IDirect3DTexture8
+DECLARE_INTERFACE_(IDirect3DTexture8,IDirect3DBaseTexture8)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DResource8 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice8 ** ppDevice) PURE;
+ STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void * pData, DWORD SizeOfData, DWORD Flags) PURE;
+ STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void * pData, DWORD * pSizeOfData) PURE;
+ STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+ STDMETHOD_(DWORD,SetPriority)(THIS_ DWORD PriorityNew) PURE;
+ STDMETHOD_(DWORD,GetPriority)(THIS) PURE;
+ STDMETHOD_(void,PreLoad)(THIS) PURE;
+ STDMETHOD_(D3DRESOURCETYPE,GetType)(THIS) PURE;
+ /*** IDirect3DBaseTexture8 methods ***/
+ STDMETHOD_(DWORD,SetLOD)(THIS_ DWORD LODNew) PURE;
+ STDMETHOD_(DWORD,GetLOD)(THIS) PURE;
+ STDMETHOD_(DWORD,GetLevelCount)(THIS) PURE;
+ /*** IDirect3DTexture8 methods ***/
+ STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DSURFACE_DESC * pDesc) PURE;
+ STDMETHOD(GetSurfaceLevel)(THIS_ UINT Level,IDirect3DSurface8 ** ppSurfaceLevel) PURE;
+ STDMETHOD(LockRect)(THIS_ UINT Level,D3DLOCKED_RECT * pLockedRect,CONST RECT * pRect,DWORD Flags) PURE;
+ STDMETHOD(UnlockRect)(THIS_ UINT Level) PURE;
+ STDMETHOD(AddDirtyRect)(THIS_ CONST RECT * pDirtyRect) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DTexture8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DTexture8_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DTexture8_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DTexture8 methods: IDirect3DResource8 ***/
+#define IDirect3DTexture8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DTexture8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DTexture8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DTexture8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DTexture8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DTexture8_GetPriority(p) (p)->lpVtbl->GetPriority(p)
+#define IDirect3DTexture8_PreLoad(p) (p)->lpVtbl->PreLoad(p)
+#define IDirect3DTexture8_GetType(p) (p)->lpVtbl->GetType(p)
+/*** IDirect3DTexture8 methods: IDirect3DBaseTexture8 ***/
+#define IDirect3DTexture8_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a)
+#define IDirect3DTexture8_GetLOD(p) (p)->lpVtbl->GetLOD(p)
+#define IDirect3DTexture8_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p)
+/*** IDirect3DTexture8 methods ***/
+#define IDirect3DTexture8_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b)
+#define IDirect3DTexture8_GetSurfaceLevel(p,a,b) (p)->lpVtbl->GetSurfaceLevel(p,a,b)
+#define IDirect3DTexture8_LockRect(p,a,b,c,d) (p)->lpVtbl->LockRect(p,a,b,c,d)
+#define IDirect3DTexture8_UnlockRect(p,a) (p)->lpVtbl->UnlockRect(p,a)
+#define IDirect3DTexture8_AddDirtyRect(p,a) (p)->lpVtbl->AddDirtyRect(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DTexture8_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DTexture8_AddRef(p) (p)->AddRef()
+#define IDirect3DTexture8_Release(p) (p)->Release()
+/*** IDirect3DTexture8 methods: IDirect3DResource8 ***/
+#define IDirect3DTexture8_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DTexture8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DTexture8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirect3DTexture8_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirect3DTexture8_SetPriority(p,a) (p)->SetPriority(a)
+#define IDirect3DTexture8_GetPriority(p) (p)->GetPriority()
+#define IDirect3DTexture8_PreLoad(p) (p)->PreLoad()
+#define IDirect3DTexture8_GetType(p) (p)->GetType()
+/*** IDirect3DTexture8 methods: IDirect3DBaseTexture8 ***/
+#define IDirect3DTexture8_SetLOD(p,a) (p)->SetLOD(a)
+#define IDirect3DTexture8_GetLOD(p) (p)->GetLOD()
+#define IDirect3DTexture8_GetLevelCount(p) (p)->GetLevelCount()
+/*** IDirect3DTexture8 methods ***/
+#define IDirect3DTexture8_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b)
+#define IDirect3DTexture8_GetSurfaceLevel(p,a,b) (p)->GetSurfaceLevel(a,b)
+#define IDirect3DTexture8_LockRect(p,a,b,c,d) (p)->LockRect(a,b,c,d)
+#define IDirect3DTexture8_UnlockRect(p,a) (p)->UnlockRect(a)
+#define IDirect3DTexture8_AddDirtyRect(p,a) (p)->AddDirtyRect(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DVolumeTexture8 interface
+ */
+#define INTERFACE IDirect3DVolumeTexture8
+DECLARE_INTERFACE_(IDirect3DVolumeTexture8,IDirect3DBaseTexture8)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DResource8 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice8 ** ppDevice) PURE;
+ STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void * pData, DWORD SizeOfData, DWORD Flags) PURE;
+ STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void * pData, DWORD * pSizeOfData) PURE;
+ STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+ STDMETHOD_(DWORD,SetPriority)(THIS_ DWORD PriorityNew) PURE;
+ STDMETHOD_(DWORD,GetPriority)(THIS) PURE;
+ STDMETHOD_(void,PreLoad)(THIS) PURE;
+ STDMETHOD_(D3DRESOURCETYPE,GetType)(THIS) PURE;
+ /*** IDirect3DBaseTexture8 methods ***/
+ STDMETHOD_(DWORD,SetLOD)(THIS_ DWORD LODNew) PURE;
+ STDMETHOD_(DWORD,GetLOD)(THIS) PURE;
+ STDMETHOD_(DWORD,GetLevelCount)(THIS) PURE;
+ /*** IDirect3DVolumeTexture8 methods ***/
+ STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DVOLUME_DESC * pDesc) PURE;
+ STDMETHOD(GetVolumeLevel)(THIS_ UINT Level,IDirect3DVolume8 ** ppVolumeLevel) PURE;
+ STDMETHOD(LockBox)(THIS_ UINT Level,D3DLOCKED_BOX * pLockedVolume,CONST D3DBOX * pBox,DWORD Flags) PURE;
+ STDMETHOD(UnlockBox)(THIS_ UINT Level) PURE;
+ STDMETHOD(AddDirtyBox)(THIS_ CONST D3DBOX * pDirtyBox) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DVolumeTexture8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DVolumeTexture8_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DVolumeTexture8_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DVolumeTexture8 methods: IDirect3DResource8 ***/
+#define IDirect3DVolumeTexture8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DVolumeTexture8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DVolumeTexture8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DVolumeTexture8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DVolumeTexture8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DVolumeTexture8_GetPriority(p) (p)->lpVtbl->GetPriority(p)
+#define IDirect3DVolumeTexture8_PreLoad(p) (p)->lpVtbl->PreLoad(p)
+#define IDirect3DVolumeTexture8_GetType(p) (p)->lpVtbl->GetType(p)
+/*** IDirect3DVolumeTexture8 methods: IDirect3DBaseTexture8 ***/
+#define IDirect3DVolumeTexture8_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a)
+#define IDirect3DVolumeTexture8_GetLOD(p) (p)->lpVtbl->GetLOD(p)
+#define IDirect3DVolumeTexture8_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p)
+/*** IDirect3DVolumeTexture8 methods ***/
+#define IDirect3DVolumeTexture8_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b)
+#define IDirect3DVolumeTexture8_GetVolumeLevel(p,a,b) (p)->lpVtbl->GetVolumeLevel(p,a,b)
+#define IDirect3DVolumeTexture8_LockBox(p,a,b,c,d) (p)->lpVtbl->LockBox(p,a,b,c,d)
+#define IDirect3DVolumeTexture8_UnlockBox(p,a) (p)->lpVtbl->UnlockBox(p,a)
+#define IDirect3DVolumeTexture8_AddDirtyBox(p,a) (p)->lpVtbl->AddDirtyBox(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DVolumeTexture8_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DVolumeTexture8_AddRef(p) (p)->AddRef()
+#define IDirect3DVolumeTexture8_Release(p) (p)->Release()
+/*** IDirect3DVolumeTexture8 methods: IDirect3DResource8 ***/
+#define IDirect3DVolumeTexture8_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DVolumeTexture8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DVolumeTexture8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirect3DVolumeTexture8_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirect3DVolumeTexture8_SetPriority(p,a) (p)->SetPriority(a)
+#define IDirect3DVolumeTexture8_GetPriority(p) (p)->GetPriority()
+#define IDirect3DVolumeTexture8_PreLoad(p) (p)->PreLoad()
+#define IDirect3DVolumeTexture8_GetType(p) (p)->GetType()
+/*** IDirect3DVolumeTexture8 methods: IDirect3DBaseTexture8 ***/
+#define IDirect3DVolumeTexture8_SetLOD(p,a) (p)->SetLOD(a)
+#define IDirect3DVolumeTexture8_GetLOD(p) (p)->GetLOD()
+#define IDirect3DVolumeTexture8_GetLevelCount(p) (p)->GetLevelCount()
+/*** IDirect3DVolumeTexture8 methods ***/
+#define IDirect3DVolumeTexture8_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b)
+#define IDirect3DVolumeTexture8_GetVolumeLevel(p,a,b) (p)->GetVolumeLevel(a,b)
+#define IDirect3DVolumeTexture8_LockBox(p,a,b,c,d) (p)->LockBox(a,b,c,d)
+#define IDirect3DVolumeTexture8_UnlockBox(p,a) (p)->UnlockBox(a)
+#define IDirect3DVolumeTexture8_AddDirtyBox(p,a) (p)->AddDirtyBox(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DDevice8 interface
+ */
+#define INTERFACE IDirect3DDevice8
+DECLARE_INTERFACE_(IDirect3DDevice8,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DDevice8 methods ***/
+ STDMETHOD(TestCooperativeLevel)(THIS) PURE;
+ STDMETHOD_(UINT,GetAvailableTextureMem)(THIS) PURE;
+ STDMETHOD(ResourceManagerDiscardBytes)(THIS_ DWORD Bytes) PURE;
+ STDMETHOD(GetDirect3D)(THIS_ IDirect3D8 ** ppD3D8) PURE;
+ STDMETHOD(GetDeviceCaps)(THIS_ D3DCAPS8 * pCaps) PURE;
+ STDMETHOD(GetDisplayMode)(THIS_ D3DDISPLAYMODE * pMode) PURE;
+ STDMETHOD(GetCreationParameters)(THIS_ D3DDEVICE_CREATION_PARAMETERS * pParameters) PURE;
+ STDMETHOD(SetCursorProperties)(THIS_ UINT XHotSpot, UINT YHotSpot, IDirect3DSurface8 * pCursorBitmap) PURE;
+ STDMETHOD_(void,SetCursorPosition)(THIS_ UINT XScreenSpace, UINT YScreenSpace,DWORD Flags) PURE;
+ STDMETHOD_(BOOL,ShowCursor)(THIS_ BOOL bShow) PURE;
+ STDMETHOD(CreateAdditionalSwapChain)(THIS_ D3DPRESENT_PARAMETERS * pPresentationParameters, IDirect3DSwapChain8 ** pSwapChain) PURE;
+ STDMETHOD(Reset)(THIS_ D3DPRESENT_PARAMETERS * pPresentationParameters) PURE;
+ STDMETHOD(Present)(THIS_ CONST RECT * pSourceRect,CONST RECT * pDestRect,HWND hDestWindowOverride,CONST RGNDATA * pDirtyRegion) PURE;
+ STDMETHOD(GetBackBuffer)(THIS_ UINT BackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface8 ** ppBackBuffer) PURE;
+ STDMETHOD(GetRasterStatus)(THIS_ D3DRASTER_STATUS * pRasterStatus) PURE;
+ STDMETHOD_(void,SetGammaRamp)(THIS_ DWORD Flags,CONST D3DGAMMARAMP * pRamp) PURE;
+ STDMETHOD_(void,GetGammaRamp)(THIS_ D3DGAMMARAMP * pRamp) PURE;
+ STDMETHOD(CreateTexture)(THIS_ UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture8 ** ppTexture) PURE;
+ STDMETHOD(CreateVolumeTexture)(THIS_ UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture8 ** ppVolumeTexture) PURE;
+ STDMETHOD(CreateCubeTexture)(THIS_ UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture8 ** ppCubeTexture) PURE;
+ STDMETHOD(CreateVertexBuffer)(THIS_ UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer8 ** ppVertexBuffer) PURE;
+ STDMETHOD(CreateIndexBuffer)(THIS_ UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer8 ** ppIndexBuffer) PURE;
+ STDMETHOD(CreateRenderTarget)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,BOOL Lockable,IDirect3DSurface8 ** ppSurface) PURE;
+ STDMETHOD(CreateDepthStencilSurface)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,IDirect3DSurface8 ** ppSurface) PURE;
+ STDMETHOD(CreateImageSurface)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,IDirect3DSurface8 ** ppSurface) PURE;
+ STDMETHOD(CopyRects)(THIS_ IDirect3DSurface8 * pSourceSurface,CONST RECT * pSourceRectsArray,UINT cRects,IDirect3DSurface8 * pDestinationSurface,CONST POINT * pDestPointsArray) PURE;
+ STDMETHOD(UpdateTexture)(THIS_ IDirect3DBaseTexture8 * pSourceTexture,IDirect3DBaseTexture8 * pDestinationTexture) PURE;
+ STDMETHOD(GetFrontBuffer)(THIS_ IDirect3DSurface8 * pDestSurface) PURE;
+ STDMETHOD(SetRenderTarget)(THIS_ IDirect3DSurface8 * pRenderTarget,IDirect3DSurface8 * pNewZStencil) PURE;
+ STDMETHOD(GetRenderTarget)(THIS_ IDirect3DSurface8 ** ppRenderTarget) PURE;
+ STDMETHOD(GetDepthStencilSurface)(THIS_ IDirect3DSurface8 ** ppZStencilSurface) PURE;
+ STDMETHOD(BeginScene)(THIS) PURE;
+ STDMETHOD(EndScene)(THIS) PURE;
+ STDMETHOD(Clear)(THIS_ DWORD Count,CONST D3DRECT * pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) PURE;
+ STDMETHOD(SetTransform)(THIS_ D3DTRANSFORMSTATETYPE State,CONST D3DMATRIX * pMatrix) PURE;
+ STDMETHOD(GetTransform)(THIS_ D3DTRANSFORMSTATETYPE State,D3DMATRIX * pMatrix) PURE;
+ STDMETHOD(MultiplyTransform)(THIS_ D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX * pMatrix) PURE;
+ STDMETHOD(SetViewport)(THIS_ CONST D3DVIEWPORT8 * pViewport) PURE;
+ STDMETHOD(GetViewport)(THIS_ D3DVIEWPORT8 * pViewport) PURE;
+ STDMETHOD(SetMaterial)(THIS_ CONST D3DMATERIAL8 * pMaterial) PURE;
+ STDMETHOD(GetMaterial)(THIS_ D3DMATERIAL8 *pMaterial) PURE;
+ STDMETHOD(SetLight)(THIS_ DWORD Index,CONST D3DLIGHT8 * pLight) PURE;
+ STDMETHOD(GetLight)(THIS_ DWORD Index,D3DLIGHT8 * pLight) PURE;
+ STDMETHOD(LightEnable)(THIS_ DWORD Index,BOOL Enable) PURE;
+ STDMETHOD(GetLightEnable)(THIS_ DWORD Index,BOOL * pEnable) PURE;
+ STDMETHOD(SetClipPlane)(THIS_ DWORD Index,CONST float * pPlane) PURE;
+ STDMETHOD(GetClipPlane)(THIS_ DWORD Index,float * pPlane) PURE;
+ STDMETHOD(SetRenderState)(THIS_ D3DRENDERSTATETYPE State,DWORD Value) PURE;
+ STDMETHOD(GetRenderState)(THIS_ D3DRENDERSTATETYPE State,DWORD * pValue) PURE;
+ STDMETHOD(BeginStateBlock)(THIS) PURE;
+ STDMETHOD(EndStateBlock)(THIS_ DWORD * pToken) PURE;
+ STDMETHOD(ApplyStateBlock)(THIS_ DWORD Token) PURE;
+ STDMETHOD(CaptureStateBlock)(THIS_ DWORD Token) PURE;
+ STDMETHOD(DeleteStateBlock)(THIS_ DWORD Token) PURE;
+ STDMETHOD(CreateStateBlock)(THIS_ D3DSTATEBLOCKTYPE Type,DWORD * pToken) PURE;
+ STDMETHOD(SetClipStatus)(THIS_ CONST D3DCLIPSTATUS8 * pClipStatus) PURE;
+ STDMETHOD(GetClipStatus)(THIS_ D3DCLIPSTATUS8 * pClipStatus) PURE;
+ STDMETHOD(GetTexture)(THIS_ DWORD Stage,IDirect3DBaseTexture8 ** ppTexture) PURE;
+ STDMETHOD(SetTexture)(THIS_ DWORD Stage,IDirect3DBaseTexture8 * pTexture) PURE;
+ STDMETHOD(GetTextureStageState)(THIS_ DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD * pValue) PURE;
+ STDMETHOD(SetTextureStageState)(THIS_ DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) PURE;
+ STDMETHOD(ValidateDevice)(THIS_ DWORD * pNumPasses) PURE;
+ STDMETHOD(GetInfo)(THIS_ DWORD DevInfoID,void * pDevInfoStruct,DWORD DevInfoStructSize) PURE;
+ STDMETHOD(SetPaletteEntries)(THIS_ UINT PaletteNumber,CONST PALETTEENTRY * pEntries) PURE;
+ STDMETHOD(GetPaletteEntries)(THIS_ UINT PaletteNumber,PALETTEENTRY * pEntries) PURE;
+ STDMETHOD(SetCurrentTexturePalette)(THIS_ UINT PaletteNumber) PURE;
+ STDMETHOD(GetCurrentTexturePalette)(THIS_ UINT * PaletteNumber) PURE;
+ STDMETHOD(DrawPrimitive)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) PURE;
+ STDMETHOD(DrawIndexedPrimitive)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) PURE;
+ STDMETHOD(DrawPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void * pVertexStreamZeroData,UINT VertexStreamZeroStride) PURE;
+ STDMETHOD(DrawIndexedPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,UINT NumVertexIndices,UINT PrimitiveCount,CONST void * pIndexData,D3DFORMAT IndexDataFormat,CONST void * pVertexStreamZeroData,UINT VertexStreamZeroStride) PURE;
+ STDMETHOD(ProcessVertices)(THIS_ UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8 * pDestBuffer,DWORD Flags) PURE;
+ STDMETHOD(CreateVertexShader)(THIS_ CONST DWORD * pDeclaration,CONST DWORD * pFunction,DWORD * pHandle,DWORD Usage) PURE;
+ STDMETHOD(SetVertexShader)(THIS_ DWORD Handle) PURE;
+ STDMETHOD(GetVertexShader)(THIS_ DWORD * pHandle) PURE;
+ STDMETHOD(DeleteVertexShader)(THIS_ DWORD Handle) PURE;
+ STDMETHOD(SetVertexShaderConstant)(THIS_ DWORD Register,CONST void * pConstantData,DWORD ConstantCount) PURE;
+ STDMETHOD(GetVertexShaderConstant)(THIS_ DWORD Register,void * pConstantData,DWORD ConstantCount) PURE;
+ STDMETHOD(GetVertexShaderDeclaration)(THIS_ DWORD Handle,void * pData,DWORD * pSizeOfData) PURE;
+ STDMETHOD(GetVertexShaderFunction)(THIS_ DWORD Handle,void * pData,DWORD * pSizeOfData) PURE;
+ STDMETHOD(SetStreamSource)(THIS_ UINT StreamNumber,IDirect3DVertexBuffer8 * pStreamData,UINT Stride) PURE;
+ STDMETHOD(GetStreamSource)(THIS_ UINT StreamNumber,IDirect3DVertexBuffer8 ** ppStreamData,UINT * pStride) PURE;
+ STDMETHOD(SetIndices)(THIS_ IDirect3DIndexBuffer8 * pIndexData,UINT BaseVertexIndex) PURE;
+ STDMETHOD(GetIndices)(THIS_ IDirect3DIndexBuffer8 ** ppIndexData,UINT * pBaseVertexIndex) PURE;
+ STDMETHOD(CreatePixelShader)(THIS_ CONST DWORD * pFunction,DWORD * pHandle) PURE;
+ STDMETHOD(SetPixelShader)(THIS_ DWORD Handle) PURE;
+ STDMETHOD(GetPixelShader)(THIS_ DWORD * pHandle) PURE;
+ STDMETHOD(DeletePixelShader)(THIS_ DWORD Handle) PURE;
+ STDMETHOD(SetPixelShaderConstant)(THIS_ DWORD Register,CONST void * pConstantData,DWORD ConstantCount) PURE;
+ STDMETHOD(GetPixelShaderConstant)(THIS_ DWORD Register,void * pConstantData,DWORD ConstantCount) PURE;
+ STDMETHOD(GetPixelShaderFunction)(THIS_ DWORD Handle,void * pData,DWORD * pSizeOfData) PURE;
+ STDMETHOD(DrawRectPatch)(THIS_ UINT Handle,CONST float * pNumSegs,CONST D3DRECTPATCH_INFO * pRectPatchInfo) PURE;
+ STDMETHOD(DrawTriPatch)(THIS_ UINT Handle,CONST float * pNumSegs,CONST D3DTRIPATCH_INFO * pTriPatchInfo) PURE;
+ STDMETHOD(DeletePatch)(THIS_ UINT Handle) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DDevice8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DDevice8_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DDevice8_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DDevice8 methods ***/
+#define IDirect3DDevice8_TestCooperativeLevel(p) (p)->lpVtbl->TestCooperativeLevel(p)
+#define IDirect3DDevice8_GetAvailableTextureMem(p) (p)->lpVtbl->GetAvailableTextureMem(p)
+#define IDirect3DDevice8_ResourceManagerDiscardBytes(p,a) (p)->lpVtbl->ResourceManagerDiscardBytes(p,a)
+#define IDirect3DDevice8_GetDirect3D(p,a) (p)->lpVtbl->GetDirect3D(p,a)
+#define IDirect3DDevice8_GetDeviceCaps(p,a) (p)->lpVtbl->GetDeviceCaps(p,a)
+#define IDirect3DDevice8_GetDisplayMode(p,a) (p)->lpVtbl->GetDisplayMode(p,a)
+#define IDirect3DDevice8_GetCreationParameters(p,a) (p)->lpVtbl->GetCreationParameters(p,a)
+#define IDirect3DDevice8_SetCursorProperties(p,a,b,c) (p)->lpVtbl->SetCursorProperties(p,a,b,c)
+#define IDirect3DDevice8_SetCursorPosition(p,a,b,c) (p)->lpVtbl->SetCursorPosition(p,a,b,c)
+#define IDirect3DDevice8_ShowCursor(p,a) (p)->lpVtbl->ShowCursor(p,a)
+#define IDirect3DDevice8_CreateAdditionalSwapChain(p,a,b) (p)->lpVtbl->CreateAdditionalSwapChain(p,a,b)
+#define IDirect3DDevice8_Reset(p,a) (p)->lpVtbl->Reset(p,a)
+#define IDirect3DDevice8_Present(p,a,b,c,d) (p)->lpVtbl->Present(p,a,b,c,d)
+#define IDirect3DDevice8_GetBackBuffer(p,a,b,c) (p)->lpVtbl->GetBackBuffer(p,a,b,c)
+#define IDirect3DDevice8_GetRasterStatus(p,a) (p)->lpVtbl->GetRasterStatus(p,a)
+#define IDirect3DDevice8_SetGammaRamp(p,a,b) (p)->lpVtbl->SetGammaRamp(p,a,b)
+#define IDirect3DDevice8_GetGammaRamp(p,a) (p)->lpVtbl->GetGammaRamp(p,a)
+#define IDirect3DDevice8_CreateTexture(p,a,b,c,d,e,f,g) (p)->lpVtbl->CreateTexture(p,a,b,c,d,e,f,g)
+#define IDirect3DDevice8_CreateVolumeTexture(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->CreateVolumeTexture(p,a,b,c,d,e,f,g,h)
+#define IDirect3DDevice8_CreateCubeTexture(p,a,b,c,d,e,f) (p)->lpVtbl->CreateCubeTexture(p,a,b,c,d,e,f)
+#define IDirect3DDevice8_CreateVertexBuffer(p,a,b,c,d,e) (p)->lpVtbl->CreateVertexBuffer(p,a,b,c,d,e)
+#define IDirect3DDevice8_CreateIndexBuffer(p,a,b,c,d,e) (p)->lpVtbl->CreateIndexBuffer(p,a,b,c,d,e)
+#define IDirect3DDevice8_CreateRenderTarget(p,a,b,c,d,e,f) (p)->lpVtbl->CreateRenderTarget(p,a,b,c,d,e,f)
+#define IDirect3DDevice8_CreateDepthStencilSurface(p,a,b,c,d,e) (p)->lpVtbl->CreateDepthStencilSurface(p,a,b,c,d,e)
+#define IDirect3DDevice8_CreateImageSurface(p,a,b,c,d) (p)->lpVtbl->CreateImageSurface(p,a,b,c,d)
+#define IDirect3DDevice8_CopyRects(p,a,b,c,d,e) (p)->lpVtbl->CopyRects(p,a,b,c,d,e)
+#define IDirect3DDevice8_UpdateTexture(p,a,b) (p)->lpVtbl->UpdateTexture(p,a,b)
+#define IDirect3DDevice8_GetFrontBuffer(p,a) (p)->lpVtbl->GetFrontBuffer(p,a)
+#define IDirect3DDevice8_SetRenderTarget(p,a,b) (p)->lpVtbl->SetRenderTarget(p,a,b)
+#define IDirect3DDevice8_GetRenderTarget(p,a) (p)->lpVtbl->GetRenderTarget(p,a)
+#define IDirect3DDevice8_GetDepthStencilSurface(p,a) (p)->lpVtbl->GetDepthStencilSurface(p,a)
+#define IDirect3DDevice8_BeginScene(p) (p)->lpVtbl->BeginScene(p)
+#define IDirect3DDevice8_EndScene(p) (p)->lpVtbl->EndScene(p)
+#define IDirect3DDevice8_Clear(p,a,b,c,d,e,f) (p)->lpVtbl->Clear(p,a,b,c,d,e,f)
+#define IDirect3DDevice8_SetTransform(p,a,b) (p)->lpVtbl->SetTransform(p,a,b)
+#define IDirect3DDevice8_GetTransform(p,a,b) (p)->lpVtbl->GetTransform(p,a,b)
+#define IDirect3DDevice8_MultiplyTransform(p,a,b) (p)->lpVtbl->MultiplyTransform(p,a,b)
+#define IDirect3DDevice8_SetViewport(p,a) (p)->lpVtbl->SetViewport(p,a)
+#define IDirect3DDevice8_GetViewport(p,a) (p)->lpVtbl->GetViewport(p,a)
+#define IDirect3DDevice8_SetMaterial(p,a) (p)->lpVtbl->SetMaterial(p,a)
+#define IDirect3DDevice8_GetMaterial(p,a) (p)->lpVtbl->GetMaterial(p,a)
+#define IDirect3DDevice8_SetLight(p,a,b) (p)->lpVtbl->SetLight(p,a,b)
+#define IDirect3DDevice8_GetLight(p,a,b) (p)->lpVtbl->GetLight(p,a,b)
+#define IDirect3DDevice8_LightEnable(p,a,b) (p)->lpVtbl->LightEnable(p,a,b)
+#define IDirect3DDevice8_GetLightEnable(p,a,b) (p)->lpVtbl->GetLightEnable(p,a,b)
+#define IDirect3DDevice8_SetClipPlane(p,a,b) (p)->lpVtbl->SetClipPlane(p,a,b)
+#define IDirect3DDevice8_GetClipPlane(p,a,b) (p)->lpVtbl->GetClipPlane(p,a,b)
+#define IDirect3DDevice8_SetRenderState(p,a,b) (p)->lpVtbl->SetRenderState(p,a,b)
+#define IDirect3DDevice8_GetRenderState(p,a,b) (p)->lpVtbl->GetRenderState(p,a,b)
+#define IDirect3DDevice8_BeginStateBlock(p) (p)->lpVtbl->BeginStateBlock(p)
+#define IDirect3DDevice8_EndStateBlock(p,a) (p)->lpVtbl->EndStateBlock(p,a)
+#define IDirect3DDevice8_ApplyStateBlock(p,a) (p)->lpVtbl->ApplyStateBlock(p,a)
+#define IDirect3DDevice8_CaptureStateBlock(p,a) (p)->lpVtbl->CaptureStateBlock(p,a)
+#define IDirect3DDevice8_DeleteStateBlock(p,a) (p)->lpVtbl->DeleteStateBlock(p,a)
+#define IDirect3DDevice8_CreateStateBlock(p,a,b) (p)->lpVtbl->CreateStateBlock(p,a,b)
+#define IDirect3DDevice8_SetClipStatus(p,a) (p)->lpVtbl->SetClipStatus(p,a)
+#define IDirect3DDevice8_GetClipStatus(p,a) (p)->lpVtbl->GetClipStatus(p,a)
+#define IDirect3DDevice8_GetTexture(p,a,b) (p)->lpVtbl->GetTexture(p,a,b)
+#define IDirect3DDevice8_SetTexture(p,a,b) (p)->lpVtbl->SetTexture(p,a,b)
+#define IDirect3DDevice8_GetTextureStageState(p,a,b,c) (p)->lpVtbl->GetTextureStageState(p,a,b,c)
+#define IDirect3DDevice8_SetTextureStageState(p,a,b,c) (p)->lpVtbl->SetTextureStageState(p,a,b,c)
+#define IDirect3DDevice8_ValidateDevice(p,a) (p)->lpVtbl->ValidateDevice(p,a)
+#define IDirect3DDevice8_GetInfo(p,a,b,c) (p)->lpVtbl->GetInfo(p,a,b,c)
+#define IDirect3DDevice8_SetPaletteEntries(p,a,b) (p)->lpVtbl->SetPaletteEntries(p,a,b)
+#define IDirect3DDevice8_GetPaletteEntries(p,a,b) (p)->lpVtbl->GetPaletteEntries(p,a,b)
+#define IDirect3DDevice8_SetCurrentTexturePalette(p,a) (p)->lpVtbl->SetCurrentTexturePalette(p,a)
+#define IDirect3DDevice8_GetCurrentTexturePalette(p,a) (p)->lpVtbl->GetCurrentTexturePalette(p,a)
+#define IDirect3DDevice8_DrawPrimitive(p,a,b,c) (p)->lpVtbl->DrawPrimitive(p,a,b,c)
+#define IDirect3DDevice8_DrawIndexedPrimitive(p,a,b,c,d,e) (p)->lpVtbl->DrawIndexedPrimitive(p,a,b,c,d,e)
+#define IDirect3DDevice8_DrawPrimitiveUP(p,a,b,c,d) (p)->lpVtbl->DrawPrimitiveUP(p,a,b,c,d)
+#define IDirect3DDevice8_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h)
+#define IDirect3DDevice8_ProcessVertices(p,a,b,c,d,e) (p)->lpVtbl->processVertices(p,a,b,c,d,e)
+#define IDirect3DDevice8_CreateVertexShader(p,a,b,c,d) (p)->lpVtbl->CreateVertexShader(p,a,b,c,d)
+#define IDirect3DDevice8_SetVertexShader(p,a) (p)->lpVtbl->SetVertexShader(p,a)
+#define IDirect3DDevice8_GetVertexShader(p,a) (p)->lpVtbl->GetVertexShader(p,a)
+#define IDirect3DDevice8_DeleteVertexShader(p,a) (p)->lpVtbl->DeleteVertexShader(p,a)
+#define IDirect3DDevice8_SetVertexShaderConstant(p,a,b,c) (p)->lpVtbl->SetVertexShaderConstant(p,a,b,c)
+#define IDirect3DDevice8_GetVertexShaderConstant(p,a,b,c) (p)->lpVtbl->GetVertexShaderConstant(p,a,b,c)
+#define IDirect3DDevice8_GetVertexShaderDeclaration(p,a,b,c) (p)->lpVtbl->GetVertexShaderDeclaration(p,a,b,c)
+#define IDirect3DDevice8_GetVertexShaderFunction(p,a,b,c) (p)->lpVtbl->GetVertexShaderFunction(p,a,b,c)
+#define IDirect3DDevice8_SetStreamSource(p,a,b,c) (p)->lpVtbl->SetStreamSource(p,a,b,c)
+#define IDirect3DDevice8_GetStreamSource(p,a,b,c) (p)->lpVtbl->GetStreamSource(p,a,b,c)
+#define IDirect3DDevice8_SetIndices(p,a,b) (p)->lpVtbl->SetIndices(p,a,b)
+#define IDirect3DDevice8_GetIndices(p,a,b) (p)->lpVtbl->GetIndices(p,a,b)
+#define IDirect3DDevice8_CreatePixelShader(p,a,b) (p)->lpVtbl->CreatePixelShader(p,a,b)
+#define IDirect3DDevice8_SetPixelShader(p,a) (p)->lpVtbl->SetPixelShader(p,a)
+#define IDirect3DDevice8_GetPixelShader(p,a) (p)->lpVtbl->GetPixelShader(p,a)
+#define IDirect3DDevice8_DeletePixelShader(p,a) (p)->lpVtbl->DeletePixelShader(p,a)
+#define IDirect3DDevice8_SetPixelShaderConstant(p,a,b,c) (p)->lpVtbl->SetPixelShaderConstant(p,a,b,c)
+#define IDirect3DDevice8_GetPixelShaderConstant(p,a,b,c) (p)->lpVtbl->GetPixelShaderConstant(p,a,b,c)
+#define IDirect3DDevice8_GetPixelShaderFunction(p,a,b,c) (p)->lpVtbl->GetPixelShaderFunction(p,a,b,c)
+#define IDirect3DDevice8_DrawRectPatch(p,a,b,c) (p)->lpVtbl->DrawRectPatch(p,a,b,c)
+#define IDirect3DDevice8_DrawTriPatch(p,a,b,c) (p)->lpVtbl->DrawTriPatch(p,a,b,c)
+#define IDirect3DDevice8_DeletePatch(p,a) (p)->lpVtbl->DeletePatch(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DDevice8_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DDevice8_AddRef(p) (p)->AddRef()
+#define IDirect3DDevice8_Release(p) (p)->Release()
+/*** IDirect3DDevice8 methods ***/
+#define IDirect3DDevice8_TestCooperativeLevel(p) (p)->TestCooperativeLevel()
+#define IDirect3DDevice8_GetAvailableTextureMem(p) (p)->GetAvailableTextureMem()
+#define IDirect3DDevice8_ResourceManagerDiscardBytes(p,a) (p)->ResourceManagerDiscardBytes(a)
+#define IDirect3DDevice8_GetDirect3D(p,a) (p)->GetDirect3D(a)
+#define IDirect3DDevice8_GetDeviceCaps(p,a) (p)->GetDeviceCaps(a)
+#define IDirect3DDevice8_GetDisplayMode(p,a) (p)->GetDisplayMode(a)
+#define IDirect3DDevice8_GetCreationParameters(p,a) (p)->GetCreationParameters(a)
+#define IDirect3DDevice8_SetCursorProperties(p,a,b,c) (p)->SetCursorProperties(a,b,c)
+#define IDirect3DDevice8_SetCursorPosition(p,a,b,c) (p)->SetCursorPosition(a,b,c)
+#define IDirect3DDevice8_ShowCursor(p,a) (p)->ShowCursor(a)
+#define IDirect3DDevice8_CreateAdditionalSwapChain(p,a,b) (p)->CreateAdditionalSwapChain(a,b)
+#define IDirect3DDevice8_Reset(p,a) (p)->Reset(a)
+#define IDirect3DDevice8_Present(p,a,b,c,d) (p)->Present(a,b,c,d)
+#define IDirect3DDevice8_GetBackBuffer(p,a,b,c) (p)->GetBackBuffer(a,b,c)
+#define IDirect3DDevice8_GetRasterStatus(p,a) (p)->GetRasterStatus(a)
+#define IDirect3DDevice8_SetGammaRamp(p,a,b) (p)->SetGammaRamp(a,b)
+#define IDirect3DDevice8_GetGammaRamp(p,a) (p)->GetGammaRamp(a)
+#define IDirect3DDevice8_CreateTexture(p,a,b,c,d,e,f,g) (p)->CreateTexture(a,b,c,d,e,f,g)
+#define IDirect3DDevice8_CreateVolumeTexture(p,a,b,c,d,e,f,g,h) (p)->CreateVolumeTexture(a,b,c,d,e,f,g,h)
+#define IDirect3DDevice8_CreateCubeTexture(p,a,b,c,d,e,f) (p)->CreateCubeTexture(a,b,c,d,e,f)
+#define IDirect3DDevice8_CreateVertexBuffer(p,a,b,c,d,e) (p)->CreateVertexBuffer(a,b,c,d,e)
+#define IDirect3DDevice8_CreateIndexBuffer(p,a,b,c,d,e) (p)->CreateIndexBuffer(a,b,c,d,e)
+#define IDirect3DDevice8_CreateRenderTarget(p,a,b,c,d,e,f) (p)->CreateRenderTarget(a,b,c,d,e,f)
+#define IDirect3DDevice8_CreateDepthStencilSurface(p,a,b,c,d,e) (p)->CreateDepthStencilSurface(a,b,c,d,e)
+#define IDirect3DDevice8_CreateImageSurface(p,a,b,c,d) (p)->CreateImageSurface(a,b,c,d)
+#define IDirect3DDevice8_CopyRects(p,a,b,c,d,e) (p)->CopyRects(a,b,c,d,e)
+#define IDirect3DDevice8_UpdateTexture(p,a,b) (p)->UpdateTexture(a,b)
+#define IDirect3DDevice8_GetFrontBuffer(p,a) (p)->GetFrontBuffer(a)
+#define IDirect3DDevice8_SetRenderTarget(p,a,b) (p)->SetRenderTarget(a,b)
+#define IDirect3DDevice8_GetRenderTarget(p,a) (p)->GetRenderTarget(a)
+#define IDirect3DDevice8_GetDepthStencilSurface(p,a) (p)->GetDepthStencilSurface(a)
+#define IDirect3DDevice8_BeginScene(p) (p)->BeginScene()
+#define IDirect3DDevice8_EndScene(p) (p)->EndScene()
+#define IDirect3DDevice8_Clear(p,a,b,c,d,e,f) (p)->Clear(a,b,c,d,e,f)
+#define IDirect3DDevice8_SetTransform(p,a,b) (p)->SetTransform(a,b)
+#define IDirect3DDevice8_GetTransform(p,a,b) (p)->GetTransform(a,b)
+#define IDirect3DDevice8_MultiplyTransform(p,a,b) (p)->MultiplyTransform(a,b)
+#define IDirect3DDevice8_SetViewport(p,a) (p)->SetViewport(a)
+#define IDirect3DDevice8_GetViewport(p,a) (p)->GetViewport(a)
+#define IDirect3DDevice8_SetMaterial(p,a) (p)->SetMaterial(a)
+#define IDirect3DDevice8_GetMaterial(p,a) (p)->GetMaterial(a)
+#define IDirect3DDevice8_SetLight(p,a,b) (p)->SetLight(a,b)
+#define IDirect3DDevice8_GetLight(p,a,b) (p)->GetLight(a,b)
+#define IDirect3DDevice8_LightEnable(p,a,b) (p)->LightEnable(a,b)
+#define IDirect3DDevice8_GetLightEnable(p,a,b) (p)->GetLightEnable(a,b)
+#define IDirect3DDevice8_SetClipPlane(p,a,b) (p)->SetClipPlane(a,b)
+#define IDirect3DDevice8_GetClipPlane(p,a,b) (p)->GetClipPlane(a,b)
+#define IDirect3DDevice8_SetRenderState(p,a,b) (p)->SetRenderState(a,b)
+#define IDirect3DDevice8_GetRenderState(p,a,b) (p)->GetRenderState(a,b)
+#define IDirect3DDevice8_BeginStateBlock(p) (p)->BeginStateBlock()
+#define IDirect3DDevice8_EndStateBlock(p,a) (p)->EndStateBlock(a)
+#define IDirect3DDevice8_ApplyStateBlock(p,a) (p)->ApplyStateBlock(a)
+#define IDirect3DDevice8_CaptureStateBlock(p,a) (p)->CaptureStateBlock(a)
+#define IDirect3DDevice8_DeleteStateBlock(p,a) (p)->DeleteStateBlock(a)
+#define IDirect3DDevice8_CreateStateBlock(p,a,b) (p)->CreateStateBlock(a,b)
+#define IDirect3DDevice8_SetClipStatus(p,a) (p)->SetClipStatus(a)
+#define IDirect3DDevice8_GetClipStatus(p,a) (p)->GetClipStatus(a)
+#define IDirect3DDevice8_GetTexture(p,a,b) (p)->GetTexture(a,b)
+#define IDirect3DDevice8_SetTexture(p,a,b) (p)->SetTexture(a,b)
+#define IDirect3DDevice8_GetTextureStageState(p,a,b,c) (p)->GetTextureStageState(a,b,c)
+#define IDirect3DDevice8_SetTextureStageState(p,a,b,c) (p)->SetTextureStageState(a,b,c)
+#define IDirect3DDevice8_ValidateDevice(p,a) (p)->ValidateDevice(a)
+#define IDirect3DDevice8_GetInfo(p,a,b,c) (p)->GetInfo(a,b,c)
+#define IDirect3DDevice8_SetPaletteEntries(p,a,b) (p)->SetPaletteEntries(a,b)
+#define IDirect3DDevice8_GetPaletteEntries(p,a,b) (p)->GetPaletteEntries(a,b)
+#define IDirect3DDevice8_SetCurrentTexturePalette(p,a) (p)->SetCurrentTexturePalette(a)
+#define IDirect3DDevice8_GetCurrentTexturePalette(p,a) (p)->GetCurrentTexturePalette(a)
+#define IDirect3DDevice8_DrawPrimitive(p,a,b,c) (p)->DrawPrimitive(a,b,c)
+#define IDirect3DDevice8_DrawIndexedPrimitive(p,a,b,c,d,e) (p)->DrawIndexedPrimitive(a,b,c,d,e)
+#define IDirect3DDevice8_DrawPrimitiveUP(p,a,b,c,d) (p)->DrawPrimitiveUP(a,b,c,d)
+#define IDirect3DDevice8_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->DrawIndexedPrimitiveUP(a,b,c,d,e,f,g,h)
+#define IDirect3DDevice8_ProcessVertices(p,a,b,c,d,e) (p)->processVertices(a,b,c,d,e)
+#define IDirect3DDevice8_CreateVertexShader(p,a,b,c,d) (p)->CreateVertexShader(a,b,c,d)
+#define IDirect3DDevice8_SetVertexShader(p,a) (p)->SetVertexShader(a)
+#define IDirect3DDevice8_GetVertexShader(p,a) (p)->GetVertexShader(a)
+#define IDirect3DDevice8_DeleteVertexShader(p,a) (p)->DeleteVertexShader(a)
+#define IDirect3DDevice8_SetVertexShaderConstant(p,a,b,c) (p)->SetVertexShaderConstant(a,b,c)
+#define IDirect3DDevice8_GetVertexShaderConstant(p,a,b,c) (p)->GetVertexShaderConstant(a,b,c)
+#define IDirect3DDevice8_GetVertexShaderDeclaration(p,a,b,c) (p)->GetVertexShaderDeclaration(a,b,c)
+#define IDirect3DDevice8_GetVertexShaderFunction(p,a,b,c) (p)->GetVertexShaderFunction(a,b,c)
+#define IDirect3DDevice8_SetStreamSource(p,a,b,c) (p)->SetStreamSource(a,b,c)
+#define IDirect3DDevice8_GetStreamSource(p,a,b,c) (p)->GetStreamSource(a,b,c)
+#define IDirect3DDevice8_SetIndices(p,a,b) (p)->SetIndices(a,b)
+#define IDirect3DDevice8_GetIndices(p,a,b) (p)->GetIndices(a,b)
+#define IDirect3DDevice8_CreatePixelShader(p,a,b) (p)->CreatePixelShader(a,b)
+#define IDirect3DDevice8_SetPixelShader(p,a) (p)->SetPixelShader(a)
+#define IDirect3DDevice8_GetPixelShader(p,a) (p)->GetPixelShader(a)
+#define IDirect3DDevice8_DeletePixelShader(p,a) (p)->DeletePixelShader(a)
+#define IDirect3DDevice8_SetPixelShaderConstant(p,a,b,c) (p)->SetPixelShaderConstant(a,b,c)
+#define IDirect3DDevice8_GetPixelShaderConstant(p,a,b,c) (p)->GetPixelShaderConstant(a,b,c)
+#define IDirect3DDevice8_GetPixelShaderFunction(p,a,b,c) (p)->GetPixelShaderFunction(a,b,c)
+#define IDirect3DDevice8_DrawRectPatch(p,a,b,c) (p)->DrawRectPatch(a,b,c)
+#define IDirect3DDevice8_DrawTriPatch(p,a,b,c) (p)->DrawTriPatch(a,b,c)
+#define IDirect3DDevice8_DeletePatch(p,a) (p)->DeletePatch(a)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+/* Define the main entrypoint as well */
+IDirect3D8* WINAPI Direct3DCreate8(UINT SDKVersion);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* defined(__cplusplus) */
+
+#endif /* __WINE_D3D8_H */
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/d3d9.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/d3d9.h
new file mode 100644
index 00000000..a59f5733
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/d3d9.h
@@ -0,0 +1,2063 @@
+/*
+ * Copyright (C) 2002-2003 Jason Edmeades
+ * Raphael Junqueira
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#ifndef __WINE_D3D9_H
+#define __WINE_D3D9_H
+
+#ifndef DIRECT3D_VERSION
+#define DIRECT3D_VERSION 0x0900
+#endif
+
+#ifndef VBOX_WINE_WITHOUT_LIBWINE
+#include <stdlib.h>
+
+#define COM_NO_WINDOWS_H
+#include <objbase.h>
+#include <windows.h>
+#endif
+#include <d3d9types.h>
+#include <d3d9caps.h>
+#ifndef VBOX_WINE_WITHOUT_LIBWINE
+# include <d3dhal.h>
+# include <d3dtypes.h>
+# include <d3dcaps.h>
+#endif
+
+#define __MSABI_LONG(_n) _n##L
+
+/*****************************************************************************
+ * Behavior Flags for IDirect3D8::CreateDevice
+ */
+#define D3DCREATE_FPU_PRESERVE __MSABI_LONG(0x00000002)
+#define D3DCREATE_MULTITHREADED __MSABI_LONG(0x00000004)
+#define D3DCREATE_PUREDEVICE __MSABI_LONG(0x00000010)
+#define D3DCREATE_SOFTWARE_VERTEXPROCESSING __MSABI_LONG(0x00000020)
+#define D3DCREATE_HARDWARE_VERTEXPROCESSING __MSABI_LONG(0x00000040)
+#define D3DCREATE_MIXED_VERTEXPROCESSING __MSABI_LONG(0x00000080)
+#define D3DCREATE_DISABLE_DRIVER_MANAGEMENT __MSABI_LONG(0x00000100)
+#define D3DCREATE_ADAPTERGROUP_DEVICE __MSABI_LONG(0x00000200)
+#define D3DCREATE_DISABLE_DRIVER_MANAGEMENT_EX __MSABI_LONG(0x00000400)
+#define D3DCREATE_NOWINDOWCHANGES __MSABI_LONG(0x00000800)
+#define D3DCREATE_DISABLE_PSGP_THREADING __MSABI_LONG(0x00002000)
+#define D3DCREATE_ENABLE_PRESENTSTATS __MSABI_LONG(0x00004000)
+#define D3DCREATE_DISABLE_PRINTSCREEN __MSABI_LONG(0x00008000)
+#define D3DCREATE_SCREENSAVER __MSABI_LONG(0x10000000)
+
+/*****************************************************************************
+ * Flags for SetPrivateData
+ */
+#define D3DSPD_IUNKNOWN __MSABI_LONG(0x00000001)
+
+
+/*****************************************************************************
+ * #defines and error codes
+ */
+#define D3D_SDK_VERSION 32
+#define D3DADAPTER_DEFAULT 0
+#define D3DENUM_NO_WHQL_LEVEL __MSABI_LONG(0x00000002)
+#define D3DPRESENT_BACK_BUFFERS_MAX __MSABI_LONG(3)
+#define D3DSGR_NO_CALIBRATION __MSABI_LONG(0x00000000)
+#define D3DSGR_CALIBRATE __MSABI_LONG(0x00000001)
+
+#define _FACD3D 0x876
+#define MAKE_D3DHRESULT( code ) MAKE_HRESULT( 1, _FACD3D, code )
+#define MAKE_D3DSTATUS( code ) MAKE_HRESULT( 0, _FACD3D, code )
+
+/*****************************************************************************
+ * Direct3D Errors
+ */
+#define D3D_OK S_OK
+#define D3DERR_WRONGTEXTUREFORMAT MAKE_D3DHRESULT(2072)
+#define D3DERR_UNSUPPORTEDCOLOROPERATION MAKE_D3DHRESULT(2073)
+#define D3DERR_UNSUPPORTEDCOLORARG MAKE_D3DHRESULT(2074)
+#define D3DERR_UNSUPPORTEDALPHAOPERATION MAKE_D3DHRESULT(2075)
+#define D3DERR_UNSUPPORTEDALPHAARG MAKE_D3DHRESULT(2076)
+#define D3DERR_TOOMANYOPERATIONS MAKE_D3DHRESULT(2077)
+#define D3DERR_CONFLICTINGTEXTUREFILTER MAKE_D3DHRESULT(2078)
+#define D3DERR_UNSUPPORTEDFACTORVALUE MAKE_D3DHRESULT(2079)
+#define D3DERR_CONFLICTINGRENDERSTATE MAKE_D3DHRESULT(2081)
+#define D3DERR_UNSUPPORTEDTEXTUREFILTER MAKE_D3DHRESULT(2082)
+#define D3DERR_CONFLICTINGTEXTUREPALETTE MAKE_D3DHRESULT(2086)
+#define D3DERR_DRIVERINTERNALERROR MAKE_D3DHRESULT(2087)
+#define D3DERR_NOTFOUND MAKE_D3DHRESULT(2150)
+#define D3DERR_MOREDATA MAKE_D3DHRESULT(2151)
+#define D3DERR_DEVICELOST MAKE_D3DHRESULT(2152)
+#define D3DERR_DEVICENOTRESET MAKE_D3DHRESULT(2153)
+#define D3DERR_NOTAVAILABLE MAKE_D3DHRESULT(2154)
+#define D3DERR_OUTOFVIDEOMEMORY MAKE_D3DHRESULT(380)
+#define D3DERR_INVALIDDEVICE MAKE_D3DHRESULT(2155)
+#define D3DERR_INVALIDCALL MAKE_D3DHRESULT(2156)
+#define D3DERR_DRIVERINVALIDCALL MAKE_D3DHRESULT(2157)
+#define D3DERR_WASSTILLDRAWING MAKE_D3DHRESULT(540)
+#define D3DOK_NOAUTOGEN MAKE_D3DSTATUS(2159)
+
+#define D3DERR_DEVICEREMOVED MAKE_D3DHRESULT(2160)
+#define D3DERR_DEVICEHUNG MAKE_D3DHRESULT(2164)
+#define S_NOT_RESIDENT MAKE_D3DSTATUS(2165)
+#define S_RESIDENT_IN_SHARED_MEMORY MAKE_D3DSTATUS(2166)
+#define S_PRESENT_MODE_CHANGED MAKE_D3DSTATUS(2167)
+#define S_PRESENT_OCCLUDED MAKE_D3DSTATUS(2168)
+#define D3DERR_UNSUPPORTEDOVERLAY MAKE_D3DHRESULT(2171)
+#define D3DERR_UNSUPPORTEDOVERLAYFORMAT MAKE_D3DHRESULT(2172)
+#define D3DERR_CANNOTPROTECTCONTENT MAKE_D3DHRESULT(2173)
+#define D3DERR_UNSUPPORTEDCRYPTO MAKE_D3DHRESULT(2174)
+#define D3DERR_PRESENT_STATISTICS_DISJOINT MAKE_D3DHRESULT(2180)
+
+
+/*****************************************************************************
+ * Predeclare the interfaces
+ */
+DEFINE_GUID(IID_IDirect3D9, 0x81BDCBCA, 0x64D4, 0x426D, 0xAE, 0x8D, 0xAD, 0x1, 0x47, 0xF4, 0x27, 0x5C);
+typedef struct IDirect3D9 *LPDIRECT3D9, *PDIRECT3D9;
+
+DEFINE_GUID(IID_IDirect3D9Ex, 0x02177241, 0x69FC, 0x400C, 0x8F, 0xF1, 0x93, 0xA4, 0x4D, 0xF6, 0x86, 0x1D);
+typedef struct IDirect3D9Ex *LPDIRECT3D9EX, *PDIRECT3D9EX;
+
+DEFINE_GUID(IID_IDirect3DDevice9, 0xd0223b96, 0xbf7a, 0x43fd, 0x92, 0xbd, 0xa4, 0x3b, 0xd, 0x82, 0xb9, 0xeb);
+typedef struct IDirect3DDevice9 *LPDIRECT3DDEVICE9;
+
+DEFINE_GUID(IID_IDirect3DDevice9Ex, 0xb18b10ce, 0x2649, 0x405a, 0x87, 0xf, 0x95, 0xf7, 0x77, 0xd4, 0x31, 0x3a);
+typedef struct IDirect3DDevice9Ex *LPDIRECT3DDEVICE9EX, *PDIRECT3DDEVICE9EX;
+
+DEFINE_GUID(IID_IDirect3DResource9, 0x5eec05d, 0x8f7d, 0x4362, 0xb9, 0x99, 0xd1, 0xba, 0xf3, 0x57, 0xc7, 0x4);
+typedef struct IDirect3DResource9 *LPDIRECT3DRESOURCE9, *PDIRECT3DRESOURCE9;
+
+DEFINE_GUID(IID_IDirect3DVertexBuffer9, 0xb64bb1b5, 0xfd70, 0x4df6, 0xbf, 0x91, 0x19, 0xd0, 0xa1, 0x24, 0x55, 0xe3);
+typedef struct IDirect3DVertexBuffer9 *LPDIRECT3DVERTEXBUFFER9, *PDIRECT3DVERTEXBUFFER9;
+
+DEFINE_GUID(IID_IDirect3DVolume9, 0x24f416e6, 0x1f67, 0x4aa7, 0xb8, 0x8e, 0xd3, 0x3f, 0x6f, 0x31, 0x28, 0xa1);
+typedef struct IDirect3DVolume9 *LPDIRECT3DVOLUME9, *PDIRECT3DVOLUME9;
+
+DEFINE_GUID(IID_IDirect3DSwapChain9, 0x794950f2, 0xadfc, 0x458a, 0x90, 0x5e, 0x10, 0xa1, 0xb, 0xb, 0x50, 0x3b);
+typedef struct IDirect3DSwapChain9 *LPDIRECT3DSWAPCHAIN9, *PDIRECT3DSWAPCHAIN9;
+
+DEFINE_GUID(IID_IDirect3DSwapChain9Ex, 0x91886caf, 0x1c3d, 0x4d2e, 0xa0, 0xab, 0x3e, 0x4c, 0x7d, 0x8d, 0x33, 0x3);
+typedef struct IDirect3DSwapChain9Ex *LPDIRECT3DSWAPCHAIN9EX, *PDIRECT3DSWAPCHAIN9EX;
+
+DEFINE_GUID(IID_IDirect3DSurface9, 0xcfbaf3a, 0x9ff6, 0x429a, 0x99, 0xb3, 0xa2, 0x79, 0x6a, 0xf8, 0xb8, 0x9b);
+typedef struct IDirect3DSurface9 *LPDIRECT3DSURFACE9, *PDIRECT3DSURFACE9;
+
+DEFINE_GUID(IID_IDirect3DIndexBuffer9, 0x7c9dd65e, 0xd3f7, 0x4529, 0xac, 0xee, 0x78, 0x58, 0x30, 0xac, 0xde, 0x35);
+typedef struct IDirect3DIndexBuffer9 *LPDIRECT3DINDEXBUFFER9, *PDIRECT3DINDEXBUFFER9;
+
+DEFINE_GUID(IID_IDirect3DBaseTexture9, 0x580ca87e, 0x1d3c, 0x4d54, 0x99, 0x1d, 0xb7, 0xd3, 0xe3, 0xc2, 0x98, 0xce);
+typedef struct IDirect3DBaseTexture9 *LPDIRECT3DBASETEXTURE9, *PDIRECT3DBASETEXTURE9;
+
+DEFINE_GUID(IID_IDirect3DTexture9, 0x85c31227, 0x3de5, 0x4f00, 0x9b, 0x3a, 0xf1, 0x1a, 0xc3, 0x8c, 0x18, 0xb5);
+typedef struct IDirect3DTexture9 *LPDIRECT3DTEXTURE9, *PDIRECT3DTEXTURE9;
+
+DEFINE_GUID(IID_IDirect3DCubeTexture9, 0xfff32f81, 0xd953, 0x473a, 0x92, 0x23, 0x93, 0xd6, 0x52, 0xab, 0xa9, 0x3f);
+typedef struct IDirect3DCubeTexture9 *LPDIRECT3DCUBETEXTURE9, *PDIRECT3DCUBETEXTURE9;
+
+DEFINE_GUID(IID_IDirect3DVolumeTexture9, 0x2518526c, 0xe789, 0x4111, 0xa7, 0xb9, 0x47, 0xef, 0x32, 0x8d, 0x13, 0xe6);
+typedef struct IDirect3DVolumeTexture9 *LPDIRECT3DVOLUMETEXTURE9, *PDIRECT3DVOLUMETEXTURE9;
+
+DEFINE_GUID(IID_IDirect3DVertexDeclaration9, 0xdd13c59c, 0x36fa, 0x4098, 0xa8, 0xfb, 0xc7, 0xed, 0x39, 0xdc, 0x85, 0x46);
+typedef struct IDirect3DVertexDeclaration9 *LPDIRECT3DVERTEXDECLARATION9;
+
+DEFINE_GUID(IID_IDirect3DVertexShader9, 0xefc5557e, 0x6265, 0x4613, 0x8a, 0x94, 0x43, 0x85, 0x78, 0x89, 0xeb, 0x36);
+typedef struct IDirect3DVertexShader9 *LPDIRECT3DVERTEXSHADER9;
+
+DEFINE_GUID(IID_IDirect3DPixelShader9, 0x6d3bdbdc, 0x5b02, 0x4415, 0xb8, 0x52, 0xce, 0x5e, 0x8b, 0xcc, 0xb2, 0x89);
+typedef struct IDirect3DPixelShader9 *LPDIRECT3DPIXELSHADER9;
+
+DEFINE_GUID(IID_IDirect3DStateBlock9, 0xb07c4fe5, 0x310d, 0x4ba8, 0xa2, 0x3c, 0x4f, 0xf, 0x20, 0x6f, 0x21, 0x8b);
+typedef struct IDirect3DStateBlock9 *LPDIRECT3DSTATEBLOCK9;
+
+DEFINE_GUID(IID_IDirect3DQuery9, 0xd9771460, 0xa695, 0x4f26, 0xbb, 0xd3, 0x27, 0xb8, 0x40, 0xb5, 0x41, 0xcc);
+typedef struct IDirect3DQuery9 *LPDIRECT3DQUERY9, *PDIRECT3DQUERY9;
+
+/*****************************************************************************
+ * IDirect3D9 interface
+ */
+#undef INTERFACE
+#define INTERFACE IDirect3D9
+DECLARE_INTERFACE_(IDirect3D9,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3D9 methods ***/
+ STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction) PURE;
+ STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE;
+ STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER9* pIdentifier) PURE;
+ STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter, D3DFORMAT Format) PURE;
+ STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE* pMode) PURE;
+ STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT Adapter, D3DDISPLAYMODE* pMode) PURE;
+ STDMETHOD(CheckDeviceType)(THIS_ UINT iAdapter, D3DDEVTYPE DevType, D3DFORMAT DisplayFormat, D3DFORMAT BackBufferFormat, BOOL bWindowed) PURE;
+ STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) PURE;
+ STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels) PURE;
+ STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) PURE;
+ STDMETHOD(CheckDeviceFormatConversion)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat) PURE;
+ STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) PURE;
+ STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter) PURE;
+ STDMETHOD(CreateDevice)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, struct IDirect3DDevice9** ppReturnedDeviceInterface) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3D9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3D9_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3D9_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3D9 methods ***/
+#define IDirect3D9_RegisterSoftwareDevice(p,a) (p)->lpVtbl->RegisterSoftwareDevice(p,a)
+#define IDirect3D9_GetAdapterCount(p) (p)->lpVtbl->GetAdapterCount(p)
+#define IDirect3D9_GetAdapterIdentifier(p,a,b,c) (p)->lpVtbl->GetAdapterIdentifier(p,a,b,c)
+#define IDirect3D9_GetAdapterModeCount(p,a,b) (p)->lpVtbl->GetAdapterModeCount(p,a,b)
+#define IDirect3D9_EnumAdapterModes(p,a,b,c,d) (p)->lpVtbl->EnumAdapterModes(p,a,b,c,d)
+#define IDirect3D9_GetAdapterDisplayMode(p,a,b) (p)->lpVtbl->GetAdapterDisplayMode(p,a,b)
+#define IDirect3D9_CheckDeviceType(p,a,b,c,d,e) (p)->lpVtbl->CheckDeviceType(p,a,b,c,d,e)
+#define IDirect3D9_CheckDeviceFormat(p,a,b,c,d,e,f) (p)->lpVtbl->CheckDeviceFormat(p,a,b,c,d,e,f)
+#define IDirect3D9_CheckDeviceMultiSampleType(p,a,b,c,d,e,f) (p)->lpVtbl->CheckDeviceMultiSampleType(p,a,b,c,d,e,f)
+#define IDirect3D9_CheckDepthStencilMatch(p,a,b,c,d,e) (p)->lpVtbl->CheckDepthStencilMatch(p,a,b,c,d,e)
+#define IDirect3D9_CheckDeviceFormatConversion(p,a,b,c,d) (p)->lpVtbl->CheckDeviceFormatConversion(p,a,b,c,d)
+#define IDirect3D9_GetDeviceCaps(p,a,b,c) (p)->lpVtbl->GetDeviceCaps(p,a,b,c)
+#define IDirect3D9_GetAdapterMonitor(p,a) (p)->lpVtbl->GetAdapterMonitor(p,a)
+#define IDirect3D9_CreateDevice(p,a,b,c,d,e,f) (p)->lpVtbl->CreateDevice(p,a,b,c,d,e,f)
+#else
+/*** IUnknown methods ***/
+#define IDirect3D9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3D9_AddRef(p) (p)->AddRef()
+#define IDirect3D9_Release(p) (p)->Release()
+/*** IDirect3D9 methods ***/
+#define IDirect3D9_RegisterSoftwareDevice(p,a) (p)->RegisterSoftwareDevice(a)
+#define IDirect3D9_GetAdapterCount(p) (p)->GetAdapterCount()
+#define IDirect3D9_GetAdapterIdentifier(p,a,b,c) (p)->GetAdapterIdentifier(a,b,c)
+#define IDirect3D9_GetAdapterModeCount(p,a,b) (p)->GetAdapterModeCount(a,b)
+#define IDirect3D9_EnumAdapterModes(p,a,b,c,d) (p)->EnumAdapterModes(a,b,c,d)
+#define IDirect3D9_GetAdapterDisplayMode(p,a,b) (p)->GetAdapterDisplayMode(a,b)
+#define IDirect3D9_CheckDeviceType(p,a,b,c,d,e) (p)->CheckDeviceType(a,b,c,d,e)
+#define IDirect3D9_CheckDeviceFormat(p,a,b,c,d,e,f) (p)->CheckDeviceFormat(a,b,c,d,e,f)
+#define IDirect3D9_CheckDeviceMultiSampleType(p,a,b,c,d,e,f) (p)->CheckDeviceMultiSampleType(a,b,c,d,e,f)
+#define IDirect3D9_CheckDepthStencilMatch(p,a,b,c,d,e) (p)->CheckDepthStencilMatch(a,b,c,d,e)
+#define IDirect3D9_CheckDeviceFormatConversion(p,a,b,c,d) (p)->CheckDeviceFormatConversion(a,b,c,d)
+#define IDirect3D9_GetDeviceCaps(p,a,b,c) (p)->GetDeviceCaps(a,b,c)
+#define IDirect3D9_GetAdapterMonitor(p,a) (p)->GetAdapterMonitor(a)
+#define IDirect3D9_CreateDevice(p,a,b,c,d,e,f) (p)->CreateDevice(a,b,c,d,e,f)
+#endif
+
+/*****************************************************************************
+ * IDirect3D9Ex interface
+ */
+#define INTERFACE IDirect3D9Ex
+DECLARE_INTERFACE_(IDirect3D9Ex,IDirect3D9)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3D9 methods ***/
+
+ /* Note: Microsoft's d3d9.h does not declare IDirect3D9Ex::RegisterSoftwareDevice . This would mean that
+ * the offsets of the other methods in the Vtable change too. This is wrong. In Microsoft's
+ * d3d9.dll, the offsets for the other functions are still compatible with IDirect3D9.
+ * This is probably because even in MS header IDirect3D9Ex inherits from IDirect3D9, which makes the
+ * C++ interface compatible, and nobody uses the C interface in Windows world.
+ */
+ STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction) PURE;
+
+ STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE;
+ STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER9* pIdentifier) PURE;
+ STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter, D3DFORMAT Format) PURE;
+ STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE* pMode) PURE;
+ STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT Adapter, D3DDISPLAYMODE* pMode) PURE;
+ STDMETHOD(CheckDeviceType)(THIS_ UINT iAdapter, D3DDEVTYPE DevType, D3DFORMAT DisplayFormat, D3DFORMAT BackBufferFormat, BOOL bWindowed) PURE;
+ STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) PURE;
+ STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels) PURE;
+ STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) PURE;
+ STDMETHOD(CheckDeviceFormatConversion)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat) PURE;
+ STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) PURE;
+ STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter) PURE;
+ STDMETHOD(CreateDevice)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, struct IDirect3DDevice9** ppReturnedDeviceInterface) PURE;
+ /*** IDirect3D9Ex methods ***/
+ STDMETHOD_(UINT, GetAdapterModeCountEx)(THIS_ UINT Adapter, CONST D3DDISPLAYMODEFILTER *pFilter) PURE;
+ STDMETHOD(EnumAdapterModesEx)(THIS_ UINT Adapter, CONST D3DDISPLAYMODEFILTER *pFilter, UINT Mode, D3DDISPLAYMODEEX* pMode) PURE;
+ STDMETHOD(GetAdapterDisplayModeEx)(THIS_ UINT Adapter, D3DDISPLAYMODEEX *pMode, D3DDISPLAYROTATION *pRotation);
+ STDMETHOD(CreateDeviceEx)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, D3DDISPLAYMODEEX* pFullscreenDisplayMode, struct IDirect3DDevice9Ex **ppReturnedDeviceInterface) PURE;
+ STDMETHOD(GetAdapterLUID)(THIS_ UINT Adatper, LUID *pLUID) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3D9Ex_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3D9Ex_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3D9Ex_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3D9 methods ***/
+#define IDirect3D9Ex_RegisterSoftwareDevice(p,a) (p)->lpVtbl->RegisterSoftwareDevice(p,a)
+#define IDirect3D9Ex_GetAdapterCount(p) (p)->lpVtbl->GetAdapterCount(p)
+#define IDirect3D9Ex_GetAdapterIdentifier(p,a,b,c) (p)->lpVtbl->GetAdapterIdentifier(p,a,b,c)
+#define IDirect3D9Ex_GetAdapterModeCount(p,a,b) (p)->lpVtbl->GetAdapterModeCount(p,a,b)
+#define IDirect3D9Ex_EnumAdapterModes(p,a,b,c,d) (p)->lpVtbl->EnumAdapterModes(p,a,b,c,d)
+#define IDirect3D9Ex_GetAdapterDisplayMode(p,a,b) (p)->lpVtbl->GetAdapterDisplayMode(p,a,b)
+#define IDirect3D9Ex_CheckDeviceType(p,a,b,c,d,e) (p)->lpVtbl->CheckDeviceType(p,a,b,c,d,e)
+#define IDirect3D9Ex_CheckDeviceFormat(p,a,b,c,d,e,f) (p)->lpVtbl->CheckDeviceFormat(p,a,b,c,d,e,f)
+#define IDirect3D9Ex_CheckDeviceMultiSampleType(p,a,b,c,d,e,f) (p)->lpVtbl->CheckDeviceMultiSampleType(p,a,b,c,d,e,f)
+#define IDirect3D9Ex_CheckDepthStencilMatch(p,a,b,c,d,e) (p)->lpVtbl->CheckDepthStencilMatch(p,a,b,c,d,e)
+#define IDirect3D9Ex_CheckDeviceFormatConversion(p,a,b,c,d) (p)->lpVtbl->CheckDeviceFormatConversion(p,a,b,c,d)
+#define IDirect3D9Ex_GetDeviceCaps(p,a,b,c) (p)->lpVtbl->GetDeviceCaps(p,a,b,c)
+#define IDirect3D9Ex_GetAdapterMonitor(p,a) (p)->lpVtbl->GetAdapterMonitor(p,a)
+#define IDirect3D9Ex_CreateDevice(p,a,b,c,d,e,f) (p)->lpVtbl->CreateDevice(p,a,b,c,d,e,f)
+/*** IDirect3D9Ex methods ***/
+#define IDirect3D9Ex_GetAdapterModeCountEx(p,a,b) (p)->lpVtbl->GetAdapterModeCountEx(p,a,b)
+#define IDirect3D9Ex_EnumAdapterModesEx(p,a,b,c,d) (p)->lpVtbl->EnumAdapterModesEx(p,a,b,c,d)
+#define IDirect3D9Ex_GetAdapterDisplayModeEx(p,a,b,c) (p)->lpVtbl->GetAdapterDisplayModeEx(p,a,b,c)
+#define IDirect3D9Ex_CreateDeviceEx(p,a,b,c,d,e,f,g) (p)->lpVtbl->CreateDeviceEx(p,a,b,c,d,e,f,g)
+#define IDirect3D9Ex_GetAdapterLUID(p,a,b) (p)->lpVtbl->GetAdapterLUID(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirect3D9Ex_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3D9Ex_AddRef(p) (p)->AddRef()
+#define IDirect3D9Ex_Release(p) (p)->Release()
+/*** IDirect3D9 methods ***/
+#define IDirect3D9Ex_RegisterSoftwareDevice(p,a) (p)->RegisterSoftwareDevice(a)
+#define IDirect3D9Ex_GetAdapterCount(p) (p)->GetAdapterCount()
+#define IDirect3D9Ex_GetAdapterIdentifier(p,a,b,c) (p)->GetAdapterIdentifier(a,b,c)
+#define IDirect3D9Ex_GetAdapterModeCount(p,a,b) (p)->GetAdapterModeCount(a,b)
+#define IDirect3D9Ex_EnumAdapterModes(p,a,b,c,d) (p)->EnumAdapterModes(a,b,c,d)
+#define IDirect3D9Ex_GetAdapterDisplayMode(p,a,b) (p)->GetAdapterDisplayMode(a,b)
+#define IDirect3D9Ex_CheckDeviceType(p,a,b,c,d,e) (p)->CheckDeviceType(a,b,c,d,e)
+#define IDirect3D9Ex_CheckDeviceFormat(p,a,b,c,d,e,f) (p)->CheckDeviceFormat(a,b,c,d,e,f)
+#define IDirect3D9Ex_CheckDeviceMultiSampleType(p,a,b,c,d,e,f) (p)->CheckDeviceMultiSampleType(a,b,c,d,e,f)
+#define IDirect3D9Ex_CheckDepthStencilMatch(p,a,b,c,d,e) (p)->CheckDepthStencilMatch(a,b,c,d,e)
+#define IDirect3D9Ex_CheckDeviceFormatConversion(p,a,b,c,d) (p)->CheckDeviceFormatConversion(a,b,c,d)
+#define IDirect3D9Ex_GetDeviceCaps(p,a,b,c) (p)->GetDeviceCaps(a,b,c)
+#define IDirect3D9Ex_GetAdapterMonitor(p,a) (p)->GetAdapterMonitor(a)
+#define IDirect3D9Ex_CreateDevice(p,a,b,c,d,e,f) (p)->CreateDevice(a,b,c,d,e,f)
+#endif
+
+/*****************************************************************************
+ * IDirect3DVolume9 interface
+ */
+#define INTERFACE IDirect3DVolume9
+DECLARE_INTERFACE_(IDirect3DVolume9,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DVolume9 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice9** ppDevice) PURE;
+ STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) PURE;
+ STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void* pData, DWORD* pSizeOfData) PURE;
+ STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+ STDMETHOD(GetContainer)(THIS_ REFIID riid, void** ppContainer) PURE;
+ STDMETHOD(GetDesc)(THIS_ D3DVOLUME_DESC* pDesc) PURE;
+ STDMETHOD(LockBox)(THIS_ D3DLOCKED_BOX* pLockedVolume, CONST D3DBOX* pBox, DWORD Flags) PURE;
+ STDMETHOD(UnlockBox)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DVolume9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DVolume9_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DVolume9_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DVolume9 methods ***/
+#define IDirect3DVolume9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DVolume9_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DVolume9_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DVolume9_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DVolume9_GetContainer(p,a,b) (p)->lpVtbl->GetContainer(p,a,b)
+#define IDirect3DVolume9_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a)
+#define IDirect3DVolume9_LockBox(p,a,b,c) (p)->lpVtbl->LockBox(p,a,b,c)
+#define IDirect3DVolume9_UnlockBox(p) (p)->lpVtbl->UnlockBox(p)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DVolume9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DVolume9_AddRef(p) (p)->AddRef()
+#define IDirect3DVolume9_Release(p) (p)->Release()
+/*** IDirect3DVolume9 methods ***/
+#define IDirect3DVolume9_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DVolume9_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DVolume9_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirect3DVolume9_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirect3DVolume9_GetContainer(p,a,b) (p)->GetContainer(a,b)
+#define IDirect3DVolume9_GetDesc(p,a) (p)->GetDesc(a)
+#define IDirect3DVolume9_LockBox(p,a,b,c) (p)->LockBox(a,b,c)
+#define IDirect3DVolume9_UnlockBox(p) (p)->UnlockBox()
+#endif
+
+/*****************************************************************************
+ * IDirect3DSwapChain9 interface
+ */
+#define INTERFACE IDirect3DSwapChain9
+DECLARE_INTERFACE_(IDirect3DSwapChain9,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DSwapChain9 methods ***/
+ STDMETHOD(Present)(THIS_ CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion, DWORD dwFlags) PURE;
+ STDMETHOD(GetFrontBufferData)(THIS_ struct IDirect3DSurface9* pDestSurface) PURE;
+ STDMETHOD(GetBackBuffer)(THIS_ UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, struct IDirect3DSurface9** ppBackBuffer) PURE;
+ STDMETHOD(GetRasterStatus)(THIS_ D3DRASTER_STATUS* pRasterStatus) PURE;
+ STDMETHOD(GetDisplayMode)(THIS_ D3DDISPLAYMODE* pMode) PURE;
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice9** ppDevice) PURE;
+ STDMETHOD(GetPresentParameters)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DSwapChain9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DSwapChain9_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DSwapChain9_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DSwapChain9 methods ***/
+#define IDirect3DSwapChain9_Present(p,a,b,c,d,e) (p)->lpVtbl->Present(p,a,b,c,d,e)
+#define IDirect3DSwapChain9_GetFrontBufferData(p,a) (p)->lpVtbl->GetFrontBufferData(p,a)
+#define IDirect3DSwapChain9_GetBackBuffer(p,a,b,c) (p)->lpVtbl->GetBackBuffer(p,a,b,c)
+#define IDirect3DSwapChain9_GetRasterStatus(p,a) (p)->lpVtbl->GetRasterStatus(p,a)
+#define IDirect3DSwapChain9_GetDisplayMode(p,a) (p)->lpVtbl->GetDisplayMode(p,a)
+#define IDirect3DSwapChain9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DSwapChain9_GetPresentParameters(p,a) (p)->lpVtbl->GetPresentParameters(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DSwapChain9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DSwapChain9_AddRef(p) (p)->AddRef()
+#define IDirect3DSwapChain9_Release(p) (p)->Release()
+/*** IDirect3DSwapChain9 methods ***/
+#define IDirect3DSwapChain9_Present(p,a,b,c,d,e) (p)->Present(a,b,c,d,e)
+#define IDirect3DSwapChain9_GetFrontBufferData(p,a) (p)->GetFrontBufferData(a)
+#define IDirect3DSwapChain9_GetBackBuffer(p,a,b,c) (p)->GetBackBuffer(a,b,c)
+#define IDirect3DSwapChain9_GetRasterStatus(p,a) (p)->GetRasterStatus(a)
+#define IDirect3DSwapChain9_GetDisplayMode(p,a) (p)->GetDisplayMode(a)
+#define IDirect3DSwapChain9_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DSwapChain9_GetPresentParameters(p,a) (p)->GetPresentParameters(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DResource9 interface
+ */
+#define INTERFACE IDirect3DResource9
+DECLARE_INTERFACE_(IDirect3DResource9,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DResource9 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice9** ppDevice) PURE;
+ STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) PURE;
+ STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void* pData, DWORD* pSizeOfData) PURE;
+ STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+ STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE;
+ STDMETHOD_(DWORD, GetPriority)(THIS) PURE;
+ STDMETHOD_(void, PreLoad)(THIS) PURE;
+ STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DResource9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DResource9_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DResource9_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DResource9 methods ***/
+#define IDirect3DResource9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DResource9_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DResource9_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DResource9_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DResource9_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DResource9_GetPriority(p) (p)->lpVtbl->GetPriority(p)
+#define IDirect3DResource9_PreLoad(p) (p)->lpVtbl->PreLoad(p)
+#define IDirect3DResource9_GetType(p) (p)->lpVtbl->GetType(p)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DResource9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DResource9_AddRef(p) (p)->AddRef()
+#define IDirect3DResource9_Release(p) (p)->Release()
+/*** IDirect3DResource9 methods ***/
+#define IDirect3DResource9_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DResource9_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DResource9_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirect3DResource9_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirect3DResource9_SetPriority(p,a) (p)->SetPriority(a)
+#define IDirect3DResource9_GetPriority(p) (p)->GetPriority()
+#define IDirect3DResource9_PreLoad(p) (p)->PreLoad()
+#define IDirect3DResource9_GetType(p) (p)->GetType()
+#endif
+
+/*****************************************************************************
+ * IDirect3DSurface9 interface
+ */
+#define INTERFACE IDirect3DSurface9
+DECLARE_INTERFACE_(IDirect3DSurface9,IDirect3DResource9)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DResource9 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice9** ppDevice) PURE;
+ STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) PURE;
+ STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void* pData, DWORD* pSizeOfData) PURE;
+ STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+ STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE;
+ STDMETHOD_(DWORD, GetPriority)(THIS) PURE;
+ STDMETHOD_(void, PreLoad)(THIS) PURE;
+ STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE;
+ /*** IDirect3DSurface9 methods ***/
+ STDMETHOD(GetContainer)(THIS_ REFIID riid, void** ppContainer) PURE;
+ STDMETHOD(GetDesc)(THIS_ D3DSURFACE_DESC* pDesc) PURE;
+ STDMETHOD(LockRect)(THIS_ D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) PURE;
+ STDMETHOD(UnlockRect)(THIS) PURE;
+ STDMETHOD(GetDC)(THIS_ HDC* phdc) PURE;
+ STDMETHOD(ReleaseDC)(THIS_ HDC hdc) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DSurface9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DSurface9_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DSurface9_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DSurface9 methods: IDirect3DResource9 ***/
+#define IDirect3DSurface9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DSurface9_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DSurface9_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DSurface9_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DSurface9_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DSurface9_GetPriority(p) (p)->lpVtbl->GetPriority(p)
+#define IDirect3DSurface9_PreLoad(p) (p)->lpVtbl->PreLoad(p)
+#define IDirect3DSurface9_GetType(p) (p)->lpVtbl->GetType(p)
+/*** IDirect3DSurface9 methods ***/
+#define IDirect3DSurface9_GetContainer(p,a,b) (p)->lpVtbl->GetContainer(p,a,b)
+#define IDirect3DSurface9_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a)
+#define IDirect3DSurface9_LockRect(p,a,b,c) (p)->lpVtbl->LockRect(p,a,b,c)
+#define IDirect3DSurface9_UnlockRect(p) (p)->lpVtbl->UnlockRect(p)
+#define IDirect3DSurface9_GetDC(p,a) (p)->lpVtbl->GetDC(p,a)
+#define IDirect3DSurface9_ReleaseDC(p,a) (p)->lpVtbl->ReleaseDC(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DSurface9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DSurface9_AddRef(p) (p)->AddRef()
+#define IDirect3DSurface9_Release(p) (p)->Release()
+/*** IDirect3DSurface9 methods: IDirect3DResource9 ***/
+#define IDirect3DSurface9_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DSurface9_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DSurface9_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirect3DSurface9_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirect3DSurface9_SetPriority(p,a) (p)->SetPriority(a)
+#define IDirect3DSurface9_GetPriority(p) (p)->GetPriority()
+#define IDirect3DSurface9_PreLoad(p) (p)->PreLoad()
+#define IDirect3DSurface9_GetType(p) (p)->GetType()
+/*** IDirect3DSurface9 methods ***/
+#define IDirect3DSurface9_GetContainer(p,a,b) (p)->GetContainer(a,b)
+#define IDirect3DSurface9_GetDesc(p,a) (p)->GetDesc(a)
+#define IDirect3DSurface9_LockRect(p,a,b,c) (p)->LockRect(a,b,c)
+#define IDirect3DSurface9_UnlockRect(p) (p)->UnlockRect()
+#define IDirect3DSurface9_GetDC(p,a) (p)->GetDC(a)
+#define IDirect3DSurface9_ReleaseDC(p,a) (p)->ReleaseDC(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DVertexBuffer9 interface
+ */
+#define INTERFACE IDirect3DVertexBuffer9
+DECLARE_INTERFACE_(IDirect3DVertexBuffer9,IDirect3DResource9)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DResource9 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice9** ppDevice) PURE;
+ STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) PURE;
+ STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void* pData, DWORD* pSizeOfData) PURE;
+ STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+ STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE;
+ STDMETHOD_(DWORD, GetPriority)(THIS) PURE;
+ STDMETHOD_(void, PreLoad)(THIS) PURE;
+ STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE;
+ /*** IDirect3DVertexBuffer9 methods ***/
+ STDMETHOD(Lock)(THIS_ UINT OffsetToLock, UINT SizeToLock, void** ppbData, DWORD Flags) PURE;
+ STDMETHOD(Unlock)(THIS) PURE;
+ STDMETHOD(GetDesc)(THIS_ D3DVERTEXBUFFER_DESC* pDesc) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DVertexBuffer9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DVertexBuffer9_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DVertexBuffer9_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DVertexBuffer9 methods: IDirect3DResource9 ***/
+#define IDirect3DVertexBuffer9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DVertexBuffer9_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DVertexBuffer9_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DVertexBuffer9_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DVertexBuffer9_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DVertexBuffer9_GetPriority(p) (p)->lpVtbl->GetPriority(p)
+#define IDirect3DVertexBuffer9_PreLoad(p) (p)->lpVtbl->PreLoad(p)
+#define IDirect3DVertexBuffer9_GetType(p) (p)->lpVtbl->GetType(p)
+/*** IDirect3DVertexBuffer9 methods ***/
+#define IDirect3DVertexBuffer9_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d)
+#define IDirect3DVertexBuffer9_Unlock(p) (p)->lpVtbl->Unlock(p)
+#define IDirect3DVertexBuffer9_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DVertexBuffer9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DVertexBuffer9_AddRef(p) (p)->AddRef()
+#define IDirect3DVertexBuffer9_Release(p) (p)->Release()
+/*** IDirect3DVertexBuffer9 methods: IDirect3DResource9 ***/
+#define IDirect3DVertexBuffer9_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DVertexBuffer9_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DVertexBuffer9_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirect3DVertexBuffer9_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirect3DVertexBuffer9_SetPriority(p,a) (p)->SetPriority(a)
+#define IDirect3DVertexBuffer9_GetPriority(p) (p)->GetPriority()
+#define IDirect3DVertexBuffer9_PreLoad(p) (p)->PreLoad()
+#define IDirect3DVertexBuffer9_GetType(p) (p)->GetType()
+/*** IDirect3DVertexBuffer9 methods ***/
+#define IDirect3DVertexBuffer9_Lock(p,a,b,c,d) (p)->Lock(a,b,c,d)
+#define IDirect3DVertexBuffer9_Unlock(p) (p)->Unlock()
+#define IDirect3DVertexBuffer9_GetDesc(p,a) (p)->GetDesc(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DIndexBuffer9 interface
+ */
+#define INTERFACE IDirect3DIndexBuffer9
+DECLARE_INTERFACE_(IDirect3DIndexBuffer9,IDirect3DResource9)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DResource9 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice9** ppDevice) PURE;
+ STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) PURE;
+ STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void* pData, DWORD* pSizeOfData) PURE;
+ STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+ STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE;
+ STDMETHOD_(DWORD, GetPriority)(THIS) PURE;
+ STDMETHOD_(void, PreLoad)(THIS) PURE;
+ STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE;
+ /*** IDirect3DIndexBuffer9 methods ***/
+ STDMETHOD(Lock)(THIS_ UINT OffsetToLock, UINT SizeToLock, void** ppbData, DWORD Flags) PURE;
+ STDMETHOD(Unlock)(THIS) PURE;
+ STDMETHOD(GetDesc)(THIS_ D3DINDEXBUFFER_DESC* pDesc) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DIndexBuffer9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DIndexBuffer9_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DIndexBuffer9_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DIndexBuffer9 methods: IDirect3DResource9 ***/
+#define IDirect3DIndexBuffer9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DIndexBuffer9_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DIndexBuffer9_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DIndexBuffer9_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DIndexBuffer9_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DIndexBuffer9_GetPriority(p) (p)->lpVtbl->GetPriority(p)
+#define IDirect3DIndexBuffer9_PreLoad(p) (p)->lpVtbl->PreLoad(p)
+#define IDirect3DIndexBuffer9_GetType(p) (p)->lpVtbl->GetType(p)
+/*** IDirect3DIndexBuffer9 methods ***/
+#define IDirect3DIndexBuffer9_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d)
+#define IDirect3DIndexBuffer9_Unlock(p) (p)->lpVtbl->Unlock(p)
+#define IDirect3DIndexBuffer9_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DIndexBuffer9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DIndexBuffer9_AddRef(p) (p)->AddRef()
+#define IDirect3DIndexBuffer9_Release(p) (p)->Release()
+/*** IDirect3DIndexBuffer9 methods: IDirect3DResource9 ***/
+#define IDirect3DIndexBuffer9_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DIndexBuffer9_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DIndexBuffer9_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirect3DIndexBuffer9_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirect3DIndexBuffer9_SetPriority(p,a) (p)->SetPriority(a)
+#define IDirect3DIndexBuffer9_GetPriority(p) (p)->GetPriority()
+#define IDirect3DIndexBuffer9_PreLoad(p) (p)->PreLoad()
+#define IDirect3DIndexBuffer9_GetType(p) (p)->GetType()
+/*** IDirect3DIndexBuffer9 methods ***/
+#define IDirect3DIndexBuffer9_Lock(p,a,b,c,d) (p)->Lock(a,b,c,d)
+#define IDirect3DIndexBuffer9_Unlock(p) (p)->Unlock()
+#define IDirect3DIndexBuffer9_GetDesc(p,a) (p)->GetDesc(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DBaseTexture9 interface
+ */
+#define INTERFACE IDirect3DBaseTexture9
+DECLARE_INTERFACE_(IDirect3DBaseTexture9,IDirect3DResource9)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DResource9 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice9** ppDevice) PURE;
+ STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) PURE;
+ STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void* pData, DWORD* pSizeOfData) PURE;
+ STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+ STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE;
+ STDMETHOD_(DWORD, GetPriority)(THIS) PURE;
+ STDMETHOD_(void, PreLoad)(THIS) PURE;
+ STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE;
+ /*** IDirect3DBaseTexture9 methods ***/
+ STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE;
+ STDMETHOD_(DWORD, GetLOD)(THIS) PURE;
+ STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE;
+ STDMETHOD(SetAutoGenFilterType)(THIS_ D3DTEXTUREFILTERTYPE FilterType) PURE;
+ STDMETHOD_(D3DTEXTUREFILTERTYPE, GetAutoGenFilterType)(THIS) PURE;
+ STDMETHOD_(void, GenerateMipSubLevels)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DBaseTexture9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DBaseTexture9_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DBaseTexture9_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DBaseTexture9 methods: IDirect3DResource9 ***/
+#define IDirect3DBaseTexture9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DBaseTexture9_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DBaseTexture9_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DBaseTexture9_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DBaseTexture9_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DBaseTexture9_GetPriority(p) (p)->lpVtbl->GetPriority(p)
+#define IDirect3DBaseTexture9_PreLoad(p) (p)->lpVtbl->PreLoad(p)
+#define IDirect3DBaseTexture9_GetType(p) (p)->lpVtbl->GetType(p)
+/*** IDirect3DBaseTexture9 methods ***/
+#define IDirect3DBaseTexture9_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a)
+#define IDirect3DBaseTexture9_GetLOD(p) (p)->lpVtbl->GetLOD(p)
+#define IDirect3DBaseTexture9_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p)
+#define IDirect3DBaseTexture9_SetAutoGenFilterType(p,a) (p)->lpVtbl->SetAutoGenFilterType(p,a)
+#define IDirect3DBaseTexture9_GetAutoGenFilterType(p) (p)->lpVtbl->GetAutoGenFilterType(p)
+#define IDirect3DBaseTexture9_GenerateMipSubLevels(p) (p)->lpVtbl->GenerateMipSubLevels(p)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DBaseTexture9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DBaseTexture9_AddRef(p) (p)->AddRef()
+#define IDirect3DBaseTexture9_Release(p) (p)->Release()
+/*** IDirect3DBaseTexture9 methods: IDirect3DResource9 ***/
+#define IDirect3DBaseTexture9_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DBaseTexture9_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DBaseTexture9_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirect3DBaseTexture9_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirect3DBaseTexture9_SetPriority(p,a) (p)->SetPriority(a)
+#define IDirect3DBaseTexture9_GetPriority(p) (p)->GetPriority()
+#define IDirect3DBaseTexture9_PreLoad(p) (p)->PreLoad()
+#define IDirect3DBaseTexture9_GetType(p) (p)->GetType()
+/*** IDirect3DBaseTexture9 methods ***/
+#define IDirect3DBaseTexture9_SetLOD(p,a) (p)->SetLOD(a)
+#define IDirect3DBaseTexture9_GetLOD(p) (p)->GetLOD()
+#define IDirect3DBaseTexture9_GetLevelCount(p) (p)->GetLevelCount()
+#define IDirect3DBaseTexture9_SetAutoGenFilterType(p,a) (p)->SetAutoGenFilterType(a)
+#define IDirect3DBaseTexture9_GetAutoGenFilterType(p) (p)->GetAutoGenFilterType()
+#define IDirect3DBaseTexture9_GenerateMipSubLevels(p) (p)->GenerateMipSubLevels()
+#endif
+
+/*****************************************************************************
+ * IDirect3DCubeTexture9 interface
+ */
+#define INTERFACE IDirect3DCubeTexture9
+DECLARE_INTERFACE_(IDirect3DCubeTexture9,IDirect3DBaseTexture9)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DResource9 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice9** ppDevice) PURE;
+ STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) PURE;
+ STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void* pData, DWORD* pSizeOfData) PURE;
+ STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+ STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE;
+ STDMETHOD_(DWORD, GetPriority)(THIS) PURE;
+ STDMETHOD_(void, PreLoad)(THIS) PURE;
+ STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE;
+ /*** IDirect3DBaseTexture9 methods ***/
+ STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE;
+ STDMETHOD_(DWORD, GetLOD)(THIS) PURE;
+ STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE;
+ STDMETHOD(SetAutoGenFilterType)(THIS_ D3DTEXTUREFILTERTYPE FilterType) PURE;
+ STDMETHOD_(D3DTEXTUREFILTERTYPE, GetAutoGenFilterType)(THIS) PURE;
+ STDMETHOD_(void, GenerateMipSubLevels)(THIS) PURE;
+ /*** IDirect3DCubeTexture9 methods ***/
+ STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DSURFACE_DESC* pDesc) PURE;
+ STDMETHOD(GetCubeMapSurface)(THIS_ D3DCUBEMAP_FACES FaceType, UINT Level, IDirect3DSurface9** ppCubeMapSurface) PURE;
+ STDMETHOD(LockRect)(THIS_ D3DCUBEMAP_FACES FaceType, UINT Level, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) PURE;
+ STDMETHOD(UnlockRect)(THIS_ D3DCUBEMAP_FACES FaceType, UINT Level) PURE;
+ STDMETHOD(AddDirtyRect)(THIS_ D3DCUBEMAP_FACES FaceType, CONST RECT* pDirtyRect) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DCubeTexture9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DCubeTexture9_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DCubeTexture9_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DCubeTexture9 methods: IDirect3DResource9 ***/
+#define IDirect3DCubeTexture9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DCubeTexture9_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DCubeTexture9_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DCubeTexture9_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DCubeTexture9_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DCubeTexture9_GetPriority(p) (p)->lpVtbl->GetPriority(p)
+#define IDirect3DCubeTexture9_PreLoad(p) (p)->lpVtbl->PreLoad(p)
+#define IDirect3DCubeTexture9_GetType(p) (p)->lpVtbl->GetType(p)
+/*** IDirect3DCubeTexture9 methods: IDirect3DBaseTexture9 ***/
+#define IDirect3DCubeTexture9_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a)
+#define IDirect3DCubeTexture9_GetLOD(p) (p)->lpVtbl->GetLOD(p)
+#define IDirect3DCubeTexture9_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p)
+#define IDirect3DCubeTexture9_SetAutoGenFilterType(p,a) (p)->lpVtbl->SetAutoGenFilterType(p,a)
+#define IDirect3DCubeTexture9_GetAutoGenFilterType(p) (p)->lpVtbl->GetAutoGenFilterType(p)
+#define IDirect3DCubeTexture9_GenerateMipSubLevels(p) (p)->lpVtbl->GenerateMipSubLevels(p)
+/*** IDirect3DCubeTexture9 methods ***/
+#define IDirect3DCubeTexture9_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b)
+#define IDirect3DCubeTexture9_GetCubeMapSurface(p,a,b,c) (p)->lpVtbl->GetCubeMapSurface(p,a,b,c)
+#define IDirect3DCubeTexture9_LockRect(p,a,b,c,d,e) (p)->lpVtbl->LockRect(p,a,b,c,d,e)
+#define IDirect3DCubeTexture9_UnlockRect(p,a,b) (p)->lpVtbl->UnlockRect(p,a,b)
+#define IDirect3DCubeTexture9_AddDirtyRect(p,a,b) (p)->lpVtbl->AddDirtyRect(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DCubeTexture9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DCubeTexture9_AddRef(p) (p)->AddRef()
+#define IDirect3DCubeTexture9_Release(p) (p)->Release()
+/*** IDirect3DCubeTexture9 methods: IDirect3DResource9 ***/
+#define IDirect3DCubeTexture9_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DCubeTexture9_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DCubeTexture9_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirect3DCubeTexture9_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirect3DCubeTexture9_SetPriority(p,a) (p)->SetPriority(a)
+#define IDirect3DCubeTexture9_GetPriority(p) (p)->GetPriority()
+#define IDirect3DCubeTexture9_PreLoad(p) (p)->PreLoad()
+#define IDirect3DCubeTexture9_GetType(p) (p)->GetType()
+/*** IDirect3DCubeTexture9 methods: IDirect3DBaseTexture9 ***/
+#define IDirect3DCubeTexture9_SetLOD(p,a) (p)->SetLOD(a)
+#define IDirect3DCubeTexture9_GetLOD(p) (p)->GetLOD()
+#define IDirect3DCubeTexture9_GetLevelCount(p) (p)->GetLevelCount()
+#define IDirect3DCubeTexture9_SetAutoGenFilterType(p,a) (p)->SetAutoGenFilterType(a)
+#define IDirect3DCubeTexture9_GetAutoGenFilterType(p) (p)->GetAutoGenFilterType()
+#define IDirect3DCubeTexture9_GenerateMipSubLevels(p) (p)->GenerateMipSubLevels()
+/*** IDirect3DCubeTexture9 methods ***/
+#define IDirect3DCubeTexture9_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b)
+#define IDirect3DCubeTexture9_GetCubeMapSurface(p,a,b,c) (p)->GetCubeMapSurface(a,b,c)
+#define IDirect3DCubeTexture9_LockRect(p,a,b,c,d,e) (p)->LockRect(a,b,c,d,e)
+#define IDirect3DCubeTexture9_UnlockRect(p,a,b) (p)->UnlockRect(a,b)
+#define IDirect3DCubeTexture9_AddDirtyRect(p,a,b) (p)->AddDirtyRect(a,b)
+#endif
+
+/*****************************************************************************
+ * IDirect3DTexture9 interface
+ */
+#define INTERFACE IDirect3DTexture9
+DECLARE_INTERFACE_(IDirect3DTexture9,IDirect3DBaseTexture9)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DResource9 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice9** ppDevice) PURE;
+ STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) PURE;
+ STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void* pData, DWORD* pSizeOfData) PURE;
+ STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+ STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE;
+ STDMETHOD_(DWORD, GetPriority)(THIS) PURE;
+ STDMETHOD_(void, PreLoad)(THIS) PURE;
+ STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE;
+ /*** IDirect3DBaseTexture9 methods ***/
+ STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE;
+ STDMETHOD_(DWORD, GetLOD)(THIS) PURE;
+ STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE;
+ STDMETHOD(SetAutoGenFilterType)(THIS_ D3DTEXTUREFILTERTYPE FilterType) PURE;
+ STDMETHOD_(D3DTEXTUREFILTERTYPE, GetAutoGenFilterType)(THIS) PURE;
+ STDMETHOD_(void, GenerateMipSubLevels)(THIS) PURE;
+ /*** IDirect3DTexture9 methods ***/
+ STDMETHOD(GetLevelDesc)(THIS_ UINT Level, D3DSURFACE_DESC* pDesc) PURE;
+ STDMETHOD(GetSurfaceLevel)(THIS_ UINT Level, IDirect3DSurface9** ppSurfaceLevel) PURE;
+ STDMETHOD(LockRect)(THIS_ UINT Level, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) PURE;
+ STDMETHOD(UnlockRect)(THIS_ UINT Level) PURE;
+ STDMETHOD(AddDirtyRect)(THIS_ CONST RECT* pDirtyRect) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DTexture9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DTexture9_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DTexture9_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DTexture9 methods: IDirect3DResource9 ***/
+#define IDirect3DTexture9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DTexture9_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DTexture9_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DTexture9_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DTexture9_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DTexture9_GetPriority(p) (p)->lpVtbl->GetPriority(p)
+#define IDirect3DTexture9_PreLoad(p) (p)->lpVtbl->PreLoad(p)
+#define IDirect3DTexture9_GetType(p) (p)->lpVtbl->GetType(p)
+/*** IDirect3DTexture9 methods: IDirect3DBaseTexture9 ***/
+#define IDirect3DTexture9_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a)
+#define IDirect3DTexture9_GetLOD(p) (p)->lpVtbl->GetLOD(p)
+#define IDirect3DTexture9_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p)
+#define IDirect3DTexture9_SetAutoGenFilterType(p,a) (p)->lpVtbl->SetAutoGenFilterType(p,a)
+#define IDirect3DTexture9_GetAutoGenFilterType(p) (p)->lpVtbl->GetAutoGenFilterType(p)
+#define IDirect3DTexture9_GenerateMipSubLevels(p) (p)->lpVtbl->GenerateMipSubLevels(p)
+/*** IDirect3DTexture9 methods ***/
+#define IDirect3DTexture9_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b)
+#define IDirect3DTexture9_GetSurfaceLevel(p,a,b) (p)->lpVtbl->GetSurfaceLevel(p,a,b)
+#define IDirect3DTexture9_LockRect(p,a,b,c,d) (p)->lpVtbl->LockRect(p,a,b,c,d)
+#define IDirect3DTexture9_UnlockRect(p,a) (p)->lpVtbl->UnlockRect(p,a)
+#define IDirect3DTexture9_AddDirtyRect(p,a) (p)->lpVtbl->AddDirtyRect(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DTexture9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DTexture9_AddRef(p) (p)->AddRef()
+#define IDirect3DTexture9_Release(p) (p)->Release()
+/*** IDirect3DTexture9 methods: IDirect3DResource9 ***/
+#define IDirect3DTexture9_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DTexture9_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DTexture9_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirect3DTexture9_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirect3DTexture9_SetPriority(p,a) (p)->SetPriority(a)
+#define IDirect3DTexture9_GetPriority(p) (p)->GetPriority()
+#define IDirect3DTexture9_PreLoad(p) (p)->PreLoad()
+#define IDirect3DTexture9_GetType(p) (p)->GetType()
+/*** IDirect3DTexture9 methods: IDirect3DBaseTexture9 ***/
+#define IDirect3DTexture9_SetLOD(p,a) (p)->SetLOD(a)
+#define IDirect3DTexture9_GetLOD(p) (p)->GetLOD()
+#define IDirect3DTexture9_GetLevelCount(p) (p)->GetLevelCount()
+#define IDirect3DTexture9_SetAutoGenFilterType(p,a) (p)->SetAutoGenFilterType(a)
+#define IDirect3DTexture9_GetAutoGenFilterType(p) (p)->GetAutoGenFilterType()
+#define IDirect3DTexture9_GenerateMipSubLevels(p) (p)->GenerateMipSubLevels()
+/*** IDirect3DTexture9 methods ***/
+#define IDirect3DTexture9_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b)
+#define IDirect3DTexture9_GetSurfaceLevel(p,a,b) (p)->GetSurfaceLevel(a,b)
+#define IDirect3DTexture9_LockRect(p,a,b,c,d) (p)->LockRect(a,b,c,d)
+#define IDirect3DTexture9_UnlockRect(p,a) (p)->UnlockRect(a)
+#define IDirect3DTexture9_AddDirtyRect(p,a) (p)->AddDirtyRect(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DVolumeTexture9 interface
+ */
+#define INTERFACE IDirect3DVolumeTexture9
+DECLARE_INTERFACE_(IDirect3DVolumeTexture9,IDirect3DBaseTexture9)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DResource9 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice9** ppDevice) PURE;
+ STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) PURE;
+ STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void* pData, DWORD* pSizeOfData) PURE;
+ STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+ STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE;
+ STDMETHOD_(DWORD, GetPriority)(THIS) PURE;
+ STDMETHOD_(void, PreLoad)(THIS) PURE;
+ STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE;
+ /*** IDirect3DBaseTexture9 methods ***/
+ STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE;
+ STDMETHOD_(DWORD, GetLOD)(THIS) PURE;
+ STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE;
+ STDMETHOD(SetAutoGenFilterType)(THIS_ D3DTEXTUREFILTERTYPE FilterType) PURE;
+ STDMETHOD_(D3DTEXTUREFILTERTYPE, GetAutoGenFilterType)(THIS) PURE;
+ STDMETHOD_(void, GenerateMipSubLevels)(THIS) PURE;
+ /*** IDirect3DVolumeTexture9 methods ***/
+ STDMETHOD(GetLevelDesc)(THIS_ UINT Level, D3DVOLUME_DESC *pDesc) PURE;
+ STDMETHOD(GetVolumeLevel)(THIS_ UINT Level, IDirect3DVolume9** ppVolumeLevel) PURE;
+ STDMETHOD(LockBox)(THIS_ UINT Level, D3DLOCKED_BOX* pLockedVolume, CONST D3DBOX* pBox, DWORD Flags) PURE;
+ STDMETHOD(UnlockBox)(THIS_ UINT Level) PURE;
+ STDMETHOD(AddDirtyBox)(THIS_ CONST D3DBOX* pDirtyBox) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DVolumeTexture9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DVolumeTexture9_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DVolumeTexture9_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DVolumeTexture9 methods: IDirect3DResource9 ***/
+#define IDirect3DVolumeTexture9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DVolumeTexture9_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DVolumeTexture9_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DVolumeTexture9_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DVolumeTexture9_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DVolumeTexture9_GetPriority(p) (p)->lpVtbl->GetPriority(p)
+#define IDirect3DVolumeTexture9_PreLoad(p) (p)->lpVtbl->PreLoad(p)
+#define IDirect3DVolumeTexture9_GetType(p) (p)->lpVtbl->GetType(p)
+/*** IDirect3DVolumeTexture9 methods: IDirect3DBaseTexture9 ***/
+#define IDirect3DVolumeTexture9_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a)
+#define IDirect3DVolumeTexture9_GetLOD(p) (p)->lpVtbl->GetLOD(p)
+#define IDirect3DVolumeTexture9_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p)
+#define IDirect3DVolumeTexture9_SetAutoGenFilterType(p,a) (p)->lpVtbl->SetAutoGenFilterType(p,a)
+#define IDirect3DVolumeTexture9_GetAutoGenFilterType(p) (p)->lpVtbl->GetAutoGenFilterType(p)
+#define IDirect3DVolumeTexture9_GenerateMipSubLevels(p) (p)->lpVtbl->GenerateMipSubLevels(p)
+/*** IDirect3DVolumeTexture9 methods ***/
+#define IDirect3DVolumeTexture9_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b)
+#define IDirect3DVolumeTexture9_GetVolumeLevel(p,a,b) (p)->lpVtbl->GetVolumeLevel(p,a,b)
+#define IDirect3DVolumeTexture9_LockBox(p,a,b,c,d) (p)->lpVtbl->LockBox(p,a,b,c,d)
+#define IDirect3DVolumeTexture9_UnlockBox(p,a) (p)->lpVtbl->UnlockBox(p,a)
+#define IDirect3DVolumeTexture9_AddDirtyBox(p,a) (p)->lpVtbl->AddDirtyBox(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DVolumeTexture9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DVolumeTexture9_AddRef(p) (p)->AddRef()
+#define IDirect3DVolumeTexture9_Release(p) (p)->Release()
+/*** IDirect3DVolumeTexture9 methods: IDirect3DResource9 ***/
+#define IDirect3DVolumeTexture9_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DVolumeTexture9_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DVolumeTexture9_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirect3DVolumeTexture9_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirect3DVolumeTexture9_SetPriority(p,a) (p)->SetPriority(a)
+#define IDirect3DVolumeTexture9_GetPriority(p) (p)->GetPriority()
+#define IDirect3DVolumeTexture9_PreLoad(p) (p)->PreLoad()
+#define IDirect3DVolumeTexture9_GetType(p) (p)->GetType()
+/*** IDirect3DVolumeTexture9 methods: IDirect3DBaseTexture9 ***/
+#define IDirect3DVolumeTexture9_SetLOD(p,a) (p)->SetLOD(a)
+#define IDirect3DVolumeTexture9_GetLOD(p) (p)->GetLOD()
+#define IDirect3DVolumeTexture9_GetLevelCount(p) (p)->GetLevelCount()
+#define IDirect3DVolumeTexture9_SetAutoGenFilterType(p,a) (p)->SetAutoGenFilterType(a)
+#define IDirect3DVolumeTexture9_GetAutoGenFilterType(p) (p)->GetAutoGenFilterType()
+#define IDirect3DVolumeTexture9_GenerateMipSubLevels(p) (p)->GenerateMipSubLevels()
+/*** IDirect3DVolumeTexture9 methods ***/
+#define IDirect3DVolumeTexture9_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b)
+#define IDirect3DVolumeTexture9_GetVolumeLevel(p,a,b) (p)->GetVolumeLevel(a,b)
+#define IDirect3DVolumeTexture9_LockBox(p,a,b,c,d) (p)->LockBox(a,b,c,d)
+#define IDirect3DVolumeTexture9_UnlockBox(p,a) (p)->UnlockBox(a)
+#define IDirect3DVolumeTexture9_AddDirtyBox(p,a) (p)->AddDirtyBox(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DVertexDeclaration9 interface
+ */
+#define INTERFACE IDirect3DVertexDeclaration9
+DECLARE_INTERFACE_(IDirect3DVertexDeclaration9,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DVertexDeclaration9 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice9** ppDevice) PURE;
+ STDMETHOD(GetDeclaration)(THIS_ D3DVERTEXELEMENT9*, UINT* pNumElements) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DVertexDeclaration9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DVertexDeclaration9_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DVertexDeclaration9_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DVertexShader9 methods ***/
+#define IDirect3DVertexDeclaration9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DVertexDeclaration9_GetDeclaration(p,a,b) (p)->lpVtbl->GetDeclaration(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DVertexDeclaration9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DVertexDeclaration9_AddRef(p) (p)->AddRef()
+#define IDirect3DVertexDeclaration9_Release(p) (p)->Release()
+/*** IDirect3DVertexShader9 methods ***/
+#define IDirect3DVertexDeclaration9_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DVertexDeclaration9_GetDeclaration(p,a,b) (p)->GetDeclaration(a,b)
+#endif
+
+/*****************************************************************************
+ * IDirect3DVertexShader9 interface
+ */
+#define INTERFACE IDirect3DVertexShader9
+DECLARE_INTERFACE_(IDirect3DVertexShader9,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DVertexShader9 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice9** ppDevice) PURE;
+ STDMETHOD(GetFunction)(THIS_ void*, UINT* pSizeOfData) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DVertexShader9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DVertexShader9_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DVertexShader9_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DVertexShader9 methods ***/
+#define IDirect3DVertexShader9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DVertexShader9_GetFunction(p,a,b) (p)->lpVtbl->GetFunction(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DVertexShader9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DVertexShader9_AddRef(p) (p)->AddRef()
+#define IDirect3DVertexShader9_Release(p) (p)->Release()
+/*** IDirect3DVertexShader9 methods ***/
+#define IDirect3DVertexShader9_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DVertexShader9_GetFunction(p,a,b) (p)->GetFunction(a,b)
+#endif
+
+/*****************************************************************************
+ * IDirect3DPixelShader9 interface
+ */
+#define INTERFACE IDirect3DPixelShader9
+DECLARE_INTERFACE_(IDirect3DPixelShader9,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DPixelShader9 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice9** ppDevice) PURE;
+ STDMETHOD(GetFunction)(THIS_ void*, UINT* pSizeOfData) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DPixelShader9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DPixelShader9_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DPixelShader9_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DPixelShader9 methods ***/
+#define IDirect3DPixelShader9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DPixelShader9_GetFunction(p,a,b) (p)->lpVtbl->GetFunction(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DPixelShader9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DPixelShader9_AddRef(p) (p)->AddRef()
+#define IDirect3DPixelShader9_Release(p) (p)->Release()
+/*** IDirect3DPixelShader9 methods ***/
+#define IDirect3DPixelShader9_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DPixelShader9_GetFunction(p,a,b) (p)->GetFunction(a,b)
+#endif
+
+/*****************************************************************************
+ * IDirect3DStateBlock9 interface
+ */
+#define INTERFACE IDirect3DStateBlock9
+DECLARE_INTERFACE_(IDirect3DStateBlock9,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DStateBlock9 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice9** ppDevice) PURE;
+ STDMETHOD(Capture)(THIS) PURE;
+ STDMETHOD(Apply)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DStateBlock9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DStateBlock9_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DStateBlock9_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DStateBlock9 methods ***/
+#define IDirect3DStateBlock9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DStateBlock9_Capture(p) (p)->lpVtbl->Capture(p)
+#define IDirect3DStateBlock9_Apply(p) (p)->lpVtbl->Apply(p)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DStateBlock9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DStateBlock9_AddRef(p) (p)->AddRef()
+#define IDirect3DStateBlock9_Release(p) (p)->Release()
+/*** IDirect3DStateBlock9 methods ***/
+#define IDirect3DStateBlock9_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DStateBlock9_Capture(p) (p)->Capture()
+#define IDirect3DStateBlock9_Apply(p) (p)->Apply()
+#endif
+
+/*****************************************************************************
+ * IDirect3DQuery9 interface
+ */
+#define INTERFACE IDirect3DQuery9
+DECLARE_INTERFACE_(IDirect3DQuery9,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DQuery9 methods ***/
+ STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice9** ppDevice) PURE;
+ STDMETHOD_(D3DQUERYTYPE, GetType)(THIS) PURE;
+ STDMETHOD_(DWORD, GetDataSize)(THIS) PURE;
+ STDMETHOD(Issue)(THIS_ DWORD dwIssueFlags) PURE;
+ STDMETHOD(GetData)(THIS_ void* pData, DWORD dwSize, DWORD dwGetDataFlags) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DQuery9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DQuery9_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DQuery9_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DQuery9 ***/
+#define IDirect3DQuery9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DQuery9_GetType(p) (p)->lpVtbl->GetType(p)
+#define IDirect3DQuery9_GetDataSize(p) (p)->lpVtbl->GetDataSize(p)
+#define IDirect3DQuery9_Issue(p,a) (p)->lpVtbl->Issue(p,a)
+#define IDirect3DQuery9_GetData(p,a,b,c) (p)->lpVtbl->GetData(p,a,b,c)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DQuery9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DQuery9_AddRef(p) (p)->AddRef()
+#define IDirect3DQuery9_Release(p) (p)->Release()
+/*** IDirect3DQuery9 ***/
+#define IDirect3DQuery9_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DQuery9_GetType(p) (p)->GetType()
+#define IDirect3DQuery9_GetDataSize(p) (p)->GetDataSize()
+#define IDirect3DQuery9_Issue(p,a) (p)->Issue(a)
+#define IDirect3DQuery9_GetData(p,a,b,c) (p)->GetData(a,b,c)
+#endif
+
+/*****************************************************************************
+ * IDirect3DDevice9 interface
+ */
+#define INTERFACE IDirect3DDevice9
+DECLARE_INTERFACE_(IDirect3DDevice9,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DDevice9 methods ***/
+ STDMETHOD(TestCooperativeLevel)(THIS) PURE;
+ STDMETHOD_(UINT, GetAvailableTextureMem)(THIS) PURE;
+ STDMETHOD(EvictManagedResources)(THIS) PURE;
+ STDMETHOD(GetDirect3D)(THIS_ IDirect3D9** ppD3D9) PURE;
+ STDMETHOD(GetDeviceCaps)(THIS_ D3DCAPS9* pCaps) PURE;
+ STDMETHOD(GetDisplayMode)(THIS_ UINT iSwapChain, D3DDISPLAYMODE* pMode) PURE;
+ STDMETHOD(GetCreationParameters)(THIS_ D3DDEVICE_CREATION_PARAMETERS *pParameters) PURE;
+ STDMETHOD(SetCursorProperties)(THIS_ UINT XHotSpot, UINT YHotSpot, IDirect3DSurface9* pCursorBitmap) PURE;
+ STDMETHOD_(void, SetCursorPosition)(THIS_ int X,int Y, DWORD Flags) PURE;
+ STDMETHOD_(BOOL, ShowCursor)(THIS_ BOOL bShow) PURE;
+ STDMETHOD(CreateAdditionalSwapChain)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain9** pSwapChain) PURE;
+ STDMETHOD(GetSwapChain)(THIS_ UINT iSwapChain, IDirect3DSwapChain9** pSwapChain) PURE;
+ STDMETHOD_(UINT, GetNumberOfSwapChains)(THIS) PURE;
+ STDMETHOD(Reset)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters) PURE;
+ STDMETHOD(Present)(THIS_ CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion) PURE;
+ STDMETHOD(GetBackBuffer)(THIS_ UINT iSwapChain, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9** ppBackBuffer) PURE;
+ STDMETHOD(GetRasterStatus)(THIS_ UINT iSwapChain, D3DRASTER_STATUS* pRasterStatus) PURE;
+ STDMETHOD(SetDialogBoxMode)(THIS_ BOOL bEnableDialogs) PURE;
+ STDMETHOD_(void, SetGammaRamp)(THIS_ UINT iSwapChain, DWORD Flags, CONST D3DGAMMARAMP* pRamp) PURE;
+ STDMETHOD_(void, GetGammaRamp)(THIS_ UINT iSwapChain, D3DGAMMARAMP* pRamp) PURE;
+ STDMETHOD(CreateTexture)(THIS_ UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture9** ppTexture, HANDLE* pSharedHandle) PURE;
+ STDMETHOD(CreateVolumeTexture)(THIS_ UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DVolumeTexture9** ppVolumeTexture, HANDLE* pSharedHandle) PURE;
+ STDMETHOD(CreateCubeTexture)(THIS_ UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture9** ppCubeTexture, HANDLE* pSharedHandle) PURE;
+ STDMETHOD(CreateVertexBuffer)(THIS_ UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle) PURE;
+ STDMETHOD(CreateIndexBuffer)(THIS_ UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle) PURE;
+ STDMETHOD(CreateRenderTarget)(THIS_ UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Lockable, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) PURE;
+ STDMETHOD(CreateDepthStencilSurface)(THIS_ UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Discard, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) PURE;
+ STDMETHOD(UpdateSurface)(THIS_ IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestinationSurface, CONST POINT* pDestPoint) PURE;
+ STDMETHOD(UpdateTexture)(THIS_ IDirect3DBaseTexture9* pSourceTexture, IDirect3DBaseTexture9* pDestinationTexture) PURE;
+ STDMETHOD(GetRenderTargetData)(THIS_ IDirect3DSurface9* pRenderTarget, IDirect3DSurface9* pDestSurface) PURE;
+ STDMETHOD(GetFrontBufferData)(THIS_ UINT iSwapChain, IDirect3DSurface9* pDestSurface) PURE;
+ STDMETHOD(StretchRect)(THIS_ IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestSurface, CONST RECT* pDestRect, D3DTEXTUREFILTERTYPE Filter) PURE;
+ STDMETHOD(ColorFill)(THIS_ IDirect3DSurface9* pSurface, CONST RECT* pRect, D3DCOLOR color) PURE;
+ STDMETHOD(CreateOffscreenPlainSurface)(THIS_ UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) PURE;
+ STDMETHOD(SetRenderTarget)(THIS_ DWORD RenderTargetIndex, IDirect3DSurface9* pRenderTarget) PURE;
+ STDMETHOD(GetRenderTarget)(THIS_ DWORD RenderTargetIndex, IDirect3DSurface9** ppRenderTarget) PURE;
+ STDMETHOD(SetDepthStencilSurface)(THIS_ IDirect3DSurface9* pNewZStencil) PURE;
+ STDMETHOD(GetDepthStencilSurface)(THIS_ IDirect3DSurface9** ppZStencilSurface) PURE;
+ STDMETHOD(BeginScene)(THIS) PURE;
+ STDMETHOD(EndScene)(THIS) PURE;
+ STDMETHOD(Clear)(THIS_ DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) PURE;
+ STDMETHOD(SetTransform)(THIS_ D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) PURE;
+ STDMETHOD(GetTransform)(THIS_ D3DTRANSFORMSTATETYPE State, D3DMATRIX* pMatrix) PURE;
+ STDMETHOD(MultiplyTransform)(THIS_ D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*) PURE;
+ STDMETHOD(SetViewport)(THIS_ CONST D3DVIEWPORT9* pViewport) PURE;
+ STDMETHOD(GetViewport)(THIS_ D3DVIEWPORT9* pViewport) PURE;
+ STDMETHOD(SetMaterial)(THIS_ CONST D3DMATERIAL9* pMaterial) PURE;
+ STDMETHOD(GetMaterial)(THIS_ D3DMATERIAL9* pMaterial) PURE;
+ STDMETHOD(SetLight)(THIS_ DWORD Index, CONST D3DLIGHT9*) PURE;
+ STDMETHOD(GetLight)(THIS_ DWORD Index, D3DLIGHT9*) PURE;
+ STDMETHOD(LightEnable)(THIS_ DWORD Index, BOOL Enable) PURE;
+ STDMETHOD(GetLightEnable)(THIS_ DWORD Index, BOOL* pEnable) PURE;
+ STDMETHOD(SetClipPlane)(THIS_ DWORD Index, CONST float* pPlane) PURE;
+ STDMETHOD(GetClipPlane)(THIS_ DWORD Index, float* pPlane) PURE;
+ STDMETHOD(SetRenderState)(THIS_ D3DRENDERSTATETYPE State, DWORD Value) PURE;
+ STDMETHOD(GetRenderState)(THIS_ D3DRENDERSTATETYPE State, DWORD* pValue) PURE;
+ STDMETHOD(CreateStateBlock)(THIS_ D3DSTATEBLOCKTYPE Type, IDirect3DStateBlock9** ppSB) PURE;
+ STDMETHOD(BeginStateBlock)(THIS) PURE;
+ STDMETHOD(EndStateBlock)(THIS_ IDirect3DStateBlock9** ppSB) PURE;
+ STDMETHOD(SetClipStatus)(THIS_ CONST D3DCLIPSTATUS9* pClipStatus) PURE;
+ STDMETHOD(GetClipStatus)(THIS_ D3DCLIPSTATUS9* pClipStatus) PURE;
+ STDMETHOD(GetTexture)(THIS_ DWORD Stage, IDirect3DBaseTexture9** ppTexture) PURE;
+ STDMETHOD(SetTexture)(THIS_ DWORD Stage, IDirect3DBaseTexture9* pTexture) PURE;
+ STDMETHOD(GetTextureStageState)(THIS_ DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD* pValue) PURE;
+ STDMETHOD(SetTextureStageState)(THIS_ DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) PURE;
+ STDMETHOD(GetSamplerState)(THIS_ DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD* pValue) PURE;
+ STDMETHOD(SetSamplerState)(THIS_ DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) PURE;
+ STDMETHOD(ValidateDevice)(THIS_ DWORD* pNumPasses) PURE;
+ STDMETHOD(SetPaletteEntries)(THIS_ UINT PaletteNumber, CONST PALETTEENTRY* pEntries) PURE;
+ STDMETHOD(GetPaletteEntries)(THIS_ UINT PaletteNumber,PALETTEENTRY* pEntries) PURE;
+ STDMETHOD(SetCurrentTexturePalette)(THIS_ UINT PaletteNumber) PURE;
+ STDMETHOD(GetCurrentTexturePalette)(THIS_ UINT *PaletteNumber) PURE;
+ STDMETHOD(SetScissorRect)(THIS_ CONST RECT* pRect) PURE;
+ STDMETHOD(GetScissorRect)(THIS_ RECT* pRect) PURE;
+ STDMETHOD(SetSoftwareVertexProcessing)(THIS_ BOOL bSoftware) PURE;
+ STDMETHOD_(BOOL, GetSoftwareVertexProcessing)(THIS) PURE;
+ STDMETHOD(SetNPatchMode)(THIS_ float nSegments) PURE;
+ STDMETHOD_(float, GetNPatchMode)(THIS) PURE;
+ STDMETHOD(DrawPrimitive)(THIS_ D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) PURE;
+ STDMETHOD(DrawIndexedPrimitive)(THIS_ D3DPRIMITIVETYPE, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount) PURE;
+ STDMETHOD(DrawPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) PURE;
+ STDMETHOD(DrawIndexedPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertices, UINT PrimitiveCount, CONST void* pIndexData, D3DFORMAT IndexDataFormat, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) PURE;
+ STDMETHOD(ProcessVertices)(THIS_ UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IDirect3DVertexBuffer9* pDestBuffer, IDirect3DVertexDeclaration9* pVertexDecl, DWORD Flags) PURE;
+ STDMETHOD(CreateVertexDeclaration)(THIS_ CONST D3DVERTEXELEMENT9* pVertexElements, IDirect3DVertexDeclaration9** ppDecl) PURE;
+ STDMETHOD(SetVertexDeclaration)(THIS_ IDirect3DVertexDeclaration9* pDecl) PURE;
+ STDMETHOD(GetVertexDeclaration)(THIS_ IDirect3DVertexDeclaration9** ppDecl) PURE;
+ STDMETHOD(SetFVF)(THIS_ DWORD FVF) PURE;
+ STDMETHOD(GetFVF)(THIS_ DWORD* pFVF) PURE;
+ STDMETHOD(CreateVertexShader)(THIS_ CONST DWORD* pFunction, IDirect3DVertexShader9** ppShader) PURE;
+ STDMETHOD(SetVertexShader)(THIS_ IDirect3DVertexShader9* pShader) PURE;
+ STDMETHOD(GetVertexShader)(THIS_ IDirect3DVertexShader9** ppShader) PURE;
+ STDMETHOD(SetVertexShaderConstantF)(THIS_ UINT StartRegister, CONST float* pConstantData, UINT Vector4fCount) PURE;
+ STDMETHOD(GetVertexShaderConstantF)(THIS_ UINT StartRegister, float* pConstantData, UINT Vector4fCount) PURE;
+ STDMETHOD(SetVertexShaderConstantI)(THIS_ UINT StartRegister, CONST int* pConstantData, UINT Vector4iCount) PURE;
+ STDMETHOD(GetVertexShaderConstantI)(THIS_ UINT StartRegister, int* pConstantData, UINT Vector4iCount) PURE;
+ STDMETHOD(SetVertexShaderConstantB)(THIS_ UINT StartRegister, CONST BOOL* pConstantData, UINT BoolCount) PURE;
+ STDMETHOD(GetVertexShaderConstantB)(THIS_ UINT StartRegister, BOOL* pConstantData, UINT BoolCount) PURE;
+ STDMETHOD(SetStreamSource)(THIS_ UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT Stride) PURE;
+ STDMETHOD(GetStreamSource)(THIS_ UINT StreamNumber, IDirect3DVertexBuffer9** ppStreamData, UINT* OffsetInBytes, UINT* pStride) PURE;
+ STDMETHOD(SetStreamSourceFreq)(THIS_ UINT StreamNumber, UINT Divider) PURE;
+ STDMETHOD(GetStreamSourceFreq)(THIS_ UINT StreamNumber, UINT* Divider) PURE;
+ STDMETHOD(SetIndices)(THIS_ IDirect3DIndexBuffer9* pIndexData) PURE;
+ STDMETHOD(GetIndices)(THIS_ IDirect3DIndexBuffer9** ppIndexData) PURE;
+ STDMETHOD(CreatePixelShader)(THIS_ CONST DWORD* pFunction, IDirect3DPixelShader9** ppShader) PURE;
+ STDMETHOD(SetPixelShader)(THIS_ IDirect3DPixelShader9* pShader) PURE;
+ STDMETHOD(GetPixelShader)(THIS_ IDirect3DPixelShader9** ppShader) PURE;
+ STDMETHOD(SetPixelShaderConstantF)(THIS_ UINT StartRegister, CONST float* pConstantData, UINT Vector4fCount) PURE;
+ STDMETHOD(GetPixelShaderConstantF)(THIS_ UINT StartRegister, float* pConstantData, UINT Vector4fCount) PURE;
+ STDMETHOD(SetPixelShaderConstantI)(THIS_ UINT StartRegister, CONST int* pConstantData, UINT Vector4iCount) PURE;
+ STDMETHOD(GetPixelShaderConstantI)(THIS_ UINT StartRegister, int* pConstantData, UINT Vector4iCount) PURE;
+ STDMETHOD(SetPixelShaderConstantB)(THIS_ UINT StartRegister, CONST BOOL* pConstantData, UINT BoolCount) PURE;
+ STDMETHOD(GetPixelShaderConstantB)(THIS_ UINT StartRegister, BOOL* pConstantData, UINT BoolCount) PURE;
+ STDMETHOD(DrawRectPatch)(THIS_ UINT Handle, CONST float* pNumSegs, CONST D3DRECTPATCH_INFO* pRectPatchInfo) PURE;
+ STDMETHOD(DrawTriPatch)(THIS_ UINT Handle, CONST float* pNumSegs, CONST D3DTRIPATCH_INFO* pTriPatchInfo) PURE;
+ STDMETHOD(DeletePatch)(THIS_ UINT Handle) PURE;
+ STDMETHOD(CreateQuery)(THIS_ D3DQUERYTYPE Type, IDirect3DQuery9** ppQuery) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DDevice9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DDevice9_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DDevice9_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DDevice9 methods ***/
+#define IDirect3DDevice9_TestCooperativeLevel(p) (p)->lpVtbl->TestCooperativeLevel(p)
+#define IDirect3DDevice9_GetAvailableTextureMem(p) (p)->lpVtbl->GetAvailableTextureMem(p)
+#define IDirect3DDevice9_EvictManagedResources(p) (p)->lpVtbl->EvictManagedResources(p)
+#define IDirect3DDevice9_GetDirect3D(p,a) (p)->lpVtbl->GetDirect3D(p,a)
+#define IDirect3DDevice9_GetDeviceCaps(p,a) (p)->lpVtbl->GetDeviceCaps(p,a)
+#define IDirect3DDevice9_GetDisplayMode(p,a,b) (p)->lpVtbl->GetDisplayMode(p,a,b)
+#define IDirect3DDevice9_GetCreationParameters(p,a) (p)->lpVtbl->GetCreationParameters(p,a)
+#define IDirect3DDevice9_SetCursorProperties(p,a,b,c) (p)->lpVtbl->SetCursorProperties(p,a,b,c)
+#define IDirect3DDevice9_SetCursorPosition(p,a,b,c) (p)->lpVtbl->SetCursorPosition(p,a,b,c)
+#define IDirect3DDevice9_ShowCursor(p,a) (p)->lpVtbl->ShowCursor(p,a)
+#define IDirect3DDevice9_CreateAdditionalSwapChain(p,a,b) (p)->lpVtbl->CreateAdditionalSwapChain(p,a,b)
+#define IDirect3DDevice9_GetSwapChain(p,a,b) (p)->lpVtbl->GetSwapChain(p,a,b)
+#define IDirect3DDevice9_GetNumberOfSwapChains(p) (p)->lpVtbl->GetNumberOfSwapChains(p)
+#define IDirect3DDevice9_Reset(p,a) (p)->lpVtbl->Reset(p,a)
+#define IDirect3DDevice9_Present(p,a,b,c,d) (p)->lpVtbl->Present(p,a,b,c,d)
+#define IDirect3DDevice9_GetBackBuffer(p,a,b,c,d) (p)->lpVtbl->GetBackBuffer(p,a,b,c,d)
+#define IDirect3DDevice9_GetRasterStatus(p,a,b) (p)->lpVtbl->GetRasterStatus(p,a,b)
+#define IDirect3DDevice9_SetDialogBoxMode(p,a) (p)->lpVtbl->SetDialogBoxMode(p,a)
+#define IDirect3DDevice9_SetGammaRamp(p,a,b,c) (p)->lpVtbl->SetGammaRamp(p,a,b,c)
+#define IDirect3DDevice9_GetGammaRamp(p,a,b) (p)->lpVtbl->GetGammaRamp(p,a,b)
+#define IDirect3DDevice9_CreateTexture(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->CreateTexture(p,a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9_CreateVolumeTexture(p,a,b,c,d,e,f,g,h,i) (p)->lpVtbl->CreateVolumeTexture(p,a,b,c,d,e,f,g,h,i)
+#define IDirect3DDevice9_CreateCubeTexture(p,a,b,c,d,e,f,g) (p)->lpVtbl->CreateCubeTexture(p,a,b,c,d,e,f,g)
+#define IDirect3DDevice9_CreateVertexBuffer(p,a,b,c,d,e,f) (p)->lpVtbl->CreateVertexBuffer(p,a,b,c,d,e,f)
+#define IDirect3DDevice9_CreateIndexBuffer(p,a,b,c,d,e,f) (p)->lpVtbl->CreateIndexBuffer(p,a,b,c,d,e,f)
+#define IDirect3DDevice9_CreateRenderTarget(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->CreateRenderTarget(p,a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9_CreateDepthStencilSurface(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->CreateDepthStencilSurface(p,a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9_UpdateSurface(p,a,b,c,d) (p)->lpVtbl->UpdateSurface(p,a,b,c,d)
+#define IDirect3DDevice9_UpdateTexture(p,a,b) (p)->lpVtbl->UpdateTexture(p,a,b)
+#define IDirect3DDevice9_GetRenderTargetData(p,a,b) (p)->lpVtbl->GetRenderTargetData(p,a,b)
+#define IDirect3DDevice9_GetFrontBufferData(p,a,b) (p)->lpVtbl->GetFrontBufferData(p,a,b)
+#define IDirect3DDevice9_StretchRect(p,a,b,c,d,e) (p)->lpVtbl->StretchRect(p,a,b,c,d,e)
+#define IDirect3DDevice9_ColorFill(p,a,b,c) (p)->lpVtbl->ColorFill(p,a,b,c)
+#define IDirect3DDevice9_CreateOffscreenPlainSurface(p,a,b,c,d,e,f) (p)->lpVtbl->CreateOffscreenPlainSurface(p,a,b,c,d,e,f)
+#define IDirect3DDevice9_SetRenderTarget(p,a,b) (p)->lpVtbl->SetRenderTarget(p,a,b)
+#define IDirect3DDevice9_GetRenderTarget(p,a,b) (p)->lpVtbl->GetRenderTarget(p,a,b)
+#define IDirect3DDevice9_SetDepthStencilSurface(p,a) (p)->lpVtbl->SetDepthStencilSurface(p,a)
+#define IDirect3DDevice9_GetDepthStencilSurface(p,a) (p)->lpVtbl->GetDepthStencilSurface(p,a)
+#define IDirect3DDevice9_BeginScene(p) (p)->lpVtbl->BeginScene(p)
+#define IDirect3DDevice9_EndScene(p) (p)->lpVtbl->EndScene(p)
+#define IDirect3DDevice9_Clear(p,a,b,c,d,e,f) (p)->lpVtbl->Clear(p,a,b,c,d,e,f)
+#define IDirect3DDevice9_SetTransform(p,a,b) (p)->lpVtbl->SetTransform(p,a,b)
+#define IDirect3DDevice9_GetTransform(p,a,b) (p)->lpVtbl->GetTransform(p,a,b)
+#define IDirect3DDevice9_MultiplyTransform(p,a,b) (p)->lpVtbl->MultiplyTransform(p,a,b)
+#define IDirect3DDevice9_SetViewport(p,a) (p)->lpVtbl->SetViewport(p,a)
+#define IDirect3DDevice9_GetViewport(p,a) (p)->lpVtbl->GetViewport(p,a)
+#define IDirect3DDevice9_SetMaterial(p,a) (p)->lpVtbl->SetMaterial(p,a)
+#define IDirect3DDevice9_GetMaterial(p,a) (p)->lpVtbl->GetMaterial(p,a)
+#define IDirect3DDevice9_SetLight(p,a,b) (p)->lpVtbl->SetLight(p,a,b)
+#define IDirect3DDevice9_GetLight(p,a,b) (p)->lpVtbl->GetLight(p,a,b)
+#define IDirect3DDevice9_LightEnable(p,a,b) (p)->lpVtbl->LightEnable(p,a,b)
+#define IDirect3DDevice9_GetLightEnable(p,a,b) (p)->lpVtbl->GetLightEnable(p,a,b)
+#define IDirect3DDevice9_SetClipPlane(p,a,b) (p)->lpVtbl->SetClipPlane(p,a,b)
+#define IDirect3DDevice9_GetClipPlane(p,a,b) (p)->lpVtbl->GetClipPlane(p,a,b)
+#define IDirect3DDevice9_SetRenderState(p,a,b) (p)->lpVtbl->SetRenderState(p,a,b)
+#define IDirect3DDevice9_GetRenderState(p,a,b) (p)->lpVtbl->GetRenderState(p,a,b)
+#define IDirect3DDevice9_CreateStateBlock(p,a,b) (p)->lpVtbl->CreateStateBlock(p,a,b)
+#define IDirect3DDevice9_BeginStateBlock(p) (p)->lpVtbl->BeginStateBlock(p)
+#define IDirect3DDevice9_EndStateBlock(p,a) (p)->lpVtbl->EndStateBlock(p,a)
+#define IDirect3DDevice9_SetClipStatus(p,a) (p)->lpVtbl->SetClipStatus(p,a)
+#define IDirect3DDevice9_GetClipStatus(p,a) (p)->lpVtbl->GetClipStatus(p,a)
+#define IDirect3DDevice9_GetTexture(p,a,b) (p)->lpVtbl->GetTexture(p,a,b)
+#define IDirect3DDevice9_SetTexture(p,a,b) (p)->lpVtbl->SetTexture(p,a,b)
+#define IDirect3DDevice9_GetTextureStageState(p,a,b,c) (p)->lpVtbl->GetTextureStageState(p,a,b,c)
+#define IDirect3DDevice9_SetTextureStageState(p,a,b,c) (p)->lpVtbl->SetTextureStageState(p,a,b,c)
+#define IDirect3DDevice9_GetSamplerState(p,a,b,c) (p)->lpVtbl->GetSamplerState(p,a,b,c)
+#define IDirect3DDevice9_SetSamplerState(p,a,b,c) (p)->lpVtbl->SetSamplerState(p,a,b,c)
+#define IDirect3DDevice9_ValidateDevice(p,a) (p)->lpVtbl->ValidateDevice(p,a)
+#define IDirect3DDevice9_SetPaletteEntries(p,a,b) (p)->lpVtbl->SetPaletteEntries(p,a,b)
+#define IDirect3DDevice9_GetPaletteEntries(p,a,b) (p)->lpVtbl->GetPaletteEntries(p,a,b)
+#define IDirect3DDevice9_SetCurrentTexturePalette(p,a) (p)->lpVtbl->SetCurrentTexturePalette(p,a)
+#define IDirect3DDevice9_GetCurrentTexturePalette(p,a) (p)->lpVtbl->GetCurrentTexturePalette(p,a)
+#define IDirect3DDevice9_SetScissorRect(p,a) (p)->lpVtbl->SetScissorRect(p,a)
+#define IDirect3DDevice9_GetScissorRect(p,a) (p)->lpVtbl->GetScissorRect(p,a)
+#define IDirect3DDevice9_SetSoftwareVertexProcessing(p,a) (p)->lpVtbl->SetSoftwareVertexProcessing(p,a)
+#define IDirect3DDevice9_GetSoftwareVertexProcessing(p) (p)->lpVtbl->GetSoftwareVertexProcessing(p)
+#define IDirect3DDevice9_SetNPatchMode(p,a) (p)->lpVtbl->SetNPatchMode(p,a)
+#define IDirect3DDevice9_GetNPatchMode(p) (p)->lpVtbl->GetNPatchMode(p)
+#define IDirect3DDevice9_DrawPrimitive(p,a,b,c) (p)->lpVtbl->DrawPrimitive(p,a,b,c)
+#define IDirect3DDevice9_DrawIndexedPrimitive(p,a,b,c,d,e,f) (p)->lpVtbl->DrawIndexedPrimitive(p,a,b,c,d,e,f)
+#define IDirect3DDevice9_DrawPrimitiveUP(p,a,b,c,d) (p)->lpVtbl->DrawPrimitiveUP(p,a,b,c,d)
+#define IDirect3DDevice9_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9_ProcessVertices(p,a,b,c,d,e,f) (p)->lpVtbl->ProcessVertices(p,a,b,c,d,e,f)
+#define IDirect3DDevice9_CreateVertexDeclaration(p,a,b) (p)->lpVtbl->CreateVertexDeclaration(p,a,b)
+#define IDirect3DDevice9_SetVertexDeclaration(p,a) (p)->lpVtbl->SetVertexDeclaration(p,a)
+#define IDirect3DDevice9_GetVertexDeclaration(p,a) (p)->lpVtbl->GetVertexDeclaration(p,a)
+#define IDirect3DDevice9_SetFVF(p,a) (p)->lpVtbl->SetFVF(p,a)
+#define IDirect3DDevice9_GetFVF(p,a) (p)->lpVtbl->GetFVF(p,a)
+#define IDirect3DDevice9_CreateVertexShader(p,a,b) (p)->lpVtbl->CreateVertexShader(p,a,b)
+#define IDirect3DDevice9_SetVertexShader(p,a) (p)->lpVtbl->SetVertexShader(p,a)
+#define IDirect3DDevice9_GetVertexShader(p,a) (p)->lpVtbl->GetVertexShader(p,a)
+#define IDirect3DDevice9_SetVertexShaderConstantF(p,a,b,c) (p)->lpVtbl->SetVertexShaderConstantF(p,a,b,c)
+#define IDirect3DDevice9_GetVertexShaderConstantF(p,a,b,c) (p)->lpVtbl->GetVertexShaderConstantF(p,a,b,c)
+#define IDirect3DDevice9_SetVertexShaderConstantI(p,a,b,c) (p)->lpVtbl->SetVertexShaderConstantI(p,a,b,c)
+#define IDirect3DDevice9_GetVertexShaderConstantI(p,a,b,c) (p)->lpVtbl->GetVertexShaderConstantI(p,a,b,c)
+#define IDirect3DDevice9_SetVertexShaderConstantB(p,a,b,c) (p)->lpVtbl->SetVertexShaderConstantB(p,a,b,c)
+#define IDirect3DDevice9_GetVertexShaderConstantB(p,a,b,c) (p)->lpVtbl->GetVertexShaderConstantB(p,a,b,c)
+#define IDirect3DDevice9_SetStreamSource(p,a,b,c,d) (p)->lpVtbl->SetStreamSource(p,a,b,c,d)
+#define IDirect3DDevice9_GetStreamSource(p,a,b,c,d) (p)->lpVtbl->GetStreamSource(p,a,b,c,d)
+#define IDirect3DDevice9_SetStreamSourceFreq(p,a,b) (p)->lpVtbl->SetStreamSourceFreq(p,a,b)
+#define IDirect3DDevice9_GetStreamSourceFreq(p,a,b) (p)->lpVtbl->GetStreamSourceFreq(p,a,b)
+#define IDirect3DDevice9_SetIndices(p,a) (p)->lpVtbl->SetIndices(p,a)
+#define IDirect3DDevice9_GetIndices(p,a) (p)->lpVtbl->GetIndices(p,a)
+#define IDirect3DDevice9_CreatePixelShader(p,a,b) (p)->lpVtbl->CreatePixelShader(p,a,b)
+#define IDirect3DDevice9_SetPixelShader(p,a) (p)->lpVtbl->SetPixelShader(p,a)
+#define IDirect3DDevice9_GetPixelShader(p,a) (p)->lpVtbl->GetPixelShader(p,a)
+#define IDirect3DDevice9_SetPixelShaderConstantF(p,a,b,c) (p)->lpVtbl->SetPixelShaderConstantF(p,a,b,c)
+#define IDirect3DDevice9_GetPixelShaderConstantF(p,a,b,c) (p)->lpVtbl->GetPixelShaderConstantF(p,a,b,c)
+#define IDirect3DDevice9_SetPixelShaderConstantI(p,a,b,c) (p)->lpVtbl->SetPixelShaderConstantI(p,a,b,c)
+#define IDirect3DDevice9_GetPixelShaderConstantI(p,a,b,c) (p)->lpVtbl->GetPixelShaderConstantI(p,a,b,c)
+#define IDirect3DDevice9_SetPixelShaderConstantB(p,a,b,c) (p)->lpVtbl->SetPixelShaderConstantB(p,a,b,c)
+#define IDirect3DDevice9_GetPixelShaderConstantB(p,a,b,c) (p)->lpVtbl->GetPixelShaderConstantB(p,a,b,c)
+#define IDirect3DDevice9_DrawRectPatch(p,a,b,c) (p)->lpVtbl->DrawRectPatch(p,a,b,c)
+#define IDirect3DDevice9_DrawTriPatch(p,a,b,c) (p)->lpVtbl->DrawTriPatch(p,a,b,c)
+#define IDirect3DDevice9_DeletePatch(p,a) (p)->lpVtbl->DeletePatch(p,a)
+#define IDirect3DDevice9_CreateQuery(p,a,b) (p)->lpVtbl->CreateQuery(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DDevice9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DDevice9_AddRef(p) (p)->AddRef()
+#define IDirect3DDevice9_Release(p) (p)->Release()
+/*** IDirect3DDevice9 methods ***/
+#define IDirect3DDevice9_TestCooperativeLevel(p) (p)->TestCooperativeLevel()
+#define IDirect3DDevice9_GetAvailableTextureMem(p) (p)->GetAvailableTextureMem()
+#define IDirect3DDevice9_EvictManagedResources(p) (p)->EvictManagedResources()
+#define IDirect3DDevice9_GetDirect3D(p,a) (p)->GetDirect3D(a)
+#define IDirect3DDevice9_GetDeviceCaps(p,a) (p)->GetDeviceCaps(a)
+#define IDirect3DDevice9_GetDisplayMode(p,a,b) (p)->GetDisplayMode(a,b)
+#define IDirect3DDevice9_GetCreationParameters(p,a) (p)->GetCreationParameters(a)
+#define IDirect3DDevice9_SetCursorProperties(p,a,b,c) (p)->SetCursorProperties(a,b,c)
+#define IDirect3DDevice9_SetCursorPosition(p,a,b,c) (p)->SetCursorPosition(a,b,c)
+#define IDirect3DDevice9_ShowCursor(p,a) (p)->ShowCursor(a)
+#define IDirect3DDevice9_CreateAdditionalSwapChain(p,a,b) (p)->CreateAdditionalSwapChain(a,b)
+#define IDirect3DDevice9_GetSwapChain(p,a,b) (p)->GetSwapChain(a,b)
+#define IDirect3DDevice9_GetNumberOfSwapChains(p) (p)->GetNumberOfSwapChains()
+#define IDirect3DDevice9_Reset(p,a) (p)->Reset(a)
+#define IDirect3DDevice9_Present(p,a,b,c,d) (p)->Present(a,b,c,d)
+#define IDirect3DDevice9_GetBackBuffer(p,a,b,c,d) (p)->GetBackBuffer(a,b,c,d)
+#define IDirect3DDevice9_GetRasterStatus(p,a,b) (p)->GetRasterStatus(a,b)
+#define IDirect3DDevice9_SetDialogBoxMode(p,a) (p)->SetDialogBoxMode(a)
+#define IDirect3DDevice9_SetGammaRamp(p,a,b,c) (p)->SetGammaRamp(a,b,c)
+#define IDirect3DDevice9_GetGammaRamp(p,a,b) (p)->GetGammaRamp(a,b)
+#define IDirect3DDevice9_CreateTexture(p,a,b,c,d,e,f,g,h) (p)->CreateTexture(a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9_CreateVolumeTexture(p,a,b,c,d,e,f,g,h,i) (p)->CreateVolumeTexture(a,b,c,d,e,f,g,h,i)
+#define IDirect3DDevice9_CreateCubeTexture(p,a,b,c,d,e,f,g) (p)->CreateCubeTexture(a,b,c,d,e,f,g)
+#define IDirect3DDevice9_CreateVertexBuffer(p,a,b,c,d,e,f) (p)->CreateVertexBuffer(a,b,c,d,e,f)
+#define IDirect3DDevice9_CreateIndexBuffer(p,a,b,c,d,e,f) (p)->CreateIndexBuffer(a,b,c,d,e,f)
+#define IDirect3DDevice9_CreateRenderTarget(p,a,b,c,d,e,f,g,h) (p)->CreateRenderTarget(a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9_CreateDepthStencilSurface(p,a,b,c,d,e,f,g,h) (p)->CreateDepthStencilSurface(a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9_UpdateSurface(p,a,b,c,d) (p)->UpdateSurface(a,b,c,d)
+#define IDirect3DDevice9_UpdateTexture(p,a,b) (p)->UpdateTexture(a,b)
+#define IDirect3DDevice9_GetRenderTargetData(p,a,b) (p)->GetRenderTargetData(a,b)
+#define IDirect3DDevice9_GetFrontBufferData(p,a,b) (p)->GetFrontBufferData(a,b)
+#define IDirect3DDevice9_StretchRect(p,a,b,c,d,e) (p)->StretchRect(a,b,c,d,e)
+#define IDirect3DDevice9_ColorFill(p,a,b,c) (p)->ColorFill(a,b,c)
+#define IDirect3DDevice9_CreateOffscreenPlainSurface(p,a,b,c,d,e,f) (p)->CreateOffscreenPlainSurface(a,b,c,d,e,f)
+#define IDirect3DDevice9_SetRenderTarget(p,a,b) (p)->SetRenderTarget(a,b)
+#define IDirect3DDevice9_GetRenderTarget(p,a,b) (p)->GetRenderTarget(a,b)
+#define IDirect3DDevice9_SetDepthStencilSurface(p,a) (p)->SetDepthStencilSurface(a)
+#define IDirect3DDevice9_GetDepthStencilSurface(p,a) (p)->GetDepthStencilSurface(a)
+#define IDirect3DDevice9_BeginScene(p) (p)->BeginScene()
+#define IDirect3DDevice9_EndScene(p) (p)->EndScene()
+#define IDirect3DDevice9_Clear(p,a,b,c,d,e,f) (p)->Clear(a,b,c,d,e,f)
+#define IDirect3DDevice9_SetTransform(p,a,b) (p)->SetTransform(a,b)
+#define IDirect3DDevice9_GetTransform(p,a,b) (p)->GetTransform(a,b)
+#define IDirect3DDevice9_MultiplyTransform(p,a,b) (p)->MultiplyTransform(a,b)
+#define IDirect3DDevice9_SetViewport(p,a) (p)->SetViewport(a)
+#define IDirect3DDevice9_GetViewport(p,a) (p)->GetViewport(a)
+#define IDirect3DDevice9_SetMaterial(p,a) (p)->SetMaterial(a)
+#define IDirect3DDevice9_GetMaterial(p,a) (p)->GetMaterial(a)
+#define IDirect3DDevice9_SetLight(p,a,b) (p)->SetLight(a,b)
+#define IDirect3DDevice9_GetLight(p,a,b) (p)->GetLight(a,b)
+#define IDirect3DDevice9_LightEnable(p,a,b) (p)->LightEnable(a,b)
+#define IDirect3DDevice9_GetLightEnable(p,a,b) (p)->GetLightEnable(a,b)
+#define IDirect3DDevice9_SetClipPlane(p,a,b) (p)->SetClipPlane(a,b)
+#define IDirect3DDevice9_GetClipPlane(p,a,b) (p)->GetClipPlane(a,b)
+#define IDirect3DDevice9_SetRenderState(p,a,b) (p)->SetRenderState(a,b)
+#define IDirect3DDevice9_GetRenderState(p,a,b) (p)->GetRenderState(a,b)
+#define IDirect3DDevice9_CreateStateBlock(p,a,b) (p)->CreateStateBlock(a,b)
+#define IDirect3DDevice9_BeginStateBlock(p) (p)->BeginStateBlock()
+#define IDirect3DDevice9_EndStateBlock(p,a) (p)->EndStateBlock(a)
+#define IDirect3DDevice9_SetClipStatus(p,a) (p)->SetClipStatus(a)
+#define IDirect3DDevice9_GetClipStatus(p,a) (p)->GetClipStatus(a)
+#define IDirect3DDevice9_GetTexture(p,a,b) (p)->GetTexture(a,b)
+#define IDirect3DDevice9_SetTexture(p,a,b) (p)->SetTexture(a,b)
+#define IDirect3DDevice9_GetTextureStageState(p,a,b,c) (p)->GetTextureStageState(a,b,c)
+#define IDirect3DDevice9_SetTextureStageState(p,a,b,c) (p)->SetTextureStageState(a,b,c)
+#define IDirect3DDevice9_GetSamplerState(p,a,b,c) (p)->GetSamplerState(a,b,c)
+#define IDirect3DDevice9_SetSamplerState(p,a,b,c) (p)->SetSamplerState(a,b,c)
+#define IDirect3DDevice9_ValidateDevice(p,a) (p)->ValidateDevice(a)
+#define IDirect3DDevice9_SetPaletteEntries(p,a,b) (p)->SetPaletteEntries(a,b)
+#define IDirect3DDevice9_GetPaletteEntries(p,a,b) (p)->GetPaletteEntries(a,b)
+#define IDirect3DDevice9_SetCurrentTexturePalette(p,a) (p)->SetCurrentTexturePalette(a)
+#define IDirect3DDevice9_GetCurrentTexturePalette(p,a) (p)->GetCurrentTexturePalette(a)
+#define IDirect3DDevice9_SetScissorRect(p,a) (p)->SetScissorRect(a)
+#define IDirect3DDevice9_GetScissorRect(p,a) (p)->GetScissorRect(a)
+#define IDirect3DDevice9_SetSoftwareVertexProcessing(p,a) (p)->SetSoftwareVertexProcessing(a)
+#define IDirect3DDevice9_GetSoftwareVertexProcessing(p) (p)->GetSoftwareVertexProcessing()
+#define IDirect3DDevice9_SetNPatchMode(p,a) (p)->SetNPatchMode(a)
+#define IDirect3DDevice9_GetNPatchMode(p) (p)->GetNPatchMode()
+#define IDirect3DDevice9_DrawPrimitive(p,a,b,c) (p)->DrawPrimitive(a,b,c)
+#define IDirect3DDevice9_DrawIndexedPrimitive(p,a,b,c,d,e,f) (p)->DrawIndexedPrimitive(a,b,c,d,e,f)
+#define IDirect3DDevice9_DrawPrimitiveUP(p,a,b,c,d) (p)->DrawPrimitiveUP(a,b,c,d)
+#define IDirect3DDevice9_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->DrawIndexedPrimitiveUP(a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9_ProcessVertices(p,a,b,c,d,e,f) (p)->ProcessVertices(a,b,c,d,e,f)
+#define IDirect3DDevice9_CreateVertexDeclaration(p,a,b) (p)->CreateVertexDeclaration(a,b)
+#define IDirect3DDevice9_SetVertexDeclaration(p,a) (p)->SetVertexDeclaration(a)
+#define IDirect3DDevice9_GetVertexDeclaration(p,a) (p)->GetVertexDeclaration(a)
+#define IDirect3DDevice9_SetFVF(p,a) (p)->SetFVF(a)
+#define IDirect3DDevice9_GetFVF(p,a) (p)->GetFVF(a)
+#define IDirect3DDevice9_CreateVertexShader(p,a,b) (p)->CreateVertexShader(a,b)
+#define IDirect3DDevice9_SetVertexShader(p,a) (p)->SetVertexShader(a)
+#define IDirect3DDevice9_GetVertexShader(p,a) (p)->GetVertexShader(a)
+#define IDirect3DDevice9_SetVertexShaderConstantF(p,a,b,c) (p)->SetVertexShaderConstantF(a,b,c)
+#define IDirect3DDevice9_GetVertexShaderConstantF(p,a,b,c) (p)->GetVertexShaderConstantF(a,b,c)
+#define IDirect3DDevice9_SetVertexShaderConstantI(p,a,b,c) (p)->SetVertexShaderConstantI(a,b,c)
+#define IDirect3DDevice9_GetVertexShaderConstantI(p,a,b,c) (p)->GetVertexShaderConstantI(a,b,c)
+#define IDirect3DDevice9_SetVertexShaderConstantB(p,a,b,c) (p)->SetVertexShaderConstantB(a,b,c)
+#define IDirect3DDevice9_GetVertexShaderConstantB(p,a,b,c) (p)->GetVertexShaderConstantB(a,b,c)
+#define IDirect3DDevice9_SetStreamSource(p,a,b,c,d) (p)->SetStreamSource(a,b,c,d)
+#define IDirect3DDevice9_GetStreamSource(p,a,b,c,d) (p)->GetStreamSource(a,b,c,d)
+#define IDirect3DDevice9_SetStreamSourceFreq(p,a,b) (p)->SetStreamSourceFreq(a,b)
+#define IDirect3DDevice9_GetStreamSourceFreq(p,a,b) (p)->GetStreamSourceFreq(a,b)
+#define IDirect3DDevice9_SetIndices(p,a) (p)->SetIndices(a)
+#define IDirect3DDevice9_GetIndices(p,a) (p)->GetIndices(a)
+#define IDirect3DDevice9_CreatePixelShader(p,a,b) (p)->CreatePixelShader(a,b)
+#define IDirect3DDevice9_SetPixelShader(p,a) (p)->SetPixelShader(a)
+#define IDirect3DDevice9_GetPixelShader(p,a) (p)->GetPixelShader(a)
+#define IDirect3DDevice9_SetPixelShaderConstantF(p,a,b,c) (p)->SetPixelShaderConstantF(a,b,c)
+#define IDirect3DDevice9_GetPixelShaderConstantF(p,a,b,c) (p)->GetPixelShaderConstantF(a,b,c)
+#define IDirect3DDevice9_SetPixelShaderConstantI(p,a,b,c) (p)->SetPixelShaderConstantI(a,b,c)
+#define IDirect3DDevice9_GetPixelShaderConstantI(p,a,b,c) (p)->GetPixelShaderConstantI(a,b,c)
+#define IDirect3DDevice9_SetPixelShaderConstantB(p,a,b,c) (p)->SetPixelShaderConstantB(a,b,c)
+#define IDirect3DDevice9_GetPixelShaderConstantB(p,a,b,c) (p)->GetPixelShaderConstantB(a,b,c)
+#define IDirect3DDevice9_DrawRectPatch(p,a,b,c) (p)->DrawRectPatch(a,b,c)
+#define IDirect3DDevice9_DrawTriPatch(p,a,b,c) (p)->DrawTriPatch(a,b,c)
+#define IDirect3DDevice9_DeletePatch(p,a) (p)->DeletePatch(a)
+#define IDirect3DDevice9_CreateQuery(p,a,b) (p)->CreateQuery(a,b)
+#endif
+
+
+/*****************************************************************************
+ * IDirect3DDevice9Ex interface
+ */
+#define INTERFACE IDirect3DDevice9Ex
+DECLARE_INTERFACE_(IDirect3DDevice9Ex,IDirect3DDevice9)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirect3DDevice9 methods ***/
+ STDMETHOD(TestCooperativeLevel)(THIS) PURE;
+ STDMETHOD_(UINT, GetAvailableTextureMem)(THIS) PURE;
+ STDMETHOD(EvictManagedResources)(THIS) PURE;
+ STDMETHOD(GetDirect3D)(THIS_ IDirect3D9** ppD3D9) PURE;
+ STDMETHOD(GetDeviceCaps)(THIS_ D3DCAPS9* pCaps) PURE;
+ STDMETHOD(GetDisplayMode)(THIS_ UINT iSwapChain, D3DDISPLAYMODE* pMode) PURE;
+ STDMETHOD(GetCreationParameters)(THIS_ D3DDEVICE_CREATION_PARAMETERS *pParameters) PURE;
+ STDMETHOD(SetCursorProperties)(THIS_ UINT XHotSpot, UINT YHotSpot, IDirect3DSurface9* pCursorBitmap) PURE;
+ STDMETHOD_(void, SetCursorPosition)(THIS_ int X,int Y, DWORD Flags) PURE;
+ STDMETHOD_(BOOL, ShowCursor)(THIS_ BOOL bShow) PURE;
+ STDMETHOD(CreateAdditionalSwapChain)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain9** pSwapChain) PURE;
+ STDMETHOD(GetSwapChain)(THIS_ UINT iSwapChain, IDirect3DSwapChain9** pSwapChain) PURE;
+ STDMETHOD_(UINT, GetNumberOfSwapChains)(THIS) PURE;
+ STDMETHOD(Reset)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters) PURE;
+ STDMETHOD(Present)(THIS_ CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion) PURE;
+ STDMETHOD(GetBackBuffer)(THIS_ UINT iSwapChain, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9** ppBackBuffer) PURE;
+ STDMETHOD(GetRasterStatus)(THIS_ UINT iSwapChain, D3DRASTER_STATUS* pRasterStatus) PURE;
+ STDMETHOD(SetDialogBoxMode)(THIS_ BOOL bEnableDialogs) PURE;
+ STDMETHOD_(void, SetGammaRamp)(THIS_ UINT iSwapChain, DWORD Flags, CONST D3DGAMMARAMP* pRamp) PURE;
+ STDMETHOD_(void, GetGammaRamp)(THIS_ UINT iSwapChain, D3DGAMMARAMP* pRamp) PURE;
+ STDMETHOD(CreateTexture)(THIS_ UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture9** ppTexture, HANDLE* pSharedHandle) PURE;
+ STDMETHOD(CreateVolumeTexture)(THIS_ UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DVolumeTexture9** ppVolumeTexture, HANDLE* pSharedHandle) PURE;
+ STDMETHOD(CreateCubeTexture)(THIS_ UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture9** ppCubeTexture, HANDLE* pSharedHandle) PURE;
+ STDMETHOD(CreateVertexBuffer)(THIS_ UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle) PURE;
+ STDMETHOD(CreateIndexBuffer)(THIS_ UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle) PURE;
+ STDMETHOD(CreateRenderTarget)(THIS_ UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Lockable, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) PURE;
+ STDMETHOD(CreateDepthStencilSurface)(THIS_ UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Discard, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) PURE;
+ STDMETHOD(UpdateSurface)(THIS_ IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestinationSurface, CONST POINT* pDestPoint) PURE;
+ STDMETHOD(UpdateTexture)(THIS_ IDirect3DBaseTexture9* pSourceTexture, IDirect3DBaseTexture9* pDestinationTexture) PURE;
+ STDMETHOD(GetRenderTargetData)(THIS_ IDirect3DSurface9* pRenderTarget, IDirect3DSurface9* pDestSurface) PURE;
+ STDMETHOD(GetFrontBufferData)(THIS_ UINT iSwapChain, IDirect3DSurface9* pDestSurface) PURE;
+ STDMETHOD(StretchRect)(THIS_ IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestSurface, CONST RECT* pDestRect, D3DTEXTUREFILTERTYPE Filter) PURE;
+ STDMETHOD(ColorFill)(THIS_ IDirect3DSurface9* pSurface, CONST RECT* pRect, D3DCOLOR color) PURE;
+ STDMETHOD(CreateOffscreenPlainSurface)(THIS_ UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) PURE;
+ STDMETHOD(SetRenderTarget)(THIS_ DWORD RenderTargetIndex, IDirect3DSurface9* pRenderTarget) PURE;
+ STDMETHOD(GetRenderTarget)(THIS_ DWORD RenderTargetIndex, IDirect3DSurface9** ppRenderTarget) PURE;
+ STDMETHOD(SetDepthStencilSurface)(THIS_ IDirect3DSurface9* pNewZStencil) PURE;
+ STDMETHOD(GetDepthStencilSurface)(THIS_ IDirect3DSurface9** ppZStencilSurface) PURE;
+ STDMETHOD(BeginScene)(THIS) PURE;
+ STDMETHOD(EndScene)(THIS) PURE;
+ STDMETHOD(Clear)(THIS_ DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) PURE;
+ STDMETHOD(SetTransform)(THIS_ D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) PURE;
+ STDMETHOD(GetTransform)(THIS_ D3DTRANSFORMSTATETYPE State, D3DMATRIX* pMatrix) PURE;
+ STDMETHOD(MultiplyTransform)(THIS_ D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*) PURE;
+ STDMETHOD(SetViewport)(THIS_ CONST D3DVIEWPORT9* pViewport) PURE;
+ STDMETHOD(GetViewport)(THIS_ D3DVIEWPORT9* pViewport) PURE;
+ STDMETHOD(SetMaterial)(THIS_ CONST D3DMATERIAL9* pMaterial) PURE;
+ STDMETHOD(GetMaterial)(THIS_ D3DMATERIAL9* pMaterial) PURE;
+ STDMETHOD(SetLight)(THIS_ DWORD Index, CONST D3DLIGHT9*) PURE;
+ STDMETHOD(GetLight)(THIS_ DWORD Index, D3DLIGHT9*) PURE;
+ STDMETHOD(LightEnable)(THIS_ DWORD Index, BOOL Enable) PURE;
+ STDMETHOD(GetLightEnable)(THIS_ DWORD Index, BOOL* pEnable) PURE;
+ STDMETHOD(SetClipPlane)(THIS_ DWORD Index, CONST float* pPlane) PURE;
+ STDMETHOD(GetClipPlane)(THIS_ DWORD Index, float* pPlane) PURE;
+ STDMETHOD(SetRenderState)(THIS_ D3DRENDERSTATETYPE State, DWORD Value) PURE;
+ STDMETHOD(GetRenderState)(THIS_ D3DRENDERSTATETYPE State, DWORD* pValue) PURE;
+ STDMETHOD(CreateStateBlock)(THIS_ D3DSTATEBLOCKTYPE Type, IDirect3DStateBlock9** ppSB) PURE;
+ STDMETHOD(BeginStateBlock)(THIS) PURE;
+ STDMETHOD(EndStateBlock)(THIS_ IDirect3DStateBlock9** ppSB) PURE;
+ STDMETHOD(SetClipStatus)(THIS_ CONST D3DCLIPSTATUS9* pClipStatus) PURE;
+ STDMETHOD(GetClipStatus)(THIS_ D3DCLIPSTATUS9* pClipStatus) PURE;
+ STDMETHOD(GetTexture)(THIS_ DWORD Stage, IDirect3DBaseTexture9** ppTexture) PURE;
+ STDMETHOD(SetTexture)(THIS_ DWORD Stage, IDirect3DBaseTexture9* pTexture) PURE;
+ STDMETHOD(GetTextureStageState)(THIS_ DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD* pValue) PURE;
+ STDMETHOD(SetTextureStageState)(THIS_ DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) PURE;
+ STDMETHOD(GetSamplerState)(THIS_ DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD* pValue) PURE;
+ STDMETHOD(SetSamplerState)(THIS_ DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) PURE;
+ STDMETHOD(ValidateDevice)(THIS_ DWORD* pNumPasses) PURE;
+ STDMETHOD(SetPaletteEntries)(THIS_ UINT PaletteNumber, CONST PALETTEENTRY* pEntries) PURE;
+ STDMETHOD(GetPaletteEntries)(THIS_ UINT PaletteNumber,PALETTEENTRY* pEntries) PURE;
+ STDMETHOD(SetCurrentTexturePalette)(THIS_ UINT PaletteNumber) PURE;
+ STDMETHOD(GetCurrentTexturePalette)(THIS_ UINT *PaletteNumber) PURE;
+ STDMETHOD(SetScissorRect)(THIS_ CONST RECT* pRect) PURE;
+ STDMETHOD(GetScissorRect)(THIS_ RECT* pRect) PURE;
+ STDMETHOD(SetSoftwareVertexProcessing)(THIS_ BOOL bSoftware) PURE;
+ STDMETHOD_(BOOL, GetSoftwareVertexProcessing)(THIS) PURE;
+ STDMETHOD(SetNPatchMode)(THIS_ float nSegments) PURE;
+ STDMETHOD_(float, GetNPatchMode)(THIS) PURE;
+ STDMETHOD(DrawPrimitive)(THIS_ D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) PURE;
+ STDMETHOD(DrawIndexedPrimitive)(THIS_ D3DPRIMITIVETYPE, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount) PURE;
+ STDMETHOD(DrawPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) PURE;
+ STDMETHOD(DrawIndexedPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertices, UINT PrimitiveCount, CONST void* pIndexData, D3DFORMAT IndexDataFormat, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) PURE;
+ STDMETHOD(ProcessVertices)(THIS_ UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IDirect3DVertexBuffer9* pDestBuffer, IDirect3DVertexDeclaration9* pVertexDecl, DWORD Flags) PURE;
+ STDMETHOD(CreateVertexDeclaration)(THIS_ CONST D3DVERTEXELEMENT9* pVertexElements, IDirect3DVertexDeclaration9** ppDecl) PURE;
+ STDMETHOD(SetVertexDeclaration)(THIS_ IDirect3DVertexDeclaration9* pDecl) PURE;
+ STDMETHOD(GetVertexDeclaration)(THIS_ IDirect3DVertexDeclaration9** ppDecl) PURE;
+ STDMETHOD(SetFVF)(THIS_ DWORD FVF) PURE;
+ STDMETHOD(GetFVF)(THIS_ DWORD* pFVF) PURE;
+ STDMETHOD(CreateVertexShader)(THIS_ CONST DWORD* pFunction, IDirect3DVertexShader9** ppShader) PURE;
+ STDMETHOD(SetVertexShader)(THIS_ IDirect3DVertexShader9* pShader) PURE;
+ STDMETHOD(GetVertexShader)(THIS_ IDirect3DVertexShader9** ppShader) PURE;
+ STDMETHOD(SetVertexShaderConstantF)(THIS_ UINT StartRegister, CONST float* pConstantData, UINT Vector4fCount) PURE;
+ STDMETHOD(GetVertexShaderConstantF)(THIS_ UINT StartRegister, float* pConstantData, UINT Vector4fCount) PURE;
+ STDMETHOD(SetVertexShaderConstantI)(THIS_ UINT StartRegister, CONST int* pConstantData, UINT Vector4iCount) PURE;
+ STDMETHOD(GetVertexShaderConstantI)(THIS_ UINT StartRegister, int* pConstantData, UINT Vector4iCount) PURE;
+ STDMETHOD(SetVertexShaderConstantB)(THIS_ UINT StartRegister, CONST BOOL* pConstantData, UINT BoolCount) PURE;
+ STDMETHOD(GetVertexShaderConstantB)(THIS_ UINT StartRegister, BOOL* pConstantData, UINT BoolCount) PURE;
+ STDMETHOD(SetStreamSource)(THIS_ UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT Stride) PURE;
+ STDMETHOD(GetStreamSource)(THIS_ UINT StreamNumber, IDirect3DVertexBuffer9** ppStreamData, UINT* OffsetInBytes, UINT* pStride) PURE;
+ STDMETHOD(SetStreamSourceFreq)(THIS_ UINT StreamNumber, UINT Divider) PURE;
+ STDMETHOD(GetStreamSourceFreq)(THIS_ UINT StreamNumber, UINT* Divider) PURE;
+ STDMETHOD(SetIndices)(THIS_ IDirect3DIndexBuffer9* pIndexData) PURE;
+ STDMETHOD(GetIndices)(THIS_ IDirect3DIndexBuffer9** ppIndexData) PURE;
+ STDMETHOD(CreatePixelShader)(THIS_ CONST DWORD* pFunction, IDirect3DPixelShader9** ppShader) PURE;
+ STDMETHOD(SetPixelShader)(THIS_ IDirect3DPixelShader9* pShader) PURE;
+ STDMETHOD(GetPixelShader)(THIS_ IDirect3DPixelShader9** ppShader) PURE;
+ STDMETHOD(SetPixelShaderConstantF)(THIS_ UINT StartRegister, CONST float* pConstantData, UINT Vector4fCount) PURE;
+ STDMETHOD(GetPixelShaderConstantF)(THIS_ UINT StartRegister, float* pConstantData, UINT Vector4fCount) PURE;
+ STDMETHOD(SetPixelShaderConstantI)(THIS_ UINT StartRegister, CONST int* pConstantData, UINT Vector4iCount) PURE;
+ STDMETHOD(GetPixelShaderConstantI)(THIS_ UINT StartRegister, int* pConstantData, UINT Vector4iCount) PURE;
+ STDMETHOD(SetPixelShaderConstantB)(THIS_ UINT StartRegister, CONST BOOL* pConstantData, UINT BoolCount) PURE;
+ STDMETHOD(GetPixelShaderConstantB)(THIS_ UINT StartRegister, BOOL* pConstantData, UINT BoolCount) PURE;
+ STDMETHOD(DrawRectPatch)(THIS_ UINT Handle, CONST float* pNumSegs, CONST D3DRECTPATCH_INFO* pRectPatchInfo) PURE;
+ STDMETHOD(DrawTriPatch)(THIS_ UINT Handle, CONST float* pNumSegs, CONST D3DTRIPATCH_INFO* pTriPatchInfo) PURE;
+ STDMETHOD(DeletePatch)(THIS_ UINT Handle) PURE;
+ STDMETHOD(CreateQuery)(THIS_ D3DQUERYTYPE Type, IDirect3DQuery9** ppQuery) PURE;
+ /* IDirect3DDevice9Ex methods */
+ STDMETHOD(SetConvolutionMonoKernel)(THIS_ UINT width, UINT height, float *rows, float *columns) PURE;
+ STDMETHOD(ComposeRects)(THIS_ IDirect3DSurface9 *src_surface, IDirect3DSurface9 *dst_surface,
+ IDirect3DVertexBuffer9 *src_descs, UINT rect_count, IDirect3DVertexBuffer9 *dst_descs,
+ D3DCOMPOSERECTSOP operation, INT offset_x, INT offset_y) PURE;
+ STDMETHOD(PresentEx)(THIS_ CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) PURE;
+ STDMETHOD(GetGPUThreadPriority)(THIS_ INT *pPriority) PURE;
+ STDMETHOD(SetGPUThreadPriority)(THIS_ INT Priority) PURE;
+ STDMETHOD(WaitForVBlank)(THIS_ UINT iSwapChain) PURE;
+ STDMETHOD(CheckResourceResidency)(THIS_ IDirect3DResource9 **resources, UINT32 resource_count) PURE;
+ STDMETHOD(SetMaximumFrameLatency)(THIS_ UINT MaxLatency) PURE;
+ STDMETHOD(GetMaximumFrameLatency)(THIS_ UINT *pMaxLatenxy) PURE;
+ STDMETHOD(CheckDeviceState)(THIS_ HWND dst_window) PURE;
+ STDMETHOD(CreateRenderTargetEx)(THIS_ UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultiSampleQuality, BOOL Lockable, IDirect3DSurface9 ** ppSurface, HANDLE *pSharedHandle, DWORD Usage) PURE;
+ STDMETHOD(CreateOffscreenPlainSurfaceEx)(THIS_ UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9 **ppSurface, HANDLE *pSharedHandle, DWORD Usage) PURE;
+ STDMETHOD(CreateDepthStencilSurfaceEx)(THIS_ UINT width, UINT height, D3DFORMAT format,
+ D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality, BOOL discard,
+ IDirect3DSurface9 **surface, HANDLE *shared_handle, DWORD usage) PURE;
+ STDMETHOD(ResetEx)(THIS_ D3DPRESENT_PARAMETERS *pPresentationParameters, D3DDISPLAYMODEEX *pFullscreenDisplayMode) PURE;
+ STDMETHOD(GetDisplayModeEx)(THIS_ UINT iSwapChain, D3DDISPLAYMODEEX *pMode, D3DDISPLAYROTATION *pRotation) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DDevice9Ex_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DDevice9Ex_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DDevice9Ex_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DDevice9 methods ***/
+#define IDirect3DDevice9Ex_TestCooperativeLevel(p) (p)->lpVtbl->TestCooperativeLevel(p)
+#define IDirect3DDevice9Ex_GetAvailableTextureMem(p) (p)->lpVtbl->GetAvailableTextureMem(p)
+#define IDirect3DDevice9Ex_EvictManagedResources(p) (p)->lpVtbl->EvictManagedResources(p)
+#define IDirect3DDevice9Ex_GetDirect3D(p,a) (p)->lpVtbl->GetDirect3D(p,a)
+#define IDirect3DDevice9Ex_GetDeviceCaps(p,a) (p)->lpVtbl->GetDeviceCaps(p,a)
+#define IDirect3DDevice9Ex_GetDisplayMode(p,a,b) (p)->lpVtbl->GetDisplayMode(p,a,b)
+#define IDirect3DDevice9Ex_GetCreationParameters(p,a) (p)->lpVtbl->GetCreationParameters(p,a)
+#define IDirect3DDevice9Ex_SetCursorProperties(p,a,b,c) (p)->lpVtbl->SetCursorProperties(p,a,b,c)
+#define IDirect3DDevice9Ex_SetCursorPosition(p,a,b,c) (p)->lpVtbl->SetCursorPosition(p,a,b,c)
+#define IDirect3DDevice9Ex_ShowCursor(p,a) (p)->lpVtbl->ShowCursor(p,a)
+#define IDirect3DDevice9Ex_CreateAdditionalSwapChain(p,a,b) (p)->lpVtbl->CreateAdditionalSwapChain(p,a,b)
+#define IDirect3DDevice9Ex_GetSwapChain(p,a,b) (p)->lpVtbl->GetSwapChain(p,a,b)
+#define IDirect3DDevice9Ex_GetNumberOfSwapChains(p) (p)->lpVtbl->GetNumberOfSwapChains(p)
+#define IDirect3DDevice9Ex_Reset(p,a) (p)->lpVtbl->Reset(p,a)
+#define IDirect3DDevice9Ex_Present(p,a,b,c,d) (p)->lpVtbl->Present(p,a,b,c,d)
+#define IDirect3DDevice9Ex_GetBackBuffer(p,a,b,c,d) (p)->lpVtbl->GetBackBuffer(p,a,b,c,d)
+#define IDirect3DDevice9Ex_GetRasterStatus(p,a,b) (p)->lpVtbl->GetRasterStatus(p,a,b)
+#define IDirect3DDevice9Ex_SetDialogBoxMode(p,a) (p)->lpVtbl->SetDialogBoxMode(p,a)
+#define IDirect3DDevice9Ex_SetGammaRamp(p,a,b,c) (p)->lpVtbl->SetGammaRamp(p,a,b,c)
+#define IDirect3DDevice9Ex_GetGammaRamp(p,a,b) (p)->lpVtbl->GetGammaRamp(p,a,b)
+#define IDirect3DDevice9Ex_CreateTexture(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->CreateTexture(p,a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9Ex_CreateVolumeTexture(p,a,b,c,d,e,f,g,h,i) (p)->lpVtbl->CreateVolumeTexture(p,a,b,c,d,e,f,g,h,i)
+#define IDirect3DDevice9Ex_CreateCubeTexture(p,a,b,c,d,e,f,g) (p)->lpVtbl->CreateCubeTexture(p,a,b,c,d,e,f,g)
+#define IDirect3DDevice9Ex_CreateVertexBuffer(p,a,b,c,d,e,f) (p)->lpVtbl->CreateVertexBuffer(p,a,b,c,d,e,f)
+#define IDirect3DDevice9Ex_CreateIndexBuffer(p,a,b,c,d,e,f) (p)->lpVtbl->CreateIndexBuffer(p,a,b,c,d,e,f)
+#define IDirect3DDevice9Ex_CreateRenderTarget(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->CreateRenderTarget(p,a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9Ex_CreateDepthStencilSurface(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->CreateDepthStencilSurface(p,a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9Ex_UpdateSurface(p,a,b,c,d) (p)->lpVtbl->UpdateSurface(p,a,b,c,d)
+#define IDirect3DDevice9Ex_UpdateTexture(p,a,b) (p)->lpVtbl->UpdateTexture(p,a,b)
+#define IDirect3DDevice9Ex_GetRenderTargetData(p,a,b) (p)->lpVtbl->GetRenderTargetData(p,a,b)
+#define IDirect3DDevice9Ex_GetFrontBufferData(p,a,b) (p)->lpVtbl->GetFrontBufferData(p,a,b)
+#define IDirect3DDevice9Ex_StretchRect(p,a,b,c,d,e) (p)->lpVtbl->StretchRect(p,a,b,c,d,e)
+#define IDirect3DDevice9Ex_ColorFill(p,a,b,c) (p)->lpVtbl->ColorFill(p,a,b,c)
+#define IDirect3DDevice9Ex_CreateOffscreenPlainSurface(p,a,b,c,d,e,f) (p)->lpVtbl->CreateOffscreenPlainSurface(p,a,b,c,d,e,f)
+#define IDirect3DDevice9Ex_SetRenderTarget(p,a,b) (p)->lpVtbl->SetRenderTarget(p,a,b)
+#define IDirect3DDevice9Ex_GetRenderTarget(p,a,b) (p)->lpVtbl->GetRenderTarget(p,a,b)
+#define IDirect3DDevice9Ex_SetDepthStencilSurface(p,a) (p)->lpVtbl->SetDepthStencilSurface(p,a)
+#define IDirect3DDevice9Ex_GetDepthStencilSurface(p,a) (p)->lpVtbl->GetDepthStencilSurface(p,a)
+#define IDirect3DDevice9Ex_BeginScene(p) (p)->lpVtbl->BeginScene(p)
+#define IDirect3DDevice9Ex_EndScene(p) (p)->lpVtbl->EndScene(p)
+#define IDirect3DDevice9Ex_Clear(p,a,b,c,d,e,f) (p)->lpVtbl->Clear(p,a,b,c,d,e,f)
+#define IDirect3DDevice9Ex_SetTransform(p,a,b) (p)->lpVtbl->SetTransform(p,a,b)
+#define IDirect3DDevice9Ex_GetTransform(p,a,b) (p)->lpVtbl->GetTransform(p,a,b)
+#define IDirect3DDevice9Ex_MultiplyTransform(p,a,b) (p)->lpVtbl->MultiplyTransform(p,a,b)
+#define IDirect3DDevice9Ex_SetViewport(p,a) (p)->lpVtbl->SetViewport(p,a)
+#define IDirect3DDevice9Ex_GetViewport(p,a) (p)->lpVtbl->GetViewport(p,a)
+#define IDirect3DDevice9Ex_SetMaterial(p,a) (p)->lpVtbl->SetMaterial(p,a)
+#define IDirect3DDevice9Ex_GetMaterial(p,a) (p)->lpVtbl->GetMaterial(p,a)
+#define IDirect3DDevice9Ex_SetLight(p,a,b) (p)->lpVtbl->SetLight(p,a,b)
+#define IDirect3DDevice9Ex_GetLight(p,a,b) (p)->lpVtbl->GetLight(p,a,b)
+#define IDirect3DDevice9Ex_LightEnable(p,a,b) (p)->lpVtbl->LightEnable(p,a,b)
+#define IDirect3DDevice9Ex_GetLightEnable(p,a,b) (p)->lpVtbl->GetLightEnable(p,a,b)
+#define IDirect3DDevice9Ex_SetClipPlane(p,a,b) (p)->lpVtbl->SetClipPlane(p,a,b)
+#define IDirect3DDevice9Ex_GetClipPlane(p,a,b) (p)->lpVtbl->GetClipPlane(p,a,b)
+#define IDirect3DDevice9Ex_SetRenderState(p,a,b) (p)->lpVtbl->SetRenderState(p,a,b)
+#define IDirect3DDevice9Ex_GetRenderState(p,a,b) (p)->lpVtbl->GetRenderState(p,a,b)
+#define IDirect3DDevice9Ex_CreateStateBlock(p,a,b) (p)->lpVtbl->CreateStateBlock(p,a,b)
+#define IDirect3DDevice9Ex_BeginStateBlock(p) (p)->lpVtbl->BeginStateBlock(p)
+#define IDirect3DDevice9Ex_EndStateBlock(p,a) (p)->lpVtbl->EndStateBlock(p,a)
+#define IDirect3DDevice9Ex_SetClipStatus(p,a) (p)->lpVtbl->SetClipStatus(p,a)
+#define IDirect3DDevice9Ex_GetClipStatus(p,a) (p)->lpVtbl->GetClipStatus(p,a)
+#define IDirect3DDevice9Ex_GetTexture(p,a,b) (p)->lpVtbl->GetTexture(p,a,b)
+#define IDirect3DDevice9Ex_SetTexture(p,a,b) (p)->lpVtbl->SetTexture(p,a,b)
+#define IDirect3DDevice9Ex_GetTextureStageState(p,a,b,c) (p)->lpVtbl->GetTextureStageState(p,a,b,c)
+#define IDirect3DDevice9Ex_SetTextureStageState(p,a,b,c) (p)->lpVtbl->SetTextureStageState(p,a,b,c)
+#define IDirect3DDevice9Ex_GetSamplerState(p,a,b,c) (p)->lpVtbl->GetSamplerState(p,a,b,c)
+#define IDirect3DDevice9Ex_SetSamplerState(p,a,b,c) (p)->lpVtbl->SetSamplerState(p,a,b,c)
+#define IDirect3DDevice9Ex_ValidateDevice(p,a) (p)->lpVtbl->ValidateDevice(p,a)
+#define IDirect3DDevice9Ex_SetPaletteEntries(p,a,b) (p)->lpVtbl->SetPaletteEntries(p,a,b)
+#define IDirect3DDevice9Ex_GetPaletteEntries(p,a,b) (p)->lpVtbl->GetPaletteEntries(p,a,b)
+#define IDirect3DDevice9Ex_SetCurrentTexturePalette(p,a) (p)->lpVtbl->SetCurrentTexturePalette(p,a)
+#define IDirect3DDevice9Ex_GetCurrentTexturePalette(p,a) (p)->lpVtbl->GetCurrentTexturePalette(p,a)
+#define IDirect3DDevice9Ex_SetScissorRect(p,a) (p)->lpVtbl->SetScissorRect(p,a)
+#define IDirect3DDevice9Ex_GetScissorRect(p,a) (p)->lpVtbl->GetScissorRect(p,a)
+#define IDirect3DDevice9Ex_SetSoftwareVertexProcessing(p,a) (p)->lpVtbl->SetSoftwareVertexProcessing(p,a)
+#define IDirect3DDevice9Ex_GetSoftwareVertexProcessing(p) (p)->lpVtbl->GetSoftwareVertexProcessing(p)
+#define IDirect3DDevice9Ex_SetNPatchMode(p,a) (p)->lpVtbl->SetNPatchMode(p,a)
+#define IDirect3DDevice9Ex_GetNPatchMode(p) (p)->lpVtbl->GetNPatchMode(p)
+#define IDirect3DDevice9Ex_DrawPrimitive(p,a,b,c) (p)->lpVtbl->DrawPrimitive(p,a,b,c)
+#define IDirect3DDevice9Ex_DrawIndexedPrimitive(p,a,b,c,d,e,f) (p)->lpVtbl->DrawIndexedPrimitive(p,a,b,c,d,e,f)
+#define IDirect3DDevice9Ex_DrawPrimitiveUP(p,a,b,c,d) (p)->lpVtbl->DrawPrimitiveUP(p,a,b,c,d)
+#define IDirect3DDevice9Ex_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9Ex_ProcessVertices(p,a,b,c,d,e,f) (p)->lpVtbl->ProcessVertices(p,a,b,c,d,e,f)
+#define IDirect3DDevice9Ex_CreateVertexDeclaration(p,a,b) (p)->lpVtbl->CreateVertexDeclaration(p,a,b)
+#define IDirect3DDevice9Ex_SetVertexDeclaration(p,a) (p)->lpVtbl->SetVertexDeclaration(p,a)
+#define IDirect3DDevice9Ex_GetVertexDeclaration(p,a) (p)->lpVtbl->GetVertexDeclaration(p,a)
+#define IDirect3DDevice9Ex_SetFVF(p,a) (p)->lpVtbl->SetFVF(p,a)
+#define IDirect3DDevice9Ex_GetFVF(p,a) (p)->lpVtbl->GetFVF(p,a)
+#define IDirect3DDevice9Ex_CreateVertexShader(p,a,b) (p)->lpVtbl->CreateVertexShader(p,a,b)
+#define IDirect3DDevice9Ex_SetVertexShader(p,a) (p)->lpVtbl->SetVertexShader(p,a)
+#define IDirect3DDevice9Ex_GetVertexShader(p,a) (p)->lpVtbl->GetVertexShader(p,a)
+#define IDirect3DDevice9Ex_SetVertexShaderConstantF(p,a,b,c) (p)->lpVtbl->SetVertexShaderConstantF(p,a,b,c)
+#define IDirect3DDevice9Ex_GetVertexShaderConstantF(p,a,b,c) (p)->lpVtbl->GetVertexShaderConstantF(p,a,b,c)
+#define IDirect3DDevice9Ex_SetVertexShaderConstantI(p,a,b,c) (p)->lpVtbl->SetVertexShaderConstantI(p,a,b,c)
+#define IDirect3DDevice9Ex_GetVertexShaderConstantI(p,a,b,c) (p)->lpVtbl->GetVertexShaderConstantI(p,a,b,c)
+#define IDirect3DDevice9Ex_SetVertexShaderConstantB(p,a,b,c) (p)->lpVtbl->SetVertexShaderConstantB(p,a,b,c)
+#define IDirect3DDevice9Ex_GetVertexShaderConstantB(p,a,b,c) (p)->lpVtbl->GetVertexShaderConstantB(p,a,b,c)
+#define IDirect3DDevice9Ex_SetStreamSource(p,a,b,c,d) (p)->lpVtbl->SetStreamSource(p,a,b,c,d)
+#define IDirect3DDevice9Ex_GetStreamSource(p,a,b,c,d) (p)->lpVtbl->GetStreamSource(p,a,b,c,d)
+#define IDirect3DDevice9Ex_SetStreamSourceFreq(p,a,b) (p)->lpVtbl->SetStreamSourceFreq(p,a,b)
+#define IDirect3DDevice9Ex_GetStreamSourceFreq(p,a,b) (p)->lpVtbl->GetStreamSourceFreq(p,a,b)
+#define IDirect3DDevice9Ex_SetIndices(p,a) (p)->lpVtbl->SetIndices(p,a)
+#define IDirect3DDevice9Ex_GetIndices(p,a) (p)->lpVtbl->GetIndices(p,a)
+#define IDirect3DDevice9Ex_CreatePixelShader(p,a,b) (p)->lpVtbl->CreatePixelShader(p,a,b)
+#define IDirect3DDevice9Ex_SetPixelShader(p,a) (p)->lpVtbl->SetPixelShader(p,a)
+#define IDirect3DDevice9Ex_GetPixelShader(p,a) (p)->lpVtbl->GetPixelShader(p,a)
+#define IDirect3DDevice9Ex_SetPixelShaderConstantF(p,a,b,c) (p)->lpVtbl->SetPixelShaderConstantF(p,a,b,c)
+#define IDirect3DDevice9Ex_GetPixelShaderConstantF(p,a,b,c) (p)->lpVtbl->GetPixelShaderConstantF(p,a,b,c)
+#define IDirect3DDevice9Ex_SetPixelShaderConstantI(p,a,b,c) (p)->lpVtbl->SetPixelShaderConstantI(p,a,b,c)
+#define IDirect3DDevice9Ex_GetPixelShaderConstantI(p,a,b,c) (p)->lpVtbl->GetPixelShaderConstantI(p,a,b,c)
+#define IDirect3DDevice9Ex_SetPixelShaderConstantB(p,a,b,c) (p)->lpVtbl->SetPixelShaderConstantB(p,a,b,c)
+#define IDirect3DDevice9Ex_GetPixelShaderConstantB(p,a,b,c) (p)->lpVtbl->GetPixelShaderConstantB(p,a,b,c)
+#define IDirect3DDevice9Ex_DrawRectPatch(p,a,b,c) (p)->lpVtbl->DrawRectPatch(p,a,b,c)
+#define IDirect3DDevice9Ex_DrawTriPatch(p,a,b,c) (p)->lpVtbl->DrawTriPatch(p,a,b,c)
+#define IDirect3DDevice9Ex_DeletePatch(p,a) (p)->lpVtbl->DeletePatch(p,a)
+#define IDirect3DDevice9Ex_CreateQuery(p,a,b) (p)->lpVtbl->CreateQuery(p,a,b)
+/* IDirect3DDevice9Ex */
+#define IDirect3DDevice9Ex_SetConvolutionMonoKernel(p,a,b,c,d) (p)->lpVtbl->SetConvolutionMonoKernel(p,a,b,c,d)
+#define IDirect3DDevice9Ex_ComposeRects(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->ComposeRects(p,a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9Ex_PresentEx(p,a,b,c,d,e) (p)->lpVtbl->PresentEx(p,a,b,c,d,e)
+#define IDirect3DDevice9Ex_GetGPUThreadPriority(p,a) (p)->lpVtbl->GetGPUThreadPriority(p,a)
+#define IDirect3DDevice9Ex_SetGPUThreadPriority(p,a) (p)->lpVtbl->SetGPUThreadPriority(p,a)
+#define IDirect3DDevice9Ex_WaitForVBlank(p,a) (p)->lpVtbl->WaitForVBlank(p,a)
+#define IDirect3DDevice9Ex_CheckResourceResidency(p,a,b) (p)->lpVtbl->CheckResourceResidency(p,a,b)
+#define IDirect3DDevice9Ex_SetMaximumFrameLatency(p,a) (p)->lpVtbl->SetMaximumFrameLatency(p,a)
+#define IDirect3DDevice9Ex_GetMaximumFrameLatency(p,a) (p)->lpVtbl->GetMaximumFrameLatency(p,a)
+#define IDirect3DDevice9Ex_CheckDeviceState(p,a) (p)->lpVtbl->CheckDeviceState(p,a)
+#define IDirect3DDevice9Ex_CreateRenderTargetEx(p,a,b,c,d,e,f,g,h,i) (p)->lpVtbl->CreateRenderTargetEx(p,a,b,c,d,e,f,g,h,i)
+#define IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(p,a,b,c,d,e,f,g)(p)->lpVtbl->CreateOffscreenPlainSurfaceEx(p,a,b,c,d,e,f,g)
+#define IDirect3DDevice9Ex_CreateDepthStencilSurfaceEx(p,a,b,c,d,e,f,g,h,i)(p)->lpVtbl->CreateDepthStencilSurfaceEx(p,a,b,c,d,e,f,g,h,i)
+#define IDirect3DDevice9Ex_ResetEx(p,a,b) (p)->lpVtbl->ResetEx(p,a,b)
+#define IDirect3DDevice9Ex_GetDisplayModeEx(p,a,b,c) (p)->lpVtbl->GetDisplayModeEx(p,a,b,c)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DDevice9Ex_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DDevice9Ex_AddRef(p) (p)->AddRef()
+#define IDirect3DDevice9Ex_Release(p) (p)->Release()
+/*** IDirect3DDevice9 methods ***/
+#define IDirect3DDevice9Ex_TestCooperativeLevel(p) (p)->TestCooperativeLevel()
+#define IDirect3DDevice9Ex_GetAvailableTextureMem(p) (p)->GetAvailableTextureMem()
+#define IDirect3DDevice9Ex_EvictManagedResources(p) (p)->EvictManagedResources()
+#define IDirect3DDevice9Ex_GetDirect3D(p,a) (p)->GetDirect3D(a)
+#define IDirect3DDevice9Ex_GetDeviceCaps(p,a) (p)->GetDeviceCaps(a)
+#define IDirect3DDevice9Ex_GetDisplayMode(p,a,b) (p)->GetDisplayMode(a,b)
+#define IDirect3DDevice9Ex_GetCreationParameters(p,a) (p)->GetCreationParameters(a)
+#define IDirect3DDevice9Ex_SetCursorProperties(p,a,b,c) (p)->SetCursorProperties(a,b,c)
+#define IDirect3DDevice9Ex_SetCursorPosition(p,a,b,c) (p)->SetCursorPosition(a,b,c)
+#define IDirect3DDevice9Ex_ShowCursor(p,a) (p)->ShowCursor(a)
+#define IDirect3DDevice9Ex_CreateAdditionalSwapChain(p,a,b) (p)->CreateAdditionalSwapChain(a,b)
+#define IDirect3DDevice9Ex_GetSwapChain(p,a,b) (p)->GetSwapChain(a,b)
+#define IDirect3DDevice9Ex_GetNumberOfSwapChains(p) (p)->GetNumberOfSwapChains()
+#define IDirect3DDevice9Ex_Reset(p,a) (p)->Reset(a)
+#define IDirect3DDevice9Ex_Present(p,a,b,c,d) (p)->Present(a,b,c,d)
+#define IDirect3DDevice9Ex_GetBackBuffer(p,a,b,c,d) (p)->GetBackBuffer(a,b,c,d)
+#define IDirect3DDevice9Ex_GetRasterStatus(p,a,b) (p)->GetRasterStatus(a,b)
+#define IDirect3DDevice9Ex_SetDialogBoxMode(p,a) (p)->SetDialogBoxMode(a)
+#define IDirect3DDevice9Ex_SetGammaRamp(p,a,b,c) (p)->SetGammaRamp(a,b,c)
+#define IDirect3DDevice9Ex_GetGammaRamp(p,a,b) (p)->GetGammaRamp(a,b)
+#define IDirect3DDevice9Ex_CreateTexture(p,a,b,c,d,e,f,g,h) (p)->CreateTexture(a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9Ex_CreateVolumeTexture(p,a,b,c,d,e,f,g,h,i) (p)->CreateVolumeTexture(a,b,c,d,e,f,g,h,i)
+#define IDirect3DDevice9Ex_CreateCubeTexture(p,a,b,c,d,e,f,g) (p)->CreateCubeTexture(a,b,c,d,e,f,g)
+#define IDirect3DDevice9Ex_CreateVertexBuffer(p,a,b,c,d,e,f) (p)->CreateVertexBuffer(a,b,c,d,e,f)
+#define IDirect3DDevice9Ex_CreateIndexBuffer(p,a,b,c,d,e,f) (p)->CreateIndexBuffer(a,b,c,d,e,f)
+#define IDirect3DDevice9Ex_CreateRenderTarget(p,a,b,c,d,e,f,g,h) (p)->CreateRenderTarget(a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9Ex_CreateDepthStencilSurface(p,a,b,c,d,e,f,g,h) (p)->CreateDepthStencilSurface(a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9Ex_UpdateSurface(p,a,b,c,d) (p)->UpdateSurface(a,b,c,d)
+#define IDirect3DDevice9Ex_UpdateTexture(p,a,b) (p)->UpdateTexture(a,b)
+#define IDirect3DDevice9Ex_GetRenderTargetData(p,a,b) (p)->GetRenderTargetData(a,b)
+#define IDirect3DDevice9Ex_GetFrontBufferData(p,a,b) (p)->GetFrontBufferData(a,b)
+#define IDirect3DDevice9Ex_StretchRect(p,a,b,c,d,e) (p)->StretchRect(a,b,c,d,e)
+#define IDirect3DDevice9Ex_ColorFill(p,a,b,c) (p)->ColorFill(a,b,c)
+#define IDirect3DDevice9Ex_CreateOffscreenPlainSurface(p,a,b,c,d,e,f) (p)->CreateOffscreenPlainSurface(a,b,c,d,e,f)
+#define IDirect3DDevice9Ex_SetRenderTarget(p,a,b) (p)->SetRenderTarget(a,b)
+#define IDirect3DDevice9Ex_GetRenderTarget(p,a,b) (p)->GetRenderTarget(a,b)
+#define IDirect3DDevice9Ex_SetDepthStencilSurface(p,a) (p)->SetDepthStencilSurface(a)
+#define IDirect3DDevice9Ex_GetDepthStencilSurface(p,a) (p)->GetDepthStencilSurface(a)
+#define IDirect3DDevice9Ex_BeginScene(p) (p)->BeginScene()
+#define IDirect3DDevice9Ex_EndScene(p) (p)->EndScene()
+#define IDirect3DDevice9Ex_Clear(p,a,b,c,d,e,f) (p)->Clear(a,b,c,d,e,f)
+#define IDirect3DDevice9Ex_SetTransform(p,a,b) (p)->SetTransform(a,b)
+#define IDirect3DDevice9Ex_GetTransform(p,a,b) (p)->GetTransform(a,b)
+#define IDirect3DDevice9Ex_MultiplyTransform(p,a,b) (p)->MultiplyTransform(a,b)
+#define IDirect3DDevice9Ex_SetViewport(p,a) (p)->SetViewport(a)
+#define IDirect3DDevice9Ex_GetViewport(p,a) (p)->GetViewport(a)
+#define IDirect3DDevice9Ex_SetMaterial(p,a) (p)->SetMaterial(a)
+#define IDirect3DDevice9Ex_GetMaterial(p,a) (p)->GetMaterial(a)
+#define IDirect3DDevice9Ex_SetLight(p,a,b) (p)->SetLight(a,b)
+#define IDirect3DDevice9Ex_GetLight(p,a,b) (p)->GetLight(a,b)
+#define IDirect3DDevice9Ex_LightEnable(p,a,b) (p)->LightEnable(a,b)
+#define IDirect3DDevice9Ex_GetLightEnable(p,a,b) (p)->GetLightEnable(a,b)
+#define IDirect3DDevice9Ex_SetClipPlane(p,a,b) (p)->SetClipPlane(a,b)
+#define IDirect3DDevice9Ex_GetClipPlane(p,a,b) (p)->GetClipPlane(a,b)
+#define IDirect3DDevice9Ex_SetRenderState(p,a,b) (p)->SetRenderState(a,b)
+#define IDirect3DDevice9Ex_GetRenderState(p,a,b) (p)->GetRenderState(a,b)
+#define IDirect3DDevice9Ex_CreateStateBlock(p,a,b) (p)->CreateStateBlock(a,b)
+#define IDirect3DDevice9Ex_BeginStateBlock(p) (p)->BeginStateBlock()
+#define IDirect3DDevice9Ex_EndStateBlock(p,a) (p)->EndStateBlock(a)
+#define IDirect3DDevice9Ex_SetClipStatus(p,a) (p)->SetClipStatus(a)
+#define IDirect3DDevice9Ex_GetClipStatus(p,a) (p)->GetClipStatus(a)
+#define IDirect3DDevice9Ex_GetTexture(p,a,b) (p)->GetTexture(a,b)
+#define IDirect3DDevice9Ex_SetTexture(p,a,b) (p)->SetTexture(a,b)
+#define IDirect3DDevice9Ex_GetTextureStageState(p,a,b,c) (p)->GetTextureStageState(a,b,c)
+#define IDirect3DDevice9Ex_SetTextureStageState(p,a,b,c) (p)->SetTextureStageState(a,b,c)
+#define IDirect3DDevice9Ex_GetSamplerState(p,a,b,c) (p)->GetSamplerState(a,b,c)
+#define IDirect3DDevice9Ex_SetSamplerState(p,a,b,c) (p)->SetSamplerState(a,b,c)
+#define IDirect3DDevice9Ex_ValidateDevice(p,a) (p)->ValidateDevice(a)
+#define IDirect3DDevice9Ex_SetPaletteEntries(p,a,b) (p)->SetPaletteEntries(a,b)
+#define IDirect3DDevice9Ex_GetPaletteEntries(p,a,b) (p)->GetPaletteEntries(a,b)
+#define IDirect3DDevice9Ex_SetCurrentTexturePalette(p,a) (p)->SetCurrentTexturePalette(a)
+#define IDirect3DDevice9Ex_GetCurrentTexturePalette(p,a) (p)->GetCurrentTexturePalette(a)
+#define IDirect3DDevice9Ex_SetScissorRect(p,a) (p)->SetScissorRect(a)
+#define IDirect3DDevice9Ex_GetScissorRect(p,a) (p)->GetScissorRect(a)
+#define IDirect3DDevice9Ex_SetSoftwareVertexProcessing(p,a) (p)->SetSoftwareVertexProcessing(a)
+#define IDirect3DDevice9Ex_GetSoftwareVertexProcessing(p) (p)->GetSoftwareVertexProcessing()
+#define IDirect3DDevice9Ex_SetNPatchMode(p,a) (p)->SetNPatchMode(a)
+#define IDirect3DDevice9Ex_GetNPatchMode(p) (p)->GetNPatchMode()
+#define IDirect3DDevice9Ex_DrawPrimitive(p,a,b,c) (p)->DrawPrimitive(a,b,c)
+#define IDirect3DDevice9Ex_DrawIndexedPrimitive(p,a,b,c,d,e,f) (p)->DrawIndexedPrimitive(a,b,c,d,e,f)
+#define IDirect3DDevice9Ex_DrawPrimitiveUP(p,a,b,c,d) (p)->DrawPrimitiveUP(a,b,c,d)
+#define IDirect3DDevice9Ex_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->DrawIndexedPrimitiveUP(a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9Ex_ProcessVertices(p,a,b,c,d,e,f) (p)->ProcessVertices(a,b,c,d,e,f)
+#define IDirect3DDevice9Ex_CreateVertexDeclaration(p,a,b) (p)->CreateVertexDeclaration(a,b)
+#define IDirect3DDevice9Ex_SetVertexDeclaration(p,a) (p)->SetVertexDeclaration(a)
+#define IDirect3DDevice9Ex_GetVertexDeclaration(p,a) (p)->GetVertexDeclaration(a)
+#define IDirect3DDevice9Ex_SetFVF(p,a) (p)->SetFVF(a)
+#define IDirect3DDevice9Ex_GetFVF(p,a) (p)->GetFVF(a)
+#define IDirect3DDevice9Ex_CreateVertexShader(p,a,b) (p)->CreateVertexShader(a,b)
+#define IDirect3DDevice9Ex_SetVertexShader(p,a) (p)->SetVertexShader(a)
+#define IDirect3DDevice9Ex_GetVertexShader(p,a) (p)->GetVertexShader(a)
+#define IDirect3DDevice9Ex_SetVertexShaderConstantF(p,a,b,c) (p)->SetVertexShaderConstantF(a,b,c)
+#define IDirect3DDevice9Ex_GetVertexShaderConstantF(p,a,b,c) (p)->GetVertexShaderConstantF(a,b,c)
+#define IDirect3DDevice9Ex_SetVertexShaderConstantI(p,a,b,c) (p)->SetVertexShaderConstantI(a,b,c)
+#define IDirect3DDevice9Ex_GetVertexShaderConstantI(p,a,b,c) (p)->GetVertexShaderConstantI(a,b,c)
+#define IDirect3DDevice9Ex_SetVertexShaderConstantB(p,a,b,c) (p)->SetVertexShaderConstantB(a,b,c)
+#define IDirect3DDevice9Ex_GetVertexShaderConstantB(p,a,b,c) (p)->GetVertexShaderConstantB(a,b,c)
+#define IDirect3DDevice9Ex_SetStreamSource(p,a,b,c,d) (p)->SetStreamSource(a,b,c,d)
+#define IDirect3DDevice9Ex_GetStreamSource(p,a,b,c,d) (p)->GetStreamSource(a,b,c,d)
+#define IDirect3DDevice9Ex_SetStreamSourceFreq(p,a,b) (p)->SetStreamSourceFreq(a,b)
+#define IDirect3DDevice9Ex_GetStreamSourceFreq(p,a,b) (p)->GetStreamSourceFreq(a,b)
+#define IDirect3DDevice9Ex_SetIndices(p,a) (p)->SetIndices(a)
+#define IDirect3DDevice9Ex_GetIndices(p,a) (p)->GetIndices(a)
+#define IDirect3DDevice9Ex_CreatePixelShader(p,a,b) (p)->CreatePixelShader(a,b)
+#define IDirect3DDevice9Ex_SetPixelShader(p,a) (p)->SetPixelShader(a)
+#define IDirect3DDevice9Ex_GetPixelShader(p,a) (p)->GetPixelShader(a)
+#define IDirect3DDevice9Ex_SetPixelShaderConstantF(p,a,b,c) (p)->SetPixelShaderConstantF(a,b,c)
+#define IDirect3DDevice9Ex_GetPixelShaderConstantF(p,a,b,c) (p)->GetPixelShaderConstantF(a,b,c)
+#define IDirect3DDevice9Ex_SetPixelShaderConstantI(p,a,b,c) (p)->SetPixelShaderConstantI(a,b,c)
+#define IDirect3DDevice9Ex_GetPixelShaderConstantI(p,a,b,c) (p)->GetPixelShaderConstantI(a,b,c)
+#define IDirect3DDevice9Ex_SetPixelShaderConstantB(p,a,b,c) (p)->SetPixelShaderConstantB(a,b,c)
+#define IDirect3DDevice9Ex_GetPixelShaderConstantB(p,a,b,c) (p)->GetPixelShaderConstantB(a,b,c)
+#define IDirect3DDevice9Ex_DrawRectPatch(p,a,b,c) (p)->DrawRectPatch(a,b,c)
+#define IDirect3DDevice9Ex_DrawTriPatch(p,a,b,c) (p)->DrawTriPatch(a,b,c)
+#define IDirect3DDevice9Ex_DeletePatch(p,a) (p)->DeletePatch(a)
+#define IDirect3DDevice9Ex_CreateQuery(p,a,b) (p)->CreateQuery(a,b)
+/* IDirect3DDevice9Ex */
+#define IDirect3DDevice9Ex_SetConvolutionMonoKernel(p,a,b,c,d) (p)->SetConvolutionMonoKernel(a,b,c,d)
+#define IDirect3DDevice9Ex_ComposeRects(p,a,b,c,d,e,f,g,h) (p)->ComposeRects(a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9Ex_PresentEx(p,a,b,c,d,e) (p)->PresentEx(a,b,c,d,e)
+#define IDirect3DDevice9Ex_GetGPUThreadPriority(p,a) (p)->GetGPUThreadPriority(a)
+#define IDirect3DDevice9Ex_SetGPUThreadPriority(p,a) (p)->SetGPUThreadPriority(a)
+#define IDirect3DDevice9Ex_WaitForVBlank(p,a) (p)->WaitForVBlank(a)
+#define IDirect3DDevice9Ex_CheckResourceResidency(p,a,b) (p)->CheckResourceResidency(a,b)
+#define IDirect3DDevice9Ex_SetMaximumFrameLatency(p,a) (p)->SetMaximumFrameLatency(a)
+#define IDirect3DDevice9Ex_GetMaximumFrameLatency(p,a) (p)->GetMaximumFrameLatency(a)
+#define IDirect3DDevice9Ex_CheckDeviceState(p,a) (p)->CheckDeviceState(a)
+#define IDirect3DDevice9Ex_CreateRenderTargetEx(p,a,b,c,d,e,f,g,h,i) (p)->CreateRenderTargetEx(a,b,c,d,e,f,g,h,i)
+#define IDirect3DDevice9Ex_CreateOffscreenPlainSurfaceEx(p,a,b,c,d,e,f,g)(p)->CreateOffscreenPlainSurfaceEx(a,b,c,d,e,f,g)
+#define IDirect3DDevice9Ex_CreateDepthStencilSurfaceEx(p,a,b,c,d,e,f,g,h,i)(p)->CreateDepthStencilSurfaceEx(a,b,c,d,e,f,g,h,i)
+#define IDirect3DDevice9Ex_ResetEx(p,a,b) (p)->ResetEx(a,b)
+#define IDirect3DDevice9Ex_GetDisplayModeEx(p,a,b,c) (p)->GetDisplayModeEx(a,b,c)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+int WINAPI D3DPERF_BeginEvent(D3DCOLOR,LPCWSTR);
+int WINAPI D3DPERF_EndEvent(void);
+DWORD WINAPI D3DPERF_GetStatus(void);
+BOOL WINAPI D3DPERF_QueryRepeatFrame(void);
+void WINAPI D3DPERF_SetMarker(D3DCOLOR,LPCWSTR);
+void WINAPI D3DPERF_SetOptions(DWORD);
+void WINAPI D3DPERF_SetRegion(D3DCOLOR,LPCWSTR);
+
+/* Define the main entrypoint as well */
+IDirect3D9* WINAPI Direct3DCreate9(UINT SDKVersion);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* defined(__cplusplus) */
+
+
+#endif /* __WINE_D3D9_H */
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/debug.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/debug.h
new file mode 100644
index 00000000..78adb2c5
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/debug.h
@@ -0,0 +1,322 @@
+/*
+ * Wine debugging interface
+ *
+ * Copyright 1999 Patrik Stridvall
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#ifndef __WINE_WINE_DEBUG_H
+#define __WINE_WINE_DEBUG_H
+
+#include <stdarg.h>
+#include <windef.h>
+#ifndef GUID_DEFINED
+#include <guiddef.h>
+#endif
+
+#ifdef __WINE_WINE_TEST_H
+#error This file should not be used in Wine tests
+#endif
+
+//#ifdef VBOX_WINE_WITH_IPRT
+# include <iprt/assert.h>
+//#else
+//# define AssertBreakpoint() do { } while (0)
+//# define Assert(_expr) do { } while (0)
+//# ifdef DEBUG_misha
+//# include <iprt/cdefs.h>
+//# endif
+//#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _GUID;
+
+#if !defined(__cplusplus) && !defined(inline)
+# define inline _inline
+#endif
+
+
+/*
+ * Internal definitions (do not use these directly)
+ */
+
+enum __wine_debug_class
+{
+ __WINE_DBCL_FIXME,
+ __WINE_DBCL_ERR,
+ __WINE_DBCL_WARN,
+ __WINE_DBCL_TRACE,
+
+ __WINE_DBCL_INIT = 7 /* lazy init flag */
+};
+
+struct __wine_debug_channel
+{
+ unsigned char flags;
+ char name[15];
+};
+
+#ifdef VBOX_WINE_BEAK_ON_TRACE
+extern DWORD g_VDbgBreakOnTrace;
+#endif
+#ifndef WINE_NO_TRACE_MSGS
+# ifdef VBOX_WINE_BEAK_ON_TRACE
+# define __WINE_GET_DEBUGGING_TRACE(dbch) ((g_VDbgBreakOnTrace ? (RT_BREAKPOINT(),NULL) : NULL), ((dbch)->flags & (1 << __WINE_DBCL_TRACE)))
+# else
+# define __WINE_GET_DEBUGGING_TRACE(dbch) ((dbch)->flags & (1 << __WINE_DBCL_TRACE))
+# endif
+#else
+# define __WINE_GET_DEBUGGING_TRACE(dbch) 0
+#endif
+
+#ifndef WINE_NO_DEBUG_MSGS
+# define __WINE_GET_DEBUGGING_WARN(dbch) ((dbch)->flags & (1 << __WINE_DBCL_WARN))
+# define __WINE_GET_DEBUGGING_FIXME(dbch) ((dbch)->flags & (1 << __WINE_DBCL_FIXME))
+#else
+# define __WINE_GET_DEBUGGING_WARN(dbch) 0
+# define __WINE_GET_DEBUGGING_FIXME(dbch) 0
+#endif
+
+/* define error macro regardless of what is configured */
+#ifdef DEBUG_misha
+#define __WINE_GET_DEBUGGING_ERR(dbch) (RT_BREAKPOINT(), ((dbch)->flags & (1 << __WINE_DBCL_ERR)))
+#else
+#define __WINE_GET_DEBUGGING_ERR(dbch) ((dbch)->flags & (1 << __WINE_DBCL_ERR))
+#endif
+
+#define __WINE_GET_DEBUGGING(dbcl,dbch) __WINE_GET_DEBUGGING##dbcl(dbch)
+
+#define __WINE_IS_DEBUG_ON(dbcl,dbch) \
+ (__WINE_GET_DEBUGGING##dbcl(dbch) && (__wine_dbg_get_channel_flags(dbch) & (1 << __WINE_DBCL##dbcl)))
+
+#ifdef __GNUC__
+
+#define __WINE_DPRINTF(dbcl,dbch) \
+ do { if(__WINE_GET_DEBUGGING(dbcl,(dbch))) { \
+ struct __wine_debug_channel * const __dbch = (dbch); \
+ const enum __wine_debug_class __dbcl = __WINE_DBCL##dbcl; \
+ __WINE_DBG_LOG
+
+#define __WINE_DBG_LOG(args...) \
+ wine_dbg_log( __dbcl, __dbch, __FUNCTION__, args); } } while(0)
+
+#define __WINE_PRINTF_ATTR(fmt,args) __attribute__((format (printf,fmt,args)))
+
+
+#ifdef WINE_NO_TRACE_MSGS
+#define WINE_TRACE(args...) do { } while(0)
+#define WINE_TRACE_(ch) WINE_TRACE
+#endif
+
+#ifdef WINE_NO_DEBUG_MSGS
+#define WINE_WARN(args...) do { } while(0)
+#define WINE_WARN_(ch) WINE_WARN
+#define WINE_FIXME(args...) do { } while(0)
+#define WINE_FIXME_(ch) WINE_FIXME
+#endif
+
+#elif defined(__SUNPRO_C)
+
+#define __WINE_DPRINTF(dbcl,dbch) \
+ do { if(__WINE_GET_DEBUGGING(dbcl,(dbch))) { \
+ struct __wine_debug_channel * const __dbch = (dbch); \
+ const enum __WINE_DEBUG_CLASS __dbcl = __WINE_DBCL##dbcl; \
+ __WINE_DBG_LOG
+
+#define __WINE_DBG_LOG(...) \
+ wine_dbg_log( __dbcl, __dbch, __func__, __VA_ARGS__); } } while(0)
+
+#define __WINE_PRINTF_ATTR(fmt,args)
+
+#ifdef WINE_NO_TRACE_MSGS
+#define WINE_TRACE(...) do { } while(0)
+#define WINE_TRACE_(ch) WINE_TRACE
+#endif
+
+#ifdef WINE_NO_DEBUG_MSGS
+#define WINE_WARN(...) do { } while(0)
+#define WINE_WARN_(ch) WINE_WARN
+#define WINE_FIXME(...) do { } while(0)
+#define WINE_FIXME_(ch) WINE_FIXME
+#endif
+
+#else /* !__GNUC__ && !__SUNPRO_C */
+
+#define __WINE_DPRINTF(dbcl,dbch) \
+ (!__WINE_GET_DEBUGGING(dbcl,(dbch)) || \
+ (wine_dbg_log(__WINE_DBCL##dbcl,(dbch),__FILE__,"%d: ",__LINE__) == -1)) ? \
+ (void)0 : (void)wine_dbg_printf
+
+#define __WINE_PRINTF_ATTR(fmt, args)
+
+#endif /* !__GNUC__ && !__SUNPRO_C */
+
+struct __wine_debug_functions
+{
+ char * (*get_temp_buffer)( size_t n );
+ void (*release_temp_buffer)( char *buffer, size_t n );
+ const char * (*dbgstr_an)( const char * s, int n );
+ const char * (*dbgstr_wn)( const WCHAR *s, int n );
+ int (*dbg_vprintf)( const char *format, va_list args );
+ int (*dbg_vlog)( enum __wine_debug_class cls, struct __wine_debug_channel *channel,
+ const char *function, const char *format, va_list args );
+};
+
+extern unsigned char __wine_dbg_get_channel_flags( struct __wine_debug_channel *channel );
+extern int __wine_dbg_set_channel_flags( struct __wine_debug_channel *channel,
+ unsigned char set, unsigned char clear );
+extern void __wine_dbg_set_functions( const struct __wine_debug_functions *new_funcs,
+ struct __wine_debug_functions *old_funcs, size_t size );
+
+/*
+ * Exported definitions and macros
+ */
+
+/* These functions return a printable version of a string, including
+ quotes. The string will be valid for some time, but not indefinitely
+ as strings are re-used. */
+extern const char *wine_dbgstr_an( const char * s, int n );
+extern const char *wine_dbgstr_wn( const WCHAR *s, int n );
+extern const char *wine_dbg_sprintf( const char *format, ... ) __WINE_PRINTF_ATTR(1,2);
+
+extern int wine_dbg_printf( const char *format, ... ) __WINE_PRINTF_ATTR(1,2);
+extern int wine_dbg_log( enum __wine_debug_class cls, struct __wine_debug_channel *ch, const char *func,
+ const char *format, ... ) __WINE_PRINTF_ATTR(4,5);
+
+static inline const char *wine_dbgstr_a( const char *s )
+{
+ return wine_dbgstr_an( s, -1 );
+}
+
+static inline const char *wine_dbgstr_w( const WCHAR *s )
+{
+ return wine_dbgstr_wn( s, -1 );
+}
+
+static inline const char *wine_dbgstr_guid( const GUID *id )
+{
+ if (!id) return "(null)";
+ if (!((ULONG_PTR)id >> 16)) return wine_dbg_sprintf( "<guid-0x%04hx>", (WORD)(ULONG_PTR)id );
+ return wine_dbg_sprintf( "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+ id->Data1, id->Data2, id->Data3,
+ id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
+ id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] );
+}
+
+static inline const char *wine_dbgstr_point( const POINT *pt )
+{
+ if (!pt) return "(null)";
+ return wine_dbg_sprintf( "(%d,%d)", pt->x, pt->y );
+}
+
+static inline const char *wine_dbgstr_size( const SIZE *size )
+{
+ if (!size) return "(null)";
+ return wine_dbg_sprintf( "(%d,%d)", size->cx, size->cy );
+}
+
+static inline const char *wine_dbgstr_rect( const RECT *rect )
+{
+ if (!rect) return "(null)";
+ return wine_dbg_sprintf( "(%d,%d)-(%d,%d)", rect->left, rect->top,
+ rect->right, rect->bottom );
+}
+
+static inline const char *wine_dbgstr_longlong( ULONGLONG ll )
+{
+ if (sizeof(ll) > sizeof(unsigned long) && ll >> 32)
+ return wine_dbg_sprintf( "%lx%08lx", (unsigned long)(ll >> 32), (unsigned long)ll );
+ else return wine_dbg_sprintf( "%lx", (unsigned long)ll );
+}
+
+#ifndef WINE_TRACE
+#define WINE_TRACE __WINE_DPRINTF(_TRACE,__wine_dbch___default)
+#define WINE_TRACE_(ch) __WINE_DPRINTF(_TRACE,&__wine_dbch_##ch)
+#endif
+#define WINE_TRACE_ON(ch) __WINE_IS_DEBUG_ON(_TRACE,&__wine_dbch_##ch)
+
+#ifndef WINE_WARN
+#define WINE_WARN __WINE_DPRINTF(_WARN,__wine_dbch___default)
+#define WINE_WARN_(ch) __WINE_DPRINTF(_WARN,&__wine_dbch_##ch)
+#endif
+#define WINE_WARN_ON(ch) __WINE_IS_DEBUG_ON(_WARN,&__wine_dbch_##ch)
+
+#ifndef WINE_FIXME
+#define WINE_FIXME __WINE_DPRINTF(_FIXME,__wine_dbch___default)
+#define WINE_FIXME_(ch) __WINE_DPRINTF(_FIXME,&__wine_dbch_##ch)
+#endif
+#define WINE_FIXME_ON(ch) __WINE_IS_DEBUG_ON(_FIXME,&__wine_dbch_##ch)
+
+#define WINE_ERR __WINE_DPRINTF(_ERR,__wine_dbch___default)
+#define WINE_ERR_(ch) __WINE_DPRINTF(_ERR,&__wine_dbch_##ch)
+#define WINE_ERR_ON(ch) __WINE_IS_DEBUG_ON(_ERR,&__wine_dbch_##ch)
+
+#define WINE_DECLARE_DEBUG_CHANNEL(ch) \
+ static struct __wine_debug_channel __wine_dbch_##ch = { ~0, #ch }
+#define WINE_DEFAULT_DEBUG_CHANNEL(ch) \
+ static struct __wine_debug_channel __wine_dbch_##ch = { ~0, #ch }; \
+ static struct __wine_debug_channel * const __wine_dbch___default = &__wine_dbch_##ch
+
+#define WINE_DPRINTF wine_dbg_printf
+#define WINE_MESSAGE wine_dbg_printf
+
+#ifdef __WINESRC__
+/* Wine uses shorter names that are very likely to conflict with other software */
+
+static inline const char *debugstr_an( const char * s, int n ) { return wine_dbgstr_an( s, n ); }
+static inline const char *debugstr_wn( const WCHAR *s, int n ) { return wine_dbgstr_wn( s, n ); }
+static inline const char *debugstr_guid( const struct _GUID *id ) { return wine_dbgstr_guid(id); }
+static inline const char *debugstr_a( const char *s ) { return wine_dbgstr_an( s, -1 ); }
+static inline const char *debugstr_w( const WCHAR *s ) { return wine_dbgstr_wn( s, -1 ); }
+
+#define TRACE WINE_TRACE
+#define TRACE_(ch) WINE_TRACE_(ch)
+#define TRACE_ON(ch) WINE_TRACE_ON(ch)
+
+#define WARN WINE_WARN
+#define WARN_(ch) WINE_WARN_(ch)
+#define WARN_ON(ch) WINE_WARN_ON(ch)
+
+#define FIXME WINE_FIXME
+#define FIXME_(ch) WINE_FIXME_(ch)
+#define FIXME_ON(ch) WINE_FIXME_ON(ch)
+
+#undef ERR /* Solaris got an 'ERR' define in <sys/reg.h> */
+#define ERR WINE_ERR
+#define ERR_(ch) WINE_ERR_(ch)
+#define ERR_ON(ch) WINE_ERR_ON(ch)
+
+#define DPRINTF WINE_DPRINTF
+#define MESSAGE WINE_MESSAGE
+
+#endif /* __WINESRC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __WINE_WINE_DEBUG_H */
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/list.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/list.h
new file mode 100644
index 00000000..6f7afed5
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/list.h
@@ -0,0 +1,243 @@
+/*
+ * Linked lists support
+ *
+ * Copyright (C) 2002 Alexandre Julliard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#ifndef __WINE_SERVER_LIST_H
+#define __WINE_SERVER_LIST_H
+
+#include <stddef.h>
+
+struct list
+{
+ struct list *next;
+ struct list *prev;
+};
+
+/* Define a list like so:
+ *
+ * struct gadget
+ * {
+ * struct list entry; <-- doesn't have to be the first item in the struct
+ * int a, b;
+ * };
+ *
+ * static struct list global_gadgets = LIST_INIT( global_gadgets );
+ *
+ * or
+ *
+ * struct some_global_thing
+ * {
+ * struct list gadgets;
+ * };
+ *
+ * list_init( &some_global_thing->gadgets );
+ *
+ * Manipulate it like this:
+ *
+ * list_add_head( &global_gadgets, &new_gadget->entry );
+ * list_remove( &new_gadget->entry );
+ * list_add_after( &some_random_gadget->entry, &new_gadget->entry );
+ *
+ * And to iterate over it:
+ *
+ * struct gadget *gadget;
+ * LIST_FOR_EACH_ENTRY( gadget, &global_gadgets, struct gadget, entry )
+ * {
+ * ...
+ * }
+ *
+ */
+
+/* add an element after the specified one */
+static inline void list_add_after( struct list *elem, struct list *to_add )
+{
+ to_add->next = elem->next;
+ to_add->prev = elem;
+ elem->next->prev = to_add;
+ elem->next = to_add;
+}
+
+/* add an element before the specified one */
+static inline void list_add_before( struct list *elem, struct list *to_add )
+{
+ to_add->next = elem;
+ to_add->prev = elem->prev;
+ elem->prev->next = to_add;
+ elem->prev = to_add;
+}
+
+/* add element at the head of the list */
+static inline void list_add_head( struct list *list, struct list *elem )
+{
+ list_add_after( list, elem );
+}
+
+/* add element at the tail of the list */
+static inline void list_add_tail( struct list *list, struct list *elem )
+{
+ list_add_before( list, elem );
+}
+
+/* remove an element from its list */
+static inline void list_remove( struct list *elem )
+{
+ elem->next->prev = elem->prev;
+ elem->prev->next = elem->next;
+}
+
+/* get the next element */
+static inline struct list *list_next( const struct list *list, const struct list *elem )
+{
+ struct list *ret = elem->next;
+ if (elem->next == list) ret = NULL;
+ return ret;
+}
+
+/* get the previous element */
+static inline struct list *list_prev( const struct list *list, const struct list *elem )
+{
+ struct list *ret = elem->prev;
+ if (elem->prev == list) ret = NULL;
+ return ret;
+}
+
+/* get the first element */
+static inline struct list *list_head( const struct list *list )
+{
+ return list_next( list, list );
+}
+
+/* get the last element */
+static inline struct list *list_tail( const struct list *list )
+{
+ return list_prev( list, list );
+}
+
+/* check if a list is empty */
+static inline int list_empty( const struct list *list )
+{
+ return list->next == list;
+}
+
+/* initialize a list */
+static inline void list_init( struct list *list )
+{
+ list->next = list->prev = list;
+}
+
+/* count the elements of a list */
+static inline unsigned int list_count( const struct list *list )
+{
+ unsigned count = 0;
+ const struct list *ptr;
+ for (ptr = list->next; ptr != list; ptr = ptr->next) count++;
+ return count;
+}
+
+/* move all elements from src to the tail of dst */
+static inline void list_move_tail( struct list *dst, struct list *src )
+{
+ if (list_empty(src)) return;
+
+ dst->prev->next = src->next;
+ src->next->prev = dst->prev;
+ dst->prev = src->prev;
+ src->prev->next = dst;
+ list_init(src);
+}
+
+/* move all elements from src to the head of dst */
+static inline void list_move_head( struct list *dst, struct list *src )
+{
+ if (list_empty(src)) return;
+
+ dst->next->prev = src->prev;
+ src->prev->next = dst->next;
+ dst->next = src->next;
+ src->next->prev = dst;
+ list_init(src);
+}
+
+/* iterate through the list */
+#define LIST_FOR_EACH(cursor,list) \
+ for ((cursor) = (list)->next; (cursor) != (list); (cursor) = (cursor)->next)
+
+/* iterate through the list, with safety against removal */
+#define LIST_FOR_EACH_SAFE(cursor, cursor2, list) \
+ for ((cursor) = (list)->next, (cursor2) = (cursor)->next; \
+ (cursor) != (list); \
+ (cursor) = (cursor2), (cursor2) = (cursor)->next)
+
+/* iterate through the list using a list entry */
+#define LIST_FOR_EACH_ENTRY(elem, list, type, field) \
+ for ((elem) = LIST_ENTRY((list)->next, type, field); \
+ &(elem)->field != (list); \
+ (elem) = LIST_ENTRY((elem)->field.next, type, field))
+
+/* iterate through the list using a list entry, with safety against removal */
+#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field) \
+ for ((cursor) = LIST_ENTRY((list)->next, type, field), \
+ (cursor2) = LIST_ENTRY((cursor)->field.next, type, field); \
+ &(cursor)->field != (list); \
+ (cursor) = (cursor2), \
+ (cursor2) = LIST_ENTRY((cursor)->field.next, type, field))
+
+/* iterate through the list in reverse order */
+#define LIST_FOR_EACH_REV(cursor,list) \
+ for ((cursor) = (list)->prev; (cursor) != (list); (cursor) = (cursor)->prev)
+
+/* iterate through the list in reverse order, with safety against removal */
+#define LIST_FOR_EACH_SAFE_REV(cursor, cursor2, list) \
+ for ((cursor) = (list)->prev, (cursor2) = (cursor)->prev; \
+ (cursor) != (list); \
+ (cursor) = (cursor2), (cursor2) = (cursor)->prev)
+
+/* iterate through the list in reverse order using a list entry */
+#define LIST_FOR_EACH_ENTRY_REV(elem, list, type, field) \
+ for ((elem) = LIST_ENTRY((list)->prev, type, field); \
+ &(elem)->field != (list); \
+ (elem) = LIST_ENTRY((elem)->field.prev, type, field))
+
+/* iterate through the list in reverse order using a list entry, with safety against removal */
+#define LIST_FOR_EACH_ENTRY_SAFE_REV(cursor, cursor2, list, type, field) \
+ for ((cursor) = LIST_ENTRY((list)->prev, type, field), \
+ (cursor2) = LIST_ENTRY((cursor)->field.prev, type, field); \
+ &(cursor)->field != (list); \
+ (cursor) = (cursor2), \
+ (cursor2) = LIST_ENTRY((cursor)->field.prev, type, field))
+
+/* macros for statically initialized lists */
+#undef LIST_INIT
+#define LIST_INIT(list) { &(list), &(list) }
+
+/* get pointer to object containing list element */
+#undef LIST_ENTRY
+#define LIST_ENTRY(elem, type, field) \
+ ((type *)((char *)(elem) - offsetof(type, field)))
+
+#endif /* __WINE_SERVER_LIST_H */
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/port.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/port.h
new file mode 100644
index 00000000..d0ab5ee8
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/port.h
@@ -0,0 +1,489 @@
+/*
+ * Wine porting definitions
+ *
+ * Copyright 1996 Alexandre Julliard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#ifndef __WINE_WINE_PORT_H
+#define __WINE_WINE_PORT_H
+
+#ifndef __WINE_CONFIG_H
+# error You must include config.h to use this header
+#endif
+
+#ifdef __WINE_BASETSD_H
+# error You must include port.h before all other headers
+#endif
+
+#define _GNU_SOURCE /* for pread/pwrite */
+#include <fcntl.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_DIRECT_H
+# include <direct.h>
+#endif
+#ifdef HAVE_IO_H
+# include <io.h>
+#endif
+#ifdef HAVE_PROCESS_H
+# include <process.h>
+#endif
+#include <string.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+
+/****************************************************************
+ * Type definitions
+ */
+
+#if !defined(_MSC_VER) && !defined(__int64)
+# if defined(__x86_64__) || defined(__aarch64__) || defined(_WIN64)
+# define __int64 long
+# else
+# define __int64 long long
+# endif
+#endif
+
+#ifndef HAVE_MODE_T
+typedef int mode_t;
+#endif
+#ifndef HAVE_OFF_T
+typedef long off_t;
+#endif
+#ifndef HAVE_PID_T
+typedef int pid_t;
+#endif
+#ifndef HAVE_SIZE_T
+typedef unsigned int size_t;
+#endif
+#ifndef HAVE_SSIZE_T
+typedef int ssize_t;
+#endif
+#ifndef HAVE_FSBLKCNT_T
+typedef unsigned long fsblkcnt_t;
+#endif
+#ifndef HAVE_FSFILCNT_T
+typedef unsigned long fsfilcnt_t;
+#endif
+
+#ifndef HAVE_STRUCT_STATVFS_F_BLOCKS
+struct statvfs
+{
+ unsigned long f_bsize;
+ unsigned long f_frsize;
+ fsblkcnt_t f_blocks;
+ fsblkcnt_t f_bfree;
+ fsblkcnt_t f_bavail;
+ fsfilcnt_t f_files;
+ fsfilcnt_t f_ffree;
+ fsfilcnt_t f_favail;
+ unsigned long f_fsid;
+ unsigned long f_flag;
+ unsigned long f_namemax;
+};
+#endif /* HAVE_STRUCT_STATVFS_F_BLOCKS */
+
+
+/****************************************************************
+ * Macro definitions
+ */
+
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#else
+#define RTLD_LAZY 0x001
+#define RTLD_NOW 0x002
+#define RTLD_GLOBAL 0x100
+#endif
+
+#ifdef HAVE_ONE_ARG_MKDIR
+#define mkdir(path,mode) mkdir(path)
+#endif
+
+#if !defined(HAVE_FTRUNCATE) && defined(HAVE_CHSIZE)
+#define ftruncate chsize
+#endif
+
+#if !defined(HAVE_POPEN) && defined(HAVE__POPEN)
+#define popen _popen
+#endif
+
+#if !defined(HAVE_PCLOSE) && defined(HAVE__PCLOSE)
+#define pclose _pclose
+#endif
+
+#if !defined(HAVE_STRDUP) && defined(HAVE__STRDUP)
+#define strdup _strdup
+#endif
+
+#if !defined(HAVE_SNPRINTF) && defined(HAVE__SNPRINTF)
+#define snprintf _snprintf
+#endif
+
+#if !defined(HAVE_VSNPRINTF) && defined(HAVE__VSNPRINTF)
+#define vsnprintf _vsnprintf
+#endif
+
+#if !defined(HAVE_STRTOLL) && defined(HAVE__STRTOI64)
+#define strtoll _strtoi64
+#endif
+
+#if !defined(HAVE_STRTOULL) && defined(HAVE__STRTOUI64)
+#define strtoull _strtoui64
+#endif
+
+#ifndef S_ISLNK
+# define S_ISLNK(mod) (0)
+#endif
+
+#ifndef S_ISSOCK
+# define S_ISSOCK(mod) (0)
+#endif
+
+#ifndef S_ISDIR
+# define S_ISDIR(mod) (((mod) & _S_IFMT) == _S_IFDIR)
+#endif
+
+#ifndef S_ISCHR
+# define S_ISCHR(mod) (((mod) & _S_IFMT) == _S_IFCHR)
+#endif
+
+#ifndef S_ISFIFO
+# define S_ISFIFO(mod) (((mod) & _S_IFMT) == _S_IFIFO)
+#endif
+
+#ifndef S_ISREG
+# define S_ISREG(mod) (((mod) & _S_IFMT) == _S_IFREG)
+#endif
+
+/* So we open files in 64 bit access mode on Linux */
+#ifndef O_LARGEFILE
+# define O_LARGEFILE 0
+#endif
+
+#ifndef O_NONBLOCK
+# define O_NONBLOCK 0
+#endif
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+
+
+/****************************************************************
+ * Constants
+ */
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#ifndef M_PI_2
+#define M_PI_2 1.570796326794896619
+#endif
+
+#ifdef VBOX
+# if !defined(__cplusplus)
+# define inline _inline
+# endif
+#endif
+
+
+#ifndef INFINITY
+static inline float __port_infinity(void)
+{
+ static const unsigned __inf_bytes = 0x7f800000;
+ return *(const float *)&__inf_bytes;
+}
+#define INFINITY __port_infinity()
+#endif
+
+#ifndef NAN
+static inline float __port_nan(void)
+{
+ static const unsigned __nan_bytes = 0x7fc00000;
+ return *(const float *)&__nan_bytes;
+}
+#define NAN __port_nan()
+#endif
+
+
+/****************************************************************
+ * Function definitions (only when using libwine_port)
+ */
+
+#ifndef NO_LIBWINE_PORT
+
+#ifndef HAVE_FSTATVFS
+int fstatvfs( int fd, struct statvfs *buf );
+#endif
+
+#ifndef HAVE_GETOPT_LONG_ONLY
+extern char *optarg;
+extern int optind;
+extern int opterr;
+extern int optopt;
+struct option;
+
+#ifndef HAVE_STRUCT_OPTION_NAME
+struct option
+{
+ const char *name;
+ int has_arg;
+ int *flag;
+ int val;
+};
+#endif
+
+extern int getopt_long (int ___argc, char *const *___argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind);
+extern int getopt_long_only (int ___argc, char *const *___argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind);
+#endif /* HAVE_GETOPT_LONG_ONLY */
+
+#ifndef HAVE_FFS
+int ffs( int x );
+#endif
+
+#ifndef HAVE_ISINF
+int isinf(double x);
+#endif
+
+#ifndef HAVE_ISNAN
+int isnan(double x);
+#endif
+
+#ifndef HAVE_LSTAT
+int lstat(const char *file_name, struct stat *buf);
+#endif /* HAVE_LSTAT */
+
+#ifndef HAVE_MEMMOVE
+void *memmove(void *dest, const void *src, size_t len);
+#endif /* !defined(HAVE_MEMMOVE) */
+
+#ifndef HAVE_POLL
+struct pollfd
+{
+ int fd;
+ short events;
+ short revents;
+};
+#define POLLIN 0x01
+#define POLLPRI 0x02
+#define POLLOUT 0x04
+#define POLLERR 0x08
+#define POLLHUP 0x10
+#define POLLNVAL 0x20
+int poll( struct pollfd *fds, unsigned int count, int timeout );
+#endif /* HAVE_POLL */
+
+#ifndef HAVE_PREAD
+ssize_t pread( int fd, void *buf, size_t count, off_t offset );
+#endif /* HAVE_PREAD */
+
+#ifndef HAVE_PWRITE
+ssize_t pwrite( int fd, const void *buf, size_t count, off_t offset );
+#endif /* HAVE_PWRITE */
+
+#ifndef HAVE_READLINK
+int readlink( const char *path, char *buf, size_t size );
+#endif /* HAVE_READLINK */
+
+#ifndef HAVE_STATVFS
+int statvfs( const char *path, struct statvfs *buf );
+#endif
+
+#ifndef HAVE_STRNCASECMP
+# ifndef HAVE__STRNICMP
+int strncasecmp(const char *str1, const char *str2, size_t n);
+# else
+# define strncasecmp _strnicmp
+# endif
+#endif /* !defined(HAVE_STRNCASECMP) */
+
+#ifndef HAVE_STRERROR
+const char *strerror(int err);
+#endif /* !defined(HAVE_STRERROR) */
+
+#ifndef HAVE_STRCASECMP
+# ifndef HAVE__STRICMP
+int strcasecmp(const char *str1, const char *str2);
+# else
+# define strcasecmp _stricmp
+# endif
+#endif /* !defined(HAVE_STRCASECMP) */
+
+#ifndef HAVE_SYMLINK
+int symlink(const char *from, const char *to);
+#endif
+
+#ifndef HAVE_USLEEP
+int usleep (unsigned int useconds);
+#endif /* !defined(HAVE_USLEEP) */
+
+#ifdef __i386__
+static inline void *memcpy_unaligned( void *dst, const void *src, size_t size )
+{
+ return memcpy( dst, src, size );
+}
+#else
+extern void *memcpy_unaligned( void *dst, const void *src, size_t size );
+#endif /* __i386__ */
+
+extern int mkstemps(char *template, int suffix_len);
+
+/* Process creation flags */
+#ifndef _P_WAIT
+# define _P_WAIT 0
+# define _P_NOWAIT 1
+# define _P_OVERLAY 2
+# define _P_NOWAITO 3
+# define _P_DETACH 4
+#endif
+#ifndef HAVE__SPAWNVP
+extern int _spawnvp(int mode, const char *cmdname, const char * const argv[]);
+#endif
+
+/* Interlocked functions */
+
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+
+extern __int64 interlocked_cmpxchg64( __int64 *dest, __int64 xchg, __int64 compare );
+
+static inline int interlocked_cmpxchg( int *dest, int xchg, int compare )
+{
+ int ret;
+ __asm__ __volatile__( "lock; cmpxchgl %2,(%1)"
+ : "=a" (ret) : "r" (dest), "r" (xchg), "0" (compare) : "memory" );
+ return ret;
+}
+
+static inline void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare )
+{
+ void *ret;
+#ifdef __x86_64__
+ __asm__ __volatile__( "lock; cmpxchgq %2,(%1)"
+ : "=a" (ret) : "r" (dest), "r" (xchg), "0" (compare) : "memory" );
+#else
+ __asm__ __volatile__( "lock; cmpxchgl %2,(%1)"
+ : "=a" (ret) : "r" (dest), "r" (xchg), "0" (compare) : "memory" );
+#endif
+ return ret;
+}
+
+static inline int interlocked_xchg( int *dest, int val )
+{
+ int ret;
+ __asm__ __volatile__( "lock; xchgl %0,(%1)"
+ : "=r" (ret) : "r" (dest), "0" (val) : "memory" );
+ return ret;
+}
+
+static inline void *interlocked_xchg_ptr( void **dest, void *val )
+{
+ void *ret;
+#ifdef __x86_64__
+ __asm__ __volatile__( "lock; xchgq %0,(%1)"
+ : "=r" (ret) :"r" (dest), "0" (val) : "memory" );
+#else
+ __asm__ __volatile__( "lock; xchgl %0,(%1)"
+ : "=r" (ret) : "r" (dest), "0" (val) : "memory" );
+#endif
+ return ret;
+}
+
+static inline int interlocked_xchg_add( int *dest, int incr )
+{
+ int ret;
+ __asm__ __volatile__( "lock; xaddl %0,(%1)"
+ : "=r" (ret) : "r" (dest), "0" (incr) : "memory" );
+ return ret;
+}
+
+#ifdef __x86_64__
+static inline unsigned char interlocked_cmpxchg128( __int64 *dest, __int64 xchg_high,
+ __int64 xchg_low, __int64 *compare )
+{
+ unsigned char ret;
+ __asm__ __volatile__( "lock cmpxchg16b %0; setz %b2"
+ : "=m" (dest[0]), "=m" (dest[1]), "=r" (ret),
+ "=a" (compare[0]), "=d" (compare[1])
+ : "m" (dest[0]), "m" (dest[1]), "3" (compare[0]), "4" (compare[1]),
+ "c" (xchg_high), "b" (xchg_low) );
+ return ret;
+}
+#endif
+
+#else /* __GNUC__ */
+
+extern int interlocked_cmpxchg( int *dest, int xchg, int compare );
+extern void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare );
+extern __int64 interlocked_cmpxchg64( __int64 *dest, __int64 xchg, __int64 compare );
+extern int interlocked_xchg( int *dest, int val );
+extern void *interlocked_xchg_ptr( void **dest, void *val );
+extern int interlocked_xchg_add( int *dest, int incr );
+#if defined(__x86_64__) || defined(__aarch64__) || defined(_WIN64)
+extern unsigned char interlocked_cmpxchg128( __int64 *dest, __int64 xchg_high,
+ __int64 xchg_low, __int64 *compare );
+#endif
+
+#endif /* __GNUC__ */
+
+#else /* NO_LIBWINE_PORT */
+
+#define __WINE_NOT_PORTABLE(func) func##_is_not_portable func##_is_not_portable
+
+#define ffs __WINE_NOT_PORTABLE(ffs)
+#define fstatvfs __WINE_NOT_PORTABLE(fstatvfs)
+#define getopt_long __WINE_NOT_PORTABLE(getopt_long)
+#define getopt_long_only __WINE_NOT_PORTABLE(getopt_long_only)
+#define interlocked_cmpxchg __WINE_NOT_PORTABLE(interlocked_cmpxchg)
+#define interlocked_cmpxchg_ptr __WINE_NOT_PORTABLE(interlocked_cmpxchg_ptr)
+#define interlocked_xchg __WINE_NOT_PORTABLE(interlocked_xchg)
+#define interlocked_xchg_ptr __WINE_NOT_PORTABLE(interlocked_xchg_ptr)
+#define interlocked_xchg_add __WINE_NOT_PORTABLE(interlocked_xchg_add)
+#define lstat __WINE_NOT_PORTABLE(lstat)
+#define memcpy_unaligned __WINE_NOT_PORTABLE(memcpy_unaligned)
+#undef memmove
+#define memmove __WINE_NOT_PORTABLE(memmove)
+#define pread __WINE_NOT_PORTABLE(pread)
+#define pwrite __WINE_NOT_PORTABLE(pwrite)
+#define spawnvp __WINE_NOT_PORTABLE(spawnvp)
+#define statvfs __WINE_NOT_PORTABLE(statvfs)
+#define strcasecmp __WINE_NOT_PORTABLE(strcasecmp)
+#define strerror __WINE_NOT_PORTABLE(strerror)
+#define strncasecmp __WINE_NOT_PORTABLE(strncasecmp)
+#define usleep __WINE_NOT_PORTABLE(usleep)
+
+#endif /* NO_LIBWINE_PORT */
+
+#endif /* !defined(__WINE_WINE_PORT_H) */
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/rbtree.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/rbtree.h
new file mode 100644
index 00000000..4488a01d
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/rbtree.h
@@ -0,0 +1,351 @@
+/*
+ * Red-black search tree support
+ *
+ * Copyright 2009 Henri Verbeet
+ * Copyright 2009 Andrew Riedi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#ifndef __WINE_WINE_RBTREE_H
+#define __WINE_WINE_RBTREE_H
+
+#define WINE_RB_ENTRY_VALUE(element, type, field) \
+ ((type *)((char *)(element) - offsetof(type, field)))
+
+struct wine_rb_entry
+{
+ struct wine_rb_entry *left;
+ struct wine_rb_entry *right;
+ unsigned int flags;
+};
+
+struct wine_rb_stack
+{
+ struct wine_rb_entry ***entries;
+ size_t count;
+ size_t size;
+};
+
+struct wine_rb_functions
+{
+ void *(*alloc)(size_t size);
+ void *(*realloc)(void *ptr, size_t size);
+ void (*free)(void *ptr);
+ int (*compare)(const void *key, const struct wine_rb_entry *entry);
+};
+
+struct wine_rb_tree
+{
+ const struct wine_rb_functions *functions;
+ struct wine_rb_entry *root;
+ struct wine_rb_stack stack;
+};
+
+typedef void (wine_rb_traverse_func_t)(struct wine_rb_entry *entry, void *context);
+
+#define WINE_RB_FLAG_RED 0x1
+#define WINE_RB_FLAG_STOP 0x2
+#define WINE_RB_FLAG_TRAVERSED_LEFT 0x4
+#define WINE_RB_FLAG_TRAVERSED_RIGHT 0x8
+
+static inline void wine_rb_stack_clear(struct wine_rb_stack *stack)
+{
+ stack->count = 0;
+}
+
+static inline void wine_rb_stack_push(struct wine_rb_stack *stack, struct wine_rb_entry **entry)
+{
+ stack->entries[stack->count++] = entry;
+}
+
+static inline int wine_rb_ensure_stack_size(struct wine_rb_tree *tree, size_t size)
+{
+ struct wine_rb_stack *stack = &tree->stack;
+
+ if (size > stack->size)
+ {
+ size_t new_size = stack->size << 1;
+ struct wine_rb_entry ***new_entries = tree->functions->realloc(stack->entries,
+ new_size * sizeof(*stack->entries));
+
+ if (!new_entries) return -1;
+
+ stack->entries = new_entries;
+ stack->size = new_size;
+ }
+
+ return 0;
+}
+
+static inline int wine_rb_is_red(struct wine_rb_entry *entry)
+{
+ return entry && (entry->flags & WINE_RB_FLAG_RED);
+}
+
+static inline void wine_rb_rotate_left(struct wine_rb_entry **entry)
+{
+ struct wine_rb_entry *e = *entry;
+ struct wine_rb_entry *right = e->right;
+
+ e->right = right->left;
+ right->left = e;
+ right->flags &= ~WINE_RB_FLAG_RED;
+ right->flags |= e->flags & WINE_RB_FLAG_RED;
+ e->flags |= WINE_RB_FLAG_RED;
+ *entry = right;
+}
+
+static inline void wine_rb_rotate_right(struct wine_rb_entry **entry)
+{
+ struct wine_rb_entry *e = *entry;
+ struct wine_rb_entry *left = e->left;
+
+ e->left = left->right;
+ left->right = e;
+ left->flags &= ~WINE_RB_FLAG_RED;
+ left->flags |= e->flags & WINE_RB_FLAG_RED;
+ e->flags |= WINE_RB_FLAG_RED;
+ *entry = left;
+}
+
+static inline void wine_rb_flip_color(struct wine_rb_entry *entry)
+{
+ entry->flags ^= WINE_RB_FLAG_RED;
+ entry->left->flags ^= WINE_RB_FLAG_RED;
+ entry->right->flags ^= WINE_RB_FLAG_RED;
+}
+
+static inline void wine_rb_fixup(struct wine_rb_stack *stack)
+{
+ while (stack->count)
+ {
+ struct wine_rb_entry **entry = stack->entries[stack->count - 1];
+
+ if ((*entry)->flags & WINE_RB_FLAG_STOP)
+ {
+ (*entry)->flags &= ~WINE_RB_FLAG_STOP;
+ return;
+ }
+
+ if (wine_rb_is_red((*entry)->right) && !wine_rb_is_red((*entry)->left)) wine_rb_rotate_left(entry);
+ if (wine_rb_is_red((*entry)->left) && wine_rb_is_red((*entry)->left->left)) wine_rb_rotate_right(entry);
+ if (wine_rb_is_red((*entry)->left) && wine_rb_is_red((*entry)->right)) wine_rb_flip_color(*entry);
+ --stack->count;
+ }
+}
+
+static inline void wine_rb_move_red_left(struct wine_rb_entry **entry)
+{
+ wine_rb_flip_color(*entry);
+ if (wine_rb_is_red((*entry)->right->left))
+ {
+ wine_rb_rotate_right(&(*entry)->right);
+ wine_rb_rotate_left(entry);
+ wine_rb_flip_color(*entry);
+ }
+}
+
+static inline void wine_rb_move_red_right(struct wine_rb_entry **entry)
+{
+ wine_rb_flip_color(*entry);
+ if (wine_rb_is_red((*entry)->left->left))
+ {
+ wine_rb_rotate_right(entry);
+ wine_rb_flip_color(*entry);
+ }
+}
+
+static inline void wine_rb_postorder(struct wine_rb_tree *tree, wine_rb_traverse_func_t *callback, void *context)
+{
+ struct wine_rb_entry **entry;
+
+ if (!tree->root) return;
+
+ for (entry = &tree->root;;)
+ {
+ struct wine_rb_entry *e = *entry;
+
+ if (e->left && !(e->flags & WINE_RB_FLAG_TRAVERSED_LEFT))
+ {
+ wine_rb_stack_push(&tree->stack, entry);
+ e->flags |= WINE_RB_FLAG_TRAVERSED_LEFT;
+ entry = &e->left;
+ continue;
+ }
+
+ if (e->right && !(e->flags & WINE_RB_FLAG_TRAVERSED_RIGHT))
+ {
+ wine_rb_stack_push(&tree->stack, entry);
+ e->flags |= WINE_RB_FLAG_TRAVERSED_RIGHT;
+ entry = &e->right;
+ continue;
+ }
+
+ e->flags &= ~(WINE_RB_FLAG_TRAVERSED_LEFT | WINE_RB_FLAG_TRAVERSED_RIGHT);
+ callback(e, context);
+
+ if (!tree->stack.count) break;
+ entry = tree->stack.entries[--tree->stack.count];
+ }
+}
+
+static inline int wine_rb_init(struct wine_rb_tree *tree, const struct wine_rb_functions *functions)
+{
+ tree->functions = functions;
+ tree->root = NULL;
+
+ tree->stack.entries = functions->alloc(16 * sizeof(*tree->stack.entries));
+ if (!tree->stack.entries) return -1;
+ tree->stack.size = 16;
+ tree->stack.count = 0;
+
+ return 0;
+}
+
+static inline void wine_rb_for_each_entry(struct wine_rb_tree *tree, wine_rb_traverse_func_t *callback, void *context)
+{
+ wine_rb_postorder(tree, callback, context);
+}
+
+static inline void wine_rb_destroy(struct wine_rb_tree *tree, wine_rb_traverse_func_t *callback, void *context)
+{
+ /* Note that we use postorder here because the callback will likely free the entry. */
+ if (callback) wine_rb_postorder(tree, callback, context);
+
+ tree->root = NULL;
+ tree->functions->free(tree->stack.entries);
+}
+
+static inline struct wine_rb_entry *wine_rb_get(const struct wine_rb_tree *tree, const void *key)
+{
+ struct wine_rb_entry *entry = tree->root;
+ while (entry)
+ {
+ int c = tree->functions->compare(key, entry);
+ if (!c) return entry;
+ entry = c < 0 ? entry->left : entry->right;
+ }
+ return NULL;
+}
+
+static inline int wine_rb_put(struct wine_rb_tree *tree, const void *key, struct wine_rb_entry *entry)
+{
+ struct wine_rb_entry **parent = &tree->root;
+ size_t black_height = 1;
+
+ while (*parent)
+ {
+ int c;
+
+ if (!wine_rb_is_red(*parent)) ++black_height;
+
+ wine_rb_stack_push(&tree->stack, parent);
+
+ c = tree->functions->compare(key, *parent);
+ if (!c)
+ {
+ wine_rb_stack_clear(&tree->stack);
+ return -1;
+ }
+ else if (c < 0) parent = &(*parent)->left;
+ else parent = &(*parent)->right;
+ }
+
+ /* After insertion, the path length to any node should be <= (black_height + 1) * 2. */
+ if (wine_rb_ensure_stack_size(tree, black_height << 1) == -1)
+ {
+ wine_rb_stack_clear(&tree->stack);
+ return -1;
+ }
+
+ entry->flags = WINE_RB_FLAG_RED;
+ entry->left = NULL;
+ entry->right = NULL;
+ *parent = entry;
+
+ wine_rb_fixup(&tree->stack);
+ tree->root->flags &= ~WINE_RB_FLAG_RED;
+
+ return 0;
+}
+
+static inline void wine_rb_remove(struct wine_rb_tree *tree, const void *key)
+{
+ struct wine_rb_entry **entry = &tree->root;
+
+ while (*entry)
+ {
+ if (tree->functions->compare(key, *entry) < 0)
+ {
+ wine_rb_stack_push(&tree->stack, entry);
+ if (!wine_rb_is_red((*entry)->left) && !wine_rb_is_red((*entry)->left->left)) wine_rb_move_red_left(entry);
+ entry = &(*entry)->left;
+ }
+ else
+ {
+ if (wine_rb_is_red((*entry)->left)) wine_rb_rotate_right(entry);
+ if (!tree->functions->compare(key, *entry) && !(*entry)->right)
+ {
+ *entry = NULL;
+ break;
+ }
+ if (!wine_rb_is_red((*entry)->right) && !wine_rb_is_red((*entry)->right->left))
+ wine_rb_move_red_right(entry);
+ if (!tree->functions->compare(key, *entry))
+ {
+ struct wine_rb_entry **e = &(*entry)->right;
+ struct wine_rb_entry *m = *e;
+ while (m->left) m = m->left;
+
+ wine_rb_stack_push(&tree->stack, entry);
+ (*entry)->flags |= WINE_RB_FLAG_STOP;
+
+ while ((*e)->left)
+ {
+ wine_rb_stack_push(&tree->stack, e);
+ if (!wine_rb_is_red((*e)->left) && !wine_rb_is_red((*e)->left->left)) wine_rb_move_red_left(e);
+ e = &(*e)->left;
+ }
+ *e = NULL;
+ wine_rb_fixup(&tree->stack);
+
+ *m = **entry;
+ *entry = m;
+
+ break;
+ }
+ else
+ {
+ wine_rb_stack_push(&tree->stack, entry);
+ entry = &(*entry)->right;
+ }
+ }
+ }
+
+ wine_rb_fixup(&tree->stack);
+ if (tree->root) tree->root->flags &= ~WINE_RB_FLAG_RED;
+}
+
+#endif /* __WINE_WINE_RBTREE_H */
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/unicode.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/unicode.h
new file mode 100644
index 00000000..4257f153
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/unicode.h
@@ -0,0 +1,320 @@
+/*
+ * Wine internal Unicode definitions
+ *
+ * Copyright 2000 Alexandre Julliard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#ifndef __WINE_WINE_UNICODE_H
+#define __WINE_WINE_UNICODE_H
+
+#include <stdarg.h>
+
+#include <windef.h>
+#include <winbase.h>
+#include <winnls.h>
+
+#ifdef __WINE_WINE_TEST_H
+#error This file should not be used in Wine tests
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef WINE_UNICODE_API
+# if defined(_MSC_VER) || defined(__MINGW32__)
+# define WINE_UNICODE_API DECLSPEC_IMPORT
+# else
+# define WINE_UNICODE_API
+# endif
+#endif
+
+#ifndef WINE_UNICODE_INLINE
+#define WINE_UNICODE_INLINE static inline
+#endif
+
+/* code page info common to SBCS and DBCS */
+struct cp_info
+{
+ unsigned int codepage; /* codepage id */
+ unsigned int char_size; /* char size (1 or 2 bytes) */
+ WCHAR def_char; /* default char value (can be double-byte) */
+ WCHAR def_unicode_char; /* default Unicode char value */
+ const char *name; /* code page name */
+};
+
+struct sbcs_table
+{
+ struct cp_info info;
+ const WCHAR *cp2uni; /* code page -> Unicode map */
+ const WCHAR *cp2uni_glyphs; /* code page -> Unicode map with glyph chars */
+ const unsigned char *uni2cp_low; /* Unicode -> code page map */
+ const unsigned short *uni2cp_high;
+};
+
+struct dbcs_table
+{
+ struct cp_info info;
+ const WCHAR *cp2uni; /* code page -> Unicode map */
+ const unsigned char *cp2uni_leadbytes;
+ const unsigned short *uni2cp_low; /* Unicode -> code page map */
+ const unsigned short *uni2cp_high;
+ unsigned char lead_bytes[12]; /* lead bytes ranges */
+};
+
+union cptable
+{
+ struct cp_info info;
+ struct sbcs_table sbcs;
+ struct dbcs_table dbcs;
+};
+
+extern const union cptable *wine_cp_get_table( unsigned int codepage );
+extern const union cptable *wine_cp_enum_table( unsigned int index );
+
+extern int wine_cp_mbstowcs( const union cptable *table, int flags,
+ const char *src, int srclen,
+ WCHAR *dst, int dstlen );
+extern int wine_cp_wcstombs( const union cptable *table, int flags,
+ const WCHAR *src, int srclen,
+ char *dst, int dstlen, const char *defchar, int *used );
+extern int wine_cpsymbol_mbstowcs( const char *src, int srclen, WCHAR *dst, int dstlen );
+extern int wine_cpsymbol_wcstombs( const WCHAR *src, int srclen, char *dst, int dstlen );
+extern int wine_utf8_mbstowcs( int flags, const char *src, int srclen, WCHAR *dst, int dstlen );
+extern int wine_utf8_wcstombs( int flags, const WCHAR *src, int srclen, char *dst, int dstlen );
+
+extern int wine_compare_string( int flags, const WCHAR *str1, int len1, const WCHAR *str2, int len2 );
+extern int wine_get_sortkey( int flags, const WCHAR *src, int srclen, char *dst, int dstlen );
+extern int wine_fold_string( int flags, const WCHAR *src, int srclen , WCHAR *dst, int dstlen );
+
+extern int strcmpiW( const WCHAR *str1, const WCHAR *str2 );
+extern int strncmpiW( const WCHAR *str1, const WCHAR *str2, int n );
+extern int memicmpW( const WCHAR *str1, const WCHAR *str2, int n );
+extern WCHAR *strstrW( const WCHAR *str, const WCHAR *sub );
+extern long int strtolW( const WCHAR *nptr, WCHAR **endptr, int base );
+extern unsigned long int strtoulW( const WCHAR *nptr, WCHAR **endptr, int base );
+extern int sprintfW( WCHAR *str, const WCHAR *format, ... );
+extern int snprintfW( WCHAR *str, size_t len, const WCHAR *format, ... );
+extern int vsprintfW( WCHAR *str, const WCHAR *format, va_list valist );
+extern int vsnprintfW( WCHAR *str, size_t len, const WCHAR *format, va_list valist );
+
+WINE_UNICODE_INLINE int wine_is_dbcs_leadbyte( const union cptable *table, unsigned char ch )
+{
+ return (table->info.char_size == 2) && (table->dbcs.cp2uni_leadbytes[ch]);
+}
+
+WINE_UNICODE_INLINE WCHAR tolowerW( WCHAR ch )
+{
+ extern WINE_UNICODE_API const WCHAR wine_casemap_lower[];
+ return ch + wine_casemap_lower[wine_casemap_lower[ch >> 8] + (ch & 0xff)];
+}
+
+WINE_UNICODE_INLINE WCHAR toupperW( WCHAR ch )
+{
+ extern WINE_UNICODE_API const WCHAR wine_casemap_upper[];
+ return ch + wine_casemap_upper[wine_casemap_upper[ch >> 8] + (ch & 0xff)];
+}
+
+/* the character type contains the C1_* flags in the low 12 bits */
+/* and the C2_* type in the high 4 bits */
+WINE_UNICODE_INLINE unsigned short get_char_typeW( WCHAR ch )
+{
+ extern WINE_UNICODE_API const unsigned short wine_wctype_table[];
+ return wine_wctype_table[wine_wctype_table[ch >> 8] + (ch & 0xff)];
+}
+
+WINE_UNICODE_INLINE int iscntrlW( WCHAR wc )
+{
+ return get_char_typeW(wc) & C1_CNTRL;
+}
+
+WINE_UNICODE_INLINE int ispunctW( WCHAR wc )
+{
+ return get_char_typeW(wc) & C1_PUNCT;
+}
+
+WINE_UNICODE_INLINE int isspaceW( WCHAR wc )
+{
+ return get_char_typeW(wc) & C1_SPACE;
+}
+
+WINE_UNICODE_INLINE int isdigitW( WCHAR wc )
+{
+ return get_char_typeW(wc) & C1_DIGIT;
+}
+
+WINE_UNICODE_INLINE int isxdigitW( WCHAR wc )
+{
+ return get_char_typeW(wc) & C1_XDIGIT;
+}
+
+WINE_UNICODE_INLINE int islowerW( WCHAR wc )
+{
+ return get_char_typeW(wc) & C1_LOWER;
+}
+
+WINE_UNICODE_INLINE int isupperW( WCHAR wc )
+{
+ return get_char_typeW(wc) & C1_UPPER;
+}
+
+WINE_UNICODE_INLINE int isalnumW( WCHAR wc )
+{
+ return get_char_typeW(wc) & (C1_ALPHA|C1_DIGIT|C1_LOWER|C1_UPPER);
+}
+
+WINE_UNICODE_INLINE int isalphaW( WCHAR wc )
+{
+ return get_char_typeW(wc) & (C1_ALPHA|C1_LOWER|C1_UPPER);
+}
+
+WINE_UNICODE_INLINE int isgraphW( WCHAR wc )
+{
+ return get_char_typeW(wc) & (C1_ALPHA|C1_PUNCT|C1_DIGIT|C1_LOWER|C1_UPPER);
+}
+
+WINE_UNICODE_INLINE int isprintW( WCHAR wc )
+{
+ return get_char_typeW(wc) & (C1_ALPHA|C1_BLANK|C1_PUNCT|C1_DIGIT|C1_LOWER|C1_UPPER);
+}
+
+/* some useful string manipulation routines */
+
+WINE_UNICODE_INLINE unsigned int strlenW( const WCHAR *str )
+{
+ const WCHAR *s = str;
+ while (*s) s++;
+ return s - str;
+}
+
+WINE_UNICODE_INLINE WCHAR *strcpyW( WCHAR *dst, const WCHAR *src )
+{
+ WCHAR *p = dst;
+ while ((*p++ = *src++));
+ return dst;
+}
+
+/* strncpy doesn't do what you think, don't use it */
+#define strncpyW(d,s,n) error do_not_use_strncpyW_use_lstrcpynW_or_memcpy_instead
+
+WINE_UNICODE_INLINE int strcmpW( const WCHAR *str1, const WCHAR *str2 )
+{
+ while (*str1 && (*str1 == *str2)) { str1++; str2++; }
+ return *str1 - *str2;
+}
+
+WINE_UNICODE_INLINE int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
+{
+ if (n <= 0) return 0;
+ while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
+ return *str1 - *str2;
+}
+
+WINE_UNICODE_INLINE WCHAR *strcatW( WCHAR *dst, const WCHAR *src )
+{
+ strcpyW( dst + strlenW(dst), src );
+ return dst;
+}
+
+WINE_UNICODE_INLINE WCHAR *strchrW( const WCHAR *str, WCHAR ch )
+{
+ do { if (*str == ch) return (WCHAR *)(ULONG_PTR)str; } while (*str++);
+ return NULL;
+}
+
+WINE_UNICODE_INLINE WCHAR *strrchrW( const WCHAR *str, WCHAR ch )
+{
+ WCHAR *ret = NULL;
+ do { if (*str == ch) ret = (WCHAR *)(ULONG_PTR)str; } while (*str++);
+ return ret;
+}
+
+WINE_UNICODE_INLINE WCHAR *strpbrkW( const WCHAR *str, const WCHAR *accept )
+{
+ for ( ; *str; str++) if (strchrW( accept, *str )) return (WCHAR *)(ULONG_PTR)str;
+ return NULL;
+}
+
+WINE_UNICODE_INLINE size_t strspnW( const WCHAR *str, const WCHAR *accept )
+{
+ const WCHAR *ptr;
+ for (ptr = str; *ptr; ptr++) if (!strchrW( accept, *ptr )) break;
+ return ptr - str;
+}
+
+WINE_UNICODE_INLINE size_t strcspnW( const WCHAR *str, const WCHAR *reject )
+{
+ const WCHAR *ptr;
+ for (ptr = str; *ptr; ptr++) if (strchrW( reject, *ptr )) break;
+ return ptr - str;
+}
+
+WINE_UNICODE_INLINE WCHAR *strlwrW( WCHAR *str )
+{
+ WCHAR *ret;
+ for (ret = str; *str; str++) *str = tolowerW(*str);
+ return ret;
+}
+
+WINE_UNICODE_INLINE WCHAR *struprW( WCHAR *str )
+{
+ WCHAR *ret;
+ for (ret = str; *str; str++) *str = toupperW(*str);
+ return ret;
+}
+
+WINE_UNICODE_INLINE WCHAR *memchrW( const WCHAR *ptr, WCHAR ch, size_t n )
+{
+ const WCHAR *end;
+ for (end = ptr + n; ptr < end; ptr++) if (*ptr == ch) return (WCHAR *)(ULONG_PTR)ptr;
+ return NULL;
+}
+
+WINE_UNICODE_INLINE WCHAR *memrchrW( const WCHAR *ptr, WCHAR ch, size_t n )
+{
+ const WCHAR *end;
+ WCHAR *ret = NULL;
+ for (end = ptr + n; ptr < end; ptr++) if (*ptr == ch) ret = (WCHAR *)(ULONG_PTR)ptr;
+ return ret;
+}
+
+WINE_UNICODE_INLINE long int atolW( const WCHAR *str )
+{
+ return strtolW( str, (WCHAR **)0, 10 );
+}
+
+WINE_UNICODE_INLINE int atoiW( const WCHAR *str )
+{
+ return (int)atolW( str );
+}
+
+#undef WINE_UNICODE_INLINE
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __WINE_WINE_UNICODE_H */
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/wgl.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/wgl.h
new file mode 100644
index 00000000..d3cfc7e2
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/wgl.h
@@ -0,0 +1,5081 @@
+/* Automatically generated from http://www.opengl.org/registry/api files; DO NOT EDIT! */
+
+#ifndef __WINE_WGL_H
+#define __WINE_WGL_H
+
+#ifndef GLAPIENTRY
+#define GLAPIENTRY __stdcall
+#endif
+
+typedef unsigned int GLbitfield;
+typedef unsigned char GLboolean;
+typedef signed char GLbyte;
+typedef char GLchar;
+typedef char GLcharARB;
+typedef double GLclampd;
+typedef float GLclampf;
+typedef double GLdouble;
+typedef unsigned int GLenum;
+typedef float GLfloat;
+typedef unsigned short GLhalfNV;
+typedef unsigned int GLhandleARB;
+typedef int GLint;
+typedef INT64 GLint64;
+typedef INT_PTR GLintptr;
+typedef INT_PTR GLintptrARB;
+typedef short GLshort;
+typedef int GLsizei;
+typedef INT_PTR GLsizeiptr;
+typedef INT_PTR GLsizeiptrARB;
+typedef const unsigned char * GLstring;
+typedef struct __GLsync * GLsync;
+typedef unsigned char GLubyte;
+typedef unsigned int GLuint;
+typedef UINT64 GLuint64;
+typedef unsigned short GLushort;
+typedef INT_PTR GLvdpauSurfaceNV;
+typedef void GLvoid;
+
+#define GL_1PASS_EXT 0x80A1
+#define GL_1PASS_SGIS 0x80A1
+#define GL_2D 0x0600
+#define GL_2PASS_0_EXT 0x80A2
+#define GL_2PASS_0_SGIS 0x80A2
+#define GL_2PASS_1_EXT 0x80A3
+#define GL_2PASS_1_SGIS 0x80A3
+#define GL_2X_BIT_ATI 0x00000001
+#define GL_2_BYTES 0x1407
+#define GL_3D 0x0601
+#define GL_3DC_XY_AMD 0x87FA
+#define GL_3DC_X_AMD 0x87F9
+#define GL_3D_COLOR 0x0602
+#define GL_3D_COLOR_TEXTURE 0x0603
+#define GL_3_BYTES 0x1408
+#define GL_422_AVERAGE_EXT 0x80CE
+#define GL_422_EXT 0x80CC
+#define GL_422_REV_AVERAGE_EXT 0x80CF
+#define GL_422_REV_EXT 0x80CD
+#define GL_4D_COLOR_TEXTURE 0x0604
+#define GL_4PASS_0_EXT 0x80A4
+#define GL_4PASS_0_SGIS 0x80A4
+#define GL_4PASS_1_EXT 0x80A5
+#define GL_4PASS_1_SGIS 0x80A5
+#define GL_4PASS_2_EXT 0x80A6
+#define GL_4PASS_2_SGIS 0x80A6
+#define GL_4PASS_3_EXT 0x80A7
+#define GL_4PASS_3_SGIS 0x80A7
+#define GL_4X_BIT_ATI 0x00000002
+#define GL_4_BYTES 0x1409
+#define GL_8X_BIT_ATI 0x00000004
+#define GL_ABGR_EXT 0x8000
+#define GL_ACCUM 0x0100
+#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD
+#define GL_ACCUM_ALPHA_BITS 0x0D5B
+#define GL_ACCUM_BLUE_BITS 0x0D5A
+#define GL_ACCUM_BUFFER_BIT 0x00000200
+#define GL_ACCUM_CLEAR_VALUE 0x0B80
+#define GL_ACCUM_GREEN_BITS 0x0D59
+#define GL_ACCUM_RED_BITS 0x0D58
+#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define GL_ACTIVE_PROGRAM 0x8259
+#define GL_ACTIVE_PROGRAM_EXT 0x8B8D
+#define GL_ACTIVE_RESOURCES 0x92F5
+#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911
+#define GL_ACTIVE_SUBROUTINES 0x8DE5
+#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48
+#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49
+#define GL_ACTIVE_TEXTURE 0x84E0
+#define GL_ACTIVE_TEXTURE_ARB 0x84E0
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
+#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_ACTIVE_VARIABLES 0x9305
+#define GL_ACTIVE_VARYINGS_NV 0x8C81
+#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82
+#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5
+#define GL_ADD 0x0104
+#define GL_ADD_ATI 0x8963
+#define GL_ADD_BLEND_IMG 0x8C09
+#define GL_ADD_SIGNED 0x8574
+#define GL_ADD_SIGNED_ARB 0x8574
+#define GL_ADD_SIGNED_EXT 0x8574
+#define GL_ADJACENT_PAIRS_NV 0x90AE
+#define GL_AFFINE_2D_NV 0x9092
+#define GL_AFFINE_3D_NV 0x9094
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210
+#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211
+#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E
+#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F
+#define GL_ALL_ATTRIB_BITS 0xFFFFFFFF
+#define GL_ALL_BARRIER_BITS 0xFFFFFFFF
+#define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF
+#define GL_ALL_COMPLETED_NV 0x84F2
+#define GL_ALL_SHADER_BITS 0xFFFFFFFF
+#define GL_ALL_SHADER_BITS_EXT 0xFFFFFFFF
+#define GL_ALPHA 0x1906
+#define GL_ALPHA12 0x803D
+#define GL_ALPHA12_EXT 0x803D
+#define GL_ALPHA16 0x803E
+#define GL_ALPHA16F_ARB 0x881C
+#define GL_ALPHA16I_EXT 0x8D8A
+#define GL_ALPHA16UI_EXT 0x8D78
+#define GL_ALPHA16_EXT 0x803E
+#define GL_ALPHA16_SNORM 0x9018
+#define GL_ALPHA32F_ARB 0x8816
+#define GL_ALPHA32I_EXT 0x8D84
+#define GL_ALPHA32UI_EXT 0x8D72
+#define GL_ALPHA4 0x803B
+#define GL_ALPHA4_EXT 0x803B
+#define GL_ALPHA8 0x803C
+#define GL_ALPHA8I_EXT 0x8D90
+#define GL_ALPHA8UI_EXT 0x8D7E
+#define GL_ALPHA8_EXT 0x803C
+#define GL_ALPHA8_SNORM 0x9014
+#define GL_ALPHA_BIAS 0x0D1D
+#define GL_ALPHA_BITS 0x0D55
+#define GL_ALPHA_FLOAT16_APPLE 0x881C
+#define GL_ALPHA_FLOAT16_ATI 0x881C
+#define GL_ALPHA_FLOAT32_APPLE 0x8816
+#define GL_ALPHA_FLOAT32_ATI 0x8816
+#define GL_ALPHA_INTEGER 0x8D97
+#define GL_ALPHA_INTEGER_EXT 0x8D97
+#define GL_ALPHA_MAX_CLAMP_INGR 0x8567
+#define GL_ALPHA_MAX_SGIX 0x8321
+#define GL_ALPHA_MIN_CLAMP_INGR 0x8563
+#define GL_ALPHA_MIN_SGIX 0x8320
+#define GL_ALPHA_SCALE 0x0D1C
+#define GL_ALPHA_SNORM 0x9010
+#define GL_ALPHA_TEST 0x0BC0
+#define GL_ALPHA_TEST_FUNC 0x0BC1
+#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1
+#define GL_ALPHA_TEST_QCOM 0x0BC0
+#define GL_ALPHA_TEST_REF 0x0BC2
+#define GL_ALPHA_TEST_REF_QCOM 0x0BC2
+#define GL_ALREADY_SIGNALED 0x911A
+#define GL_ALREADY_SIGNALED_APPLE 0x911A
+#define GL_ALWAYS 0x0207
+#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C
+#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D
+#define GL_AMBIENT 0x1200
+#define GL_AMBIENT_AND_DIFFUSE 0x1602
+#define GL_AND 0x1501
+#define GL_AND_INVERTED 0x1504
+#define GL_AND_REVERSE 0x1502
+#define GL_ANY_SAMPLES_PASSED 0x8C2F
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A
+#define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F
+#define GL_ARC_TO_NV 0xFE
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ARRAY_BUFFER_ARB 0x8892
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894
+#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9
+#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8
+#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766
+#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767
+#define GL_ARRAY_SIZE 0x92FB
+#define GL_ARRAY_STRIDE 0x92FE
+#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D
+#define GL_ASYNC_HISTOGRAM_SGIX 0x832C
+#define GL_ASYNC_MARKER_SGIX 0x8329
+#define GL_ASYNC_READ_PIXELS_SGIX 0x835E
+#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C
+#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93
+#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE
+#define GL_ATC_RGB_AMD 0x8C92
+#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000
+#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000
+#define GL_ATOMIC_COUNTER_BUFFER 0x92C0
+#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5
+#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6
+#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1
+#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4
+#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7
+#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3
+#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2
+#define GL_ATTACHED_SHADERS 0x8B85
+#define GL_ATTENUATION_EXT 0x834D
+#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645
+#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623
+#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624
+#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625
+#define GL_ATTRIB_STACK_DEPTH 0x0BB0
+#define GL_AUTO_GENERATE_MIPMAP 0x8295
+#define GL_AUTO_NORMAL 0x0D80
+#define GL_AUX0 0x0409
+#define GL_AUX1 0x040A
+#define GL_AUX2 0x040B
+#define GL_AUX3 0x040C
+#define GL_AUX_BUFFERS 0x0C00
+#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14
+#define GL_AVERAGE_EXT 0x8335
+#define GL_AVERAGE_HP 0x8160
+#define GL_BACK 0x0405
+#define GL_BACK_LEFT 0x0402
+#define GL_BACK_NORMALS_HINT_PGI 0x1A223
+#define GL_BACK_PRIMARY_COLOR_NV 0x8C77
+#define GL_BACK_RIGHT 0x0403
+#define GL_BACK_SECONDARY_COLOR_NV 0x8C78
+#define GL_BEVEL_NV 0x90A6
+#define GL_BGR 0x80E0
+#define GL_BGRA 0x80E1
+#define GL_BGRA_EXT 0x80E1
+#define GL_BGRA_INTEGER 0x8D9B
+#define GL_BGRA_INTEGER_EXT 0x8D9B
+#define GL_BGR_EXT 0x80E0
+#define GL_BGR_INTEGER 0x8D9A
+#define GL_BGR_INTEGER_EXT 0x8D9A
+#define GL_BIAS_BIT_ATI 0x00000008
+#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541
+#define GL_BINNING_CONTROL_HINT_QCOM 0x8FB0
+#define GL_BINORMAL_ARRAY_EXT 0x843A
+#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443
+#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441
+#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440
+#define GL_BITMAP 0x1A00
+#define GL_BITMAP_TOKEN 0x0704
+#define GL_BLEND 0x0BE2
+#define GL_BLEND_COLOR 0x8005
+#define GL_BLEND_COLOR_EXT 0x8005
+#define GL_BLEND_DST 0x0BE0
+#define GL_BLEND_DST_ALPHA 0x80CA
+#define GL_BLEND_DST_ALPHA_EXT 0x80CA
+#define GL_BLEND_DST_ALPHA_OES 0x80CA
+#define GL_BLEND_DST_RGB 0x80C8
+#define GL_BLEND_DST_RGB_EXT 0x80C8
+#define GL_BLEND_DST_RGB_OES 0x80C8
+#define GL_BLEND_EQUATION 0x8009
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D
+#define GL_BLEND_EQUATION_ALPHA_OES 0x883D
+#define GL_BLEND_EQUATION_EXT 0x8009
+#define GL_BLEND_EQUATION_OES 0x8009
+#define GL_BLEND_EQUATION_RGB 0x8009
+#define GL_BLEND_EQUATION_RGB_EXT 0x8009
+#define GL_BLEND_EQUATION_RGB_OES 0x8009
+#define GL_BLEND_SRC 0x0BE1
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#define GL_BLEND_SRC_ALPHA_EXT 0x80CB
+#define GL_BLEND_SRC_ALPHA_OES 0x80CB
+#define GL_BLEND_SRC_RGB 0x80C9
+#define GL_BLEND_SRC_RGB_EXT 0x80C9
+#define GL_BLEND_SRC_RGB_OES 0x80C9
+#define GL_BLOCK_INDEX 0x92FD
+#define GL_BLUE 0x1905
+#define GL_BLUE_BIAS 0x0D1B
+#define GL_BLUE_BITS 0x0D54
+#define GL_BLUE_BIT_ATI 0x00000004
+#define GL_BLUE_INTEGER 0x8D96
+#define GL_BLUE_INTEGER_EXT 0x8D96
+#define GL_BLUE_MAX_CLAMP_INGR 0x8566
+#define GL_BLUE_MIN_CLAMP_INGR 0x8562
+#define GL_BLUE_SCALE 0x0D1A
+#define GL_BOLD_BIT_NV 0x01
+#define GL_BOOL 0x8B56
+#define GL_BOOL_ARB 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC2_ARB 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC3_ARB 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_BOOL_VEC4_ARB 0x8B59
+#define GL_BOUNDING_BOX_NV 0x908D
+#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C
+#define GL_BUFFER 0x82E0
+#define GL_BUFFER_ACCESS 0x88BB
+#define GL_BUFFER_ACCESS_ARB 0x88BB
+#define GL_BUFFER_ACCESS_FLAGS 0x911F
+#define GL_BUFFER_ACCESS_OES 0x88BB
+#define GL_BUFFER_BINDING 0x9302
+#define GL_BUFFER_DATA_SIZE 0x9303
+#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13
+#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D
+#define GL_BUFFER_MAPPED 0x88BC
+#define GL_BUFFER_MAPPED_ARB 0x88BC
+#define GL_BUFFER_MAPPED_OES 0x88BC
+#define GL_BUFFER_MAP_LENGTH 0x9120
+#define GL_BUFFER_MAP_OFFSET 0x9121
+#define GL_BUFFER_MAP_POINTER 0x88BD
+#define GL_BUFFER_MAP_POINTER_ARB 0x88BD
+#define GL_BUFFER_MAP_POINTER_OES 0x88BD
+#define GL_BUFFER_OBJECT_APPLE 0x85B3
+#define GL_BUFFER_OBJECT_EXT 0x9151
+#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_SIZE_ARB 0x8764
+#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200
+#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200
+#define GL_BUFFER_USAGE 0x8765
+#define GL_BUFFER_USAGE_ARB 0x8765
+#define GL_BUFFER_VARIABLE 0x92E5
+#define GL_BUMP_ENVMAP_ATI 0x877B
+#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777
+#define GL_BUMP_ROT_MATRIX_ATI 0x8775
+#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776
+#define GL_BUMP_TARGET_ATI 0x877C
+#define GL_BUMP_TEX_UNITS_ATI 0x8778
+#define GL_BYTE 0x1400
+#define GL_C3F_V3F 0x2A24
+#define GL_C4F_N3F_V3F 0x2A26
+#define GL_C4UB_V2F 0x2A22
+#define GL_C4UB_V3F 0x2A23
+#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183
+#define GL_CAVEAT_SUPPORT 0x82B8
+#define GL_CCW 0x0901
+#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8
+#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA
+#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC
+#define GL_CLAMP 0x2900
+#define GL_CLAMP_FRAGMENT_COLOR 0x891B
+#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B
+#define GL_CLAMP_READ_COLOR 0x891C
+#define GL_CLAMP_READ_COLOR_ARB 0x891C
+#define GL_CLAMP_TO_BORDER 0x812D
+#define GL_CLAMP_TO_BORDER_ARB 0x812D
+#define GL_CLAMP_TO_BORDER_SGIS 0x812D
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_CLAMP_TO_EDGE_SGIS 0x812F
+#define GL_CLAMP_VERTEX_COLOR 0x891A
+#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A
+#define GL_CLEAR 0x1500
+#define GL_CLEAR_BUFFER 0x82B4
+#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1
+#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1
+#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF
+#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1
+#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001
+#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002
+#define GL_CLIP_DISTANCE0 0x3000
+#define GL_CLIP_DISTANCE1 0x3001
+#define GL_CLIP_DISTANCE2 0x3002
+#define GL_CLIP_DISTANCE3 0x3003
+#define GL_CLIP_DISTANCE4 0x3004
+#define GL_CLIP_DISTANCE5 0x3005
+#define GL_CLIP_DISTANCE6 0x3006
+#define GL_CLIP_DISTANCE7 0x3007
+#define GL_CLIP_DISTANCE_NV 0x8C7A
+#define GL_CLIP_FAR_HINT_PGI 0x1A221
+#define GL_CLIP_NEAR_HINT_PGI 0x1A220
+#define GL_CLIP_PLANE0 0x3000
+#define GL_CLIP_PLANE1 0x3001
+#define GL_CLIP_PLANE2 0x3002
+#define GL_CLIP_PLANE3 0x3003
+#define GL_CLIP_PLANE4 0x3004
+#define GL_CLIP_PLANE5 0x3005
+#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0
+#define GL_CLOSE_PATH_NV 0x00
+#define GL_CMYKA_EXT 0x800D
+#define GL_CMYK_EXT 0x800C
+#define GL_CND0_ATI 0x896B
+#define GL_CND_ATI 0x896A
+#define GL_COEFF 0x0A00
+#define GL_COLOR 0x1800
+#define GL_COLOR3_BIT_PGI 0x00010000
+#define GL_COLOR4_BIT_PGI 0x00020000
+#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975
+#define GL_COLOR_ARRAY 0x8076
+#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23
+#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898
+#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898
+#define GL_COLOR_ARRAY_COUNT_EXT 0x8084
+#define GL_COLOR_ARRAY_EXT 0x8076
+#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D
+#define GL_COLOR_ARRAY_LIST_IBM 103072
+#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082
+#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7
+#define GL_COLOR_ARRAY_POINTER 0x8090
+#define GL_COLOR_ARRAY_POINTER_EXT 0x8090
+#define GL_COLOR_ARRAY_SIZE 0x8081
+#define GL_COLOR_ARRAY_SIZE_EXT 0x8081
+#define GL_COLOR_ARRAY_STRIDE 0x8083
+#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083
+#define GL_COLOR_ARRAY_TYPE 0x8082
+#define GL_COLOR_ARRAY_TYPE_EXT 0x8082
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
+#define GL_COLOR_ATTACHMENT0_NV 0x8CE0
+#define GL_COLOR_ATTACHMENT0_OES 0x8CE0
+#define GL_COLOR_ATTACHMENT1 0x8CE1
+#define GL_COLOR_ATTACHMENT10 0x8CEA
+#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
+#define GL_COLOR_ATTACHMENT10_NV 0x8CEA
+#define GL_COLOR_ATTACHMENT11 0x8CEB
+#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
+#define GL_COLOR_ATTACHMENT11_NV 0x8CEB
+#define GL_COLOR_ATTACHMENT12 0x8CEC
+#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
+#define GL_COLOR_ATTACHMENT12_NV 0x8CEC
+#define GL_COLOR_ATTACHMENT13 0x8CED
+#define GL_COLOR_ATTACHMENT13_EXT 0x8CED
+#define GL_COLOR_ATTACHMENT13_NV 0x8CED
+#define GL_COLOR_ATTACHMENT14 0x8CEE
+#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
+#define GL_COLOR_ATTACHMENT14_NV 0x8CEE
+#define GL_COLOR_ATTACHMENT15 0x8CEF
+#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
+#define GL_COLOR_ATTACHMENT15_NV 0x8CEF
+#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
+#define GL_COLOR_ATTACHMENT1_NV 0x8CE1
+#define GL_COLOR_ATTACHMENT2 0x8CE2
+#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
+#define GL_COLOR_ATTACHMENT2_NV 0x8CE2
+#define GL_COLOR_ATTACHMENT3 0x8CE3
+#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
+#define GL_COLOR_ATTACHMENT3_NV 0x8CE3
+#define GL_COLOR_ATTACHMENT4 0x8CE4
+#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
+#define GL_COLOR_ATTACHMENT4_NV 0x8CE4
+#define GL_COLOR_ATTACHMENT5 0x8CE5
+#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
+#define GL_COLOR_ATTACHMENT5_NV 0x8CE5
+#define GL_COLOR_ATTACHMENT6 0x8CE6
+#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
+#define GL_COLOR_ATTACHMENT6_NV 0x8CE6
+#define GL_COLOR_ATTACHMENT7 0x8CE7
+#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
+#define GL_COLOR_ATTACHMENT7_NV 0x8CE7
+#define GL_COLOR_ATTACHMENT8 0x8CE8
+#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
+#define GL_COLOR_ATTACHMENT8_NV 0x8CE8
+#define GL_COLOR_ATTACHMENT9 0x8CE9
+#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
+#define GL_COLOR_ATTACHMENT9_NV 0x8CE9
+#define GL_COLOR_ATTACHMENT_EXT 0x90F0
+#define GL_COLOR_BUFFER_BIT 0x00004000
+#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835
+#define GL_COLOR_CLEAR_VALUE 0x0C22
+#define GL_COLOR_COMPONENTS 0x8283
+#define GL_COLOR_ENCODING 0x8296
+#define GL_COLOR_EXT 0x1800
+#define GL_COLOR_FLOAT_APPLE 0x8A0F
+#define GL_COLOR_INDEX 0x1900
+#define GL_COLOR_INDEX12_EXT 0x80E6
+#define GL_COLOR_INDEX16_EXT 0x80E7
+#define GL_COLOR_INDEX1_EXT 0x80E2
+#define GL_COLOR_INDEX2_EXT 0x80E3
+#define GL_COLOR_INDEX4_EXT 0x80E4
+#define GL_COLOR_INDEX8_EXT 0x80E5
+#define GL_COLOR_INDEXES 0x1603
+#define GL_COLOR_LOGIC_OP 0x0BF2
+#define GL_COLOR_MATERIAL 0x0B57
+#define GL_COLOR_MATERIAL_FACE 0x0B55
+#define GL_COLOR_MATERIAL_PARAMETER 0x0B56
+#define GL_COLOR_MATRIX 0x80B1
+#define GL_COLOR_MATRIX_SGI 0x80B1
+#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2
+#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2
+#define GL_COLOR_RENDERABLE 0x8286
+#define GL_COLOR_SAMPLES_NV 0x8E20
+#define GL_COLOR_SUM 0x8458
+#define GL_COLOR_SUM_ARB 0x8458
+#define GL_COLOR_SUM_CLAMP_NV 0x854F
+#define GL_COLOR_SUM_EXT 0x8458
+#define GL_COLOR_TABLE 0x80D0
+#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD
+#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD
+#define GL_COLOR_TABLE_BIAS 0x80D7
+#define GL_COLOR_TABLE_BIAS_SGI 0x80D7
+#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC
+#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC
+#define GL_COLOR_TABLE_FORMAT 0x80D8
+#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8
+#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB
+#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB
+#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF
+#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF
+#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE
+#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE
+#define GL_COLOR_TABLE_RED_SIZE 0x80DA
+#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA
+#define GL_COLOR_TABLE_SCALE 0x80D6
+#define GL_COLOR_TABLE_SCALE_SGI 0x80D6
+#define GL_COLOR_TABLE_SGI 0x80D0
+#define GL_COLOR_TABLE_WIDTH 0x80D9
+#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9
+#define GL_COLOR_WRITEMASK 0x0C23
+#define GL_COMBINE 0x8570
+#define GL_COMBINE4_NV 0x8503
+#define GL_COMBINER0_NV 0x8550
+#define GL_COMBINER1_NV 0x8551
+#define GL_COMBINER2_NV 0x8552
+#define GL_COMBINER3_NV 0x8553
+#define GL_COMBINER4_NV 0x8554
+#define GL_COMBINER5_NV 0x8555
+#define GL_COMBINER6_NV 0x8556
+#define GL_COMBINER7_NV 0x8557
+#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545
+#define GL_COMBINER_AB_OUTPUT_NV 0x854A
+#define GL_COMBINER_BIAS_NV 0x8549
+#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546
+#define GL_COMBINER_CD_OUTPUT_NV 0x854B
+#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544
+#define GL_COMBINER_INPUT_NV 0x8542
+#define GL_COMBINER_MAPPING_NV 0x8543
+#define GL_COMBINER_MUX_SUM_NV 0x8547
+#define GL_COMBINER_SCALE_NV 0x8548
+#define GL_COMBINER_SUM_OUTPUT_NV 0x854C
+#define GL_COMBINE_ALPHA 0x8572
+#define GL_COMBINE_ALPHA_ARB 0x8572
+#define GL_COMBINE_ALPHA_EXT 0x8572
+#define GL_COMBINE_ARB 0x8570
+#define GL_COMBINE_EXT 0x8570
+#define GL_COMBINE_RGB 0x8571
+#define GL_COMBINE_RGB_ARB 0x8571
+#define GL_COMBINE_RGB_EXT 0x8571
+#define GL_COMMAND_BARRIER_BIT 0x00000040
+#define GL_COMMAND_BARRIER_BIT_EXT 0x00000040
+#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E
+#define GL_COMPARE_REF_TO_TEXTURE 0x884E
+#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E
+#define GL_COMPARE_R_TO_TEXTURE 0x884E
+#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E
+#define GL_COMPATIBLE_SUBROUTINES 0x8E4B
+#define GL_COMPILE 0x1300
+#define GL_COMPILE_AND_EXECUTE 0x1301
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_COMPRESSED_ALPHA 0x84E9
+#define GL_COMPRESSED_ALPHA_ARB 0x84E9
+#define GL_COMPRESSED_INTENSITY 0x84EC
+#define GL_COMPRESSED_INTENSITY_ARB 0x84EC
+#define GL_COMPRESSED_LUMINANCE 0x84EA
+#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB
+#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB
+#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72
+#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA
+#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70
+#define GL_COMPRESSED_R11_EAC 0x9270
+#define GL_COMPRESSED_RED 0x8225
+#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD
+#define GL_COMPRESSED_RED_RGTC1 0x8DBB
+#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB
+#define GL_COMPRESSED_RG 0x8226
+#define GL_COMPRESSED_RG11_EAC 0x9272
+#define GL_COMPRESSED_RGB 0x84ED
+#define GL_COMPRESSED_RGB8_ETC2 0x9274
+#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
+#define GL_COMPRESSED_RGBA 0x84EE
+#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
+#define GL_COMPRESSED_RGBA_ARB 0x84EE
+#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C
+#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1
+#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03
+#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
+#define GL_COMPRESSED_RGB_ARB 0x84ED
+#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E
+#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
+#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0
+#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01
+#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00
+#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
+#define GL_COMPRESSED_RG_RGTC2 0x8DBD
+#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73
+#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71
+#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
+#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE
+#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
+#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC
+#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
+#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
+#define GL_COMPRESSED_SLUMINANCE 0x8C4A
+#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B
+#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B
+#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A
+#define GL_COMPRESSED_SRGB 0x8C48
+#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
+#define GL_COMPRESSED_SRGB8_ETC2 0x9275
+#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
+#define GL_COMPRESSED_SRGB_ALPHA 0x8C49
+#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D
+#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
+#define GL_COMPRESSED_SRGB_EXT 0x8C48
+#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3
+#define GL_COMPUTE_LOCAL_WORK_SIZE 0x8267
+#define GL_COMPUTE_SHADER 0x91B9
+#define GL_COMPUTE_SHADER_BIT 0x00000020
+#define GL_COMPUTE_SUBROUTINE 0x92ED
+#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3
+#define GL_COMPUTE_TEXTURE 0x82A0
+#define GL_COMP_BIT_ATI 0x00000002
+#define GL_CONDITION_SATISFIED 0x911C
+#define GL_CONDITION_SATISFIED_APPLE 0x911C
+#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD
+#define GL_CONSTANT 0x8576
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_CONSTANT_ALPHA_EXT 0x8003
+#define GL_CONSTANT_ARB 0x8576
+#define GL_CONSTANT_ATTENUATION 0x1207
+#define GL_CONSTANT_BORDER 0x8151
+#define GL_CONSTANT_BORDER_HP 0x8151
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_CONSTANT_COLOR0_NV 0x852A
+#define GL_CONSTANT_COLOR1_NV 0x852B
+#define GL_CONSTANT_COLOR_EXT 0x8001
+#define GL_CONSTANT_EXT 0x8576
+#define GL_CONST_EYE_NV 0x86E5
+#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
+#define GL_CONTEXT_FLAGS 0x821E
+#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
+#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
+#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define GL_CONTEXT_PROFILE_MASK 0x9126
+#define GL_CONTINUOUS_AMD 0x9007
+#define GL_CONVEX_HULL_NV 0x908B
+#define GL_CONVOLUTION_1D 0x8010
+#define GL_CONVOLUTION_1D_EXT 0x8010
+#define GL_CONVOLUTION_2D 0x8011
+#define GL_CONVOLUTION_2D_EXT 0x8011
+#define GL_CONVOLUTION_BORDER_COLOR 0x8154
+#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154
+#define GL_CONVOLUTION_BORDER_MODE 0x8013
+#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013
+#define GL_CONVOLUTION_FILTER_BIAS 0x8015
+#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015
+#define GL_CONVOLUTION_FILTER_SCALE 0x8014
+#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014
+#define GL_CONVOLUTION_FORMAT 0x8017
+#define GL_CONVOLUTION_FORMAT_EXT 0x8017
+#define GL_CONVOLUTION_HEIGHT 0x8019
+#define GL_CONVOLUTION_HEIGHT_EXT 0x8019
+#define GL_CONVOLUTION_HINT_SGIX 0x8316
+#define GL_CONVOLUTION_WIDTH 0x8018
+#define GL_CONVOLUTION_WIDTH_EXT 0x8018
+#define GL_CON_0_ATI 0x8941
+#define GL_CON_10_ATI 0x894B
+#define GL_CON_11_ATI 0x894C
+#define GL_CON_12_ATI 0x894D
+#define GL_CON_13_ATI 0x894E
+#define GL_CON_14_ATI 0x894F
+#define GL_CON_15_ATI 0x8950
+#define GL_CON_16_ATI 0x8951
+#define GL_CON_17_ATI 0x8952
+#define GL_CON_18_ATI 0x8953
+#define GL_CON_19_ATI 0x8954
+#define GL_CON_1_ATI 0x8942
+#define GL_CON_20_ATI 0x8955
+#define GL_CON_21_ATI 0x8956
+#define GL_CON_22_ATI 0x8957
+#define GL_CON_23_ATI 0x8958
+#define GL_CON_24_ATI 0x8959
+#define GL_CON_25_ATI 0x895A
+#define GL_CON_26_ATI 0x895B
+#define GL_CON_27_ATI 0x895C
+#define GL_CON_28_ATI 0x895D
+#define GL_CON_29_ATI 0x895E
+#define GL_CON_2_ATI 0x8943
+#define GL_CON_30_ATI 0x895F
+#define GL_CON_31_ATI 0x8960
+#define GL_CON_3_ATI 0x8944
+#define GL_CON_4_ATI 0x8945
+#define GL_CON_5_ATI 0x8946
+#define GL_CON_6_ATI 0x8947
+#define GL_CON_7_ATI 0x8948
+#define GL_CON_8_ATI 0x8949
+#define GL_CON_9_ATI 0x894A
+#define GL_COORD_REPLACE 0x8862
+#define GL_COORD_REPLACE_ARB 0x8862
+#define GL_COORD_REPLACE_NV 0x8862
+#define GL_COPY 0x1503
+#define GL_COPY_INVERTED 0x150C
+#define GL_COPY_PIXEL_TOKEN 0x0706
+#define GL_COPY_READ_BUFFER_BINDING 0x8F36
+#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37
+#define GL_COUNTER_RANGE_AMD 0x8BC1
+#define GL_COUNTER_TYPE_AMD 0x8BC0
+#define GL_COUNT_DOWN_NV 0x9089
+#define GL_COUNT_UP_NV 0x9088
+#define GL_COVERAGE_ALL_FRAGMENTS_NV 0x8ED5
+#define GL_COVERAGE_ATTACHMENT_NV 0x8ED2
+#define GL_COVERAGE_AUTOMATIC_NV 0x8ED7
+#define GL_COVERAGE_BUFFERS_NV 0x8ED3
+#define GL_COVERAGE_BUFFER_BIT_NV 0x00008000
+#define GL_COVERAGE_COMPONENT4_NV 0x8ED1
+#define GL_COVERAGE_COMPONENT_NV 0x8ED0
+#define GL_COVERAGE_EDGE_FRAGMENTS_NV 0x8ED6
+#define GL_COVERAGE_SAMPLES_NV 0x80A9
+#define GL_CPU_OPTIMIZED_QCOM 0x8FB1
+#define GL_CUBIC_CURVE_TO_NV 0x0C
+#define GL_CUBIC_EXT 0x8334
+#define GL_CUBIC_HP 0x815F
+#define GL_CULL_FACE 0x0B44
+#define GL_CULL_FACE_MODE 0x0B45
+#define GL_CULL_FRAGMENT_NV 0x86E7
+#define GL_CULL_MODES_NV 0x86E0
+#define GL_CULL_VERTEX_EXT 0x81AA
+#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB
+#define GL_CULL_VERTEX_IBM 103050
+#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC
+#define GL_CURRENT_ATTRIB_NV 0x8626
+#define GL_CURRENT_BINORMAL_EXT 0x843C
+#define GL_CURRENT_BIT 0x00000001
+#define GL_CURRENT_COLOR 0x0B00
+#define GL_CURRENT_FOG_COORD 0x8453
+#define GL_CURRENT_FOG_COORDINATE 0x8453
+#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453
+#define GL_CURRENT_INDEX 0x0B01
+#define GL_CURRENT_MATRIX_ARB 0x8641
+#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845
+#define GL_CURRENT_MATRIX_NV 0x8641
+#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640
+#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640
+#define GL_CURRENT_NORMAL 0x0B02
+#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865
+#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843
+#define GL_CURRENT_PALETTE_MATRIX_OES 0x8843
+#define GL_CURRENT_PROGRAM 0x8B8D
+#define GL_CURRENT_QUERY 0x8865
+#define GL_CURRENT_QUERY_ARB 0x8865
+#define GL_CURRENT_QUERY_EXT 0x8865
+#define GL_CURRENT_RASTER_COLOR 0x0B04
+#define GL_CURRENT_RASTER_DISTANCE 0x0B09
+#define GL_CURRENT_RASTER_INDEX 0x0B05
+#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406
+#define GL_CURRENT_RASTER_POSITION 0x0B07
+#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08
+#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F
+#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06
+#define GL_CURRENT_SECONDARY_COLOR 0x8459
+#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459
+#define GL_CURRENT_TANGENT_EXT 0x843B
+#define GL_CURRENT_TEXTURE_COORDS 0x0B03
+#define GL_CURRENT_TIME_NV 0x8E28
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626
+#define GL_CURRENT_VERTEX_EXT 0x87E2
+#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B
+#define GL_CURRENT_WEIGHT_ARB 0x86A8
+#define GL_CW 0x0900
+#define GL_DATA_BUFFER_AMD 0x9151
+#define GL_DEBUG_ASSERT_MESA 0x875B
+#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
+#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244
+#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245
+#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245
+#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149
+#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F
+#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B
+#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150
+#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D
+#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E
+#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C
+#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A
+#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D
+#define GL_DEBUG_LOGGED_MESSAGES 0x9145
+#define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145
+#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243
+#define GL_DEBUG_OBJECT_MESA 0x8759
+#define GL_DEBUG_OUTPUT 0x92E0
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242
+#define GL_DEBUG_PRINT_MESA 0x875A
+#define GL_DEBUG_SEVERITY_HIGH 0x9146
+#define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146
+#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146
+#define GL_DEBUG_SEVERITY_LOW 0x9148
+#define GL_DEBUG_SEVERITY_LOW_AMD 0x9148
+#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148
+#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
+#define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147
+#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147
+#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
+#define GL_DEBUG_SOURCE_API 0x8246
+#define GL_DEBUG_SOURCE_API_ARB 0x8246
+#define GL_DEBUG_SOURCE_APPLICATION 0x824A
+#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A
+#define GL_DEBUG_SOURCE_OTHER 0x824B
+#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B
+#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
+#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248
+#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
+#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D
+#define GL_DEBUG_TYPE_ERROR 0x824C
+#define GL_DEBUG_TYPE_ERROR_ARB 0x824C
+#define GL_DEBUG_TYPE_MARKER 0x8268
+#define GL_DEBUG_TYPE_OTHER 0x8251
+#define GL_DEBUG_TYPE_OTHER_ARB 0x8251
+#define GL_DEBUG_TYPE_PERFORMANCE 0x8250
+#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250
+#define GL_DEBUG_TYPE_POP_GROUP 0x826A
+#define GL_DEBUG_TYPE_PORTABILITY 0x824F
+#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F
+#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E
+#define GL_DECAL 0x2101
+#define GL_DECODE_EXT 0x8A49
+#define GL_DECR 0x1E03
+#define GL_DECR_WRAP 0x8508
+#define GL_DECR_WRAP_EXT 0x8508
+#define GL_DECR_WRAP_OES 0x8508
+#define GL_DEFORMATIONS_MASK_SGIX 0x8196
+#define GL_DELETE_STATUS 0x8B80
+#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9
+#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA
+#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858
+#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859
+#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A
+#define GL_DEPTH 0x1801
+#define GL_DEPTH24_STENCIL8 0x88F0
+#define GL_DEPTH24_STENCIL8_EXT 0x88F0
+#define GL_DEPTH24_STENCIL8_OES 0x88F0
+#define GL_DEPTH32F_STENCIL8 0x8CAD
+#define GL_DEPTH32F_STENCIL8_NV 0x8DAC
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#define GL_DEPTH_ATTACHMENT_EXT 0x8D00
+#define GL_DEPTH_ATTACHMENT_OES 0x8D00
+#define GL_DEPTH_BIAS 0x0D1F
+#define GL_DEPTH_BITS 0x0D56
+#define GL_DEPTH_BOUNDS_EXT 0x8891
+#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890
+#define GL_DEPTH_BUFFER_BIT 0x00000100
+#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF
+#define GL_DEPTH_CLAMP 0x864F
+#define GL_DEPTH_CLAMP_FAR_AMD 0x901F
+#define GL_DEPTH_CLAMP_NEAR_AMD 0x901E
+#define GL_DEPTH_CLAMP_NV 0x864F
+#define GL_DEPTH_CLEAR_VALUE 0x0B73
+#define GL_DEPTH_COMPONENT 0x1902
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_DEPTH_COMPONENT16_ARB 0x81A5
+#define GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C
+#define GL_DEPTH_COMPONENT16_OES 0x81A5
+#define GL_DEPTH_COMPONENT16_SGIX 0x81A5
+#define GL_DEPTH_COMPONENT24 0x81A6
+#define GL_DEPTH_COMPONENT24_ARB 0x81A6
+#define GL_DEPTH_COMPONENT24_OES 0x81A6
+#define GL_DEPTH_COMPONENT24_SGIX 0x81A6
+#define GL_DEPTH_COMPONENT32 0x81A7
+#define GL_DEPTH_COMPONENT32F 0x8CAC
+#define GL_DEPTH_COMPONENT32F_NV 0x8DAB
+#define GL_DEPTH_COMPONENT32_ARB 0x81A7
+#define GL_DEPTH_COMPONENT32_OES 0x81A7
+#define GL_DEPTH_COMPONENT32_SGIX 0x81A7
+#define GL_DEPTH_COMPONENTS 0x8284
+#define GL_DEPTH_EXT 0x1801
+#define GL_DEPTH_FUNC 0x0B74
+#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311
+#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312
+#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310
+#define GL_DEPTH_RANGE 0x0B70
+#define GL_DEPTH_RENDERABLE 0x8287
+#define GL_DEPTH_SCALE 0x0D1E
+#define GL_DEPTH_STENCIL 0x84F9
+#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define GL_DEPTH_STENCIL_EXT 0x84F9
+#define GL_DEPTH_STENCIL_MESA 0x8750
+#define GL_DEPTH_STENCIL_NV 0x84F9
+#define GL_DEPTH_STENCIL_OES 0x84F9
+#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA
+#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F
+#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E
+#define GL_DEPTH_TEST 0x0B71
+#define GL_DEPTH_TEXTURE_MODE 0x884B
+#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B
+#define GL_DEPTH_WRITEMASK 0x0B72
+#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096
+#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095
+#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C
+#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A
+#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B
+#define GL_DIFFUSE 0x1201
+#define GL_DISCARD_ATI 0x8763
+#define GL_DISCARD_NV 0x8530
+#define GL_DISCRETE_AMD 0x9006
+#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE
+#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF
+#define GL_DISPLAY_LIST 0x82E7
+#define GL_DISTANCE_ATTENUATION_EXT 0x8129
+#define GL_DISTANCE_ATTENUATION_SGIS 0x8129
+#define GL_DITHER 0x0BD0
+#define GL_DOMAIN 0x0A02
+#define GL_DONT_CARE 0x1100
+#define GL_DOT2_ADD_ATI 0x896C
+#define GL_DOT3_ATI 0x8966
+#define GL_DOT3_RGB 0x86AE
+#define GL_DOT3_RGBA 0x86AF
+#define GL_DOT3_RGBA_ARB 0x86AF
+#define GL_DOT3_RGBA_EXT 0x8741
+#define GL_DOT3_RGBA_IMG 0x86AF
+#define GL_DOT3_RGB_ARB 0x86AE
+#define GL_DOT3_RGB_EXT 0x8740
+#define GL_DOT4_ATI 0x8967
+#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D
+#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3
+#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED
+#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1
+#define GL_DOT_PRODUCT_NV 0x86EC
+#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B
+#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2
+#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C
+#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE
+#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF
+#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0
+#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E
+#define GL_DOUBLE 0x140A
+#define GL_DOUBLEBUFFER 0x0C32
+#define GL_DOUBLE_EXT 0x140A
+#define GL_DOUBLE_MAT2 0x8F46
+#define GL_DOUBLE_MAT2_EXT 0x8F46
+#define GL_DOUBLE_MAT3 0x8F47
+#define GL_DOUBLE_MAT3_EXT 0x8F47
+#define GL_DOUBLE_MAT4 0x8F48
+#define GL_DOUBLE_MAT4_EXT 0x8F48
+#define GL_DOUBLE_VEC2 0x8FFC
+#define GL_DOUBLE_VEC2_EXT 0x8FFC
+#define GL_DOUBLE_VEC3 0x8FFD
+#define GL_DOUBLE_VEC3_EXT 0x8FFD
+#define GL_DOUBLE_VEC4 0x8FFE
+#define GL_DOUBLE_VEC4_EXT 0x8FFE
+#define GL_DRAW_BUFFER 0x0C01
+#define GL_DRAW_BUFFER0 0x8825
+#define GL_DRAW_BUFFER0_ARB 0x8825
+#define GL_DRAW_BUFFER0_ATI 0x8825
+#define GL_DRAW_BUFFER0_NV 0x8825
+#define GL_DRAW_BUFFER1 0x8826
+#define GL_DRAW_BUFFER10 0x882F
+#define GL_DRAW_BUFFER10_ARB 0x882F
+#define GL_DRAW_BUFFER10_ATI 0x882F
+#define GL_DRAW_BUFFER10_NV 0x882F
+#define GL_DRAW_BUFFER11 0x8830
+#define GL_DRAW_BUFFER11_ARB 0x8830
+#define GL_DRAW_BUFFER11_ATI 0x8830
+#define GL_DRAW_BUFFER11_NV 0x8830
+#define GL_DRAW_BUFFER12 0x8831
+#define GL_DRAW_BUFFER12_ARB 0x8831
+#define GL_DRAW_BUFFER12_ATI 0x8831
+#define GL_DRAW_BUFFER12_NV 0x8831
+#define GL_DRAW_BUFFER13 0x8832
+#define GL_DRAW_BUFFER13_ARB 0x8832
+#define GL_DRAW_BUFFER13_ATI 0x8832
+#define GL_DRAW_BUFFER13_NV 0x8832
+#define GL_DRAW_BUFFER14 0x8833
+#define GL_DRAW_BUFFER14_ARB 0x8833
+#define GL_DRAW_BUFFER14_ATI 0x8833
+#define GL_DRAW_BUFFER14_NV 0x8833
+#define GL_DRAW_BUFFER15 0x8834
+#define GL_DRAW_BUFFER15_ARB 0x8834
+#define GL_DRAW_BUFFER15_ATI 0x8834
+#define GL_DRAW_BUFFER15_NV 0x8834
+#define GL_DRAW_BUFFER1_ARB 0x8826
+#define GL_DRAW_BUFFER1_ATI 0x8826
+#define GL_DRAW_BUFFER1_NV 0x8826
+#define GL_DRAW_BUFFER2 0x8827
+#define GL_DRAW_BUFFER2_ARB 0x8827
+#define GL_DRAW_BUFFER2_ATI 0x8827
+#define GL_DRAW_BUFFER2_NV 0x8827
+#define GL_DRAW_BUFFER3 0x8828
+#define GL_DRAW_BUFFER3_ARB 0x8828
+#define GL_DRAW_BUFFER3_ATI 0x8828
+#define GL_DRAW_BUFFER3_NV 0x8828
+#define GL_DRAW_BUFFER4 0x8829
+#define GL_DRAW_BUFFER4_ARB 0x8829
+#define GL_DRAW_BUFFER4_ATI 0x8829
+#define GL_DRAW_BUFFER4_NV 0x8829
+#define GL_DRAW_BUFFER5 0x882A
+#define GL_DRAW_BUFFER5_ARB 0x882A
+#define GL_DRAW_BUFFER5_ATI 0x882A
+#define GL_DRAW_BUFFER5_NV 0x882A
+#define GL_DRAW_BUFFER6 0x882B
+#define GL_DRAW_BUFFER6_ARB 0x882B
+#define GL_DRAW_BUFFER6_ATI 0x882B
+#define GL_DRAW_BUFFER6_NV 0x882B
+#define GL_DRAW_BUFFER7 0x882C
+#define GL_DRAW_BUFFER7_ARB 0x882C
+#define GL_DRAW_BUFFER7_ATI 0x882C
+#define GL_DRAW_BUFFER7_NV 0x882C
+#define GL_DRAW_BUFFER8 0x882D
+#define GL_DRAW_BUFFER8_ARB 0x882D
+#define GL_DRAW_BUFFER8_ATI 0x882D
+#define GL_DRAW_BUFFER8_NV 0x882D
+#define GL_DRAW_BUFFER9 0x882E
+#define GL_DRAW_BUFFER9_ARB 0x882E
+#define GL_DRAW_BUFFER9_ATI 0x882E
+#define GL_DRAW_BUFFER9_NV 0x882E
+#define GL_DRAW_BUFFER_EXT 0x0C01
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6
+#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9
+#define GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41
+#define GL_DRAW_INDIRECT_BUFFER 0x8F3F
+#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43
+#define GL_DRAW_INDIRECT_LENGTH_NV 0x8F42
+#define GL_DRAW_INDIRECT_UNIFIED_NV 0x8F40
+#define GL_DRAW_PIXELS_APPLE 0x8A0A
+#define GL_DRAW_PIXEL_TOKEN 0x0705
+#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B
+#define GL_DSDT8_MAG8_NV 0x870A
+#define GL_DSDT8_NV 0x8709
+#define GL_DSDT_MAG_INTENSITY_NV 0x86DC
+#define GL_DSDT_MAG_NV 0x86F6
+#define GL_DSDT_MAG_VIB_NV 0x86F7
+#define GL_DSDT_NV 0x86F5
+#define GL_DST_ALPHA 0x0304
+#define GL_DST_COLOR 0x0306
+#define GL_DS_BIAS_NV 0x8716
+#define GL_DS_SCALE_NV 0x8710
+#define GL_DT_BIAS_NV 0x8717
+#define GL_DT_SCALE_NV 0x8711
+#define GL_DU8DV8_ATI 0x877A
+#define GL_DUAL_ALPHA12_SGIS 0x8112
+#define GL_DUAL_ALPHA16_SGIS 0x8113
+#define GL_DUAL_ALPHA4_SGIS 0x8110
+#define GL_DUAL_ALPHA8_SGIS 0x8111
+#define GL_DUAL_INTENSITY12_SGIS 0x811A
+#define GL_DUAL_INTENSITY16_SGIS 0x811B
+#define GL_DUAL_INTENSITY4_SGIS 0x8118
+#define GL_DUAL_INTENSITY8_SGIS 0x8119
+#define GL_DUAL_LUMINANCE12_SGIS 0x8116
+#define GL_DUAL_LUMINANCE16_SGIS 0x8117
+#define GL_DUAL_LUMINANCE4_SGIS 0x8114
+#define GL_DUAL_LUMINANCE8_SGIS 0x8115
+#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C
+#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D
+#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124
+#define GL_DUDV_ATI 0x8779
+#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2
+#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4
+#define GL_DYNAMIC_ATI 0x8761
+#define GL_DYNAMIC_COPY 0x88EA
+#define GL_DYNAMIC_COPY_ARB 0x88EA
+#define GL_DYNAMIC_DRAW 0x88E8
+#define GL_DYNAMIC_DRAW_ARB 0x88E8
+#define GL_DYNAMIC_READ 0x88E9
+#define GL_DYNAMIC_READ_ARB 0x88E9
+#define GL_EDGEFLAG_BIT_PGI 0x00040000
+#define GL_EDGE_FLAG 0x0B43
+#define GL_EDGE_FLAG_ARRAY 0x8079
+#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26
+#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B
+#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B
+#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D
+#define GL_EDGE_FLAG_ARRAY_EXT 0x8079
+#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30
+#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075
+#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085
+#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093
+#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093
+#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C
+#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C
+#define GL_EIGHTH_BIT_ATI 0x00000020
+#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29
+#define GL_ELEMENT_ARRAY_APPLE 0x8A0C
+#define GL_ELEMENT_ARRAY_ATI 0x8768
+#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002
+#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
+#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33
+#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E
+#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A
+#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D
+#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769
+#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F
+#define GL_EMBOSS_CONSTANT_NV 0x855E
+#define GL_EMBOSS_LIGHT_NV 0x855D
+#define GL_EMBOSS_MAP_NV 0x855F
+#define GL_EMISSION 0x1600
+#define GL_ENABLE_BIT 0x00002000
+#define GL_EQUAL 0x0202
+#define GL_EQUIV 0x1509
+#define GL_ETC1_RGB8_OES 0x8D64
+#define GL_EVAL_2D_NV 0x86C0
+#define GL_EVAL_BIT 0x00010000
+#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5
+#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1
+#define GL_EVAL_VERTEX_ATRRIB0_NV 0x86C6
+#define GL_EVAL_VERTEX_ATRRIB10_NV 0x86D0
+#define GL_EVAL_VERTEX_ATRRIB11_NV 0x86D1
+#define GL_EVAL_VERTEX_ATRRIB12_NV 0x86D2
+#define GL_EVAL_VERTEX_ATRRIB13_NV 0x86D3
+#define GL_EVAL_VERTEX_ATRRIB14_NV 0x86D4
+#define GL_EVAL_VERTEX_ATRRIB15_NV 0x86D5
+#define GL_EVAL_VERTEX_ATRRIB1_NV 0x86C7
+#define GL_EVAL_VERTEX_ATRRIB2_NV 0x86C8
+#define GL_EVAL_VERTEX_ATRRIB3_NV 0x86C9
+#define GL_EVAL_VERTEX_ATRRIB4_NV 0x86CA
+#define GL_EVAL_VERTEX_ATRRIB5_NV 0x86CB
+#define GL_EVAL_VERTEX_ATRRIB6_NV 0x86CC
+#define GL_EVAL_VERTEX_ATRRIB7_NV 0x86CD
+#define GL_EVAL_VERTEX_ATRRIB8_NV 0x86CE
+#define GL_EVAL_VERTEX_ATRRIB9_NV 0x86CF
+#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6
+#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0
+#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1
+#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2
+#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3
+#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4
+#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5
+#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7
+#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8
+#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9
+#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA
+#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB
+#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC
+#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD
+#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE
+#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF
+#define GL_EXP 0x0800
+#define GL_EXP2 0x0801
+#define GL_EXPAND_NEGATE_NV 0x8539
+#define GL_EXPAND_NORMAL_NV 0x8538
+#define GL_EXTENSIONS 0x1F03
+#define GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD 0x9160
+#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2
+#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0
+#define GL_EYE_LINEAR 0x2400
+#define GL_EYE_LINE_SGIS 0x81F6
+#define GL_EYE_PLANE 0x2502
+#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C
+#define GL_EYE_POINT_SGIS 0x81F4
+#define GL_EYE_RADIAL_NV 0x855B
+#define GL_E_TIMES_F_NV 0x8531
+#define GL_FACTOR_ALPHA_MODULATE_IMG 0x8C07
+#define GL_FACTOR_MAX_AMD 0x901D
+#define GL_FACTOR_MIN_AMD 0x901C
+#define GL_FAILURE_NV 0x9030
+#define GL_FALSE 0
+#define GL_FASTEST 0x1101
+#define GL_FEEDBACK 0x1C01
+#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0
+#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1
+#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2
+#define GL_FENCE_APPLE 0x8A0B
+#define GL_FENCE_CONDITION_NV 0x84F4
+#define GL_FENCE_STATUS_NV 0x84F3
+#define GL_FIELDS_NV 0x8E27
+#define GL_FIELD_LOWER_NV 0x9023
+#define GL_FIELD_UPPER_NV 0x9022
+#define GL_FILE_NAME_NV 0x9074
+#define GL_FILL 0x1B02
+#define GL_FILTER 0x829A
+#define GL_FILTER4_SGIS 0x8146
+#define GL_FIRST_TO_REST_NV 0x90AF
+#define GL_FIRST_VERTEX_CONVENTION 0x8E4D
+#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D
+#define GL_FIXED 0x140C
+#define GL_FIXED_OES 0x140C
+#define GL_FIXED_ONLY 0x891D
+#define GL_FIXED_ONLY_ARB 0x891D
+#define GL_FLAT 0x1D00
+#define GL_FLOAT 0x1406
+#define GL_FLOAT16_NV 0x8FF8
+#define GL_FLOAT16_VEC2_NV 0x8FF9
+#define GL_FLOAT16_VEC3_NV 0x8FFA
+#define GL_FLOAT16_VEC4_NV 0x8FFB
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD
+#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT2_ARB 0x8B5A
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT3_ARB 0x8B5B
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_FLOAT_MAT4_ARB 0x8B5C
+#define GL_FLOAT_R16_NV 0x8884
+#define GL_FLOAT_R32_NV 0x8885
+#define GL_FLOAT_RG16_NV 0x8886
+#define GL_FLOAT_RG32_NV 0x8887
+#define GL_FLOAT_RGB16_NV 0x8888
+#define GL_FLOAT_RGB32_NV 0x8889
+#define GL_FLOAT_RGBA16_NV 0x888A
+#define GL_FLOAT_RGBA32_NV 0x888B
+#define GL_FLOAT_RGBA_MODE_NV 0x888E
+#define GL_FLOAT_RGBA_NV 0x8883
+#define GL_FLOAT_RGB_NV 0x8882
+#define GL_FLOAT_RG_NV 0x8881
+#define GL_FLOAT_R_NV 0x8880
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC2_ARB 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC3_ARB 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_FLOAT_VEC4_ARB 0x8B52
+#define GL_FOG 0x0B60
+#define GL_FOG_BIT 0x00000080
+#define GL_FOG_COLOR 0x0B66
+#define GL_FOG_COORD 0x8451
+#define GL_FOG_COORDINATE 0x8451
+#define GL_FOG_COORDINATE_ARRAY 0x8457
+#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D
+#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D
+#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457
+#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076
+#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086
+#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456
+#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456
+#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455
+#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455
+#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454
+#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454
+#define GL_FOG_COORDINATE_EXT 0x8451
+#define GL_FOG_COORDINATE_SOURCE 0x8450
+#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450
+#define GL_FOG_COORD_ARRAY 0x8457
+#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28
+#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D
+#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32
+#define GL_FOG_COORD_ARRAY_POINTER 0x8456
+#define GL_FOG_COORD_ARRAY_STRIDE 0x8455
+#define GL_FOG_COORD_ARRAY_TYPE 0x8454
+#define GL_FOG_COORD_SRC 0x8450
+#define GL_FOG_DENSITY 0x0B62
+#define GL_FOG_DISTANCE_MODE_NV 0x855A
+#define GL_FOG_END 0x0B64
+#define GL_FOG_FACTOR_TO_ALPHA_SGIX 0x836F
+#define GL_FOG_FUNC_POINTS_SGIS 0x812B
+#define GL_FOG_FUNC_SGIS 0x812A
+#define GL_FOG_GEN_MODE_NV 0x855A
+#define GL_FOG_HINT 0x0C54
+#define GL_FOG_INDEX 0x0B61
+#define GL_FOG_MODE 0x0B65
+#define GL_FOG_OFFSET_SGIX 0x8198
+#define GL_FOG_OFFSET_VALUE_SGIX 0x8199
+#define GL_FOG_SCALE_SGIX 0x81FC
+#define GL_FOG_SCALE_VALUE_SGIX 0x81FD
+#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC
+#define GL_FOG_START 0x0B63
+#define GL_FONT_ASCENDER_NV 0x00200000
+#define GL_FONT_DESCENDER_NV 0x00400000
+#define GL_FONT_HAS_KERNING_NV 0x10000000
+#define GL_FONT_HEIGHT_NV 0x00800000
+#define GL_FONT_MAX_ADVANCE_HEIGHT_NV 0x02000000
+#define GL_FONT_MAX_ADVANCE_WIDTH_NV 0x01000000
+#define GL_FONT_UNDERLINE_POSITION_NV 0x04000000
+#define GL_FONT_UNDERLINE_THICKNESS_NV 0x08000000
+#define GL_FONT_UNITS_PER_EM_NV 0x00100000
+#define GL_FONT_X_MAX_BOUNDS_NV 0x00040000
+#define GL_FONT_X_MIN_BOUNDS_NV 0x00010000
+#define GL_FONT_Y_MAX_BOUNDS_NV 0x00080000
+#define GL_FONT_Y_MIN_BOUNDS_NV 0x00020000
+#define GL_FORCE_BLUE_TO_ONE_NV 0x8860
+#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983
+#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982
+#define GL_FRACTIONAL_EVEN 0x8E7C
+#define GL_FRACTIONAL_ODD 0x8E7B
+#define GL_FRAGMENTS_INSTRUMENT_COUNTERS_SGIX 0x8314
+#define GL_FRAGMENTS_INSTRUMENT_MAX_SGIX 0x8315
+#define GL_FRAGMENTS_INSTRUMENT_SGIX 0x8313
+#define GL_FRAGMENT_ALPHA_MODULATE_IMG 0x8C08
+#define GL_FRAGMENT_COLOR_EXT 0x834C
+#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402
+#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403
+#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401
+#define GL_FRAGMENT_DEPTH 0x8452
+#define GL_FRAGMENT_DEPTH_EXT 0x8452
+#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D
+#define GL_FRAGMENT_LIGHT0_SGIX 0x840C
+#define GL_FRAGMENT_LIGHT1_SGIX 0x840D
+#define GL_FRAGMENT_LIGHT2_SGIX 0x840E
+#define GL_FRAGMENT_LIGHT3_SGIX 0x840F
+#define GL_FRAGMENT_LIGHT4_SGIX 0x8410
+#define GL_FRAGMENT_LIGHT5_SGIX 0x8411
+#define GL_FRAGMENT_LIGHT6_SGIX 0x8412
+#define GL_FRAGMENT_LIGHT7_SGIX 0x8413
+#define GL_FRAGMENT_LIGHTING_SGIX 0x8400
+#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A
+#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408
+#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B
+#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409
+#define GL_FRAGMENT_MATERIAL_EXT 0x8349
+#define GL_FRAGMENT_NORMAL_EXT 0x834A
+#define GL_FRAGMENT_PROGRAM_ARB 0x8804
+#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873
+#define GL_FRAGMENT_PROGRAM_CALLBACK_DATA_MESA 0x8BB3
+#define GL_FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA 0x8BB2
+#define GL_FRAGMENT_PROGRAM_CALLBACK_MESA 0x8BB1
+#define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D
+#define GL_FRAGMENT_PROGRAM_NV 0x8870
+#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4
+#define GL_FRAGMENT_PROGRAM_POSITION_MESA 0x8BB0
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_FRAGMENT_SHADER_ARB 0x8B30
+#define GL_FRAGMENT_SHADER_ATI 0x8920
+#define GL_FRAGMENT_SHADER_BIT 0x00000002
+#define GL_FRAGMENT_SHADER_BIT_EXT 0x00000002
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B
+#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52
+#define GL_FRAGMENT_SUBROUTINE 0x92EC
+#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2
+#define GL_FRAGMENT_TEXTURE 0x829F
+#define GL_FRAMEBUFFER 0x8D40
+#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
+#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3
+#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211
+#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
+#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
+#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES 0x8CD3
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C
+#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400
+#define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_FRAMEBUFFER_BINDING_ANGLE 0x8CA6
+#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6
+#define GL_FRAMEBUFFER_BINDING_OES 0x8CA6
+#define GL_FRAMEBUFFER_BLEND 0x828B
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
+#define GL_FRAMEBUFFER_COMPLETE_OES 0x8CD5
+#define GL_FRAMEBUFFER_DEFAULT 0x8218
+#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314
+#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311
+#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312
+#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313
+#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310
+#define GL_FRAMEBUFFER_EXT 0x8D40
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES 0x8CD9
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA
+#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES 0x8CDA
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES 0x8CDC
+#define GL_FRAMEBUFFER_OES 0x8D40
+#define GL_FRAMEBUFFER_RENDERABLE 0x8289
+#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A
+#define GL_FRAMEBUFFER_SRGB 0x8DB9
+#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA
+#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
+#define GL_FRAMEBUFFER_UNDEFINED 0x8219
+#define GL_FRAMEBUFFER_UNDEFINED_OES 0x8219
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD
+#define GL_FRAMEBUFFER_UNSUPPORTED_OES 0x8CDD
+#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C
+#define GL_FRAMEZOOM_SGIX 0x818B
+#define GL_FRAME_NV 0x8E26
+#define GL_FRONT 0x0404
+#define GL_FRONT_AND_BACK 0x0408
+#define GL_FRONT_FACE 0x0B46
+#define GL_FRONT_LEFT 0x0400
+#define GL_FRONT_RIGHT 0x0401
+#define GL_FULL_RANGE_EXT 0x87E1
+#define GL_FULL_STIPPLE_HINT_PGI 0x1A219
+#define GL_FULL_SUPPORT 0x82B7
+#define GL_FUNC_ADD 0x8006
+#define GL_FUNC_ADD_EXT 0x8006
+#define GL_FUNC_ADD_OES 0x8006
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B
+#define GL_FUNC_REVERSE_SUBTRACT_OES 0x800B
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_FUNC_SUBTRACT_EXT 0x800A
+#define GL_FUNC_SUBTRACT_OES 0x800A
+#define GL_GCCSO_SHADER_BINARY_FJ 0x9260
+#define GL_GENERATE_MIPMAP 0x8191
+#define GL_GENERATE_MIPMAP_HINT 0x8192
+#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192
+#define GL_GENERATE_MIPMAP_SGIS 0x8191
+#define GL_GENERIC_ATTRIB_NV 0x8C7D
+#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002
+#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194
+#define GL_GEOMETRY_INPUT_TYPE 0x8917
+#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB
+#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB
+#define GL_GEOMETRY_OUTPUT_TYPE 0x8918
+#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC
+#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC
+#define GL_GEOMETRY_PROGRAM_NV 0x8C26
+#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3
+#define GL_GEOMETRY_SHADER 0x8DD9
+#define GL_GEOMETRY_SHADER_ARB 0x8DD9
+#define GL_GEOMETRY_SHADER_BIT 0x00000004
+#define GL_GEOMETRY_SHADER_EXT 0x8DD9
+#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F
+#define GL_GEOMETRY_SUBROUTINE 0x92EB
+#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1
+#define GL_GEOMETRY_TEXTURE 0x829E
+#define GL_GEOMETRY_VERTICES_OUT 0x8916
+#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA
+#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA
+#define GL_GEQUAL 0x0206
+#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291
+#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292
+#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA
+#define GL_GLOBAL_ALPHA_SUN 0x81D9
+#define GL_GLYPH_HAS_KERNING_NV 0x100
+#define GL_GLYPH_HEIGHT_BIT_NV 0x02
+#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10
+#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04
+#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08
+#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80
+#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20
+#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40
+#define GL_GLYPH_WIDTH_BIT_NV 0x01
+#define GL_GPU_ADDRESS_NV 0x8F34
+#define GL_GPU_OPTIMIZED_QCOM 0x8FB2
+#define GL_GREATER 0x0204
+#define GL_GREEN 0x1904
+#define GL_GREEN_BIAS 0x0D19
+#define GL_GREEN_BITS 0x0D53
+#define GL_GREEN_BIT_ATI 0x00000002
+#define GL_GREEN_INTEGER 0x8D95
+#define GL_GREEN_INTEGER_EXT 0x8D95
+#define GL_GREEN_MAX_CLAMP_INGR 0x8565
+#define GL_GREEN_MIN_CLAMP_INGR 0x8561
+#define GL_GREEN_SCALE 0x0D18
+#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253
+#define GL_HALF_APPLE 0x140B
+#define GL_HALF_BIAS_NEGATE_NV 0x853B
+#define GL_HALF_BIAS_NORMAL_NV 0x853A
+#define GL_HALF_BIT_ATI 0x00000008
+#define GL_HALF_FLOAT 0x140B
+#define GL_HALF_FLOAT_ARB 0x140B
+#define GL_HALF_FLOAT_NV 0x140B
+#define GL_HALF_FLOAT_OES 0x8D61
+#define GL_HIGH_FLOAT 0x8DF2
+#define GL_HIGH_INT 0x8DF5
+#define GL_HILO16_NV 0x86F8
+#define GL_HILO8_NV 0x885E
+#define GL_HILO_NV 0x86F4
+#define GL_HINT_BIT 0x00008000
+#define GL_HISTOGRAM 0x8024
+#define GL_HISTOGRAM_ALPHA_SIZE 0x802B
+#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B
+#define GL_HISTOGRAM_BLUE_SIZE 0x802A
+#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A
+#define GL_HISTOGRAM_EXT 0x8024
+#define GL_HISTOGRAM_FORMAT 0x8027
+#define GL_HISTOGRAM_FORMAT_EXT 0x8027
+#define GL_HISTOGRAM_GREEN_SIZE 0x8029
+#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029
+#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C
+#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C
+#define GL_HISTOGRAM_RED_SIZE 0x8028
+#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028
+#define GL_HISTOGRAM_SINK 0x802D
+#define GL_HISTOGRAM_SINK_EXT 0x802D
+#define GL_HISTOGRAM_WIDTH 0x8026
+#define GL_HISTOGRAM_WIDTH_EXT 0x8026
+#define GL_HI_BIAS_NV 0x8714
+#define GL_HI_SCALE_NV 0x870E
+#define GL_HORIZONTAL_LINE_TO_NV 0x06
+#define GL_IDENTITY_NV 0x862A
+#define GL_IGNORE_BORDER_HP 0x8150
+#define GL_IMAGE_1D 0x904C
+#define GL_IMAGE_1D_ARRAY 0x9052
+#define GL_IMAGE_1D_ARRAY_EXT 0x9052
+#define GL_IMAGE_1D_EXT 0x904C
+#define GL_IMAGE_2D 0x904D
+#define GL_IMAGE_2D_ARRAY 0x9053
+#define GL_IMAGE_2D_ARRAY_EXT 0x9053
+#define GL_IMAGE_2D_EXT 0x904D
+#define GL_IMAGE_2D_MULTISAMPLE 0x9055
+#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056
+#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056
+#define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055
+#define GL_IMAGE_2D_RECT 0x904F
+#define GL_IMAGE_2D_RECT_EXT 0x904F
+#define GL_IMAGE_3D 0x904E
+#define GL_IMAGE_3D_EXT 0x904E
+#define GL_IMAGE_BINDING_ACCESS 0x8F3E
+#define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E
+#define GL_IMAGE_BINDING_FORMAT 0x906E
+#define GL_IMAGE_BINDING_FORMAT_EXT 0x906E
+#define GL_IMAGE_BINDING_LAYER 0x8F3D
+#define GL_IMAGE_BINDING_LAYERED 0x8F3C
+#define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C
+#define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D
+#define GL_IMAGE_BINDING_LEVEL 0x8F3B
+#define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B
+#define GL_IMAGE_BINDING_NAME 0x8F3A
+#define GL_IMAGE_BINDING_NAME_EXT 0x8F3A
+#define GL_IMAGE_BUFFER 0x9051
+#define GL_IMAGE_BUFFER_EXT 0x9051
+#define GL_IMAGE_CLASS_10_10_10_2 0x82C3
+#define GL_IMAGE_CLASS_11_11_10 0x82C2
+#define GL_IMAGE_CLASS_1_X_16 0x82BE
+#define GL_IMAGE_CLASS_1_X_32 0x82BB
+#define GL_IMAGE_CLASS_1_X_8 0x82C1
+#define GL_IMAGE_CLASS_2_X_16 0x82BD
+#define GL_IMAGE_CLASS_2_X_32 0x82BA
+#define GL_IMAGE_CLASS_2_X_8 0x82C0
+#define GL_IMAGE_CLASS_4_X_16 0x82BC
+#define GL_IMAGE_CLASS_4_X_32 0x82B9
+#define GL_IMAGE_CLASS_4_X_8 0x82BF
+#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8
+#define GL_IMAGE_CUBE 0x9050
+#define GL_IMAGE_CUBE_EXT 0x9050
+#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054
+#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054
+#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8
+#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7
+#define GL_IMAGE_MAG_FILTER_HP 0x815C
+#define GL_IMAGE_MIN_FILTER_HP 0x815D
+#define GL_IMAGE_PIXEL_FORMAT 0x82A9
+#define GL_IMAGE_PIXEL_TYPE 0x82AA
+#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159
+#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A
+#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B
+#define GL_IMAGE_SCALE_X_HP 0x8155
+#define GL_IMAGE_SCALE_Y_HP 0x8156
+#define GL_IMAGE_TEXEL_SIZE 0x82A7
+#define GL_IMAGE_TRANSFORM_2D_HP 0x8161
+#define GL_IMAGE_TRANSLATE_X_HP 0x8157
+#define GL_IMAGE_TRANSLATE_Y_HP 0x8158
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A
+#define GL_INCR 0x1E02
+#define GL_INCR_WRAP 0x8507
+#define GL_INCR_WRAP_EXT 0x8507
+#define GL_INCR_WRAP_OES 0x8507
+#define GL_INDEX 0x8222
+#define GL_INDEX_ARRAY 0x8077
+#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24
+#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899
+#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899
+#define GL_INDEX_ARRAY_COUNT_EXT 0x8087
+#define GL_INDEX_ARRAY_EXT 0x8077
+#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E
+#define GL_INDEX_ARRAY_LIST_IBM 103073
+#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083
+#define GL_INDEX_ARRAY_POINTER 0x8091
+#define GL_INDEX_ARRAY_POINTER_EXT 0x8091
+#define GL_INDEX_ARRAY_STRIDE 0x8086
+#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086
+#define GL_INDEX_ARRAY_TYPE 0x8085
+#define GL_INDEX_ARRAY_TYPE_EXT 0x8085
+#define GL_INDEX_BITS 0x0D51
+#define GL_INDEX_BIT_PGI 0x00080000
+#define GL_INDEX_CLEAR_VALUE 0x0C20
+#define GL_INDEX_LOGIC_OP 0x0BF1
+#define GL_INDEX_MATERIAL_EXT 0x81B8
+#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA
+#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9
+#define GL_INDEX_MODE 0x0C30
+#define GL_INDEX_OFFSET 0x0D13
+#define GL_INDEX_SHIFT 0x0D12
+#define GL_INDEX_TEST_EXT 0x81B5
+#define GL_INDEX_TEST_FUNC_EXT 0x81B6
+#define GL_INDEX_TEST_REF_EXT 0x81B7
+#define GL_INDEX_WRITEMASK 0x0C21
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254
+#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180
+#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181
+#define GL_INT 0x1404
+#define GL_INT16_NV 0x8FE4
+#define GL_INT16_VEC2_NV 0x8FE5
+#define GL_INT16_VEC3_NV 0x8FE6
+#define GL_INT16_VEC4_NV 0x8FE7
+#define GL_INT64_NV 0x140E
+#define GL_INT64_VEC2_NV 0x8FE9
+#define GL_INT64_VEC3_NV 0x8FEA
+#define GL_INT64_VEC4_NV 0x8FEB
+#define GL_INT8_NV 0x8FE0
+#define GL_INT8_VEC2_NV 0x8FE1
+#define GL_INT8_VEC3_NV 0x8FE2
+#define GL_INT8_VEC4_NV 0x8FE3
+#define GL_INTENSITY 0x8049
+#define GL_INTENSITY12 0x804C
+#define GL_INTENSITY12_EXT 0x804C
+#define GL_INTENSITY16 0x804D
+#define GL_INTENSITY16F_ARB 0x881D
+#define GL_INTENSITY16I_EXT 0x8D8B
+#define GL_INTENSITY16UI_EXT 0x8D79
+#define GL_INTENSITY16_EXT 0x804D
+#define GL_INTENSITY16_SNORM 0x901B
+#define GL_INTENSITY32F_ARB 0x8817
+#define GL_INTENSITY32I_EXT 0x8D85
+#define GL_INTENSITY32UI_EXT 0x8D73
+#define GL_INTENSITY4 0x804A
+#define GL_INTENSITY4_EXT 0x804A
+#define GL_INTENSITY8 0x804B
+#define GL_INTENSITY8I_EXT 0x8D91
+#define GL_INTENSITY8UI_EXT 0x8D7F
+#define GL_INTENSITY8_EXT 0x804B
+#define GL_INTENSITY8_SNORM 0x9017
+#define GL_INTENSITY_EXT 0x8049
+#define GL_INTENSITY_FLOAT16_APPLE 0x881D
+#define GL_INTENSITY_FLOAT16_ATI 0x881D
+#define GL_INTENSITY_FLOAT32_APPLE 0x8817
+#define GL_INTENSITY_FLOAT32_ATI 0x8817
+#define GL_INTENSITY_SNORM 0x9013
+#define GL_INTERLACE_OML 0x8980
+#define GL_INTERLACE_READ_INGR 0x8568
+#define GL_INTERLACE_READ_OML 0x8981
+#define GL_INTERLACE_SGIX 0x8094
+#define GL_INTERLEAVED_ATTRIBS 0x8C8C
+#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C
+#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C
+#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274
+#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B
+#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273
+#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A
+#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275
+#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C
+#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272
+#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279
+#define GL_INTERNALFORMAT_PREFERRED 0x8270
+#define GL_INTERNALFORMAT_RED_SIZE 0x8271
+#define GL_INTERNALFORMAT_RED_TYPE 0x8278
+#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277
+#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276
+#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D
+#define GL_INTERNALFORMAT_SUPPORTED 0x826F
+#define GL_INTERPOLATE 0x8575
+#define GL_INTERPOLATE_ARB 0x8575
+#define GL_INTERPOLATE_EXT 0x8575
+#define GL_INT_10_10_10_2_OES 0x8DF7
+#define GL_INT_2_10_10_10_REV 0x8D9F
+#define GL_INT_IMAGE_1D 0x9057
+#define GL_INT_IMAGE_1D_ARRAY 0x905D
+#define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D
+#define GL_INT_IMAGE_1D_EXT 0x9057
+#define GL_INT_IMAGE_2D 0x9058
+#define GL_INT_IMAGE_2D_ARRAY 0x905E
+#define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E
+#define GL_INT_IMAGE_2D_EXT 0x9058
+#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060
+#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061
+#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061
+#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060
+#define GL_INT_IMAGE_2D_RECT 0x905A
+#define GL_INT_IMAGE_2D_RECT_EXT 0x905A
+#define GL_INT_IMAGE_3D 0x9059
+#define GL_INT_IMAGE_3D_EXT 0x9059
+#define GL_INT_IMAGE_BUFFER 0x905C
+#define GL_INT_IMAGE_BUFFER_EXT 0x905C
+#define GL_INT_IMAGE_CUBE 0x905B
+#define GL_INT_IMAGE_CUBE_EXT 0x905B
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F
+#define GL_INT_SAMPLER_1D 0x8DC9
+#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE
+#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE
+#define GL_INT_SAMPLER_1D_EXT 0x8DC9
+#define GL_INT_SAMPLER_2D 0x8DCA
+#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
+#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF
+#define GL_INT_SAMPLER_2D_EXT 0x8DCA
+#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109
+#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C
+#define GL_INT_SAMPLER_2D_RECT 0x8DCD
+#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD
+#define GL_INT_SAMPLER_3D 0x8DCB
+#define GL_INT_SAMPLER_3D_EXT 0x8DCB
+#define GL_INT_SAMPLER_BUFFER 0x8DD0
+#define GL_INT_SAMPLER_BUFFER_AMD 0x9002
+#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0
+#define GL_INT_SAMPLER_CUBE 0x8DCC
+#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E
+#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC2_ARB 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC3_ARB 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_INT_VEC4_ARB 0x8B55
+#define GL_INVALID_ENUM 0x0500
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
+#define GL_INVALID_FRAMEBUFFER_OPERATION_OES 0x0506
+#define GL_INVALID_INDEX 0xFFFFFFFFu
+#define GL_INVALID_OPERATION 0x0502
+#define GL_INVALID_VALUE 0x0501
+#define GL_INVARIANT_DATATYPE_EXT 0x87EB
+#define GL_INVARIANT_EXT 0x87C2
+#define GL_INVARIANT_VALUE_EXT 0x87EA
+#define GL_INVERSE_NV 0x862B
+#define GL_INVERSE_TRANSPOSE_NV 0x862D
+#define GL_INVERT 0x150A
+#define GL_INVERTED_SCREEN_W_REND 0x8491
+#define GL_IR_INSTRUMENT1_SGIX 0x817F
+#define GL_ISOLINES 0x8E7A
+#define GL_IS_PER_PATCH 0x92E7
+#define GL_IS_ROW_MAJOR 0x9300
+#define GL_ITALIC_BIT_NV 0x02
+#define GL_IUI_N3F_V2F_EXT 0x81AF
+#define GL_IUI_N3F_V3F_EXT 0x81B0
+#define GL_IUI_V2F_EXT 0x81AD
+#define GL_IUI_V3F_EXT 0x81AE
+#define GL_KEEP 0x1E00
+#define GL_LARGE_CCW_ARC_TO_NV 0x16
+#define GL_LARGE_CW_ARC_TO_NV 0x18
+#define GL_LAST_VERTEX_CONVENTION 0x8E4E
+#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E
+#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027
+#define GL_LAYER_NV 0x8DAA
+#define GL_LAYER_PROVOKING_VERTEX 0x825E
+#define GL_LEFT 0x0406
+#define GL_LEQUAL 0x0203
+#define GL_LERP_ATI 0x8969
+#define GL_LESS 0x0201
+#define GL_LIGHT0 0x4000
+#define GL_LIGHT1 0x4001
+#define GL_LIGHT2 0x4002
+#define GL_LIGHT3 0x4003
+#define GL_LIGHT4 0x4004
+#define GL_LIGHT5 0x4005
+#define GL_LIGHT6 0x4006
+#define GL_LIGHT7 0x4007
+#define GL_LIGHTING 0x0B50
+#define GL_LIGHTING_BIT 0x00000040
+#define GL_LIGHT_ENV_MODE_SGIX 0x8407
+#define GL_LIGHT_MODEL_AMBIENT 0x0B53
+#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
+#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8
+#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
+#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0
+#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52
+#define GL_LINE 0x1B01
+#define GL_LINEAR 0x2601
+#define GL_LINEAR_ATTENUATION 0x1208
+#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170
+#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F
+#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098
+#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099
+#define GL_LINEAR_DETAIL_SGIS 0x8097
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+#define GL_LINEAR_MIPMAP_NEAREST 0x2701
+#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE
+#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF
+#define GL_LINEAR_SHARPEN_SGIS 0x80AD
+#define GL_LINES 0x0001
+#define GL_LINES_ADJACENCY 0x000A
+#define GL_LINES_ADJACENCY_ARB 0x000A
+#define GL_LINES_ADJACENCY_EXT 0x000A
+#define GL_LINE_BIT 0x00000004
+#define GL_LINE_LOOP 0x0002
+#define GL_LINE_QUALITY_HINT_SGIX 0x835B
+#define GL_LINE_RESET_TOKEN 0x0707
+#define GL_LINE_SMOOTH 0x0B20
+#define GL_LINE_SMOOTH_HINT 0x0C52
+#define GL_LINE_STIPPLE 0x0B24
+#define GL_LINE_STIPPLE_PATTERN 0x0B25
+#define GL_LINE_STIPPLE_REPEAT 0x0B26
+#define GL_LINE_STRIP 0x0003
+#define GL_LINE_STRIP_ADJACENCY 0x000B
+#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B
+#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B
+#define GL_LINE_TOKEN 0x0702
+#define GL_LINE_TO_NV 0x04
+#define GL_LINE_WIDTH 0x0B21
+#define GL_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_LINE_WIDTH_RANGE 0x0B22
+#define GL_LINK_STATUS 0x8B82
+#define GL_LIST_BASE 0x0B32
+#define GL_LIST_BIT 0x00020000
+#define GL_LIST_INDEX 0x0B33
+#define GL_LIST_MODE 0x0B30
+#define GL_LIST_PRIORITY_SGIX 0x8182
+#define GL_LOAD 0x0101
+#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED
+#define GL_LOCAL_CONSTANT_EXT 0x87C3
+#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC
+#define GL_LOCAL_EXT 0x87C4
+#define GL_LOCATION 0x930E
+#define GL_LOCATION_INDEX 0x930F
+#define GL_LOGIC_OP 0x0BF1
+#define GL_LOGIC_OP_MODE 0x0BF0
+#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define GL_LOWER_LEFT 0x8CA1
+#define GL_LOW_FLOAT 0x8DF0
+#define GL_LOW_INT 0x8DF3
+#define GL_LO_BIAS_NV 0x8715
+#define GL_LO_SCALE_NV 0x870F
+#define GL_LUMINANCE 0x1909
+#define GL_LUMINANCE12 0x8041
+#define GL_LUMINANCE12_ALPHA12 0x8047
+#define GL_LUMINANCE12_ALPHA12_EXT 0x8047
+#define GL_LUMINANCE12_ALPHA4 0x8046
+#define GL_LUMINANCE12_ALPHA4_EXT 0x8046
+#define GL_LUMINANCE12_EXT 0x8041
+#define GL_LUMINANCE16 0x8042
+#define GL_LUMINANCE16F_ARB 0x881E
+#define GL_LUMINANCE16I_EXT 0x8D8C
+#define GL_LUMINANCE16UI_EXT 0x8D7A
+#define GL_LUMINANCE16_ALPHA16 0x8048
+#define GL_LUMINANCE16_ALPHA16_EXT 0x8048
+#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A
+#define GL_LUMINANCE16_EXT 0x8042
+#define GL_LUMINANCE16_SNORM 0x9019
+#define GL_LUMINANCE32F_ARB 0x8818
+#define GL_LUMINANCE32I_EXT 0x8D86
+#define GL_LUMINANCE32UI_EXT 0x8D74
+#define GL_LUMINANCE4 0x803F
+#define GL_LUMINANCE4_ALPHA4 0x8043
+#define GL_LUMINANCE4_ALPHA4_EXT 0x8043
+#define GL_LUMINANCE4_EXT 0x803F
+#define GL_LUMINANCE6_ALPHA2 0x8044
+#define GL_LUMINANCE6_ALPHA2_EXT 0x8044
+#define GL_LUMINANCE8 0x8040
+#define GL_LUMINANCE8I_EXT 0x8D92
+#define GL_LUMINANCE8UI_EXT 0x8D80
+#define GL_LUMINANCE8_ALPHA8 0x8045
+#define GL_LUMINANCE8_ALPHA8_EXT 0x8045
+#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016
+#define GL_LUMINANCE8_EXT 0x8040
+#define GL_LUMINANCE8_SNORM 0x9015
+#define GL_LUMINANCE_ALPHA 0x190A
+#define GL_LUMINANCE_ALPHA16F_ARB 0x881F
+#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D
+#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B
+#define GL_LUMINANCE_ALPHA32F_ARB 0x8819
+#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87
+#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75
+#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93
+#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81
+#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F
+#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F
+#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819
+#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819
+#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D
+#define GL_LUMINANCE_ALPHA_SNORM 0x9012
+#define GL_LUMINANCE_FLOAT16_APPLE 0x881E
+#define GL_LUMINANCE_FLOAT16_ATI 0x881E
+#define GL_LUMINANCE_FLOAT32_APPLE 0x8818
+#define GL_LUMINANCE_FLOAT32_ATI 0x8818
+#define GL_LUMINANCE_INTEGER_EXT 0x8D9C
+#define GL_LUMINANCE_SNORM 0x9011
+#define GL_MAD_ATI 0x8968
+#define GL_MAGNITUDE_BIAS_NV 0x8718
+#define GL_MAGNITUDE_SCALE_NV 0x8712
+#define GL_MAJOR_VERSION 0x821B
+#define GL_MALI_SHADER_BINARY_ARM 0x8F60
+#define GL_MANUAL_GENERATE_MIPMAP 0x8294
+#define GL_MAP1_BINORMAL_EXT 0x8446
+#define GL_MAP1_COLOR_4 0x0D90
+#define GL_MAP1_GRID_DOMAIN 0x0DD0
+#define GL_MAP1_GRID_SEGMENTS 0x0DD1
+#define GL_MAP1_INDEX 0x0D91
+#define GL_MAP1_NORMAL 0x0D92
+#define GL_MAP1_TANGENT_EXT 0x8444
+#define GL_MAP1_TEXTURE_COORD_1 0x0D93
+#define GL_MAP1_TEXTURE_COORD_2 0x0D94
+#define GL_MAP1_TEXTURE_COORD_3 0x0D95
+#define GL_MAP1_TEXTURE_COORD_4 0x0D96
+#define GL_MAP1_VERTEX_3 0x0D97
+#define GL_MAP1_VERTEX_4 0x0D98
+#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660
+#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A
+#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B
+#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C
+#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D
+#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E
+#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F
+#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661
+#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662
+#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663
+#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664
+#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665
+#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666
+#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667
+#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668
+#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669
+#define GL_MAP2_BINORMAL_EXT 0x8447
+#define GL_MAP2_COLOR_4 0x0DB0
+#define GL_MAP2_GRID_DOMAIN 0x0DD2
+#define GL_MAP2_GRID_SEGMENTS 0x0DD3
+#define GL_MAP2_INDEX 0x0DB1
+#define GL_MAP2_NORMAL 0x0DB2
+#define GL_MAP2_TANGENT_EXT 0x8445
+#define GL_MAP2_TEXTURE_COORD_1 0x0DB3
+#define GL_MAP2_TEXTURE_COORD_2 0x0DB4
+#define GL_MAP2_TEXTURE_COORD_3 0x0DB5
+#define GL_MAP2_TEXTURE_COORD_4 0x0DB6
+#define GL_MAP2_VERTEX_3 0x0DB7
+#define GL_MAP2_VERTEX_4 0x0DB8
+#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670
+#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A
+#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B
+#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C
+#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D
+#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E
+#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F
+#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671
+#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672
+#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673
+#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674
+#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675
+#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676
+#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677
+#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678
+#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679
+#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3
+#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4
+#define GL_MAP_COLOR 0x0D10
+#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
+#define GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010
+#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
+#define GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008
+#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
+#define GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_READ_BIT_EXT 0x0001
+#define GL_MAP_STENCIL 0x0D11
+#define GL_MAP_TESSELLATION_NV 0x86C2
+#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
+#define GL_MAP_UNSYNCHRONIZED_BIT_EXT 0x0020
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAP_WRITE_BIT_EXT 0x0002
+#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C
+#define GL_MATRIX0_ARB 0x88C0
+#define GL_MATRIX0_NV 0x8630
+#define GL_MATRIX10_ARB 0x88CA
+#define GL_MATRIX11_ARB 0x88CB
+#define GL_MATRIX12_ARB 0x88CC
+#define GL_MATRIX13_ARB 0x88CD
+#define GL_MATRIX14_ARB 0x88CE
+#define GL_MATRIX15_ARB 0x88CF
+#define GL_MATRIX16_ARB 0x88D0
+#define GL_MATRIX17_ARB 0x88D1
+#define GL_MATRIX18_ARB 0x88D2
+#define GL_MATRIX19_ARB 0x88D3
+#define GL_MATRIX1_ARB 0x88C1
+#define GL_MATRIX1_NV 0x8631
+#define GL_MATRIX20_ARB 0x88D4
+#define GL_MATRIX21_ARB 0x88D5
+#define GL_MATRIX22_ARB 0x88D6
+#define GL_MATRIX23_ARB 0x88D7
+#define GL_MATRIX24_ARB 0x88D8
+#define GL_MATRIX25_ARB 0x88D9
+#define GL_MATRIX26_ARB 0x88DA
+#define GL_MATRIX27_ARB 0x88DB
+#define GL_MATRIX28_ARB 0x88DC
+#define GL_MATRIX29_ARB 0x88DD
+#define GL_MATRIX2_ARB 0x88C2
+#define GL_MATRIX2_NV 0x8632
+#define GL_MATRIX30_ARB 0x88DE
+#define GL_MATRIX31_ARB 0x88DF
+#define GL_MATRIX3_ARB 0x88C3
+#define GL_MATRIX3_NV 0x8633
+#define GL_MATRIX4_ARB 0x88C4
+#define GL_MATRIX4_NV 0x8634
+#define GL_MATRIX5_ARB 0x88C5
+#define GL_MATRIX5_NV 0x8635
+#define GL_MATRIX6_ARB 0x88C6
+#define GL_MATRIX6_NV 0x8636
+#define GL_MATRIX7_ARB 0x88C7
+#define GL_MATRIX7_NV 0x8637
+#define GL_MATRIX8_ARB 0x88C8
+#define GL_MATRIX9_ARB 0x88C9
+#define GL_MATRIX_EXT 0x87C0
+#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844
+#define GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES 0x8B9E
+#define GL_MATRIX_INDEX_ARRAY_OES 0x8844
+#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849
+#define GL_MATRIX_INDEX_ARRAY_POINTER_OES 0x8849
+#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846
+#define GL_MATRIX_INDEX_ARRAY_SIZE_OES 0x8846
+#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848
+#define GL_MATRIX_INDEX_ARRAY_STRIDE_OES 0x8848
+#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847
+#define GL_MATRIX_INDEX_ARRAY_TYPE_OES 0x8847
+#define GL_MATRIX_MODE 0x0BA0
+#define GL_MATRIX_PALETTE_ARB 0x8840
+#define GL_MATRIX_PALETTE_OES 0x8840
+#define GL_MATRIX_STRIDE 0x92FF
+#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000
+#define GL_MAT_AMBIENT_BIT_PGI 0x00100000
+#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000
+#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000
+#define GL_MAT_EMISSION_BIT_PGI 0x00800000
+#define GL_MAT_SHININESS_BIT_PGI 0x02000000
+#define GL_MAT_SPECULAR_BIT_PGI 0x04000000
+#define GL_MAX 0x8008
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073
+#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073
+#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138
+#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405
+#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
+#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF
+#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360
+#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D
+#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361
+#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8
+#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35
+#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED
+#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B
+#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177
+#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178
+#define GL_MAX_CLIP_DISTANCES 0x0D32
+#define GL_MAX_CLIP_PLANES 0x0D32
+#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
+#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
+#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF
+#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3
+#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3
+#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E
+#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7
+#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1
+#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266
+#define GL_MAX_COMBINED_DIMENSIONS 0x8282
+#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
+#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32
+#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF
+#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39
+#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39
+#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC
+#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E
+#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D
+#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
+#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
+#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265
+#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264
+#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD
+#define GL_MAX_COMPUTE_LOCAL_INVOCATIONS 0x90EB
+#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB
+#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262
+#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC
+#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB
+#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263
+#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE
+#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF
+#define GL_MAX_CONVOLUTION_HEIGHT 0x801B
+#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B
+#define GL_MAX_CONVOLUTION_WIDTH 0x801A
+#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES 0x851C
+#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
+#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
+#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144
+#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144
+#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
+#define GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143
+#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143
+#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197
+#define GL_MAX_DEPTH 0x8280
+#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F
+#define GL_MAX_DRAW_BUFFERS 0x8824
+#define GL_MAX_DRAW_BUFFERS_ARB 0x8824
+#define GL_MAX_DRAW_BUFFERS_ATI 0x8824
+#define GL_MAX_DRAW_BUFFERS_NV 0x8824
+#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC
+#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9
+#define GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8
+#define GL_MAX_ELEMENT_INDEX 0x8D6B
+#define GL_MAX_EVAL_ORDER 0x0D30
+#define GL_MAX_EXT 0x8008
+#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0
+#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3
+#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C
+#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404
+#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868
+#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA
+#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316
+#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317
+#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318
+#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315
+#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D
+#define GL_MAX_GENERAL_COMBINERS_NV 0x854D
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF
+#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4
+#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0
+#define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A
+#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A
+#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1
+#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF
+#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD
+#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD
+#define GL_MAX_HEIGHT 0x827F
+#define GL_MAX_IMAGE_SAMPLES 0x906D
+#define GL_MAX_IMAGE_SAMPLES_EXT 0x906D
+#define GL_MAX_IMAGE_UNITS 0x8F38
+#define GL_MAX_IMAGE_UNITS_EXT 0x8F38
+#define GL_MAX_INTEGER_SAMPLES 0x9110
+#define GL_MAX_LABEL_LENGTH 0x82E8
+#define GL_MAX_LAYERS 0x8281
+#define GL_MAX_LIGHTS 0x0D31
+#define GL_MAX_LIST_NESTING 0x0B31
+#define GL_MAX_MAP_TESSELLATION_NV 0x86D6
+#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841
+#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36
+#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11
+#define GL_MAX_MULTIVIEW_BUFFERS_EXT 0x90F2
+#define GL_MAX_NAME_LENGTH 0x92F6
+#define GL_MAX_NAME_STACK_DEPTH 0x0D37
+#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7
+#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB
+#define GL_MAX_PALETTE_MATRICES_ARB 0x8842
+#define GL_MAX_PALETTE_MATRICES_OES 0x8842
+#define GL_MAX_PATCH_VERTICES 0x8E7D
+#define GL_MAX_PIXEL_MAP_TABLE 0x0D34
+#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337
+#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1
+#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1
+#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B
+#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD
+#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908
+#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5
+#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5
+#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4
+#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5
+#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6
+#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6
+#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1
+#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4
+#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8
+#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7
+#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F
+#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E
+#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3
+#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E
+#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF
+#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3
+#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB
+#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7
+#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810
+#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F
+#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27
+#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9
+#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0
+#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1
+#define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8
+#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909
+#define GL_MAX_PROGRAM_SUBROUTINE_NUM_NV 0x8F45
+#define GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV 0x8F44
+#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5
+#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
+#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS 0x8F9F
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5F
+#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D
+#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C
+#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28
+#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38
+#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
+#define GL_MAX_RENDERBUFFER_SIZE_OES 0x84E8
+#define GL_MAX_SAMPLES 0x8D57
+#define GL_MAX_SAMPLES_ANGLE 0x8D57
+#define GL_MAX_SAMPLES_EXT 0x8D57
+#define GL_MAX_SAMPLES_IMG 0x9135
+#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
+#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59
+#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
+#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111
+#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35
+#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE
+#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD
+#define GL_MAX_SHININESS_NV 0x8504
+#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD 0x9199
+#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS 0x919A
+#define GL_MAX_SPARSE_TEXTURE_SIZE_AMD 0x9198
+#define GL_MAX_SPOT_EXPONENT_NV 0x8505
+#define GL_MAX_SUBROUTINES 0x8DE7
+#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD
+#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB
+#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C
+#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83
+#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8
+#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81
+#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85
+#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89
+#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE
+#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC
+#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D
+#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86
+#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9
+#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82
+#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A
+#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80
+#define GL_MAX_TESS_GEN_LEVEL 0x8E7E
+#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84
+#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B
+#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B
+#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B
+#define GL_MAX_TEXTURE_COORDS 0x8871
+#define GL_MAX_TEXTURE_COORDS_ARB 0x8871
+#define GL_MAX_TEXTURE_COORDS_NV 0x8871
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872
+#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872
+#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
+#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
+#define GL_MAX_TEXTURE_SIZE 0x0D33
+#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39
+#define GL_MAX_TEXTURE_UNITS 0x84E2
+#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2
+#define GL_MAX_TRACK_MATRICES_NV 0x862F
+#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E
+#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
+#define GL_MAX_UNIFORM_LOCATIONS 0x826E
+#define GL_MAX_VARYING_COMPONENTS 0x8B4B
+#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B
+#define GL_MAX_VARYING_FLOATS 0x8B4B
+#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B
+#define GL_MAX_VARYING_VECTORS 0x8DFC
+#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520
+#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2
+#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869
+#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA
+#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9
+#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2
+#define GL_MAX_VERTEX_HINT_PGI 0x1A22D
+#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
+#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5
+#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7
+#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9
+#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8
+#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6
+#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6
+#define GL_MAX_VERTEX_STREAMS 0x8E71
+#define GL_MAX_VERTEX_STREAMS_ATI 0x876B
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C
+#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A
+#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#define GL_MAX_VERTEX_UNITS_ARB 0x86A4
+#define GL_MAX_VERTEX_UNITS_OES 0x86A4
+#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE
+#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE
+#define GL_MAX_VIEWPORTS 0x825B
+#define GL_MAX_VIEWPORT_DIMS 0x0D3A
+#define GL_MAX_WIDTH 0x827E
+#define GL_MEDIUM_FLOAT 0x8DF1
+#define GL_MEDIUM_INT 0x8DF4
+#define GL_MIN 0x8007
+#define GL_MINMAX 0x802E
+#define GL_MINMAX_EXT 0x802E
+#define GL_MINMAX_FORMAT 0x802F
+#define GL_MINMAX_FORMAT_EXT 0x802F
+#define GL_MINMAX_SINK 0x8030
+#define GL_MINMAX_SINK_EXT 0x8030
+#define GL_MINOR_VERSION 0x821C
+#define GL_MIN_EXT 0x8007
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B
+#define GL_MIN_LOD_WARNING_AMD 0x919C
+#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC
+#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
+#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5E
+#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37
+#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37
+#define GL_MIN_SPARSE_LEVEL_AMD 0x919B
+#define GL_MIPMAP 0x8293
+#define GL_MIRRORED_REPEAT 0x8370
+#define GL_MIRRORED_REPEAT_ARB 0x8370
+#define GL_MIRRORED_REPEAT_IBM 0x8370
+#define GL_MIRRORED_REPEAT_OES 0x8370
+#define GL_MIRROR_CLAMP_ATI 0x8742
+#define GL_MIRROR_CLAMP_EXT 0x8742
+#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912
+#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743
+#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743
+#define GL_MITER_REVERT_NV 0x90A7
+#define GL_MITER_TRUNCATE_NV 0x90A8
+#define GL_MODELVIEW 0x1700
+#define GL_MODELVIEW0_ARB 0x1700
+#define GL_MODELVIEW10_ARB 0x872A
+#define GL_MODELVIEW11_ARB 0x872B
+#define GL_MODELVIEW12_ARB 0x872C
+#define GL_MODELVIEW13_ARB 0x872D
+#define GL_MODELVIEW14_ARB 0x872E
+#define GL_MODELVIEW15_ARB 0x872F
+#define GL_MODELVIEW16_ARB 0x8730
+#define GL_MODELVIEW17_ARB 0x8731
+#define GL_MODELVIEW18_ARB 0x8732
+#define GL_MODELVIEW19_ARB 0x8733
+#define GL_MODELVIEW1_ARB 0x850A
+#define GL_MODELVIEW1_EXT 0x850A
+#define GL_MODELVIEW1_MATRIX_EXT 0x8506
+#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502
+#define GL_MODELVIEW20_ARB 0x8734
+#define GL_MODELVIEW21_ARB 0x8735
+#define GL_MODELVIEW22_ARB 0x8736
+#define GL_MODELVIEW23_ARB 0x8737
+#define GL_MODELVIEW24_ARB 0x8738
+#define GL_MODELVIEW25_ARB 0x8739
+#define GL_MODELVIEW26_ARB 0x873A
+#define GL_MODELVIEW27_ARB 0x873B
+#define GL_MODELVIEW28_ARB 0x873C
+#define GL_MODELVIEW29_ARB 0x873D
+#define GL_MODELVIEW2_ARB 0x8722
+#define GL_MODELVIEW30_ARB 0x873E
+#define GL_MODELVIEW31_ARB 0x873F
+#define GL_MODELVIEW3_ARB 0x8723
+#define GL_MODELVIEW4_ARB 0x8724
+#define GL_MODELVIEW5_ARB 0x8725
+#define GL_MODELVIEW6_ARB 0x8726
+#define GL_MODELVIEW7_ARB 0x8727
+#define GL_MODELVIEW8_ARB 0x8728
+#define GL_MODELVIEW9_ARB 0x8729
+#define GL_MODELVIEW_MATRIX 0x0BA6
+#define GL_MODELVIEW_MATRIX1_EXT 0x8506
+#define GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES 0x898D
+#define GL_MODELVIEW_PROJECTION_NV 0x8629
+#define GL_MODELVIEW_STACK_DEPTH 0x0BA3
+#define GL_MODULATE 0x2100
+#define GL_MODULATE_ADD_ATI 0x8744
+#define GL_MODULATE_COLOR_IMG 0x8C04
+#define GL_MODULATE_SIGNED_ADD_ATI 0x8745
+#define GL_MODULATE_SUBTRACT_ATI 0x8746
+#define GL_MOVE_TO_CONTINUES_NV 0x90B6
+#define GL_MOVE_TO_NV 0x02
+#define GL_MOVE_TO_RESETS_NV 0x90B5
+#define GL_MOV_ATI 0x8961
+#define GL_MULT 0x0103
+#define GL_MULTISAMPLE 0x809D
+#define GL_MULTISAMPLE_3DFX 0x86B2
+#define GL_MULTISAMPLE_ARB 0x809D
+#define GL_MULTISAMPLE_BIT 0x20000000
+#define GL_MULTISAMPLE_BIT_3DFX 0x20000000
+#define GL_MULTISAMPLE_BIT_ARB 0x20000000
+#define GL_MULTISAMPLE_BIT_EXT 0x20000000
+#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12
+#define GL_MULTISAMPLE_EXT 0x809D
+#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534
+#define GL_MULTISAMPLE_SGIS 0x809D
+#define GL_MULTIVIEW_EXT 0x90F1
+#define GL_MULTI_HULLS_NV 0x908C
+#define GL_MUL_ATI 0x8964
+#define GL_MVP_MATRIX_EXT 0x87E3
+#define GL_N3F_V3F 0x2A25
+#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9
+#define GL_NAMED_STRING_TYPE_ARB 0x8DEA
+#define GL_NAME_LENGTH 0x92F9
+#define GL_NAME_STACK_DEPTH 0x0D70
+#define GL_NAND 0x150E
+#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203
+#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204
+#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202
+#define GL_NEAREST 0x2600
+#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E
+#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D
+#define GL_NEAREST_MIPMAP_LINEAR 0x2702
+#define GL_NEAREST_MIPMAP_NEAREST 0x2700
+#define GL_NEGATE_BIT_ATI 0x00000004
+#define GL_NEGATIVE_ONE_EXT 0x87DF
+#define GL_NEGATIVE_W_EXT 0x87DC
+#define GL_NEGATIVE_X_EXT 0x87D9
+#define GL_NEGATIVE_Y_EXT 0x87DA
+#define GL_NEGATIVE_Z_EXT 0x87DB
+#define GL_NEVER 0x0200
+#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025
+#define GL_NICEST 0x1102
+#define GL_NONE 0
+#define GL_NOOP 0x1505
+#define GL_NOR 0x1508
+#define GL_NORMALIZE 0x0BA1
+#define GL_NORMALIZED_RANGE_EXT 0x87E0
+#define GL_NORMAL_ARRAY 0x8075
+#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22
+#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897
+#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897
+#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080
+#define GL_NORMAL_ARRAY_EXT 0x8075
+#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C
+#define GL_NORMAL_ARRAY_LIST_IBM 103071
+#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081
+#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6
+#define GL_NORMAL_ARRAY_POINTER 0x808F
+#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F
+#define GL_NORMAL_ARRAY_STRIDE 0x807F
+#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F
+#define GL_NORMAL_ARRAY_TYPE 0x807E
+#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E
+#define GL_NORMAL_BIT_PGI 0x08000000
+#define GL_NORMAL_MAP 0x8511
+#define GL_NORMAL_MAP_ARB 0x8511
+#define GL_NORMAL_MAP_EXT 0x8511
+#define GL_NORMAL_MAP_NV 0x8511
+#define GL_NORMAL_MAP_OES 0x8511
+#define GL_NOTEQUAL 0x0205
+#define GL_NO_ERROR 0
+#define GL_NO_RESET_NOTIFICATION_ARB 0x8261
+#define GL_NUM_ACTIVE_VARIABLES 0x9304
+#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2
+#define GL_NUM_EXTENSIONS 0x821D
+#define GL_NUM_FILL_STREAMS_NV 0x8E29
+#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F
+#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E
+#define GL_NUM_GENERAL_COMBINERS_NV 0x854E
+#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973
+#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971
+#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972
+#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974
+#define GL_NUM_PASSES_ATI 0x8970
+#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
+#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE
+#define GL_NUM_SAMPLE_COUNTS 0x9380
+#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9
+#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024
+#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89
+#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A
+#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86
+#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87
+#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85
+#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764
+#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765
+#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81
+#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80
+#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3
+#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1
+#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84
+#define GL_OBJECT_LINEAR 0x2401
+#define GL_OBJECT_LINE_SGIS 0x81F7
+#define GL_OBJECT_LINK_STATUS_ARB 0x8B82
+#define GL_OBJECT_PLANE 0x2501
+#define GL_OBJECT_POINT_SGIS 0x81F5
+#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88
+#define GL_OBJECT_SUBTYPE_ARB 0x8B4F
+#define GL_OBJECT_TYPE 0x9112
+#define GL_OBJECT_TYPE_APPLE 0x9112
+#define GL_OBJECT_TYPE_ARB 0x8B4E
+#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83
+#define GL_OCCLUSION_TEST_HP 0x8165
+#define GL_OCCLUSION_TEST_RESULT_HP 0x8166
+#define GL_OFFSET 0x92FC
+#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856
+#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857
+#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854
+#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855
+#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850
+#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851
+#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852
+#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853
+#define GL_OFFSET_TEXTURE_2D_NV 0x86E8
+#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3
+#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1
+#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C
+#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D
+#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2
+#define GL_ONE 1
+#define GL_ONE_EXT 0x87DE
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002
+#define GL_ONE_MINUS_DST_ALPHA 0x0305
+#define GL_ONE_MINUS_DST_COLOR 0x0307
+#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB
+#define GL_ONE_MINUS_SRC1_COLOR 0x88FA
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_ONE_MINUS_SRC_COLOR 0x0301
+#define GL_OPERAND0_ALPHA 0x8598
+#define GL_OPERAND0_ALPHA_ARB 0x8598
+#define GL_OPERAND0_ALPHA_EXT 0x8598
+#define GL_OPERAND0_RGB 0x8590
+#define GL_OPERAND0_RGB_ARB 0x8590
+#define GL_OPERAND0_RGB_EXT 0x8590
+#define GL_OPERAND1_ALPHA 0x8599
+#define GL_OPERAND1_ALPHA_ARB 0x8599
+#define GL_OPERAND1_ALPHA_EXT 0x8599
+#define GL_OPERAND1_RGB 0x8591
+#define GL_OPERAND1_RGB_ARB 0x8591
+#define GL_OPERAND1_RGB_EXT 0x8591
+#define GL_OPERAND2_ALPHA 0x859A
+#define GL_OPERAND2_ALPHA_ARB 0x859A
+#define GL_OPERAND2_ALPHA_EXT 0x859A
+#define GL_OPERAND2_RGB 0x8592
+#define GL_OPERAND2_RGB_ARB 0x8592
+#define GL_OPERAND2_RGB_EXT 0x8592
+#define GL_OPERAND3_ALPHA_NV 0x859B
+#define GL_OPERAND3_RGB_NV 0x8593
+#define GL_OP_ADD_EXT 0x8787
+#define GL_OP_CLAMP_EXT 0x878E
+#define GL_OP_CROSS_PRODUCT_EXT 0x8797
+#define GL_OP_DOT3_EXT 0x8784
+#define GL_OP_DOT4_EXT 0x8785
+#define GL_OP_EXP_BASE_2_EXT 0x8791
+#define GL_OP_FLOOR_EXT 0x878F
+#define GL_OP_FRAC_EXT 0x8789
+#define GL_OP_INDEX_EXT 0x8782
+#define GL_OP_LOG_BASE_2_EXT 0x8792
+#define GL_OP_MADD_EXT 0x8788
+#define GL_OP_MAX_EXT 0x878A
+#define GL_OP_MIN_EXT 0x878B
+#define GL_OP_MOV_EXT 0x8799
+#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798
+#define GL_OP_MUL_EXT 0x8786
+#define GL_OP_NEGATE_EXT 0x8783
+#define GL_OP_POWER_EXT 0x8793
+#define GL_OP_RECIP_EXT 0x8794
+#define GL_OP_RECIP_SQRT_EXT 0x8795
+#define GL_OP_ROUND_EXT 0x8790
+#define GL_OP_SET_GE_EXT 0x878C
+#define GL_OP_SET_LT_EXT 0x878D
+#define GL_OP_SUB_EXT 0x8796
+#define GL_OR 0x1507
+#define GL_ORDER 0x0A01
+#define GL_OR_INVERTED 0x150D
+#define GL_OR_REVERSE 0x150B
+#define GL_OUTPUT_COLOR0_EXT 0x879B
+#define GL_OUTPUT_COLOR1_EXT 0x879C
+#define GL_OUTPUT_FOG_EXT 0x87BD
+#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D
+#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7
+#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8
+#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9
+#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA
+#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB
+#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC
+#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD
+#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE
+#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF
+#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0
+#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E
+#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1
+#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2
+#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3
+#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4
+#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5
+#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6
+#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7
+#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8
+#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9
+#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA
+#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F
+#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB
+#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC
+#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0
+#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1
+#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2
+#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3
+#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4
+#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5
+#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6
+#define GL_OUTPUT_VERTEX_EXT 0x879A
+#define GL_OUT_OF_MEMORY 0x0505
+#define GL_PACK_ALIGNMENT 0x0D05
+#define GL_PACK_CMYK_HINT_EXT 0x800E
+#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D
+#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C
+#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E
+#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B
+#define GL_PACK_COMPRESSED_SIZE_SGIX 0x831C
+#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131
+#define GL_PACK_IMAGE_HEIGHT 0x806C
+#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C
+#define GL_PACK_INVERT_MESA 0x8758
+#define GL_PACK_LSB_FIRST 0x0D01
+#define GL_PACK_MAX_COMPRESSED_SIZE_SGIX 0x831B
+#define GL_PACK_RESAMPLE_OML 0x8984
+#define GL_PACK_RESAMPLE_SGIX 0x842C
+#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4
+#define GL_PACK_ROW_BYTES_APPLE 0x8A15
+#define GL_PACK_ROW_LENGTH 0x0D02
+#define GL_PACK_SKIP_IMAGES 0x806B
+#define GL_PACK_SKIP_IMAGES_EXT 0x806B
+#define GL_PACK_SKIP_PIXELS 0x0D04
+#define GL_PACK_SKIP_ROWS 0x0D03
+#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130
+#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0
+#define GL_PACK_SWAP_BYTES 0x0D00
+#define GL_PALETTE4_R5_G6_B5_OES 0x8B92
+#define GL_PALETTE4_RGB5_A1_OES 0x8B94
+#define GL_PALETTE4_RGB8_OES 0x8B90
+#define GL_PALETTE4_RGBA4_OES 0x8B93
+#define GL_PALETTE4_RGBA8_OES 0x8B91
+#define GL_PALETTE8_R5_G6_B5_OES 0x8B97
+#define GL_PALETTE8_RGB5_A1_OES 0x8B99
+#define GL_PALETTE8_RGB8_OES 0x8B95
+#define GL_PALETTE8_RGBA4_OES 0x8B98
+#define GL_PALETTE8_RGBA8_OES 0x8B96
+#define GL_PARALLEL_ARRAYS_INTEL 0x83F4
+#define GL_PARTIAL_SUCCESS_NV 0x902E
+#define GL_PASS_THROUGH_NV 0x86E6
+#define GL_PASS_THROUGH_TOKEN 0x0700
+#define GL_PATCHES 0x000E
+#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73
+#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74
+#define GL_PATCH_VERTICES 0x8E72
+#define GL_PATH_CLIENT_LENGTH_NV 0x907F
+#define GL_PATH_COMMAND_COUNT_NV 0x909D
+#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0
+#define GL_PATH_COORD_COUNT_NV 0x909E
+#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF
+#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F
+#define GL_PATH_DASH_CAPS_NV 0x907B
+#define GL_PATH_DASH_OFFSET_NV 0x907E
+#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4
+#define GL_PATH_END_CAPS_NV 0x9076
+#define GL_PATH_ERROR_POSITION_NV 0x90AB
+#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1
+#define GL_PATH_FILL_COVER_MODE_NV 0x9082
+#define GL_PATH_FILL_MASK_NV 0x9081
+#define GL_PATH_FILL_MODE_NV 0x9080
+#define GL_PATH_FOG_GEN_MODE_NV 0x90AC
+#define GL_PATH_FORMAT_PS_NV 0x9071
+#define GL_PATH_FORMAT_SVG_NV 0x9070
+#define GL_PATH_GEN_COEFF_NV 0x90B1
+#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2
+#define GL_PATH_GEN_COMPONENTS_NV 0x90B3
+#define GL_PATH_GEN_MODE_NV 0x90B0
+#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C
+#define GL_PATH_INITIAL_END_CAP_NV 0x9077
+#define GL_PATH_JOIN_STYLE_NV 0x9079
+#define GL_PATH_MITER_LIMIT_NV 0x907A
+#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A
+#define GL_PATH_SAMPLE_QUALITY_NV 0x9085
+#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD
+#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE
+#define GL_PATH_STENCIL_FUNC_NV 0x90B7
+#define GL_PATH_STENCIL_REF_NV 0x90B8
+#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9
+#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2
+#define GL_PATH_STROKE_BOUND_NV 0x9086
+#define GL_PATH_STROKE_COVER_MODE_NV 0x9083
+#define GL_PATH_STROKE_MASK_NV 0x9084
+#define GL_PATH_STROKE_OVERSAMPLE_COUNT_NV 0x9087
+#define GL_PATH_STROKE_WIDTH_NV 0x9075
+#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D
+#define GL_PATH_TERMINAL_END_CAP_NV 0x9078
+#define GL_PERCENTAGE_AMD 0x8BC3
+#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0
+#define GL_PERFMON_RESULT_AMD 0x8BC6
+#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4
+#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5
+#define GL_PERFORMANCE_MONITOR_AMD 0x9152
+#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50
+#define GL_PERTURB_EXT 0x85AE
+#define GL_PER_STAGE_CONSTANTS_NV 0x8535
+#define GL_PHONG_HINT_WIN 0x80EB
+#define GL_PHONG_WIN 0x80EA
+#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080
+#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080
+#define GL_PIXEL_COUNTER_BITS_NV 0x8864
+#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867
+#define GL_PIXEL_COUNT_NV 0x8866
+#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333
+#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355
+#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354
+#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356
+#define GL_PIXEL_MAG_FILTER_EXT 0x8331
+#define GL_PIXEL_MAP_A_TO_A 0x0C79
+#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9
+#define GL_PIXEL_MAP_B_TO_B 0x0C78
+#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8
+#define GL_PIXEL_MAP_G_TO_G 0x0C77
+#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7
+#define GL_PIXEL_MAP_I_TO_A 0x0C75
+#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5
+#define GL_PIXEL_MAP_I_TO_B 0x0C74
+#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4
+#define GL_PIXEL_MAP_I_TO_G 0x0C73
+#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3
+#define GL_PIXEL_MAP_I_TO_I 0x0C70
+#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0
+#define GL_PIXEL_MAP_I_TO_R 0x0C72
+#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2
+#define GL_PIXEL_MAP_R_TO_R 0x0C76
+#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6
+#define GL_PIXEL_MAP_S_TO_S 0x0C71
+#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1
+#define GL_PIXEL_MIN_FILTER_EXT 0x8332
+#define GL_PIXEL_MODE_BIT 0x00000020
+#define GL_PIXEL_PACK_BUFFER 0x88EB
+#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB
+#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
+#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED
+#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED
+#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB
+#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3
+#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4
+#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2
+#define GL_PIXEL_TEXTURE_SGIS 0x8353
+#define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189
+#define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A
+#define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188
+#define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187
+#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B
+#define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184
+#define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186
+#define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185
+#define GL_PIXEL_TEX_GEN_SGIX 0x8139
+#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E
+#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F
+#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145
+#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144
+#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143
+#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142
+#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141
+#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140
+#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330
+#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338
+#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336
+#define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC
+#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF
+#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC
+#define GL_PN_TRIANGLES_ATI 0x87F0
+#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3
+#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7
+#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8
+#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2
+#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6
+#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5
+#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4
+#define GL_POINT 0x1B00
+#define GL_POINTS 0x0000
+#define GL_POINT_BIT 0x00000002
+#define GL_POINT_DISTANCE_ATTENUATION 0x8129
+#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129
+#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128
+#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128
+#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128
+#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128
+#define GL_POINT_SIZE 0x0B11
+#define GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES 0x8B9F
+#define GL_POINT_SIZE_ARRAY_OES 0x8B9C
+#define GL_POINT_SIZE_ARRAY_POINTER_OES 0x898C
+#define GL_POINT_SIZE_ARRAY_STRIDE_OES 0x898B
+#define GL_POINT_SIZE_ARRAY_TYPE_OES 0x898A
+#define GL_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_POINT_SIZE_MAX 0x8127
+#define GL_POINT_SIZE_MAX_ARB 0x8127
+#define GL_POINT_SIZE_MAX_EXT 0x8127
+#define GL_POINT_SIZE_MAX_SGIS 0x8127
+#define GL_POINT_SIZE_MIN 0x8126
+#define GL_POINT_SIZE_MIN_ARB 0x8126
+#define GL_POINT_SIZE_MIN_EXT 0x8126
+#define GL_POINT_SIZE_MIN_SGIS 0x8126
+#define GL_POINT_SIZE_RANGE 0x0B12
+#define GL_POINT_SMOOTH 0x0B10
+#define GL_POINT_SMOOTH_HINT 0x0C51
+#define GL_POINT_SPRITE 0x8861
+#define GL_POINT_SPRITE_ARB 0x8861
+#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0
+#define GL_POINT_SPRITE_NV 0x8861
+#define GL_POINT_SPRITE_R_MODE_NV 0x8863
+#define GL_POINT_TOKEN 0x0701
+#define GL_POLYGON 0x0009
+#define GL_POLYGON_BIT 0x00000008
+#define GL_POLYGON_MODE 0x0B40
+#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039
+#define GL_POLYGON_OFFSET_EXT 0x8037
+#define GL_POLYGON_OFFSET_FACTOR 0x8038
+#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038
+#define GL_POLYGON_OFFSET_FILL 0x8037
+#define GL_POLYGON_OFFSET_LINE 0x2A02
+#define GL_POLYGON_OFFSET_POINT 0x2A01
+#define GL_POLYGON_OFFSET_UNITS 0x2A00
+#define GL_POLYGON_SMOOTH 0x0B41
+#define GL_POLYGON_SMOOTH_HINT 0x0C53
+#define GL_POLYGON_STIPPLE 0x0B42
+#define GL_POLYGON_STIPPLE_BIT 0x00000010
+#define GL_POLYGON_TOKEN 0x0703
+#define GL_POSITION 0x1203
+#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB
+#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB
+#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7
+#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7
+#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA
+#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA
+#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6
+#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6
+#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2
+#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2
+#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9
+#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9
+#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5
+#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5
+#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8
+#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8
+#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4
+#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4
+#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023
+#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023
+#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F
+#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F
+#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022
+#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022
+#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E
+#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E
+#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1
+#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1
+#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021
+#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021
+#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D
+#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D
+#define GL_POST_CONVOLUTION_RED_BIAS 0x8020
+#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020
+#define GL_POST_CONVOLUTION_RED_SCALE 0x801C
+#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C
+#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162
+#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B
+#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179
+#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C
+#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A
+#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8
+#define GL_PRESENT_DURATION_NV 0x8E2B
+#define GL_PRESENT_TIME_NV 0x8E2A
+#define GL_PRESERVE_ATI 0x8762
+#define GL_PREVIOUS 0x8578
+#define GL_PREVIOUS_ARB 0x8578
+#define GL_PREVIOUS_EXT 0x8578
+#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4
+#define GL_PRIMARY_COLOR 0x8577
+#define GL_PRIMARY_COLOR_ARB 0x8577
+#define GL_PRIMARY_COLOR_EXT 0x8577
+#define GL_PRIMARY_COLOR_NV 0x852C
+#define GL_PRIMITIVES_GENERATED 0x8C87
+#define GL_PRIMITIVES_GENERATED_EXT 0x8C87
+#define GL_PRIMITIVES_GENERATED_NV 0x8C87
+#define GL_PRIMITIVE_ID_NV 0x8C7C
+#define GL_PRIMITIVE_RESTART 0x8F9D
+#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
+#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E
+#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559
+#define GL_PRIMITIVE_RESTART_NV 0x8558
+#define GL_PROGRAM 0x82E2
+#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0
+#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805
+#define GL_PROGRAM_ATTRIBS_ARB 0x88AC
+#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906
+#define GL_PROGRAM_BINARY_FORMATS 0x87FF
+#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF
+#define GL_PROGRAM_BINARY_LENGTH 0x8741
+#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741
+#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
+#define GL_PROGRAM_BINDING_ARB 0x8677
+#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B
+#define GL_PROGRAM_ERROR_POSITION_NV 0x864B
+#define GL_PROGRAM_ERROR_STRING_ARB 0x8874
+#define GL_PROGRAM_ERROR_STRING_NV 0x8874
+#define GL_PROGRAM_FORMAT_ARB 0x8876
+#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875
+#define GL_PROGRAM_INPUT 0x92E3
+#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0
+#define GL_PROGRAM_LENGTH_ARB 0x8627
+#define GL_PROGRAM_LENGTH_NV 0x8627
+#define GL_PROGRAM_MATRIX_EXT 0x8E2D
+#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F
+#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2
+#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808
+#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE
+#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2
+#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA
+#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6
+#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A
+#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809
+#define GL_PROGRAM_OBJECT_ARB 0x8B40
+#define GL_PROGRAM_OBJECT_EXT 0x8B40
+#define GL_PROGRAM_OUTPUT 0x92E4
+#define GL_PROGRAM_PARAMETERS_ARB 0x88A8
+#define GL_PROGRAM_PARAMETER_NV 0x8644
+#define GL_PROGRAM_PIPELINE 0x82E4
+#define GL_PROGRAM_PIPELINE_BINDING 0x825A
+#define GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A
+#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F
+#define GL_PROGRAM_POINT_SIZE 0x8642
+#define GL_PROGRAM_POINT_SIZE_ARB 0x8642
+#define GL_PROGRAM_POINT_SIZE_EXT 0x8642
+#define GL_PROGRAM_RESIDENT_NV 0x8647
+#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907
+#define GL_PROGRAM_SEPARABLE 0x8258
+#define GL_PROGRAM_SEPARABLE_EXT 0x8258
+#define GL_PROGRAM_STRING_ARB 0x8628
+#define GL_PROGRAM_STRING_NV 0x8628
+#define GL_PROGRAM_TARGET_NV 0x8646
+#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4
+#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807
+#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806
+#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6
+#define GL_PROJECTION 0x1701
+#define GL_PROJECTION_MATRIX 0x0BA7
+#define GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES 0x898E
+#define GL_PROJECTION_STACK_DEPTH 0x0BA4
+#define GL_PROJECTIVE_2D_NV 0x9093
+#define GL_PROJECTIVE_3D_NV 0x9095
+#define GL_PROVOKING_VERTEX 0x8E4F
+#define GL_PROVOKING_VERTEX_EXT 0x8E4F
+#define GL_PROXY_COLOR_TABLE 0x80D3
+#define GL_PROXY_COLOR_TABLE_SGI 0x80D3
+#define GL_PROXY_HISTOGRAM 0x8025
+#define GL_PROXY_HISTOGRAM_EXT 0x8025
+#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5
+#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5
+#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4
+#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4
+#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163
+#define GL_PROXY_TEXTURE_1D 0x8063
+#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19
+#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19
+#define GL_PROXY_TEXTURE_1D_EXT 0x8063
+#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B
+#define GL_PROXY_TEXTURE_2D 0x8064
+#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B
+#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B
+#define GL_PROXY_TEXTURE_2D_EXT 0x8064
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103
+#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C
+#define GL_PROXY_TEXTURE_3D 0x8070
+#define GL_PROXY_TEXTURE_3D_EXT 0x8070
+#define GL_PROXY_TEXTURE_4D_SGIS 0x8135
+#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD
+#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B
+#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B
+#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7
+#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7
+#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7
+#define GL_PURGEABLE_APPLE 0x8A1D
+#define GL_Q 0x2003
+#define GL_QUADRATIC_ATTENUATION 0x1209
+#define GL_QUADRATIC_CURVE_TO_NV 0x0A
+#define GL_QUADS 0x0007
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C
+#define GL_QUAD_ALPHA4_SGIS 0x811E
+#define GL_QUAD_ALPHA8_SGIS 0x811F
+#define GL_QUAD_INTENSITY4_SGIS 0x8122
+#define GL_QUAD_INTENSITY8_SGIS 0x8123
+#define GL_QUAD_LUMINANCE4_SGIS 0x8120
+#define GL_QUAD_LUMINANCE8_SGIS 0x8121
+#define GL_QUAD_MESH_SUN 0x8614
+#define GL_QUAD_STRIP 0x0008
+#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125
+#define GL_QUARTER_BIT_ATI 0x00000010
+#define GL_QUERY 0x82E3
+#define GL_QUERY_BUFFER_AMD 0x9192
+#define GL_QUERY_BUFFER_BINDING_AMD 0x9193
+#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16
+#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16
+#define GL_QUERY_BY_REGION_WAIT 0x8E15
+#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15
+#define GL_QUERY_COUNTER_BITS 0x8864
+#define GL_QUERY_COUNTER_BITS_ARB 0x8864
+#define GL_QUERY_NO_WAIT 0x8E14
+#define GL_QUERY_NO_WAIT_NV 0x8E14
+#define GL_QUERY_OBJECT_AMD 0x9153
+#define GL_QUERY_OBJECT_EXT 0x9153
+#define GL_QUERY_RESULT 0x8866
+#define GL_QUERY_RESULT_ARB 0x8866
+#define GL_QUERY_RESULT_AVAILABLE 0x8867
+#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867
+#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867
+#define GL_QUERY_RESULT_EXT 0x8866
+#define GL_QUERY_RESULT_NO_WAIT_AMD 0x9194
+#define GL_QUERY_WAIT 0x8E13
+#define GL_QUERY_WAIT_NV 0x8E13
+#define GL_R 0x2002
+#define GL_R11F_G11F_B10F 0x8C3A
+#define GL_R11F_G11F_B10F_EXT 0x8C3A
+#define GL_R16 0x822A
+#define GL_R16F 0x822D
+#define GL_R16F_EXT 0x822D
+#define GL_R16I 0x8233
+#define GL_R16UI 0x8234
+#define GL_R16_SNORM 0x8F98
+#define GL_R1UI_C3F_V3F_SUN 0x85C6
+#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8
+#define GL_R1UI_C4UB_V3F_SUN 0x85C5
+#define GL_R1UI_N3F_V3F_SUN 0x85C7
+#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB
+#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA
+#define GL_R1UI_T2F_V3F_SUN 0x85C9
+#define GL_R1UI_V3F_SUN 0x85C4
+#define GL_R32F 0x822E
+#define GL_R32I 0x8235
+#define GL_R32UI 0x8236
+#define GL_R3_G3_B2 0x2A10
+#define GL_R8 0x8229
+#define GL_R8I 0x8231
+#define GL_R8UI 0x8232
+#define GL_R8_EXT 0x8229
+#define GL_R8_SNORM 0x8F94
+#define GL_RASTERIZER_DISCARD 0x8C89
+#define GL_RASTERIZER_DISCARD_EXT 0x8C89
+#define GL_RASTERIZER_DISCARD_NV 0x8C89
+#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262
+#define GL_READ_BUFFER 0x0C02
+#define GL_READ_BUFFER_EXT 0x0C02
+#define GL_READ_BUFFER_NV 0x0C02
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8
+#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
+#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA
+#define GL_READ_FRAMEBUFFER_EXT 0x8CA8
+#define GL_READ_ONLY 0x88B8
+#define GL_READ_ONLY_ARB 0x88B8
+#define GL_READ_PIXELS 0x828C
+#define GL_READ_PIXELS_FORMAT 0x828D
+#define GL_READ_PIXELS_TYPE 0x828E
+#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B
+#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879
+#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D
+#define GL_READ_WRITE 0x88BA
+#define GL_READ_WRITE_ARB 0x88BA
+#define GL_RECIP_ADD_SIGNED_ALPHA_IMG 0x8C05
+#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE
+#define GL_RECT_NV 0xF6
+#define GL_RED 0x1903
+#define GL_REDUCE 0x8016
+#define GL_REDUCE_EXT 0x8016
+#define GL_RED_BIAS 0x0D15
+#define GL_RED_BITS 0x0D52
+#define GL_RED_BIT_ATI 0x00000001
+#define GL_RED_EXT 0x1903
+#define GL_RED_INTEGER 0x8D94
+#define GL_RED_INTEGER_EXT 0x8D94
+#define GL_RED_MAX_CLAMP_INGR 0x8564
+#define GL_RED_MIN_CLAMP_INGR 0x8560
+#define GL_RED_SCALE 0x0D14
+#define GL_RED_SNORM 0x8F90
+#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B
+#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A
+#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309
+#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307
+#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308
+#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306
+#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E
+#define GL_REFERENCE_PLANE_SGIX 0x817D
+#define GL_REFLECTION_MAP 0x8512
+#define GL_REFLECTION_MAP_ARB 0x8512
+#define GL_REFLECTION_MAP_EXT 0x8512
+#define GL_REFLECTION_MAP_NV 0x8512
+#define GL_REFLECTION_MAP_OES 0x8512
+#define GL_REGISTER_COMBINERS_NV 0x8522
+#define GL_REG_0_ATI 0x8921
+#define GL_REG_10_ATI 0x892B
+#define GL_REG_11_ATI 0x892C
+#define GL_REG_12_ATI 0x892D
+#define GL_REG_13_ATI 0x892E
+#define GL_REG_14_ATI 0x892F
+#define GL_REG_15_ATI 0x8930
+#define GL_REG_16_ATI 0x8931
+#define GL_REG_17_ATI 0x8932
+#define GL_REG_18_ATI 0x8933
+#define GL_REG_19_ATI 0x8934
+#define GL_REG_1_ATI 0x8922
+#define GL_REG_20_ATI 0x8935
+#define GL_REG_21_ATI 0x8936
+#define GL_REG_22_ATI 0x8937
+#define GL_REG_23_ATI 0x8938
+#define GL_REG_24_ATI 0x8939
+#define GL_REG_25_ATI 0x893A
+#define GL_REG_26_ATI 0x893B
+#define GL_REG_27_ATI 0x893C
+#define GL_REG_28_ATI 0x893D
+#define GL_REG_29_ATI 0x893E
+#define GL_REG_2_ATI 0x8923
+#define GL_REG_30_ATI 0x893F
+#define GL_REG_31_ATI 0x8940
+#define GL_REG_3_ATI 0x8924
+#define GL_REG_4_ATI 0x8925
+#define GL_REG_5_ATI 0x8926
+#define GL_REG_6_ATI 0x8927
+#define GL_REG_7_ATI 0x8928
+#define GL_REG_8_ATI 0x8929
+#define GL_REG_9_ATI 0x892A
+#define GL_RELATIVE_ARC_TO_NV 0xFF
+#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D
+#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07
+#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17
+#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19
+#define GL_RELATIVE_LINE_TO_NV 0x05
+#define GL_RELATIVE_MOVE_TO_NV 0x03
+#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B
+#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13
+#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15
+#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11
+#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F
+#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09
+#define GL_RELEASED_APPLE 0x8A19
+#define GL_RENDER 0x1C00
+#define GL_RENDERBUFFER 0x8D41
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53
+#define GL_RENDERBUFFER_ALPHA_SIZE_OES 0x8D53
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#define GL_RENDERBUFFER_BINDING_ANGLE 0x8CA7
+#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7
+#define GL_RENDERBUFFER_BINDING_OES 0x8CA7
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52
+#define GL_RENDERBUFFER_BLUE_SIZE_OES 0x8D52
+#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10
+#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54
+#define GL_RENDERBUFFER_DEPTH_SIZE_OES 0x8D54
+#define GL_RENDERBUFFER_EXT 0x8D41
+#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51
+#define GL_RENDERBUFFER_GREEN_SIZE_OES 0x8D51
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43
+#define GL_RENDERBUFFER_HEIGHT_OES 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44
+#define GL_RENDERBUFFER_INTERNAL_FORMAT_OES 0x8D44
+#define GL_RENDERBUFFER_OES 0x8D41
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50
+#define GL_RENDERBUFFER_RED_SIZE_OES 0x8D50
+#define GL_RENDERBUFFER_SAMPLES 0x8CAB
+#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB
+#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
+#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55
+#define GL_RENDERBUFFER_STENCIL_SIZE_OES 0x8D55
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42
+#define GL_RENDERBUFFER_WIDTH_OES 0x8D42
+#define GL_RENDERER 0x1F01
+#define GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3
+#define GL_RENDER_MODE 0x0C40
+#define GL_REPEAT 0x2901
+#define GL_REPLACE 0x1E01
+#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3
+#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2
+#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0
+#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1
+#define GL_REPLACEMENT_CODE_SUN 0x81D8
+#define GL_REPLACE_EXT 0x8062
+#define GL_REPLACE_MIDDLE_SUN 0x0002
+#define GL_REPLACE_OLDEST_SUN 0x0003
+#define GL_REPLACE_VALUE_AMD 0x874B
+#define GL_REPLICATE_BORDER 0x8153
+#define GL_REPLICATE_BORDER_HP 0x8153
+#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68
+#define GL_RESAMPLE_AVERAGE_OML 0x8988
+#define GL_RESAMPLE_DECIMATE_OML 0x8989
+#define GL_RESAMPLE_DECIMATE_SGIX 0x8430
+#define GL_RESAMPLE_REPLICATE_OML 0x8986
+#define GL_RESAMPLE_REPLICATE_SGIX 0x842E
+#define GL_RESAMPLE_ZERO_FILL_OML 0x8987
+#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F
+#define GL_RESCALE_NORMAL 0x803A
+#define GL_RESCALE_NORMAL_EXT 0x803A
+#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define GL_RESTART_PATH_NV 0xF0
+#define GL_RESTART_SUN 0x0001
+#define GL_RETAINED_APPLE 0x8A1B
+#define GL_RETURN 0x0102
+#define GL_RG 0x8227
+#define GL_RG16 0x822C
+#define GL_RG16F 0x822F
+#define GL_RG16F_EXT 0x822F
+#define GL_RG16I 0x8239
+#define GL_RG16UI 0x823A
+#define GL_RG16_SNORM 0x8F99
+#define GL_RG32F 0x8230
+#define GL_RG32I 0x823B
+#define GL_RG32UI 0x823C
+#define GL_RG8 0x822B
+#define GL_RG8I 0x8237
+#define GL_RG8UI 0x8238
+#define GL_RG8_EXT 0x822B
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB 0x1907
+#define GL_RGB10 0x8052
+#define GL_RGB10_A2 0x8059
+#define GL_RGB10_A2UI 0x906F
+#define GL_RGB10_A2_EXT 0x8059
+#define GL_RGB10_EXT 0x8052
+#define GL_RGB12 0x8053
+#define GL_RGB12_EXT 0x8053
+#define GL_RGB16 0x8054
+#define GL_RGB16F 0x881B
+#define GL_RGB16F_ARB 0x881B
+#define GL_RGB16F_EXT 0x881B
+#define GL_RGB16I 0x8D89
+#define GL_RGB16I_EXT 0x8D89
+#define GL_RGB16UI 0x8D77
+#define GL_RGB16UI_EXT 0x8D77
+#define GL_RGB16_EXT 0x8054
+#define GL_RGB16_SNORM 0x8F9A
+#define GL_RGB2_EXT 0x804E
+#define GL_RGB32F 0x8815
+#define GL_RGB32F_ARB 0x8815
+#define GL_RGB32I 0x8D83
+#define GL_RGB32I_EXT 0x8D83
+#define GL_RGB32UI 0x8D71
+#define GL_RGB32UI_EXT 0x8D71
+#define GL_RGB4 0x804F
+#define GL_RGB4_EXT 0x804F
+#define GL_RGB4_S3TC 0x83A1
+#define GL_RGB5 0x8050
+#define GL_RGB565 0x8D62
+#define GL_RGB565_OES 0x8D62
+#define GL_RGB5_A1 0x8057
+#define GL_RGB5_A1_EXT 0x8057
+#define GL_RGB5_A1_OES 0x8057
+#define GL_RGB5_EXT 0x8050
+#define GL_RGB8 0x8051
+#define GL_RGB8I 0x8D8F
+#define GL_RGB8I_EXT 0x8D8F
+#define GL_RGB8UI 0x8D7D
+#define GL_RGB8UI_EXT 0x8D7D
+#define GL_RGB8_EXT 0x8051
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGB9_E5 0x8C3D
+#define GL_RGB9_E5_EXT 0x8C3D
+#define GL_RGBA 0x1908
+#define GL_RGBA12 0x805A
+#define GL_RGBA12_EXT 0x805A
+#define GL_RGBA16 0x805B
+#define GL_RGBA16F 0x881A
+#define GL_RGBA16F_ARB 0x881A
+#define GL_RGBA16F_EXT 0x881A
+#define GL_RGBA16I 0x8D88
+#define GL_RGBA16I_EXT 0x8D88
+#define GL_RGBA16UI 0x8D76
+#define GL_RGBA16UI_EXT 0x8D76
+#define GL_RGBA16_EXT 0x805B
+#define GL_RGBA16_SNORM 0x8F9B
+#define GL_RGBA2 0x8055
+#define GL_RGBA2_EXT 0x8055
+#define GL_RGBA32F 0x8814
+#define GL_RGBA32F_ARB 0x8814
+#define GL_RGBA32I 0x8D82
+#define GL_RGBA32I_EXT 0x8D82
+#define GL_RGBA32UI 0x8D70
+#define GL_RGBA32UI_EXT 0x8D70
+#define GL_RGBA4 0x8056
+#define GL_RGBA4_DXT5_S3TC 0x83A5
+#define GL_RGBA4_EXT 0x8056
+#define GL_RGBA4_OES 0x8056
+#define GL_RGBA4_S3TC 0x83A3
+#define GL_RGBA8 0x8058
+#define GL_RGBA8I 0x8D8E
+#define GL_RGBA8I_EXT 0x8D8E
+#define GL_RGBA8UI 0x8D7C
+#define GL_RGBA8UI_EXT 0x8D7C
+#define GL_RGBA8_EXT 0x8058
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_RGBA_DXT5_S3TC 0x83A4
+#define GL_RGBA_FLOAT16_APPLE 0x881A
+#define GL_RGBA_FLOAT16_ATI 0x881A
+#define GL_RGBA_FLOAT32_APPLE 0x8814
+#define GL_RGBA_FLOAT32_ATI 0x8814
+#define GL_RGBA_FLOAT_MODE_ARB 0x8820
+#define GL_RGBA_FLOAT_MODE_ATI 0x8820
+#define GL_RGBA_INTEGER 0x8D99
+#define GL_RGBA_INTEGER_EXT 0x8D99
+#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E
+#define GL_RGBA_MODE 0x0C31
+#define GL_RGBA_S3TC 0x83A2
+#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C
+#define GL_RGBA_SNORM 0x8F93
+#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9
+#define GL_RGB_422_APPLE 0x8A1F
+#define GL_RGB_FLOAT16_APPLE 0x881B
+#define GL_RGB_FLOAT16_ATI 0x881B
+#define GL_RGB_FLOAT32_APPLE 0x8815
+#define GL_RGB_FLOAT32_ATI 0x8815
+#define GL_RGB_INTEGER 0x8D98
+#define GL_RGB_INTEGER_EXT 0x8D98
+#define GL_RGB_S3TC 0x83A0
+#define GL_RGB_SCALE 0x8573
+#define GL_RGB_SCALE_ARB 0x8573
+#define GL_RGB_SCALE_EXT 0x8573
+#define GL_RGB_SNORM 0x8F92
+#define GL_RG_EXT 0x8227
+#define GL_RG_INTEGER 0x8228
+#define GL_RG_SNORM 0x8F91
+#define GL_RIGHT 0x0407
+#define GL_ROUND_NV 0x90A4
+#define GL_S 0x2000
+#define GL_SAMPLER 0x82E6
+#define GL_SAMPLER_1D 0x8B5D
+#define GL_SAMPLER_1D_ARB 0x8B5D
+#define GL_SAMPLER_1D_ARRAY 0x8DC0
+#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0
+#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3
+#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3
+#define GL_SAMPLER_1D_SHADOW 0x8B61
+#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_2D_ARB 0x8B5E
+#define GL_SAMPLER_2D_ARRAY 0x8DC1
+#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1
+#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
+#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4
+#define GL_SAMPLER_2D_MULTISAMPLE 0x9108
+#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B
+#define GL_SAMPLER_2D_RECT 0x8B63
+#define GL_SAMPLER_2D_RECT_ARB 0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64
+#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64
+#define GL_SAMPLER_2D_SHADOW 0x8B62
+#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62
+#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62
+#define GL_SAMPLER_3D 0x8B5F
+#define GL_SAMPLER_3D_ARB 0x8B5F
+#define GL_SAMPLER_3D_OES 0x8B5F
+#define GL_SAMPLER_BINDING 0x8919
+#define GL_SAMPLER_BUFFER 0x8DC2
+#define GL_SAMPLER_BUFFER_AMD 0x9001
+#define GL_SAMPLER_BUFFER_EXT 0x8DC2
+#define GL_SAMPLER_CUBE 0x8B60
+#define GL_SAMPLER_CUBE_ARB 0x8B60
+#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D
+#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
+#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5
+#define GL_SAMPLER_EXTERNAL_OES 0x8D66
+#define GL_SAMPLER_OBJECT_AMD 0x9155
+#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLES_3DFX 0x86B4
+#define GL_SAMPLES_ARB 0x80A9
+#define GL_SAMPLES_EXT 0x80A9
+#define GL_SAMPLES_PASSED 0x8914
+#define GL_SAMPLES_PASSED_ARB 0x8914
+#define GL_SAMPLES_SGIS 0x80A9
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E
+#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E
+#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE 0x809F
+#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F
+#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F
+#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLE_BUFFERS_3DFX 0x86B3
+#define GL_SAMPLE_BUFFERS_ARB 0x80A8
+#define GL_SAMPLE_BUFFERS_EXT 0x80A8
+#define GL_SAMPLE_BUFFERS_SGIS 0x80A8
+#define GL_SAMPLE_COVERAGE 0x80A0
+#define GL_SAMPLE_COVERAGE_ARB 0x80A0
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA
+#define GL_SAMPLE_MASK 0x8E51
+#define GL_SAMPLE_MASK_EXT 0x80A0
+#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB
+#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB
+#define GL_SAMPLE_MASK_NV 0x8E51
+#define GL_SAMPLE_MASK_SGIS 0x80A0
+#define GL_SAMPLE_MASK_VALUE 0x8E52
+#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA
+#define GL_SAMPLE_MASK_VALUE_NV 0x8E52
+#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA
+#define GL_SAMPLE_PATTERN_EXT 0x80AC
+#define GL_SAMPLE_PATTERN_SGIS 0x80AC
+#define GL_SAMPLE_POSITION 0x8E50
+#define GL_SAMPLE_POSITION_NV 0x8E50
+#define GL_SAMPLE_SHADING 0x8C36
+#define GL_SAMPLE_SHADING_ARB 0x8C36
+#define GL_SATURATE_BIT_ATI 0x00000040
+#define GL_SCALAR_EXT 0x87BE
+#define GL_SCALEBIAS_HINT_SGIX 0x8322
+#define GL_SCALED_RESOLVE_FASTEST_EXT 0x90BA
+#define GL_SCALED_RESOLVE_NICEST_EXT 0x90BB
+#define GL_SCALE_BY_FOUR_NV 0x853F
+#define GL_SCALE_BY_ONE_HALF_NV 0x8540
+#define GL_SCALE_BY_TWO_NV 0x853E
+#define GL_SCISSOR_BIT 0x00080000
+#define GL_SCISSOR_BOX 0x0C10
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_SCREEN_COORDINATES_REND 0x8490
+#define GL_SECONDARY_COLOR_ARRAY 0x845E
+#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27
+#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C
+#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C
+#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E
+#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31
+#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077
+#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087
+#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D
+#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D
+#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A
+#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A
+#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C
+#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C
+#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B
+#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B
+#define GL_SECONDARY_COLOR_NV 0x852D
+#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D
+#define GL_SELECT 0x1C02
+#define GL_SELECTION_BUFFER_POINTER 0x0DF3
+#define GL_SELECTION_BUFFER_SIZE 0x0DF4
+#define GL_SEPARABLE_2D 0x8012
+#define GL_SEPARABLE_2D_EXT 0x8012
+#define GL_SEPARATE_ATTRIBS 0x8C8D
+#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D
+#define GL_SEPARATE_ATTRIBS_NV 0x8C8D
+#define GL_SEPARATE_SPECULAR_COLOR 0x81FA
+#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA
+#define GL_SET 0x150F
+#define GL_SET_AMD 0x874A
+#define GL_SGX_BINARY_IMG 0x8C0A
+#define GL_SGX_PROGRAM_BINARY_IMG 0x9130
+#define GL_SHADER 0x82E1
+#define GL_SHADER_BINARY_DMP 0x9250
+#define GL_SHADER_BINARY_FORMATS 0x8DF8
+#define GL_SHADER_BINARY_VIV 0x8FC4
+#define GL_SHADER_COMPILER 0x8DFA
+#define GL_SHADER_CONSISTENT_NV 0x86DD
+#define GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV 0x00000010
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020
+#define GL_SHADER_IMAGE_ATOMIC 0x82A6
+#define GL_SHADER_IMAGE_LOAD 0x82A4
+#define GL_SHADER_IMAGE_STORE 0x82A5
+#define GL_SHADER_INCLUDE_ARB 0x8DAE
+#define GL_SHADER_OBJECT_ARB 0x8B48
+#define GL_SHADER_OBJECT_EXT 0x8B48
+#define GL_SHADER_OPERATION_NV 0x86DF
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#define GL_SHADER_STORAGE_BARRIER_BIT 0x2000
+#define GL_SHADER_STORAGE_BLOCK 0x92E6
+#define GL_SHADER_STORAGE_BUFFER 0x90D2
+#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3
+#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF
+#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5
+#define GL_SHADER_STORAGE_BUFFER_START 0x90D4
+#define GL_SHADER_TYPE 0x8B4F
+#define GL_SHADE_MODEL 0x0B54
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C
+#define GL_SHADOW_AMBIENT_SGIX 0x80BF
+#define GL_SHADOW_ATTENUATION_EXT 0x834E
+#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB
+#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0
+#define GL_SHININESS 0x1601
+#define GL_SHORT 0x1402
+#define GL_SIGNALED 0x9119
+#define GL_SIGNALED_APPLE 0x9119
+#define GL_SIGNED_ALPHA8_NV 0x8706
+#define GL_SIGNED_ALPHA_NV 0x8705
+#define GL_SIGNED_HILO16_NV 0x86FA
+#define GL_SIGNED_HILO8_NV 0x885F
+#define GL_SIGNED_HILO_NV 0x86F9
+#define GL_SIGNED_IDENTITY_NV 0x853C
+#define GL_SIGNED_INTENSITY8_NV 0x8708
+#define GL_SIGNED_INTENSITY_NV 0x8707
+#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704
+#define GL_SIGNED_LUMINANCE8_NV 0x8702
+#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703
+#define GL_SIGNED_LUMINANCE_NV 0x8701
+#define GL_SIGNED_NEGATE_NV 0x853D
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_SIGNED_RGB8_NV 0x86FF
+#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D
+#define GL_SIGNED_RGBA8_NV 0x86FC
+#define GL_SIGNED_RGBA_NV 0x86FB
+#define GL_SIGNED_RGB_NV 0x86FE
+#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C
+#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC
+#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE
+#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD
+#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF
+#define GL_SINGLE_COLOR 0x81F9
+#define GL_SINGLE_COLOR_EXT 0x81F9
+#define GL_SKIP_DECODE_EXT 0x8A4A
+#define GL_SKIP_MISSING_GLYPH_NV 0x90A9
+#define GL_SLICE_ACCUM_SUN 0x85CC
+#define GL_SLIM10U_SGIX 0x831E
+#define GL_SLIM12S_SGIX 0x831F
+#define GL_SLIM8U_SGIX 0x831D
+#define GL_SLUMINANCE 0x8C46
+#define GL_SLUMINANCE8 0x8C47
+#define GL_SLUMINANCE8_ALPHA8 0x8C45
+#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45
+#define GL_SLUMINANCE8_EXT 0x8C47
+#define GL_SLUMINANCE_ALPHA 0x8C44
+#define GL_SLUMINANCE_ALPHA_EXT 0x8C44
+#define GL_SLUMINANCE_EXT 0x8C46
+#define GL_SMALL_CCW_ARC_TO_NV 0x12
+#define GL_SMALL_CW_ARC_TO_NV 0x14
+#define GL_SMOOTH 0x1D01
+#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10
+#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22
+#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12
+#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E
+#define GL_SOURCE0_ALPHA 0x8588
+#define GL_SOURCE0_ALPHA_ARB 0x8588
+#define GL_SOURCE0_ALPHA_EXT 0x8588
+#define GL_SOURCE0_RGB 0x8580
+#define GL_SOURCE0_RGB_ARB 0x8580
+#define GL_SOURCE0_RGB_EXT 0x8580
+#define GL_SOURCE1_ALPHA 0x8589
+#define GL_SOURCE1_ALPHA_ARB 0x8589
+#define GL_SOURCE1_ALPHA_EXT 0x8589
+#define GL_SOURCE1_RGB 0x8581
+#define GL_SOURCE1_RGB_ARB 0x8581
+#define GL_SOURCE1_RGB_EXT 0x8581
+#define GL_SOURCE2_ALPHA 0x858A
+#define GL_SOURCE2_ALPHA_ARB 0x858A
+#define GL_SOURCE2_ALPHA_EXT 0x858A
+#define GL_SOURCE2_RGB 0x8582
+#define GL_SOURCE2_RGB_ARB 0x8582
+#define GL_SOURCE2_RGB_EXT 0x8582
+#define GL_SOURCE3_ALPHA_NV 0x858B
+#define GL_SOURCE3_RGB_NV 0x8583
+#define GL_SPARE0_NV 0x852E
+#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532
+#define GL_SPARE1_NV 0x852F
+#define GL_SPECULAR 0x1202
+#define GL_SPHERE_MAP 0x2402
+#define GL_SPOT_CUTOFF 0x1206
+#define GL_SPOT_DIRECTION 0x1204
+#define GL_SPOT_EXPONENT 0x1205
+#define GL_SPRITE_AXIAL_SGIX 0x814C
+#define GL_SPRITE_AXIS_SGIX 0x814A
+#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E
+#define GL_SPRITE_MODE_SGIX 0x8149
+#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D
+#define GL_SPRITE_SGIX 0x8148
+#define GL_SPRITE_TRANSLATION_SGIX 0x814B
+#define GL_SQUARE_NV 0x90A3
+#define GL_SRC0_ALPHA 0x8588
+#define GL_SRC0_RGB 0x8580
+#define GL_SRC1_ALPHA 0x8589
+#define GL_SRC1_COLOR 0x88F9
+#define GL_SRC1_RGB 0x8581
+#define GL_SRC2_ALPHA 0x858A
+#define GL_SRC2_RGB 0x8582
+#define GL_SRC_ALPHA 0x0302
+#define GL_SRC_ALPHA_SATURATE 0x0308
+#define GL_SRC_COLOR 0x0300
+#define GL_SRGB 0x8C40
+#define GL_SRGB8 0x8C41
+#define GL_SRGB8_ALPHA8 0x8C43
+#define GL_SRGB8_ALPHA8_EXT 0x8C43
+#define GL_SRGB8_EXT 0x8C41
+#define GL_SRGB_ALPHA 0x8C42
+#define GL_SRGB_ALPHA_EXT 0x8C42
+#define GL_SRGB_DECODE_ARB 0x8299
+#define GL_SRGB_EXT 0x8C40
+#define GL_SRGB_READ 0x8297
+#define GL_SRGB_WRITE 0x8298
+#define GL_STACK_OVERFLOW 0x0503
+#define GL_STACK_UNDERFLOW 0x0504
+#define GL_STANDARD_FONT_NAME_NV 0x9072
+#define GL_STATE_RESTORE 0x8BDC
+#define GL_STATIC_ATI 0x8760
+#define GL_STATIC_COPY 0x88E6
+#define GL_STATIC_COPY_ARB 0x88E6
+#define GL_STATIC_DRAW 0x88E4
+#define GL_STATIC_DRAW_ARB 0x88E4
+#define GL_STATIC_READ 0x88E5
+#define GL_STATIC_READ_ARB 0x88E5
+#define GL_STENCIL 0x1802
+#define GL_STENCIL_ATTACHMENT 0x8D20
+#define GL_STENCIL_ATTACHMENT_EXT 0x8D20
+#define GL_STENCIL_ATTACHMENT_OES 0x8D20
+#define GL_STENCIL_BACK_FAIL 0x8801
+#define GL_STENCIL_BACK_FAIL_ATI 0x8801
+#define GL_STENCIL_BACK_FUNC 0x8800
+#define GL_STENCIL_BACK_FUNC_ATI 0x8800
+#define GL_STENCIL_BACK_OP_VALUE_AMD 0x874D
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803
+#define GL_STENCIL_BACK_REF 0x8CA3
+#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
+#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
+#define GL_STENCIL_BITS 0x0D57
+#define GL_STENCIL_BUFFER_BIT 0x00000400
+#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3
+#define GL_STENCIL_CLEAR_VALUE 0x0B91
+#define GL_STENCIL_COMPONENTS 0x8285
+#define GL_STENCIL_EXT 0x1802
+#define GL_STENCIL_FAIL 0x0B94
+#define GL_STENCIL_FUNC 0x0B92
+#define GL_STENCIL_INDEX 0x1901
+#define GL_STENCIL_INDEX1 0x8D46
+#define GL_STENCIL_INDEX16 0x8D49
+#define GL_STENCIL_INDEX16_EXT 0x8D49
+#define GL_STENCIL_INDEX1_EXT 0x8D46
+#define GL_STENCIL_INDEX1_OES 0x8D46
+#define GL_STENCIL_INDEX4 0x8D47
+#define GL_STENCIL_INDEX4_EXT 0x8D47
+#define GL_STENCIL_INDEX4_OES 0x8D47
+#define GL_STENCIL_INDEX8 0x8D48
+#define GL_STENCIL_INDEX8_EXT 0x8D48
+#define GL_STENCIL_INDEX8_OES 0x8D48
+#define GL_STENCIL_OP_VALUE_AMD 0x874C
+#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
+#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
+#define GL_STENCIL_REF 0x0B97
+#define GL_STENCIL_RENDERABLE 0x8288
+#define GL_STENCIL_TAG_BITS_EXT 0x88F2
+#define GL_STENCIL_TEST 0x0B90
+#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910
+#define GL_STENCIL_VALUE_MASK 0x0B93
+#define GL_STENCIL_WRITEMASK 0x0B98
+#define GL_STEREO 0x0C33
+#define GL_STORAGE_CACHED_APPLE 0x85BE
+#define GL_STORAGE_CLIENT_APPLE 0x85B4
+#define GL_STORAGE_PRIVATE_APPLE 0x85BD
+#define GL_STORAGE_SHARED_APPLE 0x85BF
+#define GL_STREAM_COPY 0x88E2
+#define GL_STREAM_COPY_ARB 0x88E2
+#define GL_STREAM_DRAW 0x88E0
+#define GL_STREAM_DRAW_ARB 0x88E0
+#define GL_STREAM_READ 0x88E1
+#define GL_STREAM_READ_ARB 0x88E1
+#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216
+#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217
+#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218
+#define GL_SUBPIXEL_BITS 0x0D50
+#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F
+#define GL_SUBTRACT 0x84E7
+#define GL_SUBTRACT_ARB 0x84E7
+#define GL_SUB_ATI 0x8965
+#define GL_SUCCESS_NV 0x902F
+#define GL_SURFACE_MAPPED_NV 0x8700
+#define GL_SURFACE_REGISTERED_NV 0x86FD
+#define GL_SURFACE_STATE_NV 0x86EB
+#define GL_SWIZZLE_STQ_ATI 0x8977
+#define GL_SWIZZLE_STQ_DQ_ATI 0x8979
+#define GL_SWIZZLE_STRQ_ATI 0x897A
+#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B
+#define GL_SWIZZLE_STR_ATI 0x8976
+#define GL_SWIZZLE_STR_DR_ATI 0x8978
+#define GL_SYNC_CL_EVENT_ARB 0x8240
+#define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241
+#define GL_SYNC_CONDITION 0x9113
+#define GL_SYNC_CONDITION_APPLE 0x9113
+#define GL_SYNC_FENCE 0x9116
+#define GL_SYNC_FENCE_APPLE 0x9116
+#define GL_SYNC_FLAGS 0x9115
+#define GL_SYNC_FLAGS_APPLE 0x9115
+#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#define GL_SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001
+#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#define GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117
+#define GL_SYNC_OBJECT_APPLE 0x8A53
+#define GL_SYNC_STATUS 0x9114
+#define GL_SYNC_STATUS_APPLE 0x9114
+#define GL_SYNC_X11_FENCE_EXT 0x90E1
+#define GL_SYSTEM_FONT_NAME_NV 0x9073
+#define GL_T 0x2001
+#define GL_T2F_C3F_V3F 0x2A2A
+#define GL_T2F_C4F_N3F_V3F 0x2A2C
+#define GL_T2F_C4UB_V3F 0x2A29
+#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3
+#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4
+#define GL_T2F_IUI_V2F_EXT 0x81B1
+#define GL_T2F_IUI_V3F_EXT 0x81B2
+#define GL_T2F_N3F_V3F 0x2A2B
+#define GL_T2F_V3F 0x2A27
+#define GL_T4F_C4F_N3F_V4F 0x2A2D
+#define GL_T4F_V4F 0x2A28
+#define GL_TABLE_TOO_LARGE 0x8031
+#define GL_TABLE_TOO_LARGE_EXT 0x8031
+#define GL_TANGENT_ARRAY_EXT 0x8439
+#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442
+#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F
+#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E
+#define GL_TESSELLATION_FACTOR_AMD 0x9005
+#define GL_TESSELLATION_MODE_AMD 0x9004
+#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75
+#define GL_TESS_CONTROL_PROGRAM_NV 0x891E
+#define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74
+#define GL_TESS_CONTROL_SHADER 0x8E88
+#define GL_TESS_CONTROL_SHADER_BIT 0x00000008
+#define GL_TESS_CONTROL_SUBROUTINE 0x92E9
+#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF
+#define GL_TESS_CONTROL_TEXTURE 0x829C
+#define GL_TESS_EVALUATION_PROGRAM_NV 0x891F
+#define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75
+#define GL_TESS_EVALUATION_SHADER 0x8E87
+#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010
+#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA
+#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0
+#define GL_TESS_EVALUATION_TEXTURE 0x829D
+#define GL_TESS_GEN_MODE 0x8E76
+#define GL_TESS_GEN_POINT_MODE 0x8E79
+#define GL_TESS_GEN_SPACING 0x8E77
+#define GL_TESS_GEN_VERTEX_ORDER 0x8E78
+#define GL_TEXCOORD1_BIT_PGI 0x10000000
+#define GL_TEXCOORD2_BIT_PGI 0x20000000
+#define GL_TEXCOORD3_BIT_PGI 0x40000000
+#define GL_TEXCOORD4_BIT_PGI 0x80000000
+#define GL_TEXTURE 0x1702
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE0_ARB 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE10 0x84CA
+#define GL_TEXTURE10_ARB 0x84CA
+#define GL_TEXTURE11 0x84CB
+#define GL_TEXTURE11_ARB 0x84CB
+#define GL_TEXTURE12 0x84CC
+#define GL_TEXTURE12_ARB 0x84CC
+#define GL_TEXTURE13 0x84CD
+#define GL_TEXTURE13_ARB 0x84CD
+#define GL_TEXTURE14 0x84CE
+#define GL_TEXTURE14_ARB 0x84CE
+#define GL_TEXTURE15 0x84CF
+#define GL_TEXTURE15_ARB 0x84CF
+#define GL_TEXTURE16 0x84D0
+#define GL_TEXTURE16_ARB 0x84D0
+#define GL_TEXTURE17 0x84D1
+#define GL_TEXTURE17_ARB 0x84D1
+#define GL_TEXTURE18 0x84D2
+#define GL_TEXTURE18_ARB 0x84D2
+#define GL_TEXTURE19 0x84D3
+#define GL_TEXTURE19_ARB 0x84D3
+#define GL_TEXTURE1_ARB 0x84C1
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE20 0x84D4
+#define GL_TEXTURE20_ARB 0x84D4
+#define GL_TEXTURE21 0x84D5
+#define GL_TEXTURE21_ARB 0x84D5
+#define GL_TEXTURE22 0x84D6
+#define GL_TEXTURE22_ARB 0x84D6
+#define GL_TEXTURE23 0x84D7
+#define GL_TEXTURE23_ARB 0x84D7
+#define GL_TEXTURE24 0x84D8
+#define GL_TEXTURE24_ARB 0x84D8
+#define GL_TEXTURE25 0x84D9
+#define GL_TEXTURE25_ARB 0x84D9
+#define GL_TEXTURE26 0x84DA
+#define GL_TEXTURE26_ARB 0x84DA
+#define GL_TEXTURE27 0x84DB
+#define GL_TEXTURE27_ARB 0x84DB
+#define GL_TEXTURE28 0x84DC
+#define GL_TEXTURE28_ARB 0x84DC
+#define GL_TEXTURE29 0x84DD
+#define GL_TEXTURE29_ARB 0x84DD
+#define GL_TEXTURE2_ARB 0x84C2
+#define GL_TEXTURE3 0x84C3
+#define GL_TEXTURE30 0x84DE
+#define GL_TEXTURE30_ARB 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_TEXTURE31_ARB 0x84DF
+#define GL_TEXTURE3_ARB 0x84C3
+#define GL_TEXTURE4 0x84C4
+#define GL_TEXTURE4_ARB 0x84C4
+#define GL_TEXTURE5 0x84C5
+#define GL_TEXTURE5_ARB 0x84C5
+#define GL_TEXTURE6 0x84C6
+#define GL_TEXTURE6_ARB 0x84C6
+#define GL_TEXTURE7 0x84C7
+#define GL_TEXTURE7_ARB 0x84C7
+#define GL_TEXTURE8 0x84C8
+#define GL_TEXTURE8_ARB 0x84C8
+#define GL_TEXTURE9 0x84C9
+#define GL_TEXTURE9_ARB 0x84C9
+#define GL_TEXTURE_1D 0x0DE0
+#define GL_TEXTURE_1D_ARRAY 0x8C18
+#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18
+#define GL_TEXTURE_1D_BINDING_EXT 0x8068
+#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D
+#define GL_TEXTURE_1D_STACK_MESAX 0x8759
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A
+#define GL_TEXTURE_2D_BINDING_EXT 0x8069
+#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
+#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E
+#define GL_TEXTURE_2D_STACK_MESAX 0x875A
+#define GL_TEXTURE_3D 0x806F
+#define GL_TEXTURE_3D_BINDING_EXT 0x806A
+#define GL_TEXTURE_3D_BINDING_OES 0x806A
+#define GL_TEXTURE_3D_EXT 0x806F
+#define GL_TEXTURE_3D_OES 0x806F
+#define GL_TEXTURE_4DSIZE_SGIS 0x8136
+#define GL_TEXTURE_4D_BINDING_SGIS 0x814F
+#define GL_TEXTURE_4D_SGIS 0x8134
+#define GL_TEXTURE_ALPHA_MODULATE_IMG 0x8C06
+#define GL_TEXTURE_ALPHA_SIZE 0x805F
+#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F
+#define GL_TEXTURE_ALPHA_TYPE 0x8C13
+#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13
+#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C
+#define GL_TEXTURE_BINDING_1D 0x8068
+#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C
+#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C
+#define GL_TEXTURE_BINDING_2D 0x8069
+#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
+#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105
+#define GL_TEXTURE_BINDING_3D 0x806A
+#define GL_TEXTURE_BINDING_BUFFER 0x8C2C
+#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C
+#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A
+#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514
+#define GL_TEXTURE_BINDING_CUBE_MAP_OES 0x8514
+#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67
+#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6
+#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6
+#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6
+#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53
+#define GL_TEXTURE_BIT 0x00040000
+#define GL_TEXTURE_BLUE_SIZE 0x805E
+#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E
+#define GL_TEXTURE_BLUE_TYPE 0x8C12
+#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12
+#define GL_TEXTURE_BORDER 0x1005
+#define GL_TEXTURE_BORDER_COLOR 0x1004
+#define GL_TEXTURE_BORDER_VALUES_NV 0x871A
+#define GL_TEXTURE_BUFFER 0x8C2A
+#define GL_TEXTURE_BUFFER_ARB 0x8C2A
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D
+#define GL_TEXTURE_BUFFER_EXT 0x8C2A
+#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E
+#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E
+#define GL_TEXTURE_BUFFER_OFFSET 0x919D
+#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F
+#define GL_TEXTURE_BUFFER_SIZE 0x919E
+#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171
+#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176
+#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172
+#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175
+#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173
+#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174
+#define GL_TEXTURE_COLOR_SAMPLES_NV 0x9046
+#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC
+#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF
+#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF
+#define GL_TEXTURE_COMPARE_FUNC 0x884D
+#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D
+#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D
+#define GL_TEXTURE_COMPARE_MODE 0x884C
+#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C
+#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C
+#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B
+#define GL_TEXTURE_COMPARE_SGIX 0x819A
+#define GL_TEXTURE_COMPONENTS 0x1003
+#define GL_TEXTURE_COMPRESSED 0x86A1
+#define GL_TEXTURE_COMPRESSED_ARB 0x86A1
+#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2
+#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3
+#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0
+#define GL_TEXTURE_COMPRESSION_HINT 0x84EF
+#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF
+#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6
+#define GL_TEXTURE_COORD_ARRAY 0x8078
+#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A
+#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B
+#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078
+#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F
+#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074
+#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084
+#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8
+#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092
+#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092
+#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088
+#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088
+#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A
+#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A
+#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089
+#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089
+#define GL_TEXTURE_COORD_NV 0x8C79
+#define GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045
+#define GL_TEXTURE_CROP_RECT_OES 0x8B9D
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_CUBE_MAP_ARB 0x8513
+#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009
+#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009
+#define GL_TEXTURE_CUBE_MAP_EXT 0x8513
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES 0x8516
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES 0x8518
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES 0x851A
+#define GL_TEXTURE_CUBE_MAP_OES 0x8513
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES 0x8515
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES 0x8517
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES 0x8519
+#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
+#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001
+#define GL_TEXTURE_DEFORMATION_SGIX 0x8195
+#define GL_TEXTURE_DEPTH 0x8071
+#define GL_TEXTURE_DEPTH_EXT 0x8071
+#define GL_TEXTURE_DEPTH_QCOM 0x8BD4
+#define GL_TEXTURE_DEPTH_SIZE 0x884A
+#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A
+#define GL_TEXTURE_DEPTH_TYPE 0x8C16
+#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16
+#define GL_TEXTURE_DS_SIZE_NV 0x871D
+#define GL_TEXTURE_DT_SIZE_NV 0x871E
+#define GL_TEXTURE_ENV 0x2300
+#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE
+#define GL_TEXTURE_ENV_COLOR 0x2201
+#define GL_TEXTURE_ENV_MODE 0x2200
+#define GL_TEXTURE_EXTERNAL_OES 0x8D65
+#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008
+#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008
+#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147
+#define GL_TEXTURE_FILTER_CONTROL 0x8500
+#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500
+#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
+#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C
+#define GL_TEXTURE_FORMAT_QCOM 0x8BD6
+#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC
+#define GL_TEXTURE_GATHER 0x82A2
+#define GL_TEXTURE_GATHER_SHADOW 0x82A3
+#define GL_TEXTURE_GEN_MODE 0x2500
+#define GL_TEXTURE_GEN_Q 0x0C63
+#define GL_TEXTURE_GEN_R 0x0C62
+#define GL_TEXTURE_GEN_S 0x0C60
+#define GL_TEXTURE_GEN_STR_OES 0x8D60
+#define GL_TEXTURE_GEN_T 0x0C61
+#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D
+#define GL_TEXTURE_GREEN_SIZE 0x805D
+#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D
+#define GL_TEXTURE_GREEN_TYPE 0x8C11
+#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11
+#define GL_TEXTURE_HEIGHT 0x1001
+#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3
+#define GL_TEXTURE_HI_SIZE_NV 0x871B
+#define GL_TEXTURE_IMAGE_FORMAT 0x828F
+#define GL_TEXTURE_IMAGE_TYPE 0x8290
+#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8
+#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED
+#define GL_TEXTURE_INTENSITY_SIZE 0x8061
+#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061
+#define GL_TEXTURE_INTENSITY_TYPE 0x8C15
+#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15
+#define GL_TEXTURE_INTERNAL_FORMAT 0x1003
+#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5
+#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C
+#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167
+#define GL_TEXTURE_LIGHT_EXT 0x8350
+#define GL_TEXTURE_LOD_BIAS 0x8501
+#define GL_TEXTURE_LOD_BIAS_EXT 0x8501
+#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190
+#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E
+#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F
+#define GL_TEXTURE_LO_SIZE_NV 0x871C
+#define GL_TEXTURE_LUMINANCE_SIZE 0x8060
+#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060
+#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14
+#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#define GL_TEXTURE_MAG_SIZE_NV 0x871F
+#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351
+#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352
+#define GL_TEXTURE_MATRIX 0x0BA8
+#define GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES 0x898F
+#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
+#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B
+#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369
+#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_MAX_LOD_SGIS 0x813B
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_MIN_LOD_SGIS 0x813A
+#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E
+#define GL_TEXTURE_NORMAL_EXT 0x85AF
+#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9
+#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB
+#define GL_TEXTURE_POST_SPECULAR_HP 0x8168
+#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169
+#define GL_TEXTURE_PRIORITY 0x8066
+#define GL_TEXTURE_PRIORITY_EXT 0x8066
+#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7
+#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8
+#define GL_TEXTURE_RECTANGLE 0x84F5
+#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
+#define GL_TEXTURE_RECTANGLE_NV 0x84F5
+#define GL_TEXTURE_RED_SIZE 0x805C
+#define GL_TEXTURE_RED_SIZE_EXT 0x805C
+#define GL_TEXTURE_RED_TYPE 0x8C10
+#define GL_TEXTURE_RED_TYPE_ARB 0x8C10
+#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54
+#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55
+#define GL_TEXTURE_RESIDENT 0x8067
+#define GL_TEXTURE_RESIDENT_EXT 0x8067
+#define GL_TEXTURE_SAMPLES 0x9106
+#define GL_TEXTURE_SAMPLES_IMG 0x9136
+#define GL_TEXTURE_SHADER_NV 0x86DE
+#define GL_TEXTURE_SHADOW 0x82A1
+#define GL_TEXTURE_SHARED_SIZE 0x8C3F
+#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F
+#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48
+#define GL_TEXTURE_STACK_DEPTH 0x0BA5
+#define GL_TEXTURE_STENCIL_SIZE 0x88F1
+#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
+#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC
+#define GL_TEXTURE_STORAGE_SPARSE_BIT_AMD 0x00000001
+#define GL_TEXTURE_SWIZZLE_A 0x8E45
+#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45
+#define GL_TEXTURE_SWIZZLE_B 0x8E44
+#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44
+#define GL_TEXTURE_SWIZZLE_G 0x8E43
+#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43
+#define GL_TEXTURE_SWIZZLE_R 0x8E42
+#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
+#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46
+#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42
+#define GL_TEXTURE_TARGET_QCOM 0x8BDA
+#define GL_TEXTURE_TOO_LARGE_EXT 0x8065
+#define GL_TEXTURE_TYPE_QCOM 0x8BD7
+#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F
+#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100
+#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100
+#define GL_TEXTURE_USAGE_ANGLE 0x93A2
+#define GL_TEXTURE_VIEW 0x82B5
+#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD
+#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB
+#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE
+#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC
+#define GL_TEXTURE_WIDTH 0x1000
+#define GL_TEXTURE_WIDTH_QCOM 0x8BD2
+#define GL_TEXTURE_WRAP_Q_SGIS 0x8137
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_TEXTURE_WRAP_R_EXT 0x8072
+#define GL_TEXTURE_WRAP_R_OES 0x8072
+#define GL_TEXTURE_WRAP_S 0x2802
+#define GL_TEXTURE_WRAP_T 0x2803
+#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200
+#define GL_TIMEOUT_EXPIRED 0x911B
+#define GL_TIMEOUT_EXPIRED_APPLE 0x911B
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
+#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFFull
+#define GL_TIMESTAMP 0x8E28
+#define GL_TIME_ELAPSED 0x88BF
+#define GL_TIME_ELAPSED_EXT 0x88BF
+#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C
+#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D
+#define GL_TRACE_ALL_BITS_MESA 0xFFFF
+#define GL_TRACE_ARRAYS_BIT_MESA 0x0004
+#define GL_TRACE_ERRORS_BIT_MESA 0x0020
+#define GL_TRACE_MASK_MESA 0x8755
+#define GL_TRACE_NAME_MESA 0x8756
+#define GL_TRACE_OPERATIONS_BIT_MESA 0x0001
+#define GL_TRACE_PIXELS_BIT_MESA 0x0010
+#define GL_TRACE_PRIMITIVES_BIT_MESA 0x0002
+#define GL_TRACE_TEXTURES_BIT_MESA 0x0008
+#define GL_TRACK_MATRIX_NV 0x8648
+#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649
+#define GL_TRANSFORM_BIT 0x00001000
+#define GL_TRANSFORM_FEEDBACK 0x8E22
+#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E
+#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800
+#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800
+#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
+#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25
+#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F
+#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F
+#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84
+#define GL_TRANSFORM_FEEDBACK_NV 0x8E22
+#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88
+#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86
+#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4
+#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
+#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83
+#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76
+#define GL_TRANSFORM_HINT_APPLE 0x85B1
+#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0
+#define GL_TRANSLATE_2D_NV 0x9090
+#define GL_TRANSLATE_3D_NV 0x9091
+#define GL_TRANSLATE_X_NV 0x908E
+#define GL_TRANSLATE_Y_NV 0x908F
+#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096
+#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098
+#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6
+#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6
+#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7
+#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3
+#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3
+#define GL_TRANSPOSE_NV 0x862C
+#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E
+#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4
+#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4
+#define GL_TRANSPOSE_PROJECTIVE_2D_NV 0x9097
+#define GL_TRANSPOSE_PROJECTIVE_3D_NV 0x9099
+#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5
+#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5
+#define GL_TRIANGLES 0x0004
+#define GL_TRIANGLES_ADJACENCY 0x000C
+#define GL_TRIANGLES_ADJACENCY_ARB 0x000C
+#define GL_TRIANGLES_ADJACENCY_EXT 0x000C
+#define GL_TRIANGLE_FAN 0x0006
+#define GL_TRIANGLE_LIST_SUN 0x81D7
+#define GL_TRIANGLE_MESH_SUN 0x8615
+#define GL_TRIANGLE_STRIP 0x0005
+#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D
+#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D
+#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D
+#define GL_TRIANGULAR_NV 0x90A5
+#define GL_TRUE 1
+#define GL_TYPE 0x92FA
+#define GL_TYPE_RGBA_FLOAT_ATI 0x8820
+#define GL_UNDEFINED_APPLE 0x8A1C
+#define GL_UNDEFINED_VERTEX 0x8260
+#define GL_UNIFORM 0x92E1
+#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
+#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA
+#define GL_UNIFORM_BARRIER_BIT 0x00000004
+#define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004
+#define GL_UNIFORM_BLOCK 0x92E2
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
+#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
+#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
+#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
+#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
+#define GL_UNIFORM_BUFFER 0x8A11
+#define GL_UNIFORM_BUFFER_BINDING 0x8A28
+#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF
+#define GL_UNIFORM_BUFFER_EXT 0x8DEE
+#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
+#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
+#define GL_UNIFORM_BUFFER_START 0x8A29
+#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
+#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
+#define GL_UNIFORM_NAME_LENGTH 0x8A39
+#define GL_UNIFORM_OFFSET 0x8A3B
+#define GL_UNIFORM_SIZE 0x8A38
+#define GL_UNIFORM_TYPE 0x8A37
+#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255
+#define GL_UNPACK_ALIGNMENT 0x0CF5
+#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2
+#define GL_UNPACK_CMYK_HINT_EXT 0x800F
+#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129
+#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128
+#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A
+#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127
+#define GL_UNPACK_COMPRESSED_SIZE_SGIX 0x831A
+#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5
+#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E
+#define GL_UNPACK_LSB_FIRST 0x0CF1
+#define GL_UNPACK_RESAMPLE_OML 0x8985
+#define GL_UNPACK_RESAMPLE_SGIX 0x842D
+#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D
+#define GL_UNPACK_SKIP_PIXELS 0x0CF4
+#define GL_UNPACK_SKIP_ROWS 0x0CF3
+#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132
+#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1
+#define GL_UNPACK_SWAP_BYTES 0x0CF0
+#define GL_UNSIGNALED 0x9118
+#define GL_UNSIGNALED_APPLE 0x9118
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
+#define GL_UNSIGNED_BYTE_2_3_3_REV_EXT 0x8362
+#define GL_UNSIGNED_BYTE_3_3_2 0x8032
+#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032
+#define GL_UNSIGNED_IDENTITY_NV 0x8536
+#define GL_UNSIGNED_INT 0x1405
+#define GL_UNSIGNED_INT16_NV 0x8FF0
+#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1
+#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2
+#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3
+#define GL_UNSIGNED_INT64_AMD 0x8BC2
+#define GL_UNSIGNED_INT64_NV 0x140F
+#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5
+#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6
+#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7
+#define GL_UNSIGNED_INT8_NV 0x8FEC
+#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED
+#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE
+#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF
+#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
+#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B
+#define GL_UNSIGNED_INT_10_10_10_2 0x8036
+#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036
+#define GL_UNSIGNED_INT_10_10_10_2_OES 0x8DF6
+#define GL_UNSIGNED_INT_24_8 0x84FA
+#define GL_UNSIGNED_INT_24_8_EXT 0x84FA
+#define GL_UNSIGNED_INT_24_8_MESA 0x8751
+#define GL_UNSIGNED_INT_24_8_NV 0x84FA
+#define GL_UNSIGNED_INT_24_8_OES 0x84FA
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368
+#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
+#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E
+#define GL_UNSIGNED_INT_8_24_REV_MESA 0x8752
+#define GL_UNSIGNED_INT_8_8_8_8 0x8035
+#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035
+#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
+#define GL_UNSIGNED_INT_8_8_8_8_REV_EXT 0x8367
+#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB
+#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB
+#define GL_UNSIGNED_INT_IMAGE_1D 0x9062
+#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068
+#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068
+#define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062
+#define GL_UNSIGNED_INT_IMAGE_2D 0x9063
+#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069
+#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069
+#define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B
+#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065
+#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065
+#define GL_UNSIGNED_INT_IMAGE_3D 0x9064
+#define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064
+#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067
+#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067
+#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066
+#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A
+#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA
+#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1
+#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6
+#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6
+#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1
+#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7
+#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D
+#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5
+#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5
+#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8
+#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F
+#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58
+#define GL_UNSIGNED_INT_VEC2 0x8DC6
+#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6
+#define GL_UNSIGNED_INT_VEC3 0x8DC7
+#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7
+#define GL_UNSIGNED_INT_VEC4 0x8DC8
+#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8
+#define GL_UNSIGNED_INVERT_NV 0x8537
+#define GL_UNSIGNED_NEGATE_NV 0x853D
+#define GL_UNSIGNED_NORMALIZED 0x8C17
+#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17
+#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17
+#define GL_UNSIGNED_SHORT 0x1403
+#define GL_UNSIGNED_SHORT_15_1_MESA 0x8753
+#define GL_UNSIGNED_SHORT_1_15_REV_MESA 0x8754
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define GL_UNSIGNED_SHORT_5_6_5_EXT 0x8363
+#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
+#define GL_UNSIGNED_SHORT_5_6_5_REV_EXT 0x8364
+#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA
+#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB
+#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB
+#define GL_UPPER_LEFT 0x8CA2
+#define GL_USE_MISSING_GLYPH_NV 0x90AA
+#define GL_UTF16_NV 0x909B
+#define GL_UTF8_NV 0x909A
+#define GL_V2F 0x2A20
+#define GL_V3F 0x2A21
+#define GL_VALIDATE_STATUS 0x8B83
+#define GL_VARIABLE_A_NV 0x8523
+#define GL_VARIABLE_B_NV 0x8524
+#define GL_VARIABLE_C_NV 0x8525
+#define GL_VARIABLE_D_NV 0x8526
+#define GL_VARIABLE_E_NV 0x8527
+#define GL_VARIABLE_F_NV 0x8528
+#define GL_VARIABLE_G_NV 0x8529
+#define GL_VARIANT_ARRAY_EXT 0x87E8
+#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9
+#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6
+#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7
+#define GL_VARIANT_DATATYPE_EXT 0x87E5
+#define GL_VARIANT_EXT 0x87C1
+#define GL_VARIANT_VALUE_EXT 0x87E4
+#define GL_VBO_FREE_MEMORY_ATI 0x87FB
+#define GL_VECTOR_EXT 0x87BF
+#define GL_VENDOR 0x1F00
+#define GL_VERSION 0x1F02
+#define GL_VERSION_1_1 1
+#define GL_VERSION_1_2 1
+#define GL_VERSION_1_3 1
+#define GL_VERSION_1_4 1
+#define GL_VERSION_1_5 1
+#define GL_VERSION_2_0 1
+#define GL_VERSION_2_1 1
+#define GL_VERSION_3_0 1
+#define GL_VERSION_3_1 1
+#define GL_VERSION_3_2 1
+#define GL_VERTEX23_BIT_PGI 0x00000004
+#define GL_VERTEX4_BIT_PGI 0x00000008
+#define GL_VERTEX_ARRAY 0x8074
+#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5
+#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896
+#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896
+#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D
+#define GL_VERTEX_ARRAY_EXT 0x8074
+#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B
+#define GL_VERTEX_ARRAY_LIST_IBM 103070
+#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080
+#define GL_VERTEX_ARRAY_OBJECT_AMD 0x9154
+#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154
+#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5
+#define GL_VERTEX_ARRAY_POINTER 0x808E
+#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E
+#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D
+#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E
+#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E
+#define GL_VERTEX_ARRAY_RANGE_NV 0x851D
+#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521
+#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521
+#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F
+#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533
+#define GL_VERTEX_ARRAY_SIZE 0x807A
+#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A
+#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F
+#define GL_VERTEX_ARRAY_STRIDE 0x807C
+#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C
+#define GL_VERTEX_ARRAY_TYPE 0x807B
+#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B
+#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650
+#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A
+#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B
+#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C
+#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D
+#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E
+#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F
+#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651
+#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652
+#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653
+#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654
+#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655
+#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656
+#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657
+#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658
+#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659
+#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20
+#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001
+#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD
+#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A
+#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625
+#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E
+#define GL_VERTEX_ATTRIB_BINDING 0x82D4
+#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00
+#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03
+#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05
+#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04
+#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02
+#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01
+#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07
+#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09
+#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08
+#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06
+#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5
+#define GL_VERTEX_BINDING_DIVISOR 0x82D6
+#define GL_VERTEX_BINDING_OFFSET 0x82D7
+#define GL_VERTEX_BINDING_STRIDE 0x82D8
+#define GL_VERTEX_BLEND_ARB 0x86A7
+#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B
+#define GL_VERTEX_DATA_HINT_PGI 0x1A22A
+#define GL_VERTEX_ID_NV 0x8C7B
+#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF
+#define GL_VERTEX_PRECLIP_SGIX 0x83EE
+#define GL_VERTEX_PROGRAM_ARB 0x8620
+#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A
+#define GL_VERTEX_PROGRAM_CALLBACK_DATA_MESA 0x8BB7
+#define GL_VERTEX_PROGRAM_CALLBACK_FUNC_MESA 0x8BB6
+#define GL_VERTEX_PROGRAM_CALLBACK_MESA 0x8BB4
+#define GL_VERTEX_PROGRAM_NV 0x8620
+#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2
+#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
+#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642
+#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642
+#define GL_VERTEX_PROGRAM_POSITION_MESA 0x8BB4
+#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643
+#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643
+#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_VERTEX_SHADER_ARB 0x8B31
+#define GL_VERTEX_SHADER_BINDING_EXT 0x8781
+#define GL_VERTEX_SHADER_BIT 0x00000001
+#define GL_VERTEX_SHADER_BIT_EXT 0x00000001
+#define GL_VERTEX_SHADER_EXT 0x8780
+#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF
+#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1
+#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3
+#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2
+#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4
+#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0
+#define GL_VERTEX_SOURCE_ATI 0x8774
+#define GL_VERTEX_STATE_PROGRAM_NV 0x8621
+#define GL_VERTEX_STREAM0_ATI 0x876C
+#define GL_VERTEX_STREAM1_ATI 0x876D
+#define GL_VERTEX_STREAM2_ATI 0x876E
+#define GL_VERTEX_STREAM3_ATI 0x876F
+#define GL_VERTEX_STREAM4_ATI 0x8770
+#define GL_VERTEX_STREAM5_ATI 0x8771
+#define GL_VERTEX_STREAM6_ATI 0x8772
+#define GL_VERTEX_STREAM7_ATI 0x8773
+#define GL_VERTEX_SUBROUTINE 0x92E8
+#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE
+#define GL_VERTEX_TEXTURE 0x829B
+#define GL_VERTEX_WEIGHTING_EXT 0x8509
+#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C
+#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510
+#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D
+#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F
+#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E
+#define GL_VERTICAL_LINE_TO_NV 0x08
+#define GL_VIBRANCE_BIAS_NV 0x8719
+#define GL_VIBRANCE_SCALE_NV 0x8713
+#define GL_VIDEO_BUFFER_BINDING_NV 0x9021
+#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D
+#define GL_VIDEO_BUFFER_NV 0x9020
+#define GL_VIDEO_BUFFER_PITCH_NV 0x9028
+#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B
+#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A
+#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039
+#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038
+#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C
+#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026
+#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029
+#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A
+#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B
+#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C
+#define GL_VIEWPORT 0x0BA2
+#define GL_VIEWPORT_BIT 0x00000800
+#define GL_VIEWPORT_BOUNDS_RANGE 0x825D
+#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F
+#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C
+#define GL_VIEW_CLASS_128_BITS 0x82C4
+#define GL_VIEW_CLASS_16_BITS 0x82CA
+#define GL_VIEW_CLASS_24_BITS 0x82C9
+#define GL_VIEW_CLASS_32_BITS 0x82C8
+#define GL_VIEW_CLASS_48_BITS 0x82C7
+#define GL_VIEW_CLASS_64_BITS 0x82C6
+#define GL_VIEW_CLASS_8_BITS 0x82CB
+#define GL_VIEW_CLASS_96_BITS 0x82C5
+#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3
+#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2
+#define GL_VIEW_CLASS_RGTC1_RED 0x82D0
+#define GL_VIEW_CLASS_RGTC2_RG 0x82D1
+#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC
+#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD
+#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE
+#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF
+#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6
+#define GL_VIRTUAL_PAGE_SIZE_X_AMD 0x9195
+#define GL_VIRTUAL_PAGE_SIZE_Y_AMD 0x9196
+#define GL_VIRTUAL_PAGE_SIZE_Z_AMD 0x9197
+#define GL_VOLATILE_APPLE 0x8A1A
+#define GL_WAIT_FAILED 0x911D
+#define GL_WAIT_FAILED_APPLE 0x911D
+#define GL_WEIGHT_ARRAY_ARB 0x86AD
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING_OES 0x889E
+#define GL_WEIGHT_ARRAY_OES 0x86AD
+#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC
+#define GL_WEIGHT_ARRAY_POINTER_OES 0x86AC
+#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB
+#define GL_WEIGHT_ARRAY_SIZE_OES 0x86AB
+#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA
+#define GL_WEIGHT_ARRAY_STRIDE_OES 0x86AA
+#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9
+#define GL_WEIGHT_ARRAY_TYPE_OES 0x86A9
+#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6
+#define GL_WIDE_LINE_HINT_PGI 0x1A222
+#define GL_WRAP_BORDER_SUN 0x81D4
+#define GL_WRITEONLY_RENDERING_QCOM 0x8823
+#define GL_WRITE_DISCARD_NV 0x88BE
+#define GL_WRITE_ONLY 0x88B9
+#define GL_WRITE_ONLY_ARB 0x88B9
+#define GL_WRITE_ONLY_OES 0x88B9
+#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A
+#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878
+#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C
+#define GL_W_EXT 0x87D8
+#define GL_XOR 0x1506
+#define GL_X_EXT 0x87D5
+#define GL_YCBAYCR8A_4224_NV 0x9032
+#define GL_YCBCR_422_APPLE 0x85B9
+#define GL_YCBCR_MESA 0x8757
+#define GL_YCBYCR8_422_NV 0x9031
+#define GL_YCRCBA_SGIX 0x8319
+#define GL_YCRCB_422_SGIX 0x81BB
+#define GL_YCRCB_444_SGIX 0x81BC
+#define GL_YCRCB_SGIX 0x8318
+#define GL_Y_EXT 0x87D6
+#define GL_Z400_BINARY_AMD 0x8740
+#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036
+#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037
+#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035
+#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034
+#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033
+#define GL_ZERO 0
+#define GL_ZERO_EXT 0x87DD
+#define GL_ZOOM_X 0x0D16
+#define GL_ZOOM_Y 0x0D17
+#define GL_Z_EXT 0x87D7
+
+void GLAPIENTRY glAccum(GLenum,GLfloat);
+void GLAPIENTRY glAlphaFunc(GLenum,GLfloat);
+GLboolean GLAPIENTRY glAreTexturesResident(GLsizei,const GLuint*,GLboolean*);
+void GLAPIENTRY glArrayElement(GLint);
+void GLAPIENTRY glBegin(GLenum);
+void GLAPIENTRY glBindTexture(GLenum,GLuint);
+void GLAPIENTRY glBitmap(GLsizei,GLsizei,GLfloat,GLfloat,GLfloat,GLfloat,const GLubyte*);
+void GLAPIENTRY glBlendFunc(GLenum,GLenum);
+void GLAPIENTRY glCallList(GLuint);
+void GLAPIENTRY glCallLists(GLsizei,GLenum,const GLvoid*);
+void GLAPIENTRY glClear(GLbitfield);
+void GLAPIENTRY glClearAccum(GLfloat,GLfloat,GLfloat,GLfloat);
+void GLAPIENTRY glClearColor(GLfloat,GLfloat,GLfloat,GLfloat);
+void GLAPIENTRY glClearDepth(GLdouble);
+void GLAPIENTRY glClearIndex(GLfloat);
+void GLAPIENTRY glClearStencil(GLint);
+void GLAPIENTRY glClipPlane(GLenum,const GLdouble*);
+void GLAPIENTRY glColor3b(GLbyte,GLbyte,GLbyte);
+void GLAPIENTRY glColor3bv(const GLbyte*);
+void GLAPIENTRY glColor3d(GLdouble,GLdouble,GLdouble);
+void GLAPIENTRY glColor3dv(const GLdouble*);
+void GLAPIENTRY glColor3f(GLfloat,GLfloat,GLfloat);
+void GLAPIENTRY glColor3fv(const GLfloat*);
+void GLAPIENTRY glColor3i(GLint,GLint,GLint);
+void GLAPIENTRY glColor3iv(const GLint*);
+void GLAPIENTRY glColor3s(GLshort,GLshort,GLshort);
+void GLAPIENTRY glColor3sv(const GLshort*);
+void GLAPIENTRY glColor3ub(GLubyte,GLubyte,GLubyte);
+void GLAPIENTRY glColor3ubv(const GLubyte*);
+void GLAPIENTRY glColor3ui(GLuint,GLuint,GLuint);
+void GLAPIENTRY glColor3uiv(const GLuint*);
+void GLAPIENTRY glColor3us(GLushort,GLushort,GLushort);
+void GLAPIENTRY glColor3usv(const GLushort*);
+void GLAPIENTRY glColor4b(GLbyte,GLbyte,GLbyte,GLbyte);
+void GLAPIENTRY glColor4bv(const GLbyte*);
+void GLAPIENTRY glColor4d(GLdouble,GLdouble,GLdouble,GLdouble);
+void GLAPIENTRY glColor4dv(const GLdouble*);
+void GLAPIENTRY glColor4f(GLfloat,GLfloat,GLfloat,GLfloat);
+void GLAPIENTRY glColor4fv(const GLfloat*);
+void GLAPIENTRY glColor4i(GLint,GLint,GLint,GLint);
+void GLAPIENTRY glColor4iv(const GLint*);
+void GLAPIENTRY glColor4s(GLshort,GLshort,GLshort,GLshort);
+void GLAPIENTRY glColor4sv(const GLshort*);
+void GLAPIENTRY glColor4ub(GLubyte,GLubyte,GLubyte,GLubyte);
+void GLAPIENTRY glColor4ubv(const GLubyte*);
+void GLAPIENTRY glColor4ui(GLuint,GLuint,GLuint,GLuint);
+void GLAPIENTRY glColor4uiv(const GLuint*);
+void GLAPIENTRY glColor4us(GLushort,GLushort,GLushort,GLushort);
+void GLAPIENTRY glColor4usv(const GLushort*);
+void GLAPIENTRY glColorMask(GLboolean,GLboolean,GLboolean,GLboolean);
+void GLAPIENTRY glColorMaterial(GLenum,GLenum);
+void GLAPIENTRY glColorPointer(GLint,GLenum,GLsizei,const GLvoid*);
+void GLAPIENTRY glCopyPixels(GLint,GLint,GLsizei,GLsizei,GLenum);
+void GLAPIENTRY glCopyTexImage1D(GLenum,GLint,GLenum,GLint,GLint,GLsizei,GLint);
+void GLAPIENTRY glCopyTexImage2D(GLenum,GLint,GLenum,GLint,GLint,GLsizei,GLsizei,GLint);
+void GLAPIENTRY glCopyTexSubImage1D(GLenum,GLint,GLint,GLint,GLint,GLsizei);
+void GLAPIENTRY glCopyTexSubImage2D(GLenum,GLint,GLint,GLint,GLint,GLint,GLsizei,GLsizei);
+void GLAPIENTRY glCullFace(GLenum);
+GLint GLAPIENTRY glDebugEntry(GLint,GLint);
+void GLAPIENTRY glDeleteLists(GLuint,GLsizei);
+void GLAPIENTRY glDeleteTextures(GLsizei,const GLuint*);
+void GLAPIENTRY glDepthFunc(GLenum);
+void GLAPIENTRY glDepthMask(GLboolean);
+void GLAPIENTRY glDepthRange(GLdouble,GLdouble);
+void GLAPIENTRY glDisable(GLenum);
+void GLAPIENTRY glDisableClientState(GLenum);
+void GLAPIENTRY glDrawArrays(GLenum,GLint,GLsizei);
+void GLAPIENTRY glDrawBuffer(GLenum);
+void GLAPIENTRY glDrawElements(GLenum,GLsizei,GLenum,const GLvoid*);
+void GLAPIENTRY glDrawPixels(GLsizei,GLsizei,GLenum,GLenum,const GLvoid*);
+void GLAPIENTRY glEdgeFlag(GLboolean);
+void GLAPIENTRY glEdgeFlagPointer(GLsizei,const GLvoid*);
+void GLAPIENTRY glEdgeFlagv(const GLboolean*);
+void GLAPIENTRY glEnable(GLenum);
+void GLAPIENTRY glEnableClientState(GLenum);
+void GLAPIENTRY glEnd(void);
+void GLAPIENTRY glEndList(void);
+void GLAPIENTRY glEvalCoord1d(GLdouble);
+void GLAPIENTRY glEvalCoord1dv(const GLdouble*);
+void GLAPIENTRY glEvalCoord1f(GLfloat);
+void GLAPIENTRY glEvalCoord1fv(const GLfloat*);
+void GLAPIENTRY glEvalCoord2d(GLdouble,GLdouble);
+void GLAPIENTRY glEvalCoord2dv(const GLdouble*);
+void GLAPIENTRY glEvalCoord2f(GLfloat,GLfloat);
+void GLAPIENTRY glEvalCoord2fv(const GLfloat*);
+void GLAPIENTRY glEvalMesh1(GLenum,GLint,GLint);
+void GLAPIENTRY glEvalMesh2(GLenum,GLint,GLint,GLint,GLint);
+void GLAPIENTRY glEvalPoint1(GLint);
+void GLAPIENTRY glEvalPoint2(GLint,GLint);
+void GLAPIENTRY glFeedbackBuffer(GLsizei,GLenum,GLfloat*);
+void GLAPIENTRY glFinish(void);
+void GLAPIENTRY glFlush(void);
+void GLAPIENTRY glFogf(GLenum,GLfloat);
+void GLAPIENTRY glFogfv(GLenum,const GLfloat*);
+void GLAPIENTRY glFogi(GLenum,GLint);
+void GLAPIENTRY glFogiv(GLenum,const GLint*);
+void GLAPIENTRY glFrontFace(GLenum);
+void GLAPIENTRY glFrustum(GLdouble,GLdouble,GLdouble,GLdouble,GLdouble,GLdouble);
+GLuint GLAPIENTRY glGenLists(GLsizei);
+void GLAPIENTRY glGenTextures(GLsizei,GLuint*);
+void GLAPIENTRY glGetBooleanv(GLenum,GLboolean*);
+void GLAPIENTRY glGetClipPlane(GLenum,GLdouble*);
+void GLAPIENTRY glGetDoublev(GLenum,GLdouble*);
+GLenum GLAPIENTRY glGetError(void);
+void GLAPIENTRY glGetFloatv(GLenum,GLfloat*);
+void GLAPIENTRY glGetIntegerv(GLenum,GLint*);
+void GLAPIENTRY glGetLightfv(GLenum,GLenum,GLfloat*);
+void GLAPIENTRY glGetLightiv(GLenum,GLenum,GLint*);
+void GLAPIENTRY glGetMapdv(GLenum,GLenum,GLdouble*);
+void GLAPIENTRY glGetMapfv(GLenum,GLenum,GLfloat*);
+void GLAPIENTRY glGetMapiv(GLenum,GLenum,GLint*);
+void GLAPIENTRY glGetMaterialfv(GLenum,GLenum,GLfloat*);
+void GLAPIENTRY glGetMaterialiv(GLenum,GLenum,GLint*);
+void GLAPIENTRY glGetPixelMapfv(GLenum,GLfloat*);
+void GLAPIENTRY glGetPixelMapuiv(GLenum,GLuint*);
+void GLAPIENTRY glGetPixelMapusv(GLenum,GLushort*);
+void GLAPIENTRY glGetPointerv(GLenum,GLvoid**);
+void GLAPIENTRY glGetPolygonStipple(GLubyte*);
+const GLubyte * GLAPIENTRY glGetString(GLenum);
+void GLAPIENTRY glGetTexEnvfv(GLenum,GLenum,GLfloat*);
+void GLAPIENTRY glGetTexEnviv(GLenum,GLenum,GLint*);
+void GLAPIENTRY glGetTexGendv(GLenum,GLenum,GLdouble*);
+void GLAPIENTRY glGetTexGenfv(GLenum,GLenum,GLfloat*);
+void GLAPIENTRY glGetTexGeniv(GLenum,GLenum,GLint*);
+void GLAPIENTRY glGetTexImage(GLenum,GLint,GLenum,GLenum,GLvoid*);
+void GLAPIENTRY glGetTexLevelParameterfv(GLenum,GLint,GLenum,GLfloat*);
+void GLAPIENTRY glGetTexLevelParameteriv(GLenum,GLint,GLenum,GLint*);
+void GLAPIENTRY glGetTexParameterfv(GLenum,GLenum,GLfloat*);
+void GLAPIENTRY glGetTexParameteriv(GLenum,GLenum,GLint*);
+void GLAPIENTRY glHint(GLenum,GLenum);
+void GLAPIENTRY glIndexMask(GLuint);
+void GLAPIENTRY glIndexPointer(GLenum,GLsizei,const GLvoid*);
+void GLAPIENTRY glIndexd(GLdouble);
+void GLAPIENTRY glIndexdv(const GLdouble*);
+void GLAPIENTRY glIndexf(GLfloat);
+void GLAPIENTRY glIndexfv(const GLfloat*);
+void GLAPIENTRY glIndexi(GLint);
+void GLAPIENTRY glIndexiv(const GLint*);
+void GLAPIENTRY glIndexs(GLshort);
+void GLAPIENTRY glIndexsv(const GLshort*);
+void GLAPIENTRY glIndexub(GLubyte);
+void GLAPIENTRY glIndexubv(const GLubyte*);
+void GLAPIENTRY glInitNames(void);
+void GLAPIENTRY glInterleavedArrays(GLenum,GLsizei,const GLvoid*);
+GLboolean GLAPIENTRY glIsEnabled(GLenum);
+GLboolean GLAPIENTRY glIsList(GLuint);
+GLboolean GLAPIENTRY glIsTexture(GLuint);
+void GLAPIENTRY glLightModelf(GLenum,GLfloat);
+void GLAPIENTRY glLightModelfv(GLenum,const GLfloat*);
+void GLAPIENTRY glLightModeli(GLenum,GLint);
+void GLAPIENTRY glLightModeliv(GLenum,const GLint*);
+void GLAPIENTRY glLightf(GLenum,GLenum,GLfloat);
+void GLAPIENTRY glLightfv(GLenum,GLenum,const GLfloat*);
+void GLAPIENTRY glLighti(GLenum,GLenum,GLint);
+void GLAPIENTRY glLightiv(GLenum,GLenum,const GLint*);
+void GLAPIENTRY glLineStipple(GLint,GLushort);
+void GLAPIENTRY glLineWidth(GLfloat);
+void GLAPIENTRY glListBase(GLuint);
+void GLAPIENTRY glLoadIdentity(void);
+void GLAPIENTRY glLoadMatrixd(const GLdouble*);
+void GLAPIENTRY glLoadMatrixf(const GLfloat*);
+void GLAPIENTRY glLoadName(GLuint);
+void GLAPIENTRY glLogicOp(GLenum);
+void GLAPIENTRY glMap1d(GLenum,GLdouble,GLdouble,GLint,GLint,const GLdouble*);
+void GLAPIENTRY glMap1f(GLenum,GLfloat,GLfloat,GLint,GLint,const GLfloat*);
+void GLAPIENTRY glMap2d(GLenum,GLdouble,GLdouble,GLint,GLint,GLdouble,GLdouble,GLint,GLint,const GLdouble*);
+void GLAPIENTRY glMap2f(GLenum,GLfloat,GLfloat,GLint,GLint,GLfloat,GLfloat,GLint,GLint,const GLfloat*);
+void GLAPIENTRY glMapGrid1d(GLint,GLdouble,GLdouble);
+void GLAPIENTRY glMapGrid1f(GLint,GLfloat,GLfloat);
+void GLAPIENTRY glMapGrid2d(GLint,GLdouble,GLdouble,GLint,GLdouble,GLdouble);
+void GLAPIENTRY glMapGrid2f(GLint,GLfloat,GLfloat,GLint,GLfloat,GLfloat);
+void GLAPIENTRY glMaterialf(GLenum,GLenum,GLfloat);
+void GLAPIENTRY glMaterialfv(GLenum,GLenum,const GLfloat*);
+void GLAPIENTRY glMateriali(GLenum,GLenum,GLint);
+void GLAPIENTRY glMaterialiv(GLenum,GLenum,const GLint*);
+void GLAPIENTRY glMatrixMode(GLenum);
+void GLAPIENTRY glMultMatrixd(const GLdouble*);
+void GLAPIENTRY glMultMatrixf(const GLfloat*);
+void GLAPIENTRY glNewList(GLuint,GLenum);
+void GLAPIENTRY glNormal3b(GLbyte,GLbyte,GLbyte);
+void GLAPIENTRY glNormal3bv(const GLbyte*);
+void GLAPIENTRY glNormal3d(GLdouble,GLdouble,GLdouble);
+void GLAPIENTRY glNormal3dv(const GLdouble*);
+void GLAPIENTRY glNormal3f(GLfloat,GLfloat,GLfloat);
+void GLAPIENTRY glNormal3fv(const GLfloat*);
+void GLAPIENTRY glNormal3i(GLint,GLint,GLint);
+void GLAPIENTRY glNormal3iv(const GLint*);
+void GLAPIENTRY glNormal3s(GLshort,GLshort,GLshort);
+void GLAPIENTRY glNormal3sv(const GLshort*);
+void GLAPIENTRY glNormalPointer(GLenum,GLsizei,const GLvoid*);
+void GLAPIENTRY glOrtho(GLdouble,GLdouble,GLdouble,GLdouble,GLdouble,GLdouble);
+void GLAPIENTRY glPassThrough(GLfloat);
+void GLAPIENTRY glPixelMapfv(GLenum,GLint,const GLfloat*);
+void GLAPIENTRY glPixelMapuiv(GLenum,GLint,const GLuint*);
+void GLAPIENTRY glPixelMapusv(GLenum,GLint,const GLushort*);
+void GLAPIENTRY glPixelStoref(GLenum,GLfloat);
+void GLAPIENTRY glPixelStorei(GLenum,GLint);
+void GLAPIENTRY glPixelTransferf(GLenum,GLfloat);
+void GLAPIENTRY glPixelTransferi(GLenum,GLint);
+void GLAPIENTRY glPixelZoom(GLfloat,GLfloat);
+void GLAPIENTRY glPointSize(GLfloat);
+void GLAPIENTRY glPolygonMode(GLenum,GLenum);
+void GLAPIENTRY glPolygonOffset(GLfloat,GLfloat);
+void GLAPIENTRY glPolygonStipple(const GLubyte*);
+void GLAPIENTRY glPopAttrib(void);
+void GLAPIENTRY glPopClientAttrib(void);
+void GLAPIENTRY glPopMatrix(void);
+void GLAPIENTRY glPopName(void);
+void GLAPIENTRY glPrioritizeTextures(GLsizei,const GLuint*,const GLfloat*);
+void GLAPIENTRY glPushAttrib(GLbitfield);
+void GLAPIENTRY glPushClientAttrib(GLbitfield);
+void GLAPIENTRY glPushMatrix(void);
+void GLAPIENTRY glPushName(GLuint);
+void GLAPIENTRY glRasterPos2d(GLdouble,GLdouble);
+void GLAPIENTRY glRasterPos2dv(const GLdouble*);
+void GLAPIENTRY glRasterPos2f(GLfloat,GLfloat);
+void GLAPIENTRY glRasterPos2fv(const GLfloat*);
+void GLAPIENTRY glRasterPos2i(GLint,GLint);
+void GLAPIENTRY glRasterPos2iv(const GLint*);
+void GLAPIENTRY glRasterPos2s(GLshort,GLshort);
+void GLAPIENTRY glRasterPos2sv(const GLshort*);
+void GLAPIENTRY glRasterPos3d(GLdouble,GLdouble,GLdouble);
+void GLAPIENTRY glRasterPos3dv(const GLdouble*);
+void GLAPIENTRY glRasterPos3f(GLfloat,GLfloat,GLfloat);
+void GLAPIENTRY glRasterPos3fv(const GLfloat*);
+void GLAPIENTRY glRasterPos3i(GLint,GLint,GLint);
+void GLAPIENTRY glRasterPos3iv(const GLint*);
+void GLAPIENTRY glRasterPos3s(GLshort,GLshort,GLshort);
+void GLAPIENTRY glRasterPos3sv(const GLshort*);
+void GLAPIENTRY glRasterPos4d(GLdouble,GLdouble,GLdouble,GLdouble);
+void GLAPIENTRY glRasterPos4dv(const GLdouble*);
+void GLAPIENTRY glRasterPos4f(GLfloat,GLfloat,GLfloat,GLfloat);
+void GLAPIENTRY glRasterPos4fv(const GLfloat*);
+void GLAPIENTRY glRasterPos4i(GLint,GLint,GLint,GLint);
+void GLAPIENTRY glRasterPos4iv(const GLint*);
+void GLAPIENTRY glRasterPos4s(GLshort,GLshort,GLshort,GLshort);
+void GLAPIENTRY glRasterPos4sv(const GLshort*);
+void GLAPIENTRY glReadBuffer(GLenum);
+void GLAPIENTRY glReadPixels(GLint,GLint,GLsizei,GLsizei,GLenum,GLenum,GLvoid*);
+void GLAPIENTRY glRectd(GLdouble,GLdouble,GLdouble,GLdouble);
+void GLAPIENTRY glRectdv(const GLdouble*,const GLdouble*);
+void GLAPIENTRY glRectf(GLfloat,GLfloat,GLfloat,GLfloat);
+void GLAPIENTRY glRectfv(const GLfloat*,const GLfloat*);
+void GLAPIENTRY glRecti(GLint,GLint,GLint,GLint);
+void GLAPIENTRY glRectiv(const GLint*,const GLint*);
+void GLAPIENTRY glRects(GLshort,GLshort,GLshort,GLshort);
+void GLAPIENTRY glRectsv(const GLshort*,const GLshort*);
+GLint GLAPIENTRY glRenderMode(GLenum);
+void GLAPIENTRY glRotated(GLdouble,GLdouble,GLdouble,GLdouble);
+void GLAPIENTRY glRotatef(GLfloat,GLfloat,GLfloat,GLfloat);
+void GLAPIENTRY glScaled(GLdouble,GLdouble,GLdouble);
+void GLAPIENTRY glScalef(GLfloat,GLfloat,GLfloat);
+void GLAPIENTRY glScissor(GLint,GLint,GLsizei,GLsizei);
+void GLAPIENTRY glSelectBuffer(GLsizei,GLuint*);
+void GLAPIENTRY glShadeModel(GLenum);
+void GLAPIENTRY glStencilFunc(GLenum,GLint,GLuint);
+void GLAPIENTRY glStencilMask(GLuint);
+void GLAPIENTRY glStencilOp(GLenum,GLenum,GLenum);
+void GLAPIENTRY glTexCoord1d(GLdouble);
+void GLAPIENTRY glTexCoord1dv(const GLdouble*);
+void GLAPIENTRY glTexCoord1f(GLfloat);
+void GLAPIENTRY glTexCoord1fv(const GLfloat*);
+void GLAPIENTRY glTexCoord1i(GLint);
+void GLAPIENTRY glTexCoord1iv(const GLint*);
+void GLAPIENTRY glTexCoord1s(GLshort);
+void GLAPIENTRY glTexCoord1sv(const GLshort*);
+void GLAPIENTRY glTexCoord2d(GLdouble,GLdouble);
+void GLAPIENTRY glTexCoord2dv(const GLdouble*);
+void GLAPIENTRY glTexCoord2f(GLfloat,GLfloat);
+void GLAPIENTRY glTexCoord2fv(const GLfloat*);
+void GLAPIENTRY glTexCoord2i(GLint,GLint);
+void GLAPIENTRY glTexCoord2iv(const GLint*);
+void GLAPIENTRY glTexCoord2s(GLshort,GLshort);
+void GLAPIENTRY glTexCoord2sv(const GLshort*);
+void GLAPIENTRY glTexCoord3d(GLdouble,GLdouble,GLdouble);
+void GLAPIENTRY glTexCoord3dv(const GLdouble*);
+void GLAPIENTRY glTexCoord3f(GLfloat,GLfloat,GLfloat);
+void GLAPIENTRY glTexCoord3fv(const GLfloat*);
+void GLAPIENTRY glTexCoord3i(GLint,GLint,GLint);
+void GLAPIENTRY glTexCoord3iv(const GLint*);
+void GLAPIENTRY glTexCoord3s(GLshort,GLshort,GLshort);
+void GLAPIENTRY glTexCoord3sv(const GLshort*);
+void GLAPIENTRY glTexCoord4d(GLdouble,GLdouble,GLdouble,GLdouble);
+void GLAPIENTRY glTexCoord4dv(const GLdouble*);
+void GLAPIENTRY glTexCoord4f(GLfloat,GLfloat,GLfloat,GLfloat);
+void GLAPIENTRY glTexCoord4fv(const GLfloat*);
+void GLAPIENTRY glTexCoord4i(GLint,GLint,GLint,GLint);
+void GLAPIENTRY glTexCoord4iv(const GLint*);
+void GLAPIENTRY glTexCoord4s(GLshort,GLshort,GLshort,GLshort);
+void GLAPIENTRY glTexCoord4sv(const GLshort*);
+void GLAPIENTRY glTexCoordPointer(GLint,GLenum,GLsizei,const GLvoid*);
+void GLAPIENTRY glTexEnvf(GLenum,GLenum,GLfloat);
+void GLAPIENTRY glTexEnvfv(GLenum,GLenum,const GLfloat*);
+void GLAPIENTRY glTexEnvi(GLenum,GLenum,GLint);
+void GLAPIENTRY glTexEnviv(GLenum,GLenum,const GLint*);
+void GLAPIENTRY glTexGend(GLenum,GLenum,GLdouble);
+void GLAPIENTRY glTexGendv(GLenum,GLenum,const GLdouble*);
+void GLAPIENTRY glTexGenf(GLenum,GLenum,GLfloat);
+void GLAPIENTRY glTexGenfv(GLenum,GLenum,const GLfloat*);
+void GLAPIENTRY glTexGeni(GLenum,GLenum,GLint);
+void GLAPIENTRY glTexGeniv(GLenum,GLenum,const GLint*);
+void GLAPIENTRY glTexImage1D(GLenum,GLint,GLint,GLsizei,GLint,GLenum,GLenum,const GLvoid*);
+void GLAPIENTRY glTexImage2D(GLenum,GLint,GLint,GLsizei,GLsizei,GLint,GLenum,GLenum,const GLvoid*);
+void GLAPIENTRY glTexParameterf(GLenum,GLenum,GLfloat);
+void GLAPIENTRY glTexParameterfv(GLenum,GLenum,const GLfloat*);
+void GLAPIENTRY glTexParameteri(GLenum,GLenum,GLint);
+void GLAPIENTRY glTexParameteriv(GLenum,GLenum,const GLint*);
+void GLAPIENTRY glTexSubImage1D(GLenum,GLint,GLint,GLsizei,GLenum,GLenum,const GLvoid*);
+void GLAPIENTRY glTexSubImage2D(GLenum,GLint,GLint,GLint,GLsizei,GLsizei,GLenum,GLenum,const GLvoid*);
+void GLAPIENTRY glTranslated(GLdouble,GLdouble,GLdouble);
+void GLAPIENTRY glTranslatef(GLfloat,GLfloat,GLfloat);
+void GLAPIENTRY glVertex2d(GLdouble,GLdouble);
+void GLAPIENTRY glVertex2dv(const GLdouble*);
+void GLAPIENTRY glVertex2f(GLfloat,GLfloat);
+void GLAPIENTRY glVertex2fv(const GLfloat*);
+void GLAPIENTRY glVertex2i(GLint,GLint);
+void GLAPIENTRY glVertex2iv(const GLint*);
+void GLAPIENTRY glVertex2s(GLshort,GLshort);
+void GLAPIENTRY glVertex2sv(const GLshort*);
+void GLAPIENTRY glVertex3d(GLdouble,GLdouble,GLdouble);
+void GLAPIENTRY glVertex3dv(const GLdouble*);
+void GLAPIENTRY glVertex3f(GLfloat,GLfloat,GLfloat);
+void GLAPIENTRY glVertex3fv(const GLfloat*);
+void GLAPIENTRY glVertex3i(GLint,GLint,GLint);
+void GLAPIENTRY glVertex3iv(const GLint*);
+void GLAPIENTRY glVertex3s(GLshort,GLshort,GLshort);
+void GLAPIENTRY glVertex3sv(const GLshort*);
+void GLAPIENTRY glVertex4d(GLdouble,GLdouble,GLdouble,GLdouble);
+void GLAPIENTRY glVertex4dv(const GLdouble*);
+void GLAPIENTRY glVertex4f(GLfloat,GLfloat,GLfloat,GLfloat);
+void GLAPIENTRY glVertex4fv(const GLfloat*);
+void GLAPIENTRY glVertex4i(GLint,GLint,GLint,GLint);
+void GLAPIENTRY glVertex4iv(const GLint*);
+void GLAPIENTRY glVertex4s(GLshort,GLshort,GLshort,GLshort);
+void GLAPIENTRY glVertex4sv(const GLshort*);
+void GLAPIENTRY glVertexPointer(GLint,GLenum,GLsizei,const GLvoid*);
+void GLAPIENTRY glViewport(GLint,GLint,GLsizei,GLsizei);
+
+#endif /* __WINE_WGL_H */
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/wgl_driver.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/wgl_driver.h
new file mode 100644
index 00000000..8d235017
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/wgl_driver.h
@@ -0,0 +1,2862 @@
+/* Automatically generated from http://www.opengl.org/registry/api files; DO NOT EDIT! */
+
+#ifndef __WINE_WGL_DRIVER_H
+#define __WINE_WGL_DRIVER_H
+
+#ifndef WINE_GLAPI
+#define WINE_GLAPI
+#endif
+
+#define WINE_WGL_DRIVER_VERSION 10
+
+struct wgl_context;
+struct wgl_pbuffer;
+
+struct opengl_funcs
+{
+ struct
+ {
+ BOOL (WINE_GLAPI *p_wglCopyContext)(struct wgl_context *,struct wgl_context *,UINT);
+ struct wgl_context * (WINE_GLAPI *p_wglCreateContext)(HDC);
+ void (WINE_GLAPI *p_wglDeleteContext)(struct wgl_context *);
+ INT (WINE_GLAPI *p_wglDescribePixelFormat)(HDC,INT,UINT,PIXELFORMATDESCRIPTOR *);
+ INT (WINE_GLAPI *p_wglGetPixelFormat)(HDC);
+ PROC (WINE_GLAPI *p_wglGetProcAddress)(LPCSTR);
+ BOOL (WINE_GLAPI *p_wglMakeCurrent)(HDC,struct wgl_context *);
+ BOOL (WINE_GLAPI *p_wglSetPixelFormat)(HDC,INT,const PIXELFORMATDESCRIPTOR *);
+ BOOL (WINE_GLAPI *p_wglShareLists)(struct wgl_context *,struct wgl_context *);
+ BOOL (WINE_GLAPI *p_wglSwapBuffers)(HDC);
+ } wgl;
+
+ struct
+ {
+ void (WINE_GLAPI *p_glAccum)(GLenum,GLfloat);
+ void (WINE_GLAPI *p_glAlphaFunc)(GLenum,GLfloat);
+ GLboolean (WINE_GLAPI *p_glAreTexturesResident)(GLsizei,const GLuint*,GLboolean*);
+ void (WINE_GLAPI *p_glArrayElement)(GLint);
+ void (WINE_GLAPI *p_glBegin)(GLenum);
+ void (WINE_GLAPI *p_glBindTexture)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glBitmap)(GLsizei,GLsizei,GLfloat,GLfloat,GLfloat,GLfloat,const GLubyte*);
+ void (WINE_GLAPI *p_glBlendFunc)(GLenum,GLenum);
+ void (WINE_GLAPI *p_glCallList)(GLuint);
+ void (WINE_GLAPI *p_glCallLists)(GLsizei,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glClear)(GLbitfield);
+ void (WINE_GLAPI *p_glClearAccum)(GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glClearColor)(GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glClearDepth)(GLdouble);
+ void (WINE_GLAPI *p_glClearIndex)(GLfloat);
+ void (WINE_GLAPI *p_glClearStencil)(GLint);
+ void (WINE_GLAPI *p_glClipPlane)(GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glColor3b)(GLbyte,GLbyte,GLbyte);
+ void (WINE_GLAPI *p_glColor3bv)(const GLbyte*);
+ void (WINE_GLAPI *p_glColor3d)(GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glColor3dv)(const GLdouble*);
+ void (WINE_GLAPI *p_glColor3f)(GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glColor3fv)(const GLfloat*);
+ void (WINE_GLAPI *p_glColor3i)(GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glColor3iv)(const GLint*);
+ void (WINE_GLAPI *p_glColor3s)(GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glColor3sv)(const GLshort*);
+ void (WINE_GLAPI *p_glColor3ub)(GLubyte,GLubyte,GLubyte);
+ void (WINE_GLAPI *p_glColor3ubv)(const GLubyte*);
+ void (WINE_GLAPI *p_glColor3ui)(GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glColor3uiv)(const GLuint*);
+ void (WINE_GLAPI *p_glColor3us)(GLushort,GLushort,GLushort);
+ void (WINE_GLAPI *p_glColor3usv)(const GLushort*);
+ void (WINE_GLAPI *p_glColor4b)(GLbyte,GLbyte,GLbyte,GLbyte);
+ void (WINE_GLAPI *p_glColor4bv)(const GLbyte*);
+ void (WINE_GLAPI *p_glColor4d)(GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glColor4dv)(const GLdouble*);
+ void (WINE_GLAPI *p_glColor4f)(GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glColor4fv)(const GLfloat*);
+ void (WINE_GLAPI *p_glColor4i)(GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glColor4iv)(const GLint*);
+ void (WINE_GLAPI *p_glColor4s)(GLshort,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glColor4sv)(const GLshort*);
+ void (WINE_GLAPI *p_glColor4ub)(GLubyte,GLubyte,GLubyte,GLubyte);
+ void (WINE_GLAPI *p_glColor4ubv)(const GLubyte*);
+ void (WINE_GLAPI *p_glColor4ui)(GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glColor4uiv)(const GLuint*);
+ void (WINE_GLAPI *p_glColor4us)(GLushort,GLushort,GLushort,GLushort);
+ void (WINE_GLAPI *p_glColor4usv)(const GLushort*);
+ void (WINE_GLAPI *p_glColorMask)(GLboolean,GLboolean,GLboolean,GLboolean);
+ void (WINE_GLAPI *p_glColorMaterial)(GLenum,GLenum);
+ void (WINE_GLAPI *p_glColorPointer)(GLint,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCopyPixels)(GLint,GLint,GLsizei,GLsizei,GLenum);
+ void (WINE_GLAPI *p_glCopyTexImage1D)(GLenum,GLint,GLenum,GLint,GLint,GLsizei,GLint);
+ void (WINE_GLAPI *p_glCopyTexImage2D)(GLenum,GLint,GLenum,GLint,GLint,GLsizei,GLsizei,GLint);
+ void (WINE_GLAPI *p_glCopyTexSubImage1D)(GLenum,GLint,GLint,GLint,GLint,GLsizei);
+ void (WINE_GLAPI *p_glCopyTexSubImage2D)(GLenum,GLint,GLint,GLint,GLint,GLint,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glCullFace)(GLenum);
+ void (WINE_GLAPI *p_glDeleteLists)(GLuint,GLsizei);
+ void (WINE_GLAPI *p_glDeleteTextures)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDepthFunc)(GLenum);
+ void (WINE_GLAPI *p_glDepthMask)(GLboolean);
+ void (WINE_GLAPI *p_glDepthRange)(GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glDisable)(GLenum);
+ void (WINE_GLAPI *p_glDisableClientState)(GLenum);
+ void (WINE_GLAPI *p_glDrawArrays)(GLenum,GLint,GLsizei);
+ void (WINE_GLAPI *p_glDrawBuffer)(GLenum);
+ void (WINE_GLAPI *p_glDrawElements)(GLenum,GLsizei,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glDrawPixels)(GLsizei,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glEdgeFlag)(GLboolean);
+ void (WINE_GLAPI *p_glEdgeFlagPointer)(GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glEdgeFlagv)(const GLboolean*);
+ void (WINE_GLAPI *p_glEnable)(GLenum);
+ void (WINE_GLAPI *p_glEnableClientState)(GLenum);
+ void (WINE_GLAPI *p_glEnd)(void);
+ void (WINE_GLAPI *p_glEndList)(void);
+ void (WINE_GLAPI *p_glEvalCoord1d)(GLdouble);
+ void (WINE_GLAPI *p_glEvalCoord1dv)(const GLdouble*);
+ void (WINE_GLAPI *p_glEvalCoord1f)(GLfloat);
+ void (WINE_GLAPI *p_glEvalCoord1fv)(const GLfloat*);
+ void (WINE_GLAPI *p_glEvalCoord2d)(GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glEvalCoord2dv)(const GLdouble*);
+ void (WINE_GLAPI *p_glEvalCoord2f)(GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glEvalCoord2fv)(const GLfloat*);
+ void (WINE_GLAPI *p_glEvalMesh1)(GLenum,GLint,GLint);
+ void (WINE_GLAPI *p_glEvalMesh2)(GLenum,GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glEvalPoint1)(GLint);
+ void (WINE_GLAPI *p_glEvalPoint2)(GLint,GLint);
+ void (WINE_GLAPI *p_glFeedbackBuffer)(GLsizei,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glFinish)(void);
+ void (WINE_GLAPI *p_glFlush)(void);
+ void (WINE_GLAPI *p_glFogf)(GLenum,GLfloat);
+ void (WINE_GLAPI *p_glFogfv)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glFogi)(GLenum,GLint);
+ void (WINE_GLAPI *p_glFogiv)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glFrontFace)(GLenum);
+ void (WINE_GLAPI *p_glFrustum)(GLdouble,GLdouble,GLdouble,GLdouble,GLdouble,GLdouble);
+ GLuint (WINE_GLAPI *p_glGenLists)(GLsizei);
+ void (WINE_GLAPI *p_glGenTextures)(GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGetBooleanv)(GLenum,GLboolean*);
+ void (WINE_GLAPI *p_glGetClipPlane)(GLenum,GLdouble*);
+ void (WINE_GLAPI *p_glGetDoublev)(GLenum,GLdouble*);
+ GLenum (WINE_GLAPI *p_glGetError)(void);
+ void (WINE_GLAPI *p_glGetFloatv)(GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetIntegerv)(GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetLightfv)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetLightiv)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetMapdv)(GLenum,GLenum,GLdouble*);
+ void (WINE_GLAPI *p_glGetMapfv)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetMapiv)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetMaterialfv)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetMaterialiv)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetPixelMapfv)(GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetPixelMapuiv)(GLenum,GLuint*);
+ void (WINE_GLAPI *p_glGetPixelMapusv)(GLenum,GLushort*);
+ void (WINE_GLAPI *p_glGetPointerv)(GLenum,GLvoid**);
+ void (WINE_GLAPI *p_glGetPolygonStipple)(GLubyte*);
+ const GLubyte * (WINE_GLAPI *p_glGetString)(GLenum);
+ void (WINE_GLAPI *p_glGetTexEnvfv)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetTexEnviv)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetTexGendv)(GLenum,GLenum,GLdouble*);
+ void (WINE_GLAPI *p_glGetTexGenfv)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetTexGeniv)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetTexImage)(GLenum,GLint,GLenum,GLenum,GLvoid*);
+ void (WINE_GLAPI *p_glGetTexLevelParameterfv)(GLenum,GLint,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetTexLevelParameteriv)(GLenum,GLint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetTexParameterfv)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetTexParameteriv)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glHint)(GLenum,GLenum);
+ void (WINE_GLAPI *p_glIndexMask)(GLuint);
+ void (WINE_GLAPI *p_glIndexPointer)(GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glIndexd)(GLdouble);
+ void (WINE_GLAPI *p_glIndexdv)(const GLdouble*);
+ void (WINE_GLAPI *p_glIndexf)(GLfloat);
+ void (WINE_GLAPI *p_glIndexfv)(const GLfloat*);
+ void (WINE_GLAPI *p_glIndexi)(GLint);
+ void (WINE_GLAPI *p_glIndexiv)(const GLint*);
+ void (WINE_GLAPI *p_glIndexs)(GLshort);
+ void (WINE_GLAPI *p_glIndexsv)(const GLshort*);
+ void (WINE_GLAPI *p_glIndexub)(GLubyte);
+ void (WINE_GLAPI *p_glIndexubv)(const GLubyte*);
+ void (WINE_GLAPI *p_glInitNames)(void);
+ void (WINE_GLAPI *p_glInterleavedArrays)(GLenum,GLsizei,const GLvoid*);
+ GLboolean (WINE_GLAPI *p_glIsEnabled)(GLenum);
+ GLboolean (WINE_GLAPI *p_glIsList)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsTexture)(GLuint);
+ void (WINE_GLAPI *p_glLightModelf)(GLenum,GLfloat);
+ void (WINE_GLAPI *p_glLightModelfv)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glLightModeli)(GLenum,GLint);
+ void (WINE_GLAPI *p_glLightModeliv)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glLightf)(GLenum,GLenum,GLfloat);
+ void (WINE_GLAPI *p_glLightfv)(GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glLighti)(GLenum,GLenum,GLint);
+ void (WINE_GLAPI *p_glLightiv)(GLenum,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glLineStipple)(GLint,GLushort);
+ void (WINE_GLAPI *p_glLineWidth)(GLfloat);
+ void (WINE_GLAPI *p_glListBase)(GLuint);
+ void (WINE_GLAPI *p_glLoadIdentity)(void);
+ void (WINE_GLAPI *p_glLoadMatrixd)(const GLdouble*);
+ void (WINE_GLAPI *p_glLoadMatrixf)(const GLfloat*);
+ void (WINE_GLAPI *p_glLoadName)(GLuint);
+ void (WINE_GLAPI *p_glLogicOp)(GLenum);
+ void (WINE_GLAPI *p_glMap1d)(GLenum,GLdouble,GLdouble,GLint,GLint,const GLdouble*);
+ void (WINE_GLAPI *p_glMap1f)(GLenum,GLfloat,GLfloat,GLint,GLint,const GLfloat*);
+ void (WINE_GLAPI *p_glMap2d)(GLenum,GLdouble,GLdouble,GLint,GLint,GLdouble,GLdouble,GLint,GLint,const GLdouble*);
+ void (WINE_GLAPI *p_glMap2f)(GLenum,GLfloat,GLfloat,GLint,GLint,GLfloat,GLfloat,GLint,GLint,const GLfloat*);
+ void (WINE_GLAPI *p_glMapGrid1d)(GLint,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glMapGrid1f)(GLint,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glMapGrid2d)(GLint,GLdouble,GLdouble,GLint,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glMapGrid2f)(GLint,GLfloat,GLfloat,GLint,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glMaterialf)(GLenum,GLenum,GLfloat);
+ void (WINE_GLAPI *p_glMaterialfv)(GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glMateriali)(GLenum,GLenum,GLint);
+ void (WINE_GLAPI *p_glMaterialiv)(GLenum,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glMatrixMode)(GLenum);
+ void (WINE_GLAPI *p_glMultMatrixd)(const GLdouble*);
+ void (WINE_GLAPI *p_glMultMatrixf)(const GLfloat*);
+ void (WINE_GLAPI *p_glNewList)(GLuint,GLenum);
+ void (WINE_GLAPI *p_glNormal3b)(GLbyte,GLbyte,GLbyte);
+ void (WINE_GLAPI *p_glNormal3bv)(const GLbyte*);
+ void (WINE_GLAPI *p_glNormal3d)(GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glNormal3dv)(const GLdouble*);
+ void (WINE_GLAPI *p_glNormal3f)(GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glNormal3fv)(const GLfloat*);
+ void (WINE_GLAPI *p_glNormal3i)(GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glNormal3iv)(const GLint*);
+ void (WINE_GLAPI *p_glNormal3s)(GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glNormal3sv)(const GLshort*);
+ void (WINE_GLAPI *p_glNormalPointer)(GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glOrtho)(GLdouble,GLdouble,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glPassThrough)(GLfloat);
+ void (WINE_GLAPI *p_glPixelMapfv)(GLenum,GLint,const GLfloat*);
+ void (WINE_GLAPI *p_glPixelMapuiv)(GLenum,GLint,const GLuint*);
+ void (WINE_GLAPI *p_glPixelMapusv)(GLenum,GLint,const GLushort*);
+ void (WINE_GLAPI *p_glPixelStoref)(GLenum,GLfloat);
+ void (WINE_GLAPI *p_glPixelStorei)(GLenum,GLint);
+ void (WINE_GLAPI *p_glPixelTransferf)(GLenum,GLfloat);
+ void (WINE_GLAPI *p_glPixelTransferi)(GLenum,GLint);
+ void (WINE_GLAPI *p_glPixelZoom)(GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glPointSize)(GLfloat);
+ void (WINE_GLAPI *p_glPolygonMode)(GLenum,GLenum);
+ void (WINE_GLAPI *p_glPolygonOffset)(GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glPolygonStipple)(const GLubyte*);
+ void (WINE_GLAPI *p_glPopAttrib)(void);
+ void (WINE_GLAPI *p_glPopClientAttrib)(void);
+ void (WINE_GLAPI *p_glPopMatrix)(void);
+ void (WINE_GLAPI *p_glPopName)(void);
+ void (WINE_GLAPI *p_glPrioritizeTextures)(GLsizei,const GLuint*,const GLfloat*);
+ void (WINE_GLAPI *p_glPushAttrib)(GLbitfield);
+ void (WINE_GLAPI *p_glPushClientAttrib)(GLbitfield);
+ void (WINE_GLAPI *p_glPushMatrix)(void);
+ void (WINE_GLAPI *p_glPushName)(GLuint);
+ void (WINE_GLAPI *p_glRasterPos2d)(GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glRasterPos2dv)(const GLdouble*);
+ void (WINE_GLAPI *p_glRasterPos2f)(GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glRasterPos2fv)(const GLfloat*);
+ void (WINE_GLAPI *p_glRasterPos2i)(GLint,GLint);
+ void (WINE_GLAPI *p_glRasterPos2iv)(const GLint*);
+ void (WINE_GLAPI *p_glRasterPos2s)(GLshort,GLshort);
+ void (WINE_GLAPI *p_glRasterPos2sv)(const GLshort*);
+ void (WINE_GLAPI *p_glRasterPos3d)(GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glRasterPos3dv)(const GLdouble*);
+ void (WINE_GLAPI *p_glRasterPos3f)(GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glRasterPos3fv)(const GLfloat*);
+ void (WINE_GLAPI *p_glRasterPos3i)(GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glRasterPos3iv)(const GLint*);
+ void (WINE_GLAPI *p_glRasterPos3s)(GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glRasterPos3sv)(const GLshort*);
+ void (WINE_GLAPI *p_glRasterPos4d)(GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glRasterPos4dv)(const GLdouble*);
+ void (WINE_GLAPI *p_glRasterPos4f)(GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glRasterPos4fv)(const GLfloat*);
+ void (WINE_GLAPI *p_glRasterPos4i)(GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glRasterPos4iv)(const GLint*);
+ void (WINE_GLAPI *p_glRasterPos4s)(GLshort,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glRasterPos4sv)(const GLshort*);
+ void (WINE_GLAPI *p_glReadBuffer)(GLenum);
+ void (WINE_GLAPI *p_glReadPixels)(GLint,GLint,GLsizei,GLsizei,GLenum,GLenum,GLvoid*);
+ void (WINE_GLAPI *p_glRectd)(GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glRectdv)(const GLdouble*,const GLdouble*);
+ void (WINE_GLAPI *p_glRectf)(GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glRectfv)(const GLfloat*,const GLfloat*);
+ void (WINE_GLAPI *p_glRecti)(GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glRectiv)(const GLint*,const GLint*);
+ void (WINE_GLAPI *p_glRects)(GLshort,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glRectsv)(const GLshort*,const GLshort*);
+ GLint (WINE_GLAPI *p_glRenderMode)(GLenum);
+ void (WINE_GLAPI *p_glRotated)(GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glRotatef)(GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glScaled)(GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glScalef)(GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glScissor)(GLint,GLint,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glSelectBuffer)(GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glShadeModel)(GLenum);
+ void (WINE_GLAPI *p_glStencilFunc)(GLenum,GLint,GLuint);
+ void (WINE_GLAPI *p_glStencilMask)(GLuint);
+ void (WINE_GLAPI *p_glStencilOp)(GLenum,GLenum,GLenum);
+ void (WINE_GLAPI *p_glTexCoord1d)(GLdouble);
+ void (WINE_GLAPI *p_glTexCoord1dv)(const GLdouble*);
+ void (WINE_GLAPI *p_glTexCoord1f)(GLfloat);
+ void (WINE_GLAPI *p_glTexCoord1fv)(const GLfloat*);
+ void (WINE_GLAPI *p_glTexCoord1i)(GLint);
+ void (WINE_GLAPI *p_glTexCoord1iv)(const GLint*);
+ void (WINE_GLAPI *p_glTexCoord1s)(GLshort);
+ void (WINE_GLAPI *p_glTexCoord1sv)(const GLshort*);
+ void (WINE_GLAPI *p_glTexCoord2d)(GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glTexCoord2dv)(const GLdouble*);
+ void (WINE_GLAPI *p_glTexCoord2f)(GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glTexCoord2fv)(const GLfloat*);
+ void (WINE_GLAPI *p_glTexCoord2i)(GLint,GLint);
+ void (WINE_GLAPI *p_glTexCoord2iv)(const GLint*);
+ void (WINE_GLAPI *p_glTexCoord2s)(GLshort,GLshort);
+ void (WINE_GLAPI *p_glTexCoord2sv)(const GLshort*);
+ void (WINE_GLAPI *p_glTexCoord3d)(GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glTexCoord3dv)(const GLdouble*);
+ void (WINE_GLAPI *p_glTexCoord3f)(GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glTexCoord3fv)(const GLfloat*);
+ void (WINE_GLAPI *p_glTexCoord3i)(GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glTexCoord3iv)(const GLint*);
+ void (WINE_GLAPI *p_glTexCoord3s)(GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glTexCoord3sv)(const GLshort*);
+ void (WINE_GLAPI *p_glTexCoord4d)(GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glTexCoord4dv)(const GLdouble*);
+ void (WINE_GLAPI *p_glTexCoord4f)(GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glTexCoord4fv)(const GLfloat*);
+ void (WINE_GLAPI *p_glTexCoord4i)(GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glTexCoord4iv)(const GLint*);
+ void (WINE_GLAPI *p_glTexCoord4s)(GLshort,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glTexCoord4sv)(const GLshort*);
+ void (WINE_GLAPI *p_glTexCoordPointer)(GLint,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glTexEnvf)(GLenum,GLenum,GLfloat);
+ void (WINE_GLAPI *p_glTexEnvfv)(GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glTexEnvi)(GLenum,GLenum,GLint);
+ void (WINE_GLAPI *p_glTexEnviv)(GLenum,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glTexGend)(GLenum,GLenum,GLdouble);
+ void (WINE_GLAPI *p_glTexGendv)(GLenum,GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glTexGenf)(GLenum,GLenum,GLfloat);
+ void (WINE_GLAPI *p_glTexGenfv)(GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glTexGeni)(GLenum,GLenum,GLint);
+ void (WINE_GLAPI *p_glTexGeniv)(GLenum,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glTexImage1D)(GLenum,GLint,GLint,GLsizei,GLint,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glTexImage2D)(GLenum,GLint,GLint,GLsizei,GLsizei,GLint,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glTexParameterf)(GLenum,GLenum,GLfloat);
+ void (WINE_GLAPI *p_glTexParameterfv)(GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glTexParameteri)(GLenum,GLenum,GLint);
+ void (WINE_GLAPI *p_glTexParameteriv)(GLenum,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glTexSubImage1D)(GLenum,GLint,GLint,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glTexSubImage2D)(GLenum,GLint,GLint,GLint,GLsizei,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glTranslated)(GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glTranslatef)(GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glVertex2d)(GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertex2dv)(const GLdouble*);
+ void (WINE_GLAPI *p_glVertex2f)(GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glVertex2fv)(const GLfloat*);
+ void (WINE_GLAPI *p_glVertex2i)(GLint,GLint);
+ void (WINE_GLAPI *p_glVertex2iv)(const GLint*);
+ void (WINE_GLAPI *p_glVertex2s)(GLshort,GLshort);
+ void (WINE_GLAPI *p_glVertex2sv)(const GLshort*);
+ void (WINE_GLAPI *p_glVertex3d)(GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertex3dv)(const GLdouble*);
+ void (WINE_GLAPI *p_glVertex3f)(GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glVertex3fv)(const GLfloat*);
+ void (WINE_GLAPI *p_glVertex3i)(GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glVertex3iv)(const GLint*);
+ void (WINE_GLAPI *p_glVertex3s)(GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glVertex3sv)(const GLshort*);
+ void (WINE_GLAPI *p_glVertex4d)(GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertex4dv)(const GLdouble*);
+ void (WINE_GLAPI *p_glVertex4f)(GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glVertex4fv)(const GLfloat*);
+ void (WINE_GLAPI *p_glVertex4i)(GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glVertex4iv)(const GLint*);
+ void (WINE_GLAPI *p_glVertex4s)(GLshort,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glVertex4sv)(const GLshort*);
+ void (WINE_GLAPI *p_glVertexPointer)(GLint,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glViewport)(GLint,GLint,GLsizei,GLsizei);
+ } gl;
+
+ struct
+ {
+ void (WINE_GLAPI *p_glActiveProgramEXT)(GLuint);
+ void (WINE_GLAPI *p_glActiveShaderProgram)(GLuint,GLuint);
+ void (WINE_GLAPI *p_glActiveStencilFaceEXT)(GLenum);
+ void (WINE_GLAPI *p_glActiveTexture)(GLenum);
+ void (WINE_GLAPI *p_glActiveTextureARB)(GLenum);
+ void (WINE_GLAPI *p_glActiveVaryingNV)(GLuint,const GLchar*);
+ void (WINE_GLAPI *p_glAlphaFragmentOp1ATI)(GLenum,GLuint,GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glAlphaFragmentOp2ATI)(GLenum,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glAlphaFragmentOp3ATI)(GLenum,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glApplyTextureEXT)(GLenum);
+ GLboolean (WINE_GLAPI *p_glAreProgramsResidentNV)(GLsizei,const GLuint*,GLboolean*);
+ GLboolean (WINE_GLAPI *p_glAreTexturesResidentEXT)(GLsizei,const GLuint*,GLboolean*);
+ void (WINE_GLAPI *p_glArrayElementEXT)(GLint);
+ void (WINE_GLAPI *p_glArrayObjectATI)(GLenum,GLint,GLenum,GLsizei,GLuint,GLuint);
+ void (WINE_GLAPI *p_glAsyncMarkerSGIX)(GLuint);
+ void (WINE_GLAPI *p_glAttachObjectARB)(GLhandleARB,GLhandleARB);
+ void (WINE_GLAPI *p_glAttachShader)(GLuint,GLuint);
+ void (WINE_GLAPI *p_glBeginConditionalRender)(GLuint,GLenum);
+ void (WINE_GLAPI *p_glBeginConditionalRenderNV)(GLuint,GLenum);
+ void (WINE_GLAPI *p_glBeginFragmentShaderATI)(void);
+ void (WINE_GLAPI *p_glBeginOcclusionQueryNV)(GLuint);
+ void (WINE_GLAPI *p_glBeginPerfMonitorAMD)(GLuint);
+ void (WINE_GLAPI *p_glBeginQuery)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glBeginQueryARB)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glBeginQueryIndexed)(GLenum,GLuint,GLuint);
+ void (WINE_GLAPI *p_glBeginTransformFeedback)(GLenum);
+ void (WINE_GLAPI *p_glBeginTransformFeedbackEXT)(GLenum);
+ void (WINE_GLAPI *p_glBeginTransformFeedbackNV)(GLenum);
+ void (WINE_GLAPI *p_glBeginVertexShaderEXT)(void);
+ void (WINE_GLAPI *p_glBeginVideoCaptureNV)(GLuint);
+ void (WINE_GLAPI *p_glBindAttribLocation)(GLuint,GLuint,const GLchar*);
+ void (WINE_GLAPI *p_glBindAttribLocationARB)(GLhandleARB,GLuint,const GLcharARB*);
+ void (WINE_GLAPI *p_glBindBuffer)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glBindBufferARB)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glBindBufferBase)(GLenum,GLuint,GLuint);
+ void (WINE_GLAPI *p_glBindBufferBaseEXT)(GLenum,GLuint,GLuint);
+ void (WINE_GLAPI *p_glBindBufferBaseNV)(GLenum,GLuint,GLuint);
+ void (WINE_GLAPI *p_glBindBufferOffsetEXT)(GLenum,GLuint,GLuint,GLintptr);
+ void (WINE_GLAPI *p_glBindBufferOffsetNV)(GLenum,GLuint,GLuint,GLintptr);
+ void (WINE_GLAPI *p_glBindBufferRange)(GLenum,GLuint,GLuint,GLintptr,GLsizeiptr);
+ void (WINE_GLAPI *p_glBindBufferRangeEXT)(GLenum,GLuint,GLuint,GLintptr,GLsizeiptr);
+ void (WINE_GLAPI *p_glBindBufferRangeNV)(GLenum,GLuint,GLuint,GLintptr,GLsizeiptr);
+ void (WINE_GLAPI *p_glBindFragDataLocation)(GLuint,GLuint,const GLchar*);
+ void (WINE_GLAPI *p_glBindFragDataLocationEXT)(GLuint,GLuint,const GLchar*);
+ void (WINE_GLAPI *p_glBindFragDataLocationIndexed)(GLuint,GLuint,GLuint,const GLchar*);
+ void (WINE_GLAPI *p_glBindFragmentShaderATI)(GLuint);
+ void (WINE_GLAPI *p_glBindFramebuffer)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glBindFramebufferEXT)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glBindImageTexture)(GLuint,GLuint,GLint,GLboolean,GLint,GLenum,GLenum);
+ void (WINE_GLAPI *p_glBindImageTextureEXT)(GLuint,GLuint,GLint,GLboolean,GLint,GLenum,GLint);
+ GLuint (WINE_GLAPI *p_glBindLightParameterEXT)(GLenum,GLenum);
+ GLuint (WINE_GLAPI *p_glBindMaterialParameterEXT)(GLenum,GLenum);
+ void (WINE_GLAPI *p_glBindMultiTextureEXT)(GLenum,GLenum,GLuint);
+ GLuint (WINE_GLAPI *p_glBindParameterEXT)(GLenum);
+ void (WINE_GLAPI *p_glBindProgramARB)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glBindProgramNV)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glBindProgramPipeline)(GLuint);
+ void (WINE_GLAPI *p_glBindRenderbuffer)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glBindRenderbufferEXT)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glBindSampler)(GLuint,GLuint);
+ GLuint (WINE_GLAPI *p_glBindTexGenParameterEXT)(GLenum,GLenum,GLenum);
+ void (WINE_GLAPI *p_glBindTextureEXT)(GLenum,GLuint);
+ GLuint (WINE_GLAPI *p_glBindTextureUnitParameterEXT)(GLenum,GLenum);
+ void (WINE_GLAPI *p_glBindTransformFeedback)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glBindTransformFeedbackNV)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glBindVertexArray)(GLuint);
+ void (WINE_GLAPI *p_glBindVertexArrayAPPLE)(GLuint);
+ void (WINE_GLAPI *p_glBindVertexBuffer)(GLuint,GLuint,GLintptr,GLsizei);
+ void (WINE_GLAPI *p_glBindVertexShaderEXT)(GLuint);
+ void (WINE_GLAPI *p_glBindVideoCaptureStreamBufferNV)(GLuint,GLuint,GLenum,GLintptrARB);
+ void (WINE_GLAPI *p_glBindVideoCaptureStreamTextureNV)(GLuint,GLuint,GLenum,GLenum,GLuint);
+ void (WINE_GLAPI *p_glBinormal3bEXT)(GLbyte,GLbyte,GLbyte);
+ void (WINE_GLAPI *p_glBinormal3bvEXT)(const GLbyte*);
+ void (WINE_GLAPI *p_glBinormal3dEXT)(GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glBinormal3dvEXT)(const GLdouble*);
+ void (WINE_GLAPI *p_glBinormal3fEXT)(GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glBinormal3fvEXT)(const GLfloat*);
+ void (WINE_GLAPI *p_glBinormal3iEXT)(GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glBinormal3ivEXT)(const GLint*);
+ void (WINE_GLAPI *p_glBinormal3sEXT)(GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glBinormal3svEXT)(const GLshort*);
+ void (WINE_GLAPI *p_glBinormalPointerEXT)(GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glBlendColor)(GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glBlendColorEXT)(GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glBlendEquation)(GLenum);
+ void (WINE_GLAPI *p_glBlendEquationEXT)(GLenum);
+ void (WINE_GLAPI *p_glBlendEquationIndexedAMD)(GLuint,GLenum);
+ void (WINE_GLAPI *p_glBlendEquationSeparate)(GLenum,GLenum);
+ void (WINE_GLAPI *p_glBlendEquationSeparateEXT)(GLenum,GLenum);
+ void (WINE_GLAPI *p_glBlendEquationSeparateIndexedAMD)(GLuint,GLenum,GLenum);
+ void (WINE_GLAPI *p_glBlendEquationSeparatei)(GLuint,GLenum,GLenum);
+ void (WINE_GLAPI *p_glBlendEquationSeparateiARB)(GLuint,GLenum,GLenum);
+ void (WINE_GLAPI *p_glBlendEquationi)(GLuint,GLenum);
+ void (WINE_GLAPI *p_glBlendEquationiARB)(GLuint,GLenum);
+ void (WINE_GLAPI *p_glBlendFuncIndexedAMD)(GLuint,GLenum,GLenum);
+ void (WINE_GLAPI *p_glBlendFuncSeparate)(GLenum,GLenum,GLenum,GLenum);
+ void (WINE_GLAPI *p_glBlendFuncSeparateEXT)(GLenum,GLenum,GLenum,GLenum);
+ void (WINE_GLAPI *p_glBlendFuncSeparateINGR)(GLenum,GLenum,GLenum,GLenum);
+ void (WINE_GLAPI *p_glBlendFuncSeparateIndexedAMD)(GLuint,GLenum,GLenum,GLenum,GLenum);
+ void (WINE_GLAPI *p_glBlendFuncSeparatei)(GLuint,GLenum,GLenum,GLenum,GLenum);
+ void (WINE_GLAPI *p_glBlendFuncSeparateiARB)(GLuint,GLenum,GLenum,GLenum,GLenum);
+ void (WINE_GLAPI *p_glBlendFunci)(GLuint,GLenum,GLenum);
+ void (WINE_GLAPI *p_glBlendFunciARB)(GLuint,GLenum,GLenum);
+ void (WINE_GLAPI *p_glBlitFramebuffer)(GLint,GLint,GLint,GLint,GLint,GLint,GLint,GLint,GLbitfield,GLenum);
+ void (WINE_GLAPI *p_glBlitFramebufferEXT)(GLint,GLint,GLint,GLint,GLint,GLint,GLint,GLint,GLbitfield,GLenum);
+ void (WINE_GLAPI *p_glBufferAddressRangeNV)(GLenum,GLuint,UINT64,GLsizeiptr);
+ void (WINE_GLAPI *p_glBufferData)(GLenum,GLsizeiptr,const GLvoid*,GLenum);
+ void (WINE_GLAPI *p_glBufferDataARB)(GLenum,GLsizeiptrARB,const GLvoid*,GLenum);
+ void (WINE_GLAPI *p_glBufferParameteriAPPLE)(GLenum,GLenum,GLint);
+ GLuint (WINE_GLAPI *p_glBufferRegionEnabled)(void);
+ void (WINE_GLAPI *p_glBufferSubData)(GLenum,GLintptr,GLsizeiptr,const GLvoid*);
+ void (WINE_GLAPI *p_glBufferSubDataARB)(GLenum,GLintptrARB,GLsizeiptrARB,const GLvoid*);
+ GLenum (WINE_GLAPI *p_glCheckFramebufferStatus)(GLenum);
+ GLenum (WINE_GLAPI *p_glCheckFramebufferStatusEXT)(GLenum);
+ GLenum (WINE_GLAPI *p_glCheckNamedFramebufferStatusEXT)(GLuint,GLenum);
+ void (WINE_GLAPI *p_glClampColor)(GLenum,GLenum);
+ void (WINE_GLAPI *p_glClampColorARB)(GLenum,GLenum);
+ void (WINE_GLAPI *p_glClearBufferData)(GLenum,GLenum,GLenum,GLenum,const void*);
+ void (WINE_GLAPI *p_glClearBufferSubData)(GLenum,GLenum,GLintptr,GLsizeiptr,GLenum,GLenum,const void*);
+ void (WINE_GLAPI *p_glClearBufferfi)(GLenum,GLint,GLfloat,GLint);
+ void (WINE_GLAPI *p_glClearBufferfv)(GLenum,GLint,const GLfloat*);
+ void (WINE_GLAPI *p_glClearBufferiv)(GLenum,GLint,const GLint*);
+ void (WINE_GLAPI *p_glClearBufferuiv)(GLenum,GLint,const GLuint*);
+ void (WINE_GLAPI *p_glClearColorIiEXT)(GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glClearColorIuiEXT)(GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glClearDepthdNV)(GLdouble);
+ void (WINE_GLAPI *p_glClearDepthf)(GLfloat);
+ void (WINE_GLAPI *p_glClearNamedBufferDataEXT)(GLuint,GLenum,GLenum,GLenum,const void*);
+ void (WINE_GLAPI *p_glClearNamedBufferSubDataEXT)(GLuint,GLenum,GLenum,GLenum,GLsizeiptr,GLsizeiptr,const void*);
+ void (WINE_GLAPI *p_glClientActiveTexture)(GLenum);
+ void (WINE_GLAPI *p_glClientActiveTextureARB)(GLenum);
+ void (WINE_GLAPI *p_glClientActiveVertexStreamATI)(GLenum);
+ void (WINE_GLAPI *p_glClientAttribDefaultEXT)(GLbitfield);
+ GLenum (WINE_GLAPI *p_glClientWaitSync)(GLvoid*,GLbitfield,UINT64);
+ void (WINE_GLAPI *p_glColor3fVertex3fSUN)(GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glColor3fVertex3fvSUN)(const GLfloat*,const GLfloat*);
+ void (WINE_GLAPI *p_glColor3hNV)(GLhalfNV,GLhalfNV,GLhalfNV);
+ void (WINE_GLAPI *p_glColor3hvNV)(const GLhalfNV*);
+ void (WINE_GLAPI *p_glColor4fNormal3fVertex3fSUN)(GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glColor4fNormal3fVertex3fvSUN)(const GLfloat*,const GLfloat*,const GLfloat*);
+ void (WINE_GLAPI *p_glColor4hNV)(GLhalfNV,GLhalfNV,GLhalfNV,GLhalfNV);
+ void (WINE_GLAPI *p_glColor4hvNV)(const GLhalfNV*);
+ void (WINE_GLAPI *p_glColor4ubVertex2fSUN)(GLubyte,GLubyte,GLubyte,GLubyte,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glColor4ubVertex2fvSUN)(const GLubyte*,const GLfloat*);
+ void (WINE_GLAPI *p_glColor4ubVertex3fSUN)(GLubyte,GLubyte,GLubyte,GLubyte,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glColor4ubVertex3fvSUN)(const GLubyte*,const GLfloat*);
+ void (WINE_GLAPI *p_glColorFormatNV)(GLint,GLenum,GLsizei);
+ void (WINE_GLAPI *p_glColorFragmentOp1ATI)(GLenum,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glColorFragmentOp2ATI)(GLenum,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glColorFragmentOp3ATI)(GLenum,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glColorMaskIndexedEXT)(GLuint,GLboolean,GLboolean,GLboolean,GLboolean);
+ void (WINE_GLAPI *p_glColorMaski)(GLuint,GLboolean,GLboolean,GLboolean,GLboolean);
+ void (WINE_GLAPI *p_glColorP3ui)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glColorP3uiv)(GLenum,const GLuint*);
+ void (WINE_GLAPI *p_glColorP4ui)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glColorP4uiv)(GLenum,const GLuint*);
+ void (WINE_GLAPI *p_glColorPointerEXT)(GLint,GLenum,GLsizei,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glColorPointerListIBM)(GLint,GLenum,GLint,const GLvoid**,GLint);
+ void (WINE_GLAPI *p_glColorPointervINTEL)(GLint,GLenum,const GLvoid**);
+ void (WINE_GLAPI *p_glColorSubTable)(GLenum,GLsizei,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glColorSubTableEXT)(GLenum,GLsizei,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glColorTable)(GLenum,GLenum,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glColorTableEXT)(GLenum,GLenum,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glColorTableParameterfv)(GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glColorTableParameterfvSGI)(GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glColorTableParameteriv)(GLenum,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glColorTableParameterivSGI)(GLenum,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glColorTableSGI)(GLenum,GLenum,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glCombinerInputNV)(GLenum,GLenum,GLenum,GLenum,GLenum,GLenum);
+ void (WINE_GLAPI *p_glCombinerOutputNV)(GLenum,GLenum,GLenum,GLenum,GLenum,GLenum,GLenum,GLboolean,GLboolean,GLboolean);
+ void (WINE_GLAPI *p_glCombinerParameterfNV)(GLenum,GLfloat);
+ void (WINE_GLAPI *p_glCombinerParameterfvNV)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glCombinerParameteriNV)(GLenum,GLint);
+ void (WINE_GLAPI *p_glCombinerParameterivNV)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glCombinerStageParameterfvNV)(GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glCompileShader)(GLuint);
+ void (WINE_GLAPI *p_glCompileShaderARB)(GLhandleARB);
+ void (WINE_GLAPI *p_glCompileShaderIncludeARB)(GLuint,GLsizei,const GLchar**,const GLint*);
+ void (WINE_GLAPI *p_glCompressedMultiTexImage1DEXT)(GLenum,GLenum,GLint,GLenum,GLsizei,GLint,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedMultiTexImage2DEXT)(GLenum,GLenum,GLint,GLenum,GLsizei,GLsizei,GLint,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedMultiTexImage3DEXT)(GLenum,GLenum,GLint,GLenum,GLsizei,GLsizei,GLsizei,GLint,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedMultiTexSubImage1DEXT)(GLenum,GLenum,GLint,GLint,GLsizei,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedMultiTexSubImage2DEXT)(GLenum,GLenum,GLint,GLint,GLint,GLsizei,GLsizei,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedMultiTexSubImage3DEXT)(GLenum,GLenum,GLint,GLint,GLint,GLint,GLsizei,GLsizei,GLsizei,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedTexImage1D)(GLenum,GLint,GLenum,GLsizei,GLint,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedTexImage1DARB)(GLenum,GLint,GLenum,GLsizei,GLint,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedTexImage2D)(GLenum,GLint,GLenum,GLsizei,GLsizei,GLint,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedTexImage2DARB)(GLenum,GLint,GLenum,GLsizei,GLsizei,GLint,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedTexImage3D)(GLenum,GLint,GLenum,GLsizei,GLsizei,GLsizei,GLint,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedTexImage3DARB)(GLenum,GLint,GLenum,GLsizei,GLsizei,GLsizei,GLint,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedTexSubImage1D)(GLenum,GLint,GLint,GLsizei,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedTexSubImage1DARB)(GLenum,GLint,GLint,GLsizei,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedTexSubImage2D)(GLenum,GLint,GLint,GLint,GLsizei,GLsizei,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedTexSubImage2DARB)(GLenum,GLint,GLint,GLint,GLsizei,GLsizei,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedTexSubImage3D)(GLenum,GLint,GLint,GLint,GLint,GLsizei,GLsizei,GLsizei,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedTexSubImage3DARB)(GLenum,GLint,GLint,GLint,GLint,GLsizei,GLsizei,GLsizei,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedTextureImage1DEXT)(GLuint,GLenum,GLint,GLenum,GLsizei,GLint,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedTextureImage2DEXT)(GLuint,GLenum,GLint,GLenum,GLsizei,GLsizei,GLint,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedTextureImage3DEXT)(GLuint,GLenum,GLint,GLenum,GLsizei,GLsizei,GLsizei,GLint,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedTextureSubImage1DEXT)(GLuint,GLenum,GLint,GLint,GLsizei,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedTextureSubImage2DEXT)(GLuint,GLenum,GLint,GLint,GLint,GLsizei,GLsizei,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glCompressedTextureSubImage3DEXT)(GLuint,GLenum,GLint,GLint,GLint,GLint,GLsizei,GLsizei,GLsizei,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glConvolutionFilter1D)(GLenum,GLenum,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glConvolutionFilter1DEXT)(GLenum,GLenum,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glConvolutionFilter2D)(GLenum,GLenum,GLsizei,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glConvolutionFilter2DEXT)(GLenum,GLenum,GLsizei,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glConvolutionParameterf)(GLenum,GLenum,GLfloat);
+ void (WINE_GLAPI *p_glConvolutionParameterfEXT)(GLenum,GLenum,GLfloat);
+ void (WINE_GLAPI *p_glConvolutionParameterfv)(GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glConvolutionParameterfvEXT)(GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glConvolutionParameteri)(GLenum,GLenum,GLint);
+ void (WINE_GLAPI *p_glConvolutionParameteriEXT)(GLenum,GLenum,GLint);
+ void (WINE_GLAPI *p_glConvolutionParameteriv)(GLenum,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glConvolutionParameterivEXT)(GLenum,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glCopyBufferSubData)(GLenum,GLenum,GLintptr,GLintptr,GLsizeiptr);
+ void (WINE_GLAPI *p_glCopyColorSubTable)(GLenum,GLsizei,GLint,GLint,GLsizei);
+ void (WINE_GLAPI *p_glCopyColorSubTableEXT)(GLenum,GLsizei,GLint,GLint,GLsizei);
+ void (WINE_GLAPI *p_glCopyColorTable)(GLenum,GLenum,GLint,GLint,GLsizei);
+ void (WINE_GLAPI *p_glCopyColorTableSGI)(GLenum,GLenum,GLint,GLint,GLsizei);
+ void (WINE_GLAPI *p_glCopyConvolutionFilter1D)(GLenum,GLenum,GLint,GLint,GLsizei);
+ void (WINE_GLAPI *p_glCopyConvolutionFilter1DEXT)(GLenum,GLenum,GLint,GLint,GLsizei);
+ void (WINE_GLAPI *p_glCopyConvolutionFilter2D)(GLenum,GLenum,GLint,GLint,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glCopyConvolutionFilter2DEXT)(GLenum,GLenum,GLint,GLint,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glCopyImageSubData)(GLuint,GLenum,GLint,GLint,GLint,GLint,GLuint,GLenum,GLint,GLint,GLint,GLint,GLsizei,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glCopyImageSubDataNV)(GLuint,GLenum,GLint,GLint,GLint,GLint,GLuint,GLenum,GLint,GLint,GLint,GLint,GLsizei,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glCopyMultiTexImage1DEXT)(GLenum,GLenum,GLint,GLenum,GLint,GLint,GLsizei,GLint);
+ void (WINE_GLAPI *p_glCopyMultiTexImage2DEXT)(GLenum,GLenum,GLint,GLenum,GLint,GLint,GLsizei,GLsizei,GLint);
+ void (WINE_GLAPI *p_glCopyMultiTexSubImage1DEXT)(GLenum,GLenum,GLint,GLint,GLint,GLint,GLsizei);
+ void (WINE_GLAPI *p_glCopyMultiTexSubImage2DEXT)(GLenum,GLenum,GLint,GLint,GLint,GLint,GLint,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glCopyMultiTexSubImage3DEXT)(GLenum,GLenum,GLint,GLint,GLint,GLint,GLint,GLint,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glCopyPathNV)(GLuint,GLuint);
+ void (WINE_GLAPI *p_glCopyTexImage1DEXT)(GLenum,GLint,GLenum,GLint,GLint,GLsizei,GLint);
+ void (WINE_GLAPI *p_glCopyTexImage2DEXT)(GLenum,GLint,GLenum,GLint,GLint,GLsizei,GLsizei,GLint);
+ void (WINE_GLAPI *p_glCopyTexSubImage1DEXT)(GLenum,GLint,GLint,GLint,GLint,GLsizei);
+ void (WINE_GLAPI *p_glCopyTexSubImage2DEXT)(GLenum,GLint,GLint,GLint,GLint,GLint,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glCopyTexSubImage3D)(GLenum,GLint,GLint,GLint,GLint,GLint,GLint,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glCopyTexSubImage3DEXT)(GLenum,GLint,GLint,GLint,GLint,GLint,GLint,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glCopyTextureImage1DEXT)(GLuint,GLenum,GLint,GLenum,GLint,GLint,GLsizei,GLint);
+ void (WINE_GLAPI *p_glCopyTextureImage2DEXT)(GLuint,GLenum,GLint,GLenum,GLint,GLint,GLsizei,GLsizei,GLint);
+ void (WINE_GLAPI *p_glCopyTextureSubImage1DEXT)(GLuint,GLenum,GLint,GLint,GLint,GLint,GLsizei);
+ void (WINE_GLAPI *p_glCopyTextureSubImage2DEXT)(GLuint,GLenum,GLint,GLint,GLint,GLint,GLint,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glCopyTextureSubImage3DEXT)(GLuint,GLenum,GLint,GLint,GLint,GLint,GLint,GLint,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glCoverFillPathInstancedNV)(GLsizei,GLenum,const GLvoid*,GLuint,GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glCoverFillPathNV)(GLuint,GLenum);
+ void (WINE_GLAPI *p_glCoverStrokePathInstancedNV)(GLsizei,GLenum,const GLvoid*,GLuint,GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glCoverStrokePathNV)(GLuint,GLenum);
+ GLuint (WINE_GLAPI *p_glCreateProgram)(void);
+ GLhandleARB (WINE_GLAPI *p_glCreateProgramObjectARB)(void);
+ GLuint (WINE_GLAPI *p_glCreateShader)(GLenum);
+ GLhandleARB (WINE_GLAPI *p_glCreateShaderObjectARB)(GLenum);
+ GLuint (WINE_GLAPI *p_glCreateShaderProgramEXT)(GLenum,const GLchar*);
+ GLuint (WINE_GLAPI *p_glCreateShaderProgramv)(GLenum,GLsizei,const GLchar* const*);
+ GLvoid* (WINE_GLAPI *p_glCreateSyncFromCLeventARB)(void *,void *,GLbitfield);
+ void (WINE_GLAPI *p_glCullParameterdvEXT)(GLenum,GLdouble*);
+ void (WINE_GLAPI *p_glCullParameterfvEXT)(GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glCurrentPaletteMatrixARB)(GLint);
+ void (WINE_GLAPI *p_glDebugMessageCallback)(void *,const void*);
+ void (WINE_GLAPI *p_glDebugMessageCallbackAMD)(void *,GLvoid*);
+ void (WINE_GLAPI *p_glDebugMessageCallbackARB)(void *,const GLvoid*);
+ void (WINE_GLAPI *p_glDebugMessageControl)(GLenum,GLenum,GLenum,GLsizei,const GLuint*,GLboolean);
+ void (WINE_GLAPI *p_glDebugMessageControlARB)(GLenum,GLenum,GLenum,GLsizei,const GLuint*,GLboolean);
+ void (WINE_GLAPI *p_glDebugMessageEnableAMD)(GLenum,GLenum,GLsizei,const GLuint*,GLboolean);
+ void (WINE_GLAPI *p_glDebugMessageInsert)(GLenum,GLenum,GLuint,GLenum,GLsizei,const GLchar*);
+ void (WINE_GLAPI *p_glDebugMessageInsertAMD)(GLenum,GLenum,GLuint,GLsizei,const GLchar*);
+ void (WINE_GLAPI *p_glDebugMessageInsertARB)(GLenum,GLenum,GLuint,GLenum,GLsizei,const GLchar*);
+ void (WINE_GLAPI *p_glDeformSGIX)(GLbitfield);
+ void (WINE_GLAPI *p_glDeformationMap3dSGIX)(GLenum,GLdouble,GLdouble,GLint,GLint,GLdouble,GLdouble,GLint,GLint,GLdouble,GLdouble,GLint,GLint,const GLdouble*);
+ void (WINE_GLAPI *p_glDeformationMap3fSGIX)(GLenum,GLfloat,GLfloat,GLint,GLint,GLfloat,GLfloat,GLint,GLint,GLfloat,GLfloat,GLint,GLint,const GLfloat*);
+ void (WINE_GLAPI *p_glDeleteAsyncMarkersSGIX)(GLuint,GLsizei);
+ void (WINE_GLAPI *p_glDeleteBufferRegion)(GLenum);
+ void (WINE_GLAPI *p_glDeleteBuffers)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDeleteBuffersARB)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDeleteFencesAPPLE)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDeleteFencesNV)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDeleteFragmentShaderATI)(GLuint);
+ void (WINE_GLAPI *p_glDeleteFramebuffers)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDeleteFramebuffersEXT)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDeleteNamedStringARB)(GLint,const GLchar*);
+ void (WINE_GLAPI *p_glDeleteNamesAMD)(GLenum,GLuint,const GLuint*);
+ void (WINE_GLAPI *p_glDeleteObjectARB)(GLhandleARB);
+ void (WINE_GLAPI *p_glDeleteObjectBufferATI)(GLuint);
+ void (WINE_GLAPI *p_glDeleteOcclusionQueriesNV)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDeletePathsNV)(GLuint,GLsizei);
+ void (WINE_GLAPI *p_glDeletePerfMonitorsAMD)(GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glDeleteProgram)(GLuint);
+ void (WINE_GLAPI *p_glDeleteProgramPipelines)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDeleteProgramsARB)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDeleteProgramsNV)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDeleteQueries)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDeleteQueriesARB)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDeleteRenderbuffers)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDeleteRenderbuffersEXT)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDeleteSamplers)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDeleteShader)(GLuint);
+ void (WINE_GLAPI *p_glDeleteSync)(GLvoid*);
+ void (WINE_GLAPI *p_glDeleteTexturesEXT)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDeleteTransformFeedbacks)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDeleteTransformFeedbacksNV)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDeleteVertexArrays)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDeleteVertexArraysAPPLE)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glDeleteVertexShaderEXT)(GLuint);
+ void (WINE_GLAPI *p_glDepthBoundsEXT)(GLclampd,GLclampd);
+ void (WINE_GLAPI *p_glDepthBoundsdNV)(GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glDepthRangeArrayv)(GLuint,GLsizei,const GLdouble*);
+ void (WINE_GLAPI *p_glDepthRangeIndexed)(GLuint,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glDepthRangedNV)(GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glDepthRangef)(GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glDetachObjectARB)(GLhandleARB,GLhandleARB);
+ void (WINE_GLAPI *p_glDetachShader)(GLuint,GLuint);
+ void (WINE_GLAPI *p_glDetailTexFuncSGIS)(GLenum,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glDisableClientStateIndexedEXT)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glDisableIndexedEXT)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glDisableVariantClientStateEXT)(GLuint);
+ void (WINE_GLAPI *p_glDisableVertexAttribAPPLE)(GLuint,GLenum);
+ void (WINE_GLAPI *p_glDisableVertexAttribArray)(GLuint);
+ void (WINE_GLAPI *p_glDisableVertexAttribArrayARB)(GLuint);
+ void (WINE_GLAPI *p_glDisablei)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glDispatchCompute)(GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glDispatchComputeIndirect)(GLintptr);
+ void (WINE_GLAPI *p_glDrawArraysEXT)(GLenum,GLint,GLsizei);
+ void (WINE_GLAPI *p_glDrawArraysIndirect)(GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glDrawArraysInstanced)(GLenum,GLint,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glDrawArraysInstancedARB)(GLenum,GLint,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glDrawArraysInstancedBaseInstance)(GLenum,GLint,GLsizei,GLsizei,GLuint);
+ void (WINE_GLAPI *p_glDrawArraysInstancedEXT)(GLenum,GLint,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glDrawBufferRegion)(GLenum,GLint,GLint,GLsizei,GLsizei,GLint,GLint);
+ void (WINE_GLAPI *p_glDrawBuffers)(GLsizei,const GLenum*);
+ void (WINE_GLAPI *p_glDrawBuffersARB)(GLsizei,const GLenum*);
+ void (WINE_GLAPI *p_glDrawBuffersATI)(GLsizei,const GLenum*);
+ void (WINE_GLAPI *p_glDrawElementArrayAPPLE)(GLenum,GLint,GLsizei);
+ void (WINE_GLAPI *p_glDrawElementArrayATI)(GLenum,GLsizei);
+ void (WINE_GLAPI *p_glDrawElementsBaseVertex)(GLenum,GLsizei,GLenum,const GLvoid*,GLint);
+ void (WINE_GLAPI *p_glDrawElementsIndirect)(GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glDrawElementsInstanced)(GLenum,GLsizei,GLenum,const GLvoid*,GLsizei);
+ void (WINE_GLAPI *p_glDrawElementsInstancedARB)(GLenum,GLsizei,GLenum,const GLvoid*,GLsizei);
+ void (WINE_GLAPI *p_glDrawElementsInstancedBaseInstance)(GLenum,GLsizei,GLenum,const void*,GLsizei,GLuint);
+ void (WINE_GLAPI *p_glDrawElementsInstancedBaseVertex)(GLenum,GLsizei,GLenum,const GLvoid*,GLsizei,GLint);
+ void (WINE_GLAPI *p_glDrawElementsInstancedBaseVertexBaseInstance)(GLenum,GLsizei,GLenum,const void*,GLsizei,GLint,GLuint);
+ void (WINE_GLAPI *p_glDrawElementsInstancedEXT)(GLenum,GLsizei,GLenum,const GLvoid*,GLsizei);
+ void (WINE_GLAPI *p_glDrawMeshArraysSUN)(GLenum,GLint,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glDrawRangeElementArrayAPPLE)(GLenum,GLuint,GLuint,GLint,GLsizei);
+ void (WINE_GLAPI *p_glDrawRangeElementArrayATI)(GLenum,GLuint,GLuint,GLsizei);
+ void (WINE_GLAPI *p_glDrawRangeElements)(GLenum,GLuint,GLuint,GLsizei,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glDrawRangeElementsBaseVertex)(GLenum,GLuint,GLuint,GLsizei,GLenum,const GLvoid*,GLint);
+ void (WINE_GLAPI *p_glDrawRangeElementsEXT)(GLenum,GLuint,GLuint,GLsizei,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glDrawTransformFeedback)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glDrawTransformFeedbackInstanced)(GLenum,GLuint,GLsizei);
+ void (WINE_GLAPI *p_glDrawTransformFeedbackNV)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glDrawTransformFeedbackStream)(GLenum,GLuint,GLuint);
+ void (WINE_GLAPI *p_glDrawTransformFeedbackStreamInstanced)(GLenum,GLuint,GLuint,GLsizei);
+ void (WINE_GLAPI *p_glEdgeFlagFormatNV)(GLsizei);
+ void (WINE_GLAPI *p_glEdgeFlagPointerEXT)(GLsizei,GLsizei,const GLboolean*);
+ void (WINE_GLAPI *p_glEdgeFlagPointerListIBM)(GLint,const GLboolean**,GLint);
+ void (WINE_GLAPI *p_glElementPointerAPPLE)(GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glElementPointerATI)(GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glEnableClientStateIndexedEXT)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glEnableIndexedEXT)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glEnableVariantClientStateEXT)(GLuint);
+ void (WINE_GLAPI *p_glEnableVertexAttribAPPLE)(GLuint,GLenum);
+ void (WINE_GLAPI *p_glEnableVertexAttribArray)(GLuint);
+ void (WINE_GLAPI *p_glEnableVertexAttribArrayARB)(GLuint);
+ void (WINE_GLAPI *p_glEnablei)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glEndConditionalRender)(void);
+ void (WINE_GLAPI *p_glEndConditionalRenderNV)(void);
+ void (WINE_GLAPI *p_glEndFragmentShaderATI)(void);
+ void (WINE_GLAPI *p_glEndOcclusionQueryNV)(void);
+ void (WINE_GLAPI *p_glEndPerfMonitorAMD)(GLuint);
+ void (WINE_GLAPI *p_glEndQuery)(GLenum);
+ void (WINE_GLAPI *p_glEndQueryARB)(GLenum);
+ void (WINE_GLAPI *p_glEndQueryIndexed)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glEndTransformFeedback)(void);
+ void (WINE_GLAPI *p_glEndTransformFeedbackEXT)(void);
+ void (WINE_GLAPI *p_glEndTransformFeedbackNV)(void);
+ void (WINE_GLAPI *p_glEndVertexShaderEXT)(void);
+ void (WINE_GLAPI *p_glEndVideoCaptureNV)(GLuint);
+ void (WINE_GLAPI *p_glEvalMapsNV)(GLenum,GLenum);
+ void (WINE_GLAPI *p_glExecuteProgramNV)(GLenum,GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glExtractComponentEXT)(GLuint,GLuint,GLuint);
+ GLvoid* (WINE_GLAPI *p_glFenceSync)(GLenum,GLbitfield);
+ void (WINE_GLAPI *p_glFinalCombinerInputNV)(GLenum,GLenum,GLenum,GLenum);
+ GLint (WINE_GLAPI *p_glFinishAsyncSGIX)(GLuint*);
+ void (WINE_GLAPI *p_glFinishFenceAPPLE)(GLuint);
+ void (WINE_GLAPI *p_glFinishFenceNV)(GLuint);
+ void (WINE_GLAPI *p_glFinishObjectAPPLE)(GLenum,GLint);
+ void (WINE_GLAPI *p_glFinishTextureSUNX)(void);
+ void (WINE_GLAPI *p_glFlushMappedBufferRange)(GLenum,GLintptr,GLsizeiptr);
+ void (WINE_GLAPI *p_glFlushMappedBufferRangeAPPLE)(GLenum,GLintptr,GLsizeiptr);
+ void (WINE_GLAPI *p_glFlushMappedNamedBufferRangeEXT)(GLuint,GLintptr,GLsizeiptr);
+ void (WINE_GLAPI *p_glFlushPixelDataRangeNV)(GLenum);
+ void (WINE_GLAPI *p_glFlushRasterSGIX)(void);
+ void (WINE_GLAPI *p_glFlushVertexArrayRangeAPPLE)(GLsizei,GLvoid*);
+ void (WINE_GLAPI *p_glFlushVertexArrayRangeNV)(void);
+ void (WINE_GLAPI *p_glFogCoordFormatNV)(GLenum,GLsizei);
+ void (WINE_GLAPI *p_glFogCoordPointer)(GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glFogCoordPointerEXT)(GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glFogCoordPointerListIBM)(GLenum,GLint,const GLvoid**,GLint);
+ void (WINE_GLAPI *p_glFogCoordd)(GLdouble);
+ void (WINE_GLAPI *p_glFogCoorddEXT)(GLdouble);
+ void (WINE_GLAPI *p_glFogCoorddv)(const GLdouble*);
+ void (WINE_GLAPI *p_glFogCoorddvEXT)(const GLdouble*);
+ void (WINE_GLAPI *p_glFogCoordf)(GLfloat);
+ void (WINE_GLAPI *p_glFogCoordfEXT)(GLfloat);
+ void (WINE_GLAPI *p_glFogCoordfv)(const GLfloat*);
+ void (WINE_GLAPI *p_glFogCoordfvEXT)(const GLfloat*);
+ void (WINE_GLAPI *p_glFogCoordhNV)(GLhalfNV);
+ void (WINE_GLAPI *p_glFogCoordhvNV)(const GLhalfNV*);
+ void (WINE_GLAPI *p_glFogFuncSGIS)(GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glFragmentColorMaterialSGIX)(GLenum,GLenum);
+ void (WINE_GLAPI *p_glFragmentLightModelfSGIX)(GLenum,GLfloat);
+ void (WINE_GLAPI *p_glFragmentLightModelfvSGIX)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glFragmentLightModeliSGIX)(GLenum,GLint);
+ void (WINE_GLAPI *p_glFragmentLightModelivSGIX)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glFragmentLightfSGIX)(GLenum,GLenum,GLfloat);
+ void (WINE_GLAPI *p_glFragmentLightfvSGIX)(GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glFragmentLightiSGIX)(GLenum,GLenum,GLint);
+ void (WINE_GLAPI *p_glFragmentLightivSGIX)(GLenum,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glFragmentMaterialfSGIX)(GLenum,GLenum,GLfloat);
+ void (WINE_GLAPI *p_glFragmentMaterialfvSGIX)(GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glFragmentMaterialiSGIX)(GLenum,GLenum,GLint);
+ void (WINE_GLAPI *p_glFragmentMaterialivSGIX)(GLenum,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glFrameTerminatorGREMEDY)(void);
+ void (WINE_GLAPI *p_glFrameZoomSGIX)(GLint);
+ void (WINE_GLAPI *p_glFramebufferDrawBufferEXT)(GLuint,GLenum);
+ void (WINE_GLAPI *p_glFramebufferDrawBuffersEXT)(GLuint,GLsizei,const GLenum*);
+ void (WINE_GLAPI *p_glFramebufferParameteri)(GLenum,GLenum,GLint);
+ void (WINE_GLAPI *p_glFramebufferReadBufferEXT)(GLuint,GLenum);
+ void (WINE_GLAPI *p_glFramebufferRenderbuffer)(GLenum,GLenum,GLenum,GLuint);
+ void (WINE_GLAPI *p_glFramebufferRenderbufferEXT)(GLenum,GLenum,GLenum,GLuint);
+ void (WINE_GLAPI *p_glFramebufferTexture)(GLenum,GLenum,GLuint,GLint);
+ void (WINE_GLAPI *p_glFramebufferTexture1D)(GLenum,GLenum,GLenum,GLuint,GLint);
+ void (WINE_GLAPI *p_glFramebufferTexture1DEXT)(GLenum,GLenum,GLenum,GLuint,GLint);
+ void (WINE_GLAPI *p_glFramebufferTexture2D)(GLenum,GLenum,GLenum,GLuint,GLint);
+ void (WINE_GLAPI *p_glFramebufferTexture2DEXT)(GLenum,GLenum,GLenum,GLuint,GLint);
+ void (WINE_GLAPI *p_glFramebufferTexture3D)(GLenum,GLenum,GLenum,GLuint,GLint,GLint);
+ void (WINE_GLAPI *p_glFramebufferTexture3DEXT)(GLenum,GLenum,GLenum,GLuint,GLint,GLint);
+ void (WINE_GLAPI *p_glFramebufferTextureARB)(GLenum,GLenum,GLuint,GLint);
+ void (WINE_GLAPI *p_glFramebufferTextureEXT)(GLenum,GLenum,GLuint,GLint);
+ void (WINE_GLAPI *p_glFramebufferTextureFaceARB)(GLenum,GLenum,GLuint,GLint,GLenum);
+ void (WINE_GLAPI *p_glFramebufferTextureFaceEXT)(GLenum,GLenum,GLuint,GLint,GLenum);
+ void (WINE_GLAPI *p_glFramebufferTextureLayer)(GLenum,GLenum,GLuint,GLint,GLint);
+ void (WINE_GLAPI *p_glFramebufferTextureLayerARB)(GLenum,GLenum,GLuint,GLint,GLint);
+ void (WINE_GLAPI *p_glFramebufferTextureLayerEXT)(GLenum,GLenum,GLuint,GLint,GLint);
+ void (WINE_GLAPI *p_glFreeObjectBufferATI)(GLuint);
+ GLuint (WINE_GLAPI *p_glGenAsyncMarkersSGIX)(GLsizei);
+ void (WINE_GLAPI *p_glGenBuffers)(GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGenBuffersARB)(GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGenFencesAPPLE)(GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGenFencesNV)(GLsizei,GLuint*);
+ GLuint (WINE_GLAPI *p_glGenFragmentShadersATI)(GLuint);
+ void (WINE_GLAPI *p_glGenFramebuffers)(GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGenFramebuffersEXT)(GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGenNamesAMD)(GLenum,GLuint,GLuint*);
+ void (WINE_GLAPI *p_glGenOcclusionQueriesNV)(GLsizei,GLuint*);
+ GLuint (WINE_GLAPI *p_glGenPathsNV)(GLsizei);
+ void (WINE_GLAPI *p_glGenPerfMonitorsAMD)(GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGenProgramPipelines)(GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGenProgramsARB)(GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGenProgramsNV)(GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGenQueries)(GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGenQueriesARB)(GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGenRenderbuffers)(GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGenRenderbuffersEXT)(GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGenSamplers)(GLsizei,GLuint*);
+ GLuint (WINE_GLAPI *p_glGenSymbolsEXT)(GLenum,GLenum,GLenum,GLuint);
+ void (WINE_GLAPI *p_glGenTexturesEXT)(GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGenTransformFeedbacks)(GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGenTransformFeedbacksNV)(GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGenVertexArrays)(GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGenVertexArraysAPPLE)(GLsizei,GLuint*);
+ GLuint (WINE_GLAPI *p_glGenVertexShadersEXT)(GLuint);
+ void (WINE_GLAPI *p_glGenerateMipmap)(GLenum);
+ void (WINE_GLAPI *p_glGenerateMipmapEXT)(GLenum);
+ void (WINE_GLAPI *p_glGenerateMultiTexMipmapEXT)(GLenum,GLenum);
+ void (WINE_GLAPI *p_glGenerateTextureMipmapEXT)(GLuint,GLenum);
+ void (WINE_GLAPI *p_glGetActiveAtomicCounterBufferiv)(GLuint,GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetActiveAttrib)(GLuint,GLuint,GLsizei,GLsizei*,GLint*,GLenum*,GLchar*);
+ void (WINE_GLAPI *p_glGetActiveAttribARB)(GLhandleARB,GLuint,GLsizei,GLsizei*,GLint*,GLenum*,GLcharARB*);
+ void (WINE_GLAPI *p_glGetActiveSubroutineName)(GLuint,GLenum,GLuint,GLsizei,GLsizei*,GLchar*);
+ void (WINE_GLAPI *p_glGetActiveSubroutineUniformName)(GLuint,GLenum,GLuint,GLsizei,GLsizei*,GLchar*);
+ void (WINE_GLAPI *p_glGetActiveSubroutineUniformiv)(GLuint,GLenum,GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetActiveUniform)(GLuint,GLuint,GLsizei,GLsizei*,GLint*,GLenum*,GLchar*);
+ void (WINE_GLAPI *p_glGetActiveUniformARB)(GLhandleARB,GLuint,GLsizei,GLsizei*,GLint*,GLenum*,GLcharARB*);
+ void (WINE_GLAPI *p_glGetActiveUniformBlockName)(GLuint,GLuint,GLsizei,GLsizei*,GLchar*);
+ void (WINE_GLAPI *p_glGetActiveUniformBlockiv)(GLuint,GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetActiveUniformName)(GLuint,GLuint,GLsizei,GLsizei*,GLchar*);
+ void (WINE_GLAPI *p_glGetActiveUniformsiv)(GLuint,GLsizei,const GLuint*,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetActiveVaryingNV)(GLuint,GLuint,GLsizei,GLsizei*,GLsizei*,GLenum*,GLchar*);
+ void (WINE_GLAPI *p_glGetArrayObjectfvATI)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetArrayObjectivATI)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetAttachedObjectsARB)(GLhandleARB,GLsizei,GLsizei*,GLhandleARB*);
+ void (WINE_GLAPI *p_glGetAttachedShaders)(GLuint,GLsizei,GLsizei*,GLuint*);
+ GLint (WINE_GLAPI *p_glGetAttribLocation)(GLuint,const GLchar*);
+ GLint (WINE_GLAPI *p_glGetAttribLocationARB)(GLhandleARB,const GLcharARB*);
+ void (WINE_GLAPI *p_glGetBooleanIndexedvEXT)(GLenum,GLuint,GLboolean*);
+ void (WINE_GLAPI *p_glGetBooleani_v)(GLenum,GLuint,GLboolean*);
+ void (WINE_GLAPI *p_glGetBufferParameteri64v)(GLenum,GLenum,INT64*);
+ void (WINE_GLAPI *p_glGetBufferParameteriv)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetBufferParameterivARB)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetBufferParameterui64vNV)(GLenum,GLenum,UINT64*);
+ void (WINE_GLAPI *p_glGetBufferPointerv)(GLenum,GLenum,GLvoid**);
+ void (WINE_GLAPI *p_glGetBufferPointervARB)(GLenum,GLenum,GLvoid**);
+ void (WINE_GLAPI *p_glGetBufferSubData)(GLenum,GLintptr,GLsizeiptr,GLvoid*);
+ void (WINE_GLAPI *p_glGetBufferSubDataARB)(GLenum,GLintptrARB,GLsizeiptrARB,GLvoid*);
+ void (WINE_GLAPI *p_glGetColorTable)(GLenum,GLenum,GLenum,GLvoid*);
+ void (WINE_GLAPI *p_glGetColorTableEXT)(GLenum,GLenum,GLenum,GLvoid*);
+ void (WINE_GLAPI *p_glGetColorTableParameterfv)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetColorTableParameterfvEXT)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetColorTableParameterfvSGI)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetColorTableParameteriv)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetColorTableParameterivEXT)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetColorTableParameterivSGI)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetColorTableSGI)(GLenum,GLenum,GLenum,GLvoid*);
+ void (WINE_GLAPI *p_glGetCombinerInputParameterfvNV)(GLenum,GLenum,GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetCombinerInputParameterivNV)(GLenum,GLenum,GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetCombinerOutputParameterfvNV)(GLenum,GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetCombinerOutputParameterivNV)(GLenum,GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetCombinerStageParameterfvNV)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetCompressedMultiTexImageEXT)(GLenum,GLenum,GLint,GLvoid*);
+ void (WINE_GLAPI *p_glGetCompressedTexImage)(GLenum,GLint,GLvoid*);
+ void (WINE_GLAPI *p_glGetCompressedTexImageARB)(GLenum,GLint,GLvoid*);
+ void (WINE_GLAPI *p_glGetCompressedTextureImageEXT)(GLuint,GLenum,GLint,GLvoid*);
+ void (WINE_GLAPI *p_glGetConvolutionFilter)(GLenum,GLenum,GLenum,GLvoid*);
+ void (WINE_GLAPI *p_glGetConvolutionFilterEXT)(GLenum,GLenum,GLenum,GLvoid*);
+ void (WINE_GLAPI *p_glGetConvolutionParameterfv)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetConvolutionParameterfvEXT)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetConvolutionParameteriv)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetConvolutionParameterivEXT)(GLenum,GLenum,GLint*);
+ GLuint (WINE_GLAPI *p_glGetDebugMessageLog)(GLuint,GLsizei,GLenum*,GLenum*,GLuint*,GLenum*,GLsizei*,GLchar*);
+ GLuint (WINE_GLAPI *p_glGetDebugMessageLogAMD)(GLuint,GLsizei,GLenum*,GLuint*,GLuint*,GLsizei*,GLchar*);
+ GLuint (WINE_GLAPI *p_glGetDebugMessageLogARB)(GLuint,GLsizei,GLenum*,GLenum*,GLuint*,GLenum*,GLsizei*,GLchar*);
+ void (WINE_GLAPI *p_glGetDetailTexFuncSGIS)(GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetDoubleIndexedvEXT)(GLenum,GLuint,GLdouble*);
+ void (WINE_GLAPI *p_glGetDoublei_v)(GLenum,GLuint,GLdouble*);
+ void (WINE_GLAPI *p_glGetFenceivNV)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetFinalCombinerInputParameterfvNV)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetFinalCombinerInputParameterivNV)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetFloatIndexedvEXT)(GLenum,GLuint,GLfloat*);
+ void (WINE_GLAPI *p_glGetFloati_v)(GLenum,GLuint,GLfloat*);
+ void (WINE_GLAPI *p_glGetFogFuncSGIS)(GLfloat*);
+ GLint (WINE_GLAPI *p_glGetFragDataIndex)(GLuint,const GLchar*);
+ GLint (WINE_GLAPI *p_glGetFragDataLocation)(GLuint,const GLchar*);
+ GLint (WINE_GLAPI *p_glGetFragDataLocationEXT)(GLuint,const GLchar*);
+ void (WINE_GLAPI *p_glGetFragmentLightfvSGIX)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetFragmentLightivSGIX)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetFragmentMaterialfvSGIX)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetFragmentMaterialivSGIX)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetFramebufferAttachmentParameteriv)(GLenum,GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetFramebufferAttachmentParameterivEXT)(GLenum,GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetFramebufferParameteriv)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetFramebufferParameterivEXT)(GLuint,GLenum,GLint*);
+ GLenum (WINE_GLAPI *p_glGetGraphicsResetStatusARB)(void);
+ GLhandleARB (WINE_GLAPI *p_glGetHandleARB)(GLenum);
+ void (WINE_GLAPI *p_glGetHistogram)(GLenum,GLboolean,GLenum,GLenum,GLvoid*);
+ void (WINE_GLAPI *p_glGetHistogramEXT)(GLenum,GLboolean,GLenum,GLenum,GLvoid*);
+ void (WINE_GLAPI *p_glGetHistogramParameterfv)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetHistogramParameterfvEXT)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetHistogramParameteriv)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetHistogramParameterivEXT)(GLenum,GLenum,GLint*);
+ UINT64 (WINE_GLAPI *p_glGetImageHandleNV)(GLuint,GLint,GLboolean,GLint,GLenum);
+ void (WINE_GLAPI *p_glGetImageTransformParameterfvHP)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetImageTransformParameterivHP)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetInfoLogARB)(GLhandleARB,GLsizei,GLsizei*,GLcharARB*);
+ GLint (WINE_GLAPI *p_glGetInstrumentsSGIX)(void);
+ void (WINE_GLAPI *p_glGetInteger64i_v)(GLenum,GLuint,INT64*);
+ void (WINE_GLAPI *p_glGetInteger64v)(GLenum,INT64*);
+ void (WINE_GLAPI *p_glGetIntegerIndexedvEXT)(GLenum,GLuint,GLint*);
+ void (WINE_GLAPI *p_glGetIntegeri_v)(GLenum,GLuint,GLint*);
+ void (WINE_GLAPI *p_glGetIntegerui64i_vNV)(GLenum,GLuint,UINT64*);
+ void (WINE_GLAPI *p_glGetIntegerui64vNV)(GLenum,UINT64*);
+ void (WINE_GLAPI *p_glGetInternalformati64v)(GLenum,GLenum,GLenum,GLsizei,INT64*);
+ void (WINE_GLAPI *p_glGetInternalformativ)(GLenum,GLenum,GLenum,GLsizei,GLint*);
+ void (WINE_GLAPI *p_glGetInvariantBooleanvEXT)(GLuint,GLenum,GLboolean*);
+ void (WINE_GLAPI *p_glGetInvariantFloatvEXT)(GLuint,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetInvariantIntegervEXT)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetListParameterfvSGIX)(GLuint,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetListParameterivSGIX)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetLocalConstantBooleanvEXT)(GLuint,GLenum,GLboolean*);
+ void (WINE_GLAPI *p_glGetLocalConstantFloatvEXT)(GLuint,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetLocalConstantIntegervEXT)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetMapAttribParameterfvNV)(GLenum,GLuint,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetMapAttribParameterivNV)(GLenum,GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetMapControlPointsNV)(GLenum,GLuint,GLenum,GLsizei,GLsizei,GLboolean,GLvoid*);
+ void (WINE_GLAPI *p_glGetMapParameterfvNV)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetMapParameterivNV)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetMinmax)(GLenum,GLboolean,GLenum,GLenum,GLvoid*);
+ void (WINE_GLAPI *p_glGetMinmaxEXT)(GLenum,GLboolean,GLenum,GLenum,GLvoid*);
+ void (WINE_GLAPI *p_glGetMinmaxParameterfv)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetMinmaxParameterfvEXT)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetMinmaxParameteriv)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetMinmaxParameterivEXT)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetMultiTexEnvfvEXT)(GLenum,GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetMultiTexEnvivEXT)(GLenum,GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetMultiTexGendvEXT)(GLenum,GLenum,GLenum,GLdouble*);
+ void (WINE_GLAPI *p_glGetMultiTexGenfvEXT)(GLenum,GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetMultiTexGenivEXT)(GLenum,GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetMultiTexImageEXT)(GLenum,GLenum,GLint,GLenum,GLenum,GLvoid*);
+ void (WINE_GLAPI *p_glGetMultiTexLevelParameterfvEXT)(GLenum,GLenum,GLint,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetMultiTexLevelParameterivEXT)(GLenum,GLenum,GLint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetMultiTexParameterIivEXT)(GLenum,GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetMultiTexParameterIuivEXT)(GLenum,GLenum,GLenum,GLuint*);
+ void (WINE_GLAPI *p_glGetMultiTexParameterfvEXT)(GLenum,GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetMultiTexParameterivEXT)(GLenum,GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetMultisamplefv)(GLenum,GLuint,GLfloat*);
+ void (WINE_GLAPI *p_glGetMultisamplefvNV)(GLenum,GLuint,GLfloat*);
+ void (WINE_GLAPI *p_glGetNamedBufferParameterivEXT)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetNamedBufferParameterui64vNV)(GLuint,GLenum,UINT64*);
+ void (WINE_GLAPI *p_glGetNamedBufferPointervEXT)(GLuint,GLenum,GLvoid**);
+ void (WINE_GLAPI *p_glGetNamedBufferSubDataEXT)(GLuint,GLintptr,GLsizeiptr,GLvoid*);
+ void (WINE_GLAPI *p_glGetNamedFramebufferAttachmentParameterivEXT)(GLuint,GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetNamedFramebufferParameterivEXT)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetNamedProgramLocalParameterIivEXT)(GLuint,GLenum,GLuint,GLint*);
+ void (WINE_GLAPI *p_glGetNamedProgramLocalParameterIuivEXT)(GLuint,GLenum,GLuint,GLuint*);
+ void (WINE_GLAPI *p_glGetNamedProgramLocalParameterdvEXT)(GLuint,GLenum,GLuint,GLdouble*);
+ void (WINE_GLAPI *p_glGetNamedProgramLocalParameterfvEXT)(GLuint,GLenum,GLuint,GLfloat*);
+ void (WINE_GLAPI *p_glGetNamedProgramStringEXT)(GLuint,GLenum,GLenum,GLvoid*);
+ void (WINE_GLAPI *p_glGetNamedProgramivEXT)(GLuint,GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetNamedRenderbufferParameterivEXT)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetNamedStringARB)(GLint,const GLchar*,GLsizei,GLint*,GLchar*);
+ void (WINE_GLAPI *p_glGetNamedStringivARB)(GLint,const GLchar*,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetObjectBufferfvATI)(GLuint,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetObjectBufferivATI)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetObjectLabel)(GLenum,GLuint,GLsizei,GLsizei*,GLchar*);
+ void (WINE_GLAPI *p_glGetObjectParameterfvARB)(GLhandleARB,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetObjectParameterivAPPLE)(GLenum,GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetObjectParameterivARB)(GLhandleARB,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetObjectPtrLabel)(const void*,GLsizei,GLsizei*,GLchar*);
+ void (WINE_GLAPI *p_glGetOcclusionQueryivNV)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetOcclusionQueryuivNV)(GLuint,GLenum,GLuint*);
+ void (WINE_GLAPI *p_glGetPathColorGenfvNV)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetPathColorGenivNV)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetPathCommandsNV)(GLuint,GLubyte*);
+ void (WINE_GLAPI *p_glGetPathCoordsNV)(GLuint,GLfloat*);
+ void (WINE_GLAPI *p_glGetPathDashArrayNV)(GLuint,GLfloat*);
+ GLfloat (WINE_GLAPI *p_glGetPathLengthNV)(GLuint,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glGetPathMetricRangeNV)(GLbitfield,GLuint,GLsizei,GLsizei,GLfloat*);
+ void (WINE_GLAPI *p_glGetPathMetricsNV)(GLbitfield,GLsizei,GLenum,const GLvoid*,GLuint,GLsizei,GLfloat*);
+ void (WINE_GLAPI *p_glGetPathParameterfvNV)(GLuint,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetPathParameterivNV)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetPathSpacingNV)(GLenum,GLsizei,GLenum,const GLvoid*,GLuint,GLfloat,GLfloat,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetPathTexGenfvNV)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetPathTexGenivNV)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetPerfMonitorCounterDataAMD)(GLuint,GLenum,GLsizei,GLuint*,GLint*);
+ void (WINE_GLAPI *p_glGetPerfMonitorCounterInfoAMD)(GLuint,GLuint,GLenum,GLvoid*);
+ void (WINE_GLAPI *p_glGetPerfMonitorCounterStringAMD)(GLuint,GLuint,GLsizei,GLsizei*,GLchar*);
+ void (WINE_GLAPI *p_glGetPerfMonitorCountersAMD)(GLuint,GLint*,GLint*,GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGetPerfMonitorGroupStringAMD)(GLuint,GLsizei,GLsizei*,GLchar*);
+ void (WINE_GLAPI *p_glGetPerfMonitorGroupsAMD)(GLint*,GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGetPixelTexGenParameterfvSGIS)(GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetPixelTexGenParameterivSGIS)(GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetPixelTransformParameterfvEXT)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetPixelTransformParameterivEXT)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetPointerIndexedvEXT)(GLenum,GLuint,GLvoid**);
+ void (WINE_GLAPI *p_glGetPointervEXT)(GLenum,GLvoid**);
+ void (WINE_GLAPI *p_glGetProgramBinary)(GLuint,GLsizei,GLsizei*,GLenum*,GLvoid*);
+ void (WINE_GLAPI *p_glGetProgramEnvParameterIivNV)(GLenum,GLuint,GLint*);
+ void (WINE_GLAPI *p_glGetProgramEnvParameterIuivNV)(GLenum,GLuint,GLuint*);
+ void (WINE_GLAPI *p_glGetProgramEnvParameterdvARB)(GLenum,GLuint,GLdouble*);
+ void (WINE_GLAPI *p_glGetProgramEnvParameterfvARB)(GLenum,GLuint,GLfloat*);
+ void (WINE_GLAPI *p_glGetProgramInfoLog)(GLuint,GLsizei,GLsizei*,GLchar*);
+ void (WINE_GLAPI *p_glGetProgramInterfaceiv)(GLuint,GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetProgramLocalParameterIivNV)(GLenum,GLuint,GLint*);
+ void (WINE_GLAPI *p_glGetProgramLocalParameterIuivNV)(GLenum,GLuint,GLuint*);
+ void (WINE_GLAPI *p_glGetProgramLocalParameterdvARB)(GLenum,GLuint,GLdouble*);
+ void (WINE_GLAPI *p_glGetProgramLocalParameterfvARB)(GLenum,GLuint,GLfloat*);
+ void (WINE_GLAPI *p_glGetProgramNamedParameterdvNV)(GLuint,GLsizei,const GLubyte*,GLdouble*);
+ void (WINE_GLAPI *p_glGetProgramNamedParameterfvNV)(GLuint,GLsizei,const GLubyte*,GLfloat*);
+ void (WINE_GLAPI *p_glGetProgramParameterdvNV)(GLenum,GLuint,GLenum,GLdouble*);
+ void (WINE_GLAPI *p_glGetProgramParameterfvNV)(GLenum,GLuint,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetProgramPipelineInfoLog)(GLuint,GLsizei,GLsizei*,GLchar*);
+ void (WINE_GLAPI *p_glGetProgramPipelineiv)(GLuint,GLenum,GLint*);
+ GLuint (WINE_GLAPI *p_glGetProgramResourceIndex)(GLuint,GLenum,const GLchar*);
+ GLint (WINE_GLAPI *p_glGetProgramResourceLocation)(GLuint,GLenum,const GLchar*);
+ GLint (WINE_GLAPI *p_glGetProgramResourceLocationIndex)(GLuint,GLenum,const GLchar*);
+ void (WINE_GLAPI *p_glGetProgramResourceName)(GLuint,GLenum,GLuint,GLsizei,GLsizei*,GLchar*);
+ void (WINE_GLAPI *p_glGetProgramResourceiv)(GLuint,GLenum,GLuint,GLsizei,const GLenum*,GLsizei,GLsizei*,GLint*);
+ void (WINE_GLAPI *p_glGetProgramStageiv)(GLuint,GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetProgramStringARB)(GLenum,GLenum,GLvoid*);
+ void (WINE_GLAPI *p_glGetProgramStringNV)(GLuint,GLenum,GLubyte*);
+ void (WINE_GLAPI *p_glGetProgramSubroutineParameteruivNV)(GLenum,GLuint,GLuint*);
+ void (WINE_GLAPI *p_glGetProgramiv)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetProgramivARB)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetProgramivNV)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetQueryIndexediv)(GLenum,GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetQueryObjecti64v)(GLuint,GLenum,INT64*);
+ void (WINE_GLAPI *p_glGetQueryObjecti64vEXT)(GLuint,GLenum,INT64*);
+ void (WINE_GLAPI *p_glGetQueryObjectiv)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetQueryObjectivARB)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetQueryObjectui64v)(GLuint,GLenum,UINT64*);
+ void (WINE_GLAPI *p_glGetQueryObjectui64vEXT)(GLuint,GLenum,UINT64*);
+ void (WINE_GLAPI *p_glGetQueryObjectuiv)(GLuint,GLenum,GLuint*);
+ void (WINE_GLAPI *p_glGetQueryObjectuivARB)(GLuint,GLenum,GLuint*);
+ void (WINE_GLAPI *p_glGetQueryiv)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetQueryivARB)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetRenderbufferParameteriv)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetRenderbufferParameterivEXT)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetSamplerParameterIiv)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetSamplerParameterIuiv)(GLuint,GLenum,GLuint*);
+ void (WINE_GLAPI *p_glGetSamplerParameterfv)(GLuint,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetSamplerParameteriv)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetSeparableFilter)(GLenum,GLenum,GLenum,GLvoid*,GLvoid*,GLvoid*);
+ void (WINE_GLAPI *p_glGetSeparableFilterEXT)(GLenum,GLenum,GLenum,GLvoid*,GLvoid*,GLvoid*);
+ void (WINE_GLAPI *p_glGetShaderInfoLog)(GLuint,GLsizei,GLsizei*,GLchar*);
+ void (WINE_GLAPI *p_glGetShaderPrecisionFormat)(GLenum,GLenum,GLint*,GLint*);
+ void (WINE_GLAPI *p_glGetShaderSource)(GLuint,GLsizei,GLsizei*,GLchar*);
+ void (WINE_GLAPI *p_glGetShaderSourceARB)(GLhandleARB,GLsizei,GLsizei*,GLcharARB*);
+ void (WINE_GLAPI *p_glGetShaderiv)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetSharpenTexFuncSGIS)(GLenum,GLfloat*);
+ const GLubyte * (WINE_GLAPI *p_glGetStringi)(GLenum,GLuint);
+ GLuint (WINE_GLAPI *p_glGetSubroutineIndex)(GLuint,GLenum,const GLchar*);
+ GLint (WINE_GLAPI *p_glGetSubroutineUniformLocation)(GLuint,GLenum,const GLchar*);
+ void (WINE_GLAPI *p_glGetSynciv)(GLvoid*,GLenum,GLsizei,GLsizei*,GLint*);
+ void (WINE_GLAPI *p_glGetTexBumpParameterfvATI)(GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetTexBumpParameterivATI)(GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetTexFilterFuncSGIS)(GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetTexParameterIiv)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetTexParameterIivEXT)(GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetTexParameterIuiv)(GLenum,GLenum,GLuint*);
+ void (WINE_GLAPI *p_glGetTexParameterIuivEXT)(GLenum,GLenum,GLuint*);
+ void (WINE_GLAPI *p_glGetTexParameterPointervAPPLE)(GLenum,GLenum,GLvoid**);
+ UINT64 (WINE_GLAPI *p_glGetTextureHandleNV)(GLuint);
+ void (WINE_GLAPI *p_glGetTextureImageEXT)(GLuint,GLenum,GLint,GLenum,GLenum,GLvoid*);
+ void (WINE_GLAPI *p_glGetTextureLevelParameterfvEXT)(GLuint,GLenum,GLint,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetTextureLevelParameterivEXT)(GLuint,GLenum,GLint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetTextureParameterIivEXT)(GLuint,GLenum,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetTextureParameterIuivEXT)(GLuint,GLenum,GLenum,GLuint*);
+ void (WINE_GLAPI *p_glGetTextureParameterfvEXT)(GLuint,GLenum,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetTextureParameterivEXT)(GLuint,GLenum,GLenum,GLint*);
+ UINT64 (WINE_GLAPI *p_glGetTextureSamplerHandleNV)(GLuint,GLuint);
+ void (WINE_GLAPI *p_glGetTrackMatrixivNV)(GLenum,GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetTransformFeedbackVarying)(GLuint,GLuint,GLsizei,GLsizei*,GLsizei*,GLenum*,GLchar*);
+ void (WINE_GLAPI *p_glGetTransformFeedbackVaryingEXT)(GLuint,GLuint,GLsizei,GLsizei*,GLsizei*,GLenum*,GLchar*);
+ void (WINE_GLAPI *p_glGetTransformFeedbackVaryingNV)(GLuint,GLuint,GLint*);
+ GLuint (WINE_GLAPI *p_glGetUniformBlockIndex)(GLuint,const GLchar*);
+ GLint (WINE_GLAPI *p_glGetUniformBufferSizeEXT)(GLuint,GLint);
+ void (WINE_GLAPI *p_glGetUniformIndices)(GLuint,GLsizei,const GLchar* const*,GLuint*);
+ GLint (WINE_GLAPI *p_glGetUniformLocation)(GLuint,const GLchar*);
+ GLint (WINE_GLAPI *p_glGetUniformLocationARB)(GLhandleARB,const GLcharARB*);
+ GLintptr (WINE_GLAPI *p_glGetUniformOffsetEXT)(GLuint,GLint);
+ void (WINE_GLAPI *p_glGetUniformSubroutineuiv)(GLenum,GLint,GLuint*);
+ void (WINE_GLAPI *p_glGetUniformdv)(GLuint,GLint,GLdouble*);
+ void (WINE_GLAPI *p_glGetUniformfv)(GLuint,GLint,GLfloat*);
+ void (WINE_GLAPI *p_glGetUniformfvARB)(GLhandleARB,GLint,GLfloat*);
+ void (WINE_GLAPI *p_glGetUniformi64vNV)(GLuint,GLint,INT64*);
+ void (WINE_GLAPI *p_glGetUniformiv)(GLuint,GLint,GLint*);
+ void (WINE_GLAPI *p_glGetUniformivARB)(GLhandleARB,GLint,GLint*);
+ void (WINE_GLAPI *p_glGetUniformui64vNV)(GLuint,GLint,UINT64*);
+ void (WINE_GLAPI *p_glGetUniformuiv)(GLuint,GLint,GLuint*);
+ void (WINE_GLAPI *p_glGetUniformuivEXT)(GLuint,GLint,GLuint*);
+ void (WINE_GLAPI *p_glGetVariantArrayObjectfvATI)(GLuint,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetVariantArrayObjectivATI)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetVariantBooleanvEXT)(GLuint,GLenum,GLboolean*);
+ void (WINE_GLAPI *p_glGetVariantFloatvEXT)(GLuint,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetVariantIntegervEXT)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetVariantPointervEXT)(GLuint,GLenum,GLvoid**);
+ GLint (WINE_GLAPI *p_glGetVaryingLocationNV)(GLuint,const GLchar*);
+ void (WINE_GLAPI *p_glGetVertexAttribArrayObjectfvATI)(GLuint,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetVertexAttribArrayObjectivATI)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetVertexAttribIiv)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetVertexAttribIivEXT)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetVertexAttribIuiv)(GLuint,GLenum,GLuint*);
+ void (WINE_GLAPI *p_glGetVertexAttribIuivEXT)(GLuint,GLenum,GLuint*);
+ void (WINE_GLAPI *p_glGetVertexAttribLdv)(GLuint,GLenum,GLdouble*);
+ void (WINE_GLAPI *p_glGetVertexAttribLdvEXT)(GLuint,GLenum,GLdouble*);
+ void (WINE_GLAPI *p_glGetVertexAttribLi64vNV)(GLuint,GLenum,INT64*);
+ void (WINE_GLAPI *p_glGetVertexAttribLui64vNV)(GLuint,GLenum,UINT64*);
+ void (WINE_GLAPI *p_glGetVertexAttribPointerv)(GLuint,GLenum,GLvoid**);
+ void (WINE_GLAPI *p_glGetVertexAttribPointervARB)(GLuint,GLenum,GLvoid**);
+ void (WINE_GLAPI *p_glGetVertexAttribPointervNV)(GLuint,GLenum,GLvoid**);
+ void (WINE_GLAPI *p_glGetVertexAttribdv)(GLuint,GLenum,GLdouble*);
+ void (WINE_GLAPI *p_glGetVertexAttribdvARB)(GLuint,GLenum,GLdouble*);
+ void (WINE_GLAPI *p_glGetVertexAttribdvNV)(GLuint,GLenum,GLdouble*);
+ void (WINE_GLAPI *p_glGetVertexAttribfv)(GLuint,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetVertexAttribfvARB)(GLuint,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetVertexAttribfvNV)(GLuint,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetVertexAttribiv)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetVertexAttribivARB)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetVertexAttribivNV)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetVideoCaptureStreamdvNV)(GLuint,GLuint,GLenum,GLdouble*);
+ void (WINE_GLAPI *p_glGetVideoCaptureStreamfvNV)(GLuint,GLuint,GLenum,GLfloat*);
+ void (WINE_GLAPI *p_glGetVideoCaptureStreamivNV)(GLuint,GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetVideoCaptureivNV)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetVideoi64vNV)(GLuint,GLenum,INT64*);
+ void (WINE_GLAPI *p_glGetVideoivNV)(GLuint,GLenum,GLint*);
+ void (WINE_GLAPI *p_glGetVideoui64vNV)(GLuint,GLenum,UINT64*);
+ void (WINE_GLAPI *p_glGetVideouivNV)(GLuint,GLenum,GLuint*);
+ void (WINE_GLAPI *p_glGetnColorTableARB)(GLenum,GLenum,GLenum,GLsizei,GLvoid*);
+ void (WINE_GLAPI *p_glGetnCompressedTexImageARB)(GLenum,GLint,GLsizei,GLvoid*);
+ void (WINE_GLAPI *p_glGetnConvolutionFilterARB)(GLenum,GLenum,GLenum,GLsizei,GLvoid*);
+ void (WINE_GLAPI *p_glGetnHistogramARB)(GLenum,GLboolean,GLenum,GLenum,GLsizei,GLvoid*);
+ void (WINE_GLAPI *p_glGetnMapdvARB)(GLenum,GLenum,GLsizei,GLdouble*);
+ void (WINE_GLAPI *p_glGetnMapfvARB)(GLenum,GLenum,GLsizei,GLfloat*);
+ void (WINE_GLAPI *p_glGetnMapivARB)(GLenum,GLenum,GLsizei,GLint*);
+ void (WINE_GLAPI *p_glGetnMinmaxARB)(GLenum,GLboolean,GLenum,GLenum,GLsizei,GLvoid*);
+ void (WINE_GLAPI *p_glGetnPixelMapfvARB)(GLenum,GLsizei,GLfloat*);
+ void (WINE_GLAPI *p_glGetnPixelMapuivARB)(GLenum,GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGetnPixelMapusvARB)(GLenum,GLsizei,GLushort*);
+ void (WINE_GLAPI *p_glGetnPolygonStippleARB)(GLsizei,GLubyte*);
+ void (WINE_GLAPI *p_glGetnSeparableFilterARB)(GLenum,GLenum,GLenum,GLsizei,GLvoid*,GLsizei,GLvoid*,GLvoid*);
+ void (WINE_GLAPI *p_glGetnTexImageARB)(GLenum,GLint,GLenum,GLenum,GLsizei,GLvoid*);
+ void (WINE_GLAPI *p_glGetnUniformdvARB)(GLuint,GLint,GLsizei,GLdouble*);
+ void (WINE_GLAPI *p_glGetnUniformfvARB)(GLuint,GLint,GLsizei,GLfloat*);
+ void (WINE_GLAPI *p_glGetnUniformivARB)(GLuint,GLint,GLsizei,GLint*);
+ void (WINE_GLAPI *p_glGetnUniformuivARB)(GLuint,GLint,GLsizei,GLuint*);
+ void (WINE_GLAPI *p_glGlobalAlphaFactorbSUN)(GLbyte);
+ void (WINE_GLAPI *p_glGlobalAlphaFactordSUN)(GLdouble);
+ void (WINE_GLAPI *p_glGlobalAlphaFactorfSUN)(GLfloat);
+ void (WINE_GLAPI *p_glGlobalAlphaFactoriSUN)(GLint);
+ void (WINE_GLAPI *p_glGlobalAlphaFactorsSUN)(GLshort);
+ void (WINE_GLAPI *p_glGlobalAlphaFactorubSUN)(GLubyte);
+ void (WINE_GLAPI *p_glGlobalAlphaFactoruiSUN)(GLuint);
+ void (WINE_GLAPI *p_glGlobalAlphaFactorusSUN)(GLushort);
+ void (WINE_GLAPI *p_glHintPGI)(GLenum,GLint);
+ void (WINE_GLAPI *p_glHistogram)(GLenum,GLsizei,GLenum,GLboolean);
+ void (WINE_GLAPI *p_glHistogramEXT)(GLenum,GLsizei,GLenum,GLboolean);
+ void (WINE_GLAPI *p_glIglooInterfaceSGIX)(GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glImageTransformParameterfHP)(GLenum,GLenum,GLfloat);
+ void (WINE_GLAPI *p_glImageTransformParameterfvHP)(GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glImageTransformParameteriHP)(GLenum,GLenum,GLint);
+ void (WINE_GLAPI *p_glImageTransformParameterivHP)(GLenum,GLenum,const GLint*);
+ GLvoid* (WINE_GLAPI *p_glImportSyncEXT)(GLenum,GLintptr,GLbitfield);
+ void (WINE_GLAPI *p_glIndexFormatNV)(GLenum,GLsizei);
+ void (WINE_GLAPI *p_glIndexFuncEXT)(GLenum,GLclampf);
+ void (WINE_GLAPI *p_glIndexMaterialEXT)(GLenum,GLenum);
+ void (WINE_GLAPI *p_glIndexPointerEXT)(GLenum,GLsizei,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glIndexPointerListIBM)(GLenum,GLint,const GLvoid**,GLint);
+ void (WINE_GLAPI *p_glInsertComponentEXT)(GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glInstrumentsBufferSGIX)(GLsizei,GLint*);
+ void (WINE_GLAPI *p_glInterpolatePathsNV)(GLuint,GLuint,GLuint,GLfloat);
+ void (WINE_GLAPI *p_glInvalidateBufferData)(GLuint);
+ void (WINE_GLAPI *p_glInvalidateBufferSubData)(GLuint,GLintptr,GLsizeiptr);
+ void (WINE_GLAPI *p_glInvalidateFramebuffer)(GLenum,GLsizei,const GLenum*);
+ void (WINE_GLAPI *p_glInvalidateSubFramebuffer)(GLenum,GLsizei,const GLenum*,GLint,GLint,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glInvalidateTexImage)(GLuint,GLint);
+ void (WINE_GLAPI *p_glInvalidateTexSubImage)(GLuint,GLint,GLint,GLint,GLint,GLsizei,GLsizei,GLsizei);
+ GLboolean (WINE_GLAPI *p_glIsAsyncMarkerSGIX)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsBuffer)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsBufferARB)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsBufferResidentNV)(GLenum);
+ GLboolean (WINE_GLAPI *p_glIsEnabledIndexedEXT)(GLenum,GLuint);
+ GLboolean (WINE_GLAPI *p_glIsEnabledi)(GLenum,GLuint);
+ GLboolean (WINE_GLAPI *p_glIsFenceAPPLE)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsFenceNV)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsFramebuffer)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsFramebufferEXT)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsImageHandleResidentNV)(UINT64);
+ GLboolean (WINE_GLAPI *p_glIsNameAMD)(GLenum,GLuint);
+ GLboolean (WINE_GLAPI *p_glIsNamedBufferResidentNV)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsNamedStringARB)(GLint,const GLchar*);
+ GLboolean (WINE_GLAPI *p_glIsObjectBufferATI)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsOcclusionQueryNV)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsPathNV)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsPointInFillPathNV)(GLuint,GLuint,GLfloat,GLfloat);
+ GLboolean (WINE_GLAPI *p_glIsPointInStrokePathNV)(GLuint,GLfloat,GLfloat);
+ GLboolean (WINE_GLAPI *p_glIsProgram)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsProgramARB)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsProgramNV)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsProgramPipeline)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsQuery)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsQueryARB)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsRenderbuffer)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsRenderbufferEXT)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsSampler)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsShader)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsSync)(GLvoid*);
+ GLboolean (WINE_GLAPI *p_glIsTextureEXT)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsTextureHandleResidentNV)(UINT64);
+ GLboolean (WINE_GLAPI *p_glIsTransformFeedback)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsTransformFeedbackNV)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsVariantEnabledEXT)(GLuint,GLenum);
+ GLboolean (WINE_GLAPI *p_glIsVertexArray)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsVertexArrayAPPLE)(GLuint);
+ GLboolean (WINE_GLAPI *p_glIsVertexAttribEnabledAPPLE)(GLuint,GLenum);
+ void (WINE_GLAPI *p_glLightEnviSGIX)(GLenum,GLint);
+ void (WINE_GLAPI *p_glLinkProgram)(GLuint);
+ void (WINE_GLAPI *p_glLinkProgramARB)(GLhandleARB);
+ void (WINE_GLAPI *p_glListParameterfSGIX)(GLuint,GLenum,GLfloat);
+ void (WINE_GLAPI *p_glListParameterfvSGIX)(GLuint,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glListParameteriSGIX)(GLuint,GLenum,GLint);
+ void (WINE_GLAPI *p_glListParameterivSGIX)(GLuint,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glLoadIdentityDeformationMapSGIX)(GLbitfield);
+ void (WINE_GLAPI *p_glLoadProgramNV)(GLenum,GLuint,GLsizei,const GLubyte*);
+ void (WINE_GLAPI *p_glLoadTransposeMatrixd)(const GLdouble*);
+ void (WINE_GLAPI *p_glLoadTransposeMatrixdARB)(const GLdouble*);
+ void (WINE_GLAPI *p_glLoadTransposeMatrixf)(const GLfloat*);
+ void (WINE_GLAPI *p_glLoadTransposeMatrixfARB)(const GLfloat*);
+ void (WINE_GLAPI *p_glLockArraysEXT)(GLint,GLsizei);
+ void (WINE_GLAPI *p_glMTexCoord2fSGIS)(GLenum,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glMTexCoord2fvSGIS)(GLenum,GLfloat *);
+ void (WINE_GLAPI *p_glMakeBufferNonResidentNV)(GLenum);
+ void (WINE_GLAPI *p_glMakeBufferResidentNV)(GLenum,GLenum);
+ void (WINE_GLAPI *p_glMakeImageHandleNonResidentNV)(UINT64);
+ void (WINE_GLAPI *p_glMakeImageHandleResidentNV)(UINT64,GLenum);
+ void (WINE_GLAPI *p_glMakeNamedBufferNonResidentNV)(GLuint);
+ void (WINE_GLAPI *p_glMakeNamedBufferResidentNV)(GLuint,GLenum);
+ void (WINE_GLAPI *p_glMakeTextureHandleNonResidentNV)(UINT64);
+ void (WINE_GLAPI *p_glMakeTextureHandleResidentNV)(UINT64);
+ GLvoid* (WINE_GLAPI *p_glMapBuffer)(GLenum,GLenum);
+ GLvoid* (WINE_GLAPI *p_glMapBufferARB)(GLenum,GLenum);
+ GLvoid* (WINE_GLAPI *p_glMapBufferRange)(GLenum,GLintptr,GLsizeiptr,GLbitfield);
+ void (WINE_GLAPI *p_glMapControlPointsNV)(GLenum,GLuint,GLenum,GLsizei,GLsizei,GLint,GLint,GLboolean,const GLvoid*);
+ GLvoid* (WINE_GLAPI *p_glMapNamedBufferEXT)(GLuint,GLenum);
+ GLvoid* (WINE_GLAPI *p_glMapNamedBufferRangeEXT)(GLuint,GLintptr,GLsizeiptr,GLbitfield);
+ GLvoid* (WINE_GLAPI *p_glMapObjectBufferATI)(GLuint);
+ void (WINE_GLAPI *p_glMapParameterfvNV)(GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glMapParameterivNV)(GLenum,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glMapVertexAttrib1dAPPLE)(GLuint,GLuint,GLdouble,GLdouble,GLint,GLint,const GLdouble*);
+ void (WINE_GLAPI *p_glMapVertexAttrib1fAPPLE)(GLuint,GLuint,GLfloat,GLfloat,GLint,GLint,const GLfloat*);
+ void (WINE_GLAPI *p_glMapVertexAttrib2dAPPLE)(GLuint,GLuint,GLdouble,GLdouble,GLint,GLint,GLdouble,GLdouble,GLint,GLint,const GLdouble*);
+ void (WINE_GLAPI *p_glMapVertexAttrib2fAPPLE)(GLuint,GLuint,GLfloat,GLfloat,GLint,GLint,GLfloat,GLfloat,GLint,GLint,const GLfloat*);
+ void (WINE_GLAPI *p_glMatrixFrustumEXT)(GLenum,GLdouble,GLdouble,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glMatrixIndexPointerARB)(GLint,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glMatrixIndexubvARB)(GLint,const GLubyte*);
+ void (WINE_GLAPI *p_glMatrixIndexuivARB)(GLint,const GLuint*);
+ void (WINE_GLAPI *p_glMatrixIndexusvARB)(GLint,const GLushort*);
+ void (WINE_GLAPI *p_glMatrixLoadIdentityEXT)(GLenum);
+ void (WINE_GLAPI *p_glMatrixLoadTransposedEXT)(GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glMatrixLoadTransposefEXT)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glMatrixLoaddEXT)(GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glMatrixLoadfEXT)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glMatrixMultTransposedEXT)(GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glMatrixMultTransposefEXT)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glMatrixMultdEXT)(GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glMatrixMultfEXT)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glMatrixOrthoEXT)(GLenum,GLdouble,GLdouble,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glMatrixPopEXT)(GLenum);
+ void (WINE_GLAPI *p_glMatrixPushEXT)(GLenum);
+ void (WINE_GLAPI *p_glMatrixRotatedEXT)(GLenum,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glMatrixRotatefEXT)(GLenum,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glMatrixScaledEXT)(GLenum,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glMatrixScalefEXT)(GLenum,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glMatrixTranslatedEXT)(GLenum,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glMatrixTranslatefEXT)(GLenum,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glMemoryBarrier)(GLbitfield);
+ void (WINE_GLAPI *p_glMemoryBarrierEXT)(GLbitfield);
+ void (WINE_GLAPI *p_glMinSampleShading)(GLfloat);
+ void (WINE_GLAPI *p_glMinSampleShadingARB)(GLfloat);
+ void (WINE_GLAPI *p_glMinmax)(GLenum,GLenum,GLboolean);
+ void (WINE_GLAPI *p_glMinmaxEXT)(GLenum,GLenum,GLboolean);
+ void (WINE_GLAPI *p_glMultTransposeMatrixd)(const GLdouble*);
+ void (WINE_GLAPI *p_glMultTransposeMatrixdARB)(const GLdouble*);
+ void (WINE_GLAPI *p_glMultTransposeMatrixf)(const GLfloat*);
+ void (WINE_GLAPI *p_glMultTransposeMatrixfARB)(const GLfloat*);
+ void (WINE_GLAPI *p_glMultiDrawArrays)(GLenum,const GLint*,const GLsizei*,GLsizei);
+ void (WINE_GLAPI *p_glMultiDrawArraysEXT)(GLenum,const GLint*,const GLsizei*,GLsizei);
+ void (WINE_GLAPI *p_glMultiDrawArraysIndirect)(GLenum,const void*,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glMultiDrawArraysIndirectAMD)(GLenum,const GLvoid*,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glMultiDrawElementArrayAPPLE)(GLenum,const GLint*,const GLsizei*,GLsizei);
+ void (WINE_GLAPI *p_glMultiDrawElements)(GLenum,const GLsizei*,GLenum,const GLvoid* const*,GLsizei);
+ void (WINE_GLAPI *p_glMultiDrawElementsBaseVertex)(GLenum,const GLsizei*,GLenum,const GLvoid* const*,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glMultiDrawElementsEXT)(GLenum,const GLsizei*,GLenum,const GLvoid**,GLsizei);
+ void (WINE_GLAPI *p_glMultiDrawElementsIndirect)(GLenum,GLenum,const void*,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glMultiDrawElementsIndirectAMD)(GLenum,GLenum,const GLvoid*,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glMultiDrawRangeElementArrayAPPLE)(GLenum,GLuint,GLuint,const GLint*,const GLsizei*,GLsizei);
+ void (WINE_GLAPI *p_glMultiModeDrawArraysIBM)(const GLenum*,const GLint*,const GLsizei*,GLsizei,GLint);
+ void (WINE_GLAPI *p_glMultiModeDrawElementsIBM)(const GLenum*,const GLsizei*,GLenum,const GLvoid* const*,GLsizei,GLint);
+ void (WINE_GLAPI *p_glMultiTexBufferEXT)(GLenum,GLenum,GLenum,GLuint);
+ void (WINE_GLAPI *p_glMultiTexCoord1d)(GLenum,GLdouble);
+ void (WINE_GLAPI *p_glMultiTexCoord1dARB)(GLenum,GLdouble);
+ void (WINE_GLAPI *p_glMultiTexCoord1dSGIS)(GLenum,GLdouble);
+ void (WINE_GLAPI *p_glMultiTexCoord1dv)(GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glMultiTexCoord1dvARB)(GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glMultiTexCoord1dvSGIS)(GLenum,GLdouble *);
+ void (WINE_GLAPI *p_glMultiTexCoord1f)(GLenum,GLfloat);
+ void (WINE_GLAPI *p_glMultiTexCoord1fARB)(GLenum,GLfloat);
+ void (WINE_GLAPI *p_glMultiTexCoord1fSGIS)(GLenum,GLfloat);
+ void (WINE_GLAPI *p_glMultiTexCoord1fv)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glMultiTexCoord1fvARB)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glMultiTexCoord1fvSGIS)(GLenum,const GLfloat *);
+ void (WINE_GLAPI *p_glMultiTexCoord1hNV)(GLenum,GLhalfNV);
+ void (WINE_GLAPI *p_glMultiTexCoord1hvNV)(GLenum,const GLhalfNV*);
+ void (WINE_GLAPI *p_glMultiTexCoord1i)(GLenum,GLint);
+ void (WINE_GLAPI *p_glMultiTexCoord1iARB)(GLenum,GLint);
+ void (WINE_GLAPI *p_glMultiTexCoord1iSGIS)(GLenum,GLint);
+ void (WINE_GLAPI *p_glMultiTexCoord1iv)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glMultiTexCoord1ivARB)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glMultiTexCoord1ivSGIS)(GLenum,GLint *);
+ void (WINE_GLAPI *p_glMultiTexCoord1s)(GLenum,GLshort);
+ void (WINE_GLAPI *p_glMultiTexCoord1sARB)(GLenum,GLshort);
+ void (WINE_GLAPI *p_glMultiTexCoord1sSGIS)(GLenum,GLshort);
+ void (WINE_GLAPI *p_glMultiTexCoord1sv)(GLenum,const GLshort*);
+ void (WINE_GLAPI *p_glMultiTexCoord1svARB)(GLenum,const GLshort*);
+ void (WINE_GLAPI *p_glMultiTexCoord1svSGIS)(GLenum,GLshort *);
+ void (WINE_GLAPI *p_glMultiTexCoord2d)(GLenum,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glMultiTexCoord2dARB)(GLenum,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glMultiTexCoord2dSGIS)(GLenum,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glMultiTexCoord2dv)(GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glMultiTexCoord2dvARB)(GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glMultiTexCoord2dvSGIS)(GLenum,GLdouble *);
+ void (WINE_GLAPI *p_glMultiTexCoord2f)(GLenum,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glMultiTexCoord2fARB)(GLenum,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glMultiTexCoord2fSGIS)(GLenum,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glMultiTexCoord2fv)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glMultiTexCoord2fvARB)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glMultiTexCoord2fvSGIS)(GLenum,GLfloat *);
+ void (WINE_GLAPI *p_glMultiTexCoord2hNV)(GLenum,GLhalfNV,GLhalfNV);
+ void (WINE_GLAPI *p_glMultiTexCoord2hvNV)(GLenum,const GLhalfNV*);
+ void (WINE_GLAPI *p_glMultiTexCoord2i)(GLenum,GLint,GLint);
+ void (WINE_GLAPI *p_glMultiTexCoord2iARB)(GLenum,GLint,GLint);
+ void (WINE_GLAPI *p_glMultiTexCoord2iSGIS)(GLenum,GLint,GLint);
+ void (WINE_GLAPI *p_glMultiTexCoord2iv)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glMultiTexCoord2ivARB)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glMultiTexCoord2ivSGIS)(GLenum,GLint *);
+ void (WINE_GLAPI *p_glMultiTexCoord2s)(GLenum,GLshort,GLshort);
+ void (WINE_GLAPI *p_glMultiTexCoord2sARB)(GLenum,GLshort,GLshort);
+ void (WINE_GLAPI *p_glMultiTexCoord2sSGIS)(GLenum,GLshort,GLshort);
+ void (WINE_GLAPI *p_glMultiTexCoord2sv)(GLenum,const GLshort*);
+ void (WINE_GLAPI *p_glMultiTexCoord2svARB)(GLenum,const GLshort*);
+ void (WINE_GLAPI *p_glMultiTexCoord2svSGIS)(GLenum,GLshort *);
+ void (WINE_GLAPI *p_glMultiTexCoord3d)(GLenum,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glMultiTexCoord3dARB)(GLenum,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glMultiTexCoord3dSGIS)(GLenum,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glMultiTexCoord3dv)(GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glMultiTexCoord3dvARB)(GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glMultiTexCoord3dvSGIS)(GLenum,GLdouble *);
+ void (WINE_GLAPI *p_glMultiTexCoord3f)(GLenum,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glMultiTexCoord3fARB)(GLenum,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glMultiTexCoord3fSGIS)(GLenum,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glMultiTexCoord3fv)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glMultiTexCoord3fvARB)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glMultiTexCoord3fvSGIS)(GLenum,GLfloat *);
+ void (WINE_GLAPI *p_glMultiTexCoord3hNV)(GLenum,GLhalfNV,GLhalfNV,GLhalfNV);
+ void (WINE_GLAPI *p_glMultiTexCoord3hvNV)(GLenum,const GLhalfNV*);
+ void (WINE_GLAPI *p_glMultiTexCoord3i)(GLenum,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glMultiTexCoord3iARB)(GLenum,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glMultiTexCoord3iSGIS)(GLenum,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glMultiTexCoord3iv)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glMultiTexCoord3ivARB)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glMultiTexCoord3ivSGIS)(GLenum,GLint *);
+ void (WINE_GLAPI *p_glMultiTexCoord3s)(GLenum,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glMultiTexCoord3sARB)(GLenum,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glMultiTexCoord3sSGIS)(GLenum,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glMultiTexCoord3sv)(GLenum,const GLshort*);
+ void (WINE_GLAPI *p_glMultiTexCoord3svARB)(GLenum,const GLshort*);
+ void (WINE_GLAPI *p_glMultiTexCoord3svSGIS)(GLenum,GLshort *);
+ void (WINE_GLAPI *p_glMultiTexCoord4d)(GLenum,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glMultiTexCoord4dARB)(GLenum,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glMultiTexCoord4dSGIS)(GLenum,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glMultiTexCoord4dv)(GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glMultiTexCoord4dvARB)(GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glMultiTexCoord4dvSGIS)(GLenum,GLdouble *);
+ void (WINE_GLAPI *p_glMultiTexCoord4f)(GLenum,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glMultiTexCoord4fARB)(GLenum,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glMultiTexCoord4fSGIS)(GLenum,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glMultiTexCoord4fv)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glMultiTexCoord4fvARB)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glMultiTexCoord4fvSGIS)(GLenum,GLfloat *);
+ void (WINE_GLAPI *p_glMultiTexCoord4hNV)(GLenum,GLhalfNV,GLhalfNV,GLhalfNV,GLhalfNV);
+ void (WINE_GLAPI *p_glMultiTexCoord4hvNV)(GLenum,const GLhalfNV*);
+ void (WINE_GLAPI *p_glMultiTexCoord4i)(GLenum,GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glMultiTexCoord4iARB)(GLenum,GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glMultiTexCoord4iSGIS)(GLenum,GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glMultiTexCoord4iv)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glMultiTexCoord4ivARB)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glMultiTexCoord4ivSGIS)(GLenum,GLint *);
+ void (WINE_GLAPI *p_glMultiTexCoord4s)(GLenum,GLshort,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glMultiTexCoord4sARB)(GLenum,GLshort,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glMultiTexCoord4sSGIS)(GLenum,GLshort,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glMultiTexCoord4sv)(GLenum,const GLshort*);
+ void (WINE_GLAPI *p_glMultiTexCoord4svARB)(GLenum,const GLshort*);
+ void (WINE_GLAPI *p_glMultiTexCoord4svSGIS)(GLenum,GLshort *);
+ void (WINE_GLAPI *p_glMultiTexCoordP1ui)(GLenum,GLenum,GLuint);
+ void (WINE_GLAPI *p_glMultiTexCoordP1uiv)(GLenum,GLenum,const GLuint*);
+ void (WINE_GLAPI *p_glMultiTexCoordP2ui)(GLenum,GLenum,GLuint);
+ void (WINE_GLAPI *p_glMultiTexCoordP2uiv)(GLenum,GLenum,const GLuint*);
+ void (WINE_GLAPI *p_glMultiTexCoordP3ui)(GLenum,GLenum,GLuint);
+ void (WINE_GLAPI *p_glMultiTexCoordP3uiv)(GLenum,GLenum,const GLuint*);
+ void (WINE_GLAPI *p_glMultiTexCoordP4ui)(GLenum,GLenum,GLuint);
+ void (WINE_GLAPI *p_glMultiTexCoordP4uiv)(GLenum,GLenum,const GLuint*);
+ void (WINE_GLAPI *p_glMultiTexCoordPointerEXT)(GLenum,GLint,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glMultiTexCoordPointerSGIS)(GLenum,GLint,GLenum,GLsizei,GLvoid *);
+ void (WINE_GLAPI *p_glMultiTexEnvfEXT)(GLenum,GLenum,GLenum,GLfloat);
+ void (WINE_GLAPI *p_glMultiTexEnvfvEXT)(GLenum,GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glMultiTexEnviEXT)(GLenum,GLenum,GLenum,GLint);
+ void (WINE_GLAPI *p_glMultiTexEnvivEXT)(GLenum,GLenum,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glMultiTexGendEXT)(GLenum,GLenum,GLenum,GLdouble);
+ void (WINE_GLAPI *p_glMultiTexGendvEXT)(GLenum,GLenum,GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glMultiTexGenfEXT)(GLenum,GLenum,GLenum,GLfloat);
+ void (WINE_GLAPI *p_glMultiTexGenfvEXT)(GLenum,GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glMultiTexGeniEXT)(GLenum,GLenum,GLenum,GLint);
+ void (WINE_GLAPI *p_glMultiTexGenivEXT)(GLenum,GLenum,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glMultiTexImage1DEXT)(GLenum,GLenum,GLint,GLenum,GLsizei,GLint,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glMultiTexImage2DEXT)(GLenum,GLenum,GLint,GLenum,GLsizei,GLsizei,GLint,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glMultiTexImage3DEXT)(GLenum,GLenum,GLint,GLenum,GLsizei,GLsizei,GLsizei,GLint,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glMultiTexParameterIivEXT)(GLenum,GLenum,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glMultiTexParameterIuivEXT)(GLenum,GLenum,GLenum,const GLuint*);
+ void (WINE_GLAPI *p_glMultiTexParameterfEXT)(GLenum,GLenum,GLenum,GLfloat);
+ void (WINE_GLAPI *p_glMultiTexParameterfvEXT)(GLenum,GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glMultiTexParameteriEXT)(GLenum,GLenum,GLenum,GLint);
+ void (WINE_GLAPI *p_glMultiTexParameterivEXT)(GLenum,GLenum,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glMultiTexRenderbufferEXT)(GLenum,GLenum,GLuint);
+ void (WINE_GLAPI *p_glMultiTexSubImage1DEXT)(GLenum,GLenum,GLint,GLint,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glMultiTexSubImage2DEXT)(GLenum,GLenum,GLint,GLint,GLint,GLsizei,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glMultiTexSubImage3DEXT)(GLenum,GLenum,GLint,GLint,GLint,GLint,GLsizei,GLsizei,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glNamedBufferDataEXT)(GLuint,GLsizeiptr,const GLvoid*,GLenum);
+ void (WINE_GLAPI *p_glNamedBufferSubDataEXT)(GLuint,GLintptr,GLsizeiptr,const GLvoid*);
+ void (WINE_GLAPI *p_glNamedCopyBufferSubDataEXT)(GLuint,GLuint,GLintptr,GLintptr,GLsizeiptr);
+ void (WINE_GLAPI *p_glNamedFramebufferParameteriEXT)(GLuint,GLenum,GLint);
+ void (WINE_GLAPI *p_glNamedFramebufferRenderbufferEXT)(GLuint,GLenum,GLenum,GLuint);
+ void (WINE_GLAPI *p_glNamedFramebufferTexture1DEXT)(GLuint,GLenum,GLenum,GLuint,GLint);
+ void (WINE_GLAPI *p_glNamedFramebufferTexture2DEXT)(GLuint,GLenum,GLenum,GLuint,GLint);
+ void (WINE_GLAPI *p_glNamedFramebufferTexture3DEXT)(GLuint,GLenum,GLenum,GLuint,GLint,GLint);
+ void (WINE_GLAPI *p_glNamedFramebufferTextureEXT)(GLuint,GLenum,GLuint,GLint);
+ void (WINE_GLAPI *p_glNamedFramebufferTextureFaceEXT)(GLuint,GLenum,GLuint,GLint,GLenum);
+ void (WINE_GLAPI *p_glNamedFramebufferTextureLayerEXT)(GLuint,GLenum,GLuint,GLint,GLint);
+ void (WINE_GLAPI *p_glNamedProgramLocalParameter4dEXT)(GLuint,GLenum,GLuint,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glNamedProgramLocalParameter4dvEXT)(GLuint,GLenum,GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glNamedProgramLocalParameter4fEXT)(GLuint,GLenum,GLuint,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glNamedProgramLocalParameter4fvEXT)(GLuint,GLenum,GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glNamedProgramLocalParameterI4iEXT)(GLuint,GLenum,GLuint,GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glNamedProgramLocalParameterI4ivEXT)(GLuint,GLenum,GLuint,const GLint*);
+ void (WINE_GLAPI *p_glNamedProgramLocalParameterI4uiEXT)(GLuint,GLenum,GLuint,GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glNamedProgramLocalParameterI4uivEXT)(GLuint,GLenum,GLuint,const GLuint*);
+ void (WINE_GLAPI *p_glNamedProgramLocalParameters4fvEXT)(GLuint,GLenum,GLuint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glNamedProgramLocalParametersI4ivEXT)(GLuint,GLenum,GLuint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glNamedProgramLocalParametersI4uivEXT)(GLuint,GLenum,GLuint,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glNamedProgramStringEXT)(GLuint,GLenum,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glNamedRenderbufferStorageEXT)(GLuint,GLenum,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glNamedRenderbufferStorageMultisampleCoverageEXT)(GLuint,GLsizei,GLsizei,GLenum,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glNamedRenderbufferStorageMultisampleEXT)(GLuint,GLsizei,GLenum,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glNamedStringARB)(GLenum,GLint,const GLchar*,GLint,const GLchar*);
+ GLuint (WINE_GLAPI *p_glNewBufferRegion)(GLenum);
+ GLuint (WINE_GLAPI *p_glNewObjectBufferATI)(GLsizei,const GLvoid*,GLenum);
+ void (WINE_GLAPI *p_glNormal3fVertex3fSUN)(GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glNormal3fVertex3fvSUN)(const GLfloat*,const GLfloat*);
+ void (WINE_GLAPI *p_glNormal3hNV)(GLhalfNV,GLhalfNV,GLhalfNV);
+ void (WINE_GLAPI *p_glNormal3hvNV)(const GLhalfNV*);
+ void (WINE_GLAPI *p_glNormalFormatNV)(GLenum,GLsizei);
+ void (WINE_GLAPI *p_glNormalP3ui)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glNormalP3uiv)(GLenum,const GLuint*);
+ void (WINE_GLAPI *p_glNormalPointerEXT)(GLenum,GLsizei,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glNormalPointerListIBM)(GLenum,GLint,const GLvoid**,GLint);
+ void (WINE_GLAPI *p_glNormalPointervINTEL)(GLenum,const GLvoid**);
+ void (WINE_GLAPI *p_glNormalStream3bATI)(GLenum,GLbyte,GLbyte,GLbyte);
+ void (WINE_GLAPI *p_glNormalStream3bvATI)(GLenum,const GLbyte*);
+ void (WINE_GLAPI *p_glNormalStream3dATI)(GLenum,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glNormalStream3dvATI)(GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glNormalStream3fATI)(GLenum,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glNormalStream3fvATI)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glNormalStream3iATI)(GLenum,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glNormalStream3ivATI)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glNormalStream3sATI)(GLenum,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glNormalStream3svATI)(GLenum,const GLshort*);
+ void (WINE_GLAPI *p_glObjectLabel)(GLenum,GLuint,GLsizei,const GLchar*);
+ void (WINE_GLAPI *p_glObjectPtrLabel)(const void*,GLsizei,const GLchar*);
+ GLenum (WINE_GLAPI *p_glObjectPurgeableAPPLE)(GLenum,GLuint,GLenum);
+ GLenum (WINE_GLAPI *p_glObjectUnpurgeableAPPLE)(GLenum,GLuint,GLenum);
+ void (WINE_GLAPI *p_glPNTrianglesfATI)(GLenum,GLfloat);
+ void (WINE_GLAPI *p_glPNTrianglesiATI)(GLenum,GLint);
+ void (WINE_GLAPI *p_glPassTexCoordATI)(GLuint,GLuint,GLenum);
+ void (WINE_GLAPI *p_glPatchParameterfv)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glPatchParameteri)(GLenum,GLint);
+ void (WINE_GLAPI *p_glPathColorGenNV)(GLenum,GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glPathCommandsNV)(GLuint,GLsizei,const GLubyte*,GLsizei,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glPathCoordsNV)(GLuint,GLsizei,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glPathCoverDepthFuncNV)(GLenum);
+ void (WINE_GLAPI *p_glPathDashArrayNV)(GLuint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glPathFogGenNV)(GLenum);
+ void (WINE_GLAPI *p_glPathGlyphRangeNV)(GLuint,GLenum,const GLvoid*,GLbitfield,GLuint,GLsizei,GLenum,GLuint,GLfloat);
+ void (WINE_GLAPI *p_glPathGlyphsNV)(GLuint,GLenum,const GLvoid*,GLbitfield,GLsizei,GLenum,const GLvoid*,GLenum,GLuint,GLfloat);
+ void (WINE_GLAPI *p_glPathParameterfNV)(GLuint,GLenum,GLfloat);
+ void (WINE_GLAPI *p_glPathParameterfvNV)(GLuint,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glPathParameteriNV)(GLuint,GLenum,GLint);
+ void (WINE_GLAPI *p_glPathParameterivNV)(GLuint,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glPathStencilDepthOffsetNV)(GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glPathStencilFuncNV)(GLenum,GLint,GLuint);
+ void (WINE_GLAPI *p_glPathStringNV)(GLuint,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glPathSubCommandsNV)(GLuint,GLsizei,GLsizei,GLsizei,const GLubyte*,GLsizei,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glPathSubCoordsNV)(GLuint,GLsizei,GLsizei,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glPathTexGenNV)(GLenum,GLenum,GLint,const GLfloat*);
+ void (WINE_GLAPI *p_glPauseTransformFeedback)(void);
+ void (WINE_GLAPI *p_glPauseTransformFeedbackNV)(void);
+ void (WINE_GLAPI *p_glPixelDataRangeNV)(GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glPixelTexGenParameterfSGIS)(GLenum,GLfloat);
+ void (WINE_GLAPI *p_glPixelTexGenParameterfvSGIS)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glPixelTexGenParameteriSGIS)(GLenum,GLint);
+ void (WINE_GLAPI *p_glPixelTexGenParameterivSGIS)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glPixelTexGenSGIX)(GLenum);
+ void (WINE_GLAPI *p_glPixelTransformParameterfEXT)(GLenum,GLenum,GLfloat);
+ void (WINE_GLAPI *p_glPixelTransformParameterfvEXT)(GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glPixelTransformParameteriEXT)(GLenum,GLenum,GLint);
+ void (WINE_GLAPI *p_glPixelTransformParameterivEXT)(GLenum,GLenum,const GLint*);
+ GLboolean (WINE_GLAPI *p_glPointAlongPathNV)(GLuint,GLsizei,GLsizei,GLfloat,GLfloat*,GLfloat*,GLfloat*,GLfloat*);
+ void (WINE_GLAPI *p_glPointParameterf)(GLenum,GLfloat);
+ void (WINE_GLAPI *p_glPointParameterfARB)(GLenum,GLfloat);
+ void (WINE_GLAPI *p_glPointParameterfEXT)(GLenum,GLfloat);
+ void (WINE_GLAPI *p_glPointParameterfSGIS)(GLenum,GLfloat);
+ void (WINE_GLAPI *p_glPointParameterfv)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glPointParameterfvARB)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glPointParameterfvEXT)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glPointParameterfvSGIS)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glPointParameteri)(GLenum,GLint);
+ void (WINE_GLAPI *p_glPointParameteriNV)(GLenum,GLint);
+ void (WINE_GLAPI *p_glPointParameteriv)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glPointParameterivNV)(GLenum,const GLint*);
+ GLint (WINE_GLAPI *p_glPollAsyncSGIX)(GLuint*);
+ GLint (WINE_GLAPI *p_glPollInstrumentsSGIX)(GLint*);
+ void (WINE_GLAPI *p_glPolygonOffsetEXT)(GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glPopDebugGroup)(void);
+ void (WINE_GLAPI *p_glPresentFrameDualFillNV)(GLuint,UINT64,GLuint,GLuint,GLenum,GLenum,GLuint,GLenum,GLuint,GLenum,GLuint,GLenum,GLuint);
+ void (WINE_GLAPI *p_glPresentFrameKeyedNV)(GLuint,UINT64,GLuint,GLuint,GLenum,GLenum,GLuint,GLuint,GLenum,GLuint,GLuint);
+ void (WINE_GLAPI *p_glPrimitiveRestartIndex)(GLuint);
+ void (WINE_GLAPI *p_glPrimitiveRestartIndexNV)(GLuint);
+ void (WINE_GLAPI *p_glPrimitiveRestartNV)(void);
+ void (WINE_GLAPI *p_glPrioritizeTexturesEXT)(GLsizei,const GLuint*,const GLclampf*);
+ void (WINE_GLAPI *p_glProgramBinary)(GLuint,GLenum,const GLvoid*,GLsizei);
+ void (WINE_GLAPI *p_glProgramBufferParametersIivNV)(GLenum,GLuint,GLuint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glProgramBufferParametersIuivNV)(GLenum,GLuint,GLuint,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glProgramBufferParametersfvNV)(GLenum,GLuint,GLuint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramEnvParameter4dARB)(GLenum,GLuint,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glProgramEnvParameter4dvARB)(GLenum,GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramEnvParameter4fARB)(GLenum,GLuint,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glProgramEnvParameter4fvARB)(GLenum,GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramEnvParameterI4iNV)(GLenum,GLuint,GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glProgramEnvParameterI4ivNV)(GLenum,GLuint,const GLint*);
+ void (WINE_GLAPI *p_glProgramEnvParameterI4uiNV)(GLenum,GLuint,GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glProgramEnvParameterI4uivNV)(GLenum,GLuint,const GLuint*);
+ void (WINE_GLAPI *p_glProgramEnvParameters4fvEXT)(GLenum,GLuint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramEnvParametersI4ivNV)(GLenum,GLuint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glProgramEnvParametersI4uivNV)(GLenum,GLuint,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glProgramLocalParameter4dARB)(GLenum,GLuint,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glProgramLocalParameter4dvARB)(GLenum,GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramLocalParameter4fARB)(GLenum,GLuint,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glProgramLocalParameter4fvARB)(GLenum,GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramLocalParameterI4iNV)(GLenum,GLuint,GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glProgramLocalParameterI4ivNV)(GLenum,GLuint,const GLint*);
+ void (WINE_GLAPI *p_glProgramLocalParameterI4uiNV)(GLenum,GLuint,GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glProgramLocalParameterI4uivNV)(GLenum,GLuint,const GLuint*);
+ void (WINE_GLAPI *p_glProgramLocalParameters4fvEXT)(GLenum,GLuint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramLocalParametersI4ivNV)(GLenum,GLuint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glProgramLocalParametersI4uivNV)(GLenum,GLuint,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glProgramNamedParameter4dNV)(GLuint,GLsizei,const GLubyte*,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glProgramNamedParameter4dvNV)(GLuint,GLsizei,const GLubyte*,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramNamedParameter4fNV)(GLuint,GLsizei,const GLubyte*,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glProgramNamedParameter4fvNV)(GLuint,GLsizei,const GLubyte*,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramParameter4dNV)(GLenum,GLuint,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glProgramParameter4dvNV)(GLenum,GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramParameter4fNV)(GLenum,GLuint,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glProgramParameter4fvNV)(GLenum,GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramParameteri)(GLuint,GLenum,GLint);
+ void (WINE_GLAPI *p_glProgramParameteriARB)(GLuint,GLenum,GLint);
+ void (WINE_GLAPI *p_glProgramParameteriEXT)(GLuint,GLenum,GLint);
+ void (WINE_GLAPI *p_glProgramParameters4dvNV)(GLenum,GLuint,GLsizei,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramParameters4fvNV)(GLenum,GLuint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramStringARB)(GLenum,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glProgramSubroutineParametersuivNV)(GLenum,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glProgramUniform1d)(GLuint,GLint,GLdouble);
+ void (WINE_GLAPI *p_glProgramUniform1dEXT)(GLuint,GLint,GLdouble);
+ void (WINE_GLAPI *p_glProgramUniform1dv)(GLuint,GLint,GLsizei,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniform1dvEXT)(GLuint,GLint,GLsizei,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniform1f)(GLuint,GLint,GLfloat);
+ void (WINE_GLAPI *p_glProgramUniform1fEXT)(GLuint,GLint,GLfloat);
+ void (WINE_GLAPI *p_glProgramUniform1fv)(GLuint,GLint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniform1fvEXT)(GLuint,GLint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniform1i)(GLuint,GLint,GLint);
+ void (WINE_GLAPI *p_glProgramUniform1i64NV)(GLuint,GLint,INT64);
+ void (WINE_GLAPI *p_glProgramUniform1i64vNV)(GLuint,GLint,GLsizei,const INT64*);
+ void (WINE_GLAPI *p_glProgramUniform1iEXT)(GLuint,GLint,GLint);
+ void (WINE_GLAPI *p_glProgramUniform1iv)(GLuint,GLint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glProgramUniform1ivEXT)(GLuint,GLint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glProgramUniform1ui)(GLuint,GLint,GLuint);
+ void (WINE_GLAPI *p_glProgramUniform1ui64NV)(GLuint,GLint,UINT64);
+ void (WINE_GLAPI *p_glProgramUniform1ui64vNV)(GLuint,GLint,GLsizei,const UINT64*);
+ void (WINE_GLAPI *p_glProgramUniform1uiEXT)(GLuint,GLint,GLuint);
+ void (WINE_GLAPI *p_glProgramUniform1uiv)(GLuint,GLint,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glProgramUniform1uivEXT)(GLuint,GLint,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glProgramUniform2d)(GLuint,GLint,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glProgramUniform2dEXT)(GLuint,GLint,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glProgramUniform2dv)(GLuint,GLint,GLsizei,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniform2dvEXT)(GLuint,GLint,GLsizei,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniform2f)(GLuint,GLint,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glProgramUniform2fEXT)(GLuint,GLint,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glProgramUniform2fv)(GLuint,GLint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniform2fvEXT)(GLuint,GLint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniform2i)(GLuint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glProgramUniform2i64NV)(GLuint,GLint,INT64,INT64);
+ void (WINE_GLAPI *p_glProgramUniform2i64vNV)(GLuint,GLint,GLsizei,const INT64*);
+ void (WINE_GLAPI *p_glProgramUniform2iEXT)(GLuint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glProgramUniform2iv)(GLuint,GLint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glProgramUniform2ivEXT)(GLuint,GLint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glProgramUniform2ui)(GLuint,GLint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glProgramUniform2ui64NV)(GLuint,GLint,UINT64,UINT64);
+ void (WINE_GLAPI *p_glProgramUniform2ui64vNV)(GLuint,GLint,GLsizei,const UINT64*);
+ void (WINE_GLAPI *p_glProgramUniform2uiEXT)(GLuint,GLint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glProgramUniform2uiv)(GLuint,GLint,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glProgramUniform2uivEXT)(GLuint,GLint,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glProgramUniform3d)(GLuint,GLint,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glProgramUniform3dEXT)(GLuint,GLint,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glProgramUniform3dv)(GLuint,GLint,GLsizei,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniform3dvEXT)(GLuint,GLint,GLsizei,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniform3f)(GLuint,GLint,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glProgramUniform3fEXT)(GLuint,GLint,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glProgramUniform3fv)(GLuint,GLint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniform3fvEXT)(GLuint,GLint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniform3i)(GLuint,GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glProgramUniform3i64NV)(GLuint,GLint,INT64,INT64,INT64);
+ void (WINE_GLAPI *p_glProgramUniform3i64vNV)(GLuint,GLint,GLsizei,const INT64*);
+ void (WINE_GLAPI *p_glProgramUniform3iEXT)(GLuint,GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glProgramUniform3iv)(GLuint,GLint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glProgramUniform3ivEXT)(GLuint,GLint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glProgramUniform3ui)(GLuint,GLint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glProgramUniform3ui64NV)(GLuint,GLint,UINT64,UINT64,UINT64);
+ void (WINE_GLAPI *p_glProgramUniform3ui64vNV)(GLuint,GLint,GLsizei,const UINT64*);
+ void (WINE_GLAPI *p_glProgramUniform3uiEXT)(GLuint,GLint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glProgramUniform3uiv)(GLuint,GLint,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glProgramUniform3uivEXT)(GLuint,GLint,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glProgramUniform4d)(GLuint,GLint,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glProgramUniform4dEXT)(GLuint,GLint,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glProgramUniform4dv)(GLuint,GLint,GLsizei,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniform4dvEXT)(GLuint,GLint,GLsizei,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniform4f)(GLuint,GLint,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glProgramUniform4fEXT)(GLuint,GLint,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glProgramUniform4fv)(GLuint,GLint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniform4fvEXT)(GLuint,GLint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniform4i)(GLuint,GLint,GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glProgramUniform4i64NV)(GLuint,GLint,INT64,INT64,INT64,INT64);
+ void (WINE_GLAPI *p_glProgramUniform4i64vNV)(GLuint,GLint,GLsizei,const INT64*);
+ void (WINE_GLAPI *p_glProgramUniform4iEXT)(GLuint,GLint,GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glProgramUniform4iv)(GLuint,GLint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glProgramUniform4ivEXT)(GLuint,GLint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glProgramUniform4ui)(GLuint,GLint,GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glProgramUniform4ui64NV)(GLuint,GLint,UINT64,UINT64,UINT64,UINT64);
+ void (WINE_GLAPI *p_glProgramUniform4ui64vNV)(GLuint,GLint,GLsizei,const UINT64*);
+ void (WINE_GLAPI *p_glProgramUniform4uiEXT)(GLuint,GLint,GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glProgramUniform4uiv)(GLuint,GLint,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glProgramUniform4uivEXT)(GLuint,GLint,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glProgramUniformHandleui64NV)(GLuint,GLint,UINT64);
+ void (WINE_GLAPI *p_glProgramUniformHandleui64vNV)(GLuint,GLint,GLsizei,const UINT64*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix2dv)(GLuint,GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix2dvEXT)(GLuint,GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix2fv)(GLuint,GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix2fvEXT)(GLuint,GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix2x3dv)(GLuint,GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix2x3dvEXT)(GLuint,GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix2x3fv)(GLuint,GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix2x3fvEXT)(GLuint,GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix2x4dv)(GLuint,GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix2x4dvEXT)(GLuint,GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix2x4fv)(GLuint,GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix2x4fvEXT)(GLuint,GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix3dv)(GLuint,GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix3dvEXT)(GLuint,GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix3fv)(GLuint,GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix3fvEXT)(GLuint,GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix3x2dv)(GLuint,GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix3x2dvEXT)(GLuint,GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix3x2fv)(GLuint,GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix3x2fvEXT)(GLuint,GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix3x4dv)(GLuint,GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix3x4dvEXT)(GLuint,GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix3x4fv)(GLuint,GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix3x4fvEXT)(GLuint,GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix4dv)(GLuint,GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix4dvEXT)(GLuint,GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix4fv)(GLuint,GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix4fvEXT)(GLuint,GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix4x2dv)(GLuint,GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix4x2dvEXT)(GLuint,GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix4x2fv)(GLuint,GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix4x2fvEXT)(GLuint,GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix4x3dv)(GLuint,GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix4x3dvEXT)(GLuint,GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix4x3fv)(GLuint,GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniformMatrix4x3fvEXT)(GLuint,GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glProgramUniformui64NV)(GLuint,GLint,UINT64);
+ void (WINE_GLAPI *p_glProgramUniformui64vNV)(GLuint,GLint,GLsizei,const UINT64*);
+ void (WINE_GLAPI *p_glProgramVertexLimitNV)(GLenum,GLint);
+ void (WINE_GLAPI *p_glProvokingVertex)(GLenum);
+ void (WINE_GLAPI *p_glProvokingVertexEXT)(GLenum);
+ void (WINE_GLAPI *p_glPushClientAttribDefaultEXT)(GLbitfield);
+ void (WINE_GLAPI *p_glPushDebugGroup)(GLenum,GLuint,GLsizei,const GLchar*);
+ void (WINE_GLAPI *p_glQueryCounter)(GLuint,GLenum);
+ void (WINE_GLAPI *p_glReadBufferRegion)(GLenum,GLint,GLint,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glReadInstrumentsSGIX)(GLint);
+ void (WINE_GLAPI *p_glReadnPixelsARB)(GLint,GLint,GLsizei,GLsizei,GLenum,GLenum,GLsizei,GLvoid*);
+ void (WINE_GLAPI *p_glReferencePlaneSGIX)(const GLdouble*);
+ void (WINE_GLAPI *p_glReleaseShaderCompiler)(void);
+ void (WINE_GLAPI *p_glRenderbufferStorage)(GLenum,GLenum,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glRenderbufferStorageEXT)(GLenum,GLenum,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glRenderbufferStorageMultisample)(GLenum,GLsizei,GLenum,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glRenderbufferStorageMultisampleCoverageNV)(GLenum,GLsizei,GLsizei,GLenum,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glRenderbufferStorageMultisampleEXT)(GLenum,GLsizei,GLenum,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glReplacementCodePointerSUN)(GLenum,GLsizei,const GLvoid**);
+ void (WINE_GLAPI *p_glReplacementCodeubSUN)(GLubyte);
+ void (WINE_GLAPI *p_glReplacementCodeubvSUN)(const GLubyte*);
+ void (WINE_GLAPI *p_glReplacementCodeuiColor3fVertex3fSUN)(GLuint,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glReplacementCodeuiColor3fVertex3fvSUN)(const GLuint*,const GLfloat*,const GLfloat*);
+ void (WINE_GLAPI *p_glReplacementCodeuiColor4fNormal3fVertex3fSUN)(GLuint,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glReplacementCodeuiColor4fNormal3fVertex3fvSUN)(const GLuint*,const GLfloat*,const GLfloat*,const GLfloat*);
+ void (WINE_GLAPI *p_glReplacementCodeuiColor4ubVertex3fSUN)(GLuint,GLubyte,GLubyte,GLubyte,GLubyte,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glReplacementCodeuiColor4ubVertex3fvSUN)(const GLuint*,const GLubyte*,const GLfloat*);
+ void (WINE_GLAPI *p_glReplacementCodeuiNormal3fVertex3fSUN)(GLuint,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glReplacementCodeuiNormal3fVertex3fvSUN)(const GLuint*,const GLfloat*,const GLfloat*);
+ void (WINE_GLAPI *p_glReplacementCodeuiSUN)(GLuint);
+ void (WINE_GLAPI *p_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN)(GLuint,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN)(const GLuint*,const GLfloat*,const GLfloat*,const GLfloat*,const GLfloat*);
+ void (WINE_GLAPI *p_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN)(GLuint,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN)(const GLuint*,const GLfloat*,const GLfloat*,const GLfloat*);
+ void (WINE_GLAPI *p_glReplacementCodeuiTexCoord2fVertex3fSUN)(GLuint,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glReplacementCodeuiTexCoord2fVertex3fvSUN)(const GLuint*,const GLfloat*,const GLfloat*);
+ void (WINE_GLAPI *p_glReplacementCodeuiVertex3fSUN)(GLuint,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glReplacementCodeuiVertex3fvSUN)(const GLuint*,const GLfloat*);
+ void (WINE_GLAPI *p_glReplacementCodeuivSUN)(const GLuint*);
+ void (WINE_GLAPI *p_glReplacementCodeusSUN)(GLushort);
+ void (WINE_GLAPI *p_glReplacementCodeusvSUN)(const GLushort*);
+ void (WINE_GLAPI *p_glRequestResidentProgramsNV)(GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glResetHistogram)(GLenum);
+ void (WINE_GLAPI *p_glResetHistogramEXT)(GLenum);
+ void (WINE_GLAPI *p_glResetMinmax)(GLenum);
+ void (WINE_GLAPI *p_glResetMinmaxEXT)(GLenum);
+ void (WINE_GLAPI *p_glResizeBuffersMESA)(void);
+ void (WINE_GLAPI *p_glResumeTransformFeedback)(void);
+ void (WINE_GLAPI *p_glResumeTransformFeedbackNV)(void);
+ void (WINE_GLAPI *p_glSampleCoverage)(GLfloat,GLboolean);
+ void (WINE_GLAPI *p_glSampleCoverageARB)(GLfloat,GLboolean);
+ void (WINE_GLAPI *p_glSampleMapATI)(GLuint,GLuint,GLenum);
+ void (WINE_GLAPI *p_glSampleMaskEXT)(GLclampf,GLboolean);
+ void (WINE_GLAPI *p_glSampleMaskIndexedNV)(GLuint,GLbitfield);
+ void (WINE_GLAPI *p_glSampleMaskSGIS)(GLclampf,GLboolean);
+ void (WINE_GLAPI *p_glSampleMaski)(GLuint,GLbitfield);
+ void (WINE_GLAPI *p_glSamplePatternEXT)(GLenum);
+ void (WINE_GLAPI *p_glSamplePatternSGIS)(GLenum);
+ void (WINE_GLAPI *p_glSamplerParameterIiv)(GLuint,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glSamplerParameterIuiv)(GLuint,GLenum,const GLuint*);
+ void (WINE_GLAPI *p_glSamplerParameterf)(GLuint,GLenum,GLfloat);
+ void (WINE_GLAPI *p_glSamplerParameterfv)(GLuint,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glSamplerParameteri)(GLuint,GLenum,GLint);
+ void (WINE_GLAPI *p_glSamplerParameteriv)(GLuint,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glScissorArrayv)(GLuint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glScissorIndexed)(GLuint,GLint,GLint,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glScissorIndexedv)(GLuint,const GLint*);
+ void (WINE_GLAPI *p_glSecondaryColor3b)(GLbyte,GLbyte,GLbyte);
+ void (WINE_GLAPI *p_glSecondaryColor3bEXT)(GLbyte,GLbyte,GLbyte);
+ void (WINE_GLAPI *p_glSecondaryColor3bv)(const GLbyte*);
+ void (WINE_GLAPI *p_glSecondaryColor3bvEXT)(const GLbyte*);
+ void (WINE_GLAPI *p_glSecondaryColor3d)(GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glSecondaryColor3dEXT)(GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glSecondaryColor3dv)(const GLdouble*);
+ void (WINE_GLAPI *p_glSecondaryColor3dvEXT)(const GLdouble*);
+ void (WINE_GLAPI *p_glSecondaryColor3f)(GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glSecondaryColor3fEXT)(GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glSecondaryColor3fv)(const GLfloat*);
+ void (WINE_GLAPI *p_glSecondaryColor3fvEXT)(const GLfloat*);
+ void (WINE_GLAPI *p_glSecondaryColor3hNV)(GLhalfNV,GLhalfNV,GLhalfNV);
+ void (WINE_GLAPI *p_glSecondaryColor3hvNV)(const GLhalfNV*);
+ void (WINE_GLAPI *p_glSecondaryColor3i)(GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glSecondaryColor3iEXT)(GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glSecondaryColor3iv)(const GLint*);
+ void (WINE_GLAPI *p_glSecondaryColor3ivEXT)(const GLint*);
+ void (WINE_GLAPI *p_glSecondaryColor3s)(GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glSecondaryColor3sEXT)(GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glSecondaryColor3sv)(const GLshort*);
+ void (WINE_GLAPI *p_glSecondaryColor3svEXT)(const GLshort*);
+ void (WINE_GLAPI *p_glSecondaryColor3ub)(GLubyte,GLubyte,GLubyte);
+ void (WINE_GLAPI *p_glSecondaryColor3ubEXT)(GLubyte,GLubyte,GLubyte);
+ void (WINE_GLAPI *p_glSecondaryColor3ubv)(const GLubyte*);
+ void (WINE_GLAPI *p_glSecondaryColor3ubvEXT)(const GLubyte*);
+ void (WINE_GLAPI *p_glSecondaryColor3ui)(GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glSecondaryColor3uiEXT)(GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glSecondaryColor3uiv)(const GLuint*);
+ void (WINE_GLAPI *p_glSecondaryColor3uivEXT)(const GLuint*);
+ void (WINE_GLAPI *p_glSecondaryColor3us)(GLushort,GLushort,GLushort);
+ void (WINE_GLAPI *p_glSecondaryColor3usEXT)(GLushort,GLushort,GLushort);
+ void (WINE_GLAPI *p_glSecondaryColor3usv)(const GLushort*);
+ void (WINE_GLAPI *p_glSecondaryColor3usvEXT)(const GLushort*);
+ void (WINE_GLAPI *p_glSecondaryColorFormatNV)(GLint,GLenum,GLsizei);
+ void (WINE_GLAPI *p_glSecondaryColorP3ui)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glSecondaryColorP3uiv)(GLenum,const GLuint*);
+ void (WINE_GLAPI *p_glSecondaryColorPointer)(GLint,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glSecondaryColorPointerEXT)(GLint,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glSecondaryColorPointerListIBM)(GLint,GLenum,GLint,const GLvoid**,GLint);
+ void (WINE_GLAPI *p_glSelectPerfMonitorCountersAMD)(GLuint,GLboolean,GLuint,GLint,GLuint*);
+ void (WINE_GLAPI *p_glSelectTextureCoordSetSGIS)(GLenum);
+ void (WINE_GLAPI *p_glSelectTextureSGIS)(GLenum);
+ void (WINE_GLAPI *p_glSeparableFilter2D)(GLenum,GLenum,GLsizei,GLsizei,GLenum,GLenum,const GLvoid*,const GLvoid*);
+ void (WINE_GLAPI *p_glSeparableFilter2DEXT)(GLenum,GLenum,GLsizei,GLsizei,GLenum,GLenum,const GLvoid*,const GLvoid*);
+ void (WINE_GLAPI *p_glSetFenceAPPLE)(GLuint);
+ void (WINE_GLAPI *p_glSetFenceNV)(GLuint,GLenum);
+ void (WINE_GLAPI *p_glSetFragmentShaderConstantATI)(GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glSetInvariantEXT)(GLuint,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glSetLocalConstantEXT)(GLuint,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glSetMultisamplefvAMD)(GLenum,GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glShaderBinary)(GLsizei,const GLuint*,GLenum,const GLvoid*,GLsizei);
+ void (WINE_GLAPI *p_glShaderOp1EXT)(GLenum,GLuint,GLuint);
+ void (WINE_GLAPI *p_glShaderOp2EXT)(GLenum,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glShaderOp3EXT)(GLenum,GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glShaderSource)(GLuint,GLsizei,const GLchar* const*,const GLint*);
+ void (WINE_GLAPI *p_glShaderSourceARB)(GLhandleARB,GLsizei,const GLcharARB**,const GLint*);
+ void (WINE_GLAPI *p_glShaderStorageBlockBinding)(GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glSharpenTexFuncSGIS)(GLenum,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glSpriteParameterfSGIX)(GLenum,GLfloat);
+ void (WINE_GLAPI *p_glSpriteParameterfvSGIX)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glSpriteParameteriSGIX)(GLenum,GLint);
+ void (WINE_GLAPI *p_glSpriteParameterivSGIX)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glStartInstrumentsSGIX)(void);
+ void (WINE_GLAPI *p_glStencilClearTagEXT)(GLsizei,GLuint);
+ void (WINE_GLAPI *p_glStencilFillPathInstancedNV)(GLsizei,GLenum,const GLvoid*,GLuint,GLenum,GLuint,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glStencilFillPathNV)(GLuint,GLenum,GLuint);
+ void (WINE_GLAPI *p_glStencilFuncSeparate)(GLenum,GLenum,GLint,GLuint);
+ void (WINE_GLAPI *p_glStencilFuncSeparateATI)(GLenum,GLenum,GLint,GLuint);
+ void (WINE_GLAPI *p_glStencilMaskSeparate)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glStencilOpSeparate)(GLenum,GLenum,GLenum,GLenum);
+ void (WINE_GLAPI *p_glStencilOpSeparateATI)(GLenum,GLenum,GLenum,GLenum);
+ void (WINE_GLAPI *p_glStencilOpValueAMD)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glStencilStrokePathInstancedNV)(GLsizei,GLenum,const GLvoid*,GLuint,GLint,GLuint,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glStencilStrokePathNV)(GLuint,GLint,GLuint);
+ void (WINE_GLAPI *p_glStopInstrumentsSGIX)(GLint);
+ void (WINE_GLAPI *p_glStringMarkerGREMEDY)(GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glSwizzleEXT)(GLuint,GLuint,GLenum,GLenum,GLenum,GLenum);
+ void (WINE_GLAPI *p_glTagSampleBufferSGIX)(void);
+ void (WINE_GLAPI *p_glTangent3bEXT)(GLbyte,GLbyte,GLbyte);
+ void (WINE_GLAPI *p_glTangent3bvEXT)(const GLbyte*);
+ void (WINE_GLAPI *p_glTangent3dEXT)(GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glTangent3dvEXT)(const GLdouble*);
+ void (WINE_GLAPI *p_glTangent3fEXT)(GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glTangent3fvEXT)(const GLfloat*);
+ void (WINE_GLAPI *p_glTangent3iEXT)(GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glTangent3ivEXT)(const GLint*);
+ void (WINE_GLAPI *p_glTangent3sEXT)(GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glTangent3svEXT)(const GLshort*);
+ void (WINE_GLAPI *p_glTangentPointerEXT)(GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glTbufferMask3DFX)(GLuint);
+ void (WINE_GLAPI *p_glTessellationFactorAMD)(GLfloat);
+ void (WINE_GLAPI *p_glTessellationModeAMD)(GLenum);
+ GLboolean (WINE_GLAPI *p_glTestFenceAPPLE)(GLuint);
+ GLboolean (WINE_GLAPI *p_glTestFenceNV)(GLuint);
+ GLboolean (WINE_GLAPI *p_glTestObjectAPPLE)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glTexBuffer)(GLenum,GLenum,GLuint);
+ void (WINE_GLAPI *p_glTexBufferARB)(GLenum,GLenum,GLuint);
+ void (WINE_GLAPI *p_glTexBufferEXT)(GLenum,GLenum,GLuint);
+ void (WINE_GLAPI *p_glTexBufferRange)(GLenum,GLenum,GLuint,GLintptr,GLsizeiptr);
+ void (WINE_GLAPI *p_glTexBumpParameterfvATI)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glTexBumpParameterivATI)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glTexCoord1hNV)(GLhalfNV);
+ void (WINE_GLAPI *p_glTexCoord1hvNV)(const GLhalfNV*);
+ void (WINE_GLAPI *p_glTexCoord2fColor3fVertex3fSUN)(GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glTexCoord2fColor3fVertex3fvSUN)(const GLfloat*,const GLfloat*,const GLfloat*);
+ void (WINE_GLAPI *p_glTexCoord2fColor4fNormal3fVertex3fSUN)(GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glTexCoord2fColor4fNormal3fVertex3fvSUN)(const GLfloat*,const GLfloat*,const GLfloat*,const GLfloat*);
+ void (WINE_GLAPI *p_glTexCoord2fColor4ubVertex3fSUN)(GLfloat,GLfloat,GLubyte,GLubyte,GLubyte,GLubyte,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glTexCoord2fColor4ubVertex3fvSUN)(const GLfloat*,const GLubyte*,const GLfloat*);
+ void (WINE_GLAPI *p_glTexCoord2fNormal3fVertex3fSUN)(GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glTexCoord2fNormal3fVertex3fvSUN)(const GLfloat*,const GLfloat*,const GLfloat*);
+ void (WINE_GLAPI *p_glTexCoord2fVertex3fSUN)(GLfloat,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glTexCoord2fVertex3fvSUN)(const GLfloat*,const GLfloat*);
+ void (WINE_GLAPI *p_glTexCoord2hNV)(GLhalfNV,GLhalfNV);
+ void (WINE_GLAPI *p_glTexCoord2hvNV)(const GLhalfNV*);
+ void (WINE_GLAPI *p_glTexCoord3hNV)(GLhalfNV,GLhalfNV,GLhalfNV);
+ void (WINE_GLAPI *p_glTexCoord3hvNV)(const GLhalfNV*);
+ void (WINE_GLAPI *p_glTexCoord4fColor4fNormal3fVertex4fSUN)(GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glTexCoord4fColor4fNormal3fVertex4fvSUN)(const GLfloat*,const GLfloat*,const GLfloat*,const GLfloat*);
+ void (WINE_GLAPI *p_glTexCoord4fVertex4fSUN)(GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glTexCoord4fVertex4fvSUN)(const GLfloat*,const GLfloat*);
+ void (WINE_GLAPI *p_glTexCoord4hNV)(GLhalfNV,GLhalfNV,GLhalfNV,GLhalfNV);
+ void (WINE_GLAPI *p_glTexCoord4hvNV)(const GLhalfNV*);
+ void (WINE_GLAPI *p_glTexCoordFormatNV)(GLint,GLenum,GLsizei);
+ void (WINE_GLAPI *p_glTexCoordP1ui)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glTexCoordP1uiv)(GLenum,const GLuint*);
+ void (WINE_GLAPI *p_glTexCoordP2ui)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glTexCoordP2uiv)(GLenum,const GLuint*);
+ void (WINE_GLAPI *p_glTexCoordP3ui)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glTexCoordP3uiv)(GLenum,const GLuint*);
+ void (WINE_GLAPI *p_glTexCoordP4ui)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glTexCoordP4uiv)(GLenum,const GLuint*);
+ void (WINE_GLAPI *p_glTexCoordPointerEXT)(GLint,GLenum,GLsizei,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glTexCoordPointerListIBM)(GLint,GLenum,GLint,const GLvoid**,GLint);
+ void (WINE_GLAPI *p_glTexCoordPointervINTEL)(GLint,GLenum,const GLvoid**);
+ void (WINE_GLAPI *p_glTexFilterFuncSGIS)(GLenum,GLenum,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glTexImage2DMultisample)(GLenum,GLsizei,GLint,GLsizei,GLsizei,GLboolean);
+ void (WINE_GLAPI *p_glTexImage2DMultisampleCoverageNV)(GLenum,GLsizei,GLsizei,GLint,GLsizei,GLsizei,GLboolean);
+ void (WINE_GLAPI *p_glTexImage3D)(GLenum,GLint,GLint,GLsizei,GLsizei,GLsizei,GLint,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glTexImage3DEXT)(GLenum,GLint,GLenum,GLsizei,GLsizei,GLsizei,GLint,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glTexImage3DMultisample)(GLenum,GLsizei,GLint,GLsizei,GLsizei,GLsizei,GLboolean);
+ void (WINE_GLAPI *p_glTexImage3DMultisampleCoverageNV)(GLenum,GLsizei,GLsizei,GLint,GLsizei,GLsizei,GLsizei,GLboolean);
+ void (WINE_GLAPI *p_glTexImage4DSGIS)(GLenum,GLint,GLenum,GLsizei,GLsizei,GLsizei,GLsizei,GLint,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glTexParameterIiv)(GLenum,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glTexParameterIivEXT)(GLenum,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glTexParameterIuiv)(GLenum,GLenum,const GLuint*);
+ void (WINE_GLAPI *p_glTexParameterIuivEXT)(GLenum,GLenum,const GLuint*);
+ void (WINE_GLAPI *p_glTexRenderbufferNV)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glTexStorage1D)(GLenum,GLsizei,GLenum,GLsizei);
+ void (WINE_GLAPI *p_glTexStorage2D)(GLenum,GLsizei,GLenum,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glTexStorage2DMultisample)(GLenum,GLsizei,GLenum,GLsizei,GLsizei,GLboolean);
+ void (WINE_GLAPI *p_glTexStorage3D)(GLenum,GLsizei,GLenum,GLsizei,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glTexStorage3DMultisample)(GLenum,GLsizei,GLenum,GLsizei,GLsizei,GLsizei,GLboolean);
+ void (WINE_GLAPI *p_glTexStorageSparseAMD)(GLenum,GLenum,GLsizei,GLsizei,GLsizei,GLsizei,GLbitfield);
+ void (WINE_GLAPI *p_glTexSubImage1DEXT)(GLenum,GLint,GLint,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glTexSubImage2DEXT)(GLenum,GLint,GLint,GLint,GLsizei,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glTexSubImage3D)(GLenum,GLint,GLint,GLint,GLint,GLsizei,GLsizei,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glTexSubImage3DEXT)(GLenum,GLint,GLint,GLint,GLint,GLsizei,GLsizei,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glTexSubImage4DSGIS)(GLenum,GLint,GLint,GLint,GLint,GLint,GLsizei,GLsizei,GLsizei,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glTextureBarrierNV)(void);
+ void (WINE_GLAPI *p_glTextureBufferEXT)(GLuint,GLenum,GLenum,GLuint);
+ void (WINE_GLAPI *p_glTextureBufferRangeEXT)(GLuint,GLenum,GLenum,GLuint,GLintptr,GLsizeiptr);
+ void (WINE_GLAPI *p_glTextureColorMaskSGIS)(GLboolean,GLboolean,GLboolean,GLboolean);
+ void (WINE_GLAPI *p_glTextureImage1DEXT)(GLuint,GLenum,GLint,GLenum,GLsizei,GLint,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glTextureImage2DEXT)(GLuint,GLenum,GLint,GLenum,GLsizei,GLsizei,GLint,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glTextureImage2DMultisampleCoverageNV)(GLuint,GLenum,GLsizei,GLsizei,GLint,GLsizei,GLsizei,GLboolean);
+ void (WINE_GLAPI *p_glTextureImage2DMultisampleNV)(GLuint,GLenum,GLsizei,GLint,GLsizei,GLsizei,GLboolean);
+ void (WINE_GLAPI *p_glTextureImage3DEXT)(GLuint,GLenum,GLint,GLenum,GLsizei,GLsizei,GLsizei,GLint,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glTextureImage3DMultisampleCoverageNV)(GLuint,GLenum,GLsizei,GLsizei,GLint,GLsizei,GLsizei,GLsizei,GLboolean);
+ void (WINE_GLAPI *p_glTextureImage3DMultisampleNV)(GLuint,GLenum,GLsizei,GLint,GLsizei,GLsizei,GLsizei,GLboolean);
+ void (WINE_GLAPI *p_glTextureLightEXT)(GLenum);
+ void (WINE_GLAPI *p_glTextureMaterialEXT)(GLenum,GLenum);
+ void (WINE_GLAPI *p_glTextureNormalEXT)(GLenum);
+ void (WINE_GLAPI *p_glTextureParameterIivEXT)(GLuint,GLenum,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glTextureParameterIuivEXT)(GLuint,GLenum,GLenum,const GLuint*);
+ void (WINE_GLAPI *p_glTextureParameterfEXT)(GLuint,GLenum,GLenum,GLfloat);
+ void (WINE_GLAPI *p_glTextureParameterfvEXT)(GLuint,GLenum,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glTextureParameteriEXT)(GLuint,GLenum,GLenum,GLint);
+ void (WINE_GLAPI *p_glTextureParameterivEXT)(GLuint,GLenum,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glTextureRangeAPPLE)(GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glTextureRenderbufferEXT)(GLuint,GLenum,GLuint);
+ void (WINE_GLAPI *p_glTextureStorage1DEXT)(GLuint,GLenum,GLsizei,GLenum,GLsizei);
+ void (WINE_GLAPI *p_glTextureStorage2DEXT)(GLuint,GLenum,GLsizei,GLenum,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glTextureStorage2DMultisampleEXT)(GLuint,GLenum,GLsizei,GLenum,GLsizei,GLsizei,GLboolean);
+ void (WINE_GLAPI *p_glTextureStorage3DEXT)(GLuint,GLenum,GLsizei,GLenum,GLsizei,GLsizei,GLsizei);
+ void (WINE_GLAPI *p_glTextureStorage3DMultisampleEXT)(GLuint,GLenum,GLsizei,GLenum,GLsizei,GLsizei,GLsizei,GLboolean);
+ void (WINE_GLAPI *p_glTextureStorageSparseAMD)(GLuint,GLenum,GLenum,GLsizei,GLsizei,GLsizei,GLsizei,GLbitfield);
+ void (WINE_GLAPI *p_glTextureSubImage1DEXT)(GLuint,GLenum,GLint,GLint,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glTextureSubImage2DEXT)(GLuint,GLenum,GLint,GLint,GLint,GLsizei,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glTextureSubImage3DEXT)(GLuint,GLenum,GLint,GLint,GLint,GLint,GLsizei,GLsizei,GLsizei,GLenum,GLenum,const GLvoid*);
+ void (WINE_GLAPI *p_glTextureView)(GLuint,GLenum,GLuint,GLenum,GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glTrackMatrixNV)(GLenum,GLuint,GLenum,GLenum);
+ void (WINE_GLAPI *p_glTransformFeedbackAttribsNV)(GLuint,const GLint*,GLenum);
+ void (WINE_GLAPI *p_glTransformFeedbackStreamAttribsNV)(GLsizei,const GLint*,GLsizei,const GLint*,GLenum);
+ void (WINE_GLAPI *p_glTransformFeedbackVaryings)(GLuint,GLsizei,const GLchar* const*,GLenum);
+ void (WINE_GLAPI *p_glTransformFeedbackVaryingsEXT)(GLuint,GLsizei,const GLchar**,GLenum);
+ void (WINE_GLAPI *p_glTransformFeedbackVaryingsNV)(GLuint,GLsizei,const GLint*,GLenum);
+ void (WINE_GLAPI *p_glTransformPathNV)(GLuint,GLuint,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glUniform1d)(GLint,GLdouble);
+ void (WINE_GLAPI *p_glUniform1dv)(GLint,GLsizei,const GLdouble*);
+ void (WINE_GLAPI *p_glUniform1f)(GLint,GLfloat);
+ void (WINE_GLAPI *p_glUniform1fARB)(GLint,GLfloat);
+ void (WINE_GLAPI *p_glUniform1fv)(GLint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glUniform1fvARB)(GLint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glUniform1i)(GLint,GLint);
+ void (WINE_GLAPI *p_glUniform1i64NV)(GLint,INT64);
+ void (WINE_GLAPI *p_glUniform1i64vNV)(GLint,GLsizei,const INT64*);
+ void (WINE_GLAPI *p_glUniform1iARB)(GLint,GLint);
+ void (WINE_GLAPI *p_glUniform1iv)(GLint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glUniform1ivARB)(GLint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glUniform1ui)(GLint,GLuint);
+ void (WINE_GLAPI *p_glUniform1ui64NV)(GLint,UINT64);
+ void (WINE_GLAPI *p_glUniform1ui64vNV)(GLint,GLsizei,const UINT64*);
+ void (WINE_GLAPI *p_glUniform1uiEXT)(GLint,GLuint);
+ void (WINE_GLAPI *p_glUniform1uiv)(GLint,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glUniform1uivEXT)(GLint,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glUniform2d)(GLint,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glUniform2dv)(GLint,GLsizei,const GLdouble*);
+ void (WINE_GLAPI *p_glUniform2f)(GLint,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glUniform2fARB)(GLint,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glUniform2fv)(GLint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glUniform2fvARB)(GLint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glUniform2i)(GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glUniform2i64NV)(GLint,INT64,INT64);
+ void (WINE_GLAPI *p_glUniform2i64vNV)(GLint,GLsizei,const INT64*);
+ void (WINE_GLAPI *p_glUniform2iARB)(GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glUniform2iv)(GLint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glUniform2ivARB)(GLint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glUniform2ui)(GLint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glUniform2ui64NV)(GLint,UINT64,UINT64);
+ void (WINE_GLAPI *p_glUniform2ui64vNV)(GLint,GLsizei,const UINT64*);
+ void (WINE_GLAPI *p_glUniform2uiEXT)(GLint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glUniform2uiv)(GLint,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glUniform2uivEXT)(GLint,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glUniform3d)(GLint,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glUniform3dv)(GLint,GLsizei,const GLdouble*);
+ void (WINE_GLAPI *p_glUniform3f)(GLint,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glUniform3fARB)(GLint,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glUniform3fv)(GLint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glUniform3fvARB)(GLint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glUniform3i)(GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glUniform3i64NV)(GLint,INT64,INT64,INT64);
+ void (WINE_GLAPI *p_glUniform3i64vNV)(GLint,GLsizei,const INT64*);
+ void (WINE_GLAPI *p_glUniform3iARB)(GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glUniform3iv)(GLint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glUniform3ivARB)(GLint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glUniform3ui)(GLint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glUniform3ui64NV)(GLint,UINT64,UINT64,UINT64);
+ void (WINE_GLAPI *p_glUniform3ui64vNV)(GLint,GLsizei,const UINT64*);
+ void (WINE_GLAPI *p_glUniform3uiEXT)(GLint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glUniform3uiv)(GLint,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glUniform3uivEXT)(GLint,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glUniform4d)(GLint,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glUniform4dv)(GLint,GLsizei,const GLdouble*);
+ void (WINE_GLAPI *p_glUniform4f)(GLint,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glUniform4fARB)(GLint,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glUniform4fv)(GLint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glUniform4fvARB)(GLint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glUniform4i)(GLint,GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glUniform4i64NV)(GLint,INT64,INT64,INT64,INT64);
+ void (WINE_GLAPI *p_glUniform4i64vNV)(GLint,GLsizei,const INT64*);
+ void (WINE_GLAPI *p_glUniform4iARB)(GLint,GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glUniform4iv)(GLint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glUniform4ivARB)(GLint,GLsizei,const GLint*);
+ void (WINE_GLAPI *p_glUniform4ui)(GLint,GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glUniform4ui64NV)(GLint,UINT64,UINT64,UINT64,UINT64);
+ void (WINE_GLAPI *p_glUniform4ui64vNV)(GLint,GLsizei,const UINT64*);
+ void (WINE_GLAPI *p_glUniform4uiEXT)(GLint,GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glUniform4uiv)(GLint,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glUniform4uivEXT)(GLint,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glUniformBlockBinding)(GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glUniformBufferEXT)(GLuint,GLint,GLuint);
+ void (WINE_GLAPI *p_glUniformHandleui64NV)(GLint,UINT64);
+ void (WINE_GLAPI *p_glUniformHandleui64vNV)(GLint,GLsizei,const UINT64*);
+ void (WINE_GLAPI *p_glUniformMatrix2dv)(GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glUniformMatrix2fv)(GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glUniformMatrix2fvARB)(GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glUniformMatrix2x3dv)(GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glUniformMatrix2x3fv)(GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glUniformMatrix2x4dv)(GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glUniformMatrix2x4fv)(GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glUniformMatrix3dv)(GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glUniformMatrix3fv)(GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glUniformMatrix3fvARB)(GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glUniformMatrix3x2dv)(GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glUniformMatrix3x2fv)(GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glUniformMatrix3x4dv)(GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glUniformMatrix3x4fv)(GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glUniformMatrix4dv)(GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glUniformMatrix4fv)(GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glUniformMatrix4fvARB)(GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glUniformMatrix4x2dv)(GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glUniformMatrix4x2fv)(GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glUniformMatrix4x3dv)(GLint,GLsizei,GLboolean,const GLdouble*);
+ void (WINE_GLAPI *p_glUniformMatrix4x3fv)(GLint,GLsizei,GLboolean,const GLfloat*);
+ void (WINE_GLAPI *p_glUniformSubroutinesuiv)(GLenum,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glUniformui64NV)(GLint,UINT64);
+ void (WINE_GLAPI *p_glUniformui64vNV)(GLint,GLsizei,const UINT64*);
+ void (WINE_GLAPI *p_glUnlockArraysEXT)(void);
+ GLboolean (WINE_GLAPI *p_glUnmapBuffer)(GLenum);
+ GLboolean (WINE_GLAPI *p_glUnmapBufferARB)(GLenum);
+ GLboolean (WINE_GLAPI *p_glUnmapNamedBufferEXT)(GLuint);
+ void (WINE_GLAPI *p_glUnmapObjectBufferATI)(GLuint);
+ void (WINE_GLAPI *p_glUpdateObjectBufferATI)(GLuint,GLuint,GLsizei,const GLvoid*,GLenum);
+ void (WINE_GLAPI *p_glUseProgram)(GLuint);
+ void (WINE_GLAPI *p_glUseProgramObjectARB)(GLhandleARB);
+ void (WINE_GLAPI *p_glUseProgramStages)(GLuint,GLbitfield,GLuint);
+ void (WINE_GLAPI *p_glUseShaderProgramEXT)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glVDPAUFiniNV)(void);
+ void (WINE_GLAPI *p_glVDPAUGetSurfaceivNV)(GLvdpauSurfaceNV,GLenum,GLsizei,GLsizei*,GLint*);
+ void (WINE_GLAPI *p_glVDPAUInitNV)(const GLvoid*,const GLvoid*);
+ void (WINE_GLAPI *p_glVDPAUIsSurfaceNV)(GLvdpauSurfaceNV);
+ void (WINE_GLAPI *p_glVDPAUMapSurfacesNV)(GLsizei,const GLvdpauSurfaceNV*);
+ GLvdpauSurfaceNV (WINE_GLAPI *p_glVDPAURegisterOutputSurfaceNV)(GLvoid*,GLenum,GLsizei,const GLuint*);
+ GLvdpauSurfaceNV (WINE_GLAPI *p_glVDPAURegisterVideoSurfaceNV)(const GLvoid*,GLenum,GLsizei,const GLuint*);
+ void (WINE_GLAPI *p_glVDPAUSurfaceAccessNV)(GLvdpauSurfaceNV,GLenum);
+ void (WINE_GLAPI *p_glVDPAUUnmapSurfacesNV)(GLsizei,const GLvdpauSurfaceNV*);
+ void (WINE_GLAPI *p_glVDPAUUnregisterSurfaceNV)(GLvdpauSurfaceNV);
+ void (WINE_GLAPI *p_glValidateProgram)(GLuint);
+ void (WINE_GLAPI *p_glValidateProgramARB)(GLhandleARB);
+ void (WINE_GLAPI *p_glValidateProgramPipeline)(GLuint);
+ void (WINE_GLAPI *p_glVariantArrayObjectATI)(GLuint,GLenum,GLsizei,GLuint,GLuint);
+ void (WINE_GLAPI *p_glVariantPointerEXT)(GLuint,GLenum,GLuint,const GLvoid*);
+ void (WINE_GLAPI *p_glVariantbvEXT)(GLuint,const GLbyte*);
+ void (WINE_GLAPI *p_glVariantdvEXT)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVariantfvEXT)(GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glVariantivEXT)(GLuint,const GLint*);
+ void (WINE_GLAPI *p_glVariantsvEXT)(GLuint,const GLshort*);
+ void (WINE_GLAPI *p_glVariantubvEXT)(GLuint,const GLubyte*);
+ void (WINE_GLAPI *p_glVariantuivEXT)(GLuint,const GLuint*);
+ void (WINE_GLAPI *p_glVariantusvEXT)(GLuint,const GLushort*);
+ void (WINE_GLAPI *p_glVertex2hNV)(GLhalfNV,GLhalfNV);
+ void (WINE_GLAPI *p_glVertex2hvNV)(const GLhalfNV*);
+ void (WINE_GLAPI *p_glVertex3hNV)(GLhalfNV,GLhalfNV,GLhalfNV);
+ void (WINE_GLAPI *p_glVertex3hvNV)(const GLhalfNV*);
+ void (WINE_GLAPI *p_glVertex4hNV)(GLhalfNV,GLhalfNV,GLhalfNV,GLhalfNV);
+ void (WINE_GLAPI *p_glVertex4hvNV)(const GLhalfNV*);
+ void (WINE_GLAPI *p_glVertexArrayBindVertexBufferEXT)(GLuint,GLuint,GLuint,GLintptr,GLsizei);
+ void (WINE_GLAPI *p_glVertexArrayParameteriAPPLE)(GLenum,GLint);
+ void (WINE_GLAPI *p_glVertexArrayRangeAPPLE)(GLsizei,GLvoid*);
+ void (WINE_GLAPI *p_glVertexArrayRangeNV)(GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glVertexArrayVertexAttribBindingEXT)(GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glVertexArrayVertexAttribFormatEXT)(GLuint,GLuint,GLint,GLenum,GLboolean,GLuint);
+ void (WINE_GLAPI *p_glVertexArrayVertexAttribIFormatEXT)(GLuint,GLuint,GLint,GLenum,GLuint);
+ void (WINE_GLAPI *p_glVertexArrayVertexAttribLFormatEXT)(GLuint,GLuint,GLint,GLenum,GLuint);
+ void (WINE_GLAPI *p_glVertexArrayVertexAttribLOffsetEXT)(GLuint,GLuint,GLuint,GLint,GLenum,GLsizei,GLintptr);
+ void (WINE_GLAPI *p_glVertexArrayVertexBindingDivisorEXT)(GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glVertexAttrib1d)(GLuint,GLdouble);
+ void (WINE_GLAPI *p_glVertexAttrib1dARB)(GLuint,GLdouble);
+ void (WINE_GLAPI *p_glVertexAttrib1dNV)(GLuint,GLdouble);
+ void (WINE_GLAPI *p_glVertexAttrib1dv)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttrib1dvARB)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttrib1dvNV)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttrib1f)(GLuint,GLfloat);
+ void (WINE_GLAPI *p_glVertexAttrib1fARB)(GLuint,GLfloat);
+ void (WINE_GLAPI *p_glVertexAttrib1fNV)(GLuint,GLfloat);
+ void (WINE_GLAPI *p_glVertexAttrib1fv)(GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glVertexAttrib1fvARB)(GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glVertexAttrib1fvNV)(GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glVertexAttrib1hNV)(GLuint,GLhalfNV);
+ void (WINE_GLAPI *p_glVertexAttrib1hvNV)(GLuint,const GLhalfNV*);
+ void (WINE_GLAPI *p_glVertexAttrib1s)(GLuint,GLshort);
+ void (WINE_GLAPI *p_glVertexAttrib1sARB)(GLuint,GLshort);
+ void (WINE_GLAPI *p_glVertexAttrib1sNV)(GLuint,GLshort);
+ void (WINE_GLAPI *p_glVertexAttrib1sv)(GLuint,const GLshort*);
+ void (WINE_GLAPI *p_glVertexAttrib1svARB)(GLuint,const GLshort*);
+ void (WINE_GLAPI *p_glVertexAttrib1svNV)(GLuint,const GLshort*);
+ void (WINE_GLAPI *p_glVertexAttrib2d)(GLuint,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertexAttrib2dARB)(GLuint,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertexAttrib2dNV)(GLuint,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertexAttrib2dv)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttrib2dvARB)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttrib2dvNV)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttrib2f)(GLuint,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glVertexAttrib2fARB)(GLuint,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glVertexAttrib2fNV)(GLuint,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glVertexAttrib2fv)(GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glVertexAttrib2fvARB)(GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glVertexAttrib2fvNV)(GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glVertexAttrib2hNV)(GLuint,GLhalfNV,GLhalfNV);
+ void (WINE_GLAPI *p_glVertexAttrib2hvNV)(GLuint,const GLhalfNV*);
+ void (WINE_GLAPI *p_glVertexAttrib2s)(GLuint,GLshort,GLshort);
+ void (WINE_GLAPI *p_glVertexAttrib2sARB)(GLuint,GLshort,GLshort);
+ void (WINE_GLAPI *p_glVertexAttrib2sNV)(GLuint,GLshort,GLshort);
+ void (WINE_GLAPI *p_glVertexAttrib2sv)(GLuint,const GLshort*);
+ void (WINE_GLAPI *p_glVertexAttrib2svARB)(GLuint,const GLshort*);
+ void (WINE_GLAPI *p_glVertexAttrib2svNV)(GLuint,const GLshort*);
+ void (WINE_GLAPI *p_glVertexAttrib3d)(GLuint,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertexAttrib3dARB)(GLuint,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertexAttrib3dNV)(GLuint,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertexAttrib3dv)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttrib3dvARB)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttrib3dvNV)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttrib3f)(GLuint,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glVertexAttrib3fARB)(GLuint,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glVertexAttrib3fNV)(GLuint,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glVertexAttrib3fv)(GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glVertexAttrib3fvARB)(GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glVertexAttrib3fvNV)(GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glVertexAttrib3hNV)(GLuint,GLhalfNV,GLhalfNV,GLhalfNV);
+ void (WINE_GLAPI *p_glVertexAttrib3hvNV)(GLuint,const GLhalfNV*);
+ void (WINE_GLAPI *p_glVertexAttrib3s)(GLuint,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glVertexAttrib3sARB)(GLuint,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glVertexAttrib3sNV)(GLuint,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glVertexAttrib3sv)(GLuint,const GLshort*);
+ void (WINE_GLAPI *p_glVertexAttrib3svARB)(GLuint,const GLshort*);
+ void (WINE_GLAPI *p_glVertexAttrib3svNV)(GLuint,const GLshort*);
+ void (WINE_GLAPI *p_glVertexAttrib4Nbv)(GLuint,const GLbyte*);
+ void (WINE_GLAPI *p_glVertexAttrib4NbvARB)(GLuint,const GLbyte*);
+ void (WINE_GLAPI *p_glVertexAttrib4Niv)(GLuint,const GLint*);
+ void (WINE_GLAPI *p_glVertexAttrib4NivARB)(GLuint,const GLint*);
+ void (WINE_GLAPI *p_glVertexAttrib4Nsv)(GLuint,const GLshort*);
+ void (WINE_GLAPI *p_glVertexAttrib4NsvARB)(GLuint,const GLshort*);
+ void (WINE_GLAPI *p_glVertexAttrib4Nub)(GLuint,GLubyte,GLubyte,GLubyte,GLubyte);
+ void (WINE_GLAPI *p_glVertexAttrib4NubARB)(GLuint,GLubyte,GLubyte,GLubyte,GLubyte);
+ void (WINE_GLAPI *p_glVertexAttrib4Nubv)(GLuint,const GLubyte*);
+ void (WINE_GLAPI *p_glVertexAttrib4NubvARB)(GLuint,const GLubyte*);
+ void (WINE_GLAPI *p_glVertexAttrib4Nuiv)(GLuint,const GLuint*);
+ void (WINE_GLAPI *p_glVertexAttrib4NuivARB)(GLuint,const GLuint*);
+ void (WINE_GLAPI *p_glVertexAttrib4Nusv)(GLuint,const GLushort*);
+ void (WINE_GLAPI *p_glVertexAttrib4NusvARB)(GLuint,const GLushort*);
+ void (WINE_GLAPI *p_glVertexAttrib4bv)(GLuint,const GLbyte*);
+ void (WINE_GLAPI *p_glVertexAttrib4bvARB)(GLuint,const GLbyte*);
+ void (WINE_GLAPI *p_glVertexAttrib4d)(GLuint,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertexAttrib4dARB)(GLuint,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertexAttrib4dNV)(GLuint,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertexAttrib4dv)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttrib4dvARB)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttrib4dvNV)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttrib4f)(GLuint,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glVertexAttrib4fARB)(GLuint,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glVertexAttrib4fNV)(GLuint,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glVertexAttrib4fv)(GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glVertexAttrib4fvARB)(GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glVertexAttrib4fvNV)(GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glVertexAttrib4hNV)(GLuint,GLhalfNV,GLhalfNV,GLhalfNV,GLhalfNV);
+ void (WINE_GLAPI *p_glVertexAttrib4hvNV)(GLuint,const GLhalfNV*);
+ void (WINE_GLAPI *p_glVertexAttrib4iv)(GLuint,const GLint*);
+ void (WINE_GLAPI *p_glVertexAttrib4ivARB)(GLuint,const GLint*);
+ void (WINE_GLAPI *p_glVertexAttrib4s)(GLuint,GLshort,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glVertexAttrib4sARB)(GLuint,GLshort,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glVertexAttrib4sNV)(GLuint,GLshort,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glVertexAttrib4sv)(GLuint,const GLshort*);
+ void (WINE_GLAPI *p_glVertexAttrib4svARB)(GLuint,const GLshort*);
+ void (WINE_GLAPI *p_glVertexAttrib4svNV)(GLuint,const GLshort*);
+ void (WINE_GLAPI *p_glVertexAttrib4ubNV)(GLuint,GLubyte,GLubyte,GLubyte,GLubyte);
+ void (WINE_GLAPI *p_glVertexAttrib4ubv)(GLuint,const GLubyte*);
+ void (WINE_GLAPI *p_glVertexAttrib4ubvARB)(GLuint,const GLubyte*);
+ void (WINE_GLAPI *p_glVertexAttrib4ubvNV)(GLuint,const GLubyte*);
+ void (WINE_GLAPI *p_glVertexAttrib4uiv)(GLuint,const GLuint*);
+ void (WINE_GLAPI *p_glVertexAttrib4uivARB)(GLuint,const GLuint*);
+ void (WINE_GLAPI *p_glVertexAttrib4usv)(GLuint,const GLushort*);
+ void (WINE_GLAPI *p_glVertexAttrib4usvARB)(GLuint,const GLushort*);
+ void (WINE_GLAPI *p_glVertexAttribArrayObjectATI)(GLuint,GLint,GLenum,GLboolean,GLsizei,GLuint,GLuint);
+ void (WINE_GLAPI *p_glVertexAttribBinding)(GLuint,GLuint);
+ void (WINE_GLAPI *p_glVertexAttribDivisor)(GLuint,GLuint);
+ void (WINE_GLAPI *p_glVertexAttribDivisorARB)(GLuint,GLuint);
+ void (WINE_GLAPI *p_glVertexAttribFormat)(GLuint,GLint,GLenum,GLboolean,GLuint);
+ void (WINE_GLAPI *p_glVertexAttribFormatNV)(GLuint,GLint,GLenum,GLboolean,GLsizei);
+ void (WINE_GLAPI *p_glVertexAttribI1i)(GLuint,GLint);
+ void (WINE_GLAPI *p_glVertexAttribI1iEXT)(GLuint,GLint);
+ void (WINE_GLAPI *p_glVertexAttribI1iv)(GLuint,const GLint*);
+ void (WINE_GLAPI *p_glVertexAttribI1ivEXT)(GLuint,const GLint*);
+ void (WINE_GLAPI *p_glVertexAttribI1ui)(GLuint,GLuint);
+ void (WINE_GLAPI *p_glVertexAttribI1uiEXT)(GLuint,GLuint);
+ void (WINE_GLAPI *p_glVertexAttribI1uiv)(GLuint,const GLuint*);
+ void (WINE_GLAPI *p_glVertexAttribI1uivEXT)(GLuint,const GLuint*);
+ void (WINE_GLAPI *p_glVertexAttribI2i)(GLuint,GLint,GLint);
+ void (WINE_GLAPI *p_glVertexAttribI2iEXT)(GLuint,GLint,GLint);
+ void (WINE_GLAPI *p_glVertexAttribI2iv)(GLuint,const GLint*);
+ void (WINE_GLAPI *p_glVertexAttribI2ivEXT)(GLuint,const GLint*);
+ void (WINE_GLAPI *p_glVertexAttribI2ui)(GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glVertexAttribI2uiEXT)(GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glVertexAttribI2uiv)(GLuint,const GLuint*);
+ void (WINE_GLAPI *p_glVertexAttribI2uivEXT)(GLuint,const GLuint*);
+ void (WINE_GLAPI *p_glVertexAttribI3i)(GLuint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glVertexAttribI3iEXT)(GLuint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glVertexAttribI3iv)(GLuint,const GLint*);
+ void (WINE_GLAPI *p_glVertexAttribI3ivEXT)(GLuint,const GLint*);
+ void (WINE_GLAPI *p_glVertexAttribI3ui)(GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glVertexAttribI3uiEXT)(GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glVertexAttribI3uiv)(GLuint,const GLuint*);
+ void (WINE_GLAPI *p_glVertexAttribI3uivEXT)(GLuint,const GLuint*);
+ void (WINE_GLAPI *p_glVertexAttribI4bv)(GLuint,const GLbyte*);
+ void (WINE_GLAPI *p_glVertexAttribI4bvEXT)(GLuint,const GLbyte*);
+ void (WINE_GLAPI *p_glVertexAttribI4i)(GLuint,GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glVertexAttribI4iEXT)(GLuint,GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glVertexAttribI4iv)(GLuint,const GLint*);
+ void (WINE_GLAPI *p_glVertexAttribI4ivEXT)(GLuint,const GLint*);
+ void (WINE_GLAPI *p_glVertexAttribI4sv)(GLuint,const GLshort*);
+ void (WINE_GLAPI *p_glVertexAttribI4svEXT)(GLuint,const GLshort*);
+ void (WINE_GLAPI *p_glVertexAttribI4ubv)(GLuint,const GLubyte*);
+ void (WINE_GLAPI *p_glVertexAttribI4ubvEXT)(GLuint,const GLubyte*);
+ void (WINE_GLAPI *p_glVertexAttribI4ui)(GLuint,GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glVertexAttribI4uiEXT)(GLuint,GLuint,GLuint,GLuint,GLuint);
+ void (WINE_GLAPI *p_glVertexAttribI4uiv)(GLuint,const GLuint*);
+ void (WINE_GLAPI *p_glVertexAttribI4uivEXT)(GLuint,const GLuint*);
+ void (WINE_GLAPI *p_glVertexAttribI4usv)(GLuint,const GLushort*);
+ void (WINE_GLAPI *p_glVertexAttribI4usvEXT)(GLuint,const GLushort*);
+ void (WINE_GLAPI *p_glVertexAttribIFormat)(GLuint,GLint,GLenum,GLuint);
+ void (WINE_GLAPI *p_glVertexAttribIFormatNV)(GLuint,GLint,GLenum,GLsizei);
+ void (WINE_GLAPI *p_glVertexAttribIPointer)(GLuint,GLint,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glVertexAttribIPointerEXT)(GLuint,GLint,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glVertexAttribL1d)(GLuint,GLdouble);
+ void (WINE_GLAPI *p_glVertexAttribL1dEXT)(GLuint,GLdouble);
+ void (WINE_GLAPI *p_glVertexAttribL1dv)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttribL1dvEXT)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttribL1i64NV)(GLuint,INT64);
+ void (WINE_GLAPI *p_glVertexAttribL1i64vNV)(GLuint,const INT64*);
+ void (WINE_GLAPI *p_glVertexAttribL1ui64NV)(GLuint,UINT64);
+ void (WINE_GLAPI *p_glVertexAttribL1ui64vNV)(GLuint,const UINT64*);
+ void (WINE_GLAPI *p_glVertexAttribL2d)(GLuint,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertexAttribL2dEXT)(GLuint,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertexAttribL2dv)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttribL2dvEXT)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttribL2i64NV)(GLuint,INT64,INT64);
+ void (WINE_GLAPI *p_glVertexAttribL2i64vNV)(GLuint,const INT64*);
+ void (WINE_GLAPI *p_glVertexAttribL2ui64NV)(GLuint,UINT64,UINT64);
+ void (WINE_GLAPI *p_glVertexAttribL2ui64vNV)(GLuint,const UINT64*);
+ void (WINE_GLAPI *p_glVertexAttribL3d)(GLuint,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertexAttribL3dEXT)(GLuint,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertexAttribL3dv)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttribL3dvEXT)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttribL3i64NV)(GLuint,INT64,INT64,INT64);
+ void (WINE_GLAPI *p_glVertexAttribL3i64vNV)(GLuint,const INT64*);
+ void (WINE_GLAPI *p_glVertexAttribL3ui64NV)(GLuint,UINT64,UINT64,UINT64);
+ void (WINE_GLAPI *p_glVertexAttribL3ui64vNV)(GLuint,const UINT64*);
+ void (WINE_GLAPI *p_glVertexAttribL4d)(GLuint,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertexAttribL4dEXT)(GLuint,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertexAttribL4dv)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttribL4dvEXT)(GLuint,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttribL4i64NV)(GLuint,INT64,INT64,INT64,INT64);
+ void (WINE_GLAPI *p_glVertexAttribL4i64vNV)(GLuint,const INT64*);
+ void (WINE_GLAPI *p_glVertexAttribL4ui64NV)(GLuint,UINT64,UINT64,UINT64,UINT64);
+ void (WINE_GLAPI *p_glVertexAttribL4ui64vNV)(GLuint,const UINT64*);
+ void (WINE_GLAPI *p_glVertexAttribLFormat)(GLuint,GLint,GLenum,GLuint);
+ void (WINE_GLAPI *p_glVertexAttribLFormatNV)(GLuint,GLint,GLenum,GLsizei);
+ void (WINE_GLAPI *p_glVertexAttribLPointer)(GLuint,GLint,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glVertexAttribLPointerEXT)(GLuint,GLint,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glVertexAttribP1ui)(GLuint,GLenum,GLboolean,GLuint);
+ void (WINE_GLAPI *p_glVertexAttribP1uiv)(GLuint,GLenum,GLboolean,const GLuint*);
+ void (WINE_GLAPI *p_glVertexAttribP2ui)(GLuint,GLenum,GLboolean,GLuint);
+ void (WINE_GLAPI *p_glVertexAttribP2uiv)(GLuint,GLenum,GLboolean,const GLuint*);
+ void (WINE_GLAPI *p_glVertexAttribP3ui)(GLuint,GLenum,GLboolean,GLuint);
+ void (WINE_GLAPI *p_glVertexAttribP3uiv)(GLuint,GLenum,GLboolean,const GLuint*);
+ void (WINE_GLAPI *p_glVertexAttribP4ui)(GLuint,GLenum,GLboolean,GLuint);
+ void (WINE_GLAPI *p_glVertexAttribP4uiv)(GLuint,GLenum,GLboolean,const GLuint*);
+ void (WINE_GLAPI *p_glVertexAttribPointer)(GLuint,GLint,GLenum,GLboolean,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glVertexAttribPointerARB)(GLuint,GLint,GLenum,GLboolean,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glVertexAttribPointerNV)(GLuint,GLint,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glVertexAttribs1dvNV)(GLuint,GLsizei,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttribs1fvNV)(GLuint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glVertexAttribs1hvNV)(GLuint,GLsizei,const GLhalfNV*);
+ void (WINE_GLAPI *p_glVertexAttribs1svNV)(GLuint,GLsizei,const GLshort*);
+ void (WINE_GLAPI *p_glVertexAttribs2dvNV)(GLuint,GLsizei,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttribs2fvNV)(GLuint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glVertexAttribs2hvNV)(GLuint,GLsizei,const GLhalfNV*);
+ void (WINE_GLAPI *p_glVertexAttribs2svNV)(GLuint,GLsizei,const GLshort*);
+ void (WINE_GLAPI *p_glVertexAttribs3dvNV)(GLuint,GLsizei,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttribs3fvNV)(GLuint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glVertexAttribs3hvNV)(GLuint,GLsizei,const GLhalfNV*);
+ void (WINE_GLAPI *p_glVertexAttribs3svNV)(GLuint,GLsizei,const GLshort*);
+ void (WINE_GLAPI *p_glVertexAttribs4dvNV)(GLuint,GLsizei,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexAttribs4fvNV)(GLuint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glVertexAttribs4hvNV)(GLuint,GLsizei,const GLhalfNV*);
+ void (WINE_GLAPI *p_glVertexAttribs4svNV)(GLuint,GLsizei,const GLshort*);
+ void (WINE_GLAPI *p_glVertexAttribs4ubvNV)(GLuint,GLsizei,const GLubyte*);
+ void (WINE_GLAPI *p_glVertexBindingDivisor)(GLuint,GLuint);
+ void (WINE_GLAPI *p_glVertexBlendARB)(GLint);
+ void (WINE_GLAPI *p_glVertexBlendEnvfATI)(GLenum,GLfloat);
+ void (WINE_GLAPI *p_glVertexBlendEnviATI)(GLenum,GLint);
+ void (WINE_GLAPI *p_glVertexFormatNV)(GLint,GLenum,GLsizei);
+ void (WINE_GLAPI *p_glVertexP2ui)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glVertexP2uiv)(GLenum,const GLuint*);
+ void (WINE_GLAPI *p_glVertexP3ui)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glVertexP3uiv)(GLenum,const GLuint*);
+ void (WINE_GLAPI *p_glVertexP4ui)(GLenum,GLuint);
+ void (WINE_GLAPI *p_glVertexP4uiv)(GLenum,const GLuint*);
+ void (WINE_GLAPI *p_glVertexPointerEXT)(GLint,GLenum,GLsizei,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glVertexPointerListIBM)(GLint,GLenum,GLint,const GLvoid**,GLint);
+ void (WINE_GLAPI *p_glVertexPointervINTEL)(GLint,GLenum,const GLvoid**);
+ void (WINE_GLAPI *p_glVertexStream1dATI)(GLenum,GLdouble);
+ void (WINE_GLAPI *p_glVertexStream1dvATI)(GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexStream1fATI)(GLenum,GLfloat);
+ void (WINE_GLAPI *p_glVertexStream1fvATI)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glVertexStream1iATI)(GLenum,GLint);
+ void (WINE_GLAPI *p_glVertexStream1ivATI)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glVertexStream1sATI)(GLenum,GLshort);
+ void (WINE_GLAPI *p_glVertexStream1svATI)(GLenum,const GLshort*);
+ void (WINE_GLAPI *p_glVertexStream2dATI)(GLenum,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertexStream2dvATI)(GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexStream2fATI)(GLenum,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glVertexStream2fvATI)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glVertexStream2iATI)(GLenum,GLint,GLint);
+ void (WINE_GLAPI *p_glVertexStream2ivATI)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glVertexStream2sATI)(GLenum,GLshort,GLshort);
+ void (WINE_GLAPI *p_glVertexStream2svATI)(GLenum,const GLshort*);
+ void (WINE_GLAPI *p_glVertexStream3dATI)(GLenum,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertexStream3dvATI)(GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexStream3fATI)(GLenum,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glVertexStream3fvATI)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glVertexStream3iATI)(GLenum,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glVertexStream3ivATI)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glVertexStream3sATI)(GLenum,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glVertexStream3svATI)(GLenum,const GLshort*);
+ void (WINE_GLAPI *p_glVertexStream4dATI)(GLenum,GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glVertexStream4dvATI)(GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glVertexStream4fATI)(GLenum,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glVertexStream4fvATI)(GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glVertexStream4iATI)(GLenum,GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glVertexStream4ivATI)(GLenum,const GLint*);
+ void (WINE_GLAPI *p_glVertexStream4sATI)(GLenum,GLshort,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glVertexStream4svATI)(GLenum,const GLshort*);
+ void (WINE_GLAPI *p_glVertexWeightPointerEXT)(GLint,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glVertexWeightfEXT)(GLfloat);
+ void (WINE_GLAPI *p_glVertexWeightfvEXT)(const GLfloat*);
+ void (WINE_GLAPI *p_glVertexWeighthNV)(GLhalfNV);
+ void (WINE_GLAPI *p_glVertexWeighthvNV)(const GLhalfNV*);
+ GLenum (WINE_GLAPI *p_glVideoCaptureNV)(GLuint,GLuint*,UINT64*);
+ void (WINE_GLAPI *p_glVideoCaptureStreamParameterdvNV)(GLuint,GLuint,GLenum,const GLdouble*);
+ void (WINE_GLAPI *p_glVideoCaptureStreamParameterfvNV)(GLuint,GLuint,GLenum,const GLfloat*);
+ void (WINE_GLAPI *p_glVideoCaptureStreamParameterivNV)(GLuint,GLuint,GLenum,const GLint*);
+ void (WINE_GLAPI *p_glViewportArrayv)(GLuint,GLsizei,const GLfloat*);
+ void (WINE_GLAPI *p_glViewportIndexedf)(GLuint,GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glViewportIndexedfv)(GLuint,const GLfloat*);
+ void (WINE_GLAPI *p_glWaitSync)(GLvoid*,GLbitfield,UINT64);
+ void (WINE_GLAPI *p_glWeightPathsNV)(GLuint,GLsizei,const GLuint*,const GLfloat*);
+ void (WINE_GLAPI *p_glWeightPointerARB)(GLint,GLenum,GLsizei,const GLvoid*);
+ void (WINE_GLAPI *p_glWeightbvARB)(GLint,const GLbyte*);
+ void (WINE_GLAPI *p_glWeightdvARB)(GLint,const GLdouble*);
+ void (WINE_GLAPI *p_glWeightfvARB)(GLint,const GLfloat*);
+ void (WINE_GLAPI *p_glWeightivARB)(GLint,const GLint*);
+ void (WINE_GLAPI *p_glWeightsvARB)(GLint,const GLshort*);
+ void (WINE_GLAPI *p_glWeightubvARB)(GLint,const GLubyte*);
+ void (WINE_GLAPI *p_glWeightuivARB)(GLint,const GLuint*);
+ void (WINE_GLAPI *p_glWeightusvARB)(GLint,const GLushort*);
+ void (WINE_GLAPI *p_glWindowPos2d)(GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glWindowPos2dARB)(GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glWindowPos2dMESA)(GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glWindowPos2dv)(const GLdouble*);
+ void (WINE_GLAPI *p_glWindowPos2dvARB)(const GLdouble*);
+ void (WINE_GLAPI *p_glWindowPos2dvMESA)(const GLdouble*);
+ void (WINE_GLAPI *p_glWindowPos2f)(GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glWindowPos2fARB)(GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glWindowPos2fMESA)(GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glWindowPos2fv)(const GLfloat*);
+ void (WINE_GLAPI *p_glWindowPos2fvARB)(const GLfloat*);
+ void (WINE_GLAPI *p_glWindowPos2fvMESA)(const GLfloat*);
+ void (WINE_GLAPI *p_glWindowPos2i)(GLint,GLint);
+ void (WINE_GLAPI *p_glWindowPos2iARB)(GLint,GLint);
+ void (WINE_GLAPI *p_glWindowPos2iMESA)(GLint,GLint);
+ void (WINE_GLAPI *p_glWindowPos2iv)(const GLint*);
+ void (WINE_GLAPI *p_glWindowPos2ivARB)(const GLint*);
+ void (WINE_GLAPI *p_glWindowPos2ivMESA)(const GLint*);
+ void (WINE_GLAPI *p_glWindowPos2s)(GLshort,GLshort);
+ void (WINE_GLAPI *p_glWindowPos2sARB)(GLshort,GLshort);
+ void (WINE_GLAPI *p_glWindowPos2sMESA)(GLshort,GLshort);
+ void (WINE_GLAPI *p_glWindowPos2sv)(const GLshort*);
+ void (WINE_GLAPI *p_glWindowPos2svARB)(const GLshort*);
+ void (WINE_GLAPI *p_glWindowPos2svMESA)(const GLshort*);
+ void (WINE_GLAPI *p_glWindowPos3d)(GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glWindowPos3dARB)(GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glWindowPos3dMESA)(GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glWindowPos3dv)(const GLdouble*);
+ void (WINE_GLAPI *p_glWindowPos3dvARB)(const GLdouble*);
+ void (WINE_GLAPI *p_glWindowPos3dvMESA)(const GLdouble*);
+ void (WINE_GLAPI *p_glWindowPos3f)(GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glWindowPos3fARB)(GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glWindowPos3fMESA)(GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glWindowPos3fv)(const GLfloat*);
+ void (WINE_GLAPI *p_glWindowPos3fvARB)(const GLfloat*);
+ void (WINE_GLAPI *p_glWindowPos3fvMESA)(const GLfloat*);
+ void (WINE_GLAPI *p_glWindowPos3i)(GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glWindowPos3iARB)(GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glWindowPos3iMESA)(GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glWindowPos3iv)(const GLint*);
+ void (WINE_GLAPI *p_glWindowPos3ivARB)(const GLint*);
+ void (WINE_GLAPI *p_glWindowPos3ivMESA)(const GLint*);
+ void (WINE_GLAPI *p_glWindowPos3s)(GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glWindowPos3sARB)(GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glWindowPos3sMESA)(GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glWindowPos3sv)(const GLshort*);
+ void (WINE_GLAPI *p_glWindowPos3svARB)(const GLshort*);
+ void (WINE_GLAPI *p_glWindowPos3svMESA)(const GLshort*);
+ void (WINE_GLAPI *p_glWindowPos4dMESA)(GLdouble,GLdouble,GLdouble,GLdouble);
+ void (WINE_GLAPI *p_glWindowPos4dvMESA)(const GLdouble*);
+ void (WINE_GLAPI *p_glWindowPos4fMESA)(GLfloat,GLfloat,GLfloat,GLfloat);
+ void (WINE_GLAPI *p_glWindowPos4fvMESA)(const GLfloat*);
+ void (WINE_GLAPI *p_glWindowPos4iMESA)(GLint,GLint,GLint,GLint);
+ void (WINE_GLAPI *p_glWindowPos4ivMESA)(const GLint*);
+ void (WINE_GLAPI *p_glWindowPos4sMESA)(GLshort,GLshort,GLshort,GLshort);
+ void (WINE_GLAPI *p_glWindowPos4svMESA)(const GLshort*);
+ void (WINE_GLAPI *p_glWriteMaskEXT)(GLuint,GLuint,GLenum,GLenum,GLenum,GLenum);
+ GLvoid* (WINE_GLAPI *p_wglAllocateMemoryNV)(GLsizei,GLfloat,GLfloat,GLfloat);
+ BOOL (WINE_GLAPI *p_wglBindTexImageARB)(struct wgl_pbuffer *,int);
+ BOOL (WINE_GLAPI *p_wglChoosePixelFormatARB)(HDC,const int*,const FLOAT*,UINT,int*,UINT*);
+ struct wgl_context * (WINE_GLAPI *p_wglCreateContextAttribsARB)(HDC,struct wgl_context *,const int*);
+ struct wgl_pbuffer * (WINE_GLAPI *p_wglCreatePbufferARB)(HDC,int,int,int,const int*);
+ BOOL (WINE_GLAPI *p_wglDestroyPbufferARB)(struct wgl_pbuffer *);
+ void (WINE_GLAPI *p_wglFreeMemoryNV)(void*);
+ HDC (WINE_GLAPI *p_wglGetCurrentReadDCARB)(void);
+ const GLubyte * (WINE_GLAPI *p_wglGetExtensionsStringARB)(HDC);
+ const GLubyte * (WINE_GLAPI *p_wglGetExtensionsStringEXT)(void);
+ HDC (WINE_GLAPI *p_wglGetPbufferDCARB)(struct wgl_pbuffer *);
+ BOOL (WINE_GLAPI *p_wglGetPixelFormatAttribfvARB)(HDC,int,int,UINT,const int*,FLOAT*);
+ BOOL (WINE_GLAPI *p_wglGetPixelFormatAttribivARB)(HDC,int,int,UINT,const int*,int*);
+ int (WINE_GLAPI *p_wglGetSwapIntervalEXT)(void);
+ BOOL (WINE_GLAPI *p_wglMakeContextCurrentARB)(HDC,HDC,struct wgl_context *);
+ BOOL (WINE_GLAPI *p_wglQueryPbufferARB)(struct wgl_pbuffer *,int,int*);
+ int (WINE_GLAPI *p_wglReleasePbufferDCARB)(struct wgl_pbuffer *,HDC);
+ BOOL (WINE_GLAPI *p_wglReleaseTexImageARB)(struct wgl_pbuffer *,int);
+ BOOL (WINE_GLAPI *p_wglSetPbufferAttribARB)(struct wgl_pbuffer *,const int*);
+ BOOL (WINE_GLAPI *p_wglSetPixelFormatWINE)(HDC,int);
+ BOOL (WINE_GLAPI *p_wglSwapIntervalEXT)(int);
+ } ext;
+};
+
+#define ALL_WGL_FUNCS \
+ USE_GL_FUNC(glAccum) \
+ USE_GL_FUNC(glAlphaFunc) \
+ USE_GL_FUNC(glAreTexturesResident) \
+ USE_GL_FUNC(glArrayElement) \
+ USE_GL_FUNC(glBegin) \
+ USE_GL_FUNC(glBindTexture) \
+ USE_GL_FUNC(glBitmap) \
+ USE_GL_FUNC(glBlendFunc) \
+ USE_GL_FUNC(glCallList) \
+ USE_GL_FUNC(glCallLists) \
+ USE_GL_FUNC(glClear) \
+ USE_GL_FUNC(glClearAccum) \
+ USE_GL_FUNC(glClearColor) \
+ USE_GL_FUNC(glClearDepth) \
+ USE_GL_FUNC(glClearIndex) \
+ USE_GL_FUNC(glClearStencil) \
+ USE_GL_FUNC(glClipPlane) \
+ USE_GL_FUNC(glColor3b) \
+ USE_GL_FUNC(glColor3bv) \
+ USE_GL_FUNC(glColor3d) \
+ USE_GL_FUNC(glColor3dv) \
+ USE_GL_FUNC(glColor3f) \
+ USE_GL_FUNC(glColor3fv) \
+ USE_GL_FUNC(glColor3i) \
+ USE_GL_FUNC(glColor3iv) \
+ USE_GL_FUNC(glColor3s) \
+ USE_GL_FUNC(glColor3sv) \
+ USE_GL_FUNC(glColor3ub) \
+ USE_GL_FUNC(glColor3ubv) \
+ USE_GL_FUNC(glColor3ui) \
+ USE_GL_FUNC(glColor3uiv) \
+ USE_GL_FUNC(glColor3us) \
+ USE_GL_FUNC(glColor3usv) \
+ USE_GL_FUNC(glColor4b) \
+ USE_GL_FUNC(glColor4bv) \
+ USE_GL_FUNC(glColor4d) \
+ USE_GL_FUNC(glColor4dv) \
+ USE_GL_FUNC(glColor4f) \
+ USE_GL_FUNC(glColor4fv) \
+ USE_GL_FUNC(glColor4i) \
+ USE_GL_FUNC(glColor4iv) \
+ USE_GL_FUNC(glColor4s) \
+ USE_GL_FUNC(glColor4sv) \
+ USE_GL_FUNC(glColor4ub) \
+ USE_GL_FUNC(glColor4ubv) \
+ USE_GL_FUNC(glColor4ui) \
+ USE_GL_FUNC(glColor4uiv) \
+ USE_GL_FUNC(glColor4us) \
+ USE_GL_FUNC(glColor4usv) \
+ USE_GL_FUNC(glColorMask) \
+ USE_GL_FUNC(glColorMaterial) \
+ USE_GL_FUNC(glColorPointer) \
+ USE_GL_FUNC(glCopyPixels) \
+ USE_GL_FUNC(glCopyTexImage1D) \
+ USE_GL_FUNC(glCopyTexImage2D) \
+ USE_GL_FUNC(glCopyTexSubImage1D) \
+ USE_GL_FUNC(glCopyTexSubImage2D) \
+ USE_GL_FUNC(glCullFace) \
+ USE_GL_FUNC(glDeleteLists) \
+ USE_GL_FUNC(glDeleteTextures) \
+ USE_GL_FUNC(glDepthFunc) \
+ USE_GL_FUNC(glDepthMask) \
+ USE_GL_FUNC(glDepthRange) \
+ USE_GL_FUNC(glDisable) \
+ USE_GL_FUNC(glDisableClientState) \
+ USE_GL_FUNC(glDrawArrays) \
+ USE_GL_FUNC(glDrawBuffer) \
+ USE_GL_FUNC(glDrawElements) \
+ USE_GL_FUNC(glDrawPixels) \
+ USE_GL_FUNC(glEdgeFlag) \
+ USE_GL_FUNC(glEdgeFlagPointer) \
+ USE_GL_FUNC(glEdgeFlagv) \
+ USE_GL_FUNC(glEnable) \
+ USE_GL_FUNC(glEnableClientState) \
+ USE_GL_FUNC(glEnd) \
+ USE_GL_FUNC(glEndList) \
+ USE_GL_FUNC(glEvalCoord1d) \
+ USE_GL_FUNC(glEvalCoord1dv) \
+ USE_GL_FUNC(glEvalCoord1f) \
+ USE_GL_FUNC(glEvalCoord1fv) \
+ USE_GL_FUNC(glEvalCoord2d) \
+ USE_GL_FUNC(glEvalCoord2dv) \
+ USE_GL_FUNC(glEvalCoord2f) \
+ USE_GL_FUNC(glEvalCoord2fv) \
+ USE_GL_FUNC(glEvalMesh1) \
+ USE_GL_FUNC(glEvalMesh2) \
+ USE_GL_FUNC(glEvalPoint1) \
+ USE_GL_FUNC(glEvalPoint2) \
+ USE_GL_FUNC(glFeedbackBuffer) \
+ USE_GL_FUNC(glFinish) \
+ USE_GL_FUNC(glFlush) \
+ USE_GL_FUNC(glFogf) \
+ USE_GL_FUNC(glFogfv) \
+ USE_GL_FUNC(glFogi) \
+ USE_GL_FUNC(glFogiv) \
+ USE_GL_FUNC(glFrontFace) \
+ USE_GL_FUNC(glFrustum) \
+ USE_GL_FUNC(glGenLists) \
+ USE_GL_FUNC(glGenTextures) \
+ USE_GL_FUNC(glGetBooleanv) \
+ USE_GL_FUNC(glGetClipPlane) \
+ USE_GL_FUNC(glGetDoublev) \
+ USE_GL_FUNC(glGetError) \
+ USE_GL_FUNC(glGetFloatv) \
+ USE_GL_FUNC(glGetIntegerv) \
+ USE_GL_FUNC(glGetLightfv) \
+ USE_GL_FUNC(glGetLightiv) \
+ USE_GL_FUNC(glGetMapdv) \
+ USE_GL_FUNC(glGetMapfv) \
+ USE_GL_FUNC(glGetMapiv) \
+ USE_GL_FUNC(glGetMaterialfv) \
+ USE_GL_FUNC(glGetMaterialiv) \
+ USE_GL_FUNC(glGetPixelMapfv) \
+ USE_GL_FUNC(glGetPixelMapuiv) \
+ USE_GL_FUNC(glGetPixelMapusv) \
+ USE_GL_FUNC(glGetPointerv) \
+ USE_GL_FUNC(glGetPolygonStipple) \
+ USE_GL_FUNC(glGetString) \
+ USE_GL_FUNC(glGetTexEnvfv) \
+ USE_GL_FUNC(glGetTexEnviv) \
+ USE_GL_FUNC(glGetTexGendv) \
+ USE_GL_FUNC(glGetTexGenfv) \
+ USE_GL_FUNC(glGetTexGeniv) \
+ USE_GL_FUNC(glGetTexImage) \
+ USE_GL_FUNC(glGetTexLevelParameterfv) \
+ USE_GL_FUNC(glGetTexLevelParameteriv) \
+ USE_GL_FUNC(glGetTexParameterfv) \
+ USE_GL_FUNC(glGetTexParameteriv) \
+ USE_GL_FUNC(glHint) \
+ USE_GL_FUNC(glIndexMask) \
+ USE_GL_FUNC(glIndexPointer) \
+ USE_GL_FUNC(glIndexd) \
+ USE_GL_FUNC(glIndexdv) \
+ USE_GL_FUNC(glIndexf) \
+ USE_GL_FUNC(glIndexfv) \
+ USE_GL_FUNC(glIndexi) \
+ USE_GL_FUNC(glIndexiv) \
+ USE_GL_FUNC(glIndexs) \
+ USE_GL_FUNC(glIndexsv) \
+ USE_GL_FUNC(glIndexub) \
+ USE_GL_FUNC(glIndexubv) \
+ USE_GL_FUNC(glInitNames) \
+ USE_GL_FUNC(glInterleavedArrays) \
+ USE_GL_FUNC(glIsEnabled) \
+ USE_GL_FUNC(glIsList) \
+ USE_GL_FUNC(glIsTexture) \
+ USE_GL_FUNC(glLightModelf) \
+ USE_GL_FUNC(glLightModelfv) \
+ USE_GL_FUNC(glLightModeli) \
+ USE_GL_FUNC(glLightModeliv) \
+ USE_GL_FUNC(glLightf) \
+ USE_GL_FUNC(glLightfv) \
+ USE_GL_FUNC(glLighti) \
+ USE_GL_FUNC(glLightiv) \
+ USE_GL_FUNC(glLineStipple) \
+ USE_GL_FUNC(glLineWidth) \
+ USE_GL_FUNC(glListBase) \
+ USE_GL_FUNC(glLoadIdentity) \
+ USE_GL_FUNC(glLoadMatrixd) \
+ USE_GL_FUNC(glLoadMatrixf) \
+ USE_GL_FUNC(glLoadName) \
+ USE_GL_FUNC(glLogicOp) \
+ USE_GL_FUNC(glMap1d) \
+ USE_GL_FUNC(glMap1f) \
+ USE_GL_FUNC(glMap2d) \
+ USE_GL_FUNC(glMap2f) \
+ USE_GL_FUNC(glMapGrid1d) \
+ USE_GL_FUNC(glMapGrid1f) \
+ USE_GL_FUNC(glMapGrid2d) \
+ USE_GL_FUNC(glMapGrid2f) \
+ USE_GL_FUNC(glMaterialf) \
+ USE_GL_FUNC(glMaterialfv) \
+ USE_GL_FUNC(glMateriali) \
+ USE_GL_FUNC(glMaterialiv) \
+ USE_GL_FUNC(glMatrixMode) \
+ USE_GL_FUNC(glMultMatrixd) \
+ USE_GL_FUNC(glMultMatrixf) \
+ USE_GL_FUNC(glNewList) \
+ USE_GL_FUNC(glNormal3b) \
+ USE_GL_FUNC(glNormal3bv) \
+ USE_GL_FUNC(glNormal3d) \
+ USE_GL_FUNC(glNormal3dv) \
+ USE_GL_FUNC(glNormal3f) \
+ USE_GL_FUNC(glNormal3fv) \
+ USE_GL_FUNC(glNormal3i) \
+ USE_GL_FUNC(glNormal3iv) \
+ USE_GL_FUNC(glNormal3s) \
+ USE_GL_FUNC(glNormal3sv) \
+ USE_GL_FUNC(glNormalPointer) \
+ USE_GL_FUNC(glOrtho) \
+ USE_GL_FUNC(glPassThrough) \
+ USE_GL_FUNC(glPixelMapfv) \
+ USE_GL_FUNC(glPixelMapuiv) \
+ USE_GL_FUNC(glPixelMapusv) \
+ USE_GL_FUNC(glPixelStoref) \
+ USE_GL_FUNC(glPixelStorei) \
+ USE_GL_FUNC(glPixelTransferf) \
+ USE_GL_FUNC(glPixelTransferi) \
+ USE_GL_FUNC(glPixelZoom) \
+ USE_GL_FUNC(glPointSize) \
+ USE_GL_FUNC(glPolygonMode) \
+ USE_GL_FUNC(glPolygonOffset) \
+ USE_GL_FUNC(glPolygonStipple) \
+ USE_GL_FUNC(glPopAttrib) \
+ USE_GL_FUNC(glPopClientAttrib) \
+ USE_GL_FUNC(glPopMatrix) \
+ USE_GL_FUNC(glPopName) \
+ USE_GL_FUNC(glPrioritizeTextures) \
+ USE_GL_FUNC(glPushAttrib) \
+ USE_GL_FUNC(glPushClientAttrib) \
+ USE_GL_FUNC(glPushMatrix) \
+ USE_GL_FUNC(glPushName) \
+ USE_GL_FUNC(glRasterPos2d) \
+ USE_GL_FUNC(glRasterPos2dv) \
+ USE_GL_FUNC(glRasterPos2f) \
+ USE_GL_FUNC(glRasterPos2fv) \
+ USE_GL_FUNC(glRasterPos2i) \
+ USE_GL_FUNC(glRasterPos2iv) \
+ USE_GL_FUNC(glRasterPos2s) \
+ USE_GL_FUNC(glRasterPos2sv) \
+ USE_GL_FUNC(glRasterPos3d) \
+ USE_GL_FUNC(glRasterPos3dv) \
+ USE_GL_FUNC(glRasterPos3f) \
+ USE_GL_FUNC(glRasterPos3fv) \
+ USE_GL_FUNC(glRasterPos3i) \
+ USE_GL_FUNC(glRasterPos3iv) \
+ USE_GL_FUNC(glRasterPos3s) \
+ USE_GL_FUNC(glRasterPos3sv) \
+ USE_GL_FUNC(glRasterPos4d) \
+ USE_GL_FUNC(glRasterPos4dv) \
+ USE_GL_FUNC(glRasterPos4f) \
+ USE_GL_FUNC(glRasterPos4fv) \
+ USE_GL_FUNC(glRasterPos4i) \
+ USE_GL_FUNC(glRasterPos4iv) \
+ USE_GL_FUNC(glRasterPos4s) \
+ USE_GL_FUNC(glRasterPos4sv) \
+ USE_GL_FUNC(glReadBuffer) \
+ USE_GL_FUNC(glReadPixels) \
+ USE_GL_FUNC(glRectd) \
+ USE_GL_FUNC(glRectdv) \
+ USE_GL_FUNC(glRectf) \
+ USE_GL_FUNC(glRectfv) \
+ USE_GL_FUNC(glRecti) \
+ USE_GL_FUNC(glRectiv) \
+ USE_GL_FUNC(glRects) \
+ USE_GL_FUNC(glRectsv) \
+ USE_GL_FUNC(glRenderMode) \
+ USE_GL_FUNC(glRotated) \
+ USE_GL_FUNC(glRotatef) \
+ USE_GL_FUNC(glScaled) \
+ USE_GL_FUNC(glScalef) \
+ USE_GL_FUNC(glScissor) \
+ USE_GL_FUNC(glSelectBuffer) \
+ USE_GL_FUNC(glShadeModel) \
+ USE_GL_FUNC(glStencilFunc) \
+ USE_GL_FUNC(glStencilMask) \
+ USE_GL_FUNC(glStencilOp) \
+ USE_GL_FUNC(glTexCoord1d) \
+ USE_GL_FUNC(glTexCoord1dv) \
+ USE_GL_FUNC(glTexCoord1f) \
+ USE_GL_FUNC(glTexCoord1fv) \
+ USE_GL_FUNC(glTexCoord1i) \
+ USE_GL_FUNC(glTexCoord1iv) \
+ USE_GL_FUNC(glTexCoord1s) \
+ USE_GL_FUNC(glTexCoord1sv) \
+ USE_GL_FUNC(glTexCoord2d) \
+ USE_GL_FUNC(glTexCoord2dv) \
+ USE_GL_FUNC(glTexCoord2f) \
+ USE_GL_FUNC(glTexCoord2fv) \
+ USE_GL_FUNC(glTexCoord2i) \
+ USE_GL_FUNC(glTexCoord2iv) \
+ USE_GL_FUNC(glTexCoord2s) \
+ USE_GL_FUNC(glTexCoord2sv) \
+ USE_GL_FUNC(glTexCoord3d) \
+ USE_GL_FUNC(glTexCoord3dv) \
+ USE_GL_FUNC(glTexCoord3f) \
+ USE_GL_FUNC(glTexCoord3fv) \
+ USE_GL_FUNC(glTexCoord3i) \
+ USE_GL_FUNC(glTexCoord3iv) \
+ USE_GL_FUNC(glTexCoord3s) \
+ USE_GL_FUNC(glTexCoord3sv) \
+ USE_GL_FUNC(glTexCoord4d) \
+ USE_GL_FUNC(glTexCoord4dv) \
+ USE_GL_FUNC(glTexCoord4f) \
+ USE_GL_FUNC(glTexCoord4fv) \
+ USE_GL_FUNC(glTexCoord4i) \
+ USE_GL_FUNC(glTexCoord4iv) \
+ USE_GL_FUNC(glTexCoord4s) \
+ USE_GL_FUNC(glTexCoord4sv) \
+ USE_GL_FUNC(glTexCoordPointer) \
+ USE_GL_FUNC(glTexEnvf) \
+ USE_GL_FUNC(glTexEnvfv) \
+ USE_GL_FUNC(glTexEnvi) \
+ USE_GL_FUNC(glTexEnviv) \
+ USE_GL_FUNC(glTexGend) \
+ USE_GL_FUNC(glTexGendv) \
+ USE_GL_FUNC(glTexGenf) \
+ USE_GL_FUNC(glTexGenfv) \
+ USE_GL_FUNC(glTexGeni) \
+ USE_GL_FUNC(glTexGeniv) \
+ USE_GL_FUNC(glTexImage1D) \
+ USE_GL_FUNC(glTexImage2D) \
+ USE_GL_FUNC(glTexParameterf) \
+ USE_GL_FUNC(glTexParameterfv) \
+ USE_GL_FUNC(glTexParameteri) \
+ USE_GL_FUNC(glTexParameteriv) \
+ USE_GL_FUNC(glTexSubImage1D) \
+ USE_GL_FUNC(glTexSubImage2D) \
+ USE_GL_FUNC(glTranslated) \
+ USE_GL_FUNC(glTranslatef) \
+ USE_GL_FUNC(glVertex2d) \
+ USE_GL_FUNC(glVertex2dv) \
+ USE_GL_FUNC(glVertex2f) \
+ USE_GL_FUNC(glVertex2fv) \
+ USE_GL_FUNC(glVertex2i) \
+ USE_GL_FUNC(glVertex2iv) \
+ USE_GL_FUNC(glVertex2s) \
+ USE_GL_FUNC(glVertex2sv) \
+ USE_GL_FUNC(glVertex3d) \
+ USE_GL_FUNC(glVertex3dv) \
+ USE_GL_FUNC(glVertex3f) \
+ USE_GL_FUNC(glVertex3fv) \
+ USE_GL_FUNC(glVertex3i) \
+ USE_GL_FUNC(glVertex3iv) \
+ USE_GL_FUNC(glVertex3s) \
+ USE_GL_FUNC(glVertex3sv) \
+ USE_GL_FUNC(glVertex4d) \
+ USE_GL_FUNC(glVertex4dv) \
+ USE_GL_FUNC(glVertex4f) \
+ USE_GL_FUNC(glVertex4fv) \
+ USE_GL_FUNC(glVertex4i) \
+ USE_GL_FUNC(glVertex4iv) \
+ USE_GL_FUNC(glVertex4s) \
+ USE_GL_FUNC(glVertex4sv) \
+ USE_GL_FUNC(glVertexPointer) \
+ USE_GL_FUNC(glViewport)
+
+extern struct opengl_funcs * CDECL __wine_get_wgl_driver( HDC hdc, UINT version );
+extern BOOL CDECL __wine_set_pixel_format( HWND hwnd, int format );
+
+#endif /* __WINE_WGL_DRIVER_H */
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/wglext.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/wglext.h
new file mode 100644
index 00000000..76c42c19
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/wglext.h
@@ -0,0 +1,943 @@
+#ifndef __wglext_h_
+#define __wglext_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2007-2012 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Function declaration macros - to move into glplatform.h */
+
+#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+#endif
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+#ifndef APIENTRYP
+#define APIENTRYP APIENTRY *
+#endif
+#ifndef GLAPI
+#define GLAPI extern
+#endif
+
+/*************************************************************/
+
+/* Header file version number */
+/* wglext.h last updated 2012/01/04 */
+/* Current version at http://www.opengl.org/registry/ */
+#define WGL_WGLEXT_VERSION 24
+
+#ifndef WGL_ARB_buffer_region
+#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
+#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002
+#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004
+#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008
+#endif
+
+#ifndef WGL_ARB_multisample
+#define WGL_SAMPLE_BUFFERS_ARB 0x2041
+#define WGL_SAMPLES_ARB 0x2042
+#endif
+
+#ifndef WGL_ARB_extensions_string
+#endif
+
+#ifndef WGL_ARB_pixel_format
+#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
+#define WGL_DRAW_TO_WINDOW_ARB 0x2001
+#define WGL_DRAW_TO_BITMAP_ARB 0x2002
+#define WGL_ACCELERATION_ARB 0x2003
+#define WGL_NEED_PALETTE_ARB 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
+#define WGL_SWAP_METHOD_ARB 0x2007
+#define WGL_NUMBER_OVERLAYS_ARB 0x2008
+#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
+#define WGL_TRANSPARENT_ARB 0x200A
+#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
+#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
+#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
+#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
+#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
+#define WGL_SHARE_DEPTH_ARB 0x200C
+#define WGL_SHARE_STENCIL_ARB 0x200D
+#define WGL_SHARE_ACCUM_ARB 0x200E
+#define WGL_SUPPORT_GDI_ARB 0x200F
+#define WGL_SUPPORT_OPENGL_ARB 0x2010
+#define WGL_DOUBLE_BUFFER_ARB 0x2011
+#define WGL_STEREO_ARB 0x2012
+#define WGL_PIXEL_TYPE_ARB 0x2013
+#define WGL_COLOR_BITS_ARB 0x2014
+#define WGL_RED_BITS_ARB 0x2015
+#define WGL_RED_SHIFT_ARB 0x2016
+#define WGL_GREEN_BITS_ARB 0x2017
+#define WGL_GREEN_SHIFT_ARB 0x2018
+#define WGL_BLUE_BITS_ARB 0x2019
+#define WGL_BLUE_SHIFT_ARB 0x201A
+#define WGL_ALPHA_BITS_ARB 0x201B
+#define WGL_ALPHA_SHIFT_ARB 0x201C
+#define WGL_ACCUM_BITS_ARB 0x201D
+#define WGL_ACCUM_RED_BITS_ARB 0x201E
+#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
+#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
+#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
+#define WGL_DEPTH_BITS_ARB 0x2022
+#define WGL_STENCIL_BITS_ARB 0x2023
+#define WGL_AUX_BUFFERS_ARB 0x2024
+#define WGL_NO_ACCELERATION_ARB 0x2025
+#define WGL_GENERIC_ACCELERATION_ARB 0x2026
+#define WGL_FULL_ACCELERATION_ARB 0x2027
+#define WGL_SWAP_EXCHANGE_ARB 0x2028
+#define WGL_SWAP_COPY_ARB 0x2029
+#define WGL_SWAP_UNDEFINED_ARB 0x202A
+#define WGL_TYPE_RGBA_ARB 0x202B
+#define WGL_TYPE_COLORINDEX_ARB 0x202C
+#endif
+
+#ifndef WGL_ARB_make_current_read
+#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043
+#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
+#endif
+
+#ifndef WGL_ARB_pbuffer
+#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
+#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
+#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
+#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
+#define WGL_PBUFFER_LARGEST_ARB 0x2033
+#define WGL_PBUFFER_WIDTH_ARB 0x2034
+#define WGL_PBUFFER_HEIGHT_ARB 0x2035
+#define WGL_PBUFFER_LOST_ARB 0x2036
+#endif
+
+#ifndef WGL_ARB_render_texture
+#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
+#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
+#define WGL_TEXTURE_FORMAT_ARB 0x2072
+#define WGL_TEXTURE_TARGET_ARB 0x2073
+#define WGL_MIPMAP_TEXTURE_ARB 0x2074
+#define WGL_TEXTURE_RGB_ARB 0x2075
+#define WGL_TEXTURE_RGBA_ARB 0x2076
+#define WGL_NO_TEXTURE_ARB 0x2077
+#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078
+#define WGL_TEXTURE_1D_ARB 0x2079
+#define WGL_TEXTURE_2D_ARB 0x207A
+#define WGL_MIPMAP_LEVEL_ARB 0x207B
+#define WGL_CUBE_MAP_FACE_ARB 0x207C
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
+#define WGL_FRONT_LEFT_ARB 0x2083
+#define WGL_FRONT_RIGHT_ARB 0x2084
+#define WGL_BACK_LEFT_ARB 0x2085
+#define WGL_BACK_RIGHT_ARB 0x2086
+#define WGL_AUX0_ARB 0x2087
+#define WGL_AUX1_ARB 0x2088
+#define WGL_AUX2_ARB 0x2089
+#define WGL_AUX3_ARB 0x208A
+#define WGL_AUX4_ARB 0x208B
+#define WGL_AUX5_ARB 0x208C
+#define WGL_AUX6_ARB 0x208D
+#define WGL_AUX7_ARB 0x208E
+#define WGL_AUX8_ARB 0x208F
+#define WGL_AUX9_ARB 0x2090
+#endif
+
+#ifndef WGL_ARB_pixel_format_float
+#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0
+#endif
+
+#ifndef WGL_ARB_framebuffer_sRGB
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
+#endif
+
+#ifndef WGL_ARB_create_context
+#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
+#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
+#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
+#define WGL_CONTEXT_FLAGS_ARB 0x2094
+#define ERROR_INVALID_VERSION_ARB 0x2095
+#endif
+
+#ifndef WGL_ARB_create_context_profile
+#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define ERROR_INVALID_PROFILE_ARB 0x2096
+#endif
+
+#ifndef WGL_ARB_create_context_robustness
+#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
+#endif
+
+#ifndef WGL_EXT_make_current_read
+#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043
+#endif
+
+#ifndef WGL_EXT_pixel_format
+#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000
+#define WGL_DRAW_TO_WINDOW_EXT 0x2001
+#define WGL_DRAW_TO_BITMAP_EXT 0x2002
+#define WGL_ACCELERATION_EXT 0x2003
+#define WGL_NEED_PALETTE_EXT 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006
+#define WGL_SWAP_METHOD_EXT 0x2007
+#define WGL_NUMBER_OVERLAYS_EXT 0x2008
+#define WGL_NUMBER_UNDERLAYS_EXT 0x2009
+#define WGL_TRANSPARENT_EXT 0x200A
+#define WGL_TRANSPARENT_VALUE_EXT 0x200B
+#define WGL_SHARE_DEPTH_EXT 0x200C
+#define WGL_SHARE_STENCIL_EXT 0x200D
+#define WGL_SHARE_ACCUM_EXT 0x200E
+#define WGL_SUPPORT_GDI_EXT 0x200F
+#define WGL_SUPPORT_OPENGL_EXT 0x2010
+#define WGL_DOUBLE_BUFFER_EXT 0x2011
+#define WGL_STEREO_EXT 0x2012
+#define WGL_PIXEL_TYPE_EXT 0x2013
+#define WGL_COLOR_BITS_EXT 0x2014
+#define WGL_RED_BITS_EXT 0x2015
+#define WGL_RED_SHIFT_EXT 0x2016
+#define WGL_GREEN_BITS_EXT 0x2017
+#define WGL_GREEN_SHIFT_EXT 0x2018
+#define WGL_BLUE_BITS_EXT 0x2019
+#define WGL_BLUE_SHIFT_EXT 0x201A
+#define WGL_ALPHA_BITS_EXT 0x201B
+#define WGL_ALPHA_SHIFT_EXT 0x201C
+#define WGL_ACCUM_BITS_EXT 0x201D
+#define WGL_ACCUM_RED_BITS_EXT 0x201E
+#define WGL_ACCUM_GREEN_BITS_EXT 0x201F
+#define WGL_ACCUM_BLUE_BITS_EXT 0x2020
+#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021
+#define WGL_DEPTH_BITS_EXT 0x2022
+#define WGL_STENCIL_BITS_EXT 0x2023
+#define WGL_AUX_BUFFERS_EXT 0x2024
+#define WGL_NO_ACCELERATION_EXT 0x2025
+#define WGL_GENERIC_ACCELERATION_EXT 0x2026
+#define WGL_FULL_ACCELERATION_EXT 0x2027
+#define WGL_SWAP_EXCHANGE_EXT 0x2028
+#define WGL_SWAP_COPY_EXT 0x2029
+#define WGL_SWAP_UNDEFINED_EXT 0x202A
+#define WGL_TYPE_RGBA_EXT 0x202B
+#define WGL_TYPE_COLORINDEX_EXT 0x202C
+#endif
+
+#ifndef WGL_EXT_pbuffer
+#define WGL_DRAW_TO_PBUFFER_EXT 0x202D
+#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E
+#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F
+#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030
+#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031
+#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032
+#define WGL_PBUFFER_LARGEST_EXT 0x2033
+#define WGL_PBUFFER_WIDTH_EXT 0x2034
+#define WGL_PBUFFER_HEIGHT_EXT 0x2035
+#endif
+
+#ifndef WGL_EXT_depth_float
+#define WGL_DEPTH_FLOAT_EXT 0x2040
+#endif
+
+#ifndef WGL_3DFX_multisample
+#define WGL_SAMPLE_BUFFERS_3DFX 0x2060
+#define WGL_SAMPLES_3DFX 0x2061
+#endif
+
+#ifndef WGL_EXT_multisample
+#define WGL_SAMPLE_BUFFERS_EXT 0x2041
+#define WGL_SAMPLES_EXT 0x2042
+#endif
+
+#ifndef WGL_I3D_digital_video_control
+#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050
+#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051
+#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052
+#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053
+#endif
+
+#ifndef WGL_I3D_gamma
+#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E
+#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F
+#endif
+
+#ifndef WGL_I3D_genlock
+#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044
+#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045
+#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046
+#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047
+#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048
+#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049
+#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A
+#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B
+#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C
+#endif
+
+#ifndef WGL_I3D_image_buffer
+#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001
+#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002
+#endif
+
+#ifndef WGL_I3D_swap_frame_lock
+#endif
+
+#ifndef WGL_NV_render_depth_texture
+#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4
+#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5
+#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6
+#define WGL_DEPTH_COMPONENT_NV 0x20A7
+#endif
+
+#ifndef WGL_NV_render_texture_rectangle
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1
+#define WGL_TEXTURE_RECTANGLE_NV 0x20A2
+#endif
+
+#ifndef WGL_ATI_pixel_format_float
+#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0
+#endif
+
+#ifndef WGL_NV_float_buffer
+#define WGL_FLOAT_COMPONENTS_NV 0x20B0
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4
+#define WGL_TEXTURE_FLOAT_R_NV 0x20B5
+#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6
+#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7
+#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8
+#endif
+
+#ifndef WGL_3DL_stereo_control
+#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055
+#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056
+#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057
+#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058
+#endif
+
+#ifndef WGL_EXT_pixel_format_packed_float
+#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8
+#endif
+
+#ifndef WGL_EXT_framebuffer_sRGB
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9
+#endif
+
+#ifndef WGL_NV_present_video
+#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0
+#endif
+
+#ifndef WGL_NV_video_out
+#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0
+#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1
+#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2
+#define WGL_VIDEO_OUT_COLOR_NV 0x20C3
+#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4
+#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5
+#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
+#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
+#define WGL_VIDEO_OUT_FRAME 0x20C8
+#define WGL_VIDEO_OUT_FIELD_1 0x20C9
+#define WGL_VIDEO_OUT_FIELD_2 0x20CA
+#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB
+#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC
+#endif
+
+#ifndef WGL_NV_swap_group
+#endif
+
+#ifndef WGL_NV_gpu_affinity
+#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0
+#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1
+#endif
+
+#ifndef WGL_AMD_gpu_association
+#define WGL_GPU_VENDOR_AMD 0x1F00
+#define WGL_GPU_RENDERER_STRING_AMD 0x1F01
+#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
+#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
+#define WGL_GPU_RAM_AMD 0x21A3
+#define WGL_GPU_CLOCK_AMD 0x21A4
+#define WGL_GPU_NUM_PIPES_AMD 0x21A5
+#define WGL_GPU_NUM_SIMD_AMD 0x21A6
+#define WGL_GPU_NUM_RB_AMD 0x21A7
+#define WGL_GPU_NUM_SPI_AMD 0x21A8
+#endif
+
+#ifndef WGL_NV_video_capture
+#define WGL_UNIQUE_ID_NV 0x20CE
+#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF
+#endif
+
+#ifndef WGL_NV_copy_image
+#endif
+
+#ifndef WGL_NV_multisample_coverage
+#define WGL_COVERAGE_SAMPLES_NV 0x2042
+#define WGL_COLOR_SAMPLES_NV 0x20B9
+#endif
+
+#ifndef WGL_EXT_create_context_es2_profile
+#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
+#endif
+
+#ifndef WGL_NV_DX_interop
+#define WGL_ACCESS_READ_ONLY_NV 0x00000000
+#define WGL_ACCESS_READ_WRITE_NV 0x00000001
+#define WGL_ACCESS_WRITE_DISCARD_NV 0x00000002
+#endif
+
+#ifndef WGL_NV_DX_interop2
+#endif
+
+#ifndef WGL_EXT_swap_control_tear
+#endif
+
+
+/*************************************************************/
+
+#ifndef WGL_ARB_pbuffer
+DECLARE_HANDLE(HPBUFFERARB);
+#endif
+#ifndef WGL_EXT_pbuffer
+DECLARE_HANDLE(HPBUFFEREXT);
+#endif
+#ifndef WGL_NV_present_video
+DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV);
+#endif
+#ifndef WGL_NV_video_output
+DECLARE_HANDLE(HPVIDEODEV);
+#endif
+#ifndef WGL_NV_gpu_affinity
+DECLARE_HANDLE(HPGPUNV);
+DECLARE_HANDLE(HGPUNV);
+
+typedef struct _GPU_DEVICE {
+ DWORD cb;
+ CHAR DeviceName[32];
+ CHAR DeviceString[128];
+ DWORD Flags;
+ RECT rcVirtualScreen;
+} GPU_DEVICE, *PGPU_DEVICE;
+#endif
+#ifndef WGL_NV_video_capture
+DECLARE_HANDLE(HVIDEOINPUTDEVICENV);
+#endif
+
+#ifndef WGL_ARB_buffer_region
+#define WGL_ARB_buffer_region 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern HANDLE WINAPI wglCreateBufferRegionARB (HDC hDC, int iLayerPlane, UINT uType);
+extern VOID WINAPI wglDeleteBufferRegionARB (HANDLE hRegion);
+extern BOOL WINAPI wglSaveBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height);
+extern BOOL WINAPI wglRestoreBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType);
+typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion);
+typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height);
+typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
+#endif
+
+#ifndef WGL_ARB_multisample
+#define WGL_ARB_multisample 1
+#endif
+
+#ifndef WGL_ARB_extensions_string
+#define WGL_ARB_extensions_string 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern const char * WINAPI wglGetExtensionsStringARB (HDC hdc);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
+#endif
+
+#ifndef WGL_ARB_pixel_format
+#define WGL_ARB_pixel_format 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetPixelFormatAttribivARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
+extern BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
+extern BOOL WINAPI wglChoosePixelFormatARB (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
+typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#endif
+
+#ifndef WGL_ARB_make_current_read
+#define WGL_ARB_make_current_read 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglMakeContextCurrentARB (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+extern HDC WINAPI wglGetCurrentReadDCARB (void);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void);
+#endif
+
+#ifndef WGL_ARB_pbuffer
+#define WGL_ARB_pbuffer 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern HPBUFFERARB WINAPI wglCreatePbufferARB (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+extern HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB hPbuffer);
+extern int WINAPI wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC);
+extern BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB hPbuffer);
+extern BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer);
+typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC);
+typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer);
+typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
+#endif
+
+#ifndef WGL_ARB_render_texture
+#define WGL_ARB_render_texture 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
+extern BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
+extern BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB hPbuffer, const int *piAttribList);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
+typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
+typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList);
+#endif
+
+#ifndef WGL_ARB_pixel_format_float
+#define WGL_ARB_pixel_format_float 1
+#endif
+
+#ifndef WGL_ARB_framebuffer_sRGB
+#define WGL_ARB_framebuffer_sRGB 1
+#endif
+
+#ifndef WGL_ARB_create_context
+#define WGL_ARB_create_context 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern HGLRC WINAPI wglCreateContextAttribsARB (HDC hDC, HGLRC hShareContext, const int *attribList);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList);
+#endif
+
+#ifndef WGL_ARB_create_context_profile
+#define WGL_ARB_create_context_profile 1
+#endif
+
+#ifndef WGL_ARB_create_context_robustness
+#define WGL_ARB_create_context_robustness 1
+#endif
+
+#ifndef WGL_EXT_display_color_table
+#define WGL_EXT_display_color_table 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort id);
+extern GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *table, GLuint length);
+extern GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort id);
+extern VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort id);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length);
+typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+#endif
+
+#ifndef WGL_EXT_extensions_string
+#define WGL_EXT_extensions_string 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern const char * WINAPI wglGetExtensionsStringEXT (void);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void);
+#endif
+
+#ifndef WGL_EXT_make_current_read
+#define WGL_EXT_make_current_read 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglMakeContextCurrentEXT (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+extern HDC WINAPI wglGetCurrentReadDCEXT (void);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void);
+#endif
+
+#ifndef WGL_EXT_pbuffer
+#define WGL_EXT_pbuffer 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+extern HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT hPbuffer);
+extern int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT hPbuffer, HDC hDC);
+extern BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT hPbuffer);
+extern BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer);
+typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC);
+typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer);
+typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
+#endif
+
+#ifndef WGL_EXT_pixel_format
+#define WGL_EXT_pixel_format 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
+extern BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
+extern BOOL WINAPI wglChoosePixelFormatEXT (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
+typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#endif
+
+#ifndef WGL_EXT_swap_control
+#define WGL_EXT_swap_control 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglSwapIntervalEXT (int interval);
+extern int WINAPI wglGetSwapIntervalEXT (void);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
+typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
+#endif
+
+#ifndef WGL_EXT_depth_float
+#define WGL_EXT_depth_float 1
+#endif
+
+#ifndef WGL_NV_vertex_array_range
+#define WGL_NV_vertex_array_range 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern void* WINAPI wglAllocateMemoryNV (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
+extern void WINAPI wglFreeMemoryNV (void *pointer);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef void* (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
+typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer);
+#endif
+
+#ifndef WGL_3DFX_multisample
+#define WGL_3DFX_multisample 1
+#endif
+
+#ifndef WGL_EXT_multisample
+#define WGL_EXT_multisample 1
+#endif
+
+#ifndef WGL_OML_sync_control
+#define WGL_OML_sync_control 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetSyncValuesOML (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
+extern BOOL WINAPI wglGetMscRateOML (HDC hdc, INT32 *numerator, INT32 *denominator);
+extern INT64 WINAPI wglSwapBuffersMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
+extern INT64 WINAPI wglSwapLayerBuffersMscOML (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
+extern BOOL WINAPI wglWaitForMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
+extern BOOL WINAPI wglWaitForSbcOML (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
+typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator);
+typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
+typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
+typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
+typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
+#endif
+
+#ifndef WGL_I3D_digital_video_control
+#define WGL_I3D_digital_video_control 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC hDC, int iAttribute, int *piValue);
+extern BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC hDC, int iAttribute, const int *piValue);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
+typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
+#endif
+
+#ifndef WGL_I3D_gamma
+#define WGL_I3D_gamma 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetGammaTableParametersI3D (HDC hDC, int iAttribute, int *piValue);
+extern BOOL WINAPI wglSetGammaTableParametersI3D (HDC hDC, int iAttribute, const int *piValue);
+extern BOOL WINAPI wglGetGammaTableI3D (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
+extern BOOL WINAPI wglSetGammaTableI3D (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
+typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
+typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
+typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
+#endif
+
+#ifndef WGL_I3D_genlock
+#define WGL_I3D_genlock 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglEnableGenlockI3D (HDC hDC);
+extern BOOL WINAPI wglDisableGenlockI3D (HDC hDC);
+extern BOOL WINAPI wglIsEnabledGenlockI3D (HDC hDC, BOOL *pFlag);
+extern BOOL WINAPI wglGenlockSourceI3D (HDC hDC, UINT uSource);
+extern BOOL WINAPI wglGetGenlockSourceI3D (HDC hDC, UINT *uSource);
+extern BOOL WINAPI wglGenlockSourceEdgeI3D (HDC hDC, UINT uEdge);
+extern BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC hDC, UINT *uEdge);
+extern BOOL WINAPI wglGenlockSampleRateI3D (HDC hDC, UINT uRate);
+extern BOOL WINAPI wglGetGenlockSampleRateI3D (HDC hDC, UINT *uRate);
+extern BOOL WINAPI wglGenlockSourceDelayI3D (HDC hDC, UINT uDelay);
+extern BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC hDC, UINT *uDelay);
+extern BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC);
+typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC);
+typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay);
+typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
+#endif
+
+#ifndef WGL_I3D_image_buffer
+#define WGL_I3D_image_buffer 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern LPVOID WINAPI wglCreateImageBufferI3D (HDC hDC, DWORD dwSize, UINT uFlags);
+extern BOOL WINAPI wglDestroyImageBufferI3D (HDC hDC, LPVOID pAddress);
+extern BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
+extern BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC hDC, const LPVOID *pAddress, UINT count);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags);
+typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress);
+typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
+typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count);
+#endif
+
+#ifndef WGL_I3D_swap_frame_lock
+#define WGL_I3D_swap_frame_lock 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglEnableFrameLockI3D (void);
+extern BOOL WINAPI wglDisableFrameLockI3D (void);
+extern BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *pFlag);
+extern BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *pFlag);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag);
+#endif
+
+#ifndef WGL_I3D_swap_frame_usage
+#define WGL_I3D_swap_frame_usage 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetFrameUsageI3D (float *pUsage);
+extern BOOL WINAPI wglBeginFrameTrackingI3D (void);
+extern BOOL WINAPI wglEndFrameTrackingI3D (void);
+extern BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage);
+typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
+#endif
+
+#ifndef WGL_ATI_pixel_format_float
+#define WGL_ATI_pixel_format_float 1
+#endif
+
+#ifndef WGL_NV_float_buffer
+#define WGL_NV_float_buffer 1
+#endif
+
+#ifndef WGL_3DL_stereo_control
+#define WGL_3DL_stereo_control 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglSetStereoEmitterState3DL (HDC hDC, UINT uState);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState);
+#endif
+
+#ifndef WGL_EXT_pixel_format_packed_float
+#define WGL_EXT_pixel_format_packed_float 1
+#endif
+
+#ifndef WGL_EXT_framebuffer_sRGB
+#define WGL_EXT_framebuffer_sRGB 1
+#endif
+
+#ifndef WGL_NV_present_video
+#define WGL_NV_present_video 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern int WINAPI wglEnumerateVideoDevicesNV (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
+extern BOOL WINAPI wglBindVideoDeviceNV (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
+extern BOOL WINAPI wglQueryCurrentContextNV (int iAttribute, int *piValue);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
+typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
+typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue);
+#endif
+
+#ifndef WGL_NV_video_output
+#define WGL_NV_video_output 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetVideoDeviceNV (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
+extern BOOL WINAPI wglReleaseVideoDeviceNV (HPVIDEODEV hVideoDevice);
+extern BOOL WINAPI wglBindVideoImageNV (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
+extern BOOL WINAPI wglReleaseVideoImageNV (HPBUFFERARB hPbuffer, int iVideoBuffer);
+extern BOOL WINAPI wglSendPbufferToVideoNV (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
+extern BOOL WINAPI wglGetVideoInfoNV (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice);
+typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer);
+typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
+typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
+#endif
+
+#ifndef WGL_NV_swap_group
+#define WGL_NV_swap_group 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglJoinSwapGroupNV (HDC hDC, GLuint group);
+extern BOOL WINAPI wglBindSwapBarrierNV (GLuint group, GLuint barrier);
+extern BOOL WINAPI wglQuerySwapGroupNV (HDC hDC, GLuint *group, GLuint *barrier);
+extern BOOL WINAPI wglQueryMaxSwapGroupsNV (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
+extern BOOL WINAPI wglQueryFrameCountNV (HDC hDC, GLuint *count);
+extern BOOL WINAPI wglResetFrameCountNV (HDC hDC);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group);
+typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier);
+typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier);
+typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count);
+typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC);
+#endif
+
+#ifndef WGL_NV_gpu_affinity
+#define WGL_NV_gpu_affinity 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglEnumGpusNV (UINT iGpuIndex, HGPUNV *phGpu);
+extern BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
+extern HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *phGpuList);
+extern BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
+extern BOOL WINAPI wglDeleteDCNV (HDC hdc);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu);
+typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
+typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList);
+typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
+typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc);
+#endif
+
+#ifndef WGL_AMD_gpu_association
+#define WGL_AMD_gpu_association 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern UINT WINAPI wglGetGPUIDsAMD (UINT maxCount, UINT *ids);
+extern INT WINAPI wglGetGPUInfoAMD (UINT id, int property, GLenum dataType, UINT size, void *data);
+extern UINT WINAPI wglGetContextGPUIDAMD (HGLRC hglrc);
+extern HGLRC WINAPI wglCreateAssociatedContextAMD (UINT id);
+extern HGLRC WINAPI wglCreateAssociatedContextAttribsAMD (UINT id, HGLRC hShareContext, const int *attribList);
+extern BOOL WINAPI wglDeleteAssociatedContextAMD (HGLRC hglrc);
+extern BOOL WINAPI wglMakeAssociatedContextCurrentAMD (HGLRC hglrc);
+extern HGLRC WINAPI wglGetCurrentAssociatedContextAMD (void);
+extern VOID WINAPI wglBlitContextFramebufferAMD (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT *ids);
+typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, int property, GLenum dataType, UINT size, void *data);
+typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc);
+typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id);
+typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int *attribList);
+typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc);
+typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc);
+typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void);
+typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+
+#ifndef WGL_NV_video_capture
+#define WGL_NV_video_capture 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglBindVideoCaptureDeviceNV (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
+extern UINT WINAPI wglEnumerateVideoCaptureDevicesNV (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
+extern BOOL WINAPI wglLockVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+extern BOOL WINAPI wglQueryVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
+extern BOOL WINAPI wglReleaseVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
+typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
+typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+#endif
+
+#ifndef WGL_NV_copy_image
+#define WGL_NV_copy_image 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglCopyImageSubDataNV (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+
+#ifndef WGL_NV_multisample_coverage
+#define WGL_NV_multisample_coverage 1
+#endif
+
+#ifndef WGL_NV_DX_interop
+#define WGL_NV_DX_interop 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglDXSetResourceShareHandleNV (void *dxObject, HANDLE shareHandle);
+extern HANDLE WINAPI wglDXOpenDeviceNV (void *dxDevice);
+extern BOOL WINAPI wglDXCloseDeviceNV (HANDLE hDevice);
+extern HANDLE WINAPI wglDXRegisterObjectNV (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
+extern BOOL WINAPI wglDXUnregisterObjectNV (HANDLE hDevice, HANDLE hObject);
+extern BOOL WINAPI wglDXObjectAccessNV (HANDLE hObject, GLenum access);
+extern BOOL WINAPI wglDXLockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
+extern BOOL WINAPI wglDXUnlockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void *dxObject, HANDLE shareHandle);
+typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void *dxDevice);
+typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice);
+typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
+typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject);
+typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access);
+typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects);
+typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects);
+#endif
+
+#ifndef WGL_NV_DX_interop2
+#define WGL_NV_DX_interop2 1
+#endif
+
+#ifndef WGL_EXT_swap_control_tear
+#define WGL_EXT_swap_control_tear 1
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/wined3d.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/wined3d.h
new file mode 100644
index 00000000..df677fa1
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/vbox/libWineStub/include/wine/wined3d.h
@@ -0,0 +1,2499 @@
+/*
+ * Copyright 2002-2003 The wine-d3d team
+ * Copyright 2002-2003 Jason Edmeades
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2006 Stefan Dösinger
+ * Copyright 2006 Stefan Dösinger for CodeWeavers
+ * Copyright 2007 Henri Verbeet
+ * Copyright 2008 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#ifndef __WINE_WINED3D_H
+#define __WINE_WINED3D_H
+
+#ifdef VBOX_WITH_WDDM
+#include "../../../vbox/VBoxWineEx.h"
+#endif
+
+#ifdef VBOX
+#define DECLSPEC_HIDDEN
+#endif
+
+#define WINED3D_OK S_OK
+
+#define _FACWINED3D 0x876
+#define MAKE_WINED3DSTATUS(code) MAKE_HRESULT(0, _FACWINED3D, code)
+#define WINED3DOK_NOAUTOGEN MAKE_WINED3DSTATUS(2159)
+
+#define MAKE_WINED3DHRESULT(code) MAKE_HRESULT(1, _FACWINED3D, code)
+#define WINED3DERR_WRONGTEXTUREFORMAT MAKE_WINED3DHRESULT(2072)
+#define WINED3DERR_UNSUPPORTEDCOLOROPERATION MAKE_WINED3DHRESULT(2073)
+#define WINED3DERR_UNSUPPORTEDCOLORARG MAKE_WINED3DHRESULT(2074)
+#define WINED3DERR_UNSUPPORTEDALPHAOPERATION MAKE_WINED3DHRESULT(2075)
+#define WINED3DERR_UNSUPPORTEDALPHAARG MAKE_WINED3DHRESULT(2076)
+#define WINED3DERR_TOOMANYOPERATIONS MAKE_WINED3DHRESULT(2077)
+#define WINED3DERR_CONFLICTINGTEXTUREFILTER MAKE_WINED3DHRESULT(2078)
+#define WINED3DERR_UNSUPPORTEDFACTORVALUE MAKE_WINED3DHRESULT(2079)
+#define WINED3DERR_CONFLICTINGRENDERSTATE MAKE_WINED3DHRESULT(2081)
+#define WINED3DERR_UNSUPPORTEDTEXTUREFILTER MAKE_WINED3DHRESULT(2082)
+#define WINED3DERR_CONFLICTINGTEXTUREPALETTE MAKE_WINED3DHRESULT(2086)
+#define WINED3DERR_DRIVERINTERNALERROR MAKE_WINED3DHRESULT(2087)
+#define WINED3DERR_NOTFOUND MAKE_WINED3DHRESULT(2150)
+#define WINED3DERR_MOREDATA MAKE_WINED3DHRESULT(2151)
+#define WINED3DERR_DEVICELOST MAKE_WINED3DHRESULT(2152)
+#define WINED3DERR_DEVICENOTRESET MAKE_WINED3DHRESULT(2153)
+#define WINED3DERR_NOTAVAILABLE MAKE_WINED3DHRESULT(2154)
+#define WINED3DERR_OUTOFVIDEOMEMORY MAKE_WINED3DHRESULT(380)
+#define WINED3DERR_INVALIDDEVICE MAKE_WINED3DHRESULT(2155)
+#define WINED3DERR_INVALIDCALL MAKE_WINED3DHRESULT(2156)
+#define WINED3DERR_DRIVERINVALIDCALL MAKE_WINED3DHRESULT(2157)
+#define WINED3DERR_WASSTILLDRAWING MAKE_WINED3DHRESULT(540)
+#define WINEDDERR_NOTAOVERLAYSURFACE MAKE_WINED3DHRESULT(580)
+#define WINEDDERR_NOTLOCKED MAKE_WINED3DHRESULT(584)
+#define WINEDDERR_NODC MAKE_WINED3DHRESULT(586)
+#define WINEDDERR_DCALREADYCREATED MAKE_WINED3DHRESULT(620)
+#define WINEDDERR_NOTFLIPPABLE MAKE_WINED3DHRESULT(582)
+#define WINEDDERR_SURFACEBUSY MAKE_WINED3DHRESULT(430)
+#define WINEDDERR_INVALIDRECT MAKE_WINED3DHRESULT(150)
+#define WINEDDERR_NOCLIPLIST MAKE_WINED3DHRESULT(205)
+#define WINEDDERR_OVERLAYNOTVISIBLE MAKE_WINED3DHRESULT(577)
+
+enum wined3d_light_type
+{
+ WINED3D_LIGHT_POINT = 1,
+ WINED3D_LIGHT_SPOT = 2,
+ WINED3D_LIGHT_DIRECTIONAL = 3,
+ WINED3D_LIGHT_PARALLELPOINT = 4, /* D3D7 */
+ WINED3D_LIGHT_GLSPOT = 5, /* D3D7 */
+};
+
+enum wined3d_primitive_type
+{
+ WINED3D_PT_UNDEFINED = 0,
+ WINED3D_PT_POINTLIST = 1,
+ WINED3D_PT_LINELIST = 2,
+ WINED3D_PT_LINESTRIP = 3,
+ WINED3D_PT_TRIANGLELIST = 4,
+ WINED3D_PT_TRIANGLESTRIP = 5,
+ WINED3D_PT_TRIANGLEFAN = 6,
+ WINED3D_PT_LINELIST_ADJ = 10,
+ WINED3D_PT_LINESTRIP_ADJ = 11,
+ WINED3D_PT_TRIANGLELIST_ADJ = 12,
+ WINED3D_PT_TRIANGLESTRIP_ADJ = 13,
+};
+
+enum wined3d_device_type
+{
+ WINED3D_DEVICE_TYPE_HAL = 1,
+ WINED3D_DEVICE_TYPE_REF = 2,
+ WINED3D_DEVICE_TYPE_SW = 3,
+ WINED3D_DEVICE_TYPE_NULLREF = 4,
+};
+
+enum wined3d_degree_type
+{
+ WINED3D_DEGREE_LINEAR = 1,
+ WINED3D_DEGREE_QUADRATIC = 2,
+ WINED3D_DEGREE_CUBIC = 3,
+ WINED3D_DEGREE_QUINTIC = 5,
+};
+
+#define WINEMAKEFOURCC(ch0, ch1, ch2, ch3) \
+ ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
+ ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24))
+
+enum wined3d_format_id
+{
+ WINED3DFMT_UNKNOWN,
+ WINED3DFMT_B8G8R8_UNORM,
+ WINED3DFMT_B5G5R5X1_UNORM,
+ WINED3DFMT_B4G4R4A4_UNORM,
+ WINED3DFMT_B2G3R3_UNORM,
+ WINED3DFMT_B2G3R3A8_UNORM,
+ WINED3DFMT_B4G4R4X4_UNORM,
+ WINED3DFMT_R8G8B8X8_UNORM,
+ WINED3DFMT_B10G10R10A2_UNORM,
+ WINED3DFMT_P8_UINT_A8_UNORM,
+ WINED3DFMT_P8_UINT,
+ WINED3DFMT_L8_UNORM,
+ WINED3DFMT_L8A8_UNORM,
+ WINED3DFMT_L4A4_UNORM,
+ WINED3DFMT_R5G5_SNORM_L6_UNORM,
+ WINED3DFMT_R8G8_SNORM_L8X8_UNORM,
+ WINED3DFMT_R10G11B11_SNORM,
+ WINED3DFMT_R10G10B10_SNORM_A2_UNORM,
+ WINED3DFMT_D16_LOCKABLE,
+ WINED3DFMT_D32_UNORM,
+ WINED3DFMT_S1_UINT_D15_UNORM,
+ WINED3DFMT_X8D24_UNORM,
+ WINED3DFMT_S4X4_UINT_D24_UNORM,
+ WINED3DFMT_L16_UNORM,
+ WINED3DFMT_S8_UINT_D24_FLOAT,
+ WINED3DFMT_VERTEXDATA,
+ WINED3DFMT_R8G8_SNORM_Cx,
+ WINED3DFMT_R32G32B32A32_TYPELESS,
+ WINED3DFMT_R32G32B32A32_FLOAT,
+ WINED3DFMT_R32G32B32A32_UINT,
+ WINED3DFMT_R32G32B32A32_SINT,
+ WINED3DFMT_R32G32B32_TYPELESS,
+ WINED3DFMT_R32G32B32_FLOAT,
+ WINED3DFMT_R32G32B32_UINT,
+ WINED3DFMT_R32G32B32_SINT,
+ WINED3DFMT_R16G16B16A16_TYPELESS,
+ WINED3DFMT_R16G16B16A16_FLOAT,
+ WINED3DFMT_R16G16B16A16_UNORM,
+ WINED3DFMT_R16G16B16A16_UINT,
+ WINED3DFMT_R16G16B16A16_SNORM,
+ WINED3DFMT_R16G16B16A16_SINT,
+ WINED3DFMT_R32G32_TYPELESS,
+ WINED3DFMT_R32G32_FLOAT,
+ WINED3DFMT_R32G32_UINT,
+ WINED3DFMT_R32G32_SINT,
+ WINED3DFMT_R32G8X24_TYPELESS,
+ WINED3DFMT_D32_FLOAT_S8X24_UINT,
+ WINED3DFMT_R32_FLOAT_X8X24_TYPELESS,
+ WINED3DFMT_X32_TYPELESS_G8X24_UINT,
+ WINED3DFMT_R10G10B10A2_TYPELESS,
+ WINED3DFMT_R10G10B10A2_UNORM,
+ WINED3DFMT_R10G10B10A2_UINT,
+ WINED3DFMT_R10G10B10A2_SNORM,
+ WINED3DFMT_R11G11B10_FLOAT,
+ WINED3DFMT_R8G8B8A8_TYPELESS,
+ WINED3DFMT_R8G8B8A8_UNORM,
+ WINED3DFMT_R8G8B8A8_UNORM_SRGB,
+ WINED3DFMT_R8G8B8A8_UINT,
+ WINED3DFMT_R8G8B8A8_SNORM,
+ WINED3DFMT_R8G8B8A8_SINT,
+ WINED3DFMT_R16G16_TYPELESS,
+ WINED3DFMT_R16G16_FLOAT,
+ WINED3DFMT_R16G16_UNORM,
+ WINED3DFMT_R16G16_UINT,
+ WINED3DFMT_R16G16_SNORM,
+ WINED3DFMT_R16G16_SINT,
+ WINED3DFMT_R32_TYPELESS,
+ WINED3DFMT_D32_FLOAT,
+ WINED3DFMT_R32_FLOAT,
+ WINED3DFMT_R32_UINT,
+ WINED3DFMT_R32_SINT,
+ WINED3DFMT_R24G8_TYPELESS,
+ WINED3DFMT_D24_UNORM_S8_UINT,
+ WINED3DFMT_R24_UNORM_X8_TYPELESS,
+ WINED3DFMT_X24_TYPELESS_G8_UINT,
+ WINED3DFMT_R8G8_TYPELESS,
+ WINED3DFMT_R8G8_UNORM,
+ WINED3DFMT_R8G8_UINT,
+ WINED3DFMT_R8G8_SNORM,
+ WINED3DFMT_R8G8_SINT,
+ WINED3DFMT_R16_TYPELESS,
+ WINED3DFMT_R16_FLOAT,
+ WINED3DFMT_D16_UNORM,
+ WINED3DFMT_R16_UNORM,
+ WINED3DFMT_R16_UINT,
+ WINED3DFMT_R16_SNORM,
+ WINED3DFMT_R16_SINT,
+ WINED3DFMT_R8_TYPELESS,
+ WINED3DFMT_R8_UNORM,
+ WINED3DFMT_R8_UINT,
+ WINED3DFMT_R8_SNORM,
+ WINED3DFMT_R8_SINT,
+ WINED3DFMT_A8_UNORM,
+ WINED3DFMT_R1_UNORM,
+ WINED3DFMT_R9G9B9E5_SHAREDEXP,
+ WINED3DFMT_R8G8_B8G8_UNORM,
+ WINED3DFMT_G8R8_G8B8_UNORM,
+ WINED3DFMT_BC1_TYPELESS,
+ WINED3DFMT_BC1_UNORM,
+ WINED3DFMT_BC1_UNORM_SRGB,
+ WINED3DFMT_BC2_TYPELESS,
+ WINED3DFMT_BC2_UNORM,
+ WINED3DFMT_BC2_UNORM_SRGB,
+ WINED3DFMT_BC3_TYPELESS,
+ WINED3DFMT_BC3_UNORM,
+ WINED3DFMT_BC3_UNORM_SRGB,
+ WINED3DFMT_BC4_TYPELESS,
+ WINED3DFMT_BC4_UNORM,
+ WINED3DFMT_BC4_SNORM,
+ WINED3DFMT_BC5_TYPELESS,
+ WINED3DFMT_BC5_UNORM,
+ WINED3DFMT_BC5_SNORM,
+ WINED3DFMT_B5G6R5_UNORM,
+ WINED3DFMT_B5G5R5A1_UNORM,
+ WINED3DFMT_B8G8R8A8_UNORM,
+ WINED3DFMT_B8G8R8X8_UNORM,
+ /* FOURCC formats. */
+ WINED3DFMT_UYVY = WINEMAKEFOURCC('U','Y','V','Y'),
+ WINED3DFMT_YUY2 = WINEMAKEFOURCC('Y','U','Y','2'),
+ WINED3DFMT_YV12 = WINEMAKEFOURCC('Y','V','1','2'),
+ WINED3DFMT_DXT1 = WINEMAKEFOURCC('D','X','T','1'),
+ WINED3DFMT_DXT2 = WINEMAKEFOURCC('D','X','T','2'),
+ WINED3DFMT_DXT3 = WINEMAKEFOURCC('D','X','T','3'),
+ WINED3DFMT_DXT4 = WINEMAKEFOURCC('D','X','T','4'),
+ WINED3DFMT_DXT5 = WINEMAKEFOURCC('D','X','T','5'),
+ WINED3DFMT_MULTI2_ARGB8 = WINEMAKEFOURCC('M','E','T','1'),
+ WINED3DFMT_G8R8_G8B8 = WINEMAKEFOURCC('G','R','G','B'),
+ WINED3DFMT_R8G8_B8G8 = WINEMAKEFOURCC('R','G','B','G'),
+ WINED3DFMT_ATI2N = WINEMAKEFOURCC('A','T','I','2'),
+ WINED3DFMT_INST = WINEMAKEFOURCC('I','N','S','T'),
+ WINED3DFMT_NVDB = WINEMAKEFOURCC('N','V','D','B'),
+ WINED3DFMT_NVHU = WINEMAKEFOURCC('N','V','H','U'),
+ WINED3DFMT_NVHS = WINEMAKEFOURCC('N','V','H','S'),
+ WINED3DFMT_INTZ = WINEMAKEFOURCC('I','N','T','Z'),
+ WINED3DFMT_RESZ = WINEMAKEFOURCC('R','E','S','Z'),
+ WINED3DFMT_NULL = WINEMAKEFOURCC('N','U','L','L'),
+ WINED3DFMT_R16 = WINEMAKEFOURCC(' ','R','1','6'),
+ WINED3DFMT_AL16 = WINEMAKEFOURCC('A','L','1','6'),
+
+ WINED3DFMT_FORCE_DWORD = 0xffffffff
+};
+
+enum wined3d_render_state
+{
+ WINED3D_RS_ANTIALIAS = 2, /* d3d7 */
+ WINED3D_RS_TEXTUREPERSPECTIVE = 4, /* d3d7 */
+ WINED3D_RS_WRAPU = 5, /* d3d7 */
+ WINED3D_RS_WRAPV = 6, /* d3d7 */
+ WINED3D_RS_ZENABLE = 7,
+ WINED3D_RS_FILLMODE = 8,
+ WINED3D_RS_SHADEMODE = 9,
+ WINED3D_RS_LINEPATTERN = 10, /* d3d7, d3d8 */
+ WINED3D_RS_MONOENABLE = 11, /* d3d7 */
+ WINED3D_RS_ROP2 = 12, /* d3d7 */
+ WINED3D_RS_PLANEMASK = 13, /* d3d7 */
+ WINED3D_RS_ZWRITEENABLE = 14,
+ WINED3D_RS_ALPHATESTENABLE = 15,
+ WINED3D_RS_LASTPIXEL = 16,
+ WINED3D_RS_SRCBLEND = 19,
+ WINED3D_RS_DESTBLEND = 20,
+ WINED3D_RS_CULLMODE = 22,
+ WINED3D_RS_ZFUNC = 23,
+ WINED3D_RS_ALPHAREF = 24,
+ WINED3D_RS_ALPHAFUNC = 25,
+ WINED3D_RS_DITHERENABLE = 26,
+ WINED3D_RS_ALPHABLENDENABLE = 27,
+ WINED3D_RS_FOGENABLE = 28,
+ WINED3D_RS_SPECULARENABLE = 29,
+ WINED3D_RS_ZVISIBLE = 30, /* d3d7, d3d8 */
+ WINED3D_RS_SUBPIXEL = 31, /* d3d7 */
+ WINED3D_RS_SUBPIXELX = 32, /* d3d7 */
+ WINED3D_RS_STIPPLEDALPHA = 33, /* d3d7 */
+ WINED3D_RS_FOGCOLOR = 34,
+ WINED3D_RS_FOGTABLEMODE = 35,
+ WINED3D_RS_FOGSTART = 36,
+ WINED3D_RS_FOGEND = 37,
+ WINED3D_RS_FOGDENSITY = 38,
+ WINED3D_RS_STIPPLEENABLE = 39, /* d3d7 */
+ WINED3D_RS_EDGEANTIALIAS = 40, /* d3d7, d3d8 */
+ WINED3D_RS_COLORKEYENABLE = 41, /* d3d7 */
+ WINED3D_RS_MIPMAPLODBIAS = 46, /* d3d7 */
+ WINED3D_RS_RANGEFOGENABLE = 48,
+ WINED3D_RS_ANISOTROPY = 49, /* d3d7 */
+ WINED3D_RS_FLUSHBATCH = 50, /* d3d7 */
+ WINED3D_RS_TRANSLUCENTSORTINDEPENDENT = 51, /* d3d7 */
+ WINED3D_RS_STENCILENABLE = 52,
+ WINED3D_RS_STENCILFAIL = 53,
+ WINED3D_RS_STENCILZFAIL = 54,
+ WINED3D_RS_STENCILPASS = 55,
+ WINED3D_RS_STENCILFUNC = 56,
+ WINED3D_RS_STENCILREF = 57,
+ WINED3D_RS_STENCILMASK = 58,
+ WINED3D_RS_STENCILWRITEMASK = 59,
+ WINED3D_RS_TEXTUREFACTOR = 60,
+ WINED3D_RS_WRAP0 = 128,
+ WINED3D_RS_WRAP1 = 129,
+ WINED3D_RS_WRAP2 = 130,
+ WINED3D_RS_WRAP3 = 131,
+ WINED3D_RS_WRAP4 = 132,
+ WINED3D_RS_WRAP5 = 133,
+ WINED3D_RS_WRAP6 = 134,
+ WINED3D_RS_WRAP7 = 135,
+ WINED3D_RS_CLIPPING = 136,
+ WINED3D_RS_LIGHTING = 137,
+ WINED3D_RS_EXTENTS = 138, /* d3d7 */
+ WINED3D_RS_AMBIENT = 139,
+ WINED3D_RS_FOGVERTEXMODE = 140,
+ WINED3D_RS_COLORVERTEX = 141,
+ WINED3D_RS_LOCALVIEWER = 142,
+ WINED3D_RS_NORMALIZENORMALS = 143,
+ WINED3D_RS_COLORKEYBLENDENABLE = 144, /* d3d7 */
+ WINED3D_RS_DIFFUSEMATERIALSOURCE = 145,
+ WINED3D_RS_SPECULARMATERIALSOURCE = 146,
+ WINED3D_RS_AMBIENTMATERIALSOURCE = 147,
+ WINED3D_RS_EMISSIVEMATERIALSOURCE = 148,
+ WINED3D_RS_VERTEXBLEND = 151,
+ WINED3D_RS_CLIPPLANEENABLE = 152,
+ WINED3D_RS_SOFTWAREVERTEXPROCESSING = 153, /* d3d8 */
+ WINED3D_RS_POINTSIZE = 154,
+ WINED3D_RS_POINTSIZE_MIN = 155,
+ WINED3D_RS_POINTSPRITEENABLE = 156,
+ WINED3D_RS_POINTSCALEENABLE = 157,
+ WINED3D_RS_POINTSCALE_A = 158,
+ WINED3D_RS_POINTSCALE_B = 159,
+ WINED3D_RS_POINTSCALE_C = 160,
+ WINED3D_RS_MULTISAMPLEANTIALIAS = 161,
+ WINED3D_RS_MULTISAMPLEMASK = 162,
+ WINED3D_RS_PATCHEDGESTYLE = 163,
+ WINED3D_RS_PATCHSEGMENTS = 164, /* d3d8 */
+ WINED3D_RS_DEBUGMONITORTOKEN = 165,
+ WINED3D_RS_POINTSIZE_MAX = 166,
+ WINED3D_RS_INDEXEDVERTEXBLENDENABLE = 167,
+ WINED3D_RS_COLORWRITEENABLE = 168,
+ WINED3D_RS_TWEENFACTOR = 170,
+ WINED3D_RS_BLENDOP = 171,
+ WINED3D_RS_POSITIONDEGREE = 172,
+ WINED3D_RS_NORMALDEGREE = 173,
+ WINED3D_RS_SCISSORTESTENABLE = 174,
+ WINED3D_RS_SLOPESCALEDEPTHBIAS = 175,
+ WINED3D_RS_ANTIALIASEDLINEENABLE = 176,
+ WINED3D_RS_MINTESSELLATIONLEVEL = 178,
+ WINED3D_RS_MAXTESSELLATIONLEVEL = 179,
+ WINED3D_RS_ADAPTIVETESS_X = 180,
+ WINED3D_RS_ADAPTIVETESS_Y = 181,
+ WINED3D_RS_ADAPTIVETESS_Z = 182,
+ WINED3D_RS_ADAPTIVETESS_W = 183,
+ WINED3D_RS_ENABLEADAPTIVETESSELLATION = 184,
+ WINED3D_RS_TWOSIDEDSTENCILMODE = 185,
+ WINED3D_RS_CCW_STENCILFAIL = 186,
+ WINED3D_RS_CCW_STENCILZFAIL = 187,
+ WINED3D_RS_CCW_STENCILPASS = 188,
+ WINED3D_RS_CCW_STENCILFUNC = 189,
+ WINED3D_RS_COLORWRITEENABLE1 = 190,
+ WINED3D_RS_COLORWRITEENABLE2 = 191,
+ WINED3D_RS_COLORWRITEENABLE3 = 192,
+ WINED3D_RS_BLENDFACTOR = 193,
+ WINED3D_RS_SRGBWRITEENABLE = 194,
+ WINED3D_RS_DEPTHBIAS = 195,
+ WINED3D_RS_WRAP8 = 198,
+ WINED3D_RS_WRAP9 = 199,
+ WINED3D_RS_WRAP10 = 200,
+ WINED3D_RS_WRAP11 = 201,
+ WINED3D_RS_WRAP12 = 202,
+ WINED3D_RS_WRAP13 = 203,
+ WINED3D_RS_WRAP14 = 204,
+ WINED3D_RS_WRAP15 = 205,
+ WINED3D_RS_SEPARATEALPHABLENDENABLE = 206,
+ WINED3D_RS_SRCBLENDALPHA = 207,
+ WINED3D_RS_DESTBLENDALPHA = 208,
+ WINED3D_RS_BLENDOPALPHA = 209,
+};
+#define WINEHIGHEST_RENDER_STATE WINED3D_RS_BLENDOPALPHA
+
+enum wined3d_blend
+{
+ WINED3D_BLEND_ZERO = 1,
+ WINED3D_BLEND_ONE = 2,
+ WINED3D_BLEND_SRCCOLOR = 3,
+ WINED3D_BLEND_INVSRCCOLOR = 4,
+ WINED3D_BLEND_SRCALPHA = 5,
+ WINED3D_BLEND_INVSRCALPHA = 6,
+ WINED3D_BLEND_DESTALPHA = 7,
+ WINED3D_BLEND_INVDESTALPHA = 8,
+ WINED3D_BLEND_DESTCOLOR = 9,
+ WINED3D_BLEND_INVDESTCOLOR = 10,
+ WINED3D_BLEND_SRCALPHASAT = 11,
+ WINED3D_BLEND_BOTHSRCALPHA = 12,
+ WINED3D_BLEND_BOTHINVSRCALPHA = 13,
+ WINED3D_BLEND_BLENDFACTOR = 14,
+ WINED3D_BLEND_INVBLENDFACTOR = 15,
+};
+
+enum wined3d_blend_op
+{
+ WINED3D_BLEND_OP_ADD = 1,
+ WINED3D_BLEND_OP_SUBTRACT = 2,
+ WINED3D_BLEND_OP_REVSUBTRACT = 3,
+ WINED3D_BLEND_OP_MIN = 4,
+ WINED3D_BLEND_OP_MAX = 5,
+};
+
+enum wined3d_vertex_blend_flags
+{
+ WINED3D_VBF_DISABLE = 0,
+ WINED3D_VBF_1WEIGHTS = 1,
+ WINED3D_VBF_2WEIGHTS = 2,
+ WINED3D_VBF_3WEIGHTS = 3,
+ WINED3D_VBF_TWEENING = 255,
+ WINED3D_VBF_0WEIGHTS = 256,
+};
+
+enum wined3d_cmp_func
+{
+ WINED3D_CMP_NEVER = 1,
+ WINED3D_CMP_LESS = 2,
+ WINED3D_CMP_EQUAL = 3,
+ WINED3D_CMP_LESSEQUAL = 4,
+ WINED3D_CMP_GREATER = 5,
+ WINED3D_CMP_NOTEQUAL = 6,
+ WINED3D_CMP_GREATEREQUAL = 7,
+ WINED3D_CMP_ALWAYS = 8,
+};
+
+enum wined3d_depth_buffer_type
+{
+ WINED3D_ZB_FALSE = 0,
+ WINED3D_ZB_TRUE = 1,
+ WINED3D_ZB_USEW = 2,
+};
+
+enum wined3d_fog_mode
+{
+ WINED3D_FOG_NONE = 0,
+ WINED3D_FOG_EXP = 1,
+ WINED3D_FOG_EXP2 = 2,
+ WINED3D_FOG_LINEAR = 3,
+};
+
+enum wined3d_shade_mode
+{
+ WINED3D_SHADE_FLAT = 1,
+ WINED3D_SHADE_GOURAUD = 2,
+ WINED3D_SHADE_PHONG = 3,
+};
+
+enum wined3d_fill_mode
+{
+ WINED3D_FILL_POINT = 1,
+ WINED3D_FILL_WIREFRAME = 2,
+ WINED3D_FILL_SOLID = 3,
+};
+
+enum wined3d_cull
+{
+ WINED3D_CULL_NONE = 1,
+ WINED3D_CULL_CW = 2,
+ WINED3D_CULL_CCW = 3,
+};
+
+enum wined3d_stencil_op
+{
+ WINED3D_STENCIL_OP_KEEP = 1,
+ WINED3D_STENCIL_OP_ZERO = 2,
+ WINED3D_STENCIL_OP_REPLACE = 3,
+ WINED3D_STENCIL_OP_INCR_SAT = 4,
+ WINED3D_STENCIL_OP_DECR_SAT = 5,
+ WINED3D_STENCIL_OP_INVERT = 6,
+ WINED3D_STENCIL_OP_INCR = 7,
+ WINED3D_STENCIL_OP_DECR = 8,
+};
+
+enum wined3d_material_color_source
+{
+ WINED3D_MCS_MATERIAL = 0,
+ WINED3D_MCS_COLOR1 = 1,
+ WINED3D_MCS_COLOR2 = 2,
+};
+
+enum wined3d_patch_edge_style
+{
+ WINED3D_PATCH_EDGE_DISCRETE = 0,
+ WINED3D_PATCH_EDGE_CONTINUOUS = 1,
+};
+
+enum wined3d_backbuffer_type
+{
+ WINED3D_BACKBUFFER_TYPE_MONO = 0,
+ WINED3D_BACKBUFFER_TYPE_LEFT = 1,
+ WINED3D_BACKBUFFER_TYPE_RIGHT = 2,
+};
+
+enum wined3d_swap_effect
+{
+ WINED3D_SWAP_EFFECT_DISCARD = 1,
+ WINED3D_SWAP_EFFECT_FLIP = 2,
+ WINED3D_SWAP_EFFECT_COPY = 3,
+ WINED3D_SWAP_EFFECT_COPY_VSYNC = 4,
+};
+
+enum wined3d_sampler_state
+{
+ WINED3D_SAMP_ADDRESS_U = 1,
+ WINED3D_SAMP_ADDRESS_V = 2,
+ WINED3D_SAMP_ADDRESS_W = 3,
+ WINED3D_SAMP_BORDER_COLOR = 4,
+ WINED3D_SAMP_MAG_FILTER = 5,
+ WINED3D_SAMP_MIN_FILTER = 6,
+ WINED3D_SAMP_MIP_FILTER = 7,
+ WINED3D_SAMP_MIPMAP_LOD_BIAS = 8,
+ WINED3D_SAMP_MAX_MIP_LEVEL = 9,
+ WINED3D_SAMP_MAX_ANISOTROPY = 10,
+ WINED3D_SAMP_SRGB_TEXTURE = 11,
+ WINED3D_SAMP_ELEMENT_INDEX = 12,
+ WINED3D_SAMP_DMAP_OFFSET = 13,
+};
+#define WINED3D_HIGHEST_SAMPLER_STATE WINED3D_SAMP_DMAP_OFFSET
+
+enum wined3d_multisample_type
+{
+ WINED3D_MULTISAMPLE_NONE = 0,
+ WINED3D_MULTISAMPLE_NON_MASKABLE = 1,
+ WINED3D_MULTISAMPLE_2_SAMPLES = 2,
+ WINED3D_MULTISAMPLE_3_SAMPLES = 3,
+ WINED3D_MULTISAMPLE_4_SAMPLES = 4,
+ WINED3D_MULTISAMPLE_5_SAMPLES = 5,
+ WINED3D_MULTISAMPLE_6_SAMPLES = 6,
+ WINED3D_MULTISAMPLE_7_SAMPLES = 7,
+ WINED3D_MULTISAMPLE_8_SAMPLES = 8,
+ WINED3D_MULTISAMPLE_9_SAMPLES = 9,
+ WINED3D_MULTISAMPLE_10_SAMPLES = 10,
+ WINED3D_MULTISAMPLE_11_SAMPLES = 11,
+ WINED3D_MULTISAMPLE_12_SAMPLES = 12,
+ WINED3D_MULTISAMPLE_13_SAMPLES = 13,
+ WINED3D_MULTISAMPLE_14_SAMPLES = 14,
+ WINED3D_MULTISAMPLE_15_SAMPLES = 15,
+ WINED3D_MULTISAMPLE_16_SAMPLES = 16,
+};
+
+enum wined3d_texture_stage_state
+{
+ WINED3D_TSS_COLOR_OP = 0,
+ WINED3D_TSS_COLOR_ARG1 = 1,
+ WINED3D_TSS_COLOR_ARG2 = 2,
+ WINED3D_TSS_ALPHA_OP = 3,
+ WINED3D_TSS_ALPHA_ARG1 = 4,
+ WINED3D_TSS_ALPHA_ARG2 = 5,
+ WINED3D_TSS_BUMPENV_MAT00 = 6,
+ WINED3D_TSS_BUMPENV_MAT01 = 7,
+ WINED3D_TSS_BUMPENV_MAT10 = 8,
+ WINED3D_TSS_BUMPENV_MAT11 = 9,
+ WINED3D_TSS_TEXCOORD_INDEX = 10,
+ WINED3D_TSS_BUMPENV_LSCALE = 11,
+ WINED3D_TSS_BUMPENV_LOFFSET = 12,
+ WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS = 13,
+ WINED3D_TSS_COLOR_ARG0 = 14,
+ WINED3D_TSS_ALPHA_ARG0 = 15,
+ WINED3D_TSS_RESULT_ARG = 16,
+ WINED3D_TSS_CONSTANT = 17,
+ WINED3D_TSS_INVALID = ~0U,
+};
+#define WINED3D_HIGHEST_TEXTURE_STATE WINED3D_TSS_CONSTANT
+
+enum wined3d_texture_transform_flags
+{
+ WINED3D_TTFF_DISABLE = 0,
+ WINED3D_TTFF_COUNT1 = 1,
+ WINED3D_TTFF_COUNT2 = 2,
+ WINED3D_TTFF_COUNT3 = 3,
+ WINED3D_TTFF_COUNT4 = 4,
+ WINED3D_TTFF_PROJECTED = 256,
+};
+
+enum wined3d_texture_op
+{
+ WINED3D_TOP_DISABLE = 1,
+ WINED3D_TOP_SELECT_ARG1 = 2,
+ WINED3D_TOP_SELECT_ARG2 = 3,
+ WINED3D_TOP_MODULATE = 4,
+ WINED3D_TOP_MODULATE_2X = 5,
+ WINED3D_TOP_MODULATE_4X = 6,
+ WINED3D_TOP_ADD = 7,
+ WINED3D_TOP_ADD_SIGNED = 8,
+ WINED3D_TOP_ADD_SIGNED_2X = 9,
+ WINED3D_TOP_SUBTRACT = 10,
+ WINED3D_TOP_ADD_SMOOTH = 11,
+ WINED3D_TOP_BLEND_DIFFUSE_ALPHA = 12,
+ WINED3D_TOP_BLEND_TEXTURE_ALPHA = 13,
+ WINED3D_TOP_BLEND_FACTOR_ALPHA = 14,
+ WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM = 15,
+ WINED3D_TOP_BLEND_CURRENT_ALPHA = 16,
+ WINED3D_TOP_PREMODULATE = 17,
+ WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR = 18,
+ WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA = 19,
+ WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR = 20,
+ WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA = 21,
+ WINED3D_TOP_BUMPENVMAP = 22,
+ WINED3D_TOP_BUMPENVMAP_LUMINANCE = 23,
+ WINED3D_TOP_DOTPRODUCT3 = 24,
+ WINED3D_TOP_MULTIPLY_ADD = 25,
+ WINED3D_TOP_LERP = 26,
+};
+
+enum wined3d_texture_address
+{
+ WINED3D_TADDRESS_WRAP = 1,
+ WINED3D_TADDRESS_MIRROR = 2,
+ WINED3D_TADDRESS_CLAMP = 3,
+ WINED3D_TADDRESS_BORDER = 4,
+ WINED3D_TADDRESS_MIRROR_ONCE = 5,
+};
+
+enum wined3d_transform_state
+{
+ WINED3D_TS_VIEW = 2,
+ WINED3D_TS_PROJECTION = 3,
+ WINED3D_TS_TEXTURE0 = 16,
+ WINED3D_TS_TEXTURE1 = 17,
+ WINED3D_TS_TEXTURE2 = 18,
+ WINED3D_TS_TEXTURE3 = 19,
+ WINED3D_TS_TEXTURE4 = 20,
+ WINED3D_TS_TEXTURE5 = 21,
+ WINED3D_TS_TEXTURE6 = 22,
+ WINED3D_TS_TEXTURE7 = 23,
+ WINED3D_TS_WORLD = 256, /* WINED3D_TS_WORLD_MATRIX(0) */
+ WINED3D_TS_WORLD1 = 257,
+ WINED3D_TS_WORLD2 = 258,
+ WINED3D_TS_WORLD3 = 259,
+};
+
+#define WINED3D_TS_WORLD_MATRIX(index) (enum wined3d_transform_state)(index + 256)
+
+enum wined3d_basis_type
+{
+ WINED3D_BASIS_BEZIER = 0,
+ WINED3D_BASIS_BSPLINE = 1,
+ WINED3D_BASIS_INTERPOLATE = 2,
+};
+
+enum wined3d_cubemap_face
+{
+ WINED3D_CUBEMAP_FACE_POSITIVE_X = 0,
+ WINED3D_CUBEMAP_FACE_NEGATIVE_X = 1,
+ WINED3D_CUBEMAP_FACE_POSITIVE_Y = 2,
+ WINED3D_CUBEMAP_FACE_NEGATIVE_Y = 3,
+ WINED3D_CUBEMAP_FACE_POSITIVE_Z = 4,
+ WINED3D_CUBEMAP_FACE_NEGATIVE_Z = 5,
+};
+
+enum wined3d_texture_filter_type
+{
+ WINED3D_TEXF_NONE = 0,
+ WINED3D_TEXF_POINT = 1,
+ WINED3D_TEXF_LINEAR = 2,
+ WINED3D_TEXF_ANISOTROPIC = 3,
+ WINED3D_TEXF_FLAT_CUBIC = 4,
+ WINED3D_TEXF_GAUSSIAN_CUBIC = 5,
+ WINED3D_TEXF_PYRAMIDAL_QUAD = 6,
+ WINED3D_TEXF_GAUSSIAN_QUAD = 7,
+};
+
+enum wined3d_resource_type
+{
+ WINED3D_RTYPE_SURFACE = 1,
+ WINED3D_RTYPE_VOLUME = 2,
+ WINED3D_RTYPE_TEXTURE = 3,
+ WINED3D_RTYPE_VOLUME_TEXTURE = 4,
+ WINED3D_RTYPE_CUBE_TEXTURE = 5,
+ WINED3D_RTYPE_BUFFER = 6,
+};
+
+enum wined3d_pool
+{
+ WINED3D_POOL_DEFAULT = 0,
+ WINED3D_POOL_MANAGED = 1,
+ WINED3D_POOL_SYSTEM_MEM = 2,
+ WINED3D_POOL_SCRATCH = 3,
+};
+
+enum wined3d_query_type
+{
+ WINED3D_QUERY_TYPE_VCACHE = 4,
+ WINED3D_QUERY_TYPE_RESOURCE_MANAGER = 5,
+ WINED3D_QUERY_TYPE_VERTEX_STATS = 6,
+ WINED3D_QUERY_TYPE_EVENT = 8,
+ WINED3D_QUERY_TYPE_OCCLUSION = 9,
+ WINED3D_QUERY_TYPE_TIMESTAMP = 10,
+ WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT = 11,
+ WINED3D_QUERY_TYPE_TIMESTAMP_FREQ = 12,
+ WINED3D_QUERY_TYPE_PIPELINE_TIMINGS = 13,
+ WINED3D_QUERY_TYPE_INTERFACE_TIMINGS = 14,
+ WINED3D_QUERY_TYPE_VERTEX_TIMINGS = 15,
+ WINED3D_QUERY_TYPE_PIXEL_TIMINGS = 16,
+ WINED3D_QUERY_TYPE_BANDWIDTH_TIMINGS = 17,
+ WINED3D_QUERY_TYPE_CACHE_UTILIZATION = 18
+};
+
+#define WINED3DISSUE_BEGIN (1 << 1)
+#define WINED3DISSUE_END (1 << 0)
+#define WINED3DGETDATA_FLUSH (1 << 0)
+
+enum wined3d_stateblock_type
+{
+ WINED3D_SBT_INIT = 0,
+ WINED3D_SBT_ALL = 1,
+ WINED3D_SBT_PIXEL_STATE = 2,
+ WINED3D_SBT_VERTEX_STATE = 3,
+ WINED3D_SBT_RECORDED = 4, /* WineD3D private */
+};
+
+enum wined3d_decl_method
+{
+ WINED3D_DECL_METHOD_DEFAULT = 0,
+ WINED3D_DECL_METHOD_PARTIAL_U = 1,
+ WINED3D_DECL_METHOD_PARTIAL_V = 2,
+ WINED3D_DECL_METHOD_CROSS_UV = 3,
+ WINED3D_DECL_METHOD_UV = 4,
+ WINED3D_DECL_METHOD_LOOKUP = 5,
+ WINED3D_DECL_METHOD_LOOKUP_PRESAMPLED = 6,
+};
+
+enum wined3d_decl_usage
+{
+ WINED3D_DECL_USAGE_POSITION = 0,
+ WINED3D_DECL_USAGE_BLEND_WEIGHT = 1,
+ WINED3D_DECL_USAGE_BLEND_INDICES = 2,
+ WINED3D_DECL_USAGE_NORMAL = 3,
+ WINED3D_DECL_USAGE_PSIZE = 4,
+ WINED3D_DECL_USAGE_TEXCOORD = 5,
+ WINED3D_DECL_USAGE_TANGENT = 6,
+ WINED3D_DECL_USAGE_BINORMAL = 7,
+ WINED3D_DECL_USAGE_TESS_FACTOR = 8,
+ WINED3D_DECL_USAGE_POSITIONT = 9,
+ WINED3D_DECL_USAGE_COLOR = 10,
+ WINED3D_DECL_USAGE_FOG = 11,
+ WINED3D_DECL_USAGE_DEPTH = 12,
+ WINED3D_DECL_USAGE_SAMPLE = 13
+};
+
+enum wined3d_sysval_semantic
+{
+ WINED3D_SV_DEPTH = 0xffffffff,
+ WINED3D_SV_TARGET0 = 0,
+ WINED3D_SV_TARGET1 = 1,
+ WINED3D_SV_TARGET2 = 2,
+ WINED3D_SV_TARGET3 = 3,
+ WINED3D_SV_TARGET4 = 4,
+ WINED3D_SV_TARGET5 = 5,
+ WINED3D_SV_TARGET6 = 6,
+ WINED3D_SV_TARGET7 = 7,
+};
+
+enum wined3d_scanline_ordering
+{
+ WINED3D_SCANLINE_ORDERING_UNKNOWN = 0,
+ WINED3D_SCANLINE_ORDERING_PROGRESSIVE = 1,
+ WINED3D_SCANLINE_ORDERING_INTERLACED = 2,
+};
+
+enum wined3d_display_rotation
+{
+ WINED3D_DISPLAY_ROTATION_UNSPECIFIED = 0,
+ WINED3D_DISPLAY_ROTATION_0 = 1,
+ WINED3D_DISPLAY_ROTATION_90 = 2,
+ WINED3D_DISPLAY_ROTATION_180 = 3,
+ WINED3D_DISPLAY_ROTATION_270 = 4,
+};
+
+#define WINED3DCOLORWRITEENABLE_RED (1 << 0)
+#define WINED3DCOLORWRITEENABLE_GREEN (1 << 1)
+#define WINED3DCOLORWRITEENABLE_BLUE (1 << 2)
+#define WINED3DCOLORWRITEENABLE_ALPHA (1 << 3)
+
+#define WINED3DADAPTER_DEFAULT 0
+#define WINED3DENUM_NO_WHQL_LEVEL 2
+#define WINED3DPRESENT_BACK_BUFFER_MAX 3
+
+#define WINED3DTSS_TCI_PASSTHRU 0x00000
+#define WINED3DTSS_TCI_CAMERASPACENORMAL 0x10000
+#define WINED3DTSS_TCI_CAMERASPACEPOSITION 0x20000
+#define WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR 0x30000
+#define WINED3DTSS_TCI_SPHEREMAP 0x40000
+
+#define WINED3DTA_SELECTMASK 0x0000000f
+#define WINED3DTA_DIFFUSE 0x00000000
+#define WINED3DTA_CURRENT 0x00000001
+#define WINED3DTA_TEXTURE 0x00000002
+#define WINED3DTA_TFACTOR 0x00000003
+#define WINED3DTA_SPECULAR 0x00000004
+#define WINED3DTA_TEMP 0x00000005
+#define WINED3DTA_CONSTANT 0x00000006
+#define WINED3DTA_COMPLEMENT 0x00000010
+#define WINED3DTA_ALPHAREPLICATE 0x00000020
+
+#define WINED3DPRESENTFLAG_LOCKABLE_BACKBUFFER 0x00000001
+#define WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL 0x00000002
+#define WINED3DPRESENTFLAG_DEVICECLIP 0x00000004
+#define WINED3DPRESENTFLAG_VIDEO 0x00000010
+#define WINED3DPRESENTFLAG_NOAUTOROTATE 0x00000020
+#define WINED3DPRESENTFLAG_UNPRUNEDMODE 0x00000040
+
+#define WINED3DDP_MAXTEXCOORD 8
+
+#define WINED3DUSAGE_RENDERTARGET 0x00000001
+#define WINED3DUSAGE_DEPTHSTENCIL 0x00000002
+#define WINED3DUSAGE_WRITEONLY 0x00000008
+#define WINED3DUSAGE_SOFTWAREPROCESSING 0x00000010
+#define WINED3DUSAGE_DONOTCLIP 0x00000020
+#define WINED3DUSAGE_POINTS 0x00000040
+#define WINED3DUSAGE_RTPATCHES 0x00000080
+#define WINED3DUSAGE_NPATCHES 0x00000100
+#define WINED3DUSAGE_DYNAMIC 0x00000200
+#define WINED3DUSAGE_AUTOGENMIPMAP 0x00000400
+#define WINED3DUSAGE_DMAP 0x00004000
+#define WINED3DUSAGE_MASK 0x00004fff
+#define WINED3DUSAGE_OWNDC 0x20000000
+#define WINED3DUSAGE_STATICDECL 0x40000000
+#define WINED3DUSAGE_OVERLAY 0x80000000
+
+#define WINED3DUSAGE_QUERY_LEGACYBUMPMAP 0x00008000
+#define WINED3DUSAGE_QUERY_FILTER 0x00020000
+#define WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING 0x00080000
+#define WINED3DUSAGE_QUERY_SRGBREAD 0x00010000
+#define WINED3DUSAGE_QUERY_SRGBWRITE 0x00040000
+#define WINED3DUSAGE_QUERY_VERTEXTEXTURE 0x00100000
+#define WINED3DUSAGE_QUERY_WRAPANDMIP 0x00200000
+#define WINED3DUSAGE_QUERY_MASK 0x003f8000
+
+#define WINED3D_MAP_READONLY 0x0010
+#define WINED3D_MAP_NOSYSLOCK 0x0800
+#define WINED3D_MAP_NOOVERWRITE 0x1000
+#define WINED3D_MAP_DISCARD 0x2000
+#define WINED3D_MAP_DONOTWAIT 0x4000
+#define WINED3D_MAP_NO_DIRTY_UPDATE 0x8000
+
+#define WINED3DPRESENT_RATE_DEFAULT 0x00000000
+
+#define WINED3DPRESENT_INTERVAL_DEFAULT 0x00000000
+#define WINED3DPRESENT_INTERVAL_ONE 0x00000001
+#define WINED3DPRESENT_INTERVAL_TWO 0x00000002
+#define WINED3DPRESENT_INTERVAL_THREE 0x00000004
+#define WINED3DPRESENT_INTERVAL_FOUR 0x00000008
+#define WINED3DPRESENT_INTERVAL_IMMEDIATE 0x80000000
+
+#define WINED3DMAXUSERCLIPPLANES 32
+#define WINED3DCLIPPLANE0 (1 << 0)
+#define WINED3DCLIPPLANE1 (1 << 1)
+#define WINED3DCLIPPLANE2 (1 << 2)
+#define WINED3DCLIPPLANE3 (1 << 3)
+#define WINED3DCLIPPLANE4 (1 << 4)
+#define WINED3DCLIPPLANE5 (1 << 5)
+
+/* FVF (Flexible Vertex Format) codes */
+#define WINED3DFVF_RESERVED0 0x0001
+#define WINED3DFVF_POSITION_MASK 0x400e
+#define WINED3DFVF_XYZ 0x0002
+#define WINED3DFVF_XYZRHW 0x0004
+#define WINED3DFVF_XYZB1 0x0006
+#define WINED3DFVF_XYZB2 0x0008
+#define WINED3DFVF_XYZB3 0x000a
+#define WINED3DFVF_XYZB4 0x000c
+#define WINED3DFVF_XYZB5 0x000e
+#define WINED3DFVF_XYZW 0x4002
+#define WINED3DFVF_NORMAL 0x0010
+#define WINED3DFVF_PSIZE 0x0020
+#define WINED3DFVF_DIFFUSE 0x0040
+#define WINED3DFVF_SPECULAR 0x0080
+#define WINED3DFVF_TEXCOUNT_MASK 0x0f00
+#define WINED3DFVF_TEXCOUNT_SHIFT 8
+#define WINED3DFVF_TEX0 0x0000
+#define WINED3DFVF_TEX1 0x0100
+#define WINED3DFVF_TEX2 0x0200
+#define WINED3DFVF_TEX3 0x0300
+#define WINED3DFVF_TEX4 0x0400
+#define WINED3DFVF_TEX5 0x0500
+#define WINED3DFVF_TEX6 0x0600
+#define WINED3DFVF_TEX7 0x0700
+#define WINED3DFVF_TEX8 0x0800
+#define WINED3DFVF_LASTBETA_UBYTE4 0x1000
+#define WINED3DFVF_LASTBETA_D3DCOLOR 0x8000
+#define WINED3DFVF_RESERVED2 0x6000
+
+#define WINED3DFVF_TEXTUREFORMAT1 3
+#define WINED3DFVF_TEXTUREFORMAT2 0
+#define WINED3DFVF_TEXTUREFORMAT3 1
+#define WINED3DFVF_TEXTUREFORMAT4 2
+#define WINED3DFVF_TEXCOORDSIZE1(idx) (WINED3DFVF_TEXTUREFORMAT1 << (idx * 2 + 16))
+#define WINED3DFVF_TEXCOORDSIZE2(idx) (WINED3DFVF_TEXTUREFORMAT2 << (idx * 2 + 16))
+#define WINED3DFVF_TEXCOORDSIZE3(idx) (WINED3DFVF_TEXTUREFORMAT3 << (idx * 2 + 16))
+#define WINED3DFVF_TEXCOORDSIZE4(idx) (WINED3DFVF_TEXTUREFORMAT4 << (idx * 2 + 16))
+
+/* Clear flags */
+#define WINED3DCLEAR_TARGET 0x00000001
+#define WINED3DCLEAR_ZBUFFER 0x00000002
+#define WINED3DCLEAR_STENCIL 0x00000004
+
+/* Stream source flags */
+#define WINED3DSTREAMSOURCE_INDEXEDDATA (1 << 30)
+#define WINED3DSTREAMSOURCE_INSTANCEDATA (2 << 30)
+
+/* SetPrivateData flags */
+#define WINED3DSPD_IUNKNOWN 0x00000001
+
+/* IWineD3D::CreateDevice behaviour flags */
+#define WINED3DCREATE_FPU_PRESERVE 0x00000002
+#define WINED3DCREATE_PUREDEVICE 0x00000010
+#define WINED3DCREATE_SOFTWARE_VERTEXPROCESSING 0x00000020
+#define WINED3DCREATE_HARDWARE_VERTEXPROCESSING 0x00000040
+#define WINED3DCREATE_MIXED_VERTEXPROCESSING 0x00000080
+#define WINED3DCREATE_DISABLE_DRIVER_MANAGEMENT 0x00000100
+#define WINED3DCREATE_ADAPTERGROUP_DEVICE 0x00000200
+
+/* VTF defines */
+#define WINED3DDMAPSAMPLER 0x100
+#define WINED3DVERTEXTEXTURESAMPLER0 (WINED3DDMAPSAMPLER + 1)
+#define WINED3DVERTEXTEXTURESAMPLER1 (WINED3DDMAPSAMPLER + 2)
+#define WINED3DVERTEXTEXTURESAMPLER2 (WINED3DDMAPSAMPLER + 3)
+#define WINED3DVERTEXTEXTURESAMPLER3 (WINED3DDMAPSAMPLER + 4)
+
+#define WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD 0x00000020
+#define WINED3DCAPS3_LINEAR_TO_SRGB_PRESENTATION 0x00000080
+#define WINED3DCAPS3_COPY_TO_VIDMEM 0x00000100
+#define WINED3DCAPS3_COPY_TO_SYSTEMMEM 0x00000200
+#define WINED3DCAPS3_RESERVED 0x8000001f
+
+#define WINED3DDEVCAPS2_STREAMOFFSET 0x00000001
+#define WINED3DDEVCAPS2_DMAPNPATCH 0x00000002
+#define WINED3DDEVCAPS2_ADAPTIVETESSRTPATCH 0x00000004
+#define WINED3DDEVCAPS2_ADAPTIVETESSNPATCH 0x00000008
+#define WINED3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES 0x00000010
+#define WINED3DDEVCAPS2_PRESAMPLEDDMAPNPATCH 0x00000020
+#define WINED3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET 0x00000040
+
+#define WINED3DDTCAPS_UBYTE4 0x00000001
+#define WINED3DDTCAPS_UBYTE4N 0x00000002
+#define WINED3DDTCAPS_SHORT2N 0x00000004
+#define WINED3DDTCAPS_SHORT4N 0x00000008
+#define WINED3DDTCAPS_USHORT2N 0x00000010
+#define WINED3DDTCAPS_USHORT4N 0x00000020
+#define WINED3DDTCAPS_UDEC3 0x00000040
+#define WINED3DDTCAPS_DEC3N 0x00000080
+#define WINED3DDTCAPS_FLOAT16_2 0x00000100
+#define WINED3DDTCAPS_FLOAT16_4 0x00000200
+
+#define WINED3DFVFCAPS_TEXCOORDCOUNTMASK 0x0000ffff
+#define WINED3DFVFCAPS_DONOTSTRIPELEMENTS 0x00080000
+#define WINED3DFVFCAPS_PSIZE 0x00100000
+
+#define WINED3DLINECAPS_TEXTURE 0x00000001
+#define WINED3DLINECAPS_ZTEST 0x00000002
+#define WINED3DLINECAPS_BLEND 0x00000004
+#define WINED3DLINECAPS_ALPHACMP 0x00000008
+#define WINED3DLINECAPS_FOG 0x00000010
+#define WINED3DLINECAPS_ANTIALIAS 0x00000020
+
+#define WINED3DMAX30SHADERINSTRUCTIONS 32768
+#define WINED3DMIN30SHADERINSTRUCTIONS 512
+
+#define WINED3DPBLENDCAPS_ZERO 0x00000001
+#define WINED3DPBLENDCAPS_ONE 0x00000002
+#define WINED3DPBLENDCAPS_SRCCOLOR 0x00000004
+#define WINED3DPBLENDCAPS_INVSRCCOLOR 0x00000008
+#define WINED3DPBLENDCAPS_SRCALPHA 0x00000010
+#define WINED3DPBLENDCAPS_INVSRCALPHA 0x00000020
+#define WINED3DPBLENDCAPS_DESTALPHA 0x00000040
+#define WINED3DPBLENDCAPS_INVDESTALPHA 0x00000080
+#define WINED3DPBLENDCAPS_DESTCOLOR 0x00000100
+#define WINED3DPBLENDCAPS_INVDESTCOLOR 0x00000200
+#define WINED3DPBLENDCAPS_SRCALPHASAT 0x00000400
+#define WINED3DPBLENDCAPS_BOTHSRCALPHA 0x00000800
+#define WINED3DPBLENDCAPS_BOTHINVSRCALPHA 0x00001000
+#define WINED3DPBLENDCAPS_BLENDFACTOR 0x00002000
+
+#define WINED3DPCMPCAPS_NEVER 0x00000001
+#define WINED3DPCMPCAPS_LESS 0x00000002
+#define WINED3DPCMPCAPS_EQUAL 0x00000004
+#define WINED3DPCMPCAPS_LESSEQUAL 0x00000008
+#define WINED3DPCMPCAPS_GREATER 0x00000010
+#define WINED3DPCMPCAPS_NOTEQUAL 0x00000020
+#define WINED3DPCMPCAPS_GREATEREQUAL 0x00000040
+#define WINED3DPCMPCAPS_ALWAYS 0x00000080
+
+#define WINED3DPMISCCAPS_MASKZ 0x00000002
+#define WINED3DPMISCCAPS_LINEPATTERNREP 0x00000004
+#define WINED3DPMISCCAPS_CULLNONE 0x00000010
+#define WINED3DPMISCCAPS_CULLCW 0x00000020
+#define WINED3DPMISCCAPS_CULLCCW 0x00000040
+#define WINED3DPMISCCAPS_COLORWRITEENABLE 0x00000080
+#define WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS 0x00000100
+#define WINED3DPMISCCAPS_CLIPTLVERTS 0x00000200
+#define WINED3DPMISCCAPS_TSSARGTEMP 0x00000400
+#define WINED3DPMISCCAPS_BLENDOP 0x00000800
+#define WINED3DPMISCCAPS_NULLREFERENCE 0x00001000
+#define WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS 0x00004000
+#define WINED3DPMISCCAPS_PERSTAGECONSTANT 0x00008000
+#define WINED3DPMISCCAPS_FOGANDSPECULARALPHA 0x00010000
+#define WINED3DPMISCCAPS_SEPARATEALPHABLEND 0x00020000
+#define WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS 0x00040000
+#define WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING 0x00080000
+#define WINED3DPMISCCAPS_FOGVERTEXCLAMPED 0x00100000
+#define WINED3DPMISCCAPS_POSTBLENDSRGBCONVERT 0x00200000
+
+#define WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH 24
+#define WINED3DPS20_MIN_DYNAMICFLOWCONTROLDEPTH 0
+#define WINED3DPS20_MAX_NUMTEMPS 32
+#define WINED3DPS20_MIN_NUMTEMPS 12
+#define WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH 4
+#define WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH 0
+#define WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS 512
+#define WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS 96
+
+#define WINED3DPS20CAPS_ARBITRARYSWIZZLE 0x00000001
+#define WINED3DPS20CAPS_GRADIENTINSTRUCTIONS 0x00000002
+#define WINED3DPS20CAPS_PREDICATION 0x00000004
+#define WINED3DPS20CAPS_NODEPENDENTREADLIMIT 0x00000008
+#define WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT 0x00000010
+
+#define WINED3DPTADDRESSCAPS_WRAP 0x00000001
+#define WINED3DPTADDRESSCAPS_MIRROR 0x00000002
+#define WINED3DPTADDRESSCAPS_CLAMP 0x00000004
+#define WINED3DPTADDRESSCAPS_BORDER 0x00000008
+#define WINED3DPTADDRESSCAPS_INDEPENDENTUV 0x00000010
+#define WINED3DPTADDRESSCAPS_MIRRORONCE 0x00000020
+
+#define WINED3DSTENCILCAPS_KEEP 0x00000001
+#define WINED3DSTENCILCAPS_ZERO 0x00000002
+#define WINED3DSTENCILCAPS_REPLACE 0x00000004
+#define WINED3DSTENCILCAPS_INCRSAT 0x00000008
+#define WINED3DSTENCILCAPS_DECRSAT 0x00000010
+#define WINED3DSTENCILCAPS_INVERT 0x00000020
+#define WINED3DSTENCILCAPS_INCR 0x00000040
+#define WINED3DSTENCILCAPS_DECR 0x00000080
+#define WINED3DSTENCILCAPS_TWOSIDED 0x00000100
+
+#define WINED3DTEXOPCAPS_DISABLE 0x00000001
+#define WINED3DTEXOPCAPS_SELECTARG1 0x00000002
+#define WINED3DTEXOPCAPS_SELECTARG2 0x00000004
+#define WINED3DTEXOPCAPS_MODULATE 0x00000008
+#define WINED3DTEXOPCAPS_MODULATE2X 0x00000010
+#define WINED3DTEXOPCAPS_MODULATE4X 0x00000020
+#define WINED3DTEXOPCAPS_ADD 0x00000040
+#define WINED3DTEXOPCAPS_ADDSIGNED 0x00000080
+#define WINED3DTEXOPCAPS_ADDSIGNED2X 0x00000100
+#define WINED3DTEXOPCAPS_SUBTRACT 0x00000200
+#define WINED3DTEXOPCAPS_ADDSMOOTH 0x00000400
+#define WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA 0x00000800
+#define WINED3DTEXOPCAPS_BLENDTEXTUREALPHA 0x00001000
+#define WINED3DTEXOPCAPS_BLENDFACTORALPHA 0x00002000
+#define WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM 0x00004000
+#define WINED3DTEXOPCAPS_BLENDCURRENTALPHA 0x00008000
+#define WINED3DTEXOPCAPS_PREMODULATE 0x00010000
+#define WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR 0x00020000
+#define WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA 0x00040000
+#define WINED3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR 0x00080000
+#define WINED3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA 0x00100000
+#define WINED3DTEXOPCAPS_BUMPENVMAP 0x00200000
+#define WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE 0x00400000
+#define WINED3DTEXOPCAPS_DOTPRODUCT3 0x00800000
+#define WINED3DTEXOPCAPS_MULTIPLYADD 0x01000000
+#define WINED3DTEXOPCAPS_LERP 0x02000000
+
+#define WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH 24
+#define WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH 0
+#define WINED3DVS20_MAX_NUMTEMPS 32
+#define WINED3DVS20_MIN_NUMTEMPS 12
+#define WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH 4
+#define WINED3DVS20_MIN_STATICFLOWCONTROLDEPTH 1
+
+#define WINED3DVS20CAPS_PREDICATION 0x00000001
+
+#define WINED3DCAPS2_NO2DDURING3DSCENE 0x00000002
+#define WINED3DCAPS2_FULLSCREENGAMMA 0x00020000
+#define WINED3DCAPS2_CANRENDERWINDOWED 0x00080000
+#define WINED3DCAPS2_CANCALIBRATEGAMMA 0x00100000
+#define WINED3DCAPS2_RESERVED 0x02000000
+#define WINED3DCAPS2_CANMANAGERESOURCE 0x10000000
+#define WINED3DCAPS2_DYNAMICTEXTURES 0x20000000
+#define WINED3DCAPS2_CANAUTOGENMIPMAP 0x40000000
+
+#define WINED3DPRASTERCAPS_DITHER 0x00000001
+#define WINED3DPRASTERCAPS_ROP2 0x00000002
+#define WINED3DPRASTERCAPS_XOR 0x00000004
+#define WINED3DPRASTERCAPS_PAT 0x00000008
+#define WINED3DPRASTERCAPS_ZTEST 0x00000010
+#define WINED3DPRASTERCAPS_SUBPIXEL 0x00000020
+#define WINED3DPRASTERCAPS_SUBPIXELX 0x00000040
+#define WINED3DPRASTERCAPS_FOGVERTEX 0x00000080
+#define WINED3DPRASTERCAPS_FOGTABLE 0x00000100
+#define WINED3DPRASTERCAPS_STIPPLE 0x00000200
+#define WINED3DPRASTERCAPS_ANTIALIASSORTDEPENDENT 0x00000400
+#define WINED3DPRASTERCAPS_ANTIALIASSORTINDEPENDENT 0x00000800
+#define WINED3DPRASTERCAPS_ANTIALIASEDGES 0x00001000
+#define WINED3DPRASTERCAPS_MIPMAPLODBIAS 0x00002000
+#define WINED3DPRASTERCAPS_ZBIAS 0x00004000
+#define WINED3DPRASTERCAPS_ZBUFFERLESSHSR 0x00008000
+#define WINED3DPRASTERCAPS_FOGRANGE 0x00010000
+#define WINED3DPRASTERCAPS_ANISOTROPY 0x00020000
+#define WINED3DPRASTERCAPS_WBUFFER 0x00040000
+#define WINED3DPRASTERCAPS_TRANSLUCENTSORTINDEPENDENT 0x00080000
+#define WINED3DPRASTERCAPS_WFOG 0x00100000
+#define WINED3DPRASTERCAPS_ZFOG 0x00200000
+#define WINED3DPRASTERCAPS_COLORPERSPECTIVE 0x00400000
+#define WINED3DPRASTERCAPS_SCISSORTEST 0x01000000
+#define WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS 0x02000000
+#define WINED3DPRASTERCAPS_DEPTHBIAS 0x04000000
+#define WINED3DPRASTERCAPS_MULTISAMPLE_TOGGLE 0x08000000
+
+#define WINED3DPSHADECAPS_COLORFLATMONO 0x00000001
+#define WINED3DPSHADECAPS_COLORFLATRGB 0x00000002
+#define WINED3DPSHADECAPS_COLORGOURAUDMONO 0x00000004
+#define WINED3DPSHADECAPS_COLORGOURAUDRGB 0x00000008
+#define WINED3DPSHADECAPS_COLORPHONGMONO 0x00000010
+#define WINED3DPSHADECAPS_COLORPHONGRGB 0x00000020
+#define WINED3DPSHADECAPS_SPECULARFLATMONO 0x00000040
+#define WINED3DPSHADECAPS_SPECULARFLATRGB 0x00000080
+#define WINED3DPSHADECAPS_SPECULARGOURAUDMONO 0x00000100
+#define WINED3DPSHADECAPS_SPECULARGOURAUDRGB 0x00000200
+#define WINED3DPSHADECAPS_SPECULARPHONGMONO 0x00000400
+#define WINED3DPSHADECAPS_SPECULARPHONGRGB 0x00000800
+#define WINED3DPSHADECAPS_ALPHAFLATBLEND 0x00001000
+#define WINED3DPSHADECAPS_ALPHAFLATSTIPPLED 0x00002000
+#define WINED3DPSHADECAPS_ALPHAGOURAUDBLEND 0x00004000
+#define WINED3DPSHADECAPS_ALPHAGOURAUDSTIPPLED 0x00008000
+#define WINED3DPSHADECAPS_ALPHAPHONGBLEND 0x00010000
+#define WINED3DPSHADECAPS_ALPHAPHONGSTIPPLED 0x00020000
+#define WINED3DPSHADECAPS_FOGFLAT 0x00040000
+#define WINED3DPSHADECAPS_FOGGOURAUD 0x00080000
+#define WINED3DPSHADECAPS_FOGPHONG 0x00100000
+
+#define WINED3DPTEXTURECAPS_PERSPECTIVE 0x00000001
+#define WINED3DPTEXTURECAPS_POW2 0x00000002
+#define WINED3DPTEXTURECAPS_ALPHA 0x00000004
+#define WINED3DPTEXTURECAPS_TRANSPARENCY 0x00000008
+#define WINED3DPTEXTURECAPS_BORDER 0x00000010
+#define WINED3DPTEXTURECAPS_SQUAREONLY 0x00000020
+#define WINED3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE 0x00000040
+#define WINED3DPTEXTURECAPS_ALPHAPALETTE 0x00000080
+#define WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL 0x00000100
+#define WINED3DPTEXTURECAPS_PROJECTED 0x00000400
+#define WINED3DPTEXTURECAPS_CUBEMAP 0x00000800
+#define WINED3DPTEXTURECAPS_COLORKEYBLEND 0x00001000
+#define WINED3DPTEXTURECAPS_VOLUMEMAP 0x00002000
+#define WINED3DPTEXTURECAPS_MIPMAP 0x00004000
+#define WINED3DPTEXTURECAPS_MIPVOLUMEMAP 0x00008000
+#define WINED3DPTEXTURECAPS_MIPCUBEMAP 0x00010000
+#define WINED3DPTEXTURECAPS_CUBEMAP_POW2 0x00020000
+#define WINED3DPTEXTURECAPS_VOLUMEMAP_POW2 0x00040000
+#define WINED3DPTEXTURECAPS_NOPROJECTEDBUMPENV 0x00200000
+
+#define WINED3DPTFILTERCAPS_NEAREST 0x00000001
+#define WINED3DPTFILTERCAPS_LINEAR 0x00000002
+#define WINED3DPTFILTERCAPS_MIPNEAREST 0x00000004
+#define WINED3DPTFILTERCAPS_MIPLINEAR 0x00000008
+#define WINED3DPTFILTERCAPS_LINEARMIPNEAREST 0x00000010
+#define WINED3DPTFILTERCAPS_LINEARMIPLINEAR 0x00000020
+#define WINED3DPTFILTERCAPS_MINFPOINT 0x00000100
+#define WINED3DPTFILTERCAPS_MINFLINEAR 0x00000200
+#define WINED3DPTFILTERCAPS_MINFANISOTROPIC 0x00000400
+#define WINED3DPTFILTERCAPS_MIPFPOINT 0x00010000
+#define WINED3DPTFILTERCAPS_MIPFLINEAR 0x00020000
+#define WINED3DPTFILTERCAPS_MAGFPOINT 0x01000000
+#define WINED3DPTFILTERCAPS_MAGFLINEAR 0x02000000
+#define WINED3DPTFILTERCAPS_MAGFANISOTROPIC 0x04000000
+#define WINED3DPTFILTERCAPS_MAGFPYRAMIDALQUAD 0x08000000
+#define WINED3DPTFILTERCAPS_MAGFGAUSSIANQUAD 0x10000000
+
+#define WINED3DVTXPCAPS_TEXGEN 0x00000001
+#define WINED3DVTXPCAPS_MATERIALSOURCE7 0x00000002
+#define WINED3DVTXPCAPS_VERTEXFOG 0x00000004
+#define WINED3DVTXPCAPS_DIRECTIONALLIGHTS 0x00000008
+#define WINED3DVTXPCAPS_POSITIONALLIGHTS 0x00000010
+#define WINED3DVTXPCAPS_LOCALVIEWER 0x00000020
+#define WINED3DVTXPCAPS_TWEENING 0x00000040
+#define WINED3DVTXPCAPS_TEXGEN_SPHEREMAP 0x00000100
+#define WINED3DVTXPCAPS_NO_TEXGEN_NONLOCALVIEWER 0x00000200
+
+#define WINED3DCURSORCAPS_COLOR 0x00000001
+#define WINED3DCURSORCAPS_LOWRES 0x00000002
+
+#define WINED3DDEVCAPS_FLOATTLVERTEX 0x00000001
+#define WINED3DDEVCAPS_SORTINCREASINGZ 0x00000002
+#define WINED3DDEVCAPS_SORTDECREASINGZ 0X00000004
+#define WINED3DDEVCAPS_SORTEXACT 0x00000008
+#define WINED3DDEVCAPS_EXECUTESYSTEMMEMORY 0x00000010
+#define WINED3DDEVCAPS_EXECUTEVIDEOMEMORY 0x00000020
+#define WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY 0x00000040
+#define WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY 0x00000080
+#define WINED3DDEVCAPS_TEXTURESYSTEMMEMORY 0x00000100
+#define WINED3DDEVCAPS_TEXTUREVIDEOMEMORY 0x00000200
+#define WINED3DDEVCAPS_DRAWPRIMTLVERTEX 0x00000400
+#define WINED3DDEVCAPS_CANRENDERAFTERFLIP 0x00000800
+#define WINED3DDEVCAPS_TEXTURENONLOCALVIDMEM 0x00001000
+#define WINED3DDEVCAPS_DRAWPRIMITIVES2 0x00002000
+#define WINED3DDEVCAPS_SEPARATETEXTUREMEMORIES 0x00004000
+#define WINED3DDEVCAPS_DRAWPRIMITIVES2EX 0x00008000
+#define WINED3DDEVCAPS_HWTRANSFORMANDLIGHT 0x00010000
+#define WINED3DDEVCAPS_CANBLTSYSTONONLOCAL 0x00020000
+#define WINED3DDEVCAPS_HWRASTERIZATION 0x00080000
+#define WINED3DDEVCAPS_PUREDEVICE 0x00100000
+#define WINED3DDEVCAPS_QUINTICRTPATCHES 0x00200000
+#define WINED3DDEVCAPS_RTPATCHES 0x00400000
+#define WINED3DDEVCAPS_RTPATCHHANDLEZERO 0x00800000
+#define WINED3DDEVCAPS_NPATCHES 0x01000000
+
+#define WINED3D_LEGACY_DEPTH_BIAS 0x00000001
+#define WINED3D_NO3D 0x00000002
+#define WINED3D_VIDMEM_ACCOUNTING 0x00000004
+
+#define WINED3D_RESZ_CODE 0x7fa05000
+
+/* dwDDFX */
+/* arithmetic stretching along y axis */
+#define WINEDDBLTFX_ARITHSTRETCHY 0x00000001
+/* mirror on y axis */
+#define WINEDDBLTFX_MIRRORLEFTRIGHT 0x00000002
+/* mirror on x axis */
+#define WINEDDBLTFX_MIRRORUPDOWN 0x00000004
+/* do not tear */
+#define WINEDDBLTFX_NOTEARING 0x00000008
+/* 180 degrees clockwise rotation */
+#define WINEDDBLTFX_ROTATE180 0x00000010
+/* 270 degrees clockwise rotation */
+#define WINEDDBLTFX_ROTATE270 0x00000020
+/* 90 degrees clockwise rotation */
+#define WINEDDBLTFX_ROTATE90 0x00000040
+/* dwZBufferLow and dwZBufferHigh specify limits to the copied Z values */
+#define WINEDDBLTFX_ZBUFFERRANGE 0x00000080
+/* add dwZBufferBaseDest to every source z value before compare */
+#define WINEDDBLTFX_ZBUFFERBASEDEST 0x00000100
+
+/* dwFlags for Blt* */
+#define WINEDDBLT_ALPHADEST 0x00000001
+#define WINEDDBLT_ALPHADESTCONSTOVERRIDE 0x00000002
+#define WINEDDBLT_ALPHADESTNEG 0x00000004
+#define WINEDDBLT_ALPHADESTSURFACEOVERRIDE 0x00000008
+#define WINEDDBLT_ALPHAEDGEBLEND 0x00000010
+#define WINEDDBLT_ALPHASRC 0x00000020
+#define WINEDDBLT_ALPHASRCCONSTOVERRIDE 0x00000040
+#define WINEDDBLT_ALPHASRCNEG 0x00000080
+#define WINEDDBLT_ALPHASRCSURFACEOVERRIDE 0x00000100
+#define WINEDDBLT_ASYNC 0x00000200
+#define WINEDDBLT_COLORFILL 0x00000400
+#define WINEDDBLT_DDFX 0x00000800
+#define WINEDDBLT_DDROPS 0x00001000
+#define WINEDDBLT_KEYDEST 0x00002000
+#define WINEDDBLT_KEYDESTOVERRIDE 0x00004000
+#define WINEDDBLT_KEYSRC 0x00008000
+#define WINEDDBLT_KEYSRCOVERRIDE 0x00010000
+#define WINEDDBLT_ROP 0x00020000
+#define WINEDDBLT_ROTATIONANGLE 0x00040000
+#define WINEDDBLT_ZBUFFER 0x00080000
+#define WINEDDBLT_ZBUFFERDESTCONSTOVERRIDE 0x00100000
+#define WINEDDBLT_ZBUFFERDESTOVERRIDE 0x00200000
+#define WINEDDBLT_ZBUFFERSRCCONSTOVERRIDE 0x00400000
+#define WINEDDBLT_ZBUFFERSRCOVERRIDE 0x00800000
+#define WINEDDBLT_WAIT 0x01000000
+#define WINEDDBLT_DEPTHFILL 0x02000000
+#define WINEDDBLT_DONOTWAIT 0x08000000
+
+/* DDSURFACEDESC.dwFlags */
+#define WINEDDSD_CAPS 0x00000001
+#define WINEDDSD_HEIGHT 0x00000002
+#define WINEDDSD_WIDTH 0x00000004
+#define WINEDDSD_PITCH 0x00000008
+#define WINEDDSD_BACKBUFFERCOUNT 0x00000020
+#define WINEDDSD_ZBUFFERBITDEPTH 0x00000040
+#define WINEDDSD_ALPHABITDEPTH 0x00000080
+#define WINEDDSD_LPSURFACE 0x00000800
+#define WINEDDSD_PIXELFORMAT 0x00001000
+#define WINEDDSD_CKDESTOVERLAY 0x00002000
+#define WINEDDSD_CKDESTBLT 0x00004000
+#define WINEDDSD_CKSRCOVERLAY 0x00008000
+#define WINEDDSD_CKSRCBLT 0x00010000
+#define WINEDDSD_MIPMAPCOUNT 0x00020000
+#define WINEDDSD_REFRESHRATE 0x00040000
+#define WINEDDSD_LINEARSIZE 0x00080000
+#define WINEDDSD_TEXTURESTAGE 0x00100000
+#define WINEDDSD_FVF 0x00200000
+#define WINEDDSD_SRCVBHANDLE 0x00400000
+#define WINEDDSD_ALL 0x007ff9ee
+
+/* Set/Get Colour Key Flags */
+#define WINEDDCKEY_COLORSPACE 0x00000001 /* Struct is single colour space */
+#define WINEDDCKEY_DESTBLT 0x00000002 /* To be used as dest for blt */
+#define WINEDDCKEY_DESTOVERLAY 0x00000004 /* To be used as dest for CK overlays */
+#define WINEDDCKEY_SRCBLT 0x00000008 /* To be used as src for blt */
+#define WINEDDCKEY_SRCOVERLAY 0x00000010 /* To be used as src for CK overlays */
+
+/* dwFlags for GetBltStatus */
+#define WINEDDGBS_CANBLT 0x00000001
+#define WINEDDGBS_ISBLTDONE 0x00000002
+
+/* dwFlags for GetFlipStatus */
+#define WINEDDGFS_CANFLIP 0x00000001
+#define WINEDDGFS_ISFLIPDONE 0x00000002
+
+/* dwFlags for Flip */
+#define WINEDDFLIP_WAIT 0x00000001
+#define WINEDDFLIP_EVEN 0x00000002 /* only valid for overlay */
+#define WINEDDFLIP_ODD 0x00000004 /* only valid for overlay */
+#define WINEDDFLIP_NOVSYNC 0x00000008
+#define WINEDDFLIP_STEREO 0x00000010
+#define WINEDDFLIP_DONOTWAIT 0x00000020
+#define WINEDDFLIP_INTERVAL2 0x02000000
+#define WINEDDFLIP_INTERVAL3 0x03000000
+#define WINEDDFLIP_INTERVAL4 0x04000000
+
+#define WINEDDOVER_ALPHADEST 0x00000001
+#define WINEDDOVER_ALPHADESTCONSTOVERRIDE 0x00000002
+#define WINEDDOVER_ALPHADESTNEG 0x00000004
+#define WINEDDOVER_ALPHADESTSURFACEOVERRIDE 0x00000008
+#define WINEDDOVER_ALPHAEDGEBLEND 0x00000010
+#define WINEDDOVER_ALPHASRC 0x00000020
+#define WINEDDOVER_ALPHASRCCONSTOVERRIDE 0x00000040
+#define WINEDDOVER_ALPHASRCNEG 0x00000080
+#define WINEDDOVER_ALPHASRCSURFACEOVERRIDE 0x00000100
+#define WINEDDOVER_HIDE 0x00000200
+#define WINEDDOVER_KEYDEST 0x00000400
+#define WINEDDOVER_KEYDESTOVERRIDE 0x00000800
+#define WINEDDOVER_KEYSRC 0x00001000
+#define WINEDDOVER_KEYSRCOVERRIDE 0x00002000
+#define WINEDDOVER_SHOW 0x00004000
+#define WINEDDOVER_ADDDIRTYRECT 0x00008000
+#define WINEDDOVER_REFRESHDIRTYRECTS 0x00010000
+#define WINEDDOVER_REFRESHALL 0x00020000
+#define WINEDDOVER_DDFX 0x00080000
+#define WINEDDOVER_AUTOFLIP 0x00100000
+#define WINEDDOVER_BOB 0x00200000
+#define WINEDDOVER_OVERRIDEBOBWEAVE 0x00400000
+#define WINEDDOVER_INTERLEAVED 0x00800000
+
+/* DirectDraw Caps */
+#define WINEDDSCAPS_RESERVED1 0x00000001
+#define WINEDDSCAPS_ALPHA 0x00000002
+#define WINEDDSCAPS_BACKBUFFER 0x00000004
+#define WINEDDSCAPS_COMPLEX 0x00000008
+#define WINEDDSCAPS_FLIP 0x00000010
+#define WINEDDSCAPS_FRONTBUFFER 0x00000020
+#define WINEDDSCAPS_OFFSCREENPLAIN 0x00000040
+#define WINEDDSCAPS_OVERLAY 0x00000080
+#define WINEDDSCAPS_PALETTE 0x00000100
+#define WINEDDSCAPS_PRIMARYSURFACE 0x00000200
+#define WINEDDSCAPS_PRIMARYSURFACELEFT 0x00000400
+#define WINEDDSCAPS_SYSTEMMEMORY 0x00000800
+#define WINEDDSCAPS_TEXTURE 0x00001000
+#define WINEDDSCAPS_3DDEVICE 0x00002000
+#define WINEDDSCAPS_VIDEOMEMORY 0x00004000
+#define WINEDDSCAPS_VISIBLE 0x00008000
+#define WINEDDSCAPS_WRITEONLY 0x00010000
+#define WINEDDSCAPS_ZBUFFER 0x00020000
+#define WINEDDSCAPS_OWNDC 0x00040000
+#define WINEDDSCAPS_LIVEVIDEO 0x00080000
+#define WINEDDSCAPS_HWCODEC 0x00100000
+#define WINEDDSCAPS_MODEX 0x00200000
+#define WINEDDSCAPS_MIPMAP 0x00400000
+#define WINEDDSCAPS_RESERVED2 0x00800000
+#define WINEDDSCAPS_ALLOCONLOAD 0x04000000
+#define WINEDDSCAPS_VIDEOPORT 0x08000000
+#define WINEDDSCAPS_LOCALVIDMEM 0x10000000
+#define WINEDDSCAPS_NONLOCALVIDMEM 0x20000000
+#define WINEDDSCAPS_STANDARDVGAMODE 0x40000000
+#define WINEDDSCAPS_OPTIMIZED 0x80000000
+
+#define WINEDDCKEYCAPS_DESTBLT 0x00000001
+#define WINEDDCKEYCAPS_DESTBLTCLRSPACE 0x00000002
+#define WINEDDCKEYCAPS_DESTBLTCLRSPACEYUV 0x00000004
+#define WINEDDCKEYCAPS_DESTBLTYUV 0x00000008
+#define WINEDDCKEYCAPS_DESTOVERLAY 0x00000010
+#define WINEDDCKEYCAPS_DESTOVERLAYCLRSPACE 0x00000020
+#define WINEDDCKEYCAPS_DESTOVERLAYCLRSPACEYUV 0x00000040
+#define WINEDDCKEYCAPS_DESTOVERLAYONEACTIVE 0x00000080
+#define WINEDDCKEYCAPS_DESTOVERLAYYUV 0x00000100
+#define WINEDDCKEYCAPS_SRCBLT 0x00000200
+#define WINEDDCKEYCAPS_SRCBLTCLRSPACE 0x00000400
+#define WINEDDCKEYCAPS_SRCBLTCLRSPACEYUV 0x00000800
+#define WINEDDCKEYCAPS_SRCBLTYUV 0x00001000
+#define WINEDDCKEYCAPS_SRCOVERLAY 0x00002000
+#define WINEDDCKEYCAPS_SRCOVERLAYCLRSPACE 0x00004000
+#define WINEDDCKEYCAPS_SRCOVERLAYCLRSPACEYUV 0x00008000
+#define WINEDDCKEYCAPS_SRCOVERLAYONEACTIVE 0x00010000
+#define WINEDDCKEYCAPS_SRCOVERLAYYUV 0x00020000
+#define WINEDDCKEYCAPS_NOCOSTOVERLAY 0x00040000
+
+#define WINEDDFXCAPS_BLTALPHA 0x00000001
+#define WINEDDFXCAPS_OVERLAYALPHA 0x00000004
+#define WINEDDFXCAPS_BLTARITHSTRETCHYN 0x00000010
+#define WINEDDFXCAPS_BLTARITHSTRETCHY 0x00000020
+#define WINEDDFXCAPS_BLTMIRRORLEFTRIGHT 0x00000040
+#define WINEDDFXCAPS_BLTMIRRORUPDOWN 0x00000080
+#define WINEDDFXCAPS_BLTROTATION 0x00000100
+#define WINEDDFXCAPS_BLTROTATION90 0x00000200
+#define WINEDDFXCAPS_BLTSHRINKX 0x00000400
+#define WINEDDFXCAPS_BLTSHRINKXN 0x00000800
+#define WINEDDFXCAPS_BLTSHRINKY 0x00001000
+#define WINEDDFXCAPS_BLTSHRINKYN 0x00002000
+#define WINEDDFXCAPS_BLTSTRETCHX 0x00004000
+#define WINEDDFXCAPS_BLTSTRETCHXN 0x00008000
+#define WINEDDFXCAPS_BLTSTRETCHY 0x00010000
+#define WINEDDFXCAPS_BLTSTRETCHYN 0x00020000
+#define WINEDDFXCAPS_OVERLAYARITHSTRETCHY 0x00040000
+#define WINEDDFXCAPS_OVERLAYARITHSTRETCHYN 0x00000008
+#define WINEDDFXCAPS_OVERLAYSHRINKX 0x00080000
+#define WINEDDFXCAPS_OVERLAYSHRINKXN 0x00100000
+#define WINEDDFXCAPS_OVERLAYSHRINKY 0x00200000
+#define WINEDDFXCAPS_OVERLAYSHRINKYN 0x00400000
+#define WINEDDFXCAPS_OVERLAYSTRETCHX 0x00800000
+#define WINEDDFXCAPS_OVERLAYSTRETCHXN 0x01000000
+#define WINEDDFXCAPS_OVERLAYSTRETCHY 0x02000000
+#define WINEDDFXCAPS_OVERLAYSTRETCHYN 0x04000000
+#define WINEDDFXCAPS_OVERLAYMIRRORLEFTRIGHT 0x08000000
+#define WINEDDFXCAPS_OVERLAYMIRRORUPDOWN 0x10000000
+
+#define WINEDDCAPS_3D 0x00000001
+#define WINEDDCAPS_ALIGNBOUNDARYDEST 0x00000002
+#define WINEDDCAPS_ALIGNSIZEDEST 0x00000004
+#define WINEDDCAPS_ALIGNBOUNDARYSRC 0x00000008
+#define WINEDDCAPS_ALIGNSIZESRC 0x00000010
+#define WINEDDCAPS_ALIGNSTRIDE 0x00000020
+#define WINEDDCAPS_BLT 0x00000040
+#define WINEDDCAPS_BLTQUEUE 0x00000080
+#define WINEDDCAPS_BLTFOURCC 0x00000100
+#define WINEDDCAPS_BLTSTRETCH 0x00000200
+#define WINEDDCAPS_GDI 0x00000400
+#define WINEDDCAPS_OVERLAY 0x00000800
+#define WINEDDCAPS_OVERLAYCANTCLIP 0x00001000
+#define WINEDDCAPS_OVERLAYFOURCC 0x00002000
+#define WINEDDCAPS_OVERLAYSTRETCH 0x00004000
+#define WINEDDCAPS_PALETTE 0x00008000
+#define WINEDDCAPS_PALETTEVSYNC 0x00010000
+#define WINEDDCAPS_READSCANLINE 0x00020000
+#define WINEDDCAPS_STEREOVIEW 0x00040000
+#define WINEDDCAPS_VBI 0x00080000
+#define WINEDDCAPS_ZBLTS 0x00100000
+#define WINEDDCAPS_ZOVERLAYS 0x00200000
+#define WINEDDCAPS_COLORKEY 0x00400000
+#define WINEDDCAPS_ALPHA 0x00800000
+#define WINEDDCAPS_COLORKEYHWASSIST 0x01000000
+#define WINEDDCAPS_NOHARDWARE 0x02000000
+#define WINEDDCAPS_BLTCOLORFILL 0x04000000
+#define WINEDDCAPS_BANKSWITCHED 0x08000000
+#define WINEDDCAPS_BLTDEPTHFILL 0x10000000
+#define WINEDDCAPS_CANCLIP 0x20000000
+#define WINEDDCAPS_CANCLIPSTRETCHED 0x40000000
+#define WINEDDCAPS_CANBLTSYSMEM 0x80000000
+
+#define WINEDDCAPS2_CERTIFIED 0x00000001
+#define WINEDDCAPS2_NO2DDURING3DSCENE 0x00000002
+#define WINEDDCAPS2_VIDEOPORT 0x00000004
+#define WINEDDCAPS2_AUTOFLIPOVERLAY 0x00000008
+#define WINEDDCAPS2_CANBOBINTERLEAVED 0x00000010
+#define WINEDDCAPS2_CANBOBNONINTERLEAVED 0x00000020
+#define WINEDDCAPS2_COLORCONTROLOVERLAY 0x00000040
+#define WINEDDCAPS2_COLORCONTROLPRIMARY 0x00000080
+#define WINEDDCAPS2_CANDROPZ16BIT 0x00000100
+#define WINEDDCAPS2_NONLOCALVIDMEM 0x00000200
+#define WINEDDCAPS2_NONLOCALVIDMEMCAPS 0x00000400
+#define WINEDDCAPS2_NOPAGELOCKREQUIRED 0x00000800
+#define WINEDDCAPS2_WIDESURFACES 0x00001000
+#define WINEDDCAPS2_CANFLIPODDEVEN 0x00002000
+#define WINEDDCAPS2_CANBOBHARDWARE 0x00004000
+#define WINEDDCAPS2_COPYFOURCC 0x00008000
+#define WINEDDCAPS2_PRIMARYGAMMA 0x00020000
+#define WINEDDCAPS2_CANRENDERWINDOWED 0x00080000
+#define WINEDDCAPS2_CANCALIBRATEGAMMA 0x00100000
+#define WINEDDCAPS2_FLIPINTERVAL 0x00200000
+#define WINEDDCAPS2_FLIPNOVSYNC 0x00400000
+#define WINEDDCAPS2_CANMANAGETEXTURE 0x00800000
+#define WINEDDCAPS2_TEXMANINNONLOCALVIDMEM 0x01000000
+#define WINEDDCAPS2_STEREO 0x02000000
+#define WINEDDCAPS2_SYSTONONLOCAL_AS_SYSTOLOCAL 0x04000000
+
+/* DDCAPS.d */
+#define WINEDDPCAPS_4BIT 0x00000001
+#define WINEDDPCAPS_8BITENTRIES 0x00000002
+#define WINEDDPCAPS_8BIT 0x00000004
+#define WINEDDPCAPS_INITIALIZE 0x00000008
+#define WINEDDPCAPS_PRIMARYSURFACE 0x00000010
+#define WINEDDPCAPS_PRIMARYSURFACELEFT 0x00000020
+#define WINEDDPCAPS_ALLOW256 0x00000040
+#define WINEDDPCAPS_VSYNC 0x00000080
+#define WINEDDPCAPS_1BIT 0x00000100
+#define WINEDDPCAPS_2BIT 0x00000200
+#define WINEDDPCAPS_ALPHA 0x00000400
+
+#define WINED3D_SURFACE_MAPPABLE 0x00000001
+#define WINED3D_SURFACE_DISCARD 0x00000002
+#define WINED3D_SURFACE_PIN_SYSMEM 0x00000004
+
+struct wined3d_display_mode
+{
+ UINT width;
+ UINT height;
+ UINT refresh_rate;
+ enum wined3d_format_id format_id;
+ enum wined3d_scanline_ordering scanline_ordering;
+};
+
+struct wined3d_color
+{
+ float r;
+ float g;
+ float b;
+ float a;
+};
+
+struct wined3d_vec3
+{
+ float x;
+ float y;
+ float z;
+};
+
+struct wined3d_vec4
+{
+ float x;
+ float y;
+ float z;
+ float w;
+};
+
+struct wined3d_matrix
+{
+ union
+ {
+ struct
+ {
+ float _11, _12, _13, _14;
+ float _21, _22, _23, _24;
+ float _31, _32, _33, _34;
+ float _41, _42, _43, _44;
+ } DUMMYSTRUCTNAME;
+ float m[4][4];
+ } DUMMYUNIONNAME;
+};
+
+struct wined3d_light
+{
+ enum wined3d_light_type type;
+ struct wined3d_color diffuse;
+ struct wined3d_color specular;
+ struct wined3d_color ambient;
+ struct wined3d_vec3 position;
+ struct wined3d_vec3 direction;
+ float range;
+ float falloff;
+ float attenuation0;
+ float attenuation1;
+ float attenuation2;
+ float theta;
+ float phi;
+};
+
+struct wined3d_material
+{
+ struct wined3d_color diffuse;
+ struct wined3d_color ambient;
+ struct wined3d_color specular;
+ struct wined3d_color emissive;
+ float power;
+};
+
+struct wined3d_viewport
+{
+ UINT x;
+ UINT y;
+ UINT width;
+ UINT height;
+ float min_z;
+ float max_z;
+};
+
+struct wined3d_gamma_ramp
+{
+ WORD red[256];
+ WORD green[256];
+ WORD blue[256];
+};
+
+struct wined3d_line_pattern
+{
+ WORD repeat_factor;
+ WORD line_pattern;
+};
+
+struct wined3d_rect_patch_info
+{
+ UINT start_vertex_offset_width;
+ UINT start_vertex_offset_height;
+ UINT width;
+ UINT height;
+ UINT stride;
+ enum wined3d_basis_type basis;
+ enum wined3d_degree_type degree;
+};
+
+struct wined3d_tri_patch_info
+{
+ UINT start_vertex_offset;
+ UINT vertex_count;
+ enum wined3d_basis_type basis;
+ enum wined3d_degree_type degree;
+};
+
+struct wined3d_adapter_identifier
+{
+ char *driver;
+ UINT driver_size;
+ char *description;
+ UINT description_size;
+ char *device_name;
+ UINT device_name_size;
+ LARGE_INTEGER driver_version;
+ DWORD vendor_id;
+ DWORD device_id;
+ DWORD subsystem_id;
+ DWORD revision;
+ GUID device_identifier;
+ DWORD whql_level;
+ LUID adapter_luid;
+ SIZE_T video_memory;
+};
+
+struct wined3d_swapchain_desc
+{
+ UINT backbuffer_width;
+ UINT backbuffer_height;
+ enum wined3d_format_id backbuffer_format;
+ UINT backbuffer_count;
+ enum wined3d_multisample_type multisample_type;
+ DWORD multisample_quality;
+ enum wined3d_swap_effect swap_effect;
+ HWND device_window;
+ BOOL windowed;
+ BOOL enable_auto_depth_stencil;
+ enum wined3d_format_id auto_depth_stencil_format;
+ DWORD flags;
+ UINT refresh_rate;
+ UINT swap_interval;
+ BOOL auto_restore_display_mode;
+#ifdef VBOX_WITH_WDDM
+ struct VBOXUHGSMI *pHgsmi;
+#endif
+};
+
+struct wined3d_resource_desc
+{
+ enum wined3d_resource_type resource_type;
+ enum wined3d_format_id format;
+ enum wined3d_multisample_type multisample_type;
+ UINT multisample_quality;
+ DWORD usage;
+ enum wined3d_pool pool;
+ UINT width;
+ UINT height;
+ UINT depth;
+ UINT size;
+};
+
+struct wined3d_clip_status
+{
+ DWORD clip_union;
+ DWORD clip_intersection;
+};
+
+struct wined3d_vertex_element
+{
+ enum wined3d_format_id format;
+ WORD input_slot;
+ WORD offset;
+ UINT output_slot; /* D3D 8 & 10 */
+ BYTE method;
+ BYTE usage;
+ BYTE usage_idx;
+};
+
+struct wined3d_device_creation_parameters
+{
+ UINT adapter_idx;
+ enum wined3d_device_type device_type;
+ HWND focus_window;
+ DWORD flags;
+};
+
+struct wined3d_raster_status
+{
+ BOOL in_vblank;
+ UINT scan_line;
+};
+
+struct wined3d_map_desc
+{
+ UINT row_pitch;
+ UINT slice_pitch;
+ void *data;
+};
+
+struct wined3d_box
+{
+ UINT left;
+ UINT top;
+ UINT right;
+ UINT bottom;
+ UINT front;
+ UINT back;
+};
+
+struct wined3d_vertex_shader_caps
+{
+ DWORD caps;
+ INT dynamic_flow_control_depth;
+ INT temp_count;
+ INT static_flow_control_depth;
+};
+
+struct wined3d_pixel_shader_caps
+{
+ DWORD caps;
+ INT dynamic_flow_control_depth;
+ INT temp_count;
+ INT static_flow_control_depth;
+ INT instruction_slot_count;
+};
+
+struct wined3d_ddraw_caps
+{
+ DWORD caps;
+ DWORD caps2;
+ DWORD color_key_caps;
+ DWORD fx_caps;
+ DWORD fx_alpha_caps;
+ DWORD pal_caps;
+ DWORD sv_caps;
+ DWORD svb_caps;
+ DWORD svb_color_key_caps;
+ DWORD svb_fx_caps;
+ DWORD vsb_caps;
+ DWORD vsb_color_key_caps;
+ DWORD vsb_fx_caps;
+ DWORD ssb_caps;
+ DWORD ssb_color_key_caps;
+ DWORD ssb_fx_caps;
+ DWORD dds_caps;
+ DWORD stride_align;
+};
+
+typedef struct _WINED3DCAPS
+{
+ enum wined3d_device_type DeviceType;
+ UINT AdapterOrdinal;
+
+ DWORD Caps;
+ DWORD Caps2;
+ DWORD Caps3;
+ DWORD PresentationIntervals;
+
+ DWORD CursorCaps;
+ DWORD DevCaps;
+ DWORD PrimitiveMiscCaps;
+ DWORD RasterCaps;
+ DWORD ZCmpCaps;
+ DWORD SrcBlendCaps;
+ DWORD DestBlendCaps;
+ DWORD AlphaCmpCaps;
+ DWORD ShadeCaps;
+ DWORD TextureCaps;
+ DWORD TextureFilterCaps;
+ DWORD CubeTextureFilterCaps;
+ DWORD VolumeTextureFilterCaps;
+ DWORD TextureAddressCaps;
+ DWORD VolumeTextureAddressCaps;
+ DWORD LineCaps;
+
+ DWORD MaxTextureWidth;
+ DWORD MaxTextureHeight;
+ DWORD MaxVolumeExtent;
+ DWORD MaxTextureRepeat;
+ DWORD MaxTextureAspectRatio;
+ DWORD MaxAnisotropy;
+ float MaxVertexW;
+
+ float GuardBandLeft;
+ float GuardBandTop;
+ float GuardBandRight;
+ float GuardBandBottom;
+
+ float ExtentsAdjust;
+ DWORD StencilCaps;
+
+ DWORD FVFCaps;
+ DWORD TextureOpCaps;
+ DWORD MaxTextureBlendStages;
+ DWORD MaxSimultaneousTextures;
+
+ DWORD VertexProcessingCaps;
+ DWORD MaxActiveLights;
+ DWORD MaxUserClipPlanes;
+ DWORD MaxVertexBlendMatrices;
+ DWORD MaxVertexBlendMatrixIndex;
+
+ float MaxPointSize;
+
+ DWORD MaxPrimitiveCount;
+ DWORD MaxVertexIndex;
+ DWORD MaxStreams;
+ DWORD MaxStreamStride;
+
+ DWORD VertexShaderVersion;
+ DWORD MaxVertexShaderConst;
+
+ DWORD PixelShaderVersion;
+ float PixelShader1xMaxValue;
+
+ /* DX 9 */
+ DWORD DevCaps2;
+
+ float MaxNpatchTessellationLevel;
+ DWORD Reserved5; /* undocumented */
+
+ UINT MasterAdapterOrdinal;
+ UINT AdapterOrdinalInGroup;
+ UINT NumberOfAdaptersInGroup;
+ DWORD DeclTypes;
+ DWORD NumSimultaneousRTs;
+ DWORD StretchRectFilterCaps;
+ struct wined3d_vertex_shader_caps VS20Caps;
+ struct wined3d_pixel_shader_caps PS20Caps;
+ DWORD VertexTextureFilterCaps;
+ DWORD MaxVShaderInstructionsExecuted;
+ DWORD MaxPShaderInstructionsExecuted;
+ DWORD MaxVertexShader30InstructionSlots;
+ DWORD MaxPixelShader30InstructionSlots;
+ DWORD Reserved2; /* Not in the microsoft headers but documented */
+ DWORD Reserved3;
+
+ struct wined3d_ddraw_caps ddraw_caps;
+} WINED3DCAPS;
+
+struct wined3d_color_key
+{
+ DWORD color_space_low_value; /* low boundary of color space that is to
+ * be treated as Color Key, inclusive */
+ DWORD color_space_high_value; /* high boundary of color space that is
+ * to be treated as Color Key, inclusive */
+};
+
+typedef struct _WINEDDBLTFX
+{
+ DWORD dwSize; /* size of structure */
+ DWORD dwDDFX; /* FX operations */
+ DWORD dwROP; /* Win32 raster operations */
+ DWORD dwDDROP; /* Raster operations new for DirectDraw */
+ DWORD dwRotationAngle; /* Rotation angle for blt */
+ DWORD dwZBufferOpCode; /* ZBuffer compares */
+ DWORD dwZBufferLow; /* Low limit of Z buffer */
+ DWORD dwZBufferHigh; /* High limit of Z buffer */
+ DWORD dwZBufferBaseDest; /* Destination base value */
+ DWORD dwZDestConstBitDepth; /* Bit depth used to specify Z constant for destination */
+ union
+ {
+ DWORD dwZDestConst; /* Constant to use as Z buffer for dest */
+ struct wined3d_surface *lpDDSZBufferDest; /* Surface to use as Z buffer for dest */
+ } DUMMYUNIONNAME1;
+ DWORD dwZSrcConstBitDepth; /* Bit depth used to specify Z constant for source */
+ union
+ {
+ DWORD dwZSrcConst; /* Constant to use as Z buffer for src */
+ struct wined3d_surface *lpDDSZBufferSrc; /* Surface to use as Z buffer for src */
+ } DUMMYUNIONNAME2;
+ DWORD dwAlphaEdgeBlendBitDepth; /* Bit depth used to specify constant for alpha edge blend */
+ DWORD dwAlphaEdgeBlend; /* Alpha for edge blending */
+ DWORD dwReserved;
+ DWORD dwAlphaDestConstBitDepth; /* Bit depth used to specify alpha constant for destination */
+ union
+ {
+ DWORD dwAlphaDestConst; /* Constant to use as Alpha Channel */
+ struct wined3d_surface *lpDDSAlphaDest; /* Surface to use as Alpha Channel */
+ } DUMMYUNIONNAME3;
+ DWORD dwAlphaSrcConstBitDepth; /* Bit depth used to specify alpha constant for source */
+ union
+ {
+ DWORD dwAlphaSrcConst; /* Constant to use as Alpha Channel */
+ struct wined3d_surface *lpDDSAlphaSrc; /* Surface to use as Alpha Channel */
+ } DUMMYUNIONNAME4;
+ union
+ {
+ DWORD dwFillColor; /* color in RGB or Palettized */
+ DWORD dwFillDepth; /* depth value for z-buffer */
+ DWORD dwFillPixel; /* pixel val for RGBA or RGBZ */
+ struct wined3d_surface *lpDDSPattern; /* Surface to use as pattern */
+ } DUMMYUNIONNAME5;
+ struct wined3d_color_key ddckDestColorkey; /* DestColorkey override */
+ struct wined3d_color_key ddckSrcColorkey; /* SrcColorkey override */
+} WINEDDBLTFX,*LPWINEDDBLTFX;
+
+typedef struct _WINEDDOVERLAYFX
+{
+ DWORD dwSize; /* size of structure */
+ DWORD dwAlphaEdgeBlendBitDepth; /* Bit depth used to specify constant for alpha edge blend */
+ DWORD dwAlphaEdgeBlend; /* Constant to use as alpha for edge blend */
+ DWORD dwReserved;
+ DWORD dwAlphaDestConstBitDepth; /* Bit depth used to specify alpha constant for destination */
+ union
+ {
+ DWORD dwAlphaDestConst; /* Constant to use as alpha channel for dest */
+ struct wined3d_surface *lpDDSAlphaDest; /* Surface to use as alpha channel for dest */
+ } DUMMYUNIONNAME1;
+ DWORD dwAlphaSrcConstBitDepth; /* Bit depth used to specify alpha constant for source */
+ union
+ {
+ DWORD dwAlphaSrcConst; /* Constant to use as alpha channel for src */
+ struct wined3d_surface *lpDDSAlphaSrc; /* Surface to use as alpha channel for src */
+ } DUMMYUNIONNAME2;
+ struct wined3d_color_key dckDestColorkey; /* DestColorkey override */
+ struct wined3d_color_key dckSrcColorkey; /* SrcColorkey override */
+ DWORD dwDDFX; /* Overlay FX */
+ DWORD dwFlags; /* flags */
+} WINEDDOVERLAYFX;
+
+struct wined3d_buffer_desc
+{
+ UINT byte_width;
+ DWORD usage;
+ UINT bind_flags;
+ UINT cpu_access_flags;
+ UINT misc_flags;
+};
+
+struct wined3d_shader_signature_element
+{
+ const char *semantic_name;
+ UINT semantic_idx;
+ enum wined3d_sysval_semantic sysval_semantic;
+ DWORD component_type;
+ UINT register_idx;
+ DWORD mask;
+};
+
+struct wined3d_shader_signature
+{
+ UINT element_count;
+ struct wined3d_shader_signature_element *elements;
+ char *string_data;
+};
+
+struct wined3d_parent_ops
+{
+ void (__stdcall *wined3d_object_destroyed)(void *parent);
+};
+
+struct wined3d;
+struct wined3d_buffer;
+struct wined3d_device;
+struct wined3d_palette;
+struct wined3d_query;
+struct wined3d_rendertarget_view;
+struct wined3d_resource;
+struct wined3d_sampler;
+struct wined3d_shader;
+struct wined3d_stateblock;
+struct wined3d_surface;
+struct wined3d_swapchain;
+struct wined3d_texture;
+struct wined3d_vertex_declaration;
+struct wined3d_volume;
+
+struct wined3d_device_parent
+{
+ const struct wined3d_device_parent_ops *ops;
+};
+
+struct wined3d_device_parent_ops
+{
+ void (__cdecl *wined3d_device_created)(struct wined3d_device_parent *device_parent, struct wined3d_device *device);
+ void (__cdecl *mode_changed)(struct wined3d_device_parent *device_parent);
+ HRESULT (__cdecl *create_swapchain_surface)(struct wined3d_device_parent *device_parent, void *container_parent,
+ const struct wined3d_resource_desc *desc, struct wined3d_surface **surface);
+ HRESULT (__cdecl *create_texture_surface)(struct wined3d_device_parent *device_parent, void *container_parent,
+ const struct wined3d_resource_desc *desc, UINT sub_resource_idx, DWORD flags,
+ struct wined3d_surface **surface
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void *pvClientMem
+#endif
+ );
+ HRESULT (__cdecl *create_volume)(struct wined3d_device_parent *device_parent, void *container_parent,
+ UINT width, UINT height, UINT depth, enum wined3d_format_id format_id, enum wined3d_pool pool, DWORD usage,
+ struct wined3d_volume **volume
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void *pvClientMem
+#endif
+ );
+ HRESULT (__cdecl *create_swapchain)(struct wined3d_device_parent *device_parent,
+ struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain);
+};
+
+typedef HRESULT (CDECL *wined3d_device_reset_cb)(struct wined3d_resource *resource);
+#ifndef VBOX_WITH_WDDM
+void __stdcall wined3d_mutex_lock(void);
+void __stdcall wined3d_mutex_unlock(void);
+#else
+#define wined3d_mutex_lock() do {} while (0)
+#define wined3d_mutex_unlock() do {} while (0)
+#endif
+
+HRESULT __cdecl wined3d_check_depth_stencil_match(const struct wined3d *wined3d, UINT adapter_idx,
+ enum wined3d_device_type device_type, enum wined3d_format_id adapter_format_id,
+ enum wined3d_format_id render_target_format_id, enum wined3d_format_id depth_stencil_format_id);
+HRESULT __cdecl wined3d_check_device_format(const struct wined3d *wined3d, UINT adaper_idx,
+ enum wined3d_device_type device_type, enum wined3d_format_id adapter_format_id, DWORD usage,
+ enum wined3d_resource_type resource_type, enum wined3d_format_id check_format_id);
+HRESULT __cdecl wined3d_check_device_format_conversion(const struct wined3d *wined3d, UINT adapter_idx,
+ enum wined3d_device_type device_type, enum wined3d_format_id source_format_id,
+ enum wined3d_format_id target_format_id);
+HRESULT __cdecl wined3d_check_device_multisample_type(const struct wined3d *wined3d, UINT adapter_idx,
+ enum wined3d_device_type device_type, enum wined3d_format_id surface_format_id, BOOL windowed,
+ enum wined3d_multisample_type multisample_type, DWORD *quality_levels);
+HRESULT __cdecl wined3d_check_device_type(const struct wined3d *wined3d, UINT adapter_idx,
+ enum wined3d_device_type device_type, enum wined3d_format_id display_format_id,
+ enum wined3d_format_id backbuffer_format_id, BOOL windowed);
+struct wined3d * __cdecl wined3d_create(UINT version, DWORD flags);
+ULONG __cdecl wined3d_decref(struct wined3d *wined3d);
+HRESULT __cdecl wined3d_enum_adapter_modes(const struct wined3d *wined3d, UINT adapter_idx,
+ enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering,
+ UINT mode_idx, struct wined3d_display_mode *mode);
+UINT __cdecl wined3d_get_adapter_count(const struct wined3d *wined3d);
+HRESULT __cdecl wined3d_get_adapter_display_mode(const struct wined3d *wined3d, UINT adapter_idx,
+ struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation);
+HRESULT __cdecl wined3d_get_adapter_identifier(const struct wined3d *wined3d, UINT adapter_idx,
+ DWORD flags, struct wined3d_adapter_identifier *identifier);
+UINT __cdecl wined3d_get_adapter_mode_count(const struct wined3d *wined3d, UINT adapter_idx,
+ enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering);
+HMONITOR __cdecl wined3d_get_adapter_monitor(const struct wined3d *wined3d, UINT adapter_idx);
+HRESULT __cdecl wined3d_get_adapter_raster_status(const struct wined3d *wined3d, UINT adapter_idx,
+ struct wined3d_raster_status *raster_status);
+HRESULT __cdecl wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapter_idx,
+ enum wined3d_device_type device_type, WINED3DCAPS *caps);
+ULONG __cdecl wined3d_incref(struct wined3d *wined3d);
+HRESULT __cdecl wined3d_register_software_device(struct wined3d *wined3d, void *init_function);
+HRESULT __cdecl wined3d_set_adapter_display_mode(struct wined3d *wined3d,
+ UINT adapter_idx, const struct wined3d_display_mode *mode);
+
+HRESULT __cdecl wined3d_buffer_create(struct wined3d_device *device, struct wined3d_buffer_desc *desc,
+ const void *data, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_buffer **buffer);
+HRESULT __cdecl wined3d_buffer_create_ib(struct wined3d_device *device, UINT length, DWORD usage,
+ enum wined3d_pool pool, void *parent, const struct wined3d_parent_ops *parent_ops,
+ struct wined3d_buffer **buffer);
+HRESULT __cdecl wined3d_buffer_create_vb(struct wined3d_device *device, UINT length, DWORD usage,
+ enum wined3d_pool pool, void *parent, const struct wined3d_parent_ops *parent_ops,
+ struct wined3d_buffer **buffer);
+ULONG __cdecl wined3d_buffer_decref(struct wined3d_buffer *buffer);
+void * __cdecl wined3d_buffer_get_parent(const struct wined3d_buffer *buffer);
+DWORD __cdecl wined3d_buffer_get_priority(const struct wined3d_buffer *buffer);
+struct wined3d_resource * __cdecl wined3d_buffer_get_resource(struct wined3d_buffer *buffer);
+ULONG __cdecl wined3d_buffer_incref(struct wined3d_buffer *buffer);
+HRESULT __cdecl wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UINT size, BYTE **data, DWORD flags);
+void __cdecl wined3d_buffer_preload(struct wined3d_buffer *buffer);
+DWORD __cdecl wined3d_buffer_set_priority(struct wined3d_buffer *buffer, DWORD new_priority);
+void __cdecl wined3d_buffer_unmap(struct wined3d_buffer *buffer);
+
+HRESULT __cdecl wined3d_device_acquire_focus_window(struct wined3d_device *device, HWND window);
+HRESULT __cdecl wined3d_device_begin_scene(struct wined3d_device *device);
+HRESULT __cdecl wined3d_device_begin_stateblock(struct wined3d_device *device);
+HRESULT __cdecl wined3d_device_clear(struct wined3d_device *device, DWORD rect_count, const RECT *rects, DWORD flags,
+ const struct wined3d_color *color, float z, DWORD stencil);
+void __cdecl wined3d_device_clear_rendertarget_view(struct wined3d_device *device,
+ struct wined3d_rendertarget_view *rendertarget_view, const struct wined3d_color *color);
+HRESULT __cdecl wined3d_device_color_fill(struct wined3d_device *device, struct wined3d_surface *surface,
+ const RECT *rect, const struct wined3d_color *color);
+HRESULT __cdecl wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx,
+ enum wined3d_device_type device_type, HWND focus_window, DWORD behaviour_flags, BYTE surface_alignment,
+ struct wined3d_device_parent *device_parent, struct wined3d_device **device);
+ULONG __cdecl wined3d_device_decref(struct wined3d_device *device);
+HRESULT __cdecl wined3d_device_draw_indexed_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count);
+void __cdecl wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device *device,
+ UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count);
+HRESULT __cdecl wined3d_device_draw_primitive(struct wined3d_device *device, UINT start_vertex, UINT vertex_count);
+HRESULT __cdecl wined3d_device_end_scene(struct wined3d_device *device);
+HRESULT __cdecl wined3d_device_end_stateblock(struct wined3d_device *device, struct wined3d_stateblock **stateblock);
+void __cdecl wined3d_device_evict_managed_resources(struct wined3d_device *device);
+UINT __cdecl wined3d_device_get_available_texture_mem(const struct wined3d_device *device);
+HRESULT __cdecl wined3d_device_get_back_buffer(const struct wined3d_device *device, UINT swapchain_idx,
+ UINT backbuffer_idx, enum wined3d_backbuffer_type backbuffer_type, struct wined3d_surface **backbuffer);
+INT __cdecl wined3d_device_get_base_vertex_index(const struct wined3d_device *device);
+HRESULT __cdecl wined3d_device_get_clip_plane(const struct wined3d_device *device,
+ UINT plane_idx, struct wined3d_vec4 *plane);
+HRESULT __cdecl wined3d_device_get_clip_status(const struct wined3d_device *device,
+ struct wined3d_clip_status *clip_status);
+void __cdecl wined3d_device_get_creation_parameters(const struct wined3d_device *device,
+ struct wined3d_device_creation_parameters *creation_parameters);
+struct wined3d_surface * __cdecl wined3d_device_get_depth_stencil(const struct wined3d_device *device);
+HRESULT __cdecl wined3d_device_get_device_caps(const struct wined3d_device *device, WINED3DCAPS *caps);
+HRESULT __cdecl wined3d_device_get_display_mode(const struct wined3d_device *device, UINT swapchain_idx,
+ struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation);
+HRESULT __cdecl wined3d_device_get_front_buffer_data(const struct wined3d_device *device,
+ UINT swapchain_idx, struct wined3d_surface *dst_surface);
+void __cdecl wined3d_device_get_gamma_ramp(const struct wined3d_device *device,
+ UINT swapchain_idx, struct wined3d_gamma_ramp *ramp);
+struct wined3d_shader * __cdecl wined3d_device_get_geometry_shader(const struct wined3d_device *device);
+struct wined3d_buffer * __cdecl wined3d_device_get_gs_cb(const struct wined3d_device *device, UINT idx);
+struct wined3d_sampler * __cdecl wined3d_device_get_gs_sampler(const struct wined3d_device *device, UINT idx);
+struct wined3d_buffer * __cdecl wined3d_device_get_index_buffer(const struct wined3d_device *device,
+ enum wined3d_format_id *format);
+HRESULT __cdecl wined3d_device_get_light(const struct wined3d_device *device,
+ UINT light_idx, struct wined3d_light *light);
+HRESULT __cdecl wined3d_device_get_light_enable(const struct wined3d_device *device, UINT light_idx, BOOL *enable);
+void __cdecl wined3d_device_get_material(const struct wined3d_device *device, struct wined3d_material *material);
+float __cdecl wined3d_device_get_npatch_mode(const struct wined3d_device *device);
+struct wined3d_shader * __cdecl wined3d_device_get_pixel_shader(const struct wined3d_device *device);
+void __cdecl wined3d_device_get_primitive_type(const struct wined3d_device *device,
+ enum wined3d_primitive_type *primitive_topology);
+struct wined3d_buffer * __cdecl wined3d_device_get_ps_cb(const struct wined3d_device *device, UINT idx);
+HRESULT __cdecl wined3d_device_get_ps_consts_b(const struct wined3d_device *device,
+ UINT start_register, BOOL *constants, UINT bool_count);
+HRESULT __cdecl wined3d_device_get_ps_consts_f(const struct wined3d_device *device,
+ UINT start_register, float *constants, UINT vector4f_count);
+HRESULT __cdecl wined3d_device_get_ps_consts_i(const struct wined3d_device *device,
+ UINT start_register, int *constants, UINT vector4i_count);
+struct wined3d_sampler * __cdecl wined3d_device_get_ps_sampler(const struct wined3d_device *device, UINT idx);
+HRESULT __cdecl wined3d_device_get_raster_status(const struct wined3d_device *device,
+ UINT swapchain_idx, struct wined3d_raster_status *raster_status);
+DWORD __cdecl wined3d_device_get_render_state(const struct wined3d_device *device, enum wined3d_render_state state);
+struct wined3d_surface * __cdecl wined3d_device_get_render_target(const struct wined3d_device *device,
+ UINT render_target_idx);
+DWORD __cdecl wined3d_device_get_sampler_state(const struct wined3d_device *device,
+ UINT sampler_idx, enum wined3d_sampler_state state);
+void __cdecl wined3d_device_get_scissor_rect(const struct wined3d_device *device, RECT *rect);
+BOOL __cdecl wined3d_device_get_software_vertex_processing(const struct wined3d_device *device);
+struct wined3d_buffer * __cdecl wined3d_device_get_stream_output(struct wined3d_device *device,
+ UINT idx, UINT *offset);
+HRESULT __cdecl wined3d_device_get_stream_source(const struct wined3d_device *device,
+ UINT stream_idx, struct wined3d_buffer **buffer, UINT *offset, UINT *stride);
+HRESULT __cdecl wined3d_device_get_stream_source_freq(const struct wined3d_device *device,
+ UINT stream_idx, UINT *divider);
+struct wined3d_surface * __cdecl wined3d_device_get_surface_from_dc(const struct wined3d_device *device, HDC dc);
+struct wined3d_swapchain * __cdecl wined3d_device_get_swapchain(const struct wined3d_device *device,
+ UINT swapchain_idx);
+UINT __cdecl wined3d_device_get_swapchain_count(const struct wined3d_device *device);
+struct wined3d_texture * __cdecl wined3d_device_get_texture(const struct wined3d_device *device, UINT stage);
+DWORD __cdecl wined3d_device_get_texture_stage_state(const struct wined3d_device *device,
+ UINT stage, enum wined3d_texture_stage_state state);
+void __cdecl wined3d_device_get_transform(const struct wined3d_device *device,
+ enum wined3d_transform_state state, struct wined3d_matrix *matrix);
+struct wined3d_vertex_declaration * __cdecl wined3d_device_get_vertex_declaration(const struct wined3d_device *device);
+struct wined3d_shader * __cdecl wined3d_device_get_vertex_shader(const struct wined3d_device *device);
+void __cdecl wined3d_device_get_viewport(const struct wined3d_device *device, struct wined3d_viewport *viewport);
+struct wined3d_buffer * __cdecl wined3d_device_get_vs_cb(const struct wined3d_device *device, UINT idx);
+HRESULT __cdecl wined3d_device_get_vs_consts_b(const struct wined3d_device *device,
+ UINT start_register, BOOL *constants, UINT bool_count);
+HRESULT __cdecl wined3d_device_get_vs_consts_f(const struct wined3d_device *device,
+ UINT start_register, float *constants, UINT vector4f_count);
+HRESULT __cdecl wined3d_device_get_vs_consts_i(const struct wined3d_device *device,
+ UINT start_register, int *constants, UINT vector4i_count);
+struct wined3d_sampler * __cdecl wined3d_device_get_vs_sampler(const struct wined3d_device *device, UINT idx);
+ULONG __cdecl wined3d_device_incref(struct wined3d_device *device);
+HRESULT __cdecl wined3d_device_init_3d(struct wined3d_device *device, struct wined3d_swapchain_desc *swapchain_desc);
+HRESULT __cdecl wined3d_device_init_gdi(struct wined3d_device *device, struct wined3d_swapchain_desc *swapchain_desc);
+void __cdecl wined3d_device_multiply_transform(struct wined3d_device *device,
+ enum wined3d_transform_state state, const struct wined3d_matrix *matrix);
+HRESULT __cdecl wined3d_device_present(const struct wined3d_device *device, const RECT *src_rect,
+ const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region, DWORD flags);
+HRESULT __cdecl wined3d_device_process_vertices(struct wined3d_device *device,
+ UINT src_start_idx, UINT dst_idx, UINT vertex_count, struct wined3d_buffer *dst_buffer,
+ const struct wined3d_vertex_declaration *declaration, DWORD flags, DWORD dst_fvf);
+void __cdecl wined3d_device_release_focus_window(struct wined3d_device *device);
+HRESULT __cdecl wined3d_device_reset(struct wined3d_device *device,
+ const struct wined3d_swapchain_desc *swapchain_desc, const struct wined3d_display_mode *mode,
+ wined3d_device_reset_cb callback, BOOL reset_state);
+void __cdecl wined3d_device_restore_fullscreen_window(struct wined3d_device *device, HWND window);
+void __cdecl wined3d_device_set_base_vertex_index(struct wined3d_device *device, INT base_index);
+HRESULT __cdecl wined3d_device_set_clip_plane(struct wined3d_device *device,
+ UINT plane_idx, const struct wined3d_vec4 *plane);
+HRESULT __cdecl wined3d_device_set_clip_status(struct wined3d_device *device,
+ const struct wined3d_clip_status *clip_status);
+void __cdecl wined3d_device_set_cursor_position(struct wined3d_device *device,
+ int x_screen_space, int y_screen_space, DWORD flags);
+HRESULT __cdecl wined3d_device_set_cursor_properties(struct wined3d_device *device,
+ UINT x_hotspot, UINT y_hotspot, struct wined3d_surface *cursor_surface);
+void __cdecl wined3d_device_set_depth_stencil(struct wined3d_device *device, struct wined3d_surface *depth_stencil);
+HRESULT __cdecl wined3d_device_set_dialog_box_mode(struct wined3d_device *device, BOOL enable_dialogs);
+void __cdecl wined3d_device_set_gamma_ramp(const struct wined3d_device *device,
+ UINT swapchain_idx, DWORD flags, const struct wined3d_gamma_ramp *ramp);
+void __cdecl wined3d_device_set_geometry_shader(struct wined3d_device *device, struct wined3d_shader *shader);
+void __cdecl wined3d_device_set_gs_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer);
+void __cdecl wined3d_device_set_gs_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler);
+void __cdecl wined3d_device_set_index_buffer(struct wined3d_device *device,
+ struct wined3d_buffer *index_buffer, enum wined3d_format_id format_id);
+HRESULT __cdecl wined3d_device_set_light(struct wined3d_device *device,
+ UINT light_idx, const struct wined3d_light *light);
+HRESULT __cdecl wined3d_device_set_light_enable(struct wined3d_device *device, UINT light_idx, BOOL enable);
+void __cdecl wined3d_device_set_material(struct wined3d_device *device, const struct wined3d_material *material);
+void __cdecl wined3d_device_set_multithreaded(struct wined3d_device *device);
+HRESULT __cdecl wined3d_device_set_npatch_mode(struct wined3d_device *device, float segments);
+void __cdecl wined3d_device_set_pixel_shader(struct wined3d_device *device, struct wined3d_shader *shader);
+void __cdecl wined3d_device_set_primitive_type(struct wined3d_device *device,
+ enum wined3d_primitive_type primitive_topology);
+void __cdecl wined3d_device_set_ps_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer);
+HRESULT __cdecl wined3d_device_set_ps_consts_b(struct wined3d_device *device,
+ UINT start_register, const BOOL *constants, UINT bool_count);
+HRESULT __cdecl wined3d_device_set_ps_consts_f(struct wined3d_device *device,
+ UINT start_register, const float *constants, UINT vector4f_count);
+HRESULT __cdecl wined3d_device_set_ps_consts_i(struct wined3d_device *device,
+ UINT start_register, const int *constants, UINT vector4i_count);
+void __cdecl wined3d_device_set_ps_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler);
+void __cdecl wined3d_device_set_render_state(struct wined3d_device *device,
+ enum wined3d_render_state state, DWORD value);
+HRESULT __cdecl wined3d_device_set_render_target(struct wined3d_device *device,
+ UINT render_target_idx, struct wined3d_surface *render_target, BOOL set_viewport);
+void __cdecl wined3d_device_set_sampler_state(struct wined3d_device *device,
+ UINT sampler_idx, enum wined3d_sampler_state state, DWORD value);
+void __cdecl wined3d_device_set_scissor_rect(struct wined3d_device *device, const RECT *rect);
+void __cdecl wined3d_device_set_software_vertex_processing(struct wined3d_device *device, BOOL software);
+void __cdecl wined3d_device_set_stream_output(struct wined3d_device *device, UINT idx,
+ struct wined3d_buffer *buffer, UINT offset);
+HRESULT __cdecl wined3d_device_set_stream_source(struct wined3d_device *device,
+ UINT stream_idx, struct wined3d_buffer *buffer, UINT offset, UINT stride);
+HRESULT __cdecl wined3d_device_set_stream_source_freq(struct wined3d_device *device, UINT stream_idx, UINT divider);
+HRESULT __cdecl wined3d_device_set_texture(struct wined3d_device *device, UINT stage, struct wined3d_texture *texture);
+void __cdecl wined3d_device_set_texture_stage_state(struct wined3d_device *device,
+ UINT stage, enum wined3d_texture_stage_state state, DWORD value);
+void __cdecl wined3d_device_set_transform(struct wined3d_device *device,
+ enum wined3d_transform_state state, const struct wined3d_matrix *matrix);
+void __cdecl wined3d_device_set_vertex_declaration(struct wined3d_device *device,
+ struct wined3d_vertex_declaration *declaration);
+void __cdecl wined3d_device_set_vertex_shader(struct wined3d_device *device, struct wined3d_shader *shader);
+void __cdecl wined3d_device_set_viewport(struct wined3d_device *device, const struct wined3d_viewport *viewport);
+void __cdecl wined3d_device_set_vs_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer);
+HRESULT __cdecl wined3d_device_set_vs_consts_b(struct wined3d_device *device,
+ UINT start_register, const BOOL *constants, UINT bool_count);
+HRESULT __cdecl wined3d_device_set_vs_consts_f(struct wined3d_device *device,
+ UINT start_register, const float *constants, UINT vector4f_count);
+HRESULT __cdecl wined3d_device_set_vs_consts_i(struct wined3d_device *device,
+ UINT start_register, const int *constants, UINT vector4i_count);
+void __cdecl wined3d_device_set_vs_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler);
+void __cdecl wined3d_device_setup_fullscreen_window(struct wined3d_device *device, HWND window, UINT w, UINT h);
+BOOL __cdecl wined3d_device_show_cursor(struct wined3d_device *device, BOOL show);
+HRESULT __cdecl wined3d_device_uninit_3d(struct wined3d_device *device);
+HRESULT __cdecl wined3d_device_uninit_gdi(struct wined3d_device *device);
+HRESULT __cdecl wined3d_device_update_surface(struct wined3d_device *device, struct wined3d_surface *src_surface,
+ const RECT *src_rect, struct wined3d_surface *dst_surface, const POINT *dst_point);
+HRESULT __cdecl wined3d_device_update_texture(struct wined3d_device *device,
+ struct wined3d_texture *src_texture, struct wined3d_texture *dst_texture);
+HRESULT __cdecl wined3d_device_validate_device(const struct wined3d_device *device, DWORD *num_passes);
+
+HRESULT __cdecl wined3d_palette_create(struct wined3d_device *device, DWORD flags,
+ const PALETTEENTRY *entries, void *parent, struct wined3d_palette **palette);
+ULONG __cdecl wined3d_palette_decref(struct wined3d_palette *palette);
+HRESULT __cdecl wined3d_palette_get_entries(const struct wined3d_palette *palette,
+ DWORD flags, DWORD start, DWORD count, PALETTEENTRY *entries);
+DWORD __cdecl wined3d_palette_get_flags(const struct wined3d_palette *palette);
+void * __cdecl wined3d_palette_get_parent(const struct wined3d_palette *palette);
+ULONG __cdecl wined3d_palette_incref(struct wined3d_palette *palette);
+HRESULT __cdecl wined3d_palette_set_entries(struct wined3d_palette *palette,
+ DWORD flags, DWORD start, DWORD count, const PALETTEENTRY *entries);
+
+HRESULT __cdecl wined3d_query_create(struct wined3d_device *device,
+ enum wined3d_query_type type, struct wined3d_query **query);
+ULONG __cdecl wined3d_query_decref(struct wined3d_query *query);
+HRESULT __cdecl wined3d_query_get_data(struct wined3d_query *query, void *data, UINT data_size, DWORD flags);
+UINT __cdecl wined3d_query_get_data_size(const struct wined3d_query *query);
+enum wined3d_query_type __cdecl wined3d_query_get_type(const struct wined3d_query *query);
+ULONG __cdecl wined3d_query_incref(struct wined3d_query *query);
+HRESULT __cdecl wined3d_query_issue(struct wined3d_query *query, DWORD flags);
+
+HRESULT __cdecl wined3d_resource_free_private_data(struct wined3d_resource *resource, REFGUID guid);
+void __cdecl wined3d_resource_get_desc(const struct wined3d_resource *resource,
+ struct wined3d_resource_desc *desc);
+void * __cdecl wined3d_resource_get_parent(const struct wined3d_resource *resource);
+HRESULT __cdecl wined3d_resource_get_private_data(const struct wined3d_resource *resource,
+ REFGUID guid, void *data, DWORD *data_size);
+HRESULT __cdecl wined3d_resource_set_private_data(struct wined3d_resource *resource,
+ REFGUID guid, const void *data, DWORD data_size, DWORD flags);
+
+HRESULT __cdecl wined3d_rendertarget_view_create(struct wined3d_resource *resource,
+ void *parent, struct wined3d_rendertarget_view **rendertarget_view);
+ULONG __cdecl wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *view);
+void * __cdecl wined3d_rendertarget_view_get_parent(const struct wined3d_rendertarget_view *view);
+struct wined3d_resource * __cdecl wined3d_rendertarget_view_get_resource(const struct wined3d_rendertarget_view *view);
+ULONG __cdecl wined3d_rendertarget_view_incref(struct wined3d_rendertarget_view *view);
+
+HRESULT __cdecl wined3d_sampler_create(void *parent, struct wined3d_sampler **sampler);
+ULONG __cdecl wined3d_sampler_decref(struct wined3d_sampler *sampler);
+void * __cdecl wined3d_sampler_get_parent(const struct wined3d_sampler *sampler);
+ULONG __cdecl wined3d_sampler_incref(struct wined3d_sampler *sampler);
+
+HRESULT __cdecl wined3d_shader_create_gs(struct wined3d_device *device, const DWORD *byte_code,
+ const struct wined3d_shader_signature *output_signature, void *parent,
+ const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version);
+HRESULT __cdecl wined3d_shader_create_ps(struct wined3d_device *device, const DWORD *byte_code,
+ const struct wined3d_shader_signature *output_signature, void *parent,
+ const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version);
+HRESULT __cdecl wined3d_shader_create_vs(struct wined3d_device *device, const DWORD *byte_code,
+ const struct wined3d_shader_signature *output_signature, void *parent,
+ const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version);
+ULONG __cdecl wined3d_shader_decref(struct wined3d_shader *shader);
+HRESULT __cdecl wined3d_shader_get_byte_code(const struct wined3d_shader *shader,
+ void *byte_code, UINT *byte_code_size);
+void * __cdecl wined3d_shader_get_parent(const struct wined3d_shader *shader);
+ULONG __cdecl wined3d_shader_incref(struct wined3d_shader *shader);
+HRESULT __cdecl wined3d_shader_set_local_constants_float(struct wined3d_shader *shader,
+ UINT start_idx, const float *src_data, UINT vector4f_count);
+
+void __cdecl wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock);
+void __cdecl wined3d_stateblock_capture(struct wined3d_stateblock *stateblock);
+HRESULT __cdecl wined3d_stateblock_create(struct wined3d_device *device,
+ enum wined3d_stateblock_type type, struct wined3d_stateblock **stateblock);
+ULONG __cdecl wined3d_stateblock_decref(struct wined3d_stateblock *stateblock);
+ULONG __cdecl wined3d_stateblock_incref(struct wined3d_stateblock *stateblock);
+
+HRESULT __cdecl wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect,
+ struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags,
+ const WINEDDBLTFX *blt_fx, enum wined3d_texture_filter_type filter);
+HRESULT __cdecl wined3d_surface_create(struct wined3d_device *device, UINT width, UINT height,
+ enum wined3d_format_id format_id, DWORD usage, enum wined3d_pool pool,
+ enum wined3d_multisample_type multisample_type, DWORD multisample_quality, DWORD flags,
+ void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_surface **surface
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void *pvClientMem
+#endif
+ );
+ULONG __cdecl wined3d_surface_decref(struct wined3d_surface *surface);
+HRESULT __cdecl wined3d_surface_flip(struct wined3d_surface *surface, struct wined3d_surface *override, DWORD flags);
+struct wined3d_surface * __cdecl wined3d_surface_from_resource(struct wined3d_resource *resource);
+HRESULT __cdecl wined3d_surface_get_blt_status(const struct wined3d_surface *surface, DWORD flags);
+HRESULT __cdecl wined3d_surface_get_flip_status(const struct wined3d_surface *surface, DWORD flags);
+HRESULT __cdecl wined3d_surface_get_overlay_position(const struct wined3d_surface *surface, LONG *x, LONG *y);
+struct wined3d_palette * __cdecl wined3d_surface_get_palette(const struct wined3d_surface *surface);
+void * __cdecl wined3d_surface_get_parent(const struct wined3d_surface *surface);
+DWORD __cdecl wined3d_surface_get_pitch(const struct wined3d_surface *surface);
+DWORD __cdecl wined3d_surface_get_priority(const struct wined3d_surface *surface);
+HRESULT __cdecl wined3d_surface_get_render_target_data(struct wined3d_surface *surface,
+ struct wined3d_surface *render_target);
+struct wined3d_resource * __cdecl wined3d_surface_get_resource(struct wined3d_surface *surface);
+HRESULT __cdecl wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc);
+ULONG __cdecl wined3d_surface_incref(struct wined3d_surface *surface);
+HRESULT __cdecl wined3d_surface_is_lost(const struct wined3d_surface *surface);
+HRESULT __cdecl wined3d_surface_map(struct wined3d_surface *surface,
+ struct wined3d_map_desc *map_desc, const RECT *rect, DWORD flags);
+void __cdecl wined3d_surface_preload(struct wined3d_surface *surface);
+HRESULT __cdecl wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc);
+HRESULT __cdecl wined3d_surface_restore(struct wined3d_surface *surface);
+HRESULT __cdecl wined3d_surface_set_color_key(struct wined3d_surface *surface,
+ DWORD flags, const struct wined3d_color_key *color_key);
+HRESULT __cdecl wined3d_surface_set_mem(struct wined3d_surface *surface, void *mem, UINT pitch);
+HRESULT __cdecl wined3d_surface_set_overlay_position(struct wined3d_surface *surface, LONG x, LONG y);
+void __cdecl wined3d_surface_set_palette(struct wined3d_surface *surface, struct wined3d_palette *palette);
+DWORD __cdecl wined3d_surface_set_priority(struct wined3d_surface *surface, DWORD new_priority);
+HRESULT __cdecl wined3d_surface_unmap(struct wined3d_surface *surface);
+HRESULT __cdecl wined3d_surface_update_desc(struct wined3d_surface *surface,
+ UINT width, UINT height, enum wined3d_format_id format_id,
+ enum wined3d_multisample_type multisample_type, UINT multisample_quality);
+HRESULT __cdecl wined3d_surface_update_overlay(struct wined3d_surface *surface, const RECT *src_rect,
+ struct wined3d_surface *dst_surface, const RECT *dst_rect, DWORD flags, const WINEDDOVERLAYFX *fx);
+HRESULT __cdecl wined3d_surface_update_overlay_z_order(struct wined3d_surface *surface,
+ DWORD flags, struct wined3d_surface *ref);
+
+HRESULT __cdecl wined3d_swapchain_create(struct wined3d_device *device, struct wined3d_swapchain_desc *desc,
+ void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain);
+ULONG __cdecl wined3d_swapchain_decref(struct wined3d_swapchain *swapchain);
+struct wined3d_surface * __cdecl wined3d_swapchain_get_back_buffer(const struct wined3d_swapchain *swapchain,
+ UINT backbuffer_idx, enum wined3d_backbuffer_type backbuffer_type);
+struct wined3d_device * __cdecl wined3d_swapchain_get_device(const struct wined3d_swapchain *swapchain);
+HRESULT __cdecl wined3d_swapchain_get_display_mode(const struct wined3d_swapchain *swapchain,
+ struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation);
+HRESULT __cdecl wined3d_swapchain_get_front_buffer_data(const struct wined3d_swapchain *swapchain,
+ struct wined3d_surface *dst_surface);
+HRESULT __cdecl wined3d_swapchain_get_gamma_ramp(const struct wined3d_swapchain *swapchain,
+ struct wined3d_gamma_ramp *ramp);
+void * __cdecl wined3d_swapchain_get_parent(const struct wined3d_swapchain *swapchain);
+void __cdecl wined3d_swapchain_get_desc(const struct wined3d_swapchain *swapchain,
+ struct wined3d_swapchain_desc *desc);
+HRESULT __cdecl wined3d_swapchain_get_raster_status(const struct wined3d_swapchain *swapchain,
+ struct wined3d_raster_status *raster_status);
+ULONG __cdecl wined3d_swapchain_incref(struct wined3d_swapchain *swapchain);
+HRESULT __cdecl wined3d_swapchain_present(struct wined3d_swapchain *swapchain,
+ const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
+ const RGNDATA *dirty_region, DWORD flags);
+HRESULT __cdecl wined3d_swapchain_set_gamma_ramp(const struct wined3d_swapchain *swapchain,
+ DWORD flags, const struct wined3d_gamma_ramp *ramp);
+void __cdecl wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, HWND window);
+
+HRESULT __cdecl wined3d_texture_add_dirty_region(struct wined3d_texture *texture,
+ UINT layer, const struct wined3d_box *dirty_region);
+HRESULT __cdecl wined3d_texture_create_2d(struct wined3d_device *device, const struct wined3d_resource_desc *desc,
+ UINT level_count, DWORD surface_flags, void *parent, const struct wined3d_parent_ops *parent_ops,
+ struct wined3d_texture **texture
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void **pavClientMem
+#endif
+ );
+HRESULT __cdecl wined3d_texture_create_3d(struct wined3d_device *device, const struct wined3d_resource_desc *desc,
+ UINT level_count, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void **pavClientMem
+#endif
+ );
+HRESULT __cdecl wined3d_texture_create_cube(struct wined3d_device *device, const struct wined3d_resource_desc *desc,
+ UINT level_count, DWORD surface_flags, void *parent, const struct wined3d_parent_ops *parent_ops,
+ struct wined3d_texture **texture
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void **pavClientMem
+#endif
+ );
+ULONG __cdecl wined3d_texture_decref(struct wined3d_texture *texture);
+void __cdecl wined3d_texture_generate_mipmaps(struct wined3d_texture *texture);
+enum wined3d_texture_filter_type __cdecl wined3d_texture_get_autogen_filter_type(const struct wined3d_texture *texture);
+DWORD __cdecl wined3d_texture_get_level_count(const struct wined3d_texture *texture);
+DWORD __cdecl wined3d_texture_get_lod(const struct wined3d_texture *texture);
+void * __cdecl wined3d_texture_get_parent(const struct wined3d_texture *texture);
+DWORD __cdecl wined3d_texture_get_priority(const struct wined3d_texture *texture);
+struct wined3d_resource * __cdecl wined3d_texture_get_resource(struct wined3d_texture *texture);
+struct wined3d_resource * __cdecl wined3d_texture_get_sub_resource(struct wined3d_texture *texture,
+ UINT sub_resource_idx);
+ULONG __cdecl wined3d_texture_incref(struct wined3d_texture *texture);
+void __cdecl wined3d_texture_preload(struct wined3d_texture *texture);
+HRESULT __cdecl wined3d_texture_set_autogen_filter_type(struct wined3d_texture *texture,
+ enum wined3d_texture_filter_type filter_type);
+DWORD __cdecl wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod);
+DWORD __cdecl wined3d_texture_set_priority(struct wined3d_texture *texture, DWORD priority);
+
+HRESULT __cdecl wined3d_vertex_declaration_create(struct wined3d_device *device,
+ const struct wined3d_vertex_element *elements, UINT element_count, void *parent,
+ const struct wined3d_parent_ops *parent_ops, struct wined3d_vertex_declaration **declaration);
+HRESULT __cdecl wined3d_vertex_declaration_create_from_fvf(struct wined3d_device *device,
+ DWORD fvf, void *parent, const struct wined3d_parent_ops *parent_ops,
+ struct wined3d_vertex_declaration **declaration);
+ULONG __cdecl wined3d_vertex_declaration_decref(struct wined3d_vertex_declaration *declaration);
+void * __cdecl wined3d_vertex_declaration_get_parent(const struct wined3d_vertex_declaration *declaration);
+ULONG __cdecl wined3d_vertex_declaration_incref(struct wined3d_vertex_declaration *declaration);
+
+HRESULT __cdecl wined3d_volume_create(struct wined3d_device *device, UINT width, UINT height, UINT depth,
+ DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool, void *parent,
+ const struct wined3d_parent_ops *parent_ops, struct wined3d_volume **volume
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void *pvClientMem
+#endif
+ );
+ULONG __cdecl wined3d_volume_decref(struct wined3d_volume *volume);
+struct wined3d_volume * __cdecl wined3d_volume_from_resource(struct wined3d_resource *resource);
+void * __cdecl wined3d_volume_get_parent(const struct wined3d_volume *volume);
+DWORD __cdecl wined3d_volume_get_priority(const struct wined3d_volume *volume);
+struct wined3d_resource * __cdecl wined3d_volume_get_resource(struct wined3d_volume *volume);
+ULONG __cdecl wined3d_volume_incref(struct wined3d_volume *volume);
+HRESULT __cdecl wined3d_volume_map(struct wined3d_volume *volume,
+ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags);
+void __cdecl wined3d_volume_preload(struct wined3d_volume *volume);
+DWORD __cdecl wined3d_volume_set_priority(struct wined3d_volume *volume, DWORD new_priority);
+HRESULT __cdecl wined3d_volume_unmap(struct wined3d_volume *volume);
+
+#ifdef VBOX_WITH_WDDM
+HRESULT __cdecl wined3d_device_flush(struct wined3d_device *device);
+HRESULT __cdecl wined3d_device_flush_to_host(struct wined3d_device *device);
+HRESULT __cdecl wined3d_device_finish(struct wined3d_device *device);
+HRESULT __cdecl wined3d_device_blt_vol(struct wined3d_device *device, struct wined3d_volume *src, struct wined3d_volume *dst, const struct wined3d_box *pSrcBoxArg, const struct VBOXPOINT3D *pDstPoin3D);
+HRESULT __cdecl wined3d_device_blt_voltex(struct wined3d_device *device, struct wined3d_texture *src, struct wined3d_texture *dst, const struct wined3d_box *pSrcBoxArg, const struct VBOXPOINT3D *pDstPoin3D);
+HRESULT __cdecl wined3d_device_get_host_id(struct wined3d_device *device, int32_t *pid);
+
+HRESULT __cdecl wined3d_surface_get_host_id(struct wined3d_surface *surface, uint32_t *id);
+HRESULT __cdecl wined3d_surface_sync_to_host(struct wined3d_surface *surface);
+
+HRESULT __cdecl wined3d_swapchain_present_rt(struct wined3d_swapchain *swapchain, struct wined3d_surface *rt);
+HRESULT __cdecl wined3d_swapchain_get_host_win_id(struct wined3d_swapchain *swapchain, int32_t *pi32Id);
+#endif
+
+#endif /* __WINE_WINED3D_H */
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/Makefile.kup b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/Makefile.kup
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/arb_program_shader.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/arb_program_shader.c
new file mode 100644
index 00000000..b7a09a61
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/arb_program_shader.c
@@ -0,0 +1,7523 @@
+/*
+ * Pixel and vertex shaders implementation using ARB_vertex_program
+ * and ARB_fragment_program GL extensions.
+ *
+ * Copyright 2002-2003 Jason Edmeades
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2004 Christian Costa
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2006 Ivan Gyurdiev
+ * Copyright 2006 Jason Green
+ * Copyright 2006 Henri Verbeet
+ * Copyright 2007-2011, 2013 Stefan Dösinger for CodeWeavers
+ * Copyright 2009 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <math.h>
+#include <stdio.h>
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_constants);
+WINE_DECLARE_DEBUG_CHANNEL(d3d);
+
+/* sRGB correction constants */
+static const float srgb_cmp = 0.0031308f;
+static const float srgb_mul_low = 12.92f;
+static const float srgb_pow = 0.41666f;
+static const float srgb_mul_high = 1.055f;
+static const float srgb_sub_high = 0.055f;
+
+static BOOL shader_is_pshader_version(enum wined3d_shader_type type)
+{
+ return type == WINED3D_SHADER_TYPE_PIXEL;
+}
+
+static BOOL shader_is_vshader_version(enum wined3d_shader_type type)
+{
+ return type == WINED3D_SHADER_TYPE_VERTEX;
+}
+
+/* Extract a line. Note that this modifies the source string. */
+static char *get_line(char **ptr)
+{
+ char *p, *q;
+
+ p = *ptr;
+ if (!(q = strstr(p, "\n")))
+ {
+ if (!*p) return NULL;
+ *ptr += strlen(p);
+ return p;
+ }
+ *q = '\0';
+ *ptr = q + 1;
+
+ return p;
+}
+
+static void shader_arb_dump_program_source(const char *source)
+{
+ ULONG source_size;
+ char *ptr, *line, *tmp;
+
+ source_size = strlen(source) + 1;
+ tmp = HeapAlloc(GetProcessHeap(), 0, source_size);
+ if (!tmp)
+ {
+ ERR("Failed to allocate %u bytes for shader source.\n", source_size);
+ return;
+ }
+ memcpy(tmp, source, source_size);
+
+ ptr = tmp;
+ while ((line = get_line(&ptr))) FIXME(" %s\n", line);
+ FIXME("\n");
+
+ HeapFree(GetProcessHeap(), 0, tmp);
+}
+
+enum arb_helper_value
+{
+ ARB_ZERO,
+ ARB_ONE,
+ ARB_TWO,
+ ARB_0001,
+ ARB_EPS,
+
+ ARB_VS_REL_OFFSET
+};
+
+static const char *arb_get_helper_value(enum wined3d_shader_type shader, enum arb_helper_value value)
+{
+ if (shader == WINED3D_SHADER_TYPE_GEOMETRY)
+ {
+ ERR("Geometry shaders are unsupported\n");
+ return "bad";
+ }
+
+ if (shader == WINED3D_SHADER_TYPE_PIXEL)
+ {
+ switch (value)
+ {
+ case ARB_ZERO: return "ps_helper_const.x";
+ case ARB_ONE: return "ps_helper_const.y";
+ case ARB_TWO: return "coefmul.x";
+ case ARB_0001: return "ps_helper_const.xxxy";
+ case ARB_EPS: return "ps_helper_const.z";
+ default: break;
+ }
+ }
+ else
+ {
+ switch (value)
+ {
+ case ARB_ZERO: return "helper_const.x";
+ case ARB_ONE: return "helper_const.y";
+ case ARB_TWO: return "helper_const.z";
+ case ARB_EPS: return "helper_const.w";
+ case ARB_0001: return "helper_const.xxxy";
+ case ARB_VS_REL_OFFSET: return "rel_addr_const.y";
+ }
+ }
+ FIXME("Unmanaged %s shader helper constant requested: %u\n",
+ shader == WINED3D_SHADER_TYPE_PIXEL ? "pixel" : "vertex", value);
+ switch (value)
+ {
+ case ARB_ZERO: return "0.0";
+ case ARB_ONE: return "1.0";
+ case ARB_TWO: return "2.0";
+ case ARB_0001: return "{0.0, 0.0, 0.0, 1.0}";
+ case ARB_EPS: return "1e-8";
+ default: return "bad";
+ }
+}
+
+static inline BOOL ffp_clip_emul(const struct wined3d_state *state)
+{
+ return state->lowest_disabled_stage < 7;
+}
+
+/* ARB_program_shader private data */
+
+struct control_frame
+{
+ struct list entry;
+ enum
+ {
+ IF,
+ IFC,
+ LOOP,
+ REP
+ } type;
+ BOOL muting;
+ BOOL outer_loop;
+ union
+ {
+ unsigned int loop;
+ unsigned int ifc;
+ } no;
+ struct wined3d_shader_loop_control loop_control;
+ BOOL had_else;
+};
+
+struct arb_ps_np2fixup_info
+{
+ struct ps_np2fixup_info super;
+ /* For ARB we need a offset value:
+ * With both GLSL and ARB mode the NP2 fixup information (the texture dimensions) are stored in a
+ * consecutive way (GLSL uses a uniform array). Since ARB doesn't know the notion of a "standalone"
+ * array we need an offset to the index inside the program local parameter array. */
+ UINT offset;
+};
+
+struct arb_ps_compile_args
+{
+ struct ps_compile_args super;
+ WORD bools;
+ WORD clip; /* only a boolean, use a WORD for alignment */
+ unsigned char loop_ctrl[MAX_CONST_I][3];
+};
+
+struct stb_const_desc
+{
+ unsigned char texunit;
+ UINT const_num;
+};
+
+struct arb_ps_compiled_shader
+{
+ struct arb_ps_compile_args args;
+ struct arb_ps_np2fixup_info np2fixup_info;
+ struct stb_const_desc bumpenvmatconst[MAX_TEXTURES];
+ struct stb_const_desc luminanceconst[MAX_TEXTURES];
+ UINT int_consts[MAX_CONST_I];
+ GLuint prgId;
+ UINT ycorrection;
+ unsigned char numbumpenvmatconsts;
+ char num_int_consts;
+};
+
+struct arb_vs_compile_args
+{
+ struct vs_compile_args super;
+ union
+ {
+ struct
+ {
+ WORD bools;
+ unsigned char clip_texcoord;
+ unsigned char clipplane_mask;
+ } boolclip;
+ DWORD boolclip_compare;
+ } clip;
+ DWORD ps_signature;
+ union
+ {
+ unsigned char samplers[4];
+ DWORD samplers_compare;
+ } vertex;
+ unsigned char loop_ctrl[MAX_CONST_I][3];
+};
+
+struct arb_vs_compiled_shader
+{
+ struct arb_vs_compile_args args;
+ GLuint prgId;
+ UINT int_consts[MAX_CONST_I];
+ char num_int_consts;
+ char need_color_unclamp;
+ UINT pos_fixup;
+};
+
+struct recorded_instruction
+{
+ struct wined3d_shader_instruction ins;
+ struct list entry;
+};
+
+struct shader_arb_ctx_priv
+{
+ char addr_reg[20];
+ enum
+ {
+ /* plain GL_ARB_vertex_program or GL_ARB_fragment_program */
+ ARB,
+ /* GL_NV_vertex_progam2_option or GL_NV_fragment_program_option */
+ NV2,
+ /* GL_NV_vertex_program3 or GL_NV_fragment_program2 */
+ NV3
+ } target_version;
+
+ const struct arb_vs_compile_args *cur_vs_args;
+ const struct arb_ps_compile_args *cur_ps_args;
+ const struct arb_ps_compiled_shader *compiled_fprog;
+ const struct arb_vs_compiled_shader *compiled_vprog;
+ struct arb_ps_np2fixup_info *cur_np2fixup_info;
+ struct list control_frames;
+ struct list record;
+ BOOL recording;
+ BOOL muted;
+ unsigned int num_loops, loop_depth, num_ifcs;
+ int aL;
+ BOOL ps_post_process;
+
+ unsigned int vs_clipplanes;
+ BOOL footer_written;
+ BOOL in_main_func;
+
+ /* For 3.0 vertex shaders */
+ const char *vs_output[MAX_REG_OUTPUT];
+ /* For 2.x and earlier vertex shaders */
+ const char *texcrd_output[8], *color_output[2], *fog_output;
+
+ /* 3.0 pshader input for compatibility with fixed function */
+ const char *ps_input[MAX_REG_INPUT];
+};
+
+struct ps_signature
+{
+ struct wined3d_shader_signature_element *sig;
+ DWORD idx;
+ struct wine_rb_entry entry;
+};
+
+struct arb_pshader_private {
+ struct arb_ps_compiled_shader *gl_shaders;
+ UINT num_gl_shaders, shader_array_size;
+ DWORD input_signature_idx;
+ DWORD clipplane_emulation;
+ BOOL clamp_consts;
+};
+
+struct arb_vshader_private {
+ struct arb_vs_compiled_shader *gl_shaders;
+ UINT num_gl_shaders, shader_array_size;
+ UINT rel_offset;
+};
+
+struct shader_arb_priv
+{
+ GLuint current_vprogram_id;
+ GLuint current_fprogram_id;
+ const struct arb_ps_compiled_shader *compiled_fprog;
+ const struct arb_vs_compiled_shader *compiled_vprog;
+ GLuint depth_blt_vprogram_id;
+ GLuint depth_blt_fprogram_id_full[tex_type_count];
+ GLuint depth_blt_fprogram_id_masked[tex_type_count];
+ BOOL use_arbfp_fixed_func;
+ struct wine_rb_tree fragment_shaders;
+ BOOL last_ps_const_clamped;
+ BOOL last_vs_color_unclamp;
+
+ struct wine_rb_tree signature_tree;
+ DWORD ps_sig_number;
+
+ unsigned int highest_dirty_ps_const, highest_dirty_vs_const;
+ char *vshader_const_dirty, *pshader_const_dirty;
+ const struct wined3d_context *last_context;
+
+ const struct wined3d_vertex_pipe_ops *vertex_pipe;
+ const struct fragment_pipeline *fragment_pipe;
+ BOOL ffp_proj_control;
+};
+
+/* Context activation for state handlers is done by the caller. */
+
+static BOOL need_rel_addr_const(const struct arb_vshader_private *shader_data,
+ const struct wined3d_shader_reg_maps *reg_maps, const struct wined3d_gl_info *gl_info)
+{
+ if (shader_data->rel_offset) return TRUE;
+ if (!reg_maps->usesmova) return FALSE;
+ return !gl_info->supported[NV_VERTEX_PROGRAM2_OPTION];
+}
+
+/* Returns TRUE if result.clip from GL_NV_vertex_program2 should be used and FALSE otherwise */
+static inline BOOL use_nv_clip(const struct wined3d_gl_info *gl_info)
+{
+ return gl_info->supported[NV_VERTEX_PROGRAM2_OPTION]
+ && !(gl_info->quirks & WINED3D_QUIRK_NV_CLIP_BROKEN);
+}
+
+static BOOL need_helper_const(const struct arb_vshader_private *shader_data,
+ const struct wined3d_shader_reg_maps *reg_maps, const struct wined3d_gl_info *gl_info)
+{
+ if (need_rel_addr_const(shader_data, reg_maps, gl_info)) return TRUE;
+ if (!gl_info->supported[NV_VERTEX_PROGRAM]) return TRUE; /* Need to init colors. */
+ if (gl_info->quirks & WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT) return TRUE; /* Load the immval offset. */
+ if (gl_info->quirks & WINED3D_QUIRK_SET_TEXCOORD_W) return TRUE; /* Have to init texcoords. */
+ if (!use_nv_clip(gl_info)) return TRUE; /* Init the clip texcoord */
+ if (reg_maps->usesnrm) return TRUE; /* 0.0 */
+ if (reg_maps->usespow) return TRUE; /* EPS, 0.0 and 1.0 */
+ if (reg_maps->fog) return TRUE; /* Clamping fog coord, 0.0 and 1.0 */
+ return FALSE;
+}
+
+static unsigned int reserved_vs_const(const struct arb_vshader_private *shader_data,
+ const struct wined3d_shader_reg_maps *reg_maps, const struct wined3d_gl_info *gl_info)
+{
+ unsigned int ret = 1;
+ /* We use one PARAM for the pos fixup, and in some cases one to load
+ * some immediate values into the shader. */
+ if (need_helper_const(shader_data, reg_maps, gl_info)) ++ret;
+ if (need_rel_addr_const(shader_data, reg_maps, gl_info)) ++ret;
+ return ret;
+}
+
+/* Loads floating point constants into the currently set ARB_vertex/fragment_program.
+ * When constant_list == NULL, it will load all the constants.
+ *
+ * @target_type should be either GL_VERTEX_PROGRAM_ARB (for vertex shaders)
+ * or GL_FRAGMENT_PROGRAM_ARB (for pixel shaders)
+ */
+/* Context activation is done by the caller. */
+static unsigned int shader_arb_load_constantsF(const struct wined3d_shader *shader,
+ const struct wined3d_gl_info *gl_info, GLuint target_type, unsigned int max_constants,
+ const float *constants, char *dirty_consts)
+{
+ struct wined3d_shader_lconst *lconst;
+ DWORD i, j;
+ unsigned int ret;
+
+ if (TRACE_ON(d3d_constants))
+ {
+ for(i = 0; i < max_constants; i++) {
+ if(!dirty_consts[i]) continue;
+ TRACE_(d3d_constants)("Loading constants %i: %f, %f, %f, %f\n", i,
+ constants[i * 4 + 0], constants[i * 4 + 1],
+ constants[i * 4 + 2], constants[i * 4 + 3]);
+ }
+ }
+
+ i = 0;
+
+ /* In 1.X pixel shaders constants are implicitly clamped in the range [-1;1] */
+ if (target_type == GL_FRAGMENT_PROGRAM_ARB && shader->reg_maps.shader_version.major == 1)
+ {
+ float lcl_const[4];
+ /* ps 1.x supports only 8 constants, clamp only those. When switching between 1.x and higher
+ * shaders, the first 8 constants are marked dirty for reload
+ */
+ for(; i < min(8, max_constants); i++) {
+ if(!dirty_consts[i]) continue;
+ dirty_consts[i] = 0;
+
+ j = 4 * i;
+ if (constants[j + 0] > 1.0f) lcl_const[0] = 1.0f;
+ else if (constants[j + 0] < -1.0f) lcl_const[0] = -1.0f;
+ else lcl_const[0] = constants[j + 0];
+
+ if (constants[j + 1] > 1.0f) lcl_const[1] = 1.0f;
+ else if (constants[j + 1] < -1.0f) lcl_const[1] = -1.0f;
+ else lcl_const[1] = constants[j + 1];
+
+ if (constants[j + 2] > 1.0f) lcl_const[2] = 1.0f;
+ else if (constants[j + 2] < -1.0f) lcl_const[2] = -1.0f;
+ else lcl_const[2] = constants[j + 2];
+
+ if (constants[j + 3] > 1.0f) lcl_const[3] = 1.0f;
+ else if (constants[j + 3] < -1.0f) lcl_const[3] = -1.0f;
+ else lcl_const[3] = constants[j + 3];
+
+ GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, i, lcl_const));
+ }
+
+ /* If further constants are dirty, reload them without clamping.
+ *
+ * The alternative is not to touch them, but then we cannot reset the dirty constant count
+ * to zero. That's bad for apps that only use PS 1.x shaders, because in that case the code
+ * above would always re-check the first 8 constants since max_constant remains at the init
+ * value
+ */
+ }
+
+ if (gl_info->supported[EXT_GPU_PROGRAM_PARAMETERS])
+ {
+ /* TODO: Benchmark if we're better of with finding the dirty constants ourselves,
+ * or just reloading *all* constants at once
+ *
+ GL_EXTCALL(glProgramEnvParameters4fvEXT(target_type, i, max_constants, constants + (i * 4)));
+ */
+ for(; i < max_constants; i++) {
+ if(!dirty_consts[i]) continue;
+
+ /* Find the next block of dirty constants */
+ dirty_consts[i] = 0;
+ j = i;
+ for(i++; (i < max_constants) && dirty_consts[i]; i++) {
+ dirty_consts[i] = 0;
+ }
+
+ GL_EXTCALL(glProgramEnvParameters4fvEXT(target_type, j, i - j, constants + (j * 4)));
+ }
+ } else {
+ for(; i < max_constants; i++) {
+ if(dirty_consts[i]) {
+ dirty_consts[i] = 0;
+ GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, i, constants + (i * 4)));
+ }
+ }
+ }
+ checkGLcall("glProgramEnvParameter4fvARB()");
+
+ /* Load immediate constants */
+ if (shader->load_local_constsF)
+ {
+ if (TRACE_ON(d3d_shader))
+ {
+ LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
+ {
+ GLfloat* values = (GLfloat*)lconst->value;
+ TRACE_(d3d_constants)("Loading local constants %i: %f, %f, %f, %f\n", lconst->idx,
+ values[0], values[1], values[2], values[3]);
+ }
+ }
+ /* Immediate constants are clamped for 1.X shaders at loading times */
+ ret = 0;
+ LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
+ {
+ dirty_consts[lconst->idx] = 1; /* Dirtify so the non-immediate constant overwrites it next time */
+ ret = max(ret, lconst->idx + 1);
+ GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, lconst->idx, (GLfloat*)lconst->value));
+ }
+ checkGLcall("glProgramEnvParameter4fvARB()");
+ return ret; /* The loaded immediate constants need reloading for the next shader */
+ } else {
+ return 0; /* No constants are dirty now */
+ }
+}
+
+/**
+ * Loads the texture dimensions for NP2 fixup into the currently set ARB_[vertex/fragment]_programs.
+ */
+static void shader_arb_load_np2fixup_constants(void *shader_priv,
+ const struct wined3d_gl_info *gl_info, const struct wined3d_state *state)
+{
+ const struct shader_arb_priv * priv = shader_priv;
+
+ /* NP2 texcoord fixup is (currently) only done for pixelshaders. */
+ if (!use_ps(state)) return;
+
+ if (priv->compiled_fprog && priv->compiled_fprog->np2fixup_info.super.active) {
+ const struct arb_ps_np2fixup_info* const fixup = &priv->compiled_fprog->np2fixup_info;
+ UINT i;
+ WORD active = fixup->super.active;
+ GLfloat np2fixup_constants[4 * MAX_FRAGMENT_SAMPLERS];
+
+ for (i = 0; active; active >>= 1, ++i)
+ {
+ const struct wined3d_texture *tex = state->textures[i];
+ const unsigned char idx = fixup->super.idx[i];
+ GLfloat *tex_dim = &np2fixup_constants[(idx >> 1) * 4];
+
+ if (!(active & 1)) continue;
+
+ if (!tex) {
+ FIXME("Nonexistent texture is flagged for NP2 texcoord fixup\n");
+ continue;
+ }
+
+ if (idx % 2)
+ {
+ tex_dim[2] = tex->pow2_matrix[0];
+ tex_dim[3] = tex->pow2_matrix[5];
+ }
+ else
+ {
+ tex_dim[0] = tex->pow2_matrix[0];
+ tex_dim[1] = tex->pow2_matrix[5];
+ }
+ }
+
+ for (i = 0; i < fixup->super.num_consts; ++i) {
+ GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB,
+ fixup->offset + i, &np2fixup_constants[i * 4]));
+ }
+ }
+}
+
+/* Context activation is done by the caller. */
+static void shader_arb_ps_local_constants(const struct arb_ps_compiled_shader *gl_shader,
+ const struct wined3d_context *context, const struct wined3d_state *state, UINT rt_height)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ unsigned char i;
+
+ for(i = 0; i < gl_shader->numbumpenvmatconsts; i++)
+ {
+ int texunit = gl_shader->bumpenvmatconst[i].texunit;
+
+ /* The state manager takes care that this function is always called if the bump env matrix changes */
+ const float *data = (const float *)&state->texture_states[texunit][WINED3D_TSS_BUMPENV_MAT00];
+ GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB,
+ gl_shader->bumpenvmatconst[i].const_num, data));
+
+ if (gl_shader->luminanceconst[i].const_num != WINED3D_CONST_NUM_UNUSED)
+ {
+ /* WINED3D_TSS_BUMPENVLSCALE and WINED3D_TSS_BUMPENVLOFFSET are next to each other.
+ * point gl to the scale, and load 4 floats. x = scale, y = offset, z and w are junk, we
+ * don't care about them. The pointers are valid for sure because the stateblock is bigger.
+ * (they're WINED3D_TSS_TEXTURETRANSFORMFLAGS and WINED3D_TSS_ADDRESSW, so most likely 0 or NaN
+ */
+ const float *scale = (const float *)&state->texture_states[texunit][WINED3D_TSS_BUMPENV_LSCALE];
+ GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB,
+ gl_shader->luminanceconst[i].const_num, scale));
+ }
+ }
+ checkGLcall("Load bumpmap consts");
+
+ if(gl_shader->ycorrection != WINED3D_CONST_NUM_UNUSED)
+ {
+ /* ycorrection.x: Backbuffer height(onscreen) or 0(offscreen).
+ * ycorrection.y: -1.0(onscreen), 1.0(offscreen)
+ * ycorrection.z: 1.0
+ * ycorrection.w: 0.0
+ */
+ float val[4];
+ val[0] = context->render_offscreen ? 0.0f : (float) rt_height;
+ val[1] = context->render_offscreen ? 1.0f : -1.0f;
+ val[2] = 1.0f;
+ val[3] = 0.0f;
+ GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, gl_shader->ycorrection, val));
+ checkGLcall("y correction loading");
+ }
+
+ if (!gl_shader->num_int_consts) return;
+
+ for(i = 0; i < MAX_CONST_I; i++)
+ {
+ if(gl_shader->int_consts[i] != WINED3D_CONST_NUM_UNUSED)
+ {
+ float val[4];
+ val[0] = (float)state->ps_consts_i[4 * i];
+ val[1] = (float)state->ps_consts_i[4 * i + 1];
+ val[2] = (float)state->ps_consts_i[4 * i + 2];
+ val[3] = -1.0f;
+
+ GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, gl_shader->int_consts[i], val));
+ }
+ }
+ checkGLcall("Load ps int consts");
+}
+
+/* Context activation is done by the caller. */
+static void shader_arb_vs_local_constants(const struct arb_vs_compiled_shader *gl_shader,
+ const struct wined3d_context *context, const struct wined3d_state *state)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ float position_fixup[4];
+ unsigned char i;
+
+ /* Upload the position fixup */
+ shader_get_position_fixup(context, state, position_fixup);
+ GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, gl_shader->pos_fixup, position_fixup));
+
+ if (!gl_shader->num_int_consts) return;
+
+ for(i = 0; i < MAX_CONST_I; i++)
+ {
+ if(gl_shader->int_consts[i] != WINED3D_CONST_NUM_UNUSED)
+ {
+ float val[4];
+ val[0] = (float)state->vs_consts_i[4 * i];
+ val[1] = (float)state->vs_consts_i[4 * i + 1];
+ val[2] = (float)state->vs_consts_i[4 * i + 2];
+ val[3] = -1.0f;
+
+ GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, gl_shader->int_consts[i], val));
+ }
+ }
+ checkGLcall("Load vs int consts");
+}
+
+static void shader_arb_select(void *shader_priv, const struct wined3d_context *context,
+ const struct wined3d_state *state);
+
+/**
+ * Loads the app-supplied constants into the currently set ARB_[vertex/fragment]_programs.
+ *
+ * We only support float constants in ARB at the moment, so don't
+ * worry about the Integers or Booleans
+ */
+/* Context activation is done by the caller (state handler). */
+static void shader_arb_load_constants_internal(struct shader_arb_priv *priv,
+ const struct wined3d_context *context, const struct wined3d_state *state,
+ BOOL usePixelShader, BOOL useVertexShader, BOOL from_shader_select)
+{
+ const struct wined3d_d3d_info *d3d_info = context->d3d_info;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (!from_shader_select)
+ {
+ const struct wined3d_shader *vshader = state->vertex_shader, *pshader = state->pixel_shader;
+ if (vshader
+ && (vshader->reg_maps.boolean_constants
+ || (!gl_info->supported[NV_VERTEX_PROGRAM2_OPTION]
+ && (vshader->reg_maps.integer_constants & ~vshader->reg_maps.local_int_consts))))
+ {
+ TRACE("bool/integer vertex shader constants potentially modified, forcing shader reselection.\n");
+ shader_arb_select(priv, context, state);
+ }
+ else if (pshader
+ && (pshader->reg_maps.boolean_constants
+ || (!gl_info->supported[NV_FRAGMENT_PROGRAM_OPTION]
+ && (pshader->reg_maps.integer_constants & ~pshader->reg_maps.local_int_consts))))
+ {
+ TRACE("bool/integer pixel shader constants potentially modified, forcing shader reselection.\n");
+ shader_arb_select(priv, context, state);
+ }
+ }
+
+ if (context != priv->last_context)
+ {
+ memset(priv->vshader_const_dirty, 1,
+ sizeof(*priv->vshader_const_dirty) * d3d_info->limits.vs_uniform_count);
+ priv->highest_dirty_vs_const = d3d_info->limits.vs_uniform_count;
+
+ memset(priv->pshader_const_dirty, 1,
+ sizeof(*priv->pshader_const_dirty) * d3d_info->limits.ps_uniform_count);
+ priv->highest_dirty_ps_const = d3d_info->limits.ps_uniform_count;
+
+ priv->last_context = context;
+ }
+
+ if (useVertexShader)
+ {
+ struct wined3d_shader *vshader = state->vertex_shader;
+ const struct arb_vs_compiled_shader *gl_shader = priv->compiled_vprog;
+
+ /* Load DirectX 9 float constants for vertex shader */
+ priv->highest_dirty_vs_const = shader_arb_load_constantsF(vshader, gl_info, GL_VERTEX_PROGRAM_ARB,
+ priv->highest_dirty_vs_const, state->vs_consts_f, priv->vshader_const_dirty);
+ shader_arb_vs_local_constants(gl_shader, context, state);
+ }
+
+ if (usePixelShader)
+ {
+ struct wined3d_shader *pshader = state->pixel_shader;
+ const struct arb_ps_compiled_shader *gl_shader = priv->compiled_fprog;
+ UINT rt_height = state->fb->render_targets[0]->resource.height;
+
+ /* Load DirectX 9 float constants for pixel shader */
+ priv->highest_dirty_ps_const = shader_arb_load_constantsF(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB,
+ priv->highest_dirty_ps_const, state->ps_consts_f, priv->pshader_const_dirty);
+ shader_arb_ps_local_constants(gl_shader, context, state, rt_height);
+ }
+}
+
+static void shader_arb_load_constants(void *shader_priv, const struct wined3d_context *context,
+ const struct wined3d_state *state)
+{
+ BOOL vs = use_vs(state);
+ BOOL ps = use_ps(state);
+
+ shader_arb_load_constants_internal(shader_priv, context, state, ps, vs, FALSE);
+}
+
+static void shader_arb_update_float_vertex_constants(struct wined3d_device *device, UINT start, UINT count)
+{
+ struct wined3d_context *context = context_get_current();
+ struct shader_arb_priv *priv = device->shader_priv;
+
+ /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active
+ * context. On a context switch the old context will be fully dirtified */
+ if (!context || context->swapchain->device != device) return;
+
+ memset(priv->vshader_const_dirty + start, 1, sizeof(*priv->vshader_const_dirty) * count);
+ priv->highest_dirty_vs_const = max(priv->highest_dirty_vs_const, start + count);
+}
+
+static void shader_arb_update_float_pixel_constants(struct wined3d_device *device, UINT start, UINT count)
+{
+ struct wined3d_context *context = context_get_current();
+ struct shader_arb_priv *priv = device->shader_priv;
+
+ /* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active
+ * context. On a context switch the old context will be fully dirtified */
+ if (!context || context->swapchain->device != device) return;
+
+ memset(priv->pshader_const_dirty + start, 1, sizeof(*priv->pshader_const_dirty) * count);
+ priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, start + count);
+}
+
+/* Generate the variable & register declarations for the ARB_vertex_program output target */
+static void shader_generate_arb_declarations(const struct wined3d_shader *shader,
+ const struct wined3d_shader_reg_maps *reg_maps, struct wined3d_shader_buffer *buffer,
+ const struct wined3d_gl_info *gl_info, DWORD *num_clipplanes,
+ const struct shader_arb_ctx_priv *ctx)
+{
+ DWORD i;
+ char pshader = shader_is_pshader_version(reg_maps->shader_version.type);
+ const struct wined3d_shader_lconst *lconst;
+ unsigned max_constantsF;
+ DWORD map;
+
+ /* In pixel shaders, all private constants are program local, we don't need anything
+ * from program.env. Thus we can advertise the full set of constants in pixel shaders.
+ * If we need a private constant the GL implementation will squeeze it in somewhere
+ *
+ * With vertex shaders we need the posFixup and on some GL implementations 4 helper
+ * immediate values. The posFixup is loaded using program.env for now, so always
+ * subtract one from the number of constants. If the shader uses indirect addressing,
+ * account for the helper const too because we have to declare all available d3d constants
+ * and don't know which are actually used.
+ */
+ if (pshader)
+ {
+ max_constantsF = gl_info->limits.arb_ps_native_constants;
+ /* 24 is the minimum MAX_PROGRAM_ENV_PARAMETERS_ARB value. */
+ if (max_constantsF < 24)
+ max_constantsF = gl_info->limits.arb_ps_float_constants;
+ }
+ else
+ {
+ const struct arb_vshader_private *shader_data = shader->backend_data;
+ max_constantsF = gl_info->limits.arb_vs_native_constants;
+ /* 96 is the minimum MAX_PROGRAM_ENV_PARAMETERS_ARB value.
+ * Also prevents max_constantsF from becoming less than 0 and
+ * wrapping . */
+ if (max_constantsF < 96)
+ max_constantsF = gl_info->limits.arb_vs_float_constants;
+
+ if (reg_maps->usesrelconstF)
+ {
+ DWORD highest_constf = 0, clip_limit;
+
+ max_constantsF -= reserved_vs_const(shader_data, reg_maps, gl_info);
+ max_constantsF -= count_bits(reg_maps->integer_constants);
+ max_constantsF -= gl_info->reserved_arb_constants;
+
+ for (i = 0; i < shader->limits.constant_float; ++i)
+ {
+ DWORD idx = i >> 5;
+ DWORD shift = i & 0x1f;
+ if(reg_maps->constf[idx] & (1 << shift)) highest_constf = i;
+ }
+
+ if(use_nv_clip(gl_info) && ctx->target_version >= NV2)
+ {
+ if(ctx->cur_vs_args->super.clip_enabled)
+ clip_limit = gl_info->limits.clipplanes;
+ else
+ clip_limit = 0;
+ }
+ else
+ {
+ unsigned int mask = ctx->cur_vs_args->clip.boolclip.clipplane_mask;
+ clip_limit = min(count_bits(mask), 4);
+ }
+ *num_clipplanes = min(clip_limit, max_constantsF - highest_constf - 1);
+ max_constantsF -= *num_clipplanes;
+ if(*num_clipplanes < clip_limit)
+ {
+ WARN("Only %u clipplanes out of %u enabled\n", *num_clipplanes, gl_info->limits.clipplanes);
+ }
+ }
+ else
+ {
+ if (ctx->target_version >= NV2) *num_clipplanes = gl_info->limits.clipplanes;
+ else *num_clipplanes = min(gl_info->limits.clipplanes, 4);
+ }
+ }
+
+ for (i = 0, map = reg_maps->temporary; map; map >>= 1, ++i)
+ {
+ if (map & 1) shader_addline(buffer, "TEMP R%u;\n", i);
+ }
+
+ for (i = 0, map = reg_maps->address; map; map >>= 1, ++i)
+ {
+ if (map & 1) shader_addline(buffer, "ADDRESS A%u;\n", i);
+ }
+
+ if (pshader && reg_maps->shader_version.major == 1 && reg_maps->shader_version.minor <= 3)
+ {
+ for (i = 0, map = reg_maps->texcoord; map; map >>= 1, ++i)
+ {
+ if (map & 1) shader_addline(buffer, "TEMP T%u;\n", i);
+ }
+ }
+
+ if (!shader->load_local_constsF)
+ {
+ LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
+ {
+ const float *value;
+ value = (const float *)lconst->value;
+ shader_addline(buffer, "PARAM C%u = {%.8e, %.8e, %.8e, %.8e};\n", lconst->idx,
+ value[0], value[1], value[2], value[3]);
+ }
+ }
+
+ /* After subtracting privately used constants from the hardware limit(they are loaded as
+ * local constants), make sure the shader doesn't violate the env constant limit
+ */
+ if(pshader)
+ {
+ max_constantsF = min(max_constantsF, gl_info->limits.arb_ps_float_constants);
+ }
+ else
+ {
+ max_constantsF = min(max_constantsF, gl_info->limits.arb_vs_float_constants);
+ }
+
+ /* Avoid declaring more constants than needed */
+ max_constantsF = min(max_constantsF, shader->limits.constant_float);
+
+ /* we use the array-based constants array if the local constants are marked for loading,
+ * because then we use indirect addressing, or when the local constant list is empty,
+ * because then we don't know if we're using indirect addressing or not. If we're hardcoding
+ * local constants do not declare the loaded constants as an array because ARB compilers usually
+ * do not optimize unused constants away
+ */
+ if (reg_maps->usesrelconstF)
+ {
+ /* Need to PARAM the environment parameters (constants) so we can use relative addressing */
+ shader_addline(buffer, "PARAM C[%d] = { program.env[0..%d] };\n",
+ max_constantsF, max_constantsF - 1);
+ } else {
+ for(i = 0; i < max_constantsF; i++) {
+ DWORD idx, mask;
+ idx = i >> 5;
+ mask = 1 << (i & 0x1f);
+ if (!shader_constant_is_local(shader, i) && (reg_maps->constf[idx] & mask))
+ {
+ shader_addline(buffer, "PARAM C%d = program.env[%d];\n",i, i);
+ }
+ }
+ }
+}
+
+static const char * const shift_tab[] = {
+ "dummy", /* 0 (none) */
+ "coefmul.x", /* 1 (x2) */
+ "coefmul.y", /* 2 (x4) */
+ "coefmul.z", /* 3 (x8) */
+ "coefmul.w", /* 4 (x16) */
+ "dummy", /* 5 (x32) */
+ "dummy", /* 6 (x64) */
+ "dummy", /* 7 (x128) */
+ "dummy", /* 8 (d256) */
+ "dummy", /* 9 (d128) */
+ "dummy", /* 10 (d64) */
+ "dummy", /* 11 (d32) */
+ "coefdiv.w", /* 12 (d16) */
+ "coefdiv.z", /* 13 (d8) */
+ "coefdiv.y", /* 14 (d4) */
+ "coefdiv.x" /* 15 (d2) */
+};
+
+static void shader_arb_get_write_mask(const struct wined3d_shader_instruction *ins,
+ const struct wined3d_shader_dst_param *dst, char *write_mask)
+{
+ char *ptr = write_mask;
+
+ if (dst->write_mask != WINED3DSP_WRITEMASK_ALL)
+ {
+ *ptr++ = '.';
+ if (dst->write_mask & WINED3DSP_WRITEMASK_0) *ptr++ = 'x';
+ if (dst->write_mask & WINED3DSP_WRITEMASK_1) *ptr++ = 'y';
+ if (dst->write_mask & WINED3DSP_WRITEMASK_2) *ptr++ = 'z';
+ if (dst->write_mask & WINED3DSP_WRITEMASK_3) *ptr++ = 'w';
+ }
+
+ *ptr = '\0';
+}
+
+static void shader_arb_get_swizzle(const struct wined3d_shader_src_param *param, BOOL fixup, char *swizzle_str)
+{
+ /* For registers of type WINED3DDECLTYPE_D3DCOLOR, data is stored as "bgra",
+ * but addressed as "rgba". To fix this we need to swap the register's x
+ * and z components. */
+ const char *swizzle_chars = fixup ? "zyxw" : "xyzw";
+ char *ptr = swizzle_str;
+
+ /* swizzle bits fields: wwzzyyxx */
+ DWORD swizzle = param->swizzle;
+ DWORD swizzle_x = swizzle & 0x03;
+ DWORD swizzle_y = (swizzle >> 2) & 0x03;
+ DWORD swizzle_z = (swizzle >> 4) & 0x03;
+ DWORD swizzle_w = (swizzle >> 6) & 0x03;
+
+ /* If the swizzle is the default swizzle (ie, "xyzw"), we don't need to
+ * generate a swizzle string. Unless we need to our own swizzling. */
+ if (swizzle != WINED3DSP_NOSWIZZLE || fixup)
+ {
+ *ptr++ = '.';
+ if (swizzle_x == swizzle_y && swizzle_x == swizzle_z && swizzle_x == swizzle_w) {
+ *ptr++ = swizzle_chars[swizzle_x];
+ } else {
+ *ptr++ = swizzle_chars[swizzle_x];
+ *ptr++ = swizzle_chars[swizzle_y];
+ *ptr++ = swizzle_chars[swizzle_z];
+ *ptr++ = swizzle_chars[swizzle_w];
+ }
+ }
+
+ *ptr = '\0';
+}
+
+static void shader_arb_request_a0(const struct wined3d_shader_instruction *ins, const char *src)
+{
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+
+ if (!strcmp(priv->addr_reg, src)) return;
+
+ strcpy(priv->addr_reg, src);
+ shader_addline(buffer, "ARL A0.x, %s;\n", src);
+}
+
+static void shader_arb_get_src_param(const struct wined3d_shader_instruction *ins,
+ const struct wined3d_shader_src_param *src, unsigned int tmpreg, char *outregstr);
+
+static void shader_arb_get_register_name(const struct wined3d_shader_instruction *ins,
+ const struct wined3d_shader_register *reg, char *register_name, BOOL *is_color)
+{
+ /* oPos, oFog and oPts in D3D */
+ static const char * const rastout_reg_names[] = {"TMP_OUT", "TMP_FOGCOORD", "result.pointsize"};
+ const struct wined3d_shader *shader = ins->ctx->shader;
+ const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
+ BOOL pshader = shader_is_pshader_version(reg_maps->shader_version.type);
+ struct shader_arb_ctx_priv *ctx = ins->ctx->backend_data;
+
+ *is_color = FALSE;
+
+ switch (reg->type)
+ {
+ case WINED3DSPR_TEMP:
+ sprintf(register_name, "R%u", reg->idx[0].offset);
+ break;
+
+ case WINED3DSPR_INPUT:
+ if (pshader)
+ {
+ if (reg_maps->shader_version.major < 3)
+ {
+ if (!reg->idx[0].offset)
+ strcpy(register_name, "fragment.color.primary");
+ else
+ strcpy(register_name, "fragment.color.secondary");
+ }
+ else
+ {
+ if (reg->idx[0].rel_addr)
+ {
+ char rel_reg[50];
+ shader_arb_get_src_param(ins, reg->idx[0].rel_addr, 0, rel_reg);
+
+ if (!strcmp(rel_reg, "**aL_emul**"))
+ {
+ DWORD idx = ctx->aL + reg->idx[0].offset;
+ if(idx < MAX_REG_INPUT)
+ {
+ strcpy(register_name, ctx->ps_input[idx]);
+ }
+ else
+ {
+ ERR("Pixel shader input register out of bounds: %u\n", idx);
+ sprintf(register_name, "out_of_bounds_%u", idx);
+ }
+ }
+ else if (reg_maps->input_registers & 0x0300)
+ {
+ /* There are two ways basically:
+ *
+ * 1) Use the unrolling code that is used for loop emulation and unroll the loop.
+ * That means trouble if the loop also contains a breakc or if the control values
+ * aren't local constants.
+ * 2) Generate an if block that checks if aL.y < 8, == 8 or == 9 and selects the
+ * source dynamically. The trouble is that we cannot simply read aL.y because it
+ * is an ADDRESS register. We could however push it, load .zw with a value and use
+ * ADAC to load the condition code register and pop it again afterwards
+ */
+ FIXME("Relative input register addressing with more than 8 registers\n");
+
+ /* This is better than nothing for now */
+ sprintf(register_name, "fragment.texcoord[%s + %u]", rel_reg, reg->idx[0].offset);
+ }
+ else if(ctx->cur_ps_args->super.vp_mode != vertexshader)
+ {
+ /* This is problematic because we'd have to consult the ctx->ps_input strings
+ * for where to find the varying. Some may be "0.0", others can be texcoords or
+ * colors. This needs either a pipeline replacement to make the vertex shader feed
+ * proper varyings, or loop unrolling
+ *
+ * For now use the texcoords and hope for the best
+ */
+ FIXME("Non-vertex shader varying input with indirect addressing\n");
+ sprintf(register_name, "fragment.texcoord[%s + %u]", rel_reg, reg->idx[0].offset);
+ }
+ else
+ {
+ /* D3D supports indirect addressing only with aL in loop registers. The loop instruction
+ * pulls GL_NV_fragment_program2 in
+ */
+ sprintf(register_name, "fragment.texcoord[%s + %u]", rel_reg, reg->idx[0].offset);
+ }
+ }
+ else
+ {
+ if (reg->idx[0].offset < MAX_REG_INPUT)
+ {
+ strcpy(register_name, ctx->ps_input[reg->idx[0].offset]);
+ }
+ else
+ {
+ ERR("Pixel shader input register out of bounds: %u\n", reg->idx[0].offset);
+ sprintf(register_name, "out_of_bounds_%u", reg->idx[0].offset);
+ }
+ }
+ }
+ }
+ else
+ {
+ if (ctx->cur_vs_args->super.swizzle_map & (1 << reg->idx[0].offset))
+ *is_color = TRUE;
+ sprintf(register_name, "vertex.attrib[%u]", reg->idx[0].offset);
+ }
+ break;
+
+ case WINED3DSPR_CONST:
+ if (!pshader && reg->idx[0].rel_addr)
+ {
+ const struct arb_vshader_private *shader_data = shader->backend_data;
+ UINT rel_offset = shader_data->rel_offset;
+ BOOL aL = FALSE;
+ char rel_reg[50];
+ if (reg_maps->shader_version.major < 2)
+ {
+ sprintf(rel_reg, "A0.x");
+ }
+ else
+ {
+ shader_arb_get_src_param(ins, reg->idx[0].rel_addr, 0, rel_reg);
+ if (ctx->target_version == ARB)
+ {
+ if (!strcmp(rel_reg, "**aL_emul**"))
+ {
+ aL = TRUE;
+ } else {
+ shader_arb_request_a0(ins, rel_reg);
+ sprintf(rel_reg, "A0.x");
+ }
+ }
+ }
+ if (aL)
+ sprintf(register_name, "C[%u]", ctx->aL + reg->idx[0].offset);
+ else if (reg->idx[0].offset >= rel_offset)
+ sprintf(register_name, "C[%s + %u]", rel_reg, reg->idx[0].offset - rel_offset);
+ else
+ sprintf(register_name, "C[%s - %u]", rel_reg, rel_offset - reg->idx[0].offset);
+ }
+ else
+ {
+ if (reg_maps->usesrelconstF)
+ sprintf(register_name, "C[%u]", reg->idx[0].offset);
+ else
+ sprintf(register_name, "C%u", reg->idx[0].offset);
+ }
+ break;
+
+ case WINED3DSPR_TEXTURE: /* case WINED3DSPR_ADDR: */
+ if (pshader)
+ {
+ if (reg_maps->shader_version.major == 1
+ && reg_maps->shader_version.minor <= 3)
+ /* In ps <= 1.3, Tx is a temporary register as destination
+ * to all instructions, and as source to most instructions.
+ * For some instructions it is the texcoord input. Those
+ * instructions know about the special use. */
+ sprintf(register_name, "T%u", reg->idx[0].offset);
+ else
+ /* In ps 1.4 and 2.x Tx is always a (read-only) varying. */
+ sprintf(register_name, "fragment.texcoord[%u]", reg->idx[0].offset);
+ }
+ else
+ {
+ if (reg_maps->shader_version.major == 1 || ctx->target_version >= NV2)
+ sprintf(register_name, "A%u", reg->idx[0].offset);
+ else
+ sprintf(register_name, "A%u_SHADOW", reg->idx[0].offset);
+ }
+ break;
+
+ case WINED3DSPR_COLOROUT:
+ if (ctx->ps_post_process && !reg->idx[0].offset)
+ {
+ strcpy(register_name, "TMP_COLOR");
+ }
+ else
+ {
+ if (ctx->cur_ps_args->super.srgb_correction)
+ FIXME("sRGB correction on higher render targets.\n");
+ if (reg_maps->rt_mask > 1)
+ sprintf(register_name, "result.color[%u]", reg->idx[0].offset);
+ else
+ strcpy(register_name, "result.color");
+ }
+ break;
+
+ case WINED3DSPR_RASTOUT:
+ if (reg->idx[0].offset == 1)
+ sprintf(register_name, "%s", ctx->fog_output);
+ else
+ sprintf(register_name, "%s", rastout_reg_names[reg->idx[0].offset]);
+ break;
+
+ case WINED3DSPR_DEPTHOUT:
+ strcpy(register_name, "result.depth");
+ break;
+
+ case WINED3DSPR_ATTROUT:
+ /* case WINED3DSPR_OUTPUT: */
+ if (pshader)
+ sprintf(register_name, "oD[%u]", reg->idx[0].offset);
+ else
+ strcpy(register_name, ctx->color_output[reg->idx[0].offset]);
+ break;
+
+ case WINED3DSPR_TEXCRDOUT:
+ if (pshader)
+ sprintf(register_name, "oT[%u]", reg->idx[0].offset);
+ else if (reg_maps->shader_version.major < 3)
+ strcpy(register_name, ctx->texcrd_output[reg->idx[0].offset]);
+ else
+ strcpy(register_name, ctx->vs_output[reg->idx[0].offset]);
+ break;
+
+ case WINED3DSPR_LOOP:
+ if(ctx->target_version >= NV2)
+ {
+ /* Pshader has an implicitly declared loop index counter A0.x that cannot be renamed */
+ if(pshader) sprintf(register_name, "A0.x");
+ else sprintf(register_name, "aL.y");
+ }
+ else
+ {
+ /* Unfortunately this code cannot return the value of ctx->aL here. An immediate value
+ * would be valid, but if aL is used for indexing(its only use), there's likely an offset,
+ * thus the result would be something like C[15 + 30], which is not valid in the ARB program
+ * grammar. So return a marker for the emulated aL and intercept it in constant and varying
+ * indexing
+ */
+ sprintf(register_name, "**aL_emul**");
+ }
+
+ break;
+
+ case WINED3DSPR_CONSTINT:
+ sprintf(register_name, "I%u", reg->idx[0].offset);
+ break;
+
+ case WINED3DSPR_MISCTYPE:
+ if (!reg->idx[0].offset)
+ sprintf(register_name, "vpos");
+ else if (reg->idx[0].offset == 1)
+ sprintf(register_name, "fragment.facing.x");
+ else
+ FIXME("Unknown MISCTYPE register index %u.\n", reg->idx[0].offset);
+ break;
+
+ default:
+ FIXME("Unhandled register type %#x[%u].\n", reg->type, reg->idx[0].offset);
+ sprintf(register_name, "unrecognized_register[%u]", reg->idx[0].offset);
+ break;
+ }
+}
+
+static void shader_arb_get_dst_param(const struct wined3d_shader_instruction *ins,
+ const struct wined3d_shader_dst_param *wined3d_dst, char *str)
+{
+ char register_name[255];
+ char write_mask[6];
+ BOOL is_color;
+
+ shader_arb_get_register_name(ins, &wined3d_dst->reg, register_name, &is_color);
+ strcpy(str, register_name);
+
+ shader_arb_get_write_mask(ins, wined3d_dst, write_mask);
+ strcat(str, write_mask);
+}
+
+static const char *shader_arb_get_fixup_swizzle(enum fixup_channel_source channel_source)
+{
+ switch(channel_source)
+ {
+ case CHANNEL_SOURCE_ZERO: return "0";
+ case CHANNEL_SOURCE_ONE: return "1";
+ case CHANNEL_SOURCE_X: return "x";
+ case CHANNEL_SOURCE_Y: return "y";
+ case CHANNEL_SOURCE_Z: return "z";
+ case CHANNEL_SOURCE_W: return "w";
+ default:
+ FIXME("Unhandled channel source %#x\n", channel_source);
+ return "undefined";
+ }
+}
+
+static void gen_color_correction(struct wined3d_shader_buffer *buffer, const char *reg,
+ DWORD dst_mask, const char *one, const char *two, struct color_fixup_desc fixup)
+{
+ DWORD mask;
+
+ if (is_complex_fixup(fixup))
+ {
+ enum complex_fixup complex_fixup = get_complex_fixup(fixup);
+ FIXME("Complex fixup (%#x) not supported\n", complex_fixup);
+ return;
+ }
+
+ mask = 0;
+ if (fixup.x_source != CHANNEL_SOURCE_X) mask |= WINED3DSP_WRITEMASK_0;
+ if (fixup.y_source != CHANNEL_SOURCE_Y) mask |= WINED3DSP_WRITEMASK_1;
+ if (fixup.z_source != CHANNEL_SOURCE_Z) mask |= WINED3DSP_WRITEMASK_2;
+ if (fixup.w_source != CHANNEL_SOURCE_W) mask |= WINED3DSP_WRITEMASK_3;
+ mask &= dst_mask;
+
+ if (mask)
+ {
+ shader_addline(buffer, "SWZ %s, %s, %s, %s, %s, %s;\n", reg, reg,
+ shader_arb_get_fixup_swizzle(fixup.x_source), shader_arb_get_fixup_swizzle(fixup.y_source),
+ shader_arb_get_fixup_swizzle(fixup.z_source), shader_arb_get_fixup_swizzle(fixup.w_source));
+ }
+
+ mask = 0;
+ if (fixup.x_sign_fixup) mask |= WINED3DSP_WRITEMASK_0;
+ if (fixup.y_sign_fixup) mask |= WINED3DSP_WRITEMASK_1;
+ if (fixup.z_sign_fixup) mask |= WINED3DSP_WRITEMASK_2;
+ if (fixup.w_sign_fixup) mask |= WINED3DSP_WRITEMASK_3;
+ mask &= dst_mask;
+
+ if (mask)
+ {
+ char reg_mask[6];
+ char *ptr = reg_mask;
+
+ if (mask != WINED3DSP_WRITEMASK_ALL)
+ {
+ *ptr++ = '.';
+ if (mask & WINED3DSP_WRITEMASK_0) *ptr++ = 'x';
+ if (mask & WINED3DSP_WRITEMASK_1) *ptr++ = 'y';
+ if (mask & WINED3DSP_WRITEMASK_2) *ptr++ = 'z';
+ if (mask & WINED3DSP_WRITEMASK_3) *ptr++ = 'w';
+ }
+ *ptr = '\0';
+
+ shader_addline(buffer, "MAD %s%s, %s, %s, -%s;\n", reg, reg_mask, reg, two, one);
+ }
+}
+
+static const char *shader_arb_get_modifier(const struct wined3d_shader_instruction *ins)
+{
+ DWORD mod;
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ if (!ins->dst_count) return "";
+
+ mod = ins->dst[0].modifiers;
+
+ /* Silently ignore PARTIALPRECISION if its not supported */
+ if(priv->target_version == ARB) mod &= ~WINED3DSPDM_PARTIALPRECISION;
+
+ if(mod & WINED3DSPDM_MSAMPCENTROID)
+ {
+ FIXME("Unhandled modifier WINED3DSPDM_MSAMPCENTROID\n");
+ mod &= ~WINED3DSPDM_MSAMPCENTROID;
+ }
+
+ switch(mod)
+ {
+ case WINED3DSPDM_SATURATE | WINED3DSPDM_PARTIALPRECISION:
+ return "H_SAT";
+
+ case WINED3DSPDM_SATURATE:
+ return "_SAT";
+
+ case WINED3DSPDM_PARTIALPRECISION:
+ return "H";
+
+ case 0:
+ return "";
+
+ default:
+ FIXME("Unknown modifiers 0x%08x\n", mod);
+ return "";
+ }
+}
+
+#define TEX_PROJ 0x1
+#define TEX_BIAS 0x2
+#define TEX_LOD 0x4
+#define TEX_DERIV 0x10
+
+static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD sampler_idx,
+ const char *dst_str, const char *coord_reg, WORD flags, const char *dsx, const char *dsy)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ DWORD sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
+ const char *tex_type;
+ BOOL np2_fixup = FALSE;
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ const char *mod;
+ BOOL pshader = shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type);
+ const struct wined3d_shader *shader;
+ const struct wined3d_device *device;
+ const struct wined3d_gl_info *gl_info;
+
+ /* D3D vertex shader sampler IDs are vertex samplers(0-3), not global d3d samplers */
+ if(!pshader) sampler_idx += MAX_FRAGMENT_SAMPLERS;
+
+ switch(sampler_type) {
+ case WINED3DSTT_1D:
+ tex_type = "1D";
+ break;
+
+ case WINED3DSTT_2D:
+ shader = ins->ctx->shader;
+ device = shader->device;
+ gl_info = &device->adapter->gl_info;
+
+ if (pshader && priv->cur_ps_args->super.np2_fixup & (1 << sampler_idx)
+ && gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ tex_type = "RECT";
+ else
+ tex_type = "2D";
+ if (shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
+ {
+ if (priv->cur_np2fixup_info->super.active & (1 << sampler_idx))
+ {
+ if (flags) FIXME("Only ordinary sampling from NP2 textures is supported.\n");
+ else np2_fixup = TRUE;
+ }
+ }
+ break;
+
+ case WINED3DSTT_VOLUME:
+ tex_type = "3D";
+ break;
+
+ case WINED3DSTT_CUBE:
+ tex_type = "CUBE";
+ break;
+
+ default:
+ ERR("Unexpected texture type %d\n", sampler_type);
+ tex_type = "";
+ }
+
+ /* TEX, TXL, TXD and TXP do not support the "H" modifier,
+ * so don't use shader_arb_get_modifier
+ */
+ if(ins->dst[0].modifiers & WINED3DSPDM_SATURATE) mod = "_SAT";
+ else mod = "";
+
+ /* Fragment samplers always have indentity mapping */
+ if(sampler_idx >= MAX_FRAGMENT_SAMPLERS)
+ {
+ sampler_idx = priv->cur_vs_args->vertex.samplers[sampler_idx - MAX_FRAGMENT_SAMPLERS];
+ }
+
+ if (flags & TEX_DERIV)
+ {
+ if(flags & TEX_PROJ) FIXME("Projected texture sampling with custom derivatives\n");
+ if(flags & TEX_BIAS) FIXME("Biased texture sampling with custom derivatives\n");
+ shader_addline(buffer, "TXD%s %s, %s, %s, %s, texture[%u], %s;\n", mod, dst_str, coord_reg,
+ dsx, dsy,sampler_idx, tex_type);
+ }
+ else if(flags & TEX_LOD)
+ {
+ if(flags & TEX_PROJ) FIXME("Projected texture sampling with explicit lod\n");
+ if(flags & TEX_BIAS) FIXME("Biased texture sampling with explicit lod\n");
+ shader_addline(buffer, "TXL%s %s, %s, texture[%u], %s;\n", mod, dst_str, coord_reg,
+ sampler_idx, tex_type);
+ }
+ else if (flags & TEX_BIAS)
+ {
+ /* Shouldn't be possible, but let's check for it */
+ if(flags & TEX_PROJ) FIXME("Biased and Projected texture sampling\n");
+ /* TXB takes the 4th component of the source vector automatically, as d3d. Nothing more to do */
+ shader_addline(buffer, "TXB%s %s, %s, texture[%u], %s;\n", mod, dst_str, coord_reg, sampler_idx, tex_type);
+ }
+ else if (flags & TEX_PROJ)
+ {
+ shader_addline(buffer, "TXP%s %s, %s, texture[%u], %s;\n", mod, dst_str, coord_reg, sampler_idx, tex_type);
+ }
+ else
+ {
+ if (np2_fixup)
+ {
+ const unsigned char idx = priv->cur_np2fixup_info->super.idx[sampler_idx];
+ shader_addline(buffer, "MUL TA, np2fixup[%u].%s, %s;\n", idx >> 1,
+ (idx % 2) ? "zwxy" : "xyzw", coord_reg);
+
+ shader_addline(buffer, "TEX%s %s, TA, texture[%u], %s;\n", mod, dst_str, sampler_idx, tex_type);
+ }
+ else
+ shader_addline(buffer, "TEX%s %s, %s, texture[%u], %s;\n", mod, dst_str, coord_reg, sampler_idx, tex_type);
+ }
+
+ if (pshader)
+ {
+ gen_color_correction(buffer, dst_str, ins->dst[0].write_mask,
+ arb_get_helper_value(WINED3D_SHADER_TYPE_PIXEL, ARB_ONE),
+ arb_get_helper_value(WINED3D_SHADER_TYPE_PIXEL, ARB_TWO),
+ priv->cur_ps_args->super.color_fixup[sampler_idx]);
+ }
+}
+
+static void shader_arb_get_src_param(const struct wined3d_shader_instruction *ins,
+ const struct wined3d_shader_src_param *src, unsigned int tmpreg, char *outregstr)
+{
+ /* Generate a line that does the input modifier computation and return the input register to use */
+ BOOL is_color = FALSE;
+ char regstr[256];
+ char swzstr[20];
+ int insert_line;
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct shader_arb_ctx_priv *ctx = ins->ctx->backend_data;
+ const char *one = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ONE);
+ const char *two = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_TWO);
+
+ /* Assume a new line will be added */
+ insert_line = 1;
+
+ /* Get register name */
+ shader_arb_get_register_name(ins, &src->reg, regstr, &is_color);
+ shader_arb_get_swizzle(src, is_color, swzstr);
+
+ switch (src->modifiers)
+ {
+ case WINED3DSPSM_NONE:
+ sprintf(outregstr, "%s%s", regstr, swzstr);
+ insert_line = 0;
+ break;
+ case WINED3DSPSM_NEG:
+ sprintf(outregstr, "-%s%s", regstr, swzstr);
+ insert_line = 0;
+ break;
+ case WINED3DSPSM_BIAS:
+ shader_addline(buffer, "ADD T%c, %s, -coefdiv.x;\n", 'A' + tmpreg, regstr);
+ break;
+ case WINED3DSPSM_BIASNEG:
+ shader_addline(buffer, "ADD T%c, -%s, coefdiv.x;\n", 'A' + tmpreg, regstr);
+ break;
+ case WINED3DSPSM_SIGN:
+ shader_addline(buffer, "MAD T%c, %s, %s, -%s;\n", 'A' + tmpreg, regstr, two, one);
+ break;
+ case WINED3DSPSM_SIGNNEG:
+ shader_addline(buffer, "MAD T%c, %s, -%s, %s;\n", 'A' + tmpreg, regstr, two, one);
+ break;
+ case WINED3DSPSM_COMP:
+ shader_addline(buffer, "SUB T%c, %s, %s;\n", 'A' + tmpreg, one, regstr);
+ break;
+ case WINED3DSPSM_X2:
+ shader_addline(buffer, "ADD T%c, %s, %s;\n", 'A' + tmpreg, regstr, regstr);
+ break;
+ case WINED3DSPSM_X2NEG:
+ shader_addline(buffer, "ADD T%c, -%s, -%s;\n", 'A' + tmpreg, regstr, regstr);
+ break;
+ case WINED3DSPSM_DZ:
+ shader_addline(buffer, "RCP T%c, %s.z;\n", 'A' + tmpreg, regstr);
+ shader_addline(buffer, "MUL T%c, %s, T%c;\n", 'A' + tmpreg, regstr, 'A' + tmpreg);
+ break;
+ case WINED3DSPSM_DW:
+ shader_addline(buffer, "RCP T%c, %s.w;\n", 'A' + tmpreg, regstr);
+ shader_addline(buffer, "MUL T%c, %s, T%c;\n", 'A' + tmpreg, regstr, 'A' + tmpreg);
+ break;
+ case WINED3DSPSM_ABS:
+ if(ctx->target_version >= NV2) {
+ sprintf(outregstr, "|%s%s|", regstr, swzstr);
+ insert_line = 0;
+ } else {
+ shader_addline(buffer, "ABS T%c, %s;\n", 'A' + tmpreg, regstr);
+ }
+ break;
+ case WINED3DSPSM_ABSNEG:
+ if(ctx->target_version >= NV2) {
+ sprintf(outregstr, "-|%s%s|", regstr, swzstr);
+ } else {
+ shader_addline(buffer, "ABS T%c, %s;\n", 'A' + tmpreg, regstr);
+ sprintf(outregstr, "-T%c%s", 'A' + tmpreg, swzstr);
+ }
+ insert_line = 0;
+ break;
+ default:
+ sprintf(outregstr, "%s%s", regstr, swzstr);
+ insert_line = 0;
+ }
+
+ /* Return modified or original register, with swizzle */
+ if (insert_line)
+ sprintf(outregstr, "T%c%s", 'A' + tmpreg, swzstr);
+}
+
+static void pshader_hw_bem(const struct wined3d_shader_instruction *ins)
+{
+ const struct wined3d_shader_dst_param *dst = &ins->dst[0];
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ DWORD sampler_code = dst->reg.idx[0].offset;
+ char dst_name[50];
+ char src_name[2][50];
+
+ shader_arb_get_dst_param(ins, dst, dst_name);
+
+ /* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed
+ *
+ * Keep in mind that src_name[1] can be "TB" and src_name[0] can be "TA" because modifiers like _x2 are valid
+ * with bem. So delay loading the first parameter until after the perturbation calculation which needs two
+ * temps is done.
+ */
+ shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
+ shader_addline(buffer, "SWZ TA, bumpenvmat%d, x, z, 0, 0;\n", sampler_code);
+ shader_addline(buffer, "DP3 TC.r, TA, %s;\n", src_name[1]);
+ shader_addline(buffer, "SWZ TA, bumpenvmat%d, y, w, 0, 0;\n", sampler_code);
+ shader_addline(buffer, "DP3 TC.g, TA, %s;\n", src_name[1]);
+
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]);
+ shader_addline(buffer, "ADD %s, %s, TC;\n", dst_name, src_name[0]);
+}
+
+static DWORD negate_modifiers(DWORD mod, char *extra_char)
+{
+ *extra_char = ' ';
+ switch(mod)
+ {
+ case WINED3DSPSM_NONE: return WINED3DSPSM_NEG;
+ case WINED3DSPSM_NEG: return WINED3DSPSM_NONE;
+ case WINED3DSPSM_BIAS: return WINED3DSPSM_BIASNEG;
+ case WINED3DSPSM_BIASNEG: return WINED3DSPSM_BIAS;
+ case WINED3DSPSM_SIGN: return WINED3DSPSM_SIGNNEG;
+ case WINED3DSPSM_SIGNNEG: return WINED3DSPSM_SIGN;
+ case WINED3DSPSM_COMP: *extra_char = '-'; return WINED3DSPSM_COMP;
+ case WINED3DSPSM_X2: return WINED3DSPSM_X2NEG;
+ case WINED3DSPSM_X2NEG: return WINED3DSPSM_X2;
+ case WINED3DSPSM_DZ: *extra_char = '-'; return WINED3DSPSM_DZ;
+ case WINED3DSPSM_DW: *extra_char = '-'; return WINED3DSPSM_DW;
+ case WINED3DSPSM_ABS: return WINED3DSPSM_ABSNEG;
+ case WINED3DSPSM_ABSNEG: return WINED3DSPSM_ABS;
+ }
+ FIXME("Unknown modifier %u\n", mod);
+ return mod;
+}
+
+static void pshader_hw_cnd(const struct wined3d_shader_instruction *ins)
+{
+ const struct wined3d_shader_dst_param *dst = &ins->dst[0];
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char dst_name[50];
+ char src_name[3][50];
+ DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
+ ins->ctx->reg_maps->shader_version.minor);
+
+ shader_arb_get_dst_param(ins, dst, dst_name);
+ shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
+
+ if (shader_version <= WINED3D_SHADER_VERSION(1, 3) && ins->coissue
+ && ins->dst->write_mask != WINED3DSP_WRITEMASK_3)
+ {
+ shader_addline(buffer, "MOV%s %s, %s;\n", shader_arb_get_modifier(ins), dst_name, src_name[1]);
+ }
+ else
+ {
+ struct wined3d_shader_src_param src0_copy = ins->src[0];
+ char extra_neg;
+
+ /* src0 may have a negate srcmod set, so we can't blindly add "-" to the name */
+ src0_copy.modifiers = negate_modifiers(src0_copy.modifiers, &extra_neg);
+
+ shader_arb_get_src_param(ins, &src0_copy, 0, src_name[0]);
+ shader_arb_get_src_param(ins, &ins->src[2], 2, src_name[2]);
+ shader_addline(buffer, "ADD TA, %c%s, coefdiv.x;\n", extra_neg, src_name[0]);
+ shader_addline(buffer, "CMP%s %s, TA, %s, %s;\n", shader_arb_get_modifier(ins),
+ dst_name, src_name[1], src_name[2]);
+ }
+}
+
+static void pshader_hw_cmp(const struct wined3d_shader_instruction *ins)
+{
+ const struct wined3d_shader_dst_param *dst = &ins->dst[0];
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char dst_name[50];
+ char src_name[3][50];
+
+ shader_arb_get_dst_param(ins, dst, dst_name);
+
+ /* Generate input register names (with modifiers) */
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]);
+ shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
+ shader_arb_get_src_param(ins, &ins->src[2], 2, src_name[2]);
+
+ shader_addline(buffer, "CMP%s %s, %s, %s, %s;\n", shader_arb_get_modifier(ins),
+ dst_name, src_name[0], src_name[2], src_name[1]);
+}
+
+/** Process the WINED3DSIO_DP2ADD instruction in ARB.
+ * dst = dot2(src0, src1) + src2 */
+static void pshader_hw_dp2add(const struct wined3d_shader_instruction *ins)
+{
+ const struct wined3d_shader_dst_param *dst = &ins->dst[0];
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char dst_name[50];
+ char src_name[3][50];
+ struct shader_arb_ctx_priv *ctx = ins->ctx->backend_data;
+
+ shader_arb_get_dst_param(ins, dst, dst_name);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]);
+ shader_arb_get_src_param(ins, &ins->src[2], 2, src_name[2]);
+
+ if(ctx->target_version >= NV3)
+ {
+ /* GL_NV_fragment_program2 has a 1:1 matching instruction */
+ shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
+ shader_addline(buffer, "DP2A%s %s, %s, %s, %s;\n", shader_arb_get_modifier(ins),
+ dst_name, src_name[0], src_name[1], src_name[2]);
+ }
+ else if(ctx->target_version >= NV2)
+ {
+ /* dst.x = src2.?, src0.x, src1.x + src0.y * src1.y
+ * dst.y = src2.?, src0.x, src1.z + src0.y * src1.w
+ * dst.z = src2.?, src0.x, src1.x + src0.y * src1.y
+ * dst.z = src2.?, src0.x, src1.z + src0.y * src1.w
+ *
+ * Make sure that src1.zw = src1.xy, then we get a classic dp2add
+ *
+ * .xyxy and other swizzles that we could get with this are not valid in
+ * plain ARBfp, but luckily the NV extension grammar lifts this limitation.
+ */
+ struct wined3d_shader_src_param tmp_param = ins->src[1];
+ DWORD swizzle = tmp_param.swizzle & 0xf; /* Selects .xy */
+ tmp_param.swizzle = swizzle | (swizzle << 4); /* Creates .xyxy */
+
+ shader_arb_get_src_param(ins, &tmp_param, 1, src_name[1]);
+
+ shader_addline(buffer, "X2D%s %s, %s, %s, %s;\n", shader_arb_get_modifier(ins),
+ dst_name, src_name[2], src_name[0], src_name[1]);
+ }
+ else
+ {
+ shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
+ /* Emulate a DP2 with a DP3 and 0.0. Don't use the dest as temp register, it could be src[1] or src[2]
+ * src_name[0] can be TA, but TA is a private temp for modifiers, so it is save to overwrite
+ */
+ shader_addline(buffer, "MOV TA, %s;\n", src_name[0]);
+ shader_addline(buffer, "MOV TA.z, 0.0;\n");
+ shader_addline(buffer, "DP3 TA, TA, %s;\n", src_name[1]);
+ shader_addline(buffer, "ADD%s %s, TA, %s;\n", shader_arb_get_modifier(ins), dst_name, src_name[2]);
+ }
+}
+
+/* Map the opcode 1-to-1 to the GL code */
+static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ const char *instruction;
+ char arguments[256], dst_str[50];
+ unsigned int i;
+ const struct wined3d_shader_dst_param *dst = &ins->dst[0];
+
+ switch (ins->handler_idx)
+ {
+ case WINED3DSIH_ABS: instruction = "ABS"; break;
+ case WINED3DSIH_ADD: instruction = "ADD"; break;
+ case WINED3DSIH_CRS: instruction = "XPD"; break;
+ case WINED3DSIH_DP3: instruction = "DP3"; break;
+ case WINED3DSIH_DP4: instruction = "DP4"; break;
+ case WINED3DSIH_DST: instruction = "DST"; break;
+ case WINED3DSIH_FRC: instruction = "FRC"; break;
+ case WINED3DSIH_LIT: instruction = "LIT"; break;
+ case WINED3DSIH_LRP: instruction = "LRP"; break;
+ case WINED3DSIH_MAD: instruction = "MAD"; break;
+ case WINED3DSIH_MAX: instruction = "MAX"; break;
+ case WINED3DSIH_MIN: instruction = "MIN"; break;
+ case WINED3DSIH_MOV: instruction = "MOV"; break;
+ case WINED3DSIH_MUL: instruction = "MUL"; break;
+ case WINED3DSIH_SGE: instruction = "SGE"; break;
+ case WINED3DSIH_SLT: instruction = "SLT"; break;
+ case WINED3DSIH_SUB: instruction = "SUB"; break;
+ case WINED3DSIH_MOVA:instruction = "ARR"; break;
+ case WINED3DSIH_DSX: instruction = "DDX"; break;
+ default: instruction = "";
+ FIXME("Unhandled opcode %#x\n", ins->handler_idx);
+ break;
+ }
+
+ /* Note that shader_arb_add_dst_param() adds spaces. */
+ arguments[0] = '\0';
+ shader_arb_get_dst_param(ins, dst, dst_str);
+ for (i = 0; i < ins->src_count; ++i)
+ {
+ char operand[100];
+ strcat(arguments, ", ");
+ shader_arb_get_src_param(ins, &ins->src[i], i, operand);
+ strcat(arguments, operand);
+ }
+ shader_addline(buffer, "%s%s %s%s;\n", instruction, shader_arb_get_modifier(ins), dst_str, arguments);
+}
+
+static void shader_hw_nop(const struct wined3d_shader_instruction *ins) {}
+
+static void shader_hw_mov(const struct wined3d_shader_instruction *ins)
+{
+ const struct wined3d_shader *shader = ins->ctx->shader;
+ const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
+ BOOL pshader = shader_is_pshader_version(reg_maps->shader_version.type);
+ struct shader_arb_ctx_priv *ctx = ins->ctx->backend_data;
+ const char *zero = arb_get_helper_value(reg_maps->shader_version.type, ARB_ZERO);
+ const char *one = arb_get_helper_value(reg_maps->shader_version.type, ARB_ONE);
+ const char *two = arb_get_helper_value(reg_maps->shader_version.type, ARB_TWO);
+
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char src0_param[256];
+
+ if (ins->handler_idx == WINED3DSIH_MOVA)
+ {
+ const struct arb_vshader_private *shader_data = shader->backend_data;
+ char write_mask[6];
+ const char *offset = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_VS_REL_OFFSET);
+
+ if(ctx->target_version >= NV2) {
+ shader_hw_map2gl(ins);
+ return;
+ }
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0_param);
+ shader_arb_get_write_mask(ins, &ins->dst[0], write_mask);
+
+ /* This implements the mova formula used in GLSL. The first two instructions
+ * prepare the sign() part. Note that it is fine to have my_sign(0.0) = 1.0
+ * in this case:
+ * mova A0.x, 0.0
+ *
+ * A0.x = arl(floor(abs(0.0) + 0.5) * 1.0) = floor(0.5) = 0.0 since arl does a floor
+ *
+ * The ARL is performed when A0 is used - the requested component is read from A0_SHADOW into
+ * A0.x. We can use the overwritten component of A0_shadow as temporary storage for the sign.
+ */
+ shader_addline(buffer, "SGE A0_SHADOW%s, %s, %s;\n", write_mask, src0_param, zero);
+ shader_addline(buffer, "MAD A0_SHADOW%s, A0_SHADOW, %s, -%s;\n", write_mask, two, one);
+
+ shader_addline(buffer, "ABS TA%s, %s;\n", write_mask, src0_param);
+ shader_addline(buffer, "ADD TA%s, TA, rel_addr_const.x;\n", write_mask);
+ shader_addline(buffer, "FLR TA%s, TA;\n", write_mask);
+ if (shader_data->rel_offset)
+ {
+ shader_addline(buffer, "ADD TA%s, TA, %s;\n", write_mask, offset);
+ }
+ shader_addline(buffer, "MUL A0_SHADOW%s, TA, A0_SHADOW;\n", write_mask);
+
+ ((struct shader_arb_ctx_priv *)ins->ctx->backend_data)->addr_reg[0] = '\0';
+ }
+ else if (reg_maps->shader_version.major == 1
+ && !shader_is_pshader_version(reg_maps->shader_version.type)
+ && ins->dst[0].reg.type == WINED3DSPR_ADDR)
+ {
+ const struct arb_vshader_private *shader_data = shader->backend_data;
+ src0_param[0] = '\0';
+
+ if (shader_data->rel_offset)
+ {
+ const char *offset = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_VS_REL_OFFSET);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0_param);
+ shader_addline(buffer, "ADD TA.x, %s, %s;\n", src0_param, offset);
+ shader_addline(buffer, "ARL A0.x, TA.x;\n");
+ }
+ else
+ {
+ /* Apple's ARB_vertex_program implementation does not accept an ARL source argument
+ * with more than one component. Thus replicate the first source argument over all
+ * 4 components. For example, .xyzw -> .x (or better: .xxxx), .zwxy -> .z, etc) */
+ struct wined3d_shader_src_param tmp_src = ins->src[0];
+ tmp_src.swizzle = (tmp_src.swizzle & 0x3) * 0x55;
+ shader_arb_get_src_param(ins, &tmp_src, 0, src0_param);
+ shader_addline(buffer, "ARL A0.x, %s;\n", src0_param);
+ }
+ }
+ else if (ins->dst[0].reg.type == WINED3DSPR_COLOROUT && !ins->dst[0].reg.idx[0].offset && pshader)
+ {
+ if (ctx->ps_post_process && shader->u.ps.color0_mov)
+ {
+ shader_addline(buffer, "#mov handled in srgb write or fog code\n");
+ return;
+ }
+ shader_hw_map2gl(ins);
+ }
+ else
+ {
+ shader_hw_map2gl(ins);
+ }
+}
+
+static void pshader_hw_texkill(const struct wined3d_shader_instruction *ins)
+{
+ const struct wined3d_shader_dst_param *dst = &ins->dst[0];
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char reg_dest[40];
+
+ /* No swizzles are allowed in d3d's texkill. PS 1.x ignores the 4th component as documented,
+ * but >= 2.0 honors it (undocumented, but tested by the d3d9 testsuite)
+ */
+ shader_arb_get_dst_param(ins, dst, reg_dest);
+
+ if (ins->ctx->reg_maps->shader_version.major >= 2)
+ {
+ const char *kilsrc = "TA";
+ BOOL is_color;
+
+ shader_arb_get_register_name(ins, &dst->reg, reg_dest, &is_color);
+ if(dst->write_mask == WINED3DSP_WRITEMASK_ALL)
+ {
+ kilsrc = reg_dest;
+ }
+ else
+ {
+ /* Sigh. KIL doesn't support swizzles/writemasks. KIL passes a writemask, but ".xy" for example
+ * is not valid as a swizzle in ARB (needs ".xyyy"). Use SWZ to load the register properly, and set
+ * masked out components to 0(won't kill)
+ */
+ char x = '0', y = '0', z = '0', w = '0';
+ if(dst->write_mask & WINED3DSP_WRITEMASK_0) x = 'x';
+ if(dst->write_mask & WINED3DSP_WRITEMASK_1) y = 'y';
+ if(dst->write_mask & WINED3DSP_WRITEMASK_2) z = 'z';
+ if(dst->write_mask & WINED3DSP_WRITEMASK_3) w = 'w';
+ shader_addline(buffer, "SWZ TA, %s, %c, %c, %c, %c;\n", reg_dest, x, y, z, w);
+ }
+ shader_addline(buffer, "KIL %s;\n", kilsrc);
+ }
+ else
+ {
+ /* ARB fp doesn't like swizzles on the parameter of the KIL instruction. To mask the 4th component,
+ * copy the register into our general purpose TMP variable, overwrite .w and pass TMP to KIL
+ *
+ * ps_1_3 shaders use the texcoord incarnation of the Tx register. ps_1_4 shaders can use the same,
+ * or pass in any temporary register(in shader phase 2)
+ */
+ if (ins->ctx->reg_maps->shader_version.minor <= 3)
+ sprintf(reg_dest, "fragment.texcoord[%u]", dst->reg.idx[0].offset);
+ else
+ shader_arb_get_dst_param(ins, dst, reg_dest);
+ shader_addline(buffer, "SWZ TA, %s, x, y, z, 1;\n", reg_dest);
+ shader_addline(buffer, "KIL TA;\n");
+ }
+}
+
+static void pshader_hw_tex(const struct wined3d_shader_instruction *ins)
+{
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ const struct wined3d_shader_dst_param *dst = &ins->dst[0];
+ DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
+ ins->ctx->reg_maps->shader_version.minor);
+ struct wined3d_shader_src_param src;
+
+ char reg_dest[40];
+ char reg_coord[40];
+ DWORD reg_sampler_code;
+ WORD myflags = 0;
+ BOOL swizzle_coord = FALSE;
+
+ /* All versions have a destination register */
+ shader_arb_get_dst_param(ins, dst, reg_dest);
+
+ /* 1.0-1.4: Use destination register number as texture code.
+ 2.0+: Use provided sampler number as texure code. */
+ if (shader_version < WINED3D_SHADER_VERSION(2,0))
+ reg_sampler_code = dst->reg.idx[0].offset;
+ else
+ reg_sampler_code = ins->src[1].reg.idx[0].offset;
+
+ /* 1.0-1.3: Use the texcoord varying.
+ 1.4+: Use provided coordinate source register. */
+ if (shader_version < WINED3D_SHADER_VERSION(1,4))
+ sprintf(reg_coord, "fragment.texcoord[%u]", reg_sampler_code);
+ else {
+ /* TEX is the only instruction that can handle DW and DZ natively */
+ src = ins->src[0];
+ if(src.modifiers == WINED3DSPSM_DW) src.modifiers = WINED3DSPSM_NONE;
+ if(src.modifiers == WINED3DSPSM_DZ) src.modifiers = WINED3DSPSM_NONE;
+ shader_arb_get_src_param(ins, &src, 0, reg_coord);
+ }
+
+ /* projection flag:
+ * 1.1, 1.2, 1.3: Use WINED3D_TSS_TEXTURETRANSFORMFLAGS
+ * 1.4: Use WINED3DSPSM_DZ or WINED3DSPSM_DW on src[0]
+ * 2.0+: Use WINED3DSI_TEXLD_PROJECT on the opcode
+ */
+ if (shader_version < WINED3D_SHADER_VERSION(1,4))
+ {
+ DWORD flags = 0;
+ if (reg_sampler_code < MAX_TEXTURES)
+ flags = priv->cur_ps_args->super.tex_transform >> reg_sampler_code * WINED3D_PSARGS_TEXTRANSFORM_SHIFT;
+ if (flags & WINED3D_PSARGS_PROJECTED)
+ {
+ myflags |= TEX_PROJ;
+ if ((flags & ~WINED3D_PSARGS_PROJECTED) == WINED3D_TTFF_COUNT3)
+ swizzle_coord = TRUE;
+ }
+ }
+ else if (shader_version < WINED3D_SHADER_VERSION(2,0))
+ {
+ enum wined3d_shader_src_modifier src_mod = ins->src[0].modifiers;
+ if (src_mod == WINED3DSPSM_DZ)
+ {
+ swizzle_coord = TRUE;
+ myflags |= TEX_PROJ;
+ } else if(src_mod == WINED3DSPSM_DW) {
+ myflags |= TEX_PROJ;
+ }
+ } else {
+ if (ins->flags & WINED3DSI_TEXLD_PROJECT) myflags |= TEX_PROJ;
+ if (ins->flags & WINED3DSI_TEXLD_BIAS) myflags |= TEX_BIAS;
+ }
+
+ if (swizzle_coord)
+ {
+ /* TXP cannot handle DZ natively, so move the z coordinate to .w.
+ * reg_coord is a read-only varying register, so we need a temp reg */
+ shader_addline(ins->ctx->buffer, "SWZ TA, %s, x, y, z, z;\n", reg_coord);
+ strcpy(reg_coord, "TA");
+ }
+
+ shader_hw_sample(ins, reg_sampler_code, reg_dest, reg_coord, myflags, NULL, NULL);
+}
+
+static void pshader_hw_texcoord(const struct wined3d_shader_instruction *ins)
+{
+ const struct wined3d_shader_dst_param *dst = &ins->dst[0];
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
+ ins->ctx->reg_maps->shader_version.minor);
+ char dst_str[50];
+
+ if (shader_version < WINED3D_SHADER_VERSION(1,4))
+ {
+ DWORD reg = dst->reg.idx[0].offset;
+
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
+ shader_addline(buffer, "MOV_SAT %s, fragment.texcoord[%u];\n", dst_str, reg);
+ } else {
+ char reg_src[40];
+
+ shader_arb_get_src_param(ins, &ins->src[0], 0, reg_src);
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
+ shader_addline(buffer, "MOV %s, %s;\n", dst_str, reg_src);
+ }
+}
+
+static void pshader_hw_texreg2ar(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ DWORD flags = 0;
+
+ DWORD reg1 = ins->dst[0].reg.idx[0].offset;
+ char dst_str[50];
+ char src_str[50];
+
+ /* Note that texreg2ar treats Tx as a temporary register, not as a varying */
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_str);
+ /* Move .x first in case src_str is "TA" */
+ shader_addline(buffer, "MOV TA.y, %s.x;\n", src_str);
+ shader_addline(buffer, "MOV TA.x, %s.w;\n", src_str);
+ if (reg1 < MAX_TEXTURES)
+ {
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ flags = priv->cur_ps_args->super.tex_transform >> reg1 * WINED3D_PSARGS_TEXTRANSFORM_SHIFT;
+ }
+ shader_hw_sample(ins, reg1, dst_str, "TA", flags & WINED3D_PSARGS_PROJECTED ? TEX_PROJ : 0, NULL, NULL);
+}
+
+static void pshader_hw_texreg2gb(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+
+ DWORD reg1 = ins->dst[0].reg.idx[0].offset;
+ char dst_str[50];
+ char src_str[50];
+
+ /* Note that texreg2gb treats Tx as a temporary register, not as a varying */
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_str);
+ shader_addline(buffer, "MOV TA.x, %s.y;\n", src_str);
+ shader_addline(buffer, "MOV TA.y, %s.z;\n", src_str);
+ shader_hw_sample(ins, reg1, dst_str, "TA", 0, NULL, NULL);
+}
+
+static void pshader_hw_texreg2rgb(const struct wined3d_shader_instruction *ins)
+{
+ DWORD reg1 = ins->dst[0].reg.idx[0].offset;
+ char dst_str[50];
+ char src_str[50];
+
+ /* Note that texreg2rg treats Tx as a temporary register, not as a varying */
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_str);
+ shader_hw_sample(ins, reg1, dst_str, src_str, 0, NULL, NULL);
+}
+
+static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins)
+{
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ const struct wined3d_shader_dst_param *dst = &ins->dst[0];
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char reg_coord[40], dst_reg[50], src_reg[50];
+ DWORD reg_dest_code;
+
+ /* All versions have a destination register. The Tx where the texture coordinates come
+ * from is the varying incarnation of the texture register
+ */
+ reg_dest_code = dst->reg.idx[0].offset;
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst_reg);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_reg);
+ sprintf(reg_coord, "fragment.texcoord[%u]", reg_dest_code);
+
+ /* Sampling the perturbation map in Tsrc was done already, including the signedness correction if needed
+ * The Tx in which the perturbation map is stored is the tempreg incarnation of the texture register
+ *
+ * GL_NV_fragment_program_option could handle this in one instruction via X2D:
+ * X2D TA.xy, fragment.texcoord, T%u, bumpenvmat%u.xzyw
+ *
+ * However, the NV extensions are never enabled for <= 2.0 shaders because of the performance penalty that
+ * comes with it, and texbem is an 1.x only instruction. No 1.x instruction forces us to enable the NV
+ * extension.
+ */
+ shader_addline(buffer, "SWZ TB, bumpenvmat%d, x, z, 0, 0;\n", reg_dest_code);
+ shader_addline(buffer, "DP3 TA.x, TB, %s;\n", src_reg);
+ shader_addline(buffer, "SWZ TB, bumpenvmat%d, y, w, 0, 0;\n", reg_dest_code);
+ shader_addline(buffer, "DP3 TA.y, TB, %s;\n", src_reg);
+
+ /* with projective textures, texbem only divides the static texture coord, not the displacement,
+ * so we can't let the GL handle this.
+ */
+ if ((priv->cur_ps_args->super.tex_transform >> reg_dest_code * WINED3D_PSARGS_TEXTRANSFORM_SHIFT)
+ & WINED3D_PSARGS_PROJECTED)
+ {
+ shader_addline(buffer, "RCP TB.w, %s.w;\n", reg_coord);
+ shader_addline(buffer, "MUL TB.xy, %s, TB.w;\n", reg_coord);
+ shader_addline(buffer, "ADD TA.xy, TA, TB;\n");
+ } else {
+ shader_addline(buffer, "ADD TA.xy, TA, %s;\n", reg_coord);
+ }
+
+ shader_hw_sample(ins, reg_dest_code, dst_reg, "TA", 0, NULL, NULL);
+
+ if (ins->handler_idx == WINED3DSIH_TEXBEML)
+ {
+ /* No src swizzles are allowed, so this is ok */
+ shader_addline(buffer, "MAD TA, %s.z, luminance%d.x, luminance%d.y;\n",
+ src_reg, reg_dest_code, reg_dest_code);
+ shader_addline(buffer, "MUL %s, %s, TA;\n", dst_reg, dst_reg);
+ }
+}
+
+static void pshader_hw_texm3x2pad(const struct wined3d_shader_instruction *ins)
+{
+ DWORD reg = ins->dst[0].reg.idx[0].offset;
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char src0_name[50], dst_name[50];
+ BOOL is_color;
+ struct wined3d_shader_register tmp_reg = ins->dst[0].reg;
+
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
+ /* The next instruction will be a texm3x2tex or texm3x2depth that writes to the uninitialized
+ * T<reg+1> register. Use this register to store the calculated vector
+ */
+ tmp_reg.idx[0].offset = reg + 1;
+ shader_arb_get_register_name(ins, &tmp_reg, dst_name, &is_color);
+ shader_addline(buffer, "DP3 %s.x, fragment.texcoord[%u], %s;\n", dst_name, reg, src0_name);
+}
+
+static void pshader_hw_texm3x2tex(const struct wined3d_shader_instruction *ins)
+{
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ DWORD flags;
+ DWORD reg = ins->dst[0].reg.idx[0].offset;
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char dst_str[50];
+ char src0_name[50];
+ char dst_reg[50];
+ BOOL is_color;
+
+ /* We know that we're writing to the uninitialized T<reg> register, so use it for temporary storage */
+ shader_arb_get_register_name(ins, &ins->dst[0].reg, dst_reg, &is_color);
+
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
+ shader_addline(buffer, "DP3 %s.y, fragment.texcoord[%u], %s;\n", dst_reg, reg, src0_name);
+ flags = reg < MAX_TEXTURES ? priv->cur_ps_args->super.tex_transform >> reg * WINED3D_PSARGS_TEXTRANSFORM_SHIFT : 0;
+ shader_hw_sample(ins, reg, dst_str, dst_reg, flags & WINED3D_PSARGS_PROJECTED ? TEX_PROJ : 0, NULL, NULL);
+}
+
+static void pshader_hw_texm3x3pad(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
+ DWORD reg = ins->dst[0].reg.idx[0].offset;
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char src0_name[50], dst_name[50];
+ struct wined3d_shader_register tmp_reg = ins->dst[0].reg;
+ BOOL is_color;
+
+ /* There are always 2 texm3x3pad instructions followed by one texm3x3[tex,vspec, ...] instruction, with
+ * incrementing ins->dst[0].register_idx numbers. So the pad instruction already knows the final destination
+ * register, and this register is uninitialized(otherwise the assembler complains that it is 'redeclared')
+ */
+ tmp_reg.idx[0].offset = reg + 2 - tex_mx->current_row;
+ shader_arb_get_register_name(ins, &tmp_reg, dst_name, &is_color);
+
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
+ shader_addline(buffer, "DP3 %s.%c, fragment.texcoord[%u], %s;\n",
+ dst_name, 'x' + tex_mx->current_row, reg, src0_name);
+ tex_mx->texcoord_w[tex_mx->current_row++] = reg;
+}
+
+static void pshader_hw_texm3x3tex(const struct wined3d_shader_instruction *ins)
+{
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
+ DWORD flags;
+ DWORD reg = ins->dst[0].reg.idx[0].offset;
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char dst_str[50];
+ char src0_name[50], dst_name[50];
+ BOOL is_color;
+
+ shader_arb_get_register_name(ins, &ins->dst[0].reg, dst_name, &is_color);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
+ shader_addline(buffer, "DP3 %s.z, fragment.texcoord[%u], %s;\n", dst_name, reg, src0_name);
+
+ /* Sample the texture using the calculated coordinates */
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
+ flags = reg < MAX_TEXTURES ? priv->cur_ps_args->super.tex_transform >> reg * WINED3D_PSARGS_TEXTRANSFORM_SHIFT : 0;
+ shader_hw_sample(ins, reg, dst_str, dst_name, flags & WINED3D_PSARGS_PROJECTED ? TEX_PROJ : 0, NULL, NULL);
+ tex_mx->current_row = 0;
+}
+
+static void pshader_hw_texm3x3vspec(const struct wined3d_shader_instruction *ins)
+{
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
+ DWORD flags;
+ DWORD reg = ins->dst[0].reg.idx[0].offset;
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char dst_str[50];
+ char src0_name[50];
+ char dst_reg[50];
+ BOOL is_color;
+
+ /* Get the dst reg without writemask strings. We know this register is uninitialized, so we can use all
+ * components for temporary data storage
+ */
+ shader_arb_get_register_name(ins, &ins->dst[0].reg, dst_reg, &is_color);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
+ shader_addline(buffer, "DP3 %s.z, fragment.texcoord[%u], %s;\n", dst_reg, reg, src0_name);
+
+ /* Construct the eye-ray vector from w coordinates */
+ shader_addline(buffer, "MOV TB.x, fragment.texcoord[%u].w;\n", tex_mx->texcoord_w[0]);
+ shader_addline(buffer, "MOV TB.y, fragment.texcoord[%u].w;\n", tex_mx->texcoord_w[1]);
+ shader_addline(buffer, "MOV TB.z, fragment.texcoord[%u].w;\n", reg);
+
+ /* Calculate reflection vector
+ */
+ shader_addline(buffer, "DP3 %s.w, %s, TB;\n", dst_reg, dst_reg);
+ /* The .w is ignored when sampling, so I can use TB.w to calculate dot(N, N) */
+ shader_addline(buffer, "DP3 TB.w, %s, %s;\n", dst_reg, dst_reg);
+ shader_addline(buffer, "RCP TB.w, TB.w;\n");
+ shader_addline(buffer, "MUL %s.w, %s.w, TB.w;\n", dst_reg, dst_reg);
+ shader_addline(buffer, "MUL %s, %s.w, %s;\n", dst_reg, dst_reg, dst_reg);
+ shader_addline(buffer, "MAD %s, coefmul.x, %s, -TB;\n", dst_reg, dst_reg);
+
+ /* Sample the texture using the calculated coordinates */
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
+ flags = reg < MAX_TEXTURES ? priv->cur_ps_args->super.tex_transform >> reg * WINED3D_PSARGS_TEXTRANSFORM_SHIFT : 0;
+ shader_hw_sample(ins, reg, dst_str, dst_reg, flags & WINED3D_PSARGS_PROJECTED ? TEX_PROJ : 0, NULL, NULL);
+ tex_mx->current_row = 0;
+}
+
+static void pshader_hw_texm3x3spec(const struct wined3d_shader_instruction *ins)
+{
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
+ DWORD flags;
+ DWORD reg = ins->dst[0].reg.idx[0].offset;
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char dst_str[50];
+ char src0_name[50];
+ char src1_name[50];
+ char dst_reg[50];
+ BOOL is_color;
+
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0_name);
+ shader_arb_get_src_param(ins, &ins->src[0], 1, src1_name);
+ shader_arb_get_register_name(ins, &ins->dst[0].reg, dst_reg, &is_color);
+ /* Note: dst_reg.xy is input here, generated by two texm3x3pad instructions */
+ shader_addline(buffer, "DP3 %s.z, fragment.texcoord[%u], %s;\n", dst_reg, reg, src0_name);
+
+ /* Calculate reflection vector.
+ *
+ * dot(N, E)
+ * dst_reg.xyz = 2 * --------- * N - E
+ * dot(N, N)
+ *
+ * Which normalizes the normal vector
+ */
+ shader_addline(buffer, "DP3 %s.w, %s, %s;\n", dst_reg, dst_reg, src1_name);
+ shader_addline(buffer, "DP3 TC.w, %s, %s;\n", dst_reg, dst_reg);
+ shader_addline(buffer, "RCP TC.w, TC.w;\n");
+ shader_addline(buffer, "MUL %s.w, %s.w, TC.w;\n", dst_reg, dst_reg);
+ shader_addline(buffer, "MUL %s, %s.w, %s;\n", dst_reg, dst_reg, dst_reg);
+ shader_addline(buffer, "MAD %s, coefmul.x, %s, -%s;\n", dst_reg, dst_reg, src1_name);
+
+ /* Sample the texture using the calculated coordinates */
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
+ flags = reg < MAX_TEXTURES ? priv->cur_ps_args->super.tex_transform >> reg * WINED3D_PSARGS_TEXTRANSFORM_SHIFT : 0;
+ shader_hw_sample(ins, reg, dst_str, dst_reg, flags & WINED3D_PSARGS_PROJECTED ? TEX_PROJ : 0, NULL, NULL);
+ tex_mx->current_row = 0;
+}
+
+static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins)
+{
+ const struct wined3d_shader_dst_param *dst = &ins->dst[0];
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char dst_name[50];
+ const char *zero = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ZERO);
+ const char *one = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ONE);
+
+ /* texdepth has an implicit destination, the fragment depth value. It's only parameter,
+ * which is essentially an input, is the destination register because it is the first
+ * parameter. According to the msdn, this must be register r5, but let's keep it more flexible
+ * here(writemasks/swizzles are not valid on texdepth)
+ */
+ shader_arb_get_dst_param(ins, dst, dst_name);
+
+ /* According to the msdn, the source register(must be r5) is unusable after
+ * the texdepth instruction, so we're free to modify it
+ */
+ shader_addline(buffer, "MIN %s.y, %s.y, %s;\n", dst_name, dst_name, one);
+
+ /* How to deal with the special case dst_name.g == 0? if r != 0, then
+ * the r * (1 / 0) will give infinity, which is clamped to 1.0, the correct
+ * result. But if r = 0.0, then 0 * inf = 0, which is incorrect.
+ */
+ shader_addline(buffer, "RCP %s.y, %s.y;\n", dst_name, dst_name);
+ shader_addline(buffer, "MUL TA.x, %s.x, %s.y;\n", dst_name, dst_name);
+ shader_addline(buffer, "MIN TA.x, TA.x, %s;\n", one);
+ shader_addline(buffer, "MAX result.depth, TA.x, %s;\n", zero);
+}
+
+/** Process the WINED3DSIO_TEXDP3TEX instruction in ARB:
+ * Take a 3-component dot product of the TexCoord[dstreg] and src,
+ * then perform a 1D texture lookup from stage dstregnum, place into dst. */
+static void pshader_hw_texdp3tex(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ DWORD sampler_idx = ins->dst[0].reg.idx[0].offset;
+ char src0[50];
+ char dst_str[50];
+
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
+ shader_addline(buffer, "MOV TB, 0.0;\n");
+ shader_addline(buffer, "DP3 TB.x, fragment.texcoord[%u], %s;\n", sampler_idx, src0);
+
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst_str);
+ shader_hw_sample(ins, sampler_idx, dst_str, "TB", 0 /* Only one coord, can't be projected */, NULL, NULL);
+}
+
+/** Process the WINED3DSIO_TEXDP3 instruction in ARB:
+ * Take a 3-component dot product of the TexCoord[dstreg] and src. */
+static void pshader_hw_texdp3(const struct wined3d_shader_instruction *ins)
+{
+ const struct wined3d_shader_dst_param *dst = &ins->dst[0];
+ char src0[50];
+ char dst_str[50];
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+
+ /* Handle output register */
+ shader_arb_get_dst_param(ins, dst, dst_str);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
+ shader_addline(buffer, "DP3 %s, fragment.texcoord[%u], %s;\n", dst_str, dst->reg.idx[0].offset, src0);
+}
+
+/** Process the WINED3DSIO_TEXM3X3 instruction in ARB
+ * Perform the 3rd row of a 3x3 matrix multiply */
+static void pshader_hw_texm3x3(const struct wined3d_shader_instruction *ins)
+{
+ const struct wined3d_shader_dst_param *dst = &ins->dst[0];
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char dst_str[50], dst_name[50];
+ char src0[50];
+ BOOL is_color;
+
+ shader_arb_get_dst_param(ins, dst, dst_str);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
+ shader_arb_get_register_name(ins, &ins->dst[0].reg, dst_name, &is_color);
+ shader_addline(buffer, "DP3 %s.z, fragment.texcoord[%u], %s;\n", dst_name, dst->reg.idx[0].offset, src0);
+ shader_addline(buffer, "MOV %s, %s;\n", dst_str, dst_name);
+}
+
+/** Process the WINED3DSIO_TEXM3X2DEPTH instruction in ARB:
+ * Last row of a 3x2 matrix multiply, use the result to calculate the depth:
+ * Calculate tmp0.y = TexCoord[dstreg] . src.xyz; (tmp0.x has already been calculated)
+ * depth = (tmp0.y == 0.0) ? 1.0 : tmp0.x / tmp0.y
+ */
+static void pshader_hw_texm3x2depth(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ const struct wined3d_shader_dst_param *dst = &ins->dst[0];
+ char src0[50], dst_name[50];
+ BOOL is_color;
+ const char *zero = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ZERO);
+ const char *one = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ONE);
+
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src0);
+ shader_arb_get_register_name(ins, &ins->dst[0].reg, dst_name, &is_color);
+ shader_addline(buffer, "DP3 %s.y, fragment.texcoord[%u], %s;\n", dst_name, dst->reg.idx[0].offset, src0);
+
+ /* How to deal with the special case dst_name.g == 0? if r != 0, then
+ * the r * (1 / 0) will give infinity, which is clamped to 1.0, the correct
+ * result. But if r = 0.0, then 0 * inf = 0, which is incorrect.
+ */
+ shader_addline(buffer, "RCP %s.y, %s.y;\n", dst_name, dst_name);
+ shader_addline(buffer, "MUL %s.x, %s.x, %s.y;\n", dst_name, dst_name, dst_name);
+ shader_addline(buffer, "MIN %s.x, %s.x, %s;\n", dst_name, dst_name, one);
+ shader_addline(buffer, "MAX result.depth, %s.x, %s;\n", dst_name, zero);
+}
+
+/** Handles transforming all WINED3DSIO_M?x? opcodes for
+ Vertex/Pixel shaders to ARB_vertex_program codes */
+static void shader_hw_mnxn(const struct wined3d_shader_instruction *ins)
+{
+ int i;
+ int nComponents = 0;
+ struct wined3d_shader_dst_param tmp_dst = {{0}};
+ struct wined3d_shader_src_param tmp_src[2] = {{{0}}};
+ struct wined3d_shader_instruction tmp_ins;
+
+ memset(&tmp_ins, 0, sizeof(tmp_ins));
+
+ /* Set constants for the temporary argument */
+ tmp_ins.ctx = ins->ctx;
+ tmp_ins.dst_count = 1;
+ tmp_ins.dst = &tmp_dst;
+ tmp_ins.src_count = 2;
+ tmp_ins.src = tmp_src;
+
+ switch(ins->handler_idx)
+ {
+ case WINED3DSIH_M4x4:
+ nComponents = 4;
+ tmp_ins.handler_idx = WINED3DSIH_DP4;
+ break;
+ case WINED3DSIH_M4x3:
+ nComponents = 3;
+ tmp_ins.handler_idx = WINED3DSIH_DP4;
+ break;
+ case WINED3DSIH_M3x4:
+ nComponents = 4;
+ tmp_ins.handler_idx = WINED3DSIH_DP3;
+ break;
+ case WINED3DSIH_M3x3:
+ nComponents = 3;
+ tmp_ins.handler_idx = WINED3DSIH_DP3;
+ break;
+ case WINED3DSIH_M3x2:
+ nComponents = 2;
+ tmp_ins.handler_idx = WINED3DSIH_DP3;
+ break;
+ default:
+ FIXME("Unhandled opcode %#x\n", ins->handler_idx);
+ break;
+ }
+
+ tmp_dst = ins->dst[0];
+ tmp_src[0] = ins->src[0];
+ tmp_src[1] = ins->src[1];
+ for (i = 0; i < nComponents; ++i)
+ {
+ tmp_dst.write_mask = WINED3DSP_WRITEMASK_0 << i;
+ shader_hw_map2gl(&tmp_ins);
+ ++tmp_src[1].reg.idx[0].offset;
+ }
+}
+
+static void shader_hw_rcp(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+
+ char dst[50];
+ char src[50];
+
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst); /* Destination */
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src);
+ if (ins->src[0].swizzle == WINED3DSP_NOSWIZZLE)
+ {
+ /* Dx sdk says .x is used if no swizzle is given, but our test shows that
+ * .w is used
+ */
+ strcat(src, ".w");
+ }
+
+ shader_addline(buffer, "RCP%s %s, %s;\n", shader_arb_get_modifier(ins), dst, src);
+}
+
+static void shader_hw_scalar_op(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ const char *instruction;
+
+ char dst[50];
+ char src[50];
+
+ switch(ins->handler_idx)
+ {
+ case WINED3DSIH_RSQ: instruction = "RSQ"; break;
+ case WINED3DSIH_RCP: instruction = "RCP"; break;
+ case WINED3DSIH_EXP: instruction = "EX2"; break;
+ case WINED3DSIH_EXPP: instruction = "EXP"; break;
+ default: instruction = "";
+ FIXME("Unhandled opcode %#x\n", ins->handler_idx);
+ break;
+ }
+
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst); /* Destination */
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src);
+ if (ins->src[0].swizzle == WINED3DSP_NOSWIZZLE)
+ {
+ /* Dx sdk says .x is used if no swizzle is given, but our test shows that
+ * .w is used
+ */
+ strcat(src, ".w");
+ }
+
+ shader_addline(buffer, "%s%s %s, %s;\n", instruction, shader_arb_get_modifier(ins), dst, src);
+}
+
+static void shader_hw_nrm(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char dst_name[50];
+ char src_name[50];
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ BOOL pshader = shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type);
+ const char *zero = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ZERO);
+
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst_name);
+ shader_arb_get_src_param(ins, &ins->src[0], 1 /* Use TB */, src_name);
+
+ /* In D3D, NRM of a vector with length zero returns zero. Catch this situation, as
+ * otherwise NRM or RSQ would return NaN */
+ if(pshader && priv->target_version >= NV3)
+ {
+ /* GL_NV_fragment_program2's NRM needs protection against length zero vectors too
+ *
+ * TODO: Find out if DP3+NRM+MOV is really faster than DP3+RSQ+MUL
+ */
+ shader_addline(buffer, "DP3C TA, %s, %s;\n", src_name, src_name);
+ shader_addline(buffer, "NRM%s %s, %s;\n", shader_arb_get_modifier(ins), dst_name, src_name);
+ shader_addline(buffer, "MOV %s (EQ), %s;\n", dst_name, zero);
+ }
+ else if(priv->target_version >= NV2)
+ {
+ shader_addline(buffer, "DP3C TA.x, %s, %s;\n", src_name, src_name);
+ shader_addline(buffer, "RSQ TA.x (NE), TA.x;\n");
+ shader_addline(buffer, "MUL%s %s, %s, TA.x;\n", shader_arb_get_modifier(ins), dst_name,
+ src_name);
+ }
+ else
+ {
+ const char *one = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ONE);
+
+ shader_addline(buffer, "DP3 TA.x, %s, %s;\n", src_name, src_name);
+ /* Pass any non-zero value to RSQ if the input vector has a length of zero. The
+ * RSQ result doesn't matter, as long as multiplying it by 0 returns 0.
+ */
+ shader_addline(buffer, "SGE TA.y, -TA.x, %s;\n", zero);
+ shader_addline(buffer, "MAD TA.x, %s, TA.y, TA.x;\n", one);
+
+ shader_addline(buffer, "RSQ TA.x, TA.x;\n");
+ /* dst.w = src[0].w * 1 / (src.x^2 + src.y^2 + src.z^2)^(1/2) according to msdn*/
+ shader_addline(buffer, "MUL%s %s, %s, TA.x;\n", shader_arb_get_modifier(ins), dst_name,
+ src_name);
+ }
+}
+
+static void shader_hw_lrp(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char dst_name[50];
+ char src_name[3][50];
+
+ /* ARB_fragment_program has a convenient LRP instruction */
+ if(shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type)) {
+ shader_hw_map2gl(ins);
+ return;
+ }
+
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst_name);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_name[0]);
+ shader_arb_get_src_param(ins, &ins->src[1], 1, src_name[1]);
+ shader_arb_get_src_param(ins, &ins->src[2], 2, src_name[2]);
+
+ shader_addline(buffer, "SUB TA, %s, %s;\n", src_name[1], src_name[2]);
+ shader_addline(buffer, "MAD%s %s, %s, TA, %s;\n", shader_arb_get_modifier(ins),
+ dst_name, src_name[0], src_name[2]);
+}
+
+static void shader_hw_sincos(const struct wined3d_shader_instruction *ins)
+{
+ /* This instruction exists in ARB, but the d3d instruction takes two extra parameters which
+ * must contain fixed constants. So we need a separate function to filter those constants and
+ * can't use map2gl
+ */
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ const struct wined3d_shader_dst_param *dst = &ins->dst[0];
+ char dst_name[50];
+ char src_name0[50], src_name1[50], src_name2[50];
+ BOOL is_color;
+
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_name0);
+ if(shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type)) {
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst_name);
+ /* No modifiers are supported on SCS */
+ shader_addline(buffer, "SCS %s, %s;\n", dst_name, src_name0);
+
+ if(ins->dst[0].modifiers & WINED3DSPDM_SATURATE)
+ {
+ shader_arb_get_register_name(ins, &dst->reg, src_name0, &is_color);
+ shader_addline(buffer, "MOV_SAT %s, %s;\n", dst_name, src_name0);
+ }
+ } else if(priv->target_version >= NV2) {
+ shader_arb_get_register_name(ins, &dst->reg, dst_name, &is_color);
+
+ /* Sincos writemask must be .x, .y or .xy */
+ if(dst->write_mask & WINED3DSP_WRITEMASK_0)
+ shader_addline(buffer, "COS%s %s.x, %s;\n", shader_arb_get_modifier(ins), dst_name, src_name0);
+ if(dst->write_mask & WINED3DSP_WRITEMASK_1)
+ shader_addline(buffer, "SIN%s %s.y, %s;\n", shader_arb_get_modifier(ins), dst_name, src_name0);
+ } else {
+ /* Approximate sine and cosine with a taylor series, as per math textbook. The application passes 8
+ * helper constants(D3DSINCOSCONST1 and D3DSINCOSCONST2) in src1 and src2.
+ *
+ * sin(x) = x - x^3/3! + x^5/5! - x^7/7! + ...
+ * cos(x) = 1 - x^2/2! + x^4/4! - x^6/6! + ...
+ *
+ * The constants we get are:
+ *
+ * +1 +1, -1 -1 +1 +1 -1 -1
+ * ---- , ---- , ---- , ----- , ----- , ----- , ------
+ * 1!*2 2!*4 3!*8 4!*16 5!*32 6!*64 7!*128
+ *
+ * If used with x^2, x^3, x^4 etc they calculate sin(x/2) and cos(x/2):
+ *
+ * (x/2)^2 = x^2 / 4
+ * (x/2)^3 = x^3 / 8
+ * (x/2)^4 = x^4 / 16
+ * (x/2)^5 = x^5 / 32
+ * etc
+ *
+ * To get the final result:
+ * sin(x) = 2 * sin(x/2) * cos(x/2)
+ * cos(x) = cos(x/2)^2 - sin(x/2)^2
+ * (from sin(x+y) and cos(x+y) rules)
+ *
+ * As per MSDN, dst.z is undefined after the operation, and so is
+ * dst.x and dst.y if they're masked out by the writemask. Ie
+ * sincos dst.y, src1, c0, c1
+ * returns the sine in dst.y. dst.x and dst.z are undefined, dst.w is not touched. The assembler
+ * vsa.exe also stops with an error if the dest register is the same register as the source
+ * register. This means we can use dest.xyz as temporary storage. The assembler vsa.exe output also
+ * indicates that sincos consumes 8 instruction slots in vs_2_0(and, strangely, in vs_3_0).
+ */
+ shader_arb_get_src_param(ins, &ins->src[1], 1, src_name1);
+ shader_arb_get_src_param(ins, &ins->src[2], 2, src_name2);
+ shader_arb_get_register_name(ins, &dst->reg, dst_name, &is_color);
+
+ shader_addline(buffer, "MUL %s.x, %s, %s;\n", dst_name, src_name0, src_name0); /* x ^ 2 */
+ shader_addline(buffer, "MUL TA.y, %s.x, %s;\n", dst_name, src_name0); /* x ^ 3 */
+ shader_addline(buffer, "MUL %s.y, TA.y, %s;\n", dst_name, src_name0); /* x ^ 4 */
+ shader_addline(buffer, "MUL TA.z, %s.y, %s;\n", dst_name, src_name0); /* x ^ 5 */
+ shader_addline(buffer, "MUL %s.z, TA.z, %s;\n", dst_name, src_name0); /* x ^ 6 */
+ shader_addline(buffer, "MUL TA.w, %s.z, %s;\n", dst_name, src_name0); /* x ^ 7 */
+
+ /* sin(x/2)
+ *
+ * Unfortunately we don't get the constants in a DP4-capable form. Is there a way to
+ * properly merge that with MULs in the code above?
+ * The swizzles .yz and xw however fit into the .yzxw swizzle added to ps_2_0. Maybe
+ * we can merge the sine and cosine MAD rows to calculate them together.
+ */
+ shader_addline(buffer, "MUL TA.x, %s, %s.w;\n", src_name0, src_name2); /* x^1, +1/(1!*2) */
+ shader_addline(buffer, "MAD TA.x, TA.y, %s.x, TA.x;\n", src_name2); /* -1/(3!*8) */
+ shader_addline(buffer, "MAD TA.x, TA.z, %s.w, TA.x;\n", src_name1); /* +1/(5!*32) */
+ shader_addline(buffer, "MAD TA.x, TA.w, %s.x, TA.x;\n", src_name1); /* -1/(7!*128) */
+
+ /* cos(x/2) */
+ shader_addline(buffer, "MAD TA.y, %s.x, %s.y, %s.z;\n", dst_name, src_name2, src_name2); /* -1/(2!*4), +1.0 */
+ shader_addline(buffer, "MAD TA.y, %s.y, %s.z, TA.y;\n", dst_name, src_name1); /* +1/(4!*16) */
+ shader_addline(buffer, "MAD TA.y, %s.z, %s.y, TA.y;\n", dst_name, src_name1); /* -1/(6!*64) */
+
+ if(dst->write_mask & WINED3DSP_WRITEMASK_0) {
+ /* cos x */
+ shader_addline(buffer, "MUL TA.z, TA.y, TA.y;\n");
+ shader_addline(buffer, "MAD %s.x, -TA.x, TA.x, TA.z;\n", dst_name);
+ }
+ if(dst->write_mask & WINED3DSP_WRITEMASK_1) {
+ /* sin x */
+ shader_addline(buffer, "MUL %s.y, TA.x, TA.y;\n", dst_name);
+ shader_addline(buffer, "ADD %s.y, %s.y, %s.y;\n", dst_name, dst_name, dst_name);
+ }
+ }
+}
+
+static void shader_hw_sgn(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char dst_name[50];
+ char src_name[50];
+ struct shader_arb_ctx_priv *ctx = ins->ctx->backend_data;
+
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst_name);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_name);
+
+ /* SGN is only valid in vertex shaders */
+ if(ctx->target_version >= NV2) {
+ shader_addline(buffer, "SSG%s %s, %s;\n", shader_arb_get_modifier(ins), dst_name, src_name);
+ return;
+ }
+
+ /* If SRC > 0.0, -SRC < SRC = TRUE, otherwise false.
+ * if SRC < 0.0, SRC < -SRC = TRUE. If neither is true, src = 0.0
+ */
+ if(ins->dst[0].modifiers & WINED3DSPDM_SATURATE) {
+ shader_addline(buffer, "SLT %s, -%s, %s;\n", dst_name, src_name, src_name);
+ } else {
+ /* src contains TA? Write to the dest first. This won't overwrite our destination.
+ * Then use TA, and calculate the final result
+ *
+ * Not reading from TA? Store the first result in TA to avoid overwriting the
+ * destination if src reg = dst reg
+ */
+ if(strstr(src_name, "TA"))
+ {
+ shader_addline(buffer, "SLT %s, %s, -%s;\n", dst_name, src_name, src_name);
+ shader_addline(buffer, "SLT TA, -%s, %s;\n", src_name, src_name);
+ shader_addline(buffer, "ADD %s, %s, -TA;\n", dst_name, dst_name);
+ }
+ else
+ {
+ shader_addline(buffer, "SLT TA, -%s, %s;\n", src_name, src_name);
+ shader_addline(buffer, "SLT %s, %s, -%s;\n", dst_name, src_name, src_name);
+ shader_addline(buffer, "ADD %s, TA, -%s;\n", dst_name, dst_name);
+ }
+ }
+}
+
+static void shader_hw_dsy(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char src[50];
+ char dst[50];
+ char dst_name[50];
+ BOOL is_color;
+
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src);
+ shader_arb_get_register_name(ins, &ins->dst[0].reg, dst_name, &is_color);
+
+ shader_addline(buffer, "DDY %s, %s;\n", dst, src);
+ shader_addline(buffer, "MUL%s %s, %s, ycorrection.y;\n", shader_arb_get_modifier(ins), dst, dst_name);
+}
+
+static DWORD abs_modifier(DWORD mod, BOOL *need_abs)
+{
+ *need_abs = FALSE;
+
+ switch(mod)
+ {
+ case WINED3DSPSM_NONE: return WINED3DSPSM_ABS;
+ case WINED3DSPSM_NEG: return WINED3DSPSM_ABS;
+ case WINED3DSPSM_BIAS: *need_abs = TRUE; return WINED3DSPSM_BIAS;
+ case WINED3DSPSM_BIASNEG: *need_abs = TRUE; return WINED3DSPSM_BIASNEG;
+ case WINED3DSPSM_SIGN: *need_abs = TRUE; return WINED3DSPSM_SIGN;
+ case WINED3DSPSM_SIGNNEG: *need_abs = TRUE; return WINED3DSPSM_SIGNNEG;
+ case WINED3DSPSM_COMP: *need_abs = TRUE; return WINED3DSPSM_COMP;
+ case WINED3DSPSM_X2: *need_abs = TRUE; return WINED3DSPSM_X2;
+ case WINED3DSPSM_X2NEG: *need_abs = TRUE; return WINED3DSPSM_X2NEG;
+ case WINED3DSPSM_DZ: *need_abs = TRUE; return WINED3DSPSM_DZ;
+ case WINED3DSPSM_DW: *need_abs = TRUE; return WINED3DSPSM_DW;
+ case WINED3DSPSM_ABS: return WINED3DSPSM_ABS;
+ case WINED3DSPSM_ABSNEG: return WINED3DSPSM_ABS;
+ }
+ FIXME("Unknown modifier %u\n", mod);
+ return mod;
+}
+
+static void shader_hw_log(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char src0[50], dst[50];
+ struct wined3d_shader_src_param src0_copy = ins->src[0];
+ BOOL need_abs = FALSE;
+ const char *instr;
+
+ switch(ins->handler_idx)
+ {
+ case WINED3DSIH_LOG: instr = "LG2"; break;
+ case WINED3DSIH_LOGP: instr = "LOG"; break;
+ default:
+ ERR("Unexpected instruction %d\n", ins->handler_idx);
+ return;
+ }
+
+ /* LOG and LOGP operate on the absolute value of the input */
+ src0_copy.modifiers = abs_modifier(src0_copy.modifiers, &need_abs);
+
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst);
+ shader_arb_get_src_param(ins, &src0_copy, 0, src0);
+
+ if(need_abs)
+ {
+ shader_addline(buffer, "ABS TA, %s;\n", src0);
+ shader_addline(buffer, "%s%s %s, TA;\n", instr, shader_arb_get_modifier(ins), dst);
+ }
+ else
+ {
+ shader_addline(buffer, "%s%s %s, %s;\n", instr, shader_arb_get_modifier(ins), dst, src0);
+ }
+}
+
+static void shader_hw_pow(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char src0[50], src1[50], dst[50];
+ struct wined3d_shader_src_param src0_copy = ins->src[0];
+ BOOL need_abs = FALSE;
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ const char *one = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ONE);
+
+ /* POW operates on the absolute value of the input */
+ src0_copy.modifiers = abs_modifier(src0_copy.modifiers, &need_abs);
+
+ shader_arb_get_dst_param(ins, &ins->dst[0], dst);
+ shader_arb_get_src_param(ins, &src0_copy, 0, src0);
+ shader_arb_get_src_param(ins, &ins->src[1], 1, src1);
+
+ if (need_abs)
+ shader_addline(buffer, "ABS TA.x, %s;\n", src0);
+ else
+ shader_addline(buffer, "MOV TA.x, %s;\n", src0);
+
+ if (priv->target_version >= NV2)
+ {
+ shader_addline(buffer, "MOVC TA.y, %s;\n", src1);
+ shader_addline(buffer, "POW%s %s, TA.x, TA.y;\n", shader_arb_get_modifier(ins), dst);
+ shader_addline(buffer, "MOV %s (EQ.y), %s;\n", dst, one);
+ }
+ else
+ {
+ const char *zero = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_ZERO);
+ const char *flt_eps = arb_get_helper_value(ins->ctx->reg_maps->shader_version.type, ARB_EPS);
+
+ shader_addline(buffer, "ABS TA.y, %s;\n", src1);
+ shader_addline(buffer, "SGE TA.y, -TA.y, %s;\n", zero);
+ /* Possibly add flt_eps to avoid getting float special values */
+ shader_addline(buffer, "MAD TA.z, TA.y, %s, %s;\n", flt_eps, src1);
+ shader_addline(buffer, "POW%s TA.x, TA.x, TA.z;\n", shader_arb_get_modifier(ins));
+ shader_addline(buffer, "MAD TA.x, -TA.x, TA.y, TA.x;\n");
+ shader_addline(buffer, "MAD %s, TA.y, %s, TA.x;\n", dst, one);
+ }
+}
+
+static void shader_hw_loop(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char src_name[50];
+ BOOL vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
+
+ /* src0 is aL */
+ shader_arb_get_src_param(ins, &ins->src[1], 0, src_name);
+
+ if(vshader)
+ {
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ struct list *e = list_head(&priv->control_frames);
+ struct control_frame *control_frame = LIST_ENTRY(e, struct control_frame, entry);
+
+ if(priv->loop_depth > 1) shader_addline(buffer, "PUSHA aL;\n");
+ /* The constant loader makes sure to load -1 into iX.w */
+ shader_addline(buffer, "ARLC aL, %s.xywz;\n", src_name);
+ shader_addline(buffer, "BRA loop_%u_end (LE.x);\n", control_frame->no.loop);
+ shader_addline(buffer, "loop_%u_start:\n", control_frame->no.loop);
+ }
+ else
+ {
+ shader_addline(buffer, "LOOP %s;\n", src_name);
+ }
+}
+
+static void shader_hw_rep(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ char src_name[50];
+ BOOL vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
+
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_name);
+
+ /* The constant loader makes sure to load -1 into iX.w */
+ if(vshader)
+ {
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ struct list *e = list_head(&priv->control_frames);
+ struct control_frame *control_frame = LIST_ENTRY(e, struct control_frame, entry);
+
+ if(priv->loop_depth > 1) shader_addline(buffer, "PUSHA aL;\n");
+
+ shader_addline(buffer, "ARLC aL, %s.xywz;\n", src_name);
+ shader_addline(buffer, "BRA loop_%u_end (LE.x);\n", control_frame->no.loop);
+ shader_addline(buffer, "loop_%u_start:\n", control_frame->no.loop);
+ }
+ else
+ {
+ shader_addline(buffer, "REP %s;\n", src_name);
+ }
+}
+
+static void shader_hw_endloop(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ BOOL vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
+
+ if(vshader)
+ {
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ struct list *e = list_head(&priv->control_frames);
+ struct control_frame *control_frame = LIST_ENTRY(e, struct control_frame, entry);
+
+ shader_addline(buffer, "ARAC aL.xy, aL;\n");
+ shader_addline(buffer, "BRA loop_%u_start (GT.x);\n", control_frame->no.loop);
+ shader_addline(buffer, "loop_%u_end:\n", control_frame->no.loop);
+
+ if(priv->loop_depth > 1) shader_addline(buffer, "POPA aL;\n");
+ }
+ else
+ {
+ shader_addline(buffer, "ENDLOOP;\n");
+ }
+}
+
+static void shader_hw_endrep(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ BOOL vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
+
+ if(vshader)
+ {
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ struct list *e = list_head(&priv->control_frames);
+ struct control_frame *control_frame = LIST_ENTRY(e, struct control_frame, entry);
+
+ shader_addline(buffer, "ARAC aL.xy, aL;\n");
+ shader_addline(buffer, "BRA loop_%u_start (GT.x);\n", control_frame->no.loop);
+ shader_addline(buffer, "loop_%u_end:\n", control_frame->no.loop);
+
+ if(priv->loop_depth > 1) shader_addline(buffer, "POPA aL;\n");
+ }
+ else
+ {
+ shader_addline(buffer, "ENDREP;\n");
+ }
+}
+
+static const struct control_frame *find_last_loop(const struct shader_arb_ctx_priv *priv)
+{
+ struct control_frame *control_frame;
+
+ LIST_FOR_EACH_ENTRY(control_frame, &priv->control_frames, struct control_frame, entry)
+ {
+ if(control_frame->type == LOOP || control_frame->type == REP) return control_frame;
+ }
+ ERR("Could not find loop for break\n");
+ return NULL;
+}
+
+static void shader_hw_break(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ const struct control_frame *control_frame = find_last_loop(ins->ctx->backend_data);
+ BOOL vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
+
+ if(vshader)
+ {
+ shader_addline(buffer, "BRA loop_%u_end;\n", control_frame->no.loop);
+ }
+ else
+ {
+ shader_addline(buffer, "BRK;\n");
+ }
+}
+
+static const char *get_compare(enum wined3d_shader_rel_op op)
+{
+ switch (op)
+ {
+ case WINED3D_SHADER_REL_OP_GT: return "GT";
+ case WINED3D_SHADER_REL_OP_EQ: return "EQ";
+ case WINED3D_SHADER_REL_OP_GE: return "GE";
+ case WINED3D_SHADER_REL_OP_LT: return "LT";
+ case WINED3D_SHADER_REL_OP_NE: return "NE";
+ case WINED3D_SHADER_REL_OP_LE: return "LE";
+ default:
+ FIXME("Unrecognized operator %#x.\n", op);
+ return "(\?\?)";
+ }
+}
+
+static enum wined3d_shader_rel_op invert_compare(enum wined3d_shader_rel_op op)
+{
+ switch (op)
+ {
+ case WINED3D_SHADER_REL_OP_GT: return WINED3D_SHADER_REL_OP_LE;
+ case WINED3D_SHADER_REL_OP_EQ: return WINED3D_SHADER_REL_OP_NE;
+ case WINED3D_SHADER_REL_OP_GE: return WINED3D_SHADER_REL_OP_LT;
+ case WINED3D_SHADER_REL_OP_LT: return WINED3D_SHADER_REL_OP_GE;
+ case WINED3D_SHADER_REL_OP_NE: return WINED3D_SHADER_REL_OP_EQ;
+ case WINED3D_SHADER_REL_OP_LE: return WINED3D_SHADER_REL_OP_GT;
+ default:
+ FIXME("Unrecognized operator %#x.\n", op);
+ return -1;
+ }
+}
+
+static void shader_hw_breakc(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ BOOL vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
+ const struct control_frame *control_frame = find_last_loop(ins->ctx->backend_data);
+ char src_name0[50];
+ char src_name1[50];
+ const char *comp = get_compare(ins->flags);
+
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_name0);
+ shader_arb_get_src_param(ins, &ins->src[1], 1, src_name1);
+
+ if(vshader)
+ {
+ /* SUBC CC, src0, src1" works only in pixel shaders, so use TA to throw
+ * away the subtraction result
+ */
+ shader_addline(buffer, "SUBC TA, %s, %s;\n", src_name0, src_name1);
+ shader_addline(buffer, "BRA loop_%u_end (%s.x);\n", control_frame->no.loop, comp);
+ }
+ else
+ {
+ shader_addline(buffer, "SUBC TA, %s, %s;\n", src_name0, src_name1);
+ shader_addline(buffer, "BRK (%s.x);\n", comp);
+ }
+}
+
+static void shader_hw_ifc(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ struct list *e = list_head(&priv->control_frames);
+ struct control_frame *control_frame = LIST_ENTRY(e, struct control_frame, entry);
+ const char *comp;
+ char src_name0[50];
+ char src_name1[50];
+ BOOL vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
+
+ shader_arb_get_src_param(ins, &ins->src[0], 0, src_name0);
+ shader_arb_get_src_param(ins, &ins->src[1], 1, src_name1);
+
+ if(vshader)
+ {
+ /* Invert the flag. We jump to the else label if the condition is NOT true */
+ comp = get_compare(invert_compare(ins->flags));
+ shader_addline(buffer, "SUBC TA, %s, %s;\n", src_name0, src_name1);
+ shader_addline(buffer, "BRA ifc_%u_else (%s.x);\n", control_frame->no.ifc, comp);
+ }
+ else
+ {
+ comp = get_compare(ins->flags);
+ shader_addline(buffer, "SUBC TA, %s, %s;\n", src_name0, src_name1);
+ shader_addline(buffer, "IF %s.x;\n", comp);
+ }
+}
+
+static void shader_hw_else(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ struct list *e = list_head(&priv->control_frames);
+ struct control_frame *control_frame = LIST_ENTRY(e, struct control_frame, entry);
+ BOOL vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
+
+ if(vshader)
+ {
+ shader_addline(buffer, "BRA ifc_%u_endif;\n", control_frame->no.ifc);
+ shader_addline(buffer, "ifc_%u_else:\n", control_frame->no.ifc);
+ control_frame->had_else = TRUE;
+ }
+ else
+ {
+ shader_addline(buffer, "ELSE;\n");
+ }
+}
+
+static void shader_hw_endif(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ struct list *e = list_head(&priv->control_frames);
+ struct control_frame *control_frame = LIST_ENTRY(e, struct control_frame, entry);
+ BOOL vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
+
+ if(vshader)
+ {
+ if(control_frame->had_else)
+ {
+ shader_addline(buffer, "ifc_%u_endif:\n", control_frame->no.ifc);
+ }
+ else
+ {
+ shader_addline(buffer, "#No else branch. else is endif\n");
+ shader_addline(buffer, "ifc_%u_else:\n", control_frame->no.ifc);
+ }
+ }
+ else
+ {
+ shader_addline(buffer, "ENDIF;\n");
+ }
+}
+
+static void shader_hw_texldd(const struct wined3d_shader_instruction *ins)
+{
+ DWORD sampler_idx = ins->src[1].reg.idx[0].offset;
+ char reg_dest[40];
+ char reg_src[3][40];
+ WORD flags = TEX_DERIV;
+
+ shader_arb_get_dst_param(ins, &ins->dst[0], reg_dest);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, reg_src[0]);
+ shader_arb_get_src_param(ins, &ins->src[2], 1, reg_src[1]);
+ shader_arb_get_src_param(ins, &ins->src[3], 2, reg_src[2]);
+
+ if (ins->flags & WINED3DSI_TEXLD_PROJECT) flags |= TEX_PROJ;
+ if (ins->flags & WINED3DSI_TEXLD_BIAS) flags |= TEX_BIAS;
+
+ shader_hw_sample(ins, sampler_idx, reg_dest, reg_src[0], flags, reg_src[1], reg_src[2]);
+}
+
+static void shader_hw_texldl(const struct wined3d_shader_instruction *ins)
+{
+ DWORD sampler_idx = ins->src[1].reg.idx[0].offset;
+ char reg_dest[40];
+ char reg_coord[40];
+ WORD flags = TEX_LOD;
+
+ shader_arb_get_dst_param(ins, &ins->dst[0], reg_dest);
+ shader_arb_get_src_param(ins, &ins->src[0], 0, reg_coord);
+
+ if (ins->flags & WINED3DSI_TEXLD_PROJECT) flags |= TEX_PROJ;
+ if (ins->flags & WINED3DSI_TEXLD_BIAS) flags |= TEX_BIAS;
+
+ shader_hw_sample(ins, sampler_idx, reg_dest, reg_coord, flags, NULL, NULL);
+}
+
+static void shader_hw_label(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+
+ priv->in_main_func = FALSE;
+ /* Call instructions activate the NV extensions, not labels and rets. If there is an uncalled
+ * subroutine, don't generate a label that will make GL complain
+ */
+ if(priv->target_version == ARB) return;
+
+ shader_addline(buffer, "l%u:\n", ins->src[0].reg.idx[0].offset);
+}
+
+static void vshader_add_footer(struct shader_arb_ctx_priv *priv_ctx,
+ const struct arb_vshader_private *shader_data, const struct arb_vs_compile_args *args,
+ const struct wined3d_shader_reg_maps *reg_maps, const struct wined3d_gl_info *gl_info,
+ struct wined3d_shader_buffer *buffer)
+{
+ unsigned int i;
+
+ /* The D3DRS_FOGTABLEMODE render state defines if the shader-generated fog coord is used
+ * or if the fragment depth is used. If the fragment depth is used(FOGTABLEMODE != NONE),
+ * the fog frag coord is thrown away. If the fog frag coord is used, but not written by
+ * the shader, it is set to 0.0(fully fogged, since start = 1.0, end = 0.0)
+ */
+ if (args->super.fog_src == VS_FOG_Z)
+ {
+ shader_addline(buffer, "MOV result.fogcoord, TMP_OUT.z;\n");
+ }
+ else
+ {
+ if (!reg_maps->fog)
+ {
+ /* posFixup.x is always 1.0, so we can safely use it */
+ shader_addline(buffer, "ADD result.fogcoord, posFixup.x, -posFixup.x;\n");
+ }
+ else
+ {
+ /* Clamp fogcoord */
+ const char *zero = arb_get_helper_value(reg_maps->shader_version.type, ARB_ZERO);
+ const char *one = arb_get_helper_value(reg_maps->shader_version.type, ARB_ONE);
+
+ shader_addline(buffer, "MIN TMP_FOGCOORD.x, TMP_FOGCOORD.x, %s;\n", one);
+ shader_addline(buffer, "MAX result.fogcoord.x, TMP_FOGCOORD.x, %s;\n", zero);
+ }
+ }
+
+ /* Clipplanes are always stored without y inversion */
+ if (use_nv_clip(gl_info) && priv_ctx->target_version >= NV2)
+ {
+ if (args->super.clip_enabled)
+ {
+ for (i = 0; i < priv_ctx->vs_clipplanes; i++)
+ {
+ shader_addline(buffer, "DP4 result.clip[%u].x, TMP_OUT, state.clip[%u].plane;\n", i, i);
+ }
+ }
+ }
+ else if (args->clip.boolclip.clip_texcoord)
+ {
+ unsigned int cur_clip = 0;
+ char component[4] = {'x', 'y', 'z', 'w'};
+ const char *zero = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_ZERO);
+
+ for (i = 0; i < gl_info->limits.clipplanes; ++i)
+ {
+ if (args->clip.boolclip.clipplane_mask & (1 << i))
+ {
+ shader_addline(buffer, "DP4 TA.%c, TMP_OUT, state.clip[%u].plane;\n",
+ component[cur_clip++], i);
+ }
+ }
+ switch (cur_clip)
+ {
+ case 0:
+ shader_addline(buffer, "MOV TA, %s;\n", zero);
+ break;
+ case 1:
+ shader_addline(buffer, "MOV TA.yzw, %s;\n", zero);
+ break;
+ case 2:
+ shader_addline(buffer, "MOV TA.zw, %s;\n", zero);
+ break;
+ case 3:
+ shader_addline(buffer, "MOV TA.w, %s;\n", zero);
+ break;
+ }
+ shader_addline(buffer, "MOV result.texcoord[%u], TA;\n",
+ args->clip.boolclip.clip_texcoord - 1);
+ }
+
+ /* Write the final position.
+ *
+ * OpenGL coordinates specify the center of the pixel while d3d coords specify
+ * the corner. The offsets are stored in z and w in posFixup. posFixup.y contains
+ * 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x
+ * contains 1.0 to allow a mad, but arb vs swizzles are too restricted for that.
+ */
+ shader_addline(buffer, "MUL TA, posFixup, TMP_OUT.w;\n");
+ shader_addline(buffer, "ADD TMP_OUT.x, TMP_OUT.x, TA.z;\n");
+ shader_addline(buffer, "MAD TMP_OUT.y, TMP_OUT.y, posFixup.y, TA.w;\n");
+
+ /* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c
+ * and the glsl equivalent
+ */
+ if (need_helper_const(shader_data, reg_maps, gl_info))
+ {
+ const char *two = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_TWO);
+ shader_addline(buffer, "MAD TMP_OUT.z, TMP_OUT.z, %s, -TMP_OUT.w;\n", two);
+ }
+ else
+ {
+ shader_addline(buffer, "ADD TMP_OUT.z, TMP_OUT.z, TMP_OUT.z;\n");
+ shader_addline(buffer, "ADD TMP_OUT.z, TMP_OUT.z, -TMP_OUT.w;\n");
+ }
+
+ shader_addline(buffer, "MOV result.position, TMP_OUT;\n");
+
+ priv_ctx->footer_written = TRUE;
+}
+
+static void shader_hw_ret(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ const struct wined3d_shader *shader = ins->ctx->shader;
+ BOOL vshader = shader_is_vshader_version(ins->ctx->reg_maps->shader_version.type);
+
+ if(priv->target_version == ARB) return;
+
+ if(vshader)
+ {
+ if (priv->in_main_func) vshader_add_footer(priv, shader->backend_data,
+ priv->cur_vs_args, ins->ctx->reg_maps, ins->ctx->gl_info, buffer);
+ }
+
+ shader_addline(buffer, "RET;\n");
+}
+
+static void shader_hw_call(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ shader_addline(buffer, "CAL l%u;\n", ins->src[0].reg.idx[0].offset);
+}
+
+/* Context activation is done by the caller. */
+static GLuint create_arb_blt_vertex_program(const struct wined3d_gl_info *gl_info)
+{
+ GLuint program_id = 0;
+ GLint pos;
+
+ const char *blt_vprogram =
+ "!!ARBvp1.0\n"
+ "PARAM c[1] = { { 1, 0.5 } };\n"
+ "MOV result.position, vertex.position;\n"
+ "MOV result.color, c[0].x;\n"
+ "MOV result.texcoord[0], vertex.texcoord[0];\n"
+ "END\n";
+
+ GL_EXTCALL(glGenProgramsARB(1, &program_id));
+ GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, program_id));
+ GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+ strlen(blt_vprogram), blt_vprogram));
+ checkGLcall("glProgramStringARB()");
+
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
+ if (pos != -1)
+ {
+ FIXME("Vertex program error at position %d: %s\n\n", pos,
+ debugstr_a((const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
+ shader_arb_dump_program_source(blt_vprogram);
+ }
+ else
+ {
+ GLint native;
+
+ GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, &native));
+ checkGLcall("glGetProgramivARB()");
+ if (!native) WARN("Program exceeds native resource limits.\n");
+ }
+
+ return program_id;
+}
+
+/* Context activation is done by the caller. */
+static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_info,
+ enum tex_types tex_type, BOOL masked)
+{
+ GLuint program_id = 0;
+ const char *fprogram;
+ GLint pos;
+
+ static const char * const blt_fprograms_full[tex_type_count] =
+ {
+ /* tex_1d */
+ NULL,
+ /* tex_2d */
+ "!!ARBfp1.0\n"
+ "TEMP R0;\n"
+ "TEX R0.x, fragment.texcoord[0], texture[0], 2D;\n"
+ "MOV result.depth.z, R0.x;\n"
+ "END\n",
+ /* tex_3d */
+ NULL,
+ /* tex_cube */
+ "!!ARBfp1.0\n"
+ "TEMP R0;\n"
+ "TEX R0.x, fragment.texcoord[0], texture[0], CUBE;\n"
+ "MOV result.depth.z, R0.x;\n"
+ "END\n",
+ /* tex_rect */
+ "!!ARBfp1.0\n"
+ "TEMP R0;\n"
+ "TEX R0.x, fragment.texcoord[0], texture[0], RECT;\n"
+ "MOV result.depth.z, R0.x;\n"
+ "END\n",
+ };
+
+ static const char * const blt_fprograms_masked[tex_type_count] =
+ {
+ /* tex_1d */
+ NULL,
+ /* tex_2d */
+ "!!ARBfp1.0\n"
+ "PARAM mask = program.local[0];\n"
+ "TEMP R0;\n"
+ "SLT R0.xy, fragment.position, mask.zwzw;\n"
+ "MUL R0.x, R0.x, R0.y;\n"
+ "KIL -R0.x;\n"
+ "TEX R0.x, fragment.texcoord[0], texture[0], 2D;\n"
+ "MOV result.depth.z, R0.x;\n"
+ "END\n",
+ /* tex_3d */
+ NULL,
+ /* tex_cube */
+ "!!ARBfp1.0\n"
+ "PARAM mask = program.local[0];\n"
+ "TEMP R0;\n"
+ "SLT R0.xy, fragment.position, mask.zwzw;\n"
+ "MUL R0.x, R0.x, R0.y;\n"
+ "KIL -R0.x;\n"
+ "TEX R0.x, fragment.texcoord[0], texture[0], CUBE;\n"
+ "MOV result.depth.z, R0.x;\n"
+ "END\n",
+ /* tex_rect */
+ "!!ARBfp1.0\n"
+ "PARAM mask = program.local[0];\n"
+ "TEMP R0;\n"
+ "SLT R0.xy, fragment.position, mask.zwzw;\n"
+ "MUL R0.x, R0.x, R0.y;\n"
+ "KIL -R0.x;\n"
+ "TEX R0.x, fragment.texcoord[0], texture[0], RECT;\n"
+ "MOV result.depth.z, R0.x;\n"
+ "END\n",
+ };
+
+ fprogram = masked ? blt_fprograms_masked[tex_type] : blt_fprograms_full[tex_type];
+ if (!fprogram)
+ {
+ FIXME("tex_type %#x not supported, falling back to tex_2d\n", tex_type);
+ tex_type = tex_2d;
+ fprogram = masked ? blt_fprograms_masked[tex_type] : blt_fprograms_full[tex_type];
+ }
+
+ GL_EXTCALL(glGenProgramsARB(1, &program_id));
+ GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, program_id));
+ GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(fprogram), fprogram));
+ checkGLcall("glProgramStringARB()");
+
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
+ if (pos != -1)
+ {
+ FIXME("Fragment program error at position %d: %s\n\n", pos,
+ debugstr_a((const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
+ shader_arb_dump_program_source(fprogram);
+ }
+ else
+ {
+ GLint native;
+
+ GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, &native));
+ checkGLcall("glGetProgramivARB()");
+ if (!native) WARN("Program exceeds native resource limits.\n");
+ }
+
+ return program_id;
+}
+
+static void arbfp_add_sRGB_correction(struct wined3d_shader_buffer *buffer, const char *fragcolor,
+ const char *tmp1, const char *tmp2, const char *tmp3, const char *tmp4, BOOL condcode)
+{
+ /* Perform sRGB write correction. See GLX_EXT_framebuffer_sRGB */
+
+ if(condcode)
+ {
+ /* Sigh. MOVC CC doesn't work, so use one of the temps as dummy dest */
+ shader_addline(buffer, "SUBC %s, %s.x, srgb_consts1.y;\n", tmp1, fragcolor);
+ /* Calculate the > 0.0031308 case */
+ shader_addline(buffer, "POW %s.x (GE), %s.x, srgb_consts1.z;\n", fragcolor, fragcolor);
+ shader_addline(buffer, "POW %s.y (GE), %s.y, srgb_consts1.z;\n", fragcolor, fragcolor);
+ shader_addline(buffer, "POW %s.z (GE), %s.z, srgb_consts1.z;\n", fragcolor, fragcolor);
+ shader_addline(buffer, "MUL %s.xyz (GE), %s, srgb_consts1.w;\n", fragcolor, fragcolor);
+ shader_addline(buffer, "SUB %s.xyz (GE), %s, srgb_consts2.x;\n", fragcolor, fragcolor);
+ /* Calculate the < case */
+ shader_addline(buffer, "MUL %s.xyz (LT), srgb_consts1.x, %s;\n", fragcolor, fragcolor);
+ }
+ else
+ {
+ /* Calculate the > 0.0031308 case */
+ shader_addline(buffer, "POW %s.x, %s.x, srgb_consts1.z;\n", tmp1, fragcolor);
+ shader_addline(buffer, "POW %s.y, %s.y, srgb_consts1.z;\n", tmp1, fragcolor);
+ shader_addline(buffer, "POW %s.z, %s.z, srgb_consts1.z;\n", tmp1, fragcolor);
+ shader_addline(buffer, "MUL %s, %s, srgb_consts1.w;\n", tmp1, tmp1);
+ shader_addline(buffer, "SUB %s, %s, srgb_consts2.x;\n", tmp1, tmp1);
+ /* Calculate the < case */
+ shader_addline(buffer, "MUL %s, srgb_consts1.x, %s;\n", tmp2, fragcolor);
+ /* Get 1.0 / 0.0 masks for > 0.0031308 and < 0.0031308 */
+ shader_addline(buffer, "SLT %s, srgb_consts1.y, %s;\n", tmp3, fragcolor);
+ shader_addline(buffer, "SGE %s, srgb_consts1.y, %s;\n", tmp4, fragcolor);
+ /* Store the components > 0.0031308 in the destination */
+ shader_addline(buffer, "MUL %s.xyz, %s, %s;\n", fragcolor, tmp1, tmp3);
+ /* Add the components that are < 0.0031308 */
+ shader_addline(buffer, "MAD %s.xyz, %s, %s, %s;\n", fragcolor, tmp2, tmp4, fragcolor);
+ /* Move everything into result.color at once. Nvidia hardware cannot handle partial
+ * result.color writes(.rgb first, then .a), or handle overwriting already written
+ * components. The assembler uses a temporary register in this case, which is usually
+ * not allocated from one of our registers that were used earlier.
+ */
+ }
+ /* [0.0;1.0] clamping. Not needed, this is done implicitly */
+}
+
+static const DWORD *find_loop_control_values(const struct wined3d_shader *shader, DWORD idx)
+{
+ const struct wined3d_shader_lconst *constant;
+
+ LIST_FOR_EACH_ENTRY(constant, &shader->constantsI, struct wined3d_shader_lconst, entry)
+ {
+ if (constant->idx == idx)
+ {
+ return constant->value;
+ }
+ }
+ return NULL;
+}
+
+static void init_ps_input(const struct wined3d_shader *shader,
+ const struct arb_ps_compile_args *args, struct shader_arb_ctx_priv *priv)
+{
+ static const char * const texcoords[8] =
+ {
+ "fragment.texcoord[0]", "fragment.texcoord[1]", "fragment.texcoord[2]", "fragment.texcoord[3]",
+ "fragment.texcoord[4]", "fragment.texcoord[5]", "fragment.texcoord[6]", "fragment.texcoord[7]"
+ };
+ unsigned int i;
+ const struct wined3d_shader_signature_element *sig = shader->input_signature;
+ const char *semantic_name;
+ DWORD semantic_idx;
+
+ switch(args->super.vp_mode)
+ {
+ case pretransformed:
+ case fixedfunction:
+ /* The pixelshader has to collect the varyings on its own. In any case properly load
+ * color0 and color1. In the case of pretransformed vertices also load texcoords. Set
+ * other attribs to 0.0.
+ *
+ * For fixedfunction this behavior is correct, according to the tests. For pretransformed
+ * we'd either need a replacement shader that can load other attribs like BINORMAL, or
+ * load the texcoord attrib pointers to match the pixel shader signature
+ */
+ for(i = 0; i < MAX_REG_INPUT; i++)
+ {
+ semantic_name = sig[i].semantic_name;
+ semantic_idx = sig[i].semantic_idx;
+ if (!semantic_name) continue;
+
+ if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR))
+ {
+ if (!semantic_idx) priv->ps_input[i] = "fragment.color.primary";
+ else if(semantic_idx == 1) priv->ps_input[i] = "fragment.color.secondary";
+ else priv->ps_input[i] = "0.0";
+ }
+ else if(args->super.vp_mode == fixedfunction)
+ {
+ priv->ps_input[i] = "0.0";
+ }
+ else if(shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
+ {
+ if(semantic_idx < 8) priv->ps_input[i] = texcoords[semantic_idx];
+ else priv->ps_input[i] = "0.0";
+ }
+ else if(shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG))
+ {
+ if (!semantic_idx) priv->ps_input[i] = "fragment.fogcoord";
+ else priv->ps_input[i] = "0.0";
+ }
+ else
+ {
+ priv->ps_input[i] = "0.0";
+ }
+
+ TRACE("v%u, semantic %s%u is %s\n", i, semantic_name, semantic_idx, priv->ps_input[i]);
+ }
+ break;
+
+ case vertexshader:
+ /* That one is easy. The vertex shaders provide v0-v7 in fragment.texcoord and v8 and v9 in
+ * fragment.color
+ */
+ for(i = 0; i < 8; i++)
+ {
+ priv->ps_input[i] = texcoords[i];
+ }
+ priv->ps_input[8] = "fragment.color.primary";
+ priv->ps_input[9] = "fragment.color.secondary";
+ break;
+ }
+}
+
+static void arbfp_add_linear_fog(struct wined3d_shader_buffer *buffer,
+ const char *fragcolor, const char *tmp)
+{
+ shader_addline(buffer, "SUB %s.x, state.fog.params.z, fragment.fogcoord.x;\n", tmp);
+ shader_addline(buffer, "MUL_SAT %s.x, %s.x, state.fog.params.w;\n", tmp, tmp);
+ shader_addline(buffer, "LRP %s.rgb, %s.x, %s, state.fog.color;\n", fragcolor, tmp, fragcolor);
+}
+
+/* Context activation is done by the caller. */
+static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader,
+ const struct wined3d_gl_info *gl_info, struct wined3d_shader_buffer *buffer,
+ const struct arb_ps_compile_args *args, struct arb_ps_compiled_shader *compiled)
+{
+ const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
+ const DWORD *function = shader->function;
+ GLuint retval;
+ char fragcolor[16];
+ DWORD next_local = 0;
+ struct shader_arb_ctx_priv priv_ctx;
+ BOOL dcl_td = FALSE;
+ BOOL want_nv_prog = FALSE;
+ struct arb_pshader_private *shader_priv = shader->backend_data;
+ GLint errPos;
+ DWORD map;
+ BOOL custom_linear_fog = FALSE;
+
+ char srgbtmp[4][4];
+ unsigned int i, found = 0;
+
+ for (i = 0, map = reg_maps->temporary; map; map >>= 1, ++i)
+ {
+ if (!(map & 1)
+ || (shader->u.ps.color0_mov && i == shader->u.ps.color0_reg)
+ || (reg_maps->shader_version.major < 2 && !i))
+ continue;
+
+ sprintf(srgbtmp[found], "R%u", i);
+ ++found;
+ if (found == 4) break;
+ }
+
+ switch(found) {
+ case 0:
+ sprintf(srgbtmp[0], "TA");
+ sprintf(srgbtmp[1], "TB");
+ sprintf(srgbtmp[2], "TC");
+ sprintf(srgbtmp[3], "TD");
+ dcl_td = TRUE;
+ break;
+ case 1:
+ sprintf(srgbtmp[1], "TA");
+ sprintf(srgbtmp[2], "TB");
+ sprintf(srgbtmp[3], "TC");
+ break;
+ case 2:
+ sprintf(srgbtmp[2], "TA");
+ sprintf(srgbtmp[3], "TB");
+ break;
+ case 3:
+ sprintf(srgbtmp[3], "TA");
+ break;
+ case 4:
+ break;
+ }
+
+ /* Create the hw ARB shader */
+ memset(&priv_ctx, 0, sizeof(priv_ctx));
+ priv_ctx.cur_ps_args = args;
+ priv_ctx.compiled_fprog = compiled;
+ priv_ctx.cur_np2fixup_info = &compiled->np2fixup_info;
+ init_ps_input(shader, args, &priv_ctx);
+ list_init(&priv_ctx.control_frames);
+ priv_ctx.ps_post_process = args->super.srgb_correction;
+
+ /* Avoid enabling NV_fragment_program* if we do not need it.
+ *
+ * Enabling GL_NV_fragment_program_option causes the driver to occupy a temporary register,
+ * and it slows down the shader execution noticeably(about 5%). Usually our instruction emulation
+ * is faster than what we gain from using higher native instructions. There are some things though
+ * that cannot be emulated. In that case enable the extensions.
+ * If the extension is enabled, instruction handlers that support both ways will use it.
+ *
+ * Testing shows no performance difference between OPTION NV_fragment_program2 and NV_fragment_program.
+ * So enable the best we can get.
+ */
+ if(reg_maps->usesdsx || reg_maps->usesdsy || reg_maps->loop_depth > 0 || reg_maps->usestexldd ||
+ reg_maps->usestexldl || reg_maps->usesfacing || reg_maps->usesifc || reg_maps->usescall)
+ {
+ want_nv_prog = TRUE;
+ }
+
+ shader_addline(buffer, "!!ARBfp1.0\n");
+ if (want_nv_prog && gl_info->supported[NV_FRAGMENT_PROGRAM2])
+ {
+ shader_addline(buffer, "OPTION NV_fragment_program2;\n");
+ priv_ctx.target_version = NV3;
+ }
+ else if (want_nv_prog && gl_info->supported[NV_FRAGMENT_PROGRAM_OPTION])
+ {
+ shader_addline(buffer, "OPTION NV_fragment_program;\n");
+ priv_ctx.target_version = NV2;
+ } else {
+ if(want_nv_prog)
+ {
+ /* This is an error - either we're advertising the wrong shader version, or aren't enforcing some
+ * limits properly
+ */
+ ERR("The shader requires instructions that are not available in plain GL_ARB_fragment_program\n");
+ ERR("Try GLSL\n");
+ }
+ priv_ctx.target_version = ARB;
+ }
+
+ if (reg_maps->rt_mask > 1)
+ {
+ shader_addline(buffer, "OPTION ARB_draw_buffers;\n");
+ }
+
+ if (reg_maps->shader_version.major < 3)
+ {
+ switch (args->super.fog)
+ {
+ case WINED3D_FFP_PS_FOG_OFF:
+ break;
+ case WINED3D_FFP_PS_FOG_LINEAR:
+ if (gl_info->quirks & WINED3D_QUIRK_BROKEN_ARB_FOG)
+ {
+ custom_linear_fog = TRUE;
+ priv_ctx.ps_post_process = TRUE;
+ break;
+ }
+ shader_addline(buffer, "OPTION ARB_fog_linear;\n");
+ break;
+ case WINED3D_FFP_PS_FOG_EXP:
+ shader_addline(buffer, "OPTION ARB_fog_exp;\n");
+ break;
+ case WINED3D_FFP_PS_FOG_EXP2:
+ shader_addline(buffer, "OPTION ARB_fog_exp2;\n");
+ break;
+ }
+ }
+
+ /* For now always declare the temps. At least the Nvidia assembler optimizes completely
+ * unused temps away(but occupies them for the whole shader if they're used once). Always
+ * declaring them avoids tricky bookkeeping work
+ */
+ shader_addline(buffer, "TEMP TA;\n"); /* Used for modifiers */
+ shader_addline(buffer, "TEMP TB;\n"); /* Used for modifiers */
+ shader_addline(buffer, "TEMP TC;\n"); /* Used for modifiers */
+ if(dcl_td) shader_addline(buffer, "TEMP TD;\n"); /* Used for sRGB writing */
+ shader_addline(buffer, "PARAM coefdiv = { 0.5, 0.25, 0.125, 0.0625 };\n");
+ shader_addline(buffer, "PARAM coefmul = { 2, 4, 8, 16 };\n");
+ shader_addline(buffer, "PARAM ps_helper_const = { 0.0, 1.0, %1.10f, 0.0 };\n", eps);
+
+ if (reg_maps->shader_version.major < 2)
+ {
+ strcpy(fragcolor, "R0");
+ }
+ else
+ {
+ if (priv_ctx.ps_post_process)
+ {
+ if (shader->u.ps.color0_mov)
+ {
+ sprintf(fragcolor, "R%u", shader->u.ps.color0_reg);
+ }
+ else
+ {
+ shader_addline(buffer, "TEMP TMP_COLOR;\n");
+ strcpy(fragcolor, "TMP_COLOR");
+ }
+ } else {
+ strcpy(fragcolor, "result.color");
+ }
+ }
+
+ if(args->super.srgb_correction) {
+ shader_addline(buffer, "PARAM srgb_consts1 = {%f, %f, %f, %f};\n",
+ srgb_mul_low, srgb_cmp, srgb_pow, srgb_mul_high);
+ shader_addline(buffer, "PARAM srgb_consts2 = {%f, %f, %f, %f};\n",
+ srgb_sub_high, 0.0, 0.0, 0.0);
+ }
+
+ /* Base Declarations */
+ shader_generate_arb_declarations(shader, reg_maps, buffer, gl_info, NULL, &priv_ctx);
+
+ for (i = 0, map = reg_maps->bumpmat; map; map >>= 1, ++i)
+ {
+ unsigned char bump_const;
+
+ if (!(map & 1)) continue;
+
+ bump_const = compiled->numbumpenvmatconsts;
+ compiled->bumpenvmatconst[bump_const].const_num = WINED3D_CONST_NUM_UNUSED;
+ compiled->bumpenvmatconst[bump_const].texunit = i;
+ compiled->luminanceconst[bump_const].const_num = WINED3D_CONST_NUM_UNUSED;
+ compiled->luminanceconst[bump_const].texunit = i;
+
+ /* We can fit the constants into the constant limit for sure because texbem, texbeml, bem and beml are only supported
+ * in 1.x shaders, and GL_ARB_fragment_program has a constant limit of 24 constants. So in the worst case we're loading
+ * 8 shader constants, 8 bump matrices and 8 luminance parameters and are perfectly fine. (No NP2 fixup on bumpmapped
+ * textures due to conditional NP2 restrictions)
+ *
+ * Use local constants to load the bump env parameters, not program.env. This avoids collisions with d3d constants of
+ * shaders in newer shader models. Since the bump env parameters have to share their space with NP2 fixup constants,
+ * their location is shader dependent anyway and they cannot be loaded globally.
+ */
+ compiled->bumpenvmatconst[bump_const].const_num = next_local++;
+ shader_addline(buffer, "PARAM bumpenvmat%d = program.local[%d];\n",
+ i, compiled->bumpenvmatconst[bump_const].const_num);
+ compiled->numbumpenvmatconsts = bump_const + 1;
+
+ if (!(reg_maps->luminanceparams & (1 << i))) continue;
+
+ compiled->luminanceconst[bump_const].const_num = next_local++;
+ shader_addline(buffer, "PARAM luminance%d = program.local[%d];\n",
+ i, compiled->luminanceconst[bump_const].const_num);
+ }
+
+ for(i = 0; i < MAX_CONST_I; i++)
+ {
+ compiled->int_consts[i] = WINED3D_CONST_NUM_UNUSED;
+ if (reg_maps->integer_constants & (1 << i) && priv_ctx.target_version >= NV2)
+ {
+ const DWORD *control_values = find_loop_control_values(shader, i);
+
+ if(control_values)
+ {
+ shader_addline(buffer, "PARAM I%u = {%u, %u, %u, -1};\n", i,
+ control_values[0], control_values[1], control_values[2]);
+ }
+ else
+ {
+ compiled->int_consts[i] = next_local;
+ compiled->num_int_consts++;
+ shader_addline(buffer, "PARAM I%u = program.local[%u];\n", i, next_local++);
+ }
+ }
+ }
+
+ if(reg_maps->vpos || reg_maps->usesdsy)
+ {
+ compiled->ycorrection = next_local;
+ shader_addline(buffer, "PARAM ycorrection = program.local[%u];\n", next_local++);
+
+ if(reg_maps->vpos)
+ {
+ shader_addline(buffer, "TEMP vpos;\n");
+ /* ycorrection.x: Backbuffer height(onscreen) or 0(offscreen).
+ * ycorrection.y: -1.0(onscreen), 1.0(offscreen)
+ * ycorrection.z: 1.0
+ * ycorrection.w: 0.0
+ */
+ shader_addline(buffer, "MAD vpos, fragment.position, ycorrection.zyww, ycorrection.wxww;\n");
+ shader_addline(buffer, "FLR vpos.xy, vpos;\n");
+ }
+ }
+ else
+ {
+ compiled->ycorrection = WINED3D_CONST_NUM_UNUSED;
+ }
+
+ /* Load constants to fixup NP2 texcoords if there are still free constants left:
+ * Constants (texture dimensions) for the NP2 fixup are loaded as local program parameters. This will consume
+ * at most 8 (MAX_FRAGMENT_SAMPLERS / 2) parameters, which is highly unlikely, since the application had to
+ * use 16 NP2 textures at the same time. In case that we run out of constants the fixup is simply not
+ * applied / activated. This will probably result in wrong rendering of the texture, but will save us from
+ * shader compilation errors and the subsequent errors when drawing with this shader. */
+ if (priv_ctx.cur_ps_args->super.np2_fixup) {
+ unsigned char cur_fixup_sampler = 0;
+
+ struct arb_ps_np2fixup_info* const fixup = priv_ctx.cur_np2fixup_info;
+ const WORD map = priv_ctx.cur_ps_args->super.np2_fixup;
+ const UINT max_lconsts = gl_info->limits.arb_ps_local_constants;
+
+ fixup->offset = next_local;
+ fixup->super.active = 0;
+
+ for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) {
+ if (!(map & (1 << i))) continue;
+
+ if (fixup->offset + (cur_fixup_sampler >> 1) < max_lconsts) {
+ fixup->super.active |= (1 << i);
+ fixup->super.idx[i] = cur_fixup_sampler++;
+ } else {
+ FIXME("No free constant found to load NP2 fixup data into shader. "
+ "Sampling from this texture will probably look wrong.\n");
+ break;
+ }
+ }
+
+ fixup->super.num_consts = (cur_fixup_sampler + 1) >> 1;
+ if (fixup->super.num_consts) {
+ shader_addline(buffer, "PARAM np2fixup[%u] = { program.env[%u..%u] };\n",
+ fixup->super.num_consts, fixup->offset, fixup->super.num_consts + fixup->offset - 1);
+ }
+ }
+
+ if (shader_priv->clipplane_emulation != ~0U && args->clip)
+ {
+ shader_addline(buffer, "KIL fragment.texcoord[%u];\n", shader_priv->clipplane_emulation);
+ }
+
+ /* Base Shader Body */
+ shader_generate_main(shader, buffer, reg_maps, function, &priv_ctx);
+
+ if(args->super.srgb_correction) {
+ arbfp_add_sRGB_correction(buffer, fragcolor, srgbtmp[0], srgbtmp[1], srgbtmp[2], srgbtmp[3],
+ priv_ctx.target_version >= NV2);
+ }
+
+ if (custom_linear_fog)
+ arbfp_add_linear_fog(buffer, fragcolor, "TA");
+
+ if(strcmp(fragcolor, "result.color")) {
+ shader_addline(buffer, "MOV result.color, %s;\n", fragcolor);
+ }
+ shader_addline(buffer, "END\n");
+
+ /* TODO: change to resource.glObjectHandle or something like that */
+ GL_EXTCALL(glGenProgramsARB(1, &retval));
+
+ TRACE("Creating a hw pixel shader, prg=%d\n", retval);
+ GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, retval));
+
+ TRACE("Created hw pixel shader, prg=%d\n", retval);
+ /* Create the program and check for errors */
+ GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+ buffer->content_size, buffer->buffer));
+ checkGLcall("glProgramStringARB()");
+
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos);
+ if (errPos != -1)
+ {
+ FIXME("HW PixelShader Error at position %d: %s\n\n",
+ errPos, debugstr_a((const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
+ shader_arb_dump_program_source(buffer->buffer);
+ retval = 0;
+ }
+ else
+ {
+ GLint native;
+
+ GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, &native));
+ checkGLcall("glGetProgramivARB()");
+ if (!native) WARN("Program exceeds native resource limits.\n");
+ }
+
+ return retval;
+}
+
+static int compare_sig(const struct wined3d_shader_signature_element *sig1, const struct wined3d_shader_signature_element *sig2)
+{
+ unsigned int i;
+ int ret;
+
+ for(i = 0; i < MAX_REG_INPUT; i++)
+ {
+ if (!sig1[i].semantic_name || !sig2[i].semantic_name)
+ {
+ /* Compare pointers, not contents. One string is NULL(element does not exist), the other one is not NULL */
+ if(sig1[i].semantic_name != sig2[i].semantic_name) return sig1[i].semantic_name < sig2[i].semantic_name ? -1 : 1;
+ continue;
+ }
+
+ if ((ret = strcmp(sig1[i].semantic_name, sig2[i].semantic_name))) return ret;
+ if(sig1[i].semantic_idx != sig2[i].semantic_idx) return sig1[i].semantic_idx < sig2[i].semantic_idx ? -1 : 1;
+ if(sig1[i].sysval_semantic != sig2[i].sysval_semantic) return sig1[i].sysval_semantic < sig2[i].sysval_semantic ? -1 : 1;
+ if(sig1[i].component_type != sig2[i].component_type) return sig1[i].component_type < sig2[i].component_type ? -1 : 1;
+ if(sig1[i].register_idx != sig2[i].register_idx) return sig1[i].register_idx < sig2[i].register_idx ? -1 : 1;
+ if(sig1[i].mask != sig2[i].mask) return sig1[i].mask < sig2[i].mask ? -1 : 1;
+ }
+ return 0;
+}
+
+static struct wined3d_shader_signature_element *clone_sig(const struct wined3d_shader_signature_element *sig)
+{
+ struct wined3d_shader_signature_element *new;
+ int i;
+ char *name;
+
+ new = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*new) * MAX_REG_INPUT);
+ for(i = 0; i < MAX_REG_INPUT; i++)
+ {
+ if (!sig[i].semantic_name) continue;
+
+ new[i] = sig[i];
+ /* Clone the semantic string */
+ name = HeapAlloc(GetProcessHeap(), 0, strlen(sig[i].semantic_name) + 1);
+ strcpy(name, sig[i].semantic_name);
+ new[i].semantic_name = name;
+ }
+ return new;
+}
+
+static DWORD find_input_signature(struct shader_arb_priv *priv, const struct wined3d_shader_signature_element *sig)
+{
+ struct wine_rb_entry *entry = wine_rb_get(&priv->signature_tree, sig);
+ struct ps_signature *found_sig;
+
+ if (entry)
+ {
+ found_sig = WINE_RB_ENTRY_VALUE(entry, struct ps_signature, entry);
+ TRACE("Found existing signature %u\n", found_sig->idx);
+ return found_sig->idx;
+ }
+ found_sig = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*found_sig));
+ found_sig->sig = clone_sig(sig);
+ found_sig->idx = priv->ps_sig_number++;
+ TRACE("New signature stored and assigned number %u\n", found_sig->idx);
+ if(wine_rb_put(&priv->signature_tree, sig, &found_sig->entry) == -1)
+ {
+ ERR("Failed to insert program entry.\n");
+ }
+ return found_sig->idx;
+}
+
+static void init_output_registers(const struct wined3d_shader *shader,
+ const struct wined3d_shader_signature_element *ps_input_sig,
+ struct shader_arb_ctx_priv *priv_ctx, struct arb_vs_compiled_shader *compiled)
+{
+ unsigned int i, j;
+ static const char * const texcoords[8] =
+ {
+ "result.texcoord[0]", "result.texcoord[1]", "result.texcoord[2]", "result.texcoord[3]",
+ "result.texcoord[4]", "result.texcoord[5]", "result.texcoord[6]", "result.texcoord[7]"
+ };
+ const char *semantic_name;
+ DWORD semantic_idx, reg_idx;
+
+ /* Write generic input varyings 0 to 7 to result.texcoord[], varying 8 to result.color.primary
+ * and varying 9 to result.color.secondary
+ */
+ static const char * const decl_idx_to_string[MAX_REG_INPUT] =
+ {
+ "result.texcoord[0]", "result.texcoord[1]", "result.texcoord[2]", "result.texcoord[3]",
+ "result.texcoord[4]", "result.texcoord[5]", "result.texcoord[6]", "result.texcoord[7]",
+ "result.color.primary", "result.color.secondary"
+ };
+
+ if (!ps_input_sig)
+ {
+ TRACE("Pixel shader uses builtin varyings\n");
+ /* Map builtins to builtins */
+ for(i = 0; i < 8; i++)
+ {
+ priv_ctx->texcrd_output[i] = texcoords[i];
+ }
+ priv_ctx->color_output[0] = "result.color.primary";
+ priv_ctx->color_output[1] = "result.color.secondary";
+ priv_ctx->fog_output = "TMP_FOGCOORD";
+
+ /* Map declared regs to builtins. Use "TA" to /dev/null unread output */
+ for (i = 0; i < (sizeof(shader->output_signature) / sizeof(*shader->output_signature)); ++i)
+ {
+ semantic_name = shader->output_signature[i].semantic_name;
+ if (!semantic_name) continue;
+
+ if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION))
+ {
+ TRACE("o%u is TMP_OUT\n", i);
+ if (!shader->output_signature[i].semantic_idx) priv_ctx->vs_output[i] = "TMP_OUT";
+ else priv_ctx->vs_output[i] = "TA";
+ }
+ else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_PSIZE))
+ {
+ TRACE("o%u is result.pointsize\n", i);
+ if (!shader->output_signature[i].semantic_idx) priv_ctx->vs_output[i] = "result.pointsize";
+ else priv_ctx->vs_output[i] = "TA";
+ }
+ else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR))
+ {
+ TRACE("o%u is result.color.?, idx %u\n", i, shader->output_signature[i].semantic_idx);
+ if (!shader->output_signature[i].semantic_idx)
+ priv_ctx->vs_output[i] = "result.color.primary";
+ else if (shader->output_signature[i].semantic_idx == 1)
+ priv_ctx->vs_output[i] = "result.color.secondary";
+ else priv_ctx->vs_output[i] = "TA";
+ }
+ else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
+ {
+ TRACE("o%u is %s\n", i, texcoords[shader->output_signature[i].semantic_idx]);
+ if (shader->output_signature[i].semantic_idx >= 8) priv_ctx->vs_output[i] = "TA";
+ else priv_ctx->vs_output[i] = texcoords[shader->output_signature[i].semantic_idx];
+ }
+ else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG))
+ {
+ TRACE("o%u is result.fogcoord\n", i);
+ if (shader->output_signature[i].semantic_idx > 0) priv_ctx->vs_output[i] = "TA";
+ else priv_ctx->vs_output[i] = "result.fogcoord";
+ }
+ else
+ {
+ priv_ctx->vs_output[i] = "TA";
+ }
+ }
+ return;
+ }
+
+ TRACE("Pixel shader uses declared varyings\n");
+
+ /* Map builtin to declared. /dev/null the results by default to the TA temp reg */
+ for(i = 0; i < 8; i++)
+ {
+ priv_ctx->texcrd_output[i] = "TA";
+ }
+ priv_ctx->color_output[0] = "TA";
+ priv_ctx->color_output[1] = "TA";
+ priv_ctx->fog_output = "TA";
+
+ for(i = 0; i < MAX_REG_INPUT; i++)
+ {
+ semantic_name = ps_input_sig[i].semantic_name;
+ semantic_idx = ps_input_sig[i].semantic_idx;
+ reg_idx = ps_input_sig[i].register_idx;
+ if (!semantic_name) continue;
+
+ /* If a declared input register is not written by builtin arguments, don't write to it.
+ * GL_NV_vertex_program makes sure the input defaults to 0.0, which is correct with D3D
+ *
+ * Don't care about POSITION and PSIZE here - this is a builtin vertex shader, position goes
+ * to TMP_OUT in any case
+ */
+ if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
+ {
+ if (semantic_idx < 8)
+ priv_ctx->texcrd_output[semantic_idx] = decl_idx_to_string[reg_idx];
+ }
+ else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR))
+ {
+ if (semantic_idx < 2)
+ priv_ctx->color_output[semantic_idx] = decl_idx_to_string[reg_idx];
+ }
+ else if(shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG))
+ {
+ if (!semantic_idx)
+ priv_ctx->fog_output = decl_idx_to_string[reg_idx];
+ }
+ else
+ {
+ continue;
+ }
+
+ if (!strcmp(decl_idx_to_string[reg_idx], "result.color.primary")
+ || !strcmp(decl_idx_to_string[reg_idx], "result.color.secondary"))
+ {
+ compiled->need_color_unclamp = TRUE;
+ }
+ }
+
+ /* Map declared to declared */
+ for (i = 0; i < (sizeof(shader->output_signature) / sizeof(*shader->output_signature)); ++i)
+ {
+ /* Write unread output to TA to throw them away */
+ priv_ctx->vs_output[i] = "TA";
+ semantic_name = shader->output_signature[i].semantic_name;
+ if (!semantic_name) continue;
+
+ if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION)
+ && !shader->output_signature[i].semantic_idx)
+ {
+ priv_ctx->vs_output[i] = "TMP_OUT";
+ continue;
+ }
+ else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_PSIZE)
+ && !shader->output_signature[i].semantic_idx)
+ {
+ priv_ctx->vs_output[i] = "result.pointsize";
+ continue;
+ }
+
+ for(j = 0; j < MAX_REG_INPUT; j++)
+ {
+ if (!ps_input_sig[j].semantic_name) continue;
+
+ if (!strcmp(ps_input_sig[j].semantic_name, semantic_name)
+ && ps_input_sig[j].semantic_idx == shader->output_signature[i].semantic_idx)
+ {
+ priv_ctx->vs_output[i] = decl_idx_to_string[ps_input_sig[j].register_idx];
+
+ if (!strcmp(priv_ctx->vs_output[i], "result.color.primary")
+ || !strcmp(priv_ctx->vs_output[i], "result.color.secondary"))
+ {
+ compiled->need_color_unclamp = TRUE;
+ }
+ }
+ }
+ }
+}
+
+/* Context activation is done by the caller. */
+static GLuint shader_arb_generate_vshader(const struct wined3d_shader *shader,
+ const struct wined3d_gl_info *gl_info, struct wined3d_shader_buffer *buffer,
+ const struct arb_vs_compile_args *args, struct arb_vs_compiled_shader *compiled,
+ const struct wined3d_shader_signature_element *ps_input_sig)
+{
+ const struct arb_vshader_private *shader_data = shader->backend_data;
+ const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
+ struct shader_arb_priv *priv = shader->device->shader_priv;
+ const DWORD *function = shader->function;
+ GLuint ret;
+ DWORD next_local = 0;
+ struct shader_arb_ctx_priv priv_ctx;
+ unsigned int i;
+ GLint errPos;
+
+ memset(&priv_ctx, 0, sizeof(priv_ctx));
+ priv_ctx.cur_vs_args = args;
+ list_init(&priv_ctx.control_frames);
+ init_output_registers(shader, ps_input_sig, &priv_ctx, compiled);
+
+ /* Create the hw ARB shader */
+ shader_addline(buffer, "!!ARBvp1.0\n");
+
+ /* Always enable the NV extension if available. Unlike fragment shaders, there is no
+ * mesurable performance penalty, and we can always make use of it for clipplanes.
+ */
+ if (gl_info->supported[NV_VERTEX_PROGRAM3])
+ {
+ shader_addline(buffer, "OPTION NV_vertex_program3;\n");
+ priv_ctx.target_version = NV3;
+ shader_addline(buffer, "ADDRESS aL;\n");
+ }
+ else if (gl_info->supported[NV_VERTEX_PROGRAM2_OPTION])
+ {
+ shader_addline(buffer, "OPTION NV_vertex_program2;\n");
+ priv_ctx.target_version = NV2;
+ shader_addline(buffer, "ADDRESS aL;\n");
+ } else {
+ priv_ctx.target_version = ARB;
+ }
+
+ shader_addline(buffer, "TEMP TMP_OUT;\n");
+ if (reg_maps->fog)
+ shader_addline(buffer, "TEMP TMP_FOGCOORD;\n");
+ if (need_helper_const(shader_data, reg_maps, gl_info))
+ {
+ shader_addline(buffer, "PARAM helper_const = { 0.0, 1.0, 2.0, %1.10f};\n", eps);
+ }
+ if (need_rel_addr_const(shader_data, reg_maps, gl_info))
+ {
+ shader_addline(buffer, "PARAM rel_addr_const = { 0.5, %d.0, 0.0, 0.0 };\n", shader_data->rel_offset);
+ shader_addline(buffer, "TEMP A0_SHADOW;\n");
+ }
+
+ shader_addline(buffer, "TEMP TA;\n");
+ shader_addline(buffer, "TEMP TB;\n");
+
+ /* Base Declarations */
+ shader_generate_arb_declarations(shader, reg_maps, buffer, gl_info,
+ &priv_ctx.vs_clipplanes, &priv_ctx);
+
+ for(i = 0; i < MAX_CONST_I; i++)
+ {
+ compiled->int_consts[i] = WINED3D_CONST_NUM_UNUSED;
+ if(reg_maps->integer_constants & (1 << i) && priv_ctx.target_version >= NV2)
+ {
+ const DWORD *control_values = find_loop_control_values(shader, i);
+
+ if(control_values)
+ {
+ shader_addline(buffer, "PARAM I%u = {%u, %u, %u, -1};\n", i,
+ control_values[0], control_values[1], control_values[2]);
+ }
+ else
+ {
+ compiled->int_consts[i] = next_local;
+ compiled->num_int_consts++;
+ shader_addline(buffer, "PARAM I%u = program.local[%u];\n", i, next_local++);
+ }
+ }
+ }
+
+ /* We need a constant to fixup the final position */
+ shader_addline(buffer, "PARAM posFixup = program.local[%u];\n", next_local);
+ compiled->pos_fixup = next_local++;
+
+ /* Initialize output parameters. GL_ARB_vertex_program does not require special initialization values
+ * for output parameters. D3D in theory does not do that either, but some applications depend on a
+ * proper initialization of the secondary color, and programs using the fixed function pipeline without
+ * a replacement shader depend on the texcoord.w being set properly.
+ *
+ * GL_NV_vertex_program defines that all output values are initialized to {0.0, 0.0, 0.0, 1.0}. This
+ * assertion is in effect even when using GL_ARB_vertex_program without any NV specific additions. So
+ * skip this if NV_vertex_program is supported. Otherwise, initialize the secondary color. For the tex-
+ * coords, we have a flag in the opengl caps. Many cards do not require the texcoord being set, and
+ * this can eat a number of instructions, so skip it unless this cap is set as well
+ */
+ if (!gl_info->supported[NV_VERTEX_PROGRAM])
+ {
+ const char *color_init = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_0001);
+ shader_addline(buffer, "MOV result.color.secondary, %s;\n", color_init);
+
+ if (gl_info->quirks & WINED3D_QUIRK_SET_TEXCOORD_W && !priv->ffp_proj_control)
+ {
+ int i;
+ const char *one = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_ONE);
+ for(i = 0; i < min(8, MAX_REG_TEXCRD); i++)
+ {
+ if (reg_maps->texcoord_mask[i] && reg_maps->texcoord_mask[i] != WINED3DSP_WRITEMASK_ALL)
+ shader_addline(buffer, "MOV result.texcoord[%u].w, %s\n", i, one);
+ }
+ }
+ }
+
+ /* The shader starts with the main function */
+ priv_ctx.in_main_func = TRUE;
+ /* Base Shader Body */
+ shader_generate_main(shader, buffer, reg_maps, function, &priv_ctx);
+
+ if (!priv_ctx.footer_written) vshader_add_footer(&priv_ctx,
+ shader_data, args, reg_maps, gl_info, buffer);
+
+ shader_addline(buffer, "END\n");
+
+ /* TODO: change to resource.glObjectHandle or something like that */
+ GL_EXTCALL(glGenProgramsARB(1, &ret));
+
+ TRACE("Creating a hw vertex shader, prg=%d\n", ret);
+ GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, ret));
+
+ TRACE("Created hw vertex shader, prg=%d\n", ret);
+ /* Create the program and check for errors */
+ GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+ buffer->content_size, buffer->buffer));
+ checkGLcall("glProgramStringARB()");
+
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos);
+ if (errPos != -1)
+ {
+ FIXME("HW VertexShader Error at position %d: %s\n\n",
+ errPos, debugstr_a((const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
+ shader_arb_dump_program_source(buffer->buffer);
+ ret = -1;
+ }
+ else
+ {
+ GLint native;
+
+ GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, &native));
+ checkGLcall("glGetProgramivARB()");
+ if (!native) WARN("Program exceeds native resource limits.\n");
+ }
+
+ return ret;
+}
+
+/* Context activation is done by the caller. */
+static struct arb_ps_compiled_shader *find_arb_pshader(struct wined3d_shader *shader,
+ const struct arb_ps_compile_args *args)
+{
+ struct wined3d_device *device = shader->device;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+ UINT i;
+ DWORD new_size;
+ struct arb_ps_compiled_shader *new_array;
+ struct wined3d_shader_buffer buffer;
+ struct arb_pshader_private *shader_data;
+ GLuint ret;
+
+ if (!shader->backend_data)
+ {
+ struct shader_arb_priv *priv = device->shader_priv;
+
+ shader->backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
+ shader_data = shader->backend_data;
+ shader_data->clamp_consts = shader->reg_maps.shader_version.major == 1;
+
+ if (shader->reg_maps.shader_version.major < 3)
+ shader_data->input_signature_idx = ~0U;
+ else
+ shader_data->input_signature_idx = find_input_signature(priv, shader->input_signature);
+
+ TRACE("Shader got assigned input signature index %u\n", shader_data->input_signature_idx);
+
+ if (!d3d_info->vs_clipping)
+ shader_data->clipplane_emulation = shader_find_free_input_register(&shader->reg_maps,
+ d3d_info->limits.ffp_blend_stages - 1);
+ else
+ shader_data->clipplane_emulation = ~0U;
+ }
+ shader_data = shader->backend_data;
+
+ /* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2),
+ * so a linear search is more performant than a hashmap or a binary search
+ * (cache coherency etc)
+ */
+ for (i = 0; i < shader_data->num_gl_shaders; ++i)
+ {
+ if (!memcmp(&shader_data->gl_shaders[i].args, args, sizeof(*args)))
+ return &shader_data->gl_shaders[i];
+ }
+
+ TRACE("No matching GL shader found, compiling a new shader\n");
+ if(shader_data->shader_array_size == shader_data->num_gl_shaders) {
+ if (shader_data->num_gl_shaders)
+ {
+ new_size = shader_data->shader_array_size + max(1, shader_data->shader_array_size / 2);
+ new_array = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, shader_data->gl_shaders,
+ new_size * sizeof(*shader_data->gl_shaders));
+ } else {
+ new_array = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data->gl_shaders));
+ new_size = 1;
+ }
+
+ if(!new_array) {
+ ERR("Out of memory\n");
+ return 0;
+ }
+ shader_data->gl_shaders = new_array;
+ shader_data->shader_array_size = new_size;
+ }
+
+ shader_data->gl_shaders[shader_data->num_gl_shaders].args = *args;
+
+ pixelshader_update_samplers(shader, args->super.tex_types);
+
+ if (!shader_buffer_init(&buffer))
+ {
+ ERR("Failed to initialize shader buffer.\n");
+ return 0;
+ }
+
+ ret = shader_arb_generate_pshader(shader, gl_info, &buffer, args,
+ &shader_data->gl_shaders[shader_data->num_gl_shaders]);
+ shader_buffer_free(&buffer);
+ shader_data->gl_shaders[shader_data->num_gl_shaders].prgId = ret;
+
+ return &shader_data->gl_shaders[shader_data->num_gl_shaders++];
+}
+
+static inline BOOL vs_args_equal(const struct arb_vs_compile_args *stored, const struct arb_vs_compile_args *new,
+ const DWORD use_map, BOOL skip_int) {
+ if((stored->super.swizzle_map & use_map) != new->super.swizzle_map) return FALSE;
+ if(stored->super.clip_enabled != new->super.clip_enabled) return FALSE;
+ if(stored->super.fog_src != new->super.fog_src) return FALSE;
+ if(stored->clip.boolclip_compare != new->clip.boolclip_compare) return FALSE;
+ if(stored->ps_signature != new->ps_signature) return FALSE;
+ if(stored->vertex.samplers_compare != new->vertex.samplers_compare) return FALSE;
+ if(skip_int) return TRUE;
+
+ return !memcmp(stored->loop_ctrl, new->loop_ctrl, sizeof(stored->loop_ctrl));
+}
+
+static struct arb_vs_compiled_shader *find_arb_vshader(struct wined3d_shader *shader,
+ const struct arb_vs_compile_args *args,
+ const struct wined3d_shader_signature_element *ps_input_sig)
+{
+ struct wined3d_device *device = shader->device;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ DWORD use_map = device->stream_info.use_map;
+ UINT i;
+ DWORD new_size;
+ struct arb_vs_compiled_shader *new_array;
+ struct wined3d_shader_buffer buffer;
+ struct arb_vshader_private *shader_data;
+ GLuint ret;
+
+ if (!shader->backend_data)
+ {
+ const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
+
+ shader->backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
+ shader_data = shader->backend_data;
+
+ if ((gl_info->quirks & WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT)
+ && reg_maps->min_rel_offset <= reg_maps->max_rel_offset)
+ {
+ if (reg_maps->max_rel_offset - reg_maps->min_rel_offset > 127)
+ {
+ FIXME("The difference between the minimum and maximum relative offset is > 127.\n");
+ FIXME("Which this OpenGL implementation does not support. Try using GLSL.\n");
+ FIXME("Min: %u, Max: %u.\n", reg_maps->min_rel_offset, reg_maps->max_rel_offset);
+ }
+ else if (reg_maps->max_rel_offset - reg_maps->min_rel_offset > 63)
+ shader_data->rel_offset = reg_maps->min_rel_offset + 63;
+ else if (reg_maps->max_rel_offset > 63)
+ shader_data->rel_offset = reg_maps->min_rel_offset;
+ }
+ }
+ shader_data = shader->backend_data;
+
+ /* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2),
+ * so a linear search is more performant than a hashmap or a binary search
+ * (cache coherency etc)
+ */
+ for(i = 0; i < shader_data->num_gl_shaders; i++) {
+ if (vs_args_equal(&shader_data->gl_shaders[i].args, args,
+ use_map, gl_info->supported[NV_VERTEX_PROGRAM2_OPTION]))
+ {
+ return &shader_data->gl_shaders[i];
+ }
+ }
+
+ TRACE("No matching GL shader found, compiling a new shader\n");
+
+ if(shader_data->shader_array_size == shader_data->num_gl_shaders) {
+ if (shader_data->num_gl_shaders)
+ {
+ new_size = shader_data->shader_array_size + max(1, shader_data->shader_array_size / 2);
+ new_array = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, shader_data->gl_shaders,
+ new_size * sizeof(*shader_data->gl_shaders));
+ } else {
+ new_array = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data->gl_shaders));
+ new_size = 1;
+ }
+
+ if(!new_array) {
+ ERR("Out of memory\n");
+ return 0;
+ }
+ shader_data->gl_shaders = new_array;
+ shader_data->shader_array_size = new_size;
+ }
+
+ shader_data->gl_shaders[shader_data->num_gl_shaders].args = *args;
+
+ if (!shader_buffer_init(&buffer))
+ {
+ ERR("Failed to initialize shader buffer.\n");
+ return 0;
+ }
+
+ ret = shader_arb_generate_vshader(shader, gl_info, &buffer, args,
+ &shader_data->gl_shaders[shader_data->num_gl_shaders],
+ ps_input_sig);
+ shader_buffer_free(&buffer);
+ shader_data->gl_shaders[shader_data->num_gl_shaders].prgId = ret;
+
+ return &shader_data->gl_shaders[shader_data->num_gl_shaders++];
+}
+
+static void find_arb_ps_compile_args(const struct wined3d_state *state,
+ const struct wined3d_context *context, const struct wined3d_shader *shader,
+ struct arb_ps_compile_args *args)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const struct wined3d_d3d_info *d3d_info = context->d3d_info;
+ int i;
+ WORD int_skip;
+
+ find_ps_compile_args(state, shader, &args->super);
+
+ /* This forces all local boolean constants to 1 to make them stateblock independent */
+ args->bools = shader->reg_maps.local_bool_consts;
+
+ for(i = 0; i < MAX_CONST_B; i++)
+ {
+ if (state->ps_consts_b[i])
+ args->bools |= ( 1 << i);
+ }
+
+ /* Only enable the clip plane emulation KIL if at least one clipplane is enabled. The KIL instruction
+ * is quite expensive because it forces the driver to disable early Z discards. It is cheaper to
+ * duplicate the shader than have a no-op KIL instruction in every shader
+ */
+ if (!d3d_info->vs_clipping && use_vs(state)
+ && state->render_states[WINED3D_RS_CLIPPING]
+ && state->render_states[WINED3D_RS_CLIPPLANEENABLE])
+ args->clip = 1;
+ else
+ args->clip = 0;
+
+ /* Skip if unused or local, or supported natively */
+ int_skip = ~shader->reg_maps.integer_constants | shader->reg_maps.local_int_consts;
+ if (int_skip == 0xffff || gl_info->supported[NV_FRAGMENT_PROGRAM_OPTION])
+ {
+ memset(args->loop_ctrl, 0, sizeof(args->loop_ctrl));
+ return;
+ }
+
+ for(i = 0; i < MAX_CONST_I; i++)
+ {
+ if(int_skip & (1 << i))
+ {
+ args->loop_ctrl[i][0] = 0;
+ args->loop_ctrl[i][1] = 0;
+ args->loop_ctrl[i][2] = 0;
+ }
+ else
+ {
+ args->loop_ctrl[i][0] = state->ps_consts_i[i * 4];
+ args->loop_ctrl[i][1] = state->ps_consts_i[i * 4 + 1];
+ args->loop_ctrl[i][2] = state->ps_consts_i[i * 4 + 2];
+ }
+ }
+}
+
+static void find_arb_vs_compile_args(const struct wined3d_state *state,
+ const struct wined3d_context *context, const struct wined3d_shader *shader,
+ struct arb_vs_compile_args *args)
+{
+ struct wined3d_device *device = shader->device;
+ const struct wined3d_adapter *adapter = device->adapter;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const struct wined3d_d3d_info *d3d_info = context->d3d_info;
+ int i;
+ WORD int_skip;
+
+ find_vs_compile_args(state, shader, &args->super);
+
+ args->clip.boolclip_compare = 0;
+ if (use_ps(state))
+ {
+ const struct wined3d_shader *ps = state->pixel_shader;
+ const struct arb_pshader_private *shader_priv = ps->backend_data;
+ args->ps_signature = shader_priv->input_signature_idx;
+
+ args->clip.boolclip.clip_texcoord = shader_priv->clipplane_emulation + 1;
+ }
+ else
+ {
+ args->ps_signature = ~0;
+ if (!d3d_info->vs_clipping && adapter->fragment_pipe == &arbfp_fragment_pipeline)
+ {
+ args->clip.boolclip.clip_texcoord = ffp_clip_emul(state) ? d3d_info->limits.ffp_blend_stages : 0;
+ }
+ /* Otherwise: Setting boolclip_compare set clip_texcoord to 0 */
+ }
+
+ if (args->clip.boolclip.clip_texcoord)
+ {
+ if (state->render_states[WINED3D_RS_CLIPPING])
+ args->clip.boolclip.clipplane_mask = (unsigned char)state->render_states[WINED3D_RS_CLIPPLANEENABLE];
+ /* clipplane_mask was set to 0 by setting boolclip_compare to 0 */
+ }
+
+ /* This forces all local boolean constants to 1 to make them stateblock independent */
+ args->clip.boolclip.bools = shader->reg_maps.local_bool_consts;
+ /* TODO: Figure out if it would be better to store bool constants as bitmasks in the stateblock */
+ for(i = 0; i < MAX_CONST_B; i++)
+ {
+ if (state->vs_consts_b[i])
+ args->clip.boolclip.bools |= ( 1 << i);
+ }
+
+ args->vertex.samplers[0] = device->texUnitMap[MAX_FRAGMENT_SAMPLERS + 0];
+ args->vertex.samplers[1] = device->texUnitMap[MAX_FRAGMENT_SAMPLERS + 1];
+ args->vertex.samplers[2] = device->texUnitMap[MAX_FRAGMENT_SAMPLERS + 2];
+ args->vertex.samplers[3] = 0;
+
+ /* Skip if unused or local */
+ int_skip = ~shader->reg_maps.integer_constants | shader->reg_maps.local_int_consts;
+ /* This is about flow control, not clipping. */
+ if (int_skip == 0xffff || gl_info->supported[NV_VERTEX_PROGRAM2_OPTION])
+ {
+ memset(args->loop_ctrl, 0, sizeof(args->loop_ctrl));
+ return;
+ }
+
+ for(i = 0; i < MAX_CONST_I; i++)
+ {
+ if(int_skip & (1 << i))
+ {
+ args->loop_ctrl[i][0] = 0;
+ args->loop_ctrl[i][1] = 0;
+ args->loop_ctrl[i][2] = 0;
+ }
+ else
+ {
+ args->loop_ctrl[i][0] = state->vs_consts_i[i * 4];
+ args->loop_ctrl[i][1] = state->vs_consts_i[i * 4 + 1];
+ args->loop_ctrl[i][2] = state->vs_consts_i[i * 4 + 2];
+ }
+ }
+}
+
+/* Context activation is done by the caller. */
+static void shader_arb_select(void *shader_priv, const struct wined3d_context *context,
+ const struct wined3d_state *state)
+{
+ struct shader_arb_priv *priv = shader_priv;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ int i;
+
+ /* Deal with pixel shaders first so the vertex shader arg function has the input signature ready */
+ if (use_ps(state))
+ {
+ struct wined3d_shader *ps = state->pixel_shader;
+ struct arb_ps_compile_args compile_args;
+ struct arb_ps_compiled_shader *compiled;
+
+ TRACE("Using pixel shader %p.\n", ps);
+ find_arb_ps_compile_args(state, context, ps, &compile_args);
+ compiled = find_arb_pshader(ps, &compile_args);
+ priv->current_fprogram_id = compiled->prgId;
+ priv->compiled_fprog = compiled;
+
+ /* Bind the fragment program */
+ GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, priv->current_fprogram_id));
+ checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, priv->current_fprogram_id);");
+
+ if (!priv->use_arbfp_fixed_func)
+ priv->fragment_pipe->enable_extension(gl_info, FALSE);
+
+ /* Enable OpenGL fragment programs. */
+ gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB);
+ checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB);");
+
+ TRACE("Bound fragment program %u and enabled GL_FRAGMENT_PROGRAM_ARB\n", priv->current_fprogram_id);
+
+ /* Pixel Shader 1.x constants are clamped to [-1;1], Pixel Shader 2.0 constants are not. If switching between
+ * a 1.x and newer shader, reload the first 8 constants
+ */
+ if (priv->last_ps_const_clamped != ((struct arb_pshader_private *)ps->backend_data)->clamp_consts)
+ {
+ priv->last_ps_const_clamped = ((struct arb_pshader_private *)ps->backend_data)->clamp_consts;
+ priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, 8);
+ for(i = 0; i < 8; i++)
+ {
+ priv->pshader_const_dirty[i] = 1;
+ }
+ /* Also takes care of loading local constants */
+ shader_arb_load_constants_internal(shader_priv, context, state, TRUE, FALSE, TRUE);
+ }
+ else
+ {
+ UINT rt_height = state->fb->render_targets[0]->resource.height;
+ shader_arb_ps_local_constants(compiled, context, state, rt_height);
+ }
+
+ /* Force constant reloading for the NP2 fixup (see comment in shader_glsl_select for more info) */
+ if (compiled->np2fixup_info.super.active)
+ shader_arb_load_np2fixup_constants(priv, gl_info, state);
+ }
+ else
+ {
+ if (gl_info->supported[ARB_FRAGMENT_PROGRAM] && !priv->use_arbfp_fixed_func)
+ {
+ /* Disable only if we're not using arbfp fixed function fragment
+ * processing. If this is used, keep GL_FRAGMENT_PROGRAM_ARB
+ * enabled, and the fixed function pipeline will bind the fixed
+ * function replacement shader. */
+ gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_PROGRAM_ARB);
+ checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)");
+ priv->current_fprogram_id = 0;
+ }
+ priv->fragment_pipe->enable_extension(gl_info, TRUE);
+ }
+
+ if (use_vs(state))
+ {
+ struct wined3d_shader *vs = state->vertex_shader;
+ struct arb_vs_compile_args compile_args;
+ struct arb_vs_compiled_shader *compiled;
+ const struct wined3d_shader_signature_element *ps_input_sig;
+
+ TRACE("Using vertex shader %p\n", vs);
+ find_arb_vs_compile_args(state, context, vs, &compile_args);
+
+ /* Instead of searching for the signature in the signature list, read the one from the
+ * current pixel shader. It's maybe not the shader where the signature came from, but it
+ * is the same signature and faster to find. */
+ if (compile_args.ps_signature == ~0U)
+ ps_input_sig = NULL;
+ else
+ ps_input_sig = state->pixel_shader->input_signature;
+
+ compiled = find_arb_vshader(vs, &compile_args, ps_input_sig);
+ priv->current_vprogram_id = compiled->prgId;
+ priv->compiled_vprog = compiled;
+
+ /* Bind the vertex program */
+ GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id));
+ checkGLcall("glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id);");
+
+ priv->vertex_pipe->vp_enable(gl_info, FALSE);
+
+ /* Enable OpenGL vertex programs */
+ gl_info->gl_ops.gl.p_glEnable(GL_VERTEX_PROGRAM_ARB);
+ checkGLcall("glEnable(GL_VERTEX_PROGRAM_ARB);");
+ TRACE("Bound vertex program %u and enabled GL_VERTEX_PROGRAM_ARB\n", priv->current_vprogram_id);
+ shader_arb_vs_local_constants(compiled, context, state);
+
+ if(priv->last_vs_color_unclamp != compiled->need_color_unclamp) {
+ priv->last_vs_color_unclamp = compiled->need_color_unclamp;
+
+ if (gl_info->supported[ARB_COLOR_BUFFER_FLOAT])
+ {
+ GL_EXTCALL(glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, !compiled->need_color_unclamp));
+ checkGLcall("glClampColorARB");
+ } else {
+ FIXME("vertex color clamp needs to be changed, but extension not supported.\n");
+ }
+ }
+ }
+ else
+ {
+ if (gl_info->supported[ARB_VERTEX_PROGRAM])
+ {
+ priv->current_vprogram_id = 0;
+ gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_PROGRAM_ARB);
+ checkGLcall("glDisable(GL_VERTEX_PROGRAM_ARB)");
+ }
+ priv->vertex_pipe->vp_enable(gl_info, TRUE);
+ }
+}
+
+
+/* Context activation is done by the caller. */
+static void shader_arb_disable(void *shader_priv, const struct wined3d_context *context)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct shader_arb_priv *priv = shader_priv;
+
+ if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_PROGRAM_ARB);
+ checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)");
+ priv->current_fprogram_id = 0;
+ }
+ priv->fragment_pipe->enable_extension(gl_info, FALSE);
+
+ if (gl_info->supported[ARB_VERTEX_PROGRAM])
+ {
+ priv->current_vprogram_id = 0;
+ gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_PROGRAM_ARB);
+ checkGLcall("glDisable(GL_VERTEX_PROGRAM_ARB)");
+ }
+ priv->vertex_pipe->vp_enable(gl_info, FALSE);
+
+ if (gl_info->supported[ARB_COLOR_BUFFER_FLOAT] && priv->last_vs_color_unclamp)
+ {
+ GL_EXTCALL(glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, GL_FIXED_ONLY_ARB));
+ checkGLcall("glClampColorARB");
+ priv->last_vs_color_unclamp = FALSE;
+ }
+}
+
+/* Context activation is done by the caller. */
+static void shader_arb_select_depth_blt(void *shader_priv, const struct wined3d_gl_info *gl_info,
+ enum tex_types tex_type, const SIZE *ds_mask_size)
+{
+ const float mask[] = {0.0f, 0.0f, (float)ds_mask_size->cx, (float)ds_mask_size->cy};
+ BOOL masked = ds_mask_size->cx && ds_mask_size->cy;
+ struct shader_arb_priv *priv = shader_priv;
+ GLuint *blt_fprogram;
+
+ if (!priv->depth_blt_vprogram_id) priv->depth_blt_vprogram_id = create_arb_blt_vertex_program(gl_info);
+ GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->depth_blt_vprogram_id));
+ gl_info->gl_ops.gl.p_glEnable(GL_VERTEX_PROGRAM_ARB);
+
+ blt_fprogram = masked ? &priv->depth_blt_fprogram_id_masked[tex_type] : &priv->depth_blt_fprogram_id_full[tex_type];
+ if (!*blt_fprogram) *blt_fprogram = create_arb_blt_fragment_program(gl_info, tex_type, masked);
+ GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, *blt_fprogram));
+ if (masked) GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0, mask));
+ gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB);
+}
+
+/* Context activation is done by the caller. */
+static void shader_arb_deselect_depth_blt(void *shader_priv, const struct wined3d_gl_info *gl_info)
+{
+ struct shader_arb_priv *priv = shader_priv;
+
+ if (priv->current_vprogram_id) {
+ GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, priv->current_vprogram_id));
+ checkGLcall("glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vertexShader->prgId);");
+
+ TRACE("Bound vertex program %u and enabled GL_VERTEX_PROGRAM_ARB.\n", priv->current_vprogram_id);
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_PROGRAM_ARB);
+ checkGLcall("glDisable(GL_VERTEX_PROGRAM_ARB)");
+ }
+
+ if (priv->current_fprogram_id) {
+ GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, priv->current_fprogram_id));
+ checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, pixelShader->prgId);");
+
+ TRACE("Bound fragment program %u and enabled GL_FRAGMENT_PROGRAM_ARB.\n", priv->current_fprogram_id);
+ }
+ else if(!priv->use_arbfp_fixed_func)
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_PROGRAM_ARB);
+ checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)");
+ }
+}
+
+static void shader_arb_destroy(struct wined3d_shader *shader)
+{
+ struct wined3d_device *device = shader->device;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+
+ if (shader_is_pshader_version(shader->reg_maps.shader_version.type))
+ {
+ struct arb_pshader_private *shader_data = shader->backend_data;
+ UINT i;
+
+ if(!shader_data) return; /* This can happen if a shader was never compiled */
+
+ if (shader_data->num_gl_shaders)
+ {
+ struct wined3d_context *context = context_acquire(device, NULL);
+
+ for (i = 0; i < shader_data->num_gl_shaders; ++i)
+ {
+ GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId));
+ checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId))");
+ }
+
+ context_release(context);
+ }
+
+ HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
+ HeapFree(GetProcessHeap(), 0, shader_data);
+ shader->backend_data = NULL;
+ }
+ else
+ {
+ struct arb_vshader_private *shader_data = shader->backend_data;
+ UINT i;
+
+ if(!shader_data) return; /* This can happen if a shader was never compiled */
+
+ if (shader_data->num_gl_shaders)
+ {
+ struct wined3d_context *context = context_acquire(device, NULL);
+
+ for (i = 0; i < shader_data->num_gl_shaders; ++i)
+ {
+ GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId));
+ checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId))");
+ }
+
+ context_release(context);
+ }
+
+ HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
+ HeapFree(GetProcessHeap(), 0, shader_data);
+ shader->backend_data = NULL;
+ }
+}
+
+static int sig_tree_compare(const void *key, const struct wine_rb_entry *entry)
+{
+ struct ps_signature *e = WINE_RB_ENTRY_VALUE(entry, struct ps_signature, entry);
+ return compare_sig(key, e->sig);
+}
+
+static const struct wine_rb_functions sig_tree_functions =
+{
+ wined3d_rb_alloc,
+ wined3d_rb_realloc,
+ wined3d_rb_free,
+ sig_tree_compare
+};
+
+static HRESULT shader_arb_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe,
+ const struct fragment_pipeline *fragment_pipe)
+{
+ struct shader_arb_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*priv));
+ struct fragment_caps fragment_caps;
+ void *vertex_priv, *fragment_priv;
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+
+ if (!(vertex_priv = vertex_pipe->vp_alloc(&arb_program_shader_backend, priv)))
+ {
+ ERR("Failed to initialize vertex pipe.\n");
+ HeapFree(GetProcessHeap(), 0, priv);
+ return E_FAIL;
+ }
+
+ if (!(fragment_priv = fragment_pipe->alloc_private(&arb_program_shader_backend, priv)))
+ {
+ ERR("Failed to initialize fragment pipe.\n");
+ vertex_pipe->vp_free(device);
+ HeapFree(GetProcessHeap(), 0, priv);
+ return E_FAIL;
+ }
+
+ priv->vshader_const_dirty = HeapAlloc(GetProcessHeap(), 0,
+ sizeof(*priv->vshader_const_dirty) * d3d_info->limits.vs_uniform_count);
+ if (!priv->vshader_const_dirty)
+ goto fail;
+ memset(priv->vshader_const_dirty, 1,
+ sizeof(*priv->vshader_const_dirty) * d3d_info->limits.vs_uniform_count);
+
+ priv->pshader_const_dirty = HeapAlloc(GetProcessHeap(), 0,
+ sizeof(*priv->pshader_const_dirty) * d3d_info->limits.ps_uniform_count);
+ if (!priv->pshader_const_dirty)
+ goto fail;
+ memset(priv->pshader_const_dirty, 1,
+ sizeof(*priv->pshader_const_dirty) * d3d_info->limits.ps_uniform_count);
+
+ if(wine_rb_init(&priv->signature_tree, &sig_tree_functions) == -1)
+ {
+ ERR("RB tree init failed\n");
+ goto fail;
+ }
+
+ priv->vertex_pipe = vertex_pipe;
+ priv->fragment_pipe = fragment_pipe;
+ fragment_pipe->get_caps(&device->adapter->gl_info, &fragment_caps);
+ priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL;
+
+ device->vertex_priv = vertex_priv;
+ device->fragment_priv = fragment_priv;
+ device->shader_priv = priv;
+
+ return WINED3D_OK;
+
+fail:
+ HeapFree(GetProcessHeap(), 0, priv->pshader_const_dirty);
+ HeapFree(GetProcessHeap(), 0, priv->vshader_const_dirty);
+ fragment_pipe->free_private(device);
+ vertex_pipe->vp_free(device);
+ HeapFree(GetProcessHeap(), 0, priv);
+ return E_OUTOFMEMORY;
+}
+
+static void release_signature(struct wine_rb_entry *entry, void *context)
+{
+ struct ps_signature *sig = WINE_RB_ENTRY_VALUE(entry, struct ps_signature, entry);
+ int i;
+ for(i = 0; i < MAX_REG_INPUT; i++)
+ {
+ HeapFree(GetProcessHeap(), 0, (char *) sig->sig[i].semantic_name);
+ }
+ HeapFree(GetProcessHeap(), 0, sig->sig);
+ HeapFree(GetProcessHeap(), 0, sig);
+}
+
+/* Context activation is done by the caller. */
+static void shader_arb_free(struct wined3d_device *device)
+{
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ struct shader_arb_priv *priv = device->shader_priv;
+ int i;
+
+ if (priv->depth_blt_vprogram_id)
+ GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_vprogram_id));
+
+ for (i = 0; i < tex_type_count; ++i)
+ {
+ if (priv->depth_blt_fprogram_id_full[i])
+ {
+ GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_fprogram_id_full[i]));
+ }
+ if (priv->depth_blt_fprogram_id_masked[i])
+ {
+ GL_EXTCALL(glDeleteProgramsARB(1, &priv->depth_blt_fprogram_id_masked[i]));
+ }
+ }
+
+ wine_rb_destroy(&priv->signature_tree, release_signature, NULL);
+ HeapFree(GetProcessHeap(), 0, priv->pshader_const_dirty);
+ HeapFree(GetProcessHeap(), 0, priv->vshader_const_dirty);
+ priv->fragment_pipe->free_private(device);
+ priv->vertex_pipe->vp_free(device);
+ HeapFree(GetProcessHeap(), 0, device->shader_priv);
+}
+
+static void shader_arb_context_destroyed(void *shader_priv, const struct wined3d_context *context)
+{
+ struct shader_arb_priv *priv = shader_priv;
+
+ if (priv->last_context == context)
+ priv->last_context = NULL;
+}
+
+static void shader_arb_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *caps)
+{
+ if (gl_info->supported[ARB_VERTEX_PROGRAM])
+ {
+ DWORD vs_consts;
+ UINT vs_version;
+
+ /* 96 is the minimum allowed value of MAX_PROGRAM_ENV_PARAMETERS_ARB
+ * for vertex programs. If the native limit is less than that it's
+ * not very useful, and e.g. Mesa swrast returns 0, probably to
+ * indicate it's a software implementation. */
+ if (gl_info->limits.arb_vs_native_constants < 96)
+ vs_consts = gl_info->limits.arb_vs_float_constants;
+ else
+ vs_consts = min(gl_info->limits.arb_vs_float_constants, gl_info->limits.arb_vs_native_constants);
+
+ if (gl_info->supported[NV_VERTEX_PROGRAM3])
+ {
+ vs_version = 3;
+ TRACE("Hardware vertex shader version 3.0 enabled (NV_VERTEX_PROGRAM3)\n");
+ }
+ else if (vs_consts >= 256)
+ {
+ /* Shader Model 2.0 requires at least 256 vertex shader constants */
+ vs_version = 2;
+ TRACE("Hardware vertex shader version 2.0 enabled (ARB_PROGRAM)\n");
+ }
+ else
+ {
+ vs_version = 1;
+ TRACE("Hardware vertex shader version 1.1 enabled (ARB_PROGRAM)\n");
+ }
+ caps->vs_version = min(wined3d_settings.max_sm_vs, vs_version);
+ caps->vs_uniform_count = vs_consts;
+ }
+ else
+ {
+ caps->vs_version = 0;
+ caps->vs_uniform_count = 0;
+ }
+
+ caps->gs_version = 0;
+
+ if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
+ {
+ DWORD ps_consts;
+ UINT ps_version;
+
+ /* Similar as above for vertex programs, but the minimum for fragment
+ * programs is 24. */
+ if (gl_info->limits.arb_ps_native_constants < 24)
+ ps_consts = gl_info->limits.arb_ps_float_constants;
+ else
+ ps_consts = min(gl_info->limits.arb_ps_float_constants, gl_info->limits.arb_ps_native_constants);
+
+ if (gl_info->supported[NV_FRAGMENT_PROGRAM2])
+ {
+ ps_version = 3;
+ TRACE("Hardware pixel shader version 3.0 enabled (NV_FRAGMENT_PROGRAM2)\n");
+ }
+ else if (ps_consts >= 32)
+ {
+ /* Shader Model 2.0 requires at least 32 pixel shader constants */
+ ps_version = 2;
+ TRACE("Hardware pixel shader version 2.0 enabled (ARB_PROGRAM)\n");
+ }
+ else
+ {
+ ps_version = 1;
+ TRACE("Hardware pixel shader version 1.4 enabled (ARB_PROGRAM)\n");
+ }
+ caps->ps_version = min(wined3d_settings.max_sm_ps, ps_version);
+ caps->ps_uniform_count = ps_consts;
+ caps->ps_1x_max_value = 8.0f;
+ }
+ else
+ {
+ caps->ps_version = 0;
+ caps->ps_uniform_count = 0;
+ caps->ps_1x_max_value = 0.0f;
+ }
+
+ caps->wined3d_caps = WINED3D_SHADER_CAP_SRGB_WRITE;
+ if (use_nv_clip(gl_info))
+ caps->wined3d_caps |= WINED3D_SHADER_CAP_VS_CLIPPING;
+}
+
+static BOOL shader_arb_color_fixup_supported(struct color_fixup_desc fixup)
+{
+ if (TRACE_ON(d3d_shader) && TRACE_ON(d3d))
+ {
+ TRACE("Checking support for color_fixup:\n");
+ dump_color_fixup_desc(fixup);
+ }
+
+ /* We support everything except complex conversions. */
+ if (!is_complex_fixup(fixup))
+ {
+ TRACE("[OK]\n");
+ return TRUE;
+ }
+
+ TRACE("[FAILED]\n");
+ return FALSE;
+}
+
+static void shader_arb_add_instruction_modifiers(const struct wined3d_shader_instruction *ins) {
+ DWORD shift;
+ char write_mask[20], regstr[50];
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ BOOL is_color = FALSE;
+ const struct wined3d_shader_dst_param *dst;
+
+ if (!ins->dst_count) return;
+
+ dst = &ins->dst[0];
+ shift = dst->shift;
+ if (!shift) return; /* Saturate alone is handled by the instructions */
+
+ shader_arb_get_write_mask(ins, dst, write_mask);
+ shader_arb_get_register_name(ins, &dst->reg, regstr, &is_color);
+
+ /* Generate a line that does the output modifier computation
+ * FIXME: _SAT vs shift? _SAT alone is already handled in the instructions, if this
+ * maps problems in e.g. _d4_sat modify shader_arb_get_modifier
+ */
+ shader_addline(buffer, "MUL%s %s%s, %s, %s;\n", shader_arb_get_modifier(ins),
+ regstr, write_mask, regstr, shift_tab[shift]);
+}
+
+static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABLE_SIZE] =
+{
+ /* WINED3DSIH_ABS */ shader_hw_map2gl,
+ /* WINED3DSIH_ADD */ shader_hw_map2gl,
+ /* WINED3DSIH_AND */ NULL,
+ /* WINED3DSIH_BEM */ pshader_hw_bem,
+ /* WINED3DSIH_BREAK */ shader_hw_break,
+ /* WINED3DSIH_BREAKC */ shader_hw_breakc,
+ /* WINED3DSIH_BREAKP */ NULL,
+ /* WINED3DSIH_CALL */ shader_hw_call,
+ /* WINED3DSIH_CALLNZ */ NULL,
+ /* WINED3DSIH_CMP */ pshader_hw_cmp,
+ /* WINED3DSIH_CND */ pshader_hw_cnd,
+ /* WINED3DSIH_CRS */ shader_hw_map2gl,
+ /* WINED3DSIH_CUT */ NULL,
+ /* WINED3DSIH_DCL */ shader_hw_nop,
+ /* WINED3DSIH_DCL_CONSTANT_BUFFER */ shader_hw_nop,
+ /* WINED3DSIH_DCL_INPUT_PRIMITIVE */ shader_hw_nop,
+ /* WINED3DSIH_DCL_OUTPUT_TOPOLOGY */ shader_hw_nop,
+ /* WINED3DSIH_DCL_VERTICES_OUT */ shader_hw_nop,
+ /* WINED3DSIH_DEF */ shader_hw_nop,
+ /* WINED3DSIH_DEFB */ shader_hw_nop,
+ /* WINED3DSIH_DEFI */ shader_hw_nop,
+ /* WINED3DSIH_DIV */ NULL,
+ /* WINED3DSIH_DP2ADD */ pshader_hw_dp2add,
+ /* WINED3DSIH_DP3 */ shader_hw_map2gl,
+ /* WINED3DSIH_DP4 */ shader_hw_map2gl,
+ /* WINED3DSIH_DST */ shader_hw_map2gl,
+ /* WINED3DSIH_DSX */ shader_hw_map2gl,
+ /* WINED3DSIH_DSY */ shader_hw_dsy,
+ /* WINED3DSIH_ELSE */ shader_hw_else,
+ /* WINED3DSIH_EMIT */ NULL,
+ /* WINED3DSIH_ENDIF */ shader_hw_endif,
+ /* WINED3DSIH_ENDLOOP */ shader_hw_endloop,
+ /* WINED3DSIH_ENDREP */ shader_hw_endrep,
+ /* WINED3DSIH_EQ */ NULL,
+ /* WINED3DSIH_EXP */ shader_hw_scalar_op,
+ /* WINED3DSIH_EXPP */ shader_hw_scalar_op,
+ /* WINED3DSIH_FRC */ shader_hw_map2gl,
+ /* WINED3DSIH_FTOI */ NULL,
+ /* WINED3DSIH_GE */ NULL,
+ /* WINED3DSIH_IADD */ NULL,
+ /* WINED3DSIH_IEQ */ NULL,
+ /* WINED3DSIH_IF */ NULL /* Hardcoded into the shader */,
+ /* WINED3DSIH_IFC */ shader_hw_ifc,
+ /* WINED3DSIH_IGE */ NULL,
+ /* WINED3DSIH_IMUL */ NULL,
+ /* WINED3DSIH_ITOF */ NULL,
+ /* WINED3DSIH_LABEL */ shader_hw_label,
+ /* WINED3DSIH_LD */ NULL,
+ /* WINED3DSIH_LIT */ shader_hw_map2gl,
+ /* WINED3DSIH_LOG */ shader_hw_log,
+ /* WINED3DSIH_LOGP */ shader_hw_log,
+ /* WINED3DSIH_LOOP */ shader_hw_loop,
+ /* WINED3DSIH_LRP */ shader_hw_lrp,
+ /* WINED3DSIH_LT */ NULL,
+ /* WINED3DSIH_M3x2 */ shader_hw_mnxn,
+ /* WINED3DSIH_M3x3 */ shader_hw_mnxn,
+ /* WINED3DSIH_M3x4 */ shader_hw_mnxn,
+ /* WINED3DSIH_M4x3 */ shader_hw_mnxn,
+ /* WINED3DSIH_M4x4 */ shader_hw_mnxn,
+ /* WINED3DSIH_MAD */ shader_hw_map2gl,
+ /* WINED3DSIH_MAX */ shader_hw_map2gl,
+ /* WINED3DSIH_MIN */ shader_hw_map2gl,
+ /* WINED3DSIH_MOV */ shader_hw_mov,
+ /* WINED3DSIH_MOVA */ shader_hw_mov,
+ /* WINED3DSIH_MOVC */ NULL,
+ /* WINED3DSIH_MUL */ shader_hw_map2gl,
+ /* WINED3DSIH_NOP */ shader_hw_nop,
+ /* WINED3DSIH_NRM */ shader_hw_nrm,
+ /* WINED3DSIH_PHASE */ shader_hw_nop,
+ /* WINED3DSIH_POW */ shader_hw_pow,
+ /* WINED3DSIH_RCP */ shader_hw_rcp,
+ /* WINED3DSIH_REP */ shader_hw_rep,
+ /* WINED3DSIH_RET */ shader_hw_ret,
+ /* WINED3DSIH_ROUND_NI */ NULL,
+ /* WINED3DSIH_RSQ */ shader_hw_scalar_op,
+ /* WINED3DSIH_SAMPLE */ NULL,
+ /* WINED3DSIH_SAMPLE_GRAD */ NULL,
+ /* WINED3DSIH_SAMPLE_LOD */ NULL,
+ /* WINED3DSIH_SETP */ NULL,
+ /* WINED3DSIH_SGE */ shader_hw_map2gl,
+ /* WINED3DSIH_SGN */ shader_hw_sgn,
+ /* WINED3DSIH_SINCOS */ shader_hw_sincos,
+ /* WINED3DSIH_SLT */ shader_hw_map2gl,
+ /* WINED3DSIH_SQRT */ NULL,
+ /* WINED3DSIH_SUB */ shader_hw_map2gl,
+ /* WINED3DSIH_TEX */ pshader_hw_tex,
+ /* WINED3DSIH_TEXBEM */ pshader_hw_texbem,
+ /* WINED3DSIH_TEXBEML */ pshader_hw_texbem,
+ /* WINED3DSIH_TEXCOORD */ pshader_hw_texcoord,
+ /* WINED3DSIH_TEXDEPTH */ pshader_hw_texdepth,
+ /* WINED3DSIH_TEXDP3 */ pshader_hw_texdp3,
+ /* WINED3DSIH_TEXDP3TEX */ pshader_hw_texdp3tex,
+ /* WINED3DSIH_TEXKILL */ pshader_hw_texkill,
+ /* WINED3DSIH_TEXLDD */ shader_hw_texldd,
+ /* WINED3DSIH_TEXLDL */ shader_hw_texldl,
+ /* WINED3DSIH_TEXM3x2DEPTH */ pshader_hw_texm3x2depth,
+ /* WINED3DSIH_TEXM3x2PAD */ pshader_hw_texm3x2pad,
+ /* WINED3DSIH_TEXM3x2TEX */ pshader_hw_texm3x2tex,
+ /* WINED3DSIH_TEXM3x3 */ pshader_hw_texm3x3,
+ /* WINED3DSIH_TEXM3x3DIFF */ NULL,
+ /* WINED3DSIH_TEXM3x3PAD */ pshader_hw_texm3x3pad,
+ /* WINED3DSIH_TEXM3x3SPEC */ pshader_hw_texm3x3spec,
+ /* WINED3DSIH_TEXM3x3TEX */ pshader_hw_texm3x3tex,
+ /* WINED3DSIH_TEXM3x3VSPEC */ pshader_hw_texm3x3vspec,
+ /* WINED3DSIH_TEXREG2AR */ pshader_hw_texreg2ar,
+ /* WINED3DSIH_TEXREG2GB */ pshader_hw_texreg2gb,
+ /* WINED3DSIH_TEXREG2RGB */ pshader_hw_texreg2rgb,
+ /* WINED3DSIH_UDIV */ NULL,
+ /* WINED3DSIH_USHR */ NULL,
+ /* WINED3DSIH_UTOF */ NULL,
+ /* WINED3DSIH_XOR */ NULL,
+};
+
+static BOOL get_bool_const(const struct wined3d_shader_instruction *ins,
+ const struct wined3d_shader *shader, DWORD idx)
+{
+ const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
+ BOOL vshader = shader_is_vshader_version(reg_maps->shader_version.type);
+ const struct wined3d_shader_lconst *constant;
+ WORD bools = 0;
+ WORD flag = (1 << idx);
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+
+ if (reg_maps->local_bool_consts & flag)
+ {
+ /* What good is a if(bool) with a hardcoded local constant? I don't know, but handle it */
+ LIST_FOR_EACH_ENTRY(constant, &shader->constantsB, struct wined3d_shader_lconst, entry)
+ {
+ if (constant->idx == idx)
+ {
+ return constant->value[0];
+ }
+ }
+ ERR("Local constant not found\n");
+ return FALSE;
+ }
+ else
+ {
+ if(vshader) bools = priv->cur_vs_args->clip.boolclip.bools;
+ else bools = priv->cur_ps_args->bools;
+ return bools & flag;
+ }
+}
+
+static void get_loop_control_const(const struct wined3d_shader_instruction *ins,
+ const struct wined3d_shader *shader, UINT idx, struct wined3d_shader_loop_control *loop_control)
+{
+ const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+
+ /* Integer constants can either be a local constant, or they can be stored in the shader
+ * type specific compile args. */
+ if (reg_maps->local_int_consts & (1 << idx))
+ {
+ const struct wined3d_shader_lconst *constant;
+
+ LIST_FOR_EACH_ENTRY(constant, &shader->constantsI, struct wined3d_shader_lconst, entry)
+ {
+ if (constant->idx == idx)
+ {
+ loop_control->count = constant->value[0];
+ loop_control->start = constant->value[1];
+ /* Step is signed. */
+ loop_control->step = (int)constant->value[2];
+ return;
+ }
+ }
+ /* If this happens the flag was set incorrectly */
+ ERR("Local constant not found\n");
+ loop_control->count = 0;
+ loop_control->start = 0;
+ loop_control->step = 0;
+ return;
+ }
+
+ switch (reg_maps->shader_version.type)
+ {
+ case WINED3D_SHADER_TYPE_VERTEX:
+ /* Count and aL start value are unsigned */
+ loop_control->count = priv->cur_vs_args->loop_ctrl[idx][0];
+ loop_control->start = priv->cur_vs_args->loop_ctrl[idx][1];
+ /* Step is signed. */
+ loop_control->step = ((char)priv->cur_vs_args->loop_ctrl[idx][2]);
+ break;
+
+ case WINED3D_SHADER_TYPE_PIXEL:
+ loop_control->count = priv->cur_ps_args->loop_ctrl[idx][0];
+ loop_control->start = priv->cur_ps_args->loop_ctrl[idx][1];
+ loop_control->step = ((char)priv->cur_ps_args->loop_ctrl[idx][2]);
+ break;
+
+ default:
+ FIXME("Unhandled shader type %#x.\n", reg_maps->shader_version.type);
+ break;
+ }
+}
+
+static void record_instruction(struct list *list, const struct wined3d_shader_instruction *ins)
+{
+ unsigned int i;
+ struct wined3d_shader_dst_param *dst_param = NULL;
+ struct wined3d_shader_src_param *src_param = NULL, *rel_addr = NULL;
+ struct recorded_instruction *rec = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*rec));
+ if(!rec)
+ {
+ ERR("Out of memory\n");
+ return;
+ }
+
+ rec->ins = *ins;
+ dst_param = HeapAlloc(GetProcessHeap(), 0, sizeof(*dst_param));
+ if(!dst_param) goto free;
+ *dst_param = *ins->dst;
+ if (ins->dst->reg.idx[0].rel_addr)
+ {
+ rel_addr = HeapAlloc(GetProcessHeap(), 0, sizeof(*rel_addr));
+ if (!rel_addr)
+ goto free;
+ *rel_addr = *ins->dst->reg.idx[0].rel_addr;
+ dst_param->reg.idx[0].rel_addr = rel_addr;
+ }
+ rec->ins.dst = dst_param;
+
+ src_param = HeapAlloc(GetProcessHeap(), 0, sizeof(*src_param) * ins->src_count);
+ if (!src_param)
+ goto free;
+ for (i = 0; i < ins->src_count; ++i)
+ {
+ src_param[i] = ins->src[i];
+ if (ins->src[i].reg.idx[0].rel_addr)
+ {
+ rel_addr = HeapAlloc(GetProcessHeap(), 0, sizeof(*rel_addr));
+ if (!rel_addr)
+ goto free;
+ *rel_addr = *ins->src[i].reg.idx[0].rel_addr;
+ src_param[i].reg.idx[0].rel_addr = rel_addr;
+ }
+ }
+ rec->ins.src = src_param;
+ list_add_tail(list, &rec->entry);
+ return;
+
+free:
+ ERR("Out of memory\n");
+ if(dst_param)
+ {
+ HeapFree(GetProcessHeap(), 0, (void *)dst_param->reg.idx[0].rel_addr);
+ HeapFree(GetProcessHeap(), 0, dst_param);
+ }
+ if(src_param)
+ {
+ for(i = 0; i < ins->src_count; i++)
+ {
+ HeapFree(GetProcessHeap(), 0, (void *)src_param[i].reg.idx[0].rel_addr);
+ }
+ HeapFree(GetProcessHeap(), 0, src_param);
+ }
+ HeapFree(GetProcessHeap(), 0, rec);
+}
+
+static void free_recorded_instruction(struct list *list)
+{
+ struct recorded_instruction *rec_ins, *entry2;
+ unsigned int i;
+
+ LIST_FOR_EACH_ENTRY_SAFE(rec_ins, entry2, list, struct recorded_instruction, entry)
+ {
+ list_remove(&rec_ins->entry);
+ if (rec_ins->ins.dst)
+ {
+ HeapFree(GetProcessHeap(), 0, (void *)rec_ins->ins.dst->reg.idx[0].rel_addr);
+ HeapFree(GetProcessHeap(), 0, (void *)rec_ins->ins.dst);
+ }
+ if (rec_ins->ins.src)
+ {
+ for (i = 0; i < rec_ins->ins.src_count; ++i)
+ {
+ HeapFree(GetProcessHeap(), 0, (void *)rec_ins->ins.src[i].reg.idx[0].rel_addr);
+ }
+ HeapFree(GetProcessHeap(), 0, (void *)rec_ins->ins.src);
+ }
+ HeapFree(GetProcessHeap(), 0, rec_ins);
+ }
+}
+
+static void pop_control_frame(const struct wined3d_shader_instruction *ins)
+{
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ struct control_frame *control_frame;
+
+ if (ins->handler_idx == WINED3DSIH_ENDLOOP || ins->handler_idx == WINED3DSIH_ENDREP)
+ {
+ struct list *e = list_head(&priv->control_frames);
+ control_frame = LIST_ENTRY(e, struct control_frame, entry);
+ list_remove(&control_frame->entry);
+ HeapFree(GetProcessHeap(), 0, control_frame);
+ priv->loop_depth--;
+ }
+ else if (ins->handler_idx == WINED3DSIH_ENDIF)
+ {
+ /* Non-ifc ENDIFs were already handled previously. */
+ struct list *e = list_head(&priv->control_frames);
+ control_frame = LIST_ENTRY(e, struct control_frame, entry);
+ list_remove(&control_frame->entry);
+ HeapFree(GetProcessHeap(), 0, control_frame);
+ }
+}
+
+static void shader_arb_handle_instruction(const struct wined3d_shader_instruction *ins) {
+ SHADER_HANDLER hw_fct;
+ struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
+ const struct wined3d_shader *shader = ins->ctx->shader;
+ struct control_frame *control_frame;
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ BOOL bool_const;
+
+ if(ins->handler_idx == WINED3DSIH_LOOP || ins->handler_idx == WINED3DSIH_REP)
+ {
+ control_frame = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*control_frame));
+ list_add_head(&priv->control_frames, &control_frame->entry);
+
+ if(ins->handler_idx == WINED3DSIH_LOOP) control_frame->type = LOOP;
+ if(ins->handler_idx == WINED3DSIH_REP) control_frame->type = REP;
+
+ if(priv->target_version >= NV2)
+ {
+ control_frame->no.loop = priv->num_loops++;
+ priv->loop_depth++;
+ }
+ else
+ {
+ /* Don't bother recording when we're in a not used if branch */
+ if(priv->muted)
+ {
+ return;
+ }
+
+ if(!priv->recording)
+ {
+ list_init(&priv->record);
+ priv->recording = TRUE;
+ control_frame->outer_loop = TRUE;
+ get_loop_control_const(ins, shader, ins->src[0].reg.idx[0].offset, &control_frame->loop_control);
+ return; /* Instruction is handled */
+ }
+ /* Record this loop in the outer loop's recording */
+ }
+ }
+ else if(ins->handler_idx == WINED3DSIH_ENDLOOP || ins->handler_idx == WINED3DSIH_ENDREP)
+ {
+ if(priv->target_version >= NV2)
+ {
+ /* Nothing to do. The control frame is popped after the HW instr handler */
+ }
+ else
+ {
+ struct list *e = list_head(&priv->control_frames);
+ control_frame = LIST_ENTRY(e, struct control_frame, entry);
+ list_remove(&control_frame->entry);
+
+ if(control_frame->outer_loop)
+ {
+ unsigned int iteration;
+ int aL = 0;
+ struct list copy;
+
+ /* Turn off recording before playback */
+ priv->recording = FALSE;
+
+ /* Move the recorded instructions to a separate list and get them out of the private data
+ * structure. If there are nested loops, the shader_arb_handle_instruction below will
+ * be recorded again, thus priv->record might be overwritten
+ */
+ list_init(&copy);
+ list_move_tail(&copy, &priv->record);
+ list_init(&priv->record);
+
+ if(ins->handler_idx == WINED3DSIH_ENDLOOP)
+ {
+ shader_addline(buffer, "#unrolling loop: %u iterations, aL=%u, inc %d\n",
+ control_frame->loop_control.count, control_frame->loop_control.start,
+ control_frame->loop_control.step);
+ aL = control_frame->loop_control.start;
+ }
+ else
+ {
+ shader_addline(buffer, "#unrolling rep: %u iterations\n", control_frame->loop_control.count);
+ }
+
+ for (iteration = 0; iteration < control_frame->loop_control.count; ++iteration)
+ {
+ struct recorded_instruction *rec_ins;
+ if(ins->handler_idx == WINED3DSIH_ENDLOOP)
+ {
+ priv->aL = aL;
+ shader_addline(buffer, "#Iteration %u, aL=%d\n", iteration, aL);
+ }
+ else
+ {
+ shader_addline(buffer, "#Iteration %u\n", iteration);
+ }
+
+ LIST_FOR_EACH_ENTRY(rec_ins, &copy, struct recorded_instruction, entry)
+ {
+ shader_arb_handle_instruction(&rec_ins->ins);
+ }
+
+ if(ins->handler_idx == WINED3DSIH_ENDLOOP)
+ {
+ aL += control_frame->loop_control.step;
+ }
+ }
+ shader_addline(buffer, "#end loop/rep\n");
+
+ free_recorded_instruction(&copy);
+ HeapFree(GetProcessHeap(), 0, control_frame);
+ return; /* Instruction is handled */
+ }
+ else
+ {
+ /* This is a nested loop. Proceed to the normal recording function */
+ HeapFree(GetProcessHeap(), 0, control_frame);
+ }
+ }
+ }
+
+ if(priv->recording)
+ {
+ record_instruction(&priv->record, ins);
+ return;
+ }
+
+ /* boolean if */
+ if(ins->handler_idx == WINED3DSIH_IF)
+ {
+ control_frame = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*control_frame));
+ list_add_head(&priv->control_frames, &control_frame->entry);
+ control_frame->type = IF;
+
+ bool_const = get_bool_const(ins, shader, ins->src[0].reg.idx[0].offset);
+ if (ins->src[0].modifiers == WINED3DSPSM_NOT)
+ bool_const = !bool_const;
+ if (!priv->muted && !bool_const)
+ {
+ shader_addline(buffer, "#if(FALSE){\n");
+ priv->muted = TRUE;
+ control_frame->muting = TRUE;
+ }
+ else shader_addline(buffer, "#if(TRUE) {\n");
+
+ return; /* Instruction is handled */
+ }
+ else if(ins->handler_idx == WINED3DSIH_IFC)
+ {
+ /* IF(bool) and if_cond(a, b) use the same ELSE and ENDIF tokens */
+ control_frame = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*control_frame));
+ control_frame->type = IFC;
+ control_frame->no.ifc = priv->num_ifcs++;
+ list_add_head(&priv->control_frames, &control_frame->entry);
+ }
+ else if(ins->handler_idx == WINED3DSIH_ELSE)
+ {
+ struct list *e = list_head(&priv->control_frames);
+ control_frame = LIST_ENTRY(e, struct control_frame, entry);
+
+ if(control_frame->type == IF)
+ {
+ shader_addline(buffer, "#} else {\n");
+ if(!priv->muted && !control_frame->muting)
+ {
+ priv->muted = TRUE;
+ control_frame->muting = TRUE;
+ }
+ else if(control_frame->muting) priv->muted = FALSE;
+ return; /* Instruction is handled. */
+ }
+ /* In case of an ifc, generate a HW shader instruction */
+ if (control_frame->type != IFC)
+ ERR("Control frame does not match.\n");
+ }
+ else if(ins->handler_idx == WINED3DSIH_ENDIF)
+ {
+ struct list *e = list_head(&priv->control_frames);
+ control_frame = LIST_ENTRY(e, struct control_frame, entry);
+
+ if(control_frame->type == IF)
+ {
+ shader_addline(buffer, "#} endif\n");
+ if(control_frame->muting) priv->muted = FALSE;
+ list_remove(&control_frame->entry);
+ HeapFree(GetProcessHeap(), 0, control_frame);
+ return; /* Instruction is handled */
+ }
+ /* In case of an ifc, generate a HW shader instruction */
+ if (control_frame->type != IFC)
+ ERR("Control frame does not match.\n");
+ }
+
+ if(priv->muted)
+ {
+ pop_control_frame(ins);
+ return;
+ }
+
+ /* Select handler */
+ hw_fct = shader_arb_instruction_handler_table[ins->handler_idx];
+
+ /* Unhandled opcode */
+ if (!hw_fct)
+ {
+ FIXME("Backend can't handle opcode %#x\n", ins->handler_idx);
+ return;
+ }
+ hw_fct(ins);
+
+ pop_control_frame(ins);
+
+ shader_arb_add_instruction_modifiers(ins);
+}
+
+static BOOL shader_arb_has_ffp_proj_control(void *shader_priv)
+{
+ struct shader_arb_priv *priv = shader_priv;
+
+ return priv->ffp_proj_control;
+}
+
+const struct wined3d_shader_backend_ops arb_program_shader_backend =
+{
+ shader_arb_handle_instruction,
+ shader_arb_select,
+ shader_arb_disable,
+ shader_arb_select_depth_blt,
+ shader_arb_deselect_depth_blt,
+ shader_arb_update_float_vertex_constants,
+ shader_arb_update_float_pixel_constants,
+ shader_arb_load_constants,
+ shader_arb_load_np2fixup_constants,
+ shader_arb_destroy,
+ shader_arb_alloc,
+ shader_arb_free,
+ shader_arb_context_destroyed,
+ shader_arb_get_caps,
+ shader_arb_color_fixup_supported,
+ shader_arb_has_ffp_proj_control,
+};
+
+/* ARB_fragment_program fixed function pipeline replacement definitions */
+#define ARB_FFP_CONST_TFACTOR 0
+#define ARB_FFP_CONST_SPECULAR_ENABLE ((ARB_FFP_CONST_TFACTOR) + 1)
+#define ARB_FFP_CONST_CONSTANT(i) ((ARB_FFP_CONST_SPECULAR_ENABLE) + 1 + i)
+#define ARB_FFP_CONST_BUMPMAT(i) ((ARB_FFP_CONST_CONSTANT(7)) + 1 + i)
+#define ARB_FFP_CONST_LUMINANCE(i) ((ARB_FFP_CONST_BUMPMAT(7)) + 1 + i)
+
+struct arbfp_ffp_desc
+{
+ struct ffp_frag_desc parent;
+ GLuint shader;
+};
+
+/* Context activation is done by the caller. */
+static void arbfp_enable(const struct wined3d_gl_info *gl_info, BOOL enable)
+{
+ if (enable)
+ {
+ gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB);
+ checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB)");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_PROGRAM_ARB);
+ checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)");
+ }
+}
+
+static void *arbfp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
+{
+ struct shader_arb_priv *priv;
+
+ /* Share private data between the shader backend and the pipeline
+ * replacement, if both are the arb implementation. This is needed to
+ * figure out whether ARBfp should be disabled if no pixel shader is bound
+ * or not. */
+ if (shader_backend == &arb_program_shader_backend)
+ priv = shader_priv;
+ else if (!(priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*priv))))
+ return NULL;
+
+ if (wine_rb_init(&priv->fragment_shaders, &wined3d_ffp_frag_program_rb_functions) == -1)
+ {
+ ERR("Failed to initialize rbtree.\n");
+ if (priv != shader_priv)
+ HeapFree(GetProcessHeap(), 0, priv);
+ return NULL;
+ }
+ priv->use_arbfp_fixed_func = TRUE;
+
+ return priv;
+}
+
+/* Context activation is done by the caller. */
+static void arbfp_free_ffpshader(struct wine_rb_entry *entry, void *context)
+{
+ const struct wined3d_gl_info *gl_info = context;
+ struct arbfp_ffp_desc *entry_arb = WINE_RB_ENTRY_VALUE(entry, struct arbfp_ffp_desc, parent.entry);
+
+ GL_EXTCALL(glDeleteProgramsARB(1, &entry_arb->shader));
+ checkGLcall("glDeleteProgramsARB(1, &entry_arb->shader)");
+ HeapFree(GetProcessHeap(), 0, entry_arb);
+}
+
+/* Context activation is done by the caller. */
+static void arbfp_free(struct wined3d_device *device)
+{
+ struct shader_arb_priv *priv = device->fragment_priv;
+
+ wine_rb_destroy(&priv->fragment_shaders, arbfp_free_ffpshader, &device->adapter->gl_info);
+ priv->use_arbfp_fixed_func = FALSE;
+
+ if (device->shader_backend != &arb_program_shader_backend)
+ {
+ HeapFree(GetProcessHeap(), 0, device->fragment_priv);
+ }
+}
+
+static void arbfp_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
+{
+ caps->wined3d_caps = WINED3D_FRAGMENT_CAP_PROJ_CONTROL
+ | WINED3D_FRAGMENT_CAP_SRGB_WRITE;
+ caps->PrimitiveMiscCaps = WINED3DPMISCCAPS_TSSARGTEMP;
+ caps->TextureOpCaps = WINED3DTEXOPCAPS_DISABLE |
+ WINED3DTEXOPCAPS_SELECTARG1 |
+ WINED3DTEXOPCAPS_SELECTARG2 |
+ WINED3DTEXOPCAPS_MODULATE4X |
+ WINED3DTEXOPCAPS_MODULATE2X |
+ WINED3DTEXOPCAPS_MODULATE |
+ WINED3DTEXOPCAPS_ADDSIGNED2X |
+ WINED3DTEXOPCAPS_ADDSIGNED |
+ WINED3DTEXOPCAPS_ADD |
+ WINED3DTEXOPCAPS_SUBTRACT |
+ WINED3DTEXOPCAPS_ADDSMOOTH |
+ WINED3DTEXOPCAPS_BLENDCURRENTALPHA |
+ WINED3DTEXOPCAPS_BLENDFACTORALPHA |
+ WINED3DTEXOPCAPS_BLENDTEXTUREALPHA |
+ WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA |
+ WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM |
+ WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
+ WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
+ WINED3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA |
+ WINED3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR |
+ WINED3DTEXOPCAPS_DOTPRODUCT3 |
+ WINED3DTEXOPCAPS_MULTIPLYADD |
+ WINED3DTEXOPCAPS_LERP |
+ WINED3DTEXOPCAPS_BUMPENVMAP |
+ WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE;
+
+ /* TODO: Implement WINED3DTEXOPCAPS_PREMODULATE */
+
+ caps->MaxTextureBlendStages = 8;
+ caps->MaxSimultaneousTextures = min(gl_info->limits.fragment_samplers, 8);
+}
+
+static void state_texfactor_arbfp(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id)
+{
+ struct wined3d_device *device = context->swapchain->device;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ float col[4];
+
+ /* Don't load the parameter if we're using an arbfp pixel shader,
+ * otherwise we'll overwrite application provided constants. */
+ if (device->shader_backend == &arb_program_shader_backend)
+ {
+ struct shader_arb_priv *priv;
+
+ if (use_ps(state)) return;
+
+ priv = device->shader_priv;
+ priv->pshader_const_dirty[ARB_FFP_CONST_TFACTOR] = 1;
+ priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, ARB_FFP_CONST_TFACTOR + 1);
+ }
+
+ D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col);
+ GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_TFACTOR, col));
+ checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_TFACTOR, col)");
+}
+
+static void state_arb_specularenable(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id)
+{
+ struct wined3d_device *device = context->swapchain->device;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ float col[4];
+
+ /* Don't load the parameter if we're using an arbfp pixel shader, otherwise we'll overwrite
+ * application provided constants
+ */
+ if (device->shader_backend == &arb_program_shader_backend)
+ {
+ struct shader_arb_priv *priv;
+
+ if (use_ps(state)) return;
+
+ priv = device->shader_priv;
+ priv->pshader_const_dirty[ARB_FFP_CONST_SPECULAR_ENABLE] = 1;
+ priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, ARB_FFP_CONST_SPECULAR_ENABLE + 1);
+ }
+
+ if (state->render_states[WINED3D_RS_SPECULARENABLE])
+ {
+ /* The specular color has no alpha */
+ col[0] = 1.0f; col[1] = 1.0f;
+ col[2] = 1.0f; col[3] = 0.0f;
+ } else {
+ col[0] = 0.0f; col[1] = 0.0f;
+ col[2] = 0.0f; col[3] = 0.0f;
+ }
+ GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_SPECULAR_ENABLE, col));
+ checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_SPECULAR_ENABLE, col)");
+}
+
+static void set_bumpmat_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
+ struct wined3d_device *device = context->swapchain->device;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ float mat[2][2];
+
+ if (use_ps(state))
+ {
+ /* The pixel shader has to know the bump env matrix. Do a constants
+ * update. */
+ if (stage && (state->pixel_shader->reg_maps.bumpmat & (1 << stage)))
+ context->load_constants = 1;
+
+ if(device->shader_backend == &arb_program_shader_backend) {
+ /* Exit now, don't set the bumpmat below, otherwise we may overwrite pixel shader constants */
+ return;
+ }
+ }
+ else if (device->shader_backend == &arb_program_shader_backend)
+ {
+ struct shader_arb_priv *priv = device->shader_priv;
+ priv->pshader_const_dirty[ARB_FFP_CONST_BUMPMAT(stage)] = 1;
+ priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, ARB_FFP_CONST_BUMPMAT(stage) + 1);
+ }
+
+ mat[0][0] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_MAT00]);
+ mat[0][1] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_MAT01]);
+ mat[1][0] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_MAT10]);
+ mat[1][1] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_MAT11]);
+
+ GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_BUMPMAT(stage), &mat[0][0]));
+ checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_BUMPMAT(stage), &mat[0][0])");
+}
+
+static void tex_bumpenvlum_arbfp(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id)
+{
+ DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
+ struct wined3d_device *device = context->swapchain->device;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ float param[4];
+
+ if (use_ps(state))
+ {
+ /* The pixel shader has to know the luminance offset. Do a constants
+ * update. */
+ if (stage && (state->pixel_shader->reg_maps.luminanceparams & (1 << stage)))
+ context->load_constants = 1;
+
+ if(device->shader_backend == &arb_program_shader_backend) {
+ /* Exit now, don't set the bumpmat below, otherwise we may overwrite pixel shader constants */
+ return;
+ }
+ }
+ else if (device->shader_backend == &arb_program_shader_backend)
+ {
+ struct shader_arb_priv *priv = device->shader_priv;
+ priv->pshader_const_dirty[ARB_FFP_CONST_LUMINANCE(stage)] = 1;
+ priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, ARB_FFP_CONST_LUMINANCE(stage) + 1);
+ }
+
+ param[0] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_LSCALE]);
+ param[1] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_LOFFSET]);
+ param[2] = 0.0f;
+ param[3] = 0.0f;
+
+ GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_LUMINANCE(stage), param));
+ checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_LUMINANCE(stage), param)");
+}
+
+static const char *get_argreg(struct wined3d_shader_buffer *buffer, DWORD argnum, unsigned int stage, DWORD arg)
+{
+ const char *ret;
+
+ if(arg == ARG_UNUSED) return "unused"; /* This is the marker for unused registers */
+
+ switch(arg & WINED3DTA_SELECTMASK) {
+ case WINED3DTA_DIFFUSE:
+ ret = "fragment.color.primary"; break;
+
+ case WINED3DTA_CURRENT:
+ if (!stage) ret = "fragment.color.primary";
+ else ret = "ret";
+ break;
+
+ case WINED3DTA_TEXTURE:
+ switch(stage) {
+ case 0: ret = "tex0"; break;
+ case 1: ret = "tex1"; break;
+ case 2: ret = "tex2"; break;
+ case 3: ret = "tex3"; break;
+ case 4: ret = "tex4"; break;
+ case 5: ret = "tex5"; break;
+ case 6: ret = "tex6"; break;
+ case 7: ret = "tex7"; break;
+ default: ret = "unknown texture";
+ }
+ break;
+
+ case WINED3DTA_TFACTOR:
+ ret = "tfactor"; break;
+
+ case WINED3DTA_SPECULAR:
+ ret = "fragment.color.secondary"; break;
+
+ case WINED3DTA_TEMP:
+ ret = "tempreg"; break;
+
+ case WINED3DTA_CONSTANT:
+ FIXME("Implement perstage constants\n");
+ switch(stage) {
+ case 0: ret = "const0"; break;
+ case 1: ret = "const1"; break;
+ case 2: ret = "const2"; break;
+ case 3: ret = "const3"; break;
+ case 4: ret = "const4"; break;
+ case 5: ret = "const5"; break;
+ case 6: ret = "const6"; break;
+ case 7: ret = "const7"; break;
+ default: ret = "unknown constant";
+ }
+ break;
+
+ default:
+ return "unknown";
+ }
+
+ if(arg & WINED3DTA_COMPLEMENT) {
+ shader_addline(buffer, "SUB arg%u, const.x, %s;\n", argnum, ret);
+ if(argnum == 0) ret = "arg0";
+ if(argnum == 1) ret = "arg1";
+ if(argnum == 2) ret = "arg2";
+ }
+ if(arg & WINED3DTA_ALPHAREPLICATE) {
+ shader_addline(buffer, "MOV arg%u, %s.w;\n", argnum, ret);
+ if(argnum == 0) ret = "arg0";
+ if(argnum == 1) ret = "arg1";
+ if(argnum == 2) ret = "arg2";
+ }
+ return ret;
+}
+
+static void gen_ffp_instr(struct wined3d_shader_buffer *buffer, unsigned int stage, BOOL color,
+ BOOL alpha, DWORD dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2)
+{
+ const char *dstmask, *dstreg, *arg0, *arg1, *arg2;
+ unsigned int mul = 1;
+
+ if(color && alpha) dstmask = "";
+ else if(color) dstmask = ".xyz";
+ else dstmask = ".w";
+
+ if(dst == tempreg) dstreg = "tempreg";
+ else dstreg = "ret";
+
+ arg0 = get_argreg(buffer, 0, stage, dw_arg0);
+ arg1 = get_argreg(buffer, 1, stage, dw_arg1);
+ arg2 = get_argreg(buffer, 2, stage, dw_arg2);
+
+ switch (op)
+ {
+ case WINED3D_TOP_DISABLE:
+ if (!stage)
+ shader_addline(buffer, "MOV %s%s, fragment.color.primary;\n", dstreg, dstmask);
+ break;
+
+ case WINED3D_TOP_SELECT_ARG2:
+ arg1 = arg2;
+ /* FALLTHROUGH */
+ case WINED3D_TOP_SELECT_ARG1:
+ shader_addline(buffer, "MOV %s%s, %s;\n", dstreg, dstmask, arg1);
+ break;
+
+ case WINED3D_TOP_MODULATE_4X:
+ mul = 2;
+ /* FALLTHROUGH */
+ case WINED3D_TOP_MODULATE_2X:
+ mul *= 2;
+ /* FALLTHROUGH */
+ case WINED3D_TOP_MODULATE:
+ shader_addline(buffer, "MUL %s%s, %s, %s;\n", dstreg, dstmask, arg1, arg2);
+ break;
+
+ case WINED3D_TOP_ADD_SIGNED_2X:
+ mul = 2;
+ /* FALLTHROUGH */
+ case WINED3D_TOP_ADD_SIGNED:
+ shader_addline(buffer, "SUB arg2, %s, const.w;\n", arg2);
+ arg2 = "arg2";
+ /* FALLTHROUGH */
+ case WINED3D_TOP_ADD:
+ shader_addline(buffer, "ADD_SAT %s%s, %s, %s;\n", dstreg, dstmask, arg1, arg2);
+ break;
+
+ case WINED3D_TOP_SUBTRACT:
+ shader_addline(buffer, "SUB_SAT %s%s, %s, %s;\n", dstreg, dstmask, arg1, arg2);
+ break;
+
+ case WINED3D_TOP_ADD_SMOOTH:
+ shader_addline(buffer, "SUB arg1, const.x, %s;\n", arg1);
+ shader_addline(buffer, "MAD_SAT %s%s, arg1, %s, %s;\n", dstreg, dstmask, arg2, arg1);
+ break;
+
+ case WINED3D_TOP_BLEND_CURRENT_ALPHA:
+ arg0 = get_argreg(buffer, 0, stage, WINED3DTA_CURRENT);
+ shader_addline(buffer, "LRP %s%s, %s.w, %s, %s;\n", dstreg, dstmask, arg0, arg1, arg2);
+ break;
+ case WINED3D_TOP_BLEND_FACTOR_ALPHA:
+ arg0 = get_argreg(buffer, 0, stage, WINED3DTA_TFACTOR);
+ shader_addline(buffer, "LRP %s%s, %s.w, %s, %s;\n", dstreg, dstmask, arg0, arg1, arg2);
+ break;
+ case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
+ arg0 = get_argreg(buffer, 0, stage, WINED3DTA_TEXTURE);
+ shader_addline(buffer, "LRP %s%s, %s.w, %s, %s;\n", dstreg, dstmask, arg0, arg1, arg2);
+ break;
+ case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
+ arg0 = get_argreg(buffer, 0, stage, WINED3DTA_DIFFUSE);
+ shader_addline(buffer, "LRP %s%s, %s.w, %s, %s;\n", dstreg, dstmask, arg0, arg1, arg2);
+ break;
+
+ case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
+ arg0 = get_argreg(buffer, 0, stage, WINED3DTA_TEXTURE);
+ shader_addline(buffer, "SUB arg0.w, const.x, %s.w;\n", arg0);
+ shader_addline(buffer, "MAD_SAT %s%s, %s, arg0.w, %s;\n", dstreg, dstmask, arg2, arg1);
+ break;
+
+ /* D3DTOP_PREMODULATE ???? */
+
+ case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
+ shader_addline(buffer, "SUB arg0.w, const.x, %s;\n", arg1);
+ shader_addline(buffer, "MAD_SAT %s%s, arg0.w, %s, %s;\n", dstreg, dstmask, arg2, arg1);
+ break;
+ case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
+ shader_addline(buffer, "MAD_SAT %s%s, %s.w, %s, %s;\n", dstreg, dstmask, arg1, arg2, arg1);
+ break;
+ case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
+ shader_addline(buffer, "SUB arg0, const.x, %s;\n", arg1);
+ shader_addline(buffer, "MAD_SAT %s%s, arg0, %s, %s.w;\n", dstreg, dstmask, arg2, arg1);
+ break;
+ case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
+ shader_addline(buffer, "MAD_SAT %s%s, %s, %s, %s.w;\n", dstreg, dstmask, arg1, arg2, arg1);
+ break;
+
+ case WINED3D_TOP_DOTPRODUCT3:
+ mul = 4;
+ shader_addline(buffer, "SUB arg1, %s, const.w;\n", arg1);
+ shader_addline(buffer, "SUB arg2, %s, const.w;\n", arg2);
+ shader_addline(buffer, "DP3_SAT %s%s, arg1, arg2;\n", dstreg, dstmask);
+ break;
+
+ case WINED3D_TOP_MULTIPLY_ADD:
+ shader_addline(buffer, "MAD_SAT %s%s, %s, %s, %s;\n", dstreg, dstmask, arg1, arg2, arg0);
+ break;
+
+ case WINED3D_TOP_LERP:
+ /* The msdn is not quite right here */
+ shader_addline(buffer, "LRP %s%s, %s, %s, %s;\n", dstreg, dstmask, arg0, arg1, arg2);
+ break;
+
+ case WINED3D_TOP_BUMPENVMAP:
+ case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
+ /* Those are handled in the first pass of the shader(generation pass 1 and 2) already */
+ break;
+
+ default:
+ FIXME("Unhandled texture op %08x\n", op);
+ }
+
+ if (mul == 2)
+ shader_addline(buffer, "MUL_SAT %s%s, %s, const.y;\n", dstreg, dstmask, dstreg);
+ else if (mul == 4)
+ shader_addline(buffer, "MUL_SAT %s%s, %s, const.z;\n", dstreg, dstmask, dstreg);
+}
+
+static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, const struct wined3d_gl_info *gl_info)
+{
+ unsigned int stage;
+ struct wined3d_shader_buffer buffer;
+ BOOL tex_read[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE};
+ BOOL bump_used[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE};
+ BOOL luminance_used[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE};
+ UINT lowest_disabled_stage;
+ const char *textype;
+ const char *instr, *sat;
+ char colorcor_dst[8];
+ GLuint ret;
+ DWORD arg0, arg1, arg2;
+ BOOL tempreg_used = FALSE, tfactor_used = FALSE;
+ BOOL op_equal;
+ const char *final_combiner_src = "ret";
+ GLint pos;
+ BOOL custom_linear_fog = FALSE;
+
+ /* Find out which textures are read */
+ for (stage = 0; stage < MAX_TEXTURES; ++stage)
+ {
+ if (settings->op[stage].cop == WINED3D_TOP_DISABLE)
+ break;
+ arg0 = settings->op[stage].carg0 & WINED3DTA_SELECTMASK;
+ arg1 = settings->op[stage].carg1 & WINED3DTA_SELECTMASK;
+ arg2 = settings->op[stage].carg2 & WINED3DTA_SELECTMASK;
+ if(arg0 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE;
+ if(arg1 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE;
+ if(arg2 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE;
+
+ if (settings->op[stage].cop == WINED3D_TOP_BLEND_TEXTURE_ALPHA)
+ tex_read[stage] = TRUE;
+ if (settings->op[stage].cop == WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM)
+ tex_read[stage] = TRUE;
+ if (settings->op[stage].cop == WINED3D_TOP_BUMPENVMAP)
+ {
+ bump_used[stage] = TRUE;
+ tex_read[stage] = TRUE;
+ }
+ if (settings->op[stage].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE)
+ {
+ bump_used[stage] = TRUE;
+ tex_read[stage] = TRUE;
+ luminance_used[stage] = TRUE;
+ }
+ else if (settings->op[stage].cop == WINED3D_TOP_BLEND_FACTOR_ALPHA)
+ {
+ tfactor_used = TRUE;
+ }
+
+ if(arg0 == WINED3DTA_TFACTOR || arg1 == WINED3DTA_TFACTOR || arg2 == WINED3DTA_TFACTOR) {
+ tfactor_used = TRUE;
+ }
+
+ if(settings->op[stage].dst == tempreg) tempreg_used = TRUE;
+ if(arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP) {
+ tempreg_used = TRUE;
+ }
+
+ if (settings->op[stage].aop == WINED3D_TOP_DISABLE)
+ continue;
+ arg0 = settings->op[stage].aarg0 & WINED3DTA_SELECTMASK;
+ arg1 = settings->op[stage].aarg1 & WINED3DTA_SELECTMASK;
+ arg2 = settings->op[stage].aarg2 & WINED3DTA_SELECTMASK;
+ if(arg0 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE;
+ if(arg1 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE;
+ if(arg2 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE;
+
+ if(arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP) {
+ tempreg_used = TRUE;
+ }
+ if(arg0 == WINED3DTA_TFACTOR || arg1 == WINED3DTA_TFACTOR || arg2 == WINED3DTA_TFACTOR) {
+ tfactor_used = TRUE;
+ }
+ }
+ lowest_disabled_stage = stage;
+
+ /* Shader header */
+ if (!shader_buffer_init(&buffer))
+ {
+ ERR("Failed to initialize shader buffer.\n");
+ return 0;
+ }
+
+ shader_addline(&buffer, "!!ARBfp1.0\n");
+
+ switch (settings->fog)
+ {
+ case WINED3D_FFP_PS_FOG_OFF: break;
+ case WINED3D_FFP_PS_FOG_LINEAR:
+ if (gl_info->quirks & WINED3D_QUIRK_BROKEN_ARB_FOG)
+ {
+ custom_linear_fog = TRUE;
+ break;
+ }
+ shader_addline(&buffer, "OPTION ARB_fog_linear;\n");
+ break;
+
+ case WINED3D_FFP_PS_FOG_EXP: shader_addline(&buffer, "OPTION ARB_fog_exp;\n"); break;
+ case WINED3D_FFP_PS_FOG_EXP2: shader_addline(&buffer, "OPTION ARB_fog_exp2;\n"); break;
+ default: FIXME("Unexpected fog setting %d\n", settings->fog);
+ }
+
+ shader_addline(&buffer, "PARAM const = {1, 2, 4, 0.5};\n");
+ shader_addline(&buffer, "TEMP TMP;\n");
+ shader_addline(&buffer, "TEMP ret;\n");
+ if(tempreg_used || settings->sRGB_write) shader_addline(&buffer, "TEMP tempreg;\n");
+ shader_addline(&buffer, "TEMP arg0;\n");
+ shader_addline(&buffer, "TEMP arg1;\n");
+ shader_addline(&buffer, "TEMP arg2;\n");
+ for(stage = 0; stage < MAX_TEXTURES; stage++) {
+ if(!tex_read[stage]) continue;
+ shader_addline(&buffer, "TEMP tex%u;\n", stage);
+ if(!bump_used[stage]) continue;
+ shader_addline(&buffer, "PARAM bumpmat%u = program.env[%u];\n", stage, ARB_FFP_CONST_BUMPMAT(stage));
+ if(!luminance_used[stage]) continue;
+ shader_addline(&buffer, "PARAM luminance%u = program.env[%u];\n", stage, ARB_FFP_CONST_LUMINANCE(stage));
+ }
+ if(tfactor_used) {
+ shader_addline(&buffer, "PARAM tfactor = program.env[%u];\n", ARB_FFP_CONST_TFACTOR);
+ }
+ shader_addline(&buffer, "PARAM specular_enable = program.env[%u];\n", ARB_FFP_CONST_SPECULAR_ENABLE);
+
+ if(settings->sRGB_write) {
+ shader_addline(&buffer, "PARAM srgb_consts1 = {%f, %f, %f, %f};\n",
+ srgb_mul_low, srgb_cmp, srgb_pow, srgb_mul_high);
+ shader_addline(&buffer, "PARAM srgb_consts2 = {%f, %f, %f, %f};\n",
+ srgb_sub_high, 0.0, 0.0, 0.0);
+ }
+
+ if (lowest_disabled_stage < 7 && settings->emul_clipplanes)
+ shader_addline(&buffer, "KIL fragment.texcoord[7];\n");
+
+ /* Generate texture sampling instructions) */
+ for (stage = 0; stage < MAX_TEXTURES && settings->op[stage].cop != WINED3D_TOP_DISABLE; ++stage)
+ {
+ if (!tex_read[stage])
+ continue;
+
+ switch(settings->op[stage].tex_type) {
+ case tex_1d: textype = "1D"; break;
+ case tex_2d: textype = "2D"; break;
+ case tex_3d: textype = "3D"; break;
+ case tex_cube: textype = "CUBE"; break;
+ case tex_rect: textype = "RECT"; break;
+ default: textype = "unexpected_textype"; break;
+ }
+
+ if (settings->op[stage].cop == WINED3D_TOP_BUMPENVMAP
+ || settings->op[stage].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE)
+ sat = "";
+ else
+ sat = "_SAT";
+
+ if(settings->op[stage].projected == proj_none) {
+ instr = "TEX";
+ } else if(settings->op[stage].projected == proj_count4 ||
+ settings->op[stage].projected == proj_count3) {
+ instr = "TXP";
+ } else {
+ FIXME("Unexpected projection mode %d\n", settings->op[stage].projected);
+ instr = "TXP";
+ }
+
+ if (stage > 0
+ && (settings->op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP
+ || settings->op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE))
+ {
+ shader_addline(&buffer, "SWZ arg1, bumpmat%u, x, z, 0, 0;\n", stage - 1);
+ shader_addline(&buffer, "DP3 ret.x, arg1, tex%u;\n", stage - 1);
+ shader_addline(&buffer, "SWZ arg1, bumpmat%u, y, w, 0, 0;\n", stage - 1);
+ shader_addline(&buffer, "DP3 ret.y, arg1, tex%u;\n", stage - 1);
+
+ /* with projective textures, texbem only divides the static texture coord, not the displacement,
+ * so multiply the displacement with the dividing parameter before passing it to TXP
+ */
+ if (settings->op[stage].projected != proj_none) {
+ if(settings->op[stage].projected == proj_count4) {
+ shader_addline(&buffer, "MOV ret.w, fragment.texcoord[%u].w;\n", stage);
+ shader_addline(&buffer, "MUL ret.xyz, ret, fragment.texcoord[%u].w, fragment.texcoord[%u];\n", stage, stage);
+ } else {
+ shader_addline(&buffer, "MOV ret.w, fragment.texcoord[%u].z;\n", stage);
+ shader_addline(&buffer, "MAD ret.xyz, ret, fragment.texcoord[%u].z, fragment.texcoord[%u];\n", stage, stage);
+ }
+ } else {
+ shader_addline(&buffer, "ADD ret, ret, fragment.texcoord[%u];\n", stage);
+ }
+
+ shader_addline(&buffer, "%s%s tex%u, ret, texture[%u], %s;\n",
+ instr, sat, stage, stage, textype);
+ if (settings->op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE)
+ {
+ shader_addline(&buffer, "MAD_SAT ret.x, tex%u.z, luminance%u.x, luminance%u.y;\n",
+ stage - 1, stage - 1, stage - 1);
+ shader_addline(&buffer, "MUL tex%u, tex%u, ret.x;\n", stage, stage);
+ }
+ } else if(settings->op[stage].projected == proj_count3) {
+ shader_addline(&buffer, "MOV ret, fragment.texcoord[%u];\n", stage);
+ shader_addline(&buffer, "MOV ret.w, ret.z;\n");
+ shader_addline(&buffer, "%s%s tex%u, ret, texture[%u], %s;\n",
+ instr, sat, stage, stage, textype);
+ } else {
+ shader_addline(&buffer, "%s%s tex%u, fragment.texcoord[%u], texture[%u], %s;\n",
+ instr, sat, stage, stage, stage, textype);
+ }
+
+ sprintf(colorcor_dst, "tex%u", stage);
+ gen_color_correction(&buffer, colorcor_dst, WINED3DSP_WRITEMASK_ALL, "const.x", "const.y",
+ settings->op[stage].color_fixup);
+ }
+
+ /* Generate the main shader */
+ for (stage = 0; stage < MAX_TEXTURES; ++stage)
+ {
+ if (settings->op[stage].cop == WINED3D_TOP_DISABLE)
+ {
+ if (!stage)
+ final_combiner_src = "fragment.color.primary";
+ break;
+ }
+
+ if (settings->op[stage].cop == WINED3D_TOP_SELECT_ARG1
+ && settings->op[stage].aop == WINED3D_TOP_SELECT_ARG1)
+ op_equal = settings->op[stage].carg1 == settings->op[stage].aarg1;
+ else if (settings->op[stage].cop == WINED3D_TOP_SELECT_ARG1
+ && settings->op[stage].aop == WINED3D_TOP_SELECT_ARG2)
+ op_equal = settings->op[stage].carg1 == settings->op[stage].aarg2;
+ else if (settings->op[stage].cop == WINED3D_TOP_SELECT_ARG2
+ && settings->op[stage].aop == WINED3D_TOP_SELECT_ARG1)
+ op_equal = settings->op[stage].carg2 == settings->op[stage].aarg1;
+ else if (settings->op[stage].cop == WINED3D_TOP_SELECT_ARG2
+ && settings->op[stage].aop == WINED3D_TOP_SELECT_ARG2)
+ op_equal = settings->op[stage].carg2 == settings->op[stage].aarg2;
+ else
+ op_equal = settings->op[stage].aop == settings->op[stage].cop
+ && settings->op[stage].carg0 == settings->op[stage].aarg0
+ && settings->op[stage].carg1 == settings->op[stage].aarg1
+ && settings->op[stage].carg2 == settings->op[stage].aarg2;
+
+ if (settings->op[stage].aop == WINED3D_TOP_DISABLE)
+ {
+ gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].dst,
+ settings->op[stage].cop, settings->op[stage].carg0,
+ settings->op[stage].carg1, settings->op[stage].carg2);
+ if (!stage)
+ shader_addline(&buffer, "MOV ret.w, fragment.color.primary.w;\n");
+ }
+ else if (op_equal)
+ {
+ gen_ffp_instr(&buffer, stage, TRUE, TRUE, settings->op[stage].dst,
+ settings->op[stage].cop, settings->op[stage].carg0,
+ settings->op[stage].carg1, settings->op[stage].carg2);
+ } else {
+ gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].dst,
+ settings->op[stage].cop, settings->op[stage].carg0,
+ settings->op[stage].carg1, settings->op[stage].carg2);
+ gen_ffp_instr(&buffer, stage, FALSE, TRUE, settings->op[stage].dst,
+ settings->op[stage].aop, settings->op[stage].aarg0,
+ settings->op[stage].aarg1, settings->op[stage].aarg2);
+ }
+ }
+
+ if (settings->sRGB_write || custom_linear_fog)
+ {
+ shader_addline(&buffer, "MAD ret, fragment.color.secondary, specular_enable, %s;\n", final_combiner_src);
+ if (settings->sRGB_write)
+ arbfp_add_sRGB_correction(&buffer, "ret", "arg0", "arg1", "arg2", "tempreg", FALSE);
+ if (custom_linear_fog)
+ arbfp_add_linear_fog(&buffer, "ret", "arg0");
+ shader_addline(&buffer, "MOV result.color, ret;\n");
+ }
+ else
+ {
+ shader_addline(&buffer, "MAD result.color, fragment.color.secondary, specular_enable, %s;\n",
+ final_combiner_src);
+ }
+
+ /* Footer */
+ shader_addline(&buffer, "END\n");
+
+ /* Generate the shader */
+ GL_EXTCALL(glGenProgramsARB(1, &ret));
+ GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, ret));
+ GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+ strlen(buffer.buffer), buffer.buffer));
+ checkGLcall("glProgramStringARB()");
+
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
+ if (pos != -1)
+ {
+ FIXME("Fragment program error at position %d: %s\n\n", pos,
+ debugstr_a((const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
+ shader_arb_dump_program_source(buffer.buffer);
+ }
+ else
+ {
+ GLint native;
+
+ GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, &native));
+ checkGLcall("glGetProgramivARB()");
+ if (!native) WARN("Program exceeds native resource limits.\n");
+ }
+
+ shader_buffer_free(&buffer);
+ return ret;
+}
+
+static void fragment_prog_arbfp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_device *device = context->swapchain->device;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct shader_arb_priv *priv = device->fragment_priv;
+ BOOL use_pshader = use_ps(state);
+ struct ffp_frag_settings settings;
+ const struct arbfp_ffp_desc *desc;
+ unsigned int i;
+
+ TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
+
+ if (isStateDirty(context, STATE_RENDER(WINED3D_RS_FOGENABLE)))
+ {
+ if (!use_pshader && device->shader_backend == &arb_program_shader_backend && context->last_was_pshader)
+ {
+ /* Reload fixed function constants since they collide with the
+ * pixel shader constants. */
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ set_bumpmat_arbfp(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_BUMPENV_MAT00));
+ }
+ state_texfactor_arbfp(context, state, STATE_RENDER(WINED3D_RS_TEXTUREFACTOR));
+ state_arb_specularenable(context, state, STATE_RENDER(WINED3D_RS_SPECULARENABLE));
+ }
+ else if (use_pshader)
+ {
+ context->select_shader = 1;
+ }
+ return;
+ }
+
+ if (!use_pshader)
+ {
+ /* Find or create a shader implementing the fixed function pipeline
+ * settings, then activate it. */
+ gen_ffp_frag_op(context, state, &settings, FALSE);
+ desc = (const struct arbfp_ffp_desc *)find_ffp_frag_shader(&priv->fragment_shaders, &settings);
+ if(!desc) {
+ struct arbfp_ffp_desc *new_desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_desc));
+ if (!new_desc)
+ {
+ ERR("Out of memory\n");
+ return;
+ }
+
+ new_desc->parent.settings = settings;
+ new_desc->shader = gen_arbfp_ffp_shader(&settings, gl_info);
+ add_ffp_frag_shader(&priv->fragment_shaders, &new_desc->parent);
+ TRACE("Allocated fixed function replacement shader descriptor %p\n", new_desc);
+ desc = new_desc;
+ }
+
+ /* Now activate the replacement program. GL_FRAGMENT_PROGRAM_ARB is already active (however, note the
+ * comment above the shader_select call below). If e.g. GLSL is active, the shader_select call will
+ * deactivate it.
+ */
+ GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, desc->shader));
+ checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, desc->shader)");
+ priv->current_fprogram_id = desc->shader;
+
+ if (device->shader_backend == &arb_program_shader_backend && context->last_was_pshader)
+ {
+ /* Reload fixed function constants since they collide with the
+ * pixel shader constants. */
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ set_bumpmat_arbfp(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_BUMPENV_MAT00));
+ }
+ state_texfactor_arbfp(context, state, STATE_RENDER(WINED3D_RS_TEXTUREFACTOR));
+ state_arb_specularenable(context, state, STATE_RENDER(WINED3D_RS_SPECULARENABLE));
+ }
+ context->last_was_pshader = FALSE;
+ } else {
+ context->last_was_pshader = TRUE;
+ }
+
+ context->select_shader = 1;
+ context->load_constants = 1;
+}
+
+/* We can't link the fog states to the fragment state directly since the
+ * vertex pipeline links them to FOGENABLE. A different linking in different
+ * pipeline parts can't be expressed in the combined state table, so we need
+ * to handle that with a forwarding function. The other invisible side effect
+ * is that changing the fog start and fog end (which links to FOGENABLE in
+ * vertex) results in the fragment_prog_arbfp function being called because
+ * FOGENABLE is dirty, which calls this function here. */
+static void state_arbfp_fog(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ enum fogsource new_source;
+ DWORD fogstart = state->render_states[WINED3D_RS_FOGSTART];
+ DWORD fogend = state->render_states[WINED3D_RS_FOGEND];
+
+ TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
+
+ if (!isStateDirty(context, STATE_PIXELSHADER))
+ fragment_prog_arbfp(context, state, state_id);
+
+ if (!state->render_states[WINED3D_RS_FOGENABLE])
+ return;
+
+ if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
+ {
+ if (use_vs(state))
+ {
+ new_source = FOGSOURCE_VS;
+ }
+ else
+ {
+ if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE || context->last_was_rhw)
+ new_source = FOGSOURCE_COORD;
+ else
+ new_source = FOGSOURCE_FFP;
+ }
+ }
+ else
+ {
+ new_source = FOGSOURCE_FFP;
+ }
+
+ if (new_source != context->fog_source || fogstart == fogend)
+ {
+ context->fog_source = new_source;
+ state_fogstartend(context, state, STATE_RENDER(WINED3D_RS_FOGSTART));
+ }
+}
+
+static void textransform(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (!isStateDirty(context, STATE_PIXELSHADER))
+ fragment_prog_arbfp(context, state, state_id);
+}
+
+static const struct StateEntryTemplate arbfp_fragmentstate_template[] =
+{
+ {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), state_texfactor_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlum_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_PIXELSHADER, { STATE_PIXELSHADER, fragment_prog_arbfp }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_arbfp_fog }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGSTART), { STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGEND), { STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), state_srgbwrite }, ARB_FRAMEBUFFER_SRGB },
+ {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGCOLOR), { STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGDENSITY), { STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_SPECULARENABLE), { STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_arb_specularenable}, WINED3D_GL_EXT_NONE },
+ {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
+};
+
+const struct fragment_pipeline arbfp_fragment_pipeline = {
+ arbfp_enable,
+ arbfp_get_caps,
+ arbfp_alloc,
+ arbfp_free,
+ shader_arb_color_fixup_supported,
+ arbfp_fragmentstate_template,
+};
+
+struct arbfp_blit_priv {
+ GLenum yuy2_rect_shader, yuy2_2d_shader;
+ GLenum uyvy_rect_shader, uyvy_2d_shader;
+ GLenum yv12_rect_shader, yv12_2d_shader;
+ GLenum p8_rect_shader, p8_2d_shader;
+ GLuint palette_texture;
+};
+
+static HRESULT arbfp_blit_alloc(struct wined3d_device *device)
+{
+ device->blit_priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct arbfp_blit_priv));
+ if(!device->blit_priv) {
+ ERR("Out of memory\n");
+ return E_OUTOFMEMORY;
+ }
+ return WINED3D_OK;
+}
+
+/* Context activation is done by the caller. */
+static void arbfp_blit_free(struct wined3d_device *device)
+{
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ struct arbfp_blit_priv *priv = device->blit_priv;
+
+ GL_EXTCALL(glDeleteProgramsARB(1, &priv->yuy2_rect_shader));
+ GL_EXTCALL(glDeleteProgramsARB(1, &priv->yuy2_2d_shader));
+ GL_EXTCALL(glDeleteProgramsARB(1, &priv->uyvy_rect_shader));
+ GL_EXTCALL(glDeleteProgramsARB(1, &priv->uyvy_2d_shader));
+ GL_EXTCALL(glDeleteProgramsARB(1, &priv->yv12_rect_shader));
+ GL_EXTCALL(glDeleteProgramsARB(1, &priv->yv12_2d_shader));
+ GL_EXTCALL(glDeleteProgramsARB(1, &priv->p8_rect_shader));
+ GL_EXTCALL(glDeleteProgramsARB(1, &priv->p8_2d_shader));
+ checkGLcall("Delete yuv and p8 programs");
+
+ if (priv->palette_texture)
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &priv->palette_texture);
+
+ HeapFree(GetProcessHeap(), 0, device->blit_priv);
+ device->blit_priv = NULL;
+}
+
+static BOOL gen_planar_yuv_read(struct wined3d_shader_buffer *buffer, enum complex_fixup fixup,
+ GLenum textype, char *luminance)
+{
+ char chroma;
+ const char *tex, *texinstr;
+
+ if (fixup == COMPLEX_FIXUP_UYVY) {
+ chroma = 'x';
+ *luminance = 'w';
+ } else {
+ chroma = 'w';
+ *luminance = 'x';
+ }
+ switch(textype) {
+ case GL_TEXTURE_2D: tex = "2D"; texinstr = "TXP"; break;
+ case GL_TEXTURE_RECTANGLE_ARB: tex = "RECT"; texinstr = "TEX"; break;
+ default:
+ /* This is more tricky than just replacing the texture type - we have to navigate
+ * properly in the texture to find the correct chroma values
+ */
+ FIXME("Implement yuv correction for non-2d, non-rect textures\n");
+ return FALSE;
+ }
+
+ /* First we have to read the chroma values. This means we need at least two pixels(no filtering),
+ * or 4 pixels(with filtering). To get the unmodified chromas, we have to rid ourselves of the
+ * filtering when we sample the texture.
+ *
+ * These are the rules for reading the chroma:
+ *
+ * Even pixel: Cr
+ * Even pixel: U
+ * Odd pixel: V
+ *
+ * So we have to get the sampling x position in non-normalized coordinates in integers
+ */
+ if(textype != GL_TEXTURE_RECTANGLE_ARB) {
+ shader_addline(buffer, "MUL texcrd.xy, fragment.texcoord[0], size.x;\n");
+ shader_addline(buffer, "MOV texcrd.w, size.x;\n");
+ } else {
+ shader_addline(buffer, "MOV texcrd, fragment.texcoord[0];\n");
+ }
+ /* We must not allow filtering between pixel x and x+1, this would mix U and V
+ * Vertical filtering is ok. However, bear in mind that the pixel center is at
+ * 0.5, so add 0.5.
+ */
+ shader_addline(buffer, "FLR texcrd.x, texcrd.x;\n");
+ shader_addline(buffer, "ADD texcrd.x, texcrd.x, coef.y;\n");
+
+ /* Divide the x coordinate by 0.5 and get the fraction. This gives 0.25 and 0.75 for the
+ * even and odd pixels respectively
+ */
+ shader_addline(buffer, "MUL texcrd2, texcrd, coef.y;\n");
+ shader_addline(buffer, "FRC texcrd2, texcrd2;\n");
+
+ /* Sample Pixel 1 */
+ shader_addline(buffer, "%s luminance, texcrd, texture[0], %s;\n", texinstr, tex);
+
+ /* Put the value into either of the chroma values */
+ shader_addline(buffer, "SGE temp.x, texcrd2.x, coef.y;\n");
+ shader_addline(buffer, "MUL chroma.x, luminance.%c, temp.x;\n", chroma);
+ shader_addline(buffer, "SLT temp.x, texcrd2.x, coef.y;\n");
+ shader_addline(buffer, "MUL chroma.y, luminance.%c, temp.x;\n", chroma);
+
+ /* Sample pixel 2. If we read an even pixel(SLT above returned 1), sample
+ * the pixel right to the current one. Otherwise, sample the left pixel.
+ * Bias and scale the SLT result to -1;1 and add it to the texcrd.x.
+ */
+ shader_addline(buffer, "MAD temp.x, temp.x, coef.z, -coef.x;\n");
+ shader_addline(buffer, "ADD texcrd.x, texcrd, temp.x;\n");
+ shader_addline(buffer, "%s luminance, texcrd, texture[0], %s;\n", texinstr, tex);
+
+ /* Put the value into the other chroma */
+ shader_addline(buffer, "SGE temp.x, texcrd2.x, coef.y;\n");
+ shader_addline(buffer, "MAD chroma.y, luminance.%c, temp.x, chroma.y;\n", chroma);
+ shader_addline(buffer, "SLT temp.x, texcrd2.x, coef.y;\n");
+ shader_addline(buffer, "MAD chroma.x, luminance.%c, temp.x, chroma.x;\n", chroma);
+
+ /* TODO: If filtering is enabled, sample a 2nd pair of pixels left or right of
+ * the current one and lerp the two U and V values
+ */
+
+ /* This gives the correctly filtered luminance value */
+ shader_addline(buffer, "TEX luminance, fragment.texcoord[0], texture[0], %s;\n", tex);
+
+ return TRUE;
+}
+
+static BOOL gen_yv12_read(struct wined3d_shader_buffer *buffer, GLenum textype, char *luminance)
+{
+ const char *tex;
+
+ switch(textype) {
+ case GL_TEXTURE_2D: tex = "2D"; break;
+ case GL_TEXTURE_RECTANGLE_ARB: tex = "RECT"; break;
+ default:
+ FIXME("Implement yv12 correction for non-2d, non-rect textures\n");
+ return FALSE;
+ }
+
+ /* YV12 surfaces contain a WxH sized luminance plane, followed by a (W/2)x(H/2)
+ * V and a (W/2)x(H/2) U plane, each with 8 bit per pixel. So the effective
+ * bitdepth is 12 bits per pixel. Since the U and V planes have only half the
+ * pitch of the luminance plane, the packing into the gl texture is a bit
+ * unfortunate. If the whole texture is interpreted as luminance data it looks
+ * approximately like this:
+ *
+ * +----------------------------------+----
+ * | |
+ * | |
+ * | |
+ * | |
+ * | | 2
+ * | LUMINANCE | -
+ * | | 3
+ * | |
+ * | |
+ * | |
+ * | |
+ * +----------------+-----------------+----
+ * | | |
+ * | U even rows | U odd rows |
+ * | | | 1
+ * +----------------+------------------ -
+ * | | | 3
+ * | V even rows | V odd rows |
+ * | | |
+ * +----------------+-----------------+----
+ * | | |
+ * | 0.5 | 0.5 |
+ *
+ * So it appears as if there are 4 chroma images, but in fact the odd rows
+ * in the chroma images are in the same row as the even ones. So its is
+ * kinda tricky to read
+ *
+ * When reading from rectangle textures, keep in mind that the input y coordinates
+ * go from 0 to d3d_height, whereas the opengl texture height is 1.5 * d3d_height
+ */
+ shader_addline(buffer, "PARAM yv12_coef = {%f, %f, %f, %f};\n",
+ 2.0f / 3.0f, 1.0f / 6.0f, (2.0f / 3.0f) + (1.0f / 6.0f), 1.0f / 3.0f);
+
+ shader_addline(buffer, "MOV texcrd, fragment.texcoord[0];\n");
+ /* the chroma planes have only half the width */
+ shader_addline(buffer, "MUL texcrd.x, texcrd.x, coef.y;\n");
+
+ /* The first value is between 2/3 and 5/6th of the texture's height, so scale+bias
+ * the coordinate. Also read the right side of the image when reading odd lines
+ *
+ * Don't forget to clamp the y values in into the range, otherwise we'll get filtering
+ * bleeding
+ */
+ if(textype == GL_TEXTURE_2D) {
+
+ shader_addline(buffer, "RCP chroma.w, size.y;\n");
+
+ shader_addline(buffer, "MUL texcrd2.y, texcrd.y, size.y;\n");
+
+ shader_addline(buffer, "FLR texcrd2.y, texcrd2.y;\n");
+ shader_addline(buffer, "MAD texcrd.y, texcrd.y, yv12_coef.y, yv12_coef.x;\n");
+
+ /* Read odd lines from the right side(add size * 0.5 to the x coordinate */
+ shader_addline(buffer, "ADD texcrd2.x, texcrd2.y, yv12_coef.y;\n"); /* To avoid 0.5 == 0.5 comparisons */
+ shader_addline(buffer, "FRC texcrd2.x, texcrd2.x;\n");
+ shader_addline(buffer, "SGE texcrd2.x, texcrd2.x, coef.y;\n");
+ shader_addline(buffer, "MAD texcrd.x, texcrd2.x, coef.y, texcrd.x;\n");
+
+ /* clamp, keep the half pixel origin in mind */
+ shader_addline(buffer, "MAD temp.y, coef.y, chroma.w, yv12_coef.x;\n");
+ shader_addline(buffer, "MAX texcrd.y, temp.y, texcrd.y;\n");
+ shader_addline(buffer, "MAD temp.y, -coef.y, chroma.w, yv12_coef.z;\n");
+ shader_addline(buffer, "MIN texcrd.y, temp.y, texcrd.y;\n");
+ } else {
+ /* Read from [size - size+size/4] */
+ shader_addline(buffer, "FLR texcrd.y, texcrd.y;\n");
+ shader_addline(buffer, "MAD texcrd.y, texcrd.y, coef.w, size.y;\n");
+
+ /* Read odd lines from the right side(add size * 0.5 to the x coordinate */
+ shader_addline(buffer, "ADD texcrd2.x, texcrd.y, yv12_coef.y;\n"); /* To avoid 0.5 == 0.5 comparisons */
+ shader_addline(buffer, "FRC texcrd2.x, texcrd2.x;\n");
+ shader_addline(buffer, "SGE texcrd2.x, texcrd2.x, coef.y;\n");
+ shader_addline(buffer, "MUL texcrd2.x, texcrd2.x, size.x;\n");
+ shader_addline(buffer, "MAD texcrd.x, texcrd2.x, coef.y, texcrd.x;\n");
+
+ /* Make sure to read exactly from the pixel center */
+ shader_addline(buffer, "FLR texcrd.y, texcrd.y;\n");
+ shader_addline(buffer, "ADD texcrd.y, texcrd.y, coef.y;\n");
+
+ /* Clamp */
+ shader_addline(buffer, "MAD temp.y, size.y, coef.w, size.y;\n");
+ shader_addline(buffer, "ADD temp.y, temp.y, -coef.y;\n");
+ shader_addline(buffer, "MIN texcrd.y, temp.y, texcrd.y;\n");
+ shader_addline(buffer, "ADD temp.y, size.y, -coef.y;\n");
+ shader_addline(buffer, "MAX texcrd.y, temp.y, texcrd.y;\n");
+ }
+ /* Read the texture, put the result into the output register */
+ shader_addline(buffer, "TEX temp, texcrd, texture[0], %s;\n", tex);
+ shader_addline(buffer, "MOV chroma.x, temp.w;\n");
+
+ /* The other chroma value is 1/6th of the texture lower, from 5/6th to 6/6th
+ * No need to clamp because we're just reusing the already clamped value from above
+ */
+ if(textype == GL_TEXTURE_2D) {
+ shader_addline(buffer, "ADD texcrd.y, texcrd.y, yv12_coef.y;\n");
+ } else {
+ shader_addline(buffer, "MAD texcrd.y, size.y, coef.w, texcrd.y;\n");
+ }
+ shader_addline(buffer, "TEX temp, texcrd, texture[0], %s;\n", tex);
+ shader_addline(buffer, "MOV chroma.y, temp.w;\n");
+
+ /* Sample the luminance value. It is in the top 2/3rd of the texture, so scale the y coordinate.
+ * Clamp the y coordinate to prevent the chroma values from bleeding into the sampled luminance
+ * values due to filtering
+ */
+ shader_addline(buffer, "MOV texcrd, fragment.texcoord[0];\n");
+ if(textype == GL_TEXTURE_2D) {
+ /* Multiply the y coordinate by 2/3 and clamp it */
+ shader_addline(buffer, "MUL texcrd.y, texcrd.y, yv12_coef.x;\n");
+ shader_addline(buffer, "MAD temp.y, -coef.y, chroma.w, yv12_coef.x;\n");
+ shader_addline(buffer, "MIN texcrd.y, temp.y, texcrd.y;\n");
+ shader_addline(buffer, "TEX luminance, texcrd, texture[0], %s;\n", tex);
+ } else {
+ /* Reading from texture_rectangles is pretty straightforward, just use the unmodified
+ * texture coordinate. It is still a good idea to clamp it though, since the opengl texture
+ * is bigger
+ */
+ shader_addline(buffer, "ADD temp.x, size.y, -coef.y;\n");
+ shader_addline(buffer, "MIN texcrd.y, texcrd.y, size.x;\n");
+ shader_addline(buffer, "TEX luminance, texcrd, texture[0], %s;\n", tex);
+ }
+ *luminance = 'a';
+
+ return TRUE;
+}
+
+static GLuint gen_p8_shader(struct arbfp_blit_priv *priv,
+ const struct wined3d_gl_info *gl_info, GLenum textype)
+{
+ GLenum shader;
+ struct wined3d_shader_buffer buffer;
+ GLint pos;
+
+ /* Shader header */
+ if (!shader_buffer_init(&buffer))
+ {
+ ERR("Failed to initialize shader buffer.\n");
+ return 0;
+ }
+
+ GL_EXTCALL(glGenProgramsARB(1, &shader));
+ GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, shader));
+ if (!shader)
+ {
+ shader_buffer_free(&buffer);
+ return 0;
+ }
+
+ shader_addline(&buffer, "!!ARBfp1.0\n");
+ shader_addline(&buffer, "TEMP index;\n");
+
+ /* { 255/256, 0.5/255*255/256, 0, 0 } */
+ shader_addline(&buffer, "PARAM constants = { 0.996, 0.00195, 0, 0 };\n");
+
+ /* The alpha-component contains the palette index */
+ if(textype == GL_TEXTURE_RECTANGLE_ARB)
+ shader_addline(&buffer, "TXP index, fragment.texcoord[0], texture[0], RECT;\n");
+ else
+ shader_addline(&buffer, "TEX index, fragment.texcoord[0], texture[0], 2D;\n");
+
+ /* Scale the index by 255/256 and add a bias of '0.5' in order to sample in the middle */
+ shader_addline(&buffer, "MAD index.a, index.a, constants.x, constants.y;\n");
+
+ /* Use the alpha-component as an index in the palette to get the final color */
+ shader_addline(&buffer, "TEX result.color, index.a, texture[1], 1D;\n");
+ shader_addline(&buffer, "END\n");
+
+ GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+ strlen(buffer.buffer), buffer.buffer));
+ checkGLcall("glProgramStringARB()");
+
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
+ if (pos != -1)
+ {
+ FIXME("Fragment program error at position %d: %s\n\n", pos,
+ debugstr_a((const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
+ shader_arb_dump_program_source(buffer.buffer);
+ }
+
+ if (textype == GL_TEXTURE_RECTANGLE_ARB)
+ priv->p8_rect_shader = shader;
+ else
+ priv->p8_2d_shader = shader;
+
+ shader_buffer_free(&buffer);
+
+ return shader;
+}
+
+/* Context activation is done by the caller. */
+static void upload_palette(const struct wined3d_surface *surface, struct wined3d_context *context)
+{
+ BYTE table[256][4];
+ struct wined3d_device *device = surface->resource.device;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct arbfp_blit_priv *priv = device->blit_priv;
+ BOOL colorkey = (surface->CKeyFlags & WINEDDSD_CKSRCBLT) != 0;
+
+ d3dfmt_p8_init_palette(surface, table, colorkey);
+
+ if (gl_info->supported[APPLE_CLIENT_STORAGE])
+ {
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
+ checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)");
+ }
+
+ if (!priv->palette_texture)
+ gl_info->gl_ops.gl.p_glGenTextures(1, &priv->palette_texture);
+
+ GL_EXTCALL(glActiveTextureARB(GL_TEXTURE1));
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_1D, priv->palette_texture);
+
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ /* Make sure we have discrete color levels. */
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ /* Upload the palette */
+ /* TODO: avoid unneeded uploads in the future by adding some SFLAG_PALETTE_DIRTY mechanism */
+ gl_info->gl_ops.gl.p_glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, table);
+
+ if (gl_info->supported[APPLE_CLIENT_STORAGE])
+ {
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
+ checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
+ }
+
+ /* Switch back to unit 0 in which the 2D texture will be stored. */
+ context_active_texture(context, gl_info, 0);
+}
+
+/* Context activation is done by the caller. */
+static GLuint gen_yuv_shader(struct arbfp_blit_priv *priv, const struct wined3d_gl_info *gl_info,
+ enum complex_fixup yuv_fixup, GLenum textype)
+{
+ GLenum shader;
+ struct wined3d_shader_buffer buffer;
+ char luminance_component;
+ GLint pos;
+
+ /* Shader header */
+ if (!shader_buffer_init(&buffer))
+ {
+ ERR("Failed to initialize shader buffer.\n");
+ return 0;
+ }
+
+ GL_EXTCALL(glGenProgramsARB(1, &shader));
+ checkGLcall("GL_EXTCALL(glGenProgramsARB(1, &shader))");
+ GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, shader));
+ checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, shader)");
+ if (!shader)
+ {
+ shader_buffer_free(&buffer);
+ return 0;
+ }
+
+ /* The YUY2 and UYVY formats contain two pixels packed into a 32 bit macropixel,
+ * giving effectively 16 bit per pixel. The color consists of a luminance(Y) and
+ * two chroma(U and V) values. Each macropixel has two luminance values, one for
+ * each single pixel it contains, and one U and one V value shared between both
+ * pixels.
+ *
+ * The data is loaded into an A8L8 texture. With YUY2, the luminance component
+ * contains the luminance and alpha the chroma. With UYVY it is vice versa. Thus
+ * take the format into account when generating the read swizzles
+ *
+ * Reading the Y value is straightforward - just sample the texture. The hardware
+ * takes care of filtering in the horizontal and vertical direction.
+ *
+ * Reading the U and V values is harder. We have to avoid filtering horizontally,
+ * because that would mix the U and V values of one pixel or two adjacent pixels.
+ * Thus floor the texture coordinate and add 0.5 to get an unfiltered read,
+ * regardless of the filtering setting. Vertical filtering works automatically
+ * though - the U and V values of two rows are mixed nicely.
+ *
+ * Apart of avoiding filtering issues, the code has to know which value it just
+ * read, and where it can find the other one. To determine this, it checks if
+ * it sampled an even or odd pixel, and shifts the 2nd read accordingly.
+ *
+ * Handling horizontal filtering of U and V values requires reading a 2nd pair
+ * of pixels, extracting U and V and mixing them. This is not implemented yet.
+ *
+ * An alternative implementation idea is to load the texture as A8R8G8B8 texture,
+ * with width / 2. This way one read gives all 3 values, finding U and V is easy
+ * in an unfiltered situation. Finding the luminance on the other hand requires
+ * finding out if it is an odd or even pixel. The real drawback of this approach
+ * is filtering. This would have to be emulated completely in the shader, reading
+ * up two 2 packed pixels in up to 2 rows and interpolating both horizontally and
+ * vertically. Beyond that it would require adjustments to the texture handling
+ * code to deal with the width scaling
+ */
+ shader_addline(&buffer, "!!ARBfp1.0\n");
+ shader_addline(&buffer, "TEMP luminance;\n");
+ shader_addline(&buffer, "TEMP temp;\n");
+ shader_addline(&buffer, "TEMP chroma;\n");
+ shader_addline(&buffer, "TEMP texcrd;\n");
+ shader_addline(&buffer, "TEMP texcrd2;\n");
+ shader_addline(&buffer, "PARAM coef = {1.0, 0.5, 2.0, 0.25};\n");
+ shader_addline(&buffer, "PARAM yuv_coef = {1.403, 0.344, 0.714, 1.770};\n");
+ shader_addline(&buffer, "PARAM size = program.local[0];\n");
+
+ switch (yuv_fixup)
+ {
+ case COMPLEX_FIXUP_UYVY:
+ case COMPLEX_FIXUP_YUY2:
+ if (!gen_planar_yuv_read(&buffer, yuv_fixup, textype, &luminance_component))
+ {
+ shader_buffer_free(&buffer);
+ return 0;
+ }
+ break;
+
+ case COMPLEX_FIXUP_YV12:
+ if (!gen_yv12_read(&buffer, textype, &luminance_component))
+ {
+ shader_buffer_free(&buffer);
+ return 0;
+ }
+ break;
+
+ default:
+ FIXME("Unsupported YUV fixup %#x\n", yuv_fixup);
+ shader_buffer_free(&buffer);
+ return 0;
+ }
+
+ /* Calculate the final result. Formula is taken from
+ * http://www.fourcc.org/fccyvrgb.php. Note that the chroma
+ * ranges from -0.5 to 0.5
+ */
+ shader_addline(&buffer, "SUB chroma.xy, chroma, coef.y;\n");
+
+ shader_addline(&buffer, "MAD result.color.x, chroma.x, yuv_coef.x, luminance.%c;\n", luminance_component);
+ shader_addline(&buffer, "MAD temp.x, -chroma.y, yuv_coef.y, luminance.%c;\n", luminance_component);
+ shader_addline(&buffer, "MAD result.color.y, -chroma.x, yuv_coef.z, temp.x;\n");
+ shader_addline(&buffer, "MAD result.color.z, chroma.y, yuv_coef.w, luminance.%c;\n", luminance_component);
+ shader_addline(&buffer, "END\n");
+
+ GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+ strlen(buffer.buffer), buffer.buffer));
+ checkGLcall("glProgramStringARB()");
+
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
+ if (pos != -1)
+ {
+ FIXME("Fragment program error at position %d: %s\n\n", pos,
+ debugstr_a((const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
+ shader_arb_dump_program_source(buffer.buffer);
+ }
+ else
+ {
+ GLint native;
+
+ GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, &native));
+ checkGLcall("glGetProgramivARB()");
+ if (!native) WARN("Program exceeds native resource limits.\n");
+ }
+
+ shader_buffer_free(&buffer);
+
+ switch (yuv_fixup)
+ {
+ case COMPLEX_FIXUP_YUY2:
+ if (textype == GL_TEXTURE_RECTANGLE_ARB) priv->yuy2_rect_shader = shader;
+ else priv->yuy2_2d_shader = shader;
+ break;
+
+ case COMPLEX_FIXUP_UYVY:
+ if (textype == GL_TEXTURE_RECTANGLE_ARB) priv->uyvy_rect_shader = shader;
+ else priv->uyvy_2d_shader = shader;
+ break;
+
+ case COMPLEX_FIXUP_YV12:
+ if (textype == GL_TEXTURE_RECTANGLE_ARB) priv->yv12_rect_shader = shader;
+ else priv->yv12_2d_shader = shader;
+ break;
+ default:
+ ERR("Unsupported complex fixup: %d\n", yuv_fixup);
+ }
+
+ return shader;
+}
+
+/* Context activation is done by the caller. */
+static HRESULT arbfp_blit_set(void *blit_priv, struct wined3d_context *context, const struct wined3d_surface *surface)
+{
+ GLenum shader;
+ float size[4] = {(float) surface->pow2Width, (float) surface->pow2Height, 1.0f, 1.0f};
+ struct arbfp_blit_priv *priv = blit_priv;
+ enum complex_fixup fixup;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ GLenum textype;
+
+ if (surface->container)
+ textype = surface->container->target;
+ else
+ textype = surface->texture_target;
+
+ if (surface->flags & SFLAG_CONVERTED)
+ {
+ gl_info->gl_ops.gl.p_glEnable(textype);
+ checkGLcall("glEnable(textype)");
+ return WINED3D_OK;
+ }
+
+ if (!is_complex_fixup(surface->resource.format->color_fixup))
+ {
+ TRACE("Fixup:\n");
+ dump_color_fixup_desc(surface->resource.format->color_fixup);
+ /* Don't bother setting up a shader for unconverted formats */
+ gl_info->gl_ops.gl.p_glEnable(textype);
+ checkGLcall("glEnable(textype)");
+ return WINED3D_OK;
+ }
+
+ fixup = get_complex_fixup(surface->resource.format->color_fixup);
+
+ switch(fixup)
+ {
+ case COMPLEX_FIXUP_YUY2:
+ shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->yuy2_rect_shader : priv->yuy2_2d_shader;
+ break;
+
+ case COMPLEX_FIXUP_UYVY:
+ shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->uyvy_rect_shader : priv->uyvy_2d_shader;
+ break;
+
+ case COMPLEX_FIXUP_YV12:
+ shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->yv12_rect_shader : priv->yv12_2d_shader;
+ break;
+
+ case COMPLEX_FIXUP_P8:
+ shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->p8_rect_shader : priv->p8_2d_shader;
+ if (!shader) shader = gen_p8_shader(priv, gl_info, textype);
+
+ upload_palette(surface, context);
+ break;
+
+ default:
+ FIXME("Unsupported complex fixup %#x, not setting a shader\n", fixup);
+ gl_info->gl_ops.gl.p_glEnable(textype);
+ checkGLcall("glEnable(textype)");
+ return E_NOTIMPL;
+ }
+
+ if (!shader) shader = gen_yuv_shader(priv, gl_info, fixup, textype);
+
+ gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB);
+ checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB)");
+ GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, shader));
+ checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, shader)");
+ GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0, size));
+ checkGLcall("glProgramLocalParameter4fvARB");
+
+ return WINED3D_OK;
+}
+
+/* Context activation is done by the caller. */
+static void arbfp_blit_unset(const struct wined3d_gl_info *gl_info)
+{
+ gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_PROGRAM_ARB);
+ checkGLcall("glDisable(GL_FRAGMENT_PROGRAM_ARB)");
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
+ checkGLcall("glDisable(GL_TEXTURE_2D)");
+ if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+ checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
+ }
+ if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
+ checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
+ }
+}
+
+static BOOL arbfp_blit_supported(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
+ const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
+ const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
+{
+ enum complex_fixup src_fixup;
+
+ if (!gl_info->supported[ARB_FRAGMENT_PROGRAM])
+ return FALSE;
+
+ if (blit_op != WINED3D_BLIT_OP_COLOR_BLIT)
+ {
+ TRACE("Unsupported blit_op=%d\n", blit_op);
+ return FALSE;
+ }
+
+ if (src_pool == WINED3D_POOL_SYSTEM_MEM || dst_pool == WINED3D_POOL_SYSTEM_MEM)
+ return FALSE;
+
+ src_fixup = get_complex_fixup(src_format->color_fixup);
+ if (TRACE_ON(d3d_shader) && TRACE_ON(d3d))
+ {
+ TRACE("Checking support for fixup:\n");
+ dump_color_fixup_desc(src_format->color_fixup);
+ }
+
+ if (!is_identity_fixup(dst_format->color_fixup))
+ {
+ TRACE("Destination fixups are not supported\n");
+ return FALSE;
+ }
+
+ if (is_identity_fixup(src_format->color_fixup))
+ {
+ TRACE("[OK]\n");
+ return TRUE;
+ }
+
+ /* We only support YUV conversions. */
+ if (!is_complex_fixup(src_format->color_fixup))
+ {
+ TRACE("[FAILED]\n");
+ return FALSE;
+ }
+
+ switch(src_fixup)
+ {
+ case COMPLEX_FIXUP_YUY2:
+ case COMPLEX_FIXUP_UYVY:
+ case COMPLEX_FIXUP_YV12:
+ case COMPLEX_FIXUP_P8:
+ TRACE("[OK]\n");
+ return TRUE;
+
+ default:
+ FIXME("Unsupported YUV fixup %#x\n", src_fixup);
+ TRACE("[FAILED]\n");
+ return FALSE;
+ }
+}
+
+HRESULT arbfp_blit_surface(struct wined3d_device *device, DWORD filter,
+ struct wined3d_surface *src_surface, const RECT *src_rect_in,
+ struct wined3d_surface *dst_surface, const RECT *dst_rect_in)
+{
+ struct wined3d_context *context;
+ RECT src_rect = *src_rect_in;
+ RECT dst_rect = *dst_rect_in;
+
+ /* Now load the surface */
+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
+ && (src_surface->flags & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE)) == SFLAG_INDRAWABLE)
+ {
+ /* Without FBO blits transferring from the drawable to the texture is
+ * expensive, because we have to flip the data in sysmem. Since we can
+ * flip in the blitter, we don't actually need that flip anyway. So we
+ * use the surface's texture as scratch texture, and flip the source
+ * rectangle instead. */
+ surface_load_fb_texture(src_surface, FALSE);
+
+ src_rect.top = src_surface->resource.height - src_rect.top;
+ src_rect.bottom = src_surface->resource.height - src_rect.bottom;
+ }
+ else
+ surface_internal_preload(src_surface, SRGB_RGB);
+
+ /* Activate the destination context, set it up for blitting */
+ context = context_acquire(device, dst_surface);
+ context_apply_blit_state(context, device);
+
+ if (!surface_is_offscreen(dst_surface))
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ surface_translate_drawable_coords(dst_surface, context->win_handle, &dst_rect);
+#else
+ surface_translate_drawable_coords(dst_surface, context->swapchain->win_handle, &dst_rect);
+#endif
+
+ arbfp_blit_set(device->blit_priv, context, src_surface);
+
+ /* Draw a textured quad */
+ draw_textured_quad(src_surface, context, &src_rect, &dst_rect, filter);
+
+ /* Leave the opengl state valid for blitting */
+ arbfp_blit_unset(context->gl_info);
+
+ if (wined3d_settings.strict_draw_ordering
+ || (dst_surface->swapchain && (dst_surface->swapchain->front_buffer == dst_surface)))
+ context->gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
+
+ context_release(context);
+
+ surface_modify_location(dst_surface, dst_surface->draw_binding, TRUE);
+ return WINED3D_OK;
+}
+
+/* Do not call while under the GL lock. */
+static HRESULT arbfp_blit_color_fill(struct wined3d_device *device, struct wined3d_surface *dst_surface,
+ const RECT *dst_rect, const struct wined3d_color *color)
+{
+ FIXME("Color filling not implemented by arbfp_blit\n");
+ return WINED3DERR_INVALIDCALL;
+}
+
+/* Do not call while under the GL lock. */
+static HRESULT arbfp_blit_depth_fill(struct wined3d_device *device,
+ struct wined3d_surface *surface, const RECT *rect, float depth)
+{
+ FIXME("Depth filling not implemented by arbfp_blit.\n");
+ return WINED3DERR_INVALIDCALL;
+}
+
+const struct blit_shader arbfp_blit = {
+ arbfp_blit_alloc,
+ arbfp_blit_free,
+ arbfp_blit_set,
+ arbfp_blit_unset,
+ arbfp_blit_supported,
+ arbfp_blit_color_fill,
+ arbfp_blit_depth_fill,
+};
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/ati_fragment_shader.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/ati_fragment_shader.c
new file mode 100644
index 00000000..2b656b95
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/ati_fragment_shader.c
@@ -0,0 +1,1228 @@
+/*
+ * Fixed function pipeline replacement using GL_ATI_fragment_shader
+ *
+ * Copyright 2008 Stefan Dösinger(for CodeWeavers)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <math.h>
+#include <stdio.h>
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
+WINE_DECLARE_DEBUG_CHANNEL(d3d);
+
+/* Context activation for state handlers is done by the caller. */
+
+/* Some private defines, Constant associations, etc.
+ * Env bump matrix and per stage constant should be independent,
+ * a stage that bump maps can't read the per state constant
+ */
+#define ATI_FFP_CONST_BUMPMAT(i) (GL_CON_0_ATI + i)
+#define ATI_FFP_CONST_CONSTANT0 GL_CON_0_ATI
+#define ATI_FFP_CONST_CONSTANT1 GL_CON_1_ATI
+#define ATI_FFP_CONST_CONSTANT2 GL_CON_2_ATI
+#define ATI_FFP_CONST_CONSTANT3 GL_CON_3_ATI
+#define ATI_FFP_CONST_CONSTANT4 GL_CON_4_ATI
+#define ATI_FFP_CONST_CONSTANT5 GL_CON_5_ATI
+#define ATI_FFP_CONST_TFACTOR GL_CON_6_ATI
+
+/* GL_ATI_fragment_shader specific fixed function pipeline description. "Inherits" from the common one */
+struct atifs_ffp_desc
+{
+ struct ffp_frag_desc parent;
+ GLuint shader;
+ unsigned int num_textures_used;
+};
+
+struct atifs_private_data
+{
+ struct wine_rb_tree fragment_shaders; /* A rb-tree to track fragment pipeline replacement shaders */
+};
+
+static const char *debug_dstmod(GLuint mod) {
+ switch(mod) {
+ case GL_NONE: return "GL_NONE";
+ case GL_2X_BIT_ATI: return "GL_2X_BIT_ATI";
+ case GL_4X_BIT_ATI: return "GL_4X_BIT_ATI";
+ case GL_8X_BIT_ATI: return "GL_8X_BIT_ATI";
+ case GL_HALF_BIT_ATI: return "GL_HALF_BIT_ATI";
+ case GL_QUARTER_BIT_ATI: return "GL_QUARTER_BIT_ATI";
+ case GL_EIGHTH_BIT_ATI: return "GL_EIGHTH_BIT_ATI";
+ case GL_SATURATE_BIT_ATI: return "GL_SATURATE_BIT_ATI";
+ default: return "Unexpected modifier\n";
+ }
+}
+
+static const char *debug_argmod(GLuint mod) {
+ switch(mod) {
+ case GL_NONE:
+ return "GL_NONE";
+
+ case GL_2X_BIT_ATI:
+ return "GL_2X_BIT_ATI";
+ case GL_COMP_BIT_ATI:
+ return "GL_COMP_BIT_ATI";
+ case GL_NEGATE_BIT_ATI:
+ return "GL_NEGATE_BIT_ATI";
+ case GL_BIAS_BIT_ATI:
+ return "GL_BIAS_BIT_ATI";
+
+ case GL_2X_BIT_ATI | GL_COMP_BIT_ATI:
+ return "GL_2X_BIT_ATI | GL_COMP_BIT_ATI";
+ case GL_2X_BIT_ATI | GL_NEGATE_BIT_ATI:
+ return "GL_2X_BIT_ATI | GL_NEGATE_BIT_ATI";
+ case GL_2X_BIT_ATI | GL_BIAS_BIT_ATI:
+ return "GL_2X_BIT_ATI | GL_BIAS_BIT_ATI";
+ case GL_COMP_BIT_ATI | GL_NEGATE_BIT_ATI:
+ return "GL_COMP_BIT_ATI | GL_NEGATE_BIT_ATI";
+ case GL_COMP_BIT_ATI | GL_BIAS_BIT_ATI:
+ return "GL_COMP_BIT_ATI | GL_BIAS_BIT_ATI";
+ case GL_NEGATE_BIT_ATI | GL_BIAS_BIT_ATI:
+ return "GL_NEGATE_BIT_ATI | GL_BIAS_BIT_ATI";
+
+ case GL_COMP_BIT_ATI | GL_NEGATE_BIT_ATI | GL_BIAS_BIT_ATI:
+ return "GL_COMP_BIT_ATI | GL_NEGATE_BIT_ATI | GL_BIAS_BIT_ATI";
+ case GL_2X_BIT_ATI | GL_NEGATE_BIT_ATI | GL_BIAS_BIT_ATI:
+ return "GL_2X_BIT_ATI | GL_NEGATE_BIT_ATI | GL_BIAS_BIT_ATI";
+ case GL_2X_BIT_ATI | GL_COMP_BIT_ATI | GL_BIAS_BIT_ATI:
+ return "GL_2X_BIT_ATI | GL_COMP_BIT_ATI | GL_BIAS_BIT_ATI";
+ case GL_2X_BIT_ATI | GL_COMP_BIT_ATI | GL_NEGATE_BIT_ATI:
+ return "GL_2X_BIT_ATI | GL_COMP_BIT_ATI | GL_NEGATE_BIT_ATI";
+
+ case GL_2X_BIT_ATI | GL_COMP_BIT_ATI | GL_NEGATE_BIT_ATI | GL_BIAS_BIT_ATI:
+ return "GL_2X_BIT_ATI | GL_COMP_BIT_ATI | GL_NEGATE_BIT_ATI | GL_BIAS_BIT_ATI";
+
+ default:
+ return "Unexpected argmod combination\n";
+ }
+}
+static const char *debug_register(GLuint reg) {
+ switch(reg) {
+ case GL_REG_0_ATI: return "GL_REG_0_ATI";
+ case GL_REG_1_ATI: return "GL_REG_1_ATI";
+ case GL_REG_2_ATI: return "GL_REG_2_ATI";
+ case GL_REG_3_ATI: return "GL_REG_3_ATI";
+ case GL_REG_4_ATI: return "GL_REG_4_ATI";
+ case GL_REG_5_ATI: return "GL_REG_5_ATI";
+
+ case GL_CON_0_ATI: return "GL_CON_0_ATI";
+ case GL_CON_1_ATI: return "GL_CON_1_ATI";
+ case GL_CON_2_ATI: return "GL_CON_2_ATI";
+ case GL_CON_3_ATI: return "GL_CON_3_ATI";
+ case GL_CON_4_ATI: return "GL_CON_4_ATI";
+ case GL_CON_5_ATI: return "GL_CON_5_ATI";
+ case GL_CON_6_ATI: return "GL_CON_6_ATI";
+ case GL_CON_7_ATI: return "GL_CON_7_ATI";
+
+ case GL_ZERO: return "GL_ZERO";
+ case GL_ONE: return "GL_ONE";
+ case GL_PRIMARY_COLOR: return "GL_PRIMARY_COLOR";
+ case GL_SECONDARY_INTERPOLATOR_ATI: return "GL_SECONDARY_INTERPOLATOR_ATI";
+
+ default: return "Unknown register\n";
+ }
+}
+
+static const char *debug_swizzle(GLuint swizzle) {
+ switch(swizzle) {
+ case GL_SWIZZLE_STR_ATI: return "GL_SWIZZLE_STR_ATI";
+ case GL_SWIZZLE_STQ_ATI: return "GL_SWIZZLE_STQ_ATI";
+ case GL_SWIZZLE_STR_DR_ATI: return "GL_SWIZZLE_STR_DR_ATI";
+ case GL_SWIZZLE_STQ_DQ_ATI: return "GL_SWIZZLE_STQ_DQ_ATI";
+ default: return "unknown swizzle";
+ }
+}
+
+static const char *debug_rep(GLuint rep) {
+ switch(rep) {
+ case GL_NONE: return "GL_NONE";
+ case GL_RED: return "GL_RED";
+ case GL_GREEN: return "GL_GREEN";
+ case GL_BLUE: return "GL_BLUE";
+ case GL_ALPHA: return "GL_ALPHA";
+ default: return "unknown argrep";
+ }
+}
+
+static const char *debug_op(GLuint op) {
+ switch(op) {
+ case GL_MOV_ATI: return "GL_MOV_ATI";
+ case GL_ADD_ATI: return "GL_ADD_ATI";
+ case GL_MUL_ATI: return "GL_MUL_ATI";
+ case GL_SUB_ATI: return "GL_SUB_ATI";
+ case GL_DOT3_ATI: return "GL_DOT3_ATI";
+ case GL_DOT4_ATI: return "GL_DOT4_ATI";
+ case GL_MAD_ATI: return "GL_MAD_ATI";
+ case GL_LERP_ATI: return "GL_LERP_ATI";
+ case GL_CND_ATI: return "GL_CND_ATI";
+ case GL_CND0_ATI: return "GL_CND0_ATI";
+ case GL_DOT2_ADD_ATI: return "GL_DOT2_ADD_ATI";
+ default: return "unexpected op";
+ }
+}
+
+static const char *debug_mask(GLuint mask) {
+ switch(mask) {
+ case GL_NONE: return "GL_NONE";
+ case GL_RED_BIT_ATI: return "GL_RED_BIT_ATI";
+ case GL_GREEN_BIT_ATI: return "GL_GREEN_BIT_ATI";
+ case GL_BLUE_BIT_ATI: return "GL_BLUE_BIT_ATI";
+ case GL_RED_BIT_ATI | GL_GREEN_BIT_ATI: return "GL_RED_BIT_ATI | GL_GREEN_BIT_ATI";
+ case GL_RED_BIT_ATI | GL_BLUE_BIT_ATI: return "GL_RED_BIT_ATI | GL_BLUE_BIT_ATI";
+ case GL_GREEN_BIT_ATI | GL_BLUE_BIT_ATI:return "GL_GREEN_BIT_ATI | GL_BLUE_BIT_ATI";
+ case GL_RED_BIT_ATI | GL_GREEN_BIT_ATI | GL_BLUE_BIT_ATI:return "GL_RED_BIT_ATI | GL_GREEN_BIT_ATI | GL_BLUE_BIT_ATI";
+ default: return "Unexpected writemask";
+ }
+}
+
+static void wrap_op1(const struct wined3d_gl_info *gl_info, GLuint op, GLuint dst, GLuint dstMask, GLuint dstMod,
+ GLuint arg1, GLuint arg1Rep, GLuint arg1Mod)
+{
+ if(dstMask == GL_ALPHA) {
+ TRACE("glAlphaFragmentOp1ATI(%s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst), debug_dstmod(dstMod),
+ debug_register(arg1), debug_rep(arg1Rep), debug_argmod(arg1Mod));
+ GL_EXTCALL(glAlphaFragmentOp1ATI(op, dst, dstMod, arg1, arg1Rep, arg1Mod));
+ } else {
+ TRACE("glColorFragmentOp1ATI(%s, %s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst),
+ debug_mask(dstMask), debug_dstmod(dstMod),
+ debug_register(arg1), debug_rep(arg1Rep), debug_argmod(arg1Mod));
+ GL_EXTCALL(glColorFragmentOp1ATI(op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod));
+ }
+}
+
+static void wrap_op2(const struct wined3d_gl_info *gl_info, GLuint op, GLuint dst, GLuint dstMask, GLuint dstMod,
+ GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod)
+{
+ if(dstMask == GL_ALPHA) {
+ TRACE("glAlphaFragmentOp2ATI(%s, %s, %s, %s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst), debug_dstmod(dstMod),
+ debug_register(arg1), debug_rep(arg1Rep), debug_argmod(arg1Mod),
+ debug_register(arg2), debug_rep(arg2Rep), debug_argmod(arg2Mod));
+ GL_EXTCALL(glAlphaFragmentOp2ATI(op, dst, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod));
+ } else {
+ TRACE("glColorFragmentOp2ATI(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst),
+ debug_mask(dstMask), debug_dstmod(dstMod),
+ debug_register(arg1), debug_rep(arg1Rep), debug_argmod(arg1Mod),
+ debug_register(arg2), debug_rep(arg2Rep), debug_argmod(arg2Mod));
+ GL_EXTCALL(glColorFragmentOp2ATI(op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod));
+ }
+}
+
+static void wrap_op3(const struct wined3d_gl_info *gl_info, GLuint op, GLuint dst, GLuint dstMask, GLuint dstMod,
+ GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod,
+ GLuint arg3, GLuint arg3Rep, GLuint arg3Mod)
+{
+ if(dstMask == GL_ALPHA) {
+ /* Leave some free space to fit "GL_NONE, " in to align most alpha and color op lines */
+ TRACE("glAlphaFragmentOp3ATI(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst), debug_dstmod(dstMod),
+ debug_register(arg1), debug_rep(arg1Rep), debug_argmod(arg1Mod),
+ debug_register(arg2), debug_rep(arg2Rep), debug_argmod(arg2Mod),
+ debug_register(arg3), debug_rep(arg3Rep), debug_argmod(arg3Mod));
+ GL_EXTCALL(glAlphaFragmentOp3ATI(op, dst, dstMod,
+ arg1, arg1Rep, arg1Mod,
+ arg2, arg2Rep, arg2Mod,
+ arg3, arg3Rep, arg3Mod));
+ } else {
+ TRACE("glColorFragmentOp3ATI(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)\n", debug_op(op), debug_register(dst),
+ debug_mask(dstMask), debug_dstmod(dstMod),
+ debug_register(arg1), debug_rep(arg1Rep), debug_argmod(arg1Mod),
+ debug_register(arg2), debug_rep(arg2Rep), debug_argmod(arg2Mod),
+ debug_register(arg3), debug_rep(arg3Rep), debug_argmod(arg3Mod));
+ GL_EXTCALL(glColorFragmentOp3ATI(op, dst, dstMask, dstMod,
+ arg1, arg1Rep, arg1Mod,
+ arg2, arg2Rep, arg2Mod,
+ arg3, arg3Rep, arg3Mod));
+ }
+}
+
+static GLuint register_for_arg(DWORD arg, const struct wined3d_gl_info *gl_info,
+ unsigned int stage, GLuint *mod, GLuint *rep, GLuint tmparg)
+{
+ GLenum ret;
+
+ if(mod) *mod = GL_NONE;
+ if(arg == ARG_UNUSED)
+ {
+ if (rep) *rep = GL_NONE;
+ return -1; /* This is the marker for unused registers */
+ }
+
+ switch(arg & WINED3DTA_SELECTMASK) {
+ case WINED3DTA_DIFFUSE:
+ ret = GL_PRIMARY_COLOR;
+ break;
+
+ case WINED3DTA_CURRENT:
+ /* Note that using GL_REG_0_ATI for the passed on register is safe because
+ * texture0 is read at stage0, so in the worst case it is read in the
+ * instruction writing to reg0. Afterwards texture0 is not used any longer.
+ * If we're reading from current
+ */
+ ret = stage ? GL_REG_0_ATI : GL_PRIMARY_COLOR;
+ break;
+
+ case WINED3DTA_TEXTURE:
+ ret = GL_REG_0_ATI + stage;
+ break;
+
+ case WINED3DTA_TFACTOR:
+ ret = ATI_FFP_CONST_TFACTOR;
+ break;
+
+ case WINED3DTA_SPECULAR:
+ ret = GL_SECONDARY_INTERPOLATOR_ATI;
+ break;
+
+ case WINED3DTA_TEMP:
+ ret = tmparg;
+ break;
+
+ case WINED3DTA_CONSTANT:
+ FIXME("Unhandled source argument WINED3DTA_TEMP\n");
+ ret = GL_CON_0_ATI;
+ break;
+
+ default:
+ FIXME("Unknown source argument %d\n", arg);
+ ret = GL_ZERO;
+ }
+
+ if(arg & WINED3DTA_COMPLEMENT) {
+ if(mod) *mod |= GL_COMP_BIT_ATI;
+ }
+ if(arg & WINED3DTA_ALPHAREPLICATE) {
+ if(rep) *rep = GL_ALPHA;
+ } else {
+ if(rep) *rep = GL_NONE;
+ }
+ return ret;
+}
+
+static GLuint find_tmpreg(const struct texture_stage_op op[MAX_TEXTURES])
+{
+ int lowest_read = -1;
+ int lowest_write = -1;
+ int i;
+ BOOL tex_used[MAX_TEXTURES];
+
+ memset(tex_used, 0, sizeof(tex_used));
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ if (op[i].cop == WINED3D_TOP_DISABLE)
+ break;
+
+ if(lowest_read == -1 &&
+ (op[i].carg1 == WINED3DTA_TEMP || op[i].carg2 == WINED3DTA_TEMP || op[i].carg0 == WINED3DTA_TEMP ||
+ op[i].aarg1 == WINED3DTA_TEMP || op[i].aarg2 == WINED3DTA_TEMP || op[i].aarg0 == WINED3DTA_TEMP)) {
+ lowest_read = i;
+ }
+
+ if(lowest_write == -1 && op[i].dst == tempreg) {
+ lowest_write = i;
+ }
+
+ if(op[i].carg1 == WINED3DTA_TEXTURE || op[i].carg2 == WINED3DTA_TEXTURE || op[i].carg0 == WINED3DTA_TEXTURE ||
+ op[i].aarg1 == WINED3DTA_TEXTURE || op[i].aarg2 == WINED3DTA_TEXTURE || op[i].aarg0 == WINED3DTA_TEXTURE) {
+ tex_used[i] = TRUE;
+ }
+ }
+
+ /* Temp reg not read? We don't need it, return GL_NONE */
+ if(lowest_read == -1) return GL_NONE;
+
+ if(lowest_write >= lowest_read) {
+ FIXME("Temp register read before being written\n");
+ }
+
+ if(lowest_write == -1) {
+ /* This needs a test. Maybe we are supposed to return 0.0/0.0/0.0/0.0, or fail drawprim, or whatever */
+ FIXME("Temp register read without being written\n");
+ return GL_REG_1_ATI;
+ } else if(lowest_write >= 1) {
+ /* If we're writing to the temp reg at earliest in stage 1, we can use register 1 for the temp result.
+ * there may be texture data stored in reg 1, but we do not need it any longer since stage 1 already
+ * read it
+ */
+ return GL_REG_1_ATI;
+ } else {
+ /* Search for a free texture register. We have 6 registers available. GL_REG_0_ATI is already used
+ * for the regular result
+ */
+ for(i = 1; i < 6; i++) {
+ if(!tex_used[i]) {
+ return GL_REG_0_ATI + i;
+ }
+ }
+ /* What to do here? Report it in ValidateDevice? */
+ FIXME("Could not find a register for the temporary register\n");
+ return 0;
+ }
+}
+
+static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], const struct wined3d_gl_info *gl_info)
+{
+ GLuint ret = GL_EXTCALL(glGenFragmentShadersATI(1));
+ unsigned int stage;
+ GLuint arg0, arg1, arg2, extrarg;
+ GLuint dstmod, argmod0, argmod1, argmod2, argmodextra;
+ GLuint rep0, rep1, rep2;
+ GLuint swizzle;
+ GLuint tmparg = find_tmpreg(op);
+ GLuint dstreg;
+
+ if(!ret) {
+ ERR("Failed to generate a GL_ATI_fragment_shader shader id\n");
+ return 0;
+ }
+ GL_EXTCALL(glBindFragmentShaderATI(ret));
+ checkGLcall("GL_EXTCALL(glBindFragmentShaderATI(ret))");
+
+ TRACE("glBeginFragmentShaderATI()\n");
+ GL_EXTCALL(glBeginFragmentShaderATI());
+ checkGLcall("GL_EXTCALL(glBeginFragmentShaderATI())");
+
+ /* Pass 1: Generate sampling instructions for perturbation maps */
+ for (stage = 0; stage < gl_info->limits.textures; ++stage)
+ {
+ if (op[stage].cop == WINED3D_TOP_DISABLE)
+ break;
+ if (op[stage].cop != WINED3D_TOP_BUMPENVMAP
+ && op[stage].cop != WINED3D_TOP_BUMPENVMAP_LUMINANCE)
+ continue;
+
+ TRACE("glSampleMapATI(GL_REG_%d_ATI, GL_TEXTURE_%d_ARB, GL_SWIZZLE_STR_ATI)\n",
+ stage, stage);
+ GL_EXTCALL(glSampleMapATI(GL_REG_0_ATI + stage,
+ GL_TEXTURE0_ARB + stage,
+ GL_SWIZZLE_STR_ATI));
+ if(op[stage + 1].projected == proj_none) {
+ swizzle = GL_SWIZZLE_STR_ATI;
+ } else if(op[stage + 1].projected == proj_count4) {
+ swizzle = GL_SWIZZLE_STQ_DQ_ATI;
+ } else {
+ swizzle = GL_SWIZZLE_STR_DR_ATI;
+ }
+ TRACE("glPassTexCoordATI(GL_REG_%d_ATI, GL_TEXTURE_%d_ARB, %s)\n",
+ stage + 1, stage + 1, debug_swizzle(swizzle));
+ GL_EXTCALL(glPassTexCoordATI(GL_REG_0_ATI + stage + 1,
+ GL_TEXTURE0_ARB + stage + 1,
+ swizzle));
+ }
+
+ /* Pass 2: Generate perturbation calculations */
+ for (stage = 0; stage < gl_info->limits.textures; ++stage)
+ {
+ GLuint argmodextra_x, argmodextra_y;
+ struct color_fixup_desc fixup;
+
+ if (op[stage].cop == WINED3D_TOP_DISABLE)
+ break;
+ if (op[stage].cop != WINED3D_TOP_BUMPENVMAP
+ && op[stage].cop != WINED3D_TOP_BUMPENVMAP_LUMINANCE)
+ continue;
+
+ fixup = op[stage].color_fixup;
+ if (fixup.x_source != CHANNEL_SOURCE_X || fixup.y_source != CHANNEL_SOURCE_Y)
+ {
+ FIXME("Swizzles not implemented\n");
+ argmodextra_x = GL_NONE;
+ argmodextra_y = GL_NONE;
+ }
+ else
+ {
+ /* Nice thing, we get the color correction for free :-) */
+ argmodextra_x = fixup.x_sign_fixup ? GL_2X_BIT_ATI | GL_BIAS_BIT_ATI : GL_NONE;
+ argmodextra_y = fixup.y_sign_fixup ? GL_2X_BIT_ATI | GL_BIAS_BIT_ATI : GL_NONE;
+ }
+
+ wrap_op3(gl_info, GL_DOT2_ADD_ATI, GL_REG_0_ATI + stage + 1, GL_RED_BIT_ATI, GL_NONE,
+ GL_REG_0_ATI + stage, GL_NONE, argmodextra_x,
+ ATI_FFP_CONST_BUMPMAT(stage), GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI,
+ GL_REG_0_ATI + stage + 1, GL_RED, GL_NONE);
+
+ /* Don't use GL_DOT2_ADD_ATI here because we cannot configure it to read the blue and alpha
+ * component of the bump matrix. Instead do this with two MADs:
+ *
+ * coord.a = tex.r * bump.b + coord.g
+ * coord.g = tex.g * bump.a + coord.a
+ *
+ * The first instruction writes to alpha so it can be coissued with the above DOT2_ADD.
+ * coord.a is unused. If the perturbed texture is projected, this was already handled
+ * in the glPassTexCoordATI above.
+ */
+ wrap_op3(gl_info, GL_MAD_ATI, GL_REG_0_ATI + stage + 1, GL_ALPHA, GL_NONE,
+ GL_REG_0_ATI + stage, GL_RED, argmodextra_y,
+ ATI_FFP_CONST_BUMPMAT(stage), GL_BLUE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI,
+ GL_REG_0_ATI + stage + 1, GL_GREEN, GL_NONE);
+ wrap_op3(gl_info, GL_MAD_ATI, GL_REG_0_ATI + stage + 1, GL_GREEN_BIT_ATI, GL_NONE,
+ GL_REG_0_ATI + stage, GL_GREEN, argmodextra_y,
+ ATI_FFP_CONST_BUMPMAT(stage), GL_ALPHA, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI,
+ GL_REG_0_ATI + stage + 1, GL_ALPHA, GL_NONE);
+ }
+
+ /* Pass 3: Generate sampling instructions for regular textures */
+ for (stage = 0; stage < gl_info->limits.textures; ++stage)
+ {
+ if (op[stage].cop == WINED3D_TOP_DISABLE)
+ break;
+
+ if(op[stage].projected == proj_none) {
+ swizzle = GL_SWIZZLE_STR_ATI;
+ } else if(op[stage].projected == proj_count3) {
+ swizzle = GL_SWIZZLE_STR_DR_ATI;
+ } else {
+ swizzle = GL_SWIZZLE_STQ_DQ_ATI;
+ }
+
+ if ((op[stage].carg0 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
+ || (op[stage].carg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
+ || (op[stage].carg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
+ || (op[stage].aarg0 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
+ || (op[stage].aarg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
+ || (op[stage].aarg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
+ || op[stage].cop == WINED3D_TOP_BLEND_TEXTURE_ALPHA)
+ {
+ if (stage > 0
+ && (op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP
+ || op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE))
+ {
+ TRACE("glSampleMapATI(GL_REG_%d_ATI, GL_REG_%d_ATI, GL_SWIZZLE_STR_ATI)\n",
+ stage, stage);
+ GL_EXTCALL(glSampleMapATI(GL_REG_0_ATI + stage,
+ GL_REG_0_ATI + stage,
+ GL_SWIZZLE_STR_ATI));
+ } else {
+ TRACE("glSampleMapATI(GL_REG_%d_ATI, GL_TEXTURE_%d_ARB, %s)\n",
+ stage, stage, debug_swizzle(swizzle));
+ GL_EXTCALL(glSampleMapATI(GL_REG_0_ATI + stage,
+ GL_TEXTURE0_ARB + stage,
+ swizzle));
+ }
+ }
+ }
+
+ /* Pass 4: Generate the arithmetic instructions */
+ for (stage = 0; stage < MAX_TEXTURES; ++stage)
+ {
+ if (op[stage].cop == WINED3D_TOP_DISABLE)
+ {
+ if (!stage)
+ {
+ /* Handle complete texture disabling gracefully */
+ wrap_op1(gl_info, GL_MOV_ATI, GL_REG_0_ATI, GL_NONE, GL_NONE,
+ GL_PRIMARY_COLOR, GL_NONE, GL_NONE);
+ wrap_op1(gl_info, GL_MOV_ATI, GL_REG_0_ATI, GL_ALPHA, GL_NONE,
+ GL_PRIMARY_COLOR, GL_NONE, GL_NONE);
+ }
+ break;
+ }
+
+ if(op[stage].dst == tempreg) {
+ /* If we're writing to D3DTA_TEMP, but never reading from it we don't have to write there in the first place.
+ * skip the entire stage, this saves some GPU time
+ */
+ if(tmparg == GL_NONE) continue;
+
+ dstreg = tmparg;
+ } else {
+ dstreg = GL_REG_0_ATI;
+ }
+
+ arg0 = register_for_arg(op[stage].carg0, gl_info, stage, &argmod0, &rep0, tmparg);
+ arg1 = register_for_arg(op[stage].carg1, gl_info, stage, &argmod1, &rep1, tmparg);
+ arg2 = register_for_arg(op[stage].carg2, gl_info, stage, &argmod2, &rep2, tmparg);
+ dstmod = GL_NONE;
+ argmodextra = GL_NONE;
+ extrarg = GL_NONE;
+
+ switch (op[stage].cop)
+ {
+ case WINED3D_TOP_SELECT_ARG2:
+ arg1 = arg2;
+ argmod1 = argmod2;
+ rep1 = rep2;
+ /* fall through */
+ case WINED3D_TOP_SELECT_ARG1:
+ wrap_op1(gl_info, GL_MOV_ATI, dstreg, GL_NONE, GL_NONE,
+ arg1, rep1, argmod1);
+ break;
+
+ case WINED3D_TOP_MODULATE_4X:
+ if(dstmod == GL_NONE) dstmod = GL_4X_BIT_ATI;
+ /* fall through */
+ case WINED3D_TOP_MODULATE_2X:
+ if(dstmod == GL_NONE) dstmod = GL_2X_BIT_ATI;
+ dstmod |= GL_SATURATE_BIT_ATI;
+ /* fall through */
+ case WINED3D_TOP_MODULATE:
+ wrap_op2(gl_info, GL_MUL_ATI, dstreg, GL_NONE, dstmod,
+ arg1, rep1, argmod1,
+ arg2, rep2, argmod2);
+ break;
+
+ case WINED3D_TOP_ADD_SIGNED_2X:
+ dstmod = GL_2X_BIT_ATI;
+ /* fall through */
+ case WINED3D_TOP_ADD_SIGNED:
+ argmodextra = GL_BIAS_BIT_ATI;
+ /* fall through */
+ case WINED3D_TOP_ADD:
+ dstmod |= GL_SATURATE_BIT_ATI;
+ wrap_op2(gl_info, GL_ADD_ATI, GL_REG_0_ATI, GL_NONE, dstmod,
+ arg1, rep1, argmod1,
+ arg2, rep2, argmodextra | argmod2);
+ break;
+
+ case WINED3D_TOP_SUBTRACT:
+ dstmod |= GL_SATURATE_BIT_ATI;
+ wrap_op2(gl_info, GL_SUB_ATI, dstreg, GL_NONE, dstmod,
+ arg1, rep1, argmod1,
+ arg2, rep2, argmod2);
+ break;
+
+ case WINED3D_TOP_ADD_SMOOTH:
+ argmodextra = argmod1 & GL_COMP_BIT_ATI ? argmod1 & ~GL_COMP_BIT_ATI : argmod1 | GL_COMP_BIT_ATI;
+ /* Dst = arg1 + * arg2(1 -arg 1)
+ * = arg2 * (1 - arg1) + arg1
+ */
+ wrap_op3(gl_info, GL_MAD_ATI, dstreg, GL_NONE, GL_SATURATE_BIT_ATI,
+ arg2, rep2, argmod2,
+ arg1, rep1, argmodextra,
+ arg1, rep1, argmod1);
+ break;
+
+ case WINED3D_TOP_BLEND_CURRENT_ALPHA:
+ if (extrarg == GL_NONE)
+ extrarg = register_for_arg(WINED3DTA_CURRENT, gl_info, stage, NULL, NULL, -1);
+ /* fall through */
+ case WINED3D_TOP_BLEND_FACTOR_ALPHA:
+ if (extrarg == GL_NONE)
+ extrarg = register_for_arg(WINED3DTA_TFACTOR, gl_info, stage, NULL, NULL, -1);
+ /* fall through */
+ case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
+ if (extrarg == GL_NONE)
+ extrarg = register_for_arg(WINED3DTA_TEXTURE, gl_info, stage, NULL, NULL, -1);
+ /* fall through */
+ case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
+ if (extrarg == GL_NONE)
+ extrarg = register_for_arg(WINED3DTA_DIFFUSE, gl_info, stage, NULL, NULL, -1);
+ wrap_op3(gl_info, GL_LERP_ATI, dstreg, GL_NONE, GL_NONE,
+ extrarg, GL_ALPHA, GL_NONE,
+ arg1, rep1, argmod1,
+ arg2, rep2, argmod2);
+ break;
+
+ case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
+ arg0 = register_for_arg(WINED3DTA_TEXTURE, gl_info, stage, NULL, NULL, -1);
+ wrap_op3(gl_info, GL_MAD_ATI, dstreg, GL_NONE, GL_NONE,
+ arg2, rep2, argmod2,
+ arg0, GL_ALPHA, GL_COMP_BIT_ATI,
+ arg1, rep1, argmod1);
+ break;
+
+ /* D3DTOP_PREMODULATE ???? */
+
+ case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
+ argmodextra = argmod1 & GL_COMP_BIT_ATI ? argmod1 & ~GL_COMP_BIT_ATI : argmod1 | GL_COMP_BIT_ATI;
+ /* fall through */
+ case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
+ if (!argmodextra)
+ argmodextra = argmod1;
+ wrap_op3(gl_info, GL_MAD_ATI, dstreg, GL_NONE, GL_SATURATE_BIT_ATI,
+ arg2, rep2, argmod2,
+ arg1, GL_ALPHA, argmodextra,
+ arg1, rep1, argmod1);
+ break;
+
+ case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
+ argmodextra = argmod1 & GL_COMP_BIT_ATI ? argmod1 & ~GL_COMP_BIT_ATI : argmod1 | GL_COMP_BIT_ATI;
+ /* fall through */
+ case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
+ if (!argmodextra)
+ argmodextra = argmod1;
+ wrap_op3(gl_info, GL_MAD_ATI, dstreg, GL_NONE, GL_SATURATE_BIT_ATI,
+ arg2, rep2, argmod2,
+ arg1, rep1, argmodextra,
+ arg1, GL_ALPHA, argmod1);
+ break;
+
+ case WINED3D_TOP_DOTPRODUCT3:
+ wrap_op2(gl_info, GL_DOT3_ATI, dstreg, GL_NONE, GL_4X_BIT_ATI | GL_SATURATE_BIT_ATI,
+ arg1, rep1, argmod1 | GL_BIAS_BIT_ATI,
+ arg2, rep2, argmod2 | GL_BIAS_BIT_ATI);
+ break;
+
+ case WINED3D_TOP_MULTIPLY_ADD:
+ wrap_op3(gl_info, GL_MAD_ATI, dstreg, GL_NONE, GL_SATURATE_BIT_ATI,
+ arg1, rep1, argmod1,
+ arg2, rep2, argmod2,
+ arg0, rep0, argmod0);
+ break;
+
+ case WINED3D_TOP_LERP:
+ wrap_op3(gl_info, GL_LERP_ATI, dstreg, GL_NONE, GL_NONE,
+ arg0, rep0, argmod0,
+ arg1, rep1, argmod1,
+ arg2, rep2, argmod2);
+ break;
+
+ case WINED3D_TOP_BUMPENVMAP:
+ case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
+ /* Those are handled in the first pass of the shader(generation pass 1 and 2) already */
+ break;
+
+ default: FIXME("Unhandled color operation %d on stage %d\n", op[stage].cop, stage);
+ }
+
+ arg0 = register_for_arg(op[stage].aarg0, gl_info, stage, &argmod0, NULL, tmparg);
+ arg1 = register_for_arg(op[stage].aarg1, gl_info, stage, &argmod1, NULL, tmparg);
+ arg2 = register_for_arg(op[stage].aarg2, gl_info, stage, &argmod2, NULL, tmparg);
+ dstmod = GL_NONE;
+ argmodextra = GL_NONE;
+ extrarg = GL_NONE;
+
+ switch (op[stage].aop)
+ {
+ case WINED3D_TOP_DISABLE:
+ /* Get the primary color to the output if on stage 0, otherwise leave register 0 untouched */
+ if (!stage)
+ {
+ wrap_op1(gl_info, GL_MOV_ATI, GL_REG_0_ATI, GL_ALPHA, GL_NONE,
+ GL_PRIMARY_COLOR, GL_NONE, GL_NONE);
+ }
+ break;
+
+ case WINED3D_TOP_SELECT_ARG2:
+ arg1 = arg2;
+ argmod1 = argmod2;
+ /* fall through */
+ case WINED3D_TOP_SELECT_ARG1:
+ wrap_op1(gl_info, GL_MOV_ATI, dstreg, GL_ALPHA, GL_NONE,
+ arg1, GL_NONE, argmod1);
+ break;
+
+ case WINED3D_TOP_MODULATE_4X:
+ if (dstmod == GL_NONE)
+ dstmod = GL_4X_BIT_ATI;
+ /* fall through */
+ case WINED3D_TOP_MODULATE_2X:
+ if (dstmod == GL_NONE)
+ dstmod = GL_2X_BIT_ATI;
+ dstmod |= GL_SATURATE_BIT_ATI;
+ /* fall through */
+ case WINED3D_TOP_MODULATE:
+ wrap_op2(gl_info, GL_MUL_ATI, dstreg, GL_ALPHA, dstmod,
+ arg1, GL_NONE, argmod1,
+ arg2, GL_NONE, argmod2);
+ break;
+
+ case WINED3D_TOP_ADD_SIGNED_2X:
+ dstmod = GL_2X_BIT_ATI;
+ /* fall through */
+ case WINED3D_TOP_ADD_SIGNED:
+ argmodextra = GL_BIAS_BIT_ATI;
+ /* fall through */
+ case WINED3D_TOP_ADD:
+ dstmod |= GL_SATURATE_BIT_ATI;
+ wrap_op2(gl_info, GL_ADD_ATI, dstreg, GL_ALPHA, dstmod,
+ arg1, GL_NONE, argmod1,
+ arg2, GL_NONE, argmodextra | argmod2);
+ break;
+
+ case WINED3D_TOP_SUBTRACT:
+ dstmod |= GL_SATURATE_BIT_ATI;
+ wrap_op2(gl_info, GL_SUB_ATI, dstreg, GL_ALPHA, dstmod,
+ arg1, GL_NONE, argmod1,
+ arg2, GL_NONE, argmod2);
+ break;
+
+ case WINED3D_TOP_ADD_SMOOTH:
+ argmodextra = argmod1 & GL_COMP_BIT_ATI ? argmod1 & ~GL_COMP_BIT_ATI : argmod1 | GL_COMP_BIT_ATI;
+ /* Dst = arg1 + * arg2(1 -arg 1)
+ * = arg2 * (1 - arg1) + arg1
+ */
+ wrap_op3(gl_info, GL_MAD_ATI, dstreg, GL_ALPHA, GL_SATURATE_BIT_ATI,
+ arg2, GL_NONE, argmod2,
+ arg1, GL_NONE, argmodextra,
+ arg1, GL_NONE, argmod1);
+ break;
+
+ case WINED3D_TOP_BLEND_CURRENT_ALPHA:
+ if (extrarg == GL_NONE)
+ extrarg = register_for_arg(WINED3DTA_CURRENT, gl_info, stage, NULL, NULL, -1);
+ /* fall through */
+ case WINED3D_TOP_BLEND_FACTOR_ALPHA:
+ if (extrarg == GL_NONE)
+ extrarg = register_for_arg(WINED3DTA_TFACTOR, gl_info, stage, NULL, NULL, -1);
+ /* fall through */
+ case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
+ if (extrarg == GL_NONE)
+ extrarg = register_for_arg(WINED3DTA_TEXTURE, gl_info, stage, NULL, NULL, -1);
+ /* fall through */
+ case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
+ if (extrarg == GL_NONE)
+ extrarg = register_for_arg(WINED3DTA_DIFFUSE, gl_info, stage, NULL, NULL, -1);
+ wrap_op3(gl_info, GL_LERP_ATI, dstreg, GL_ALPHA, GL_NONE,
+ extrarg, GL_ALPHA, GL_NONE,
+ arg1, GL_NONE, argmod1,
+ arg2, GL_NONE, argmod2);
+ break;
+
+ case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
+ arg0 = register_for_arg(WINED3DTA_TEXTURE, gl_info, stage, NULL, NULL, -1);
+ wrap_op3(gl_info, GL_MAD_ATI, dstreg, GL_ALPHA, GL_NONE,
+ arg2, GL_NONE, argmod2,
+ arg0, GL_ALPHA, GL_COMP_BIT_ATI,
+ arg1, GL_NONE, argmod1);
+ break;
+
+ /* D3DTOP_PREMODULATE ???? */
+
+ case WINED3D_TOP_DOTPRODUCT3:
+ wrap_op2(gl_info, GL_DOT3_ATI, dstreg, GL_ALPHA, GL_4X_BIT_ATI | GL_SATURATE_BIT_ATI,
+ arg1, GL_NONE, argmod1 | GL_BIAS_BIT_ATI,
+ arg2, GL_NONE, argmod2 | GL_BIAS_BIT_ATI);
+ break;
+
+ case WINED3D_TOP_MULTIPLY_ADD:
+ wrap_op3(gl_info, GL_MAD_ATI, dstreg, GL_ALPHA, GL_SATURATE_BIT_ATI,
+ arg1, GL_NONE, argmod1,
+ arg2, GL_NONE, argmod2,
+ arg0, GL_NONE, argmod0);
+ break;
+
+ case WINED3D_TOP_LERP:
+ wrap_op3(gl_info, GL_LERP_ATI, dstreg, GL_ALPHA, GL_SATURATE_BIT_ATI,
+ arg1, GL_NONE, argmod1,
+ arg2, GL_NONE, argmod2,
+ arg0, GL_NONE, argmod0);
+ break;
+
+ case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
+ case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
+ case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
+ case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
+ case WINED3D_TOP_BUMPENVMAP:
+ case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
+ ERR("Application uses an invalid alpha operation\n");
+ break;
+
+ default: FIXME("Unhandled alpha operation %d on stage %d\n", op[stage].aop, stage);
+ }
+ }
+
+ TRACE("glEndFragmentShaderATI()\n");
+ GL_EXTCALL(glEndFragmentShaderATI());
+ checkGLcall("GL_EXTCALL(glEndFragmentShaderATI())");
+ return ret;
+}
+
+static void set_tex_op_atifs(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_device *device = context->swapchain->device;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const struct wined3d_d3d_info *d3d_info = context->d3d_info;
+ const struct atifs_ffp_desc *desc;
+ struct ffp_frag_settings settings;
+ struct atifs_private_data *priv = device->fragment_priv;
+ DWORD mapped_stage;
+ unsigned int i;
+
+ gen_ffp_frag_op(context, state, &settings, TRUE);
+ desc = (const struct atifs_ffp_desc *)find_ffp_frag_shader(&priv->fragment_shaders, &settings);
+ if(!desc) {
+ struct atifs_ffp_desc *new_desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_desc));
+ if (!new_desc)
+ {
+ ERR("Out of memory\n");
+ return;
+ }
+ new_desc->num_textures_used = 0;
+ for (i = 0; i < d3d_info->limits.ffp_blend_stages; ++i)
+ {
+ if (settings.op[i].cop == WINED3D_TOP_DISABLE)
+ break;
+ new_desc->num_textures_used = i + 1;
+ }
+
+ new_desc->parent.settings = settings;
+ new_desc->shader = gen_ati_shader(settings.op, gl_info);
+ add_ffp_frag_shader(&priv->fragment_shaders, &new_desc->parent);
+ TRACE("Allocated fixed function replacement shader descriptor %p\n", new_desc);
+ desc = new_desc;
+ }
+
+ /* GL_ATI_fragment_shader depends on the GL_TEXTURE_xD enable settings. Update the texture stages
+ * used by this shader
+ */
+ for (i = 0; i < desc->num_textures_used; ++i)
+ {
+ mapped_stage = device->texUnitMap[i];
+ if (mapped_stage != WINED3D_UNMAPPED_STAGE)
+ {
+ context_active_texture(context, gl_info, mapped_stage);
+ texture_activate_dimensions(state->textures[i], gl_info);
+ }
+ }
+
+ GL_EXTCALL(glBindFragmentShaderATI(desc->shader));
+}
+
+static void state_texfactor_atifs(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ float col[4];
+
+ D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col);
+ GL_EXTCALL(glSetFragmentShaderConstantATI(ATI_FFP_CONST_TFACTOR, col));
+ checkGLcall("glSetFragmentShaderConstantATI(ATI_FFP_CONST_TFACTOR, col)");
+}
+
+static void set_bumpmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ float mat[2][2];
+
+ mat[0][0] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_MAT00]);
+ mat[1][0] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_MAT01]);
+ mat[0][1] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_MAT10]);
+ mat[1][1] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_MAT11]);
+ /* GL_ATI_fragment_shader allows only constants from 0.0 to 1.0, but the bumpmat
+ * constants can be in any range. While they should stay between [-1.0 and 1.0] because
+ * Shader Model 1.x pixel shaders are clamped to that range negative values are used occasionally,
+ * for example by our d3d9 test. So to get negative values scale -1;1 to 0;1 and undo that in the
+ * shader(it is free). This might potentially reduce precision. However, if the hardware does
+ * support proper floats it shouldn't, and if it doesn't we can't get anything better anyway
+ */
+ mat[0][0] = (mat[0][0] + 1.0f) * 0.5f;
+ mat[1][0] = (mat[1][0] + 1.0f) * 0.5f;
+ mat[0][1] = (mat[0][1] + 1.0f) * 0.5f;
+ mat[1][1] = (mat[1][1] + 1.0f) * 0.5f;
+ GL_EXTCALL(glSetFragmentShaderConstantATI(ATI_FFP_CONST_BUMPMAT(stage), (float *) mat));
+ checkGLcall("glSetFragmentShaderConstantATI(ATI_FFP_CONST_BUMPMAT(stage), mat)");
+}
+
+static void textransform(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (!isStateDirty(context, STATE_PIXELSHADER))
+ set_tex_op_atifs(context, state, state_id);
+}
+
+static void atifs_apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ context->last_was_pshader = use_ps(state);
+ /* The ATIFS code does not support pixel shaders currently, but we have to
+ * provide a state handler to call shader_select to select a vertex shader
+ * if one is applied because the vertex shader state may defer calling the
+ * shader backend if the pshader state is dirty.
+ *
+ * In theory the application should not be able to mark the pixel shader
+ * dirty because it cannot create a shader, and thus has no way to set the
+ * state to something != NULL. However, a different pipeline part may link
+ * a different state to its pixelshader handler, thus a pshader state
+ * exists and can be dirtified. Also the pshader is always dirtified at
+ * startup, and blitting disables all shaders and dirtifies all shader
+ * states. If atifs can deal with this it keeps the rest of the code
+ * simpler. */
+ context->select_shader = 1;
+ context->load_constants = 1;
+}
+
+static void atifs_srgbwriteenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_SRGBWRITEENABLE])
+ WARN("sRGB writes are not supported by this fragment pipe.\n");
+}
+
+static const struct StateEntryTemplate atifs_fragmentstate_template[] = {
+ {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), state_texfactor_atifs }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGCOLOR), { STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGDENSITY), { STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGSTART), { STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGEND), { STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), atifs_srgbwriteenable }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), set_tex_op_atifs }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), set_bumpmat }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE },
+ {STATE_PIXELSHADER, { STATE_PIXELSHADER, atifs_apply_pixelshader }, WINED3D_GL_EXT_NONE },
+ {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
+};
+
+/* Context activation is done by the caller. */
+static void atifs_enable(const struct wined3d_gl_info *gl_info, BOOL enable)
+{
+ if (enable)
+ {
+ gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_SHADER_ATI);
+ checkGLcall("glEnable(GL_FRAGMENT_SHADER_ATI)");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_SHADER_ATI);
+ checkGLcall("glDisable(GL_FRAGMENT_SHADER_ATI)");
+ }
+}
+
+static void atifs_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
+{
+ caps->wined3d_caps = WINED3D_FRAGMENT_CAP_PROJ_CONTROL;
+ caps->PrimitiveMiscCaps = WINED3DPMISCCAPS_TSSARGTEMP;
+ caps->TextureOpCaps = WINED3DTEXOPCAPS_DISABLE |
+ WINED3DTEXOPCAPS_SELECTARG1 |
+ WINED3DTEXOPCAPS_SELECTARG2 |
+ WINED3DTEXOPCAPS_MODULATE4X |
+ WINED3DTEXOPCAPS_MODULATE2X |
+ WINED3DTEXOPCAPS_MODULATE |
+ WINED3DTEXOPCAPS_ADDSIGNED2X |
+ WINED3DTEXOPCAPS_ADDSIGNED |
+ WINED3DTEXOPCAPS_ADD |
+ WINED3DTEXOPCAPS_SUBTRACT |
+ WINED3DTEXOPCAPS_ADDSMOOTH |
+ WINED3DTEXOPCAPS_BLENDCURRENTALPHA |
+ WINED3DTEXOPCAPS_BLENDFACTORALPHA |
+ WINED3DTEXOPCAPS_BLENDTEXTUREALPHA |
+ WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA |
+ WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM |
+ WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
+ WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
+ WINED3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA |
+ WINED3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR |
+ WINED3DTEXOPCAPS_DOTPRODUCT3 |
+ WINED3DTEXOPCAPS_MULTIPLYADD |
+ WINED3DTEXOPCAPS_LERP |
+ WINED3DTEXOPCAPS_BUMPENVMAP;
+
+ /* TODO: Implement WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE
+ and WINED3DTEXOPCAPS_PREMODULATE */
+
+ /* GL_ATI_fragment_shader always supports 6 textures, which was the limit on r200 cards
+ * which this extension is exclusively focused on(later cards have GL_ARB_fragment_program).
+ * If the current card has more than 8 fixed function textures in OpenGL's regular fixed
+ * function pipeline then the ATI_fragment_shader backend imposes a stricter limit. This
+ * shouldn't be too hard since Nvidia cards have a limit of 4 textures with the default ffp
+ * pipeline, and almost all games are happy with that. We can however support up to 8
+ * texture stages because we have a 2nd pass limit of 8 instructions, and per stage we use
+ * only 1 instruction.
+ *
+ * The proper fix for this is not to use GL_ATI_fragment_shader on cards newer than the
+ * r200 series and use an ARB or GLSL shader instead
+ */
+ caps->MaxTextureBlendStages = 8;
+ caps->MaxSimultaneousTextures = 6;
+}
+
+static void *atifs_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
+{
+ struct atifs_private_data *priv;
+
+ if (!(priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*priv))))
+ return NULL;
+
+ if (wine_rb_init(&priv->fragment_shaders, &wined3d_ffp_frag_program_rb_functions) == -1)
+ {
+ ERR("Failed to initialize rbtree.\n");
+ HeapFree(GetProcessHeap(), 0, priv);
+ return NULL;
+ }
+
+ return priv;
+}
+
+/* Context activation is done by the caller. */
+static void atifs_free_ffpshader(struct wine_rb_entry *entry, void *cb_ctx)
+{
+ const struct wined3d_gl_info *gl_info = cb_ctx;
+ struct atifs_ffp_desc *entry_ati = WINE_RB_ENTRY_VALUE(entry, struct atifs_ffp_desc, parent.entry);
+
+ GL_EXTCALL(glDeleteFragmentShaderATI(entry_ati->shader));
+ checkGLcall("glDeleteFragmentShaderATI(entry->shader)");
+ HeapFree(GetProcessHeap(), 0, entry_ati);
+}
+
+/* Context activation is done by the caller. */
+static void atifs_free(struct wined3d_device *device)
+{
+ struct atifs_private_data *priv = device->fragment_priv;
+
+ wine_rb_destroy(&priv->fragment_shaders, atifs_free_ffpshader, &device->adapter->gl_info);
+
+ HeapFree(GetProcessHeap(), 0, priv);
+ device->fragment_priv = NULL;
+}
+
+static BOOL atifs_color_fixup_supported(struct color_fixup_desc fixup)
+{
+ if (TRACE_ON(d3d_shader) && TRACE_ON(d3d))
+ {
+ TRACE("Checking support for fixup:\n");
+ dump_color_fixup_desc(fixup);
+ }
+
+ /* We only support sign fixup of the first two channels. */
+ if (fixup.x_source == CHANNEL_SOURCE_X && fixup.y_source == CHANNEL_SOURCE_Y
+ && fixup.z_source == CHANNEL_SOURCE_Z && fixup.w_source == CHANNEL_SOURCE_W
+ && !fixup.z_sign_fixup && !fixup.w_sign_fixup)
+ {
+ TRACE("[OK]\n");
+ return TRUE;
+ }
+
+ TRACE("[FAILED]\n");
+ return FALSE;
+}
+
+const struct fragment_pipeline atifs_fragment_pipeline = {
+ atifs_enable,
+ atifs_get_caps,
+ atifs_alloc,
+ atifs_free,
+ atifs_color_fixup_supported,
+ atifs_fragmentstate_template,
+};
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/buffer.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/buffer.c
new file mode 100644
index 00000000..4c5383da
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/buffer.c
@@ -0,0 +1,1557 @@
+/*
+ * Copyright 2002-2005 Jason Edmeades
+ * Copyright 2002-2005 Raphael Junqueira
+ * Copyright 2004 Christian Costa
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2007-2010 Stefan Dösinger for CodeWeavers
+ * Copyright 2009-2010 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+
+#define VB_MAXDECLCHANGES 100 /* After that number of decl changes we stop converting */
+#define VB_RESETDECLCHANGE 1000 /* Reset the decl changecount after that number of draws */
+#define VB_MAXFULLCONVERSIONS 5 /* Number of full conversions before we stop converting */
+#define VB_RESETFULLCONVS 20 /* Reset full conversion counts after that number of draws */
+
+static inline BOOL buffer_add_dirty_area(struct wined3d_buffer *This, UINT offset, UINT size)
+{
+ if (!This->buffer_object) return TRUE;
+
+ if (This->maps_size <= This->modified_areas)
+ {
+ void *new = HeapReAlloc(GetProcessHeap(), 0, This->maps,
+ This->maps_size * 2 * sizeof(*This->maps));
+ if (!new)
+ {
+ ERR("Out of memory\n");
+ return FALSE;
+ }
+ else
+ {
+ This->maps = new;
+ This->maps_size *= 2;
+ }
+ }
+
+ if(offset > This->resource.size || offset + size > This->resource.size)
+ {
+ WARN("Invalid range dirtified, marking entire buffer dirty\n");
+ offset = 0;
+ size = This->resource.size;
+ }
+ else if(!offset && !size)
+ {
+ size = This->resource.size;
+ }
+
+ This->maps[This->modified_areas].offset = offset;
+ This->maps[This->modified_areas].size = size;
+ This->modified_areas++;
+ return TRUE;
+}
+
+static inline void buffer_clear_dirty_areas(struct wined3d_buffer *This)
+{
+ This->modified_areas = 0;
+}
+
+static BOOL buffer_is_dirty(const struct wined3d_buffer *buffer)
+{
+ return !!buffer->modified_areas;
+}
+
+static BOOL buffer_is_fully_dirty(const struct wined3d_buffer *buffer)
+{
+ unsigned int i;
+
+ for (i = 0; i < buffer->modified_areas; ++i)
+ {
+ if (!buffer->maps[i].offset && buffer->maps[i].size == buffer->resource.size)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* Context activation is done by the caller */
+static void delete_gl_buffer(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info)
+{
+ if(!This->buffer_object) return;
+
+ GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object));
+ checkGLcall("glDeleteBuffersARB");
+ This->buffer_object = 0;
+
+ if(This->query)
+ {
+ wined3d_event_query_destroy(This->query);
+ This->query = NULL;
+ }
+ This->flags &= ~WINED3D_BUFFER_APPLESYNC;
+}
+
+/* Context activation is done by the caller. */
+static void buffer_create_buffer_object(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info)
+{
+ GLenum gl_usage = GL_STATIC_DRAW_ARB;
+ GLenum error;
+
+ TRACE("Creating an OpenGL vertex buffer object for wined3d_buffer %p with usage %s.\n",
+ This, debug_d3dusage(This->resource.usage));
+
+ /* Make sure that the gl error is cleared. Do not use checkGLcall
+ * here because checkGLcall just prints a fixme and continues. However,
+ * if an error during VBO creation occurs we can fall back to non-vbo operation
+ * with full functionality(but performance loss)
+ */
+ while (gl_info->gl_ops.gl.p_glGetError() != GL_NO_ERROR);
+
+ /* Basically the FVF parameter passed to CreateVertexBuffer is no good.
+ * The vertex declaration from the device determines how the data in the
+ * buffer is interpreted. This means that on each draw call the buffer has
+ * to be verified to check if the rhw and color values are in the correct
+ * format. */
+
+ GL_EXTCALL(glGenBuffersARB(1, &This->buffer_object));
+ error = gl_info->gl_ops.gl.p_glGetError();
+ if (!This->buffer_object || error != GL_NO_ERROR)
+ {
+ ERR("Failed to create a VBO with error %s (%#x)\n", debug_glerror(error), error);
+ goto fail;
+ }
+
+ if (This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
+ device_invalidate_state(This->resource.device, STATE_INDEXBUFFER);
+ GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
+ error = gl_info->gl_ops.gl.p_glGetError();
+ if (error != GL_NO_ERROR)
+ {
+ ERR("Failed to bind the VBO with error %s (%#x)\n", debug_glerror(error), error);
+ goto fail;
+ }
+
+ if (This->resource.usage & WINED3DUSAGE_DYNAMIC)
+ {
+ TRACE("Buffer has WINED3DUSAGE_DYNAMIC set.\n");
+ gl_usage = GL_STREAM_DRAW_ARB;
+
+ if(gl_info->supported[APPLE_FLUSH_BUFFER_RANGE])
+ {
+ GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE));
+ checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)");
+ This->flags |= WINED3D_BUFFER_FLUSH;
+
+ GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE));
+ checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE)");
+ This->flags |= WINED3D_BUFFER_APPLESYNC;
+ }
+ /* No setup is needed here for GL_ARB_map_buffer_range */
+ }
+
+ /* Reserve memory for the buffer. The amount of data won't change
+ * so we are safe with calling glBufferData once and
+ * calling glBufferSubData on updates. Upload the actual data in case
+ * we're not double buffering, so we can release the heap mem afterwards
+ */
+ GL_EXTCALL(glBufferDataARB(This->buffer_type_hint, This->resource.size, This->resource.allocatedMemory, gl_usage));
+ error = gl_info->gl_ops.gl.p_glGetError();
+ if (error != GL_NO_ERROR)
+ {
+ ERR("glBufferDataARB failed with error %s (%#x)\n", debug_glerror(error), error);
+ goto fail;
+ }
+
+ This->buffer_object_size = This->resource.size;
+ This->buffer_object_usage = gl_usage;
+
+ if(This->flags & WINED3D_BUFFER_DOUBLEBUFFER)
+ {
+ if(!buffer_add_dirty_area(This, 0, 0))
+ {
+ ERR("buffer_add_dirty_area failed, this is not expected\n");
+ goto fail;
+ }
+ }
+ else
+ {
+ HeapFree(GetProcessHeap(), 0, This->resource.heapMemory);
+ This->resource.allocatedMemory = NULL;
+ This->resource.heapMemory = NULL;
+ }
+
+ return;
+
+fail:
+ /* Clean up all vbo init, but continue because we can work without a vbo :-) */
+ ERR("Failed to create a vertex buffer object. Continuing, but performance issues may occur\n");
+ delete_gl_buffer(This, gl_info);
+ buffer_clear_dirty_areas(This);
+}
+
+static BOOL buffer_process_converted_attribute(struct wined3d_buffer *This,
+ const enum wined3d_buffer_conversion_type conversion_type,
+ const struct wined3d_stream_info_element *attrib, DWORD *stride_this_run
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ , DWORD *offset_this_run
+#endif
+ )
+{
+ DWORD attrib_size;
+ BOOL ret = FALSE;
+ unsigned int i;
+#ifndef VBOX_WITH_WINE_FIX_BUFOFFSET
+ DWORD_PTR data;
+#else
+ UINT stream_offset = (UINT)(attrib->data.addr - attrib->offset);
+#endif
+
+ /* Check for some valid situations which cause us pain. One is if the buffer is used for
+ * constant attributes(stride = 0), the other one is if the buffer is used on two streams
+ * with different strides. In the 2nd case we might have to drop conversion entirely,
+ * it is possible that the same bytes are once read as FLOAT2 and once as UBYTE4N.
+ */
+ if (!attrib->stride)
+ {
+ FIXME("%s used with stride 0, let's hope we get the vertex stride from somewhere else\n",
+ debug_d3dformat(attrib->format->id));
+ }
+#ifndef VBOX_WITH_WINE_FIX_BUFOFFSET
+ else if(attrib->stride != *stride_this_run && *stride_this_run)
+ {
+ FIXME("Got two concurrent strides, %d and %d\n", attrib->stride, *stride_this_run);
+ }
+#else
+ else if((attrib->stride != *stride_this_run && *stride_this_run)
+ || (stream_offset != *offset_this_run && *offset_this_run))
+ {
+ ERR("Got two concurrent strides, %d and %d\n", attrib->stride, *stride_this_run);
+ }
+#endif
+ else
+ {
+ *stride_this_run = attrib->stride;
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ *offset_this_run = stream_offset;
+ if (This->stride != *stride_this_run
+ || This->offset != *offset_this_run)
+#else
+ if (This->stride != *stride_this_run)
+#endif
+ {
+ /* We rely that this happens only on the first converted attribute that is found,
+ * if at all. See above check
+ */
+ TRACE("Reconverting because converted attributes occur, and the stride changed\n");
+ This->stride = *stride_this_run;
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ This->offset = *offset_this_run;
+#endif
+ HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, This->conversion_map);
+ This->conversion_map = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof(*This->conversion_map) * This->stride);
+ ret = TRUE;
+ }
+ }
+
+#ifndef VBOX_WITH_WINE_FIX_BUFOFFSET
+ data = ((DWORD_PTR)attrib->data.addr) % This->stride;
+#endif
+ attrib_size = attrib->format->component_count * attrib->format->component_size;
+ for (i = 0; i < attrib_size; ++i)
+ {
+#ifndef VBOX_WITH_WINE_FIX_BUFOFFSET
+ DWORD_PTR idx = (data + i) % This->stride;
+#else
+ DWORD_PTR idx = attrib->offset;
+#endif
+ if (This->conversion_map[idx] != conversion_type)
+ {
+ TRACE("Byte %ld in vertex changed\n", idx);
+ TRACE("It was type %d, is %d now\n", This->conversion_map[idx], conversion_type);
+ ret = TRUE;
+ This->conversion_map[idx] = conversion_type;
+ }
+ }
+
+ return ret;
+}
+
+static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct wined3d_stream_info *si,
+ UINT attrib_idx, const BOOL check_d3dcolor, const BOOL check_position, const BOOL is_ffp_color,
+ DWORD *stride_this_run
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ , DWORD *offset_this_run
+#endif
+ )
+{
+ const struct wined3d_stream_info_element *attrib = &si->elements[attrib_idx];
+ enum wined3d_format_id format;
+ BOOL ret = FALSE;
+
+ /* Ignore attributes that do not have our vbo. After that check we can be sure that the attribute is
+ * there, on nonexistent attribs the vbo is 0.
+ */
+ if (!(si->use_map & (1 << attrib_idx))
+ || attrib->data.buffer_object != This->buffer_object)
+ return FALSE;
+
+ format = attrib->format->id;
+ /* Look for newly appeared conversion */
+ if (check_d3dcolor && format == WINED3DFMT_B8G8R8A8_UNORM)
+ {
+ ret = buffer_process_converted_attribute(This, CONV_D3DCOLOR, attrib, stride_this_run
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ , offset_this_run
+#endif
+ );
+
+ if (!is_ffp_color) FIXME("Test for non-color fixed function WINED3DFMT_B8G8R8A8_UNORM format\n");
+ }
+ else if (check_position && si->position_transformed)
+ {
+ if (format != WINED3DFMT_R32G32B32A32_FLOAT)
+ {
+ FIXME("Unexpected format %s for transformed position.\n", debug_d3dformat(format));
+ return FALSE;
+ }
+
+ ret = buffer_process_converted_attribute(This, CONV_POSITIONT, attrib, stride_this_run
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ , offset_this_run
+#endif
+ );
+ }
+ else if (This->conversion_map)
+ {
+ ret = buffer_process_converted_attribute(This, CONV_NONE, attrib, stride_this_run
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ , offset_this_run
+#endif
+ );
+ }
+
+ return ret;
+}
+
+static BOOL buffer_find_decl(struct wined3d_buffer *This)
+{
+ struct wined3d_device *device = This->resource.device;
+ const struct wined3d_adapter *adapter = device->adapter;
+ const struct wined3d_stream_info *si = &device->stream_info;
+ const struct wined3d_state *state = &device->stateBlock->state;
+ BOOL support_d3dcolor = adapter->gl_info.supported[ARB_VERTEX_ARRAY_BGRA];
+ BOOL support_xyzrhw = adapter->d3d_info.xyzrhw;
+ UINT stride_this_run = 0;
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ UINT offset_this_run = 0;
+#endif
+ BOOL ret = FALSE;
+
+ /* In d3d7 the vertex buffer declaration NEVER changes because it is stored in the d3d7 vertex buffer.
+ * Once we have our declaration there is no need to look it up again. Index buffers also never need
+ * conversion, so once the (empty) conversion structure is created don't bother checking again
+ */
+ if (This->flags & WINED3D_BUFFER_HASDESC)
+ {
+ if(This->resource.usage & WINED3DUSAGE_STATICDECL) return FALSE;
+ }
+
+ if (use_vs(state))
+ {
+ TRACE("Vertex shaders used, no VBO conversion is needed\n");
+ if(This->conversion_map)
+ {
+ HeapFree(GetProcessHeap(), 0, This->conversion_map);
+ This->conversion_map = NULL;
+ This->stride = 0;
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+ TRACE("Finding vertex buffer conversion information\n");
+ /* Certain declaration types need some fixups before we can pass them to
+ * opengl. This means D3DCOLOR attributes with fixed function vertex
+ * processing, FLOAT4 POSITIONT with fixed function, and FLOAT16 if
+ * GL_ARB_half_float_vertex is not supported.
+ *
+ * Note for d3d8 and d3d9:
+ * The vertex buffer FVF doesn't help with finding them, we have to use
+ * the decoded vertex declaration and pick the things that concern the
+ * current buffer. A problem with this is that this can change between
+ * draws, so we have to validate the information and reprocess the buffer
+ * if it changes, and avoid false positives for performance reasons.
+ * WineD3D doesn't even know the vertex buffer any more, it is managed
+ * by the client libraries and passed to SetStreamSource and ProcessVertices
+ * as needed.
+ *
+ * We have to distinguish between vertex shaders and fixed function to
+ * pick the way we access the strided vertex information.
+ *
+ * This code sets up a per-byte array with the size of the detected
+ * stride of the arrays in the buffer. For each byte we have a field
+ * that marks the conversion needed on this byte. For example, the
+ * following declaration with fixed function vertex processing:
+ *
+ * POSITIONT, FLOAT4
+ * NORMAL, FLOAT3
+ * DIFFUSE, FLOAT16_4
+ * SPECULAR, D3DCOLOR
+ *
+ * Will result in
+ * { POSITIONT }{ NORMAL }{ DIFFUSE }{SPECULAR }
+ * [P][P][P][P][P][P][P][P][P][P][P][P][P][P][P][P][0][0][0][0][0][0][0][0][0][0][0][0][F][F][F][F][F][F][F][F][C][C][C][C]
+ *
+ * Where in this example map P means 4 component position conversion, 0
+ * means no conversion, F means FLOAT16_2 conversion and C means D3DCOLOR
+ * conversion (red / blue swizzle).
+ *
+ * If we're doing conversion and the stride changes we have to reconvert
+ * the whole buffer. Note that we do not mind if the semantic changes,
+ * we only care for the conversion type. So if the NORMAL is replaced
+ * with a TEXCOORD, nothing has to be done, or if the DIFFUSE is replaced
+ * with a D3DCOLOR BLENDWEIGHT we can happily dismiss the change. Some
+ * conversion types depend on the semantic as well, for example a FLOAT4
+ * texcoord needs no conversion while a FLOAT4 positiont needs one
+ */
+
+ ret = buffer_check_attribute(This, si, WINED3D_FFP_POSITION,
+ TRUE, !support_xyzrhw, FALSE, &stride_this_run
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ , &offset_this_run
+#endif
+ ) || ret;
+ ret = buffer_check_attribute(This, si, WINED3D_FFP_NORMAL,
+ TRUE, FALSE, FALSE, &stride_this_run
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ , &offset_this_run
+#endif
+ ) || ret;
+ ret = buffer_check_attribute(This, si, WINED3D_FFP_DIFFUSE,
+ !support_d3dcolor, FALSE, TRUE, &stride_this_run
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ , &offset_this_run
+#endif
+ ) || ret;
+ ret = buffer_check_attribute(This, si, WINED3D_FFP_SPECULAR,
+ !support_d3dcolor, FALSE, TRUE, &stride_this_run
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ , &offset_this_run
+#endif
+ ) || ret;
+ ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD0,
+ TRUE, FALSE, FALSE, &stride_this_run
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ , &offset_this_run
+#endif
+ ) || ret;
+ ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD1,
+ TRUE, FALSE, FALSE, &stride_this_run
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ , &offset_this_run
+#endif
+ ) || ret;
+ ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD2,
+ TRUE, FALSE, FALSE, &stride_this_run
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ , &offset_this_run
+#endif
+ ) || ret;
+ ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD3,
+ TRUE, FALSE, FALSE, &stride_this_run
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ , &offset_this_run
+#endif
+ ) || ret;
+ ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD4,
+ TRUE, FALSE, FALSE, &stride_this_run
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ , &offset_this_run
+#endif
+ ) || ret;
+ ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD5,
+ TRUE, FALSE, FALSE, &stride_this_run
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ , &offset_this_run
+#endif
+ ) || ret;
+ ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD6,
+ TRUE, FALSE, FALSE, &stride_this_run
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ , &offset_this_run
+#endif
+ ) || ret;
+ ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD7,
+ TRUE, FALSE, FALSE, &stride_this_run
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ , &offset_this_run
+#endif
+ ) || ret;
+
+ if (!stride_this_run && This->conversion_map)
+ {
+ /* Sanity test */
+ if (!ret) ERR("no converted attributes found, old conversion map exists, and no declaration change?\n");
+ HeapFree(GetProcessHeap(), 0, This->conversion_map);
+ This->conversion_map = NULL;
+ This->stride = 0;
+ }
+
+ if (ret) TRACE("Conversion information changed\n");
+
+ return ret;
+}
+
+static inline void fixup_d3dcolor(DWORD *dst_color)
+{
+ DWORD src_color = *dst_color;
+
+ /* Color conversion like in drawStridedSlow. watch out for little endianity
+ * If we want that stuff to work on big endian machines too we have to consider more things
+ *
+ * 0xff000000: Alpha mask
+ * 0x00ff0000: Blue mask
+ * 0x0000ff00: Green mask
+ * 0x000000ff: Red mask
+ */
+ *dst_color = 0;
+ *dst_color |= (src_color & 0xff00ff00); /* Alpha Green */
+ *dst_color |= (src_color & 0x00ff0000) >> 16; /* Red */
+ *dst_color |= (src_color & 0x000000ff) << 16; /* Blue */
+}
+
+static inline void fixup_transformed_pos(float *p)
+{
+ /* rhw conversion like in position_float4(). */
+ if (p[3] != 1.0f && p[3] != 0.0f)
+ {
+ float w = 1.0f / p[3];
+ p[0] *= w;
+ p[1] *= w;
+ p[2] *= w;
+ p[3] = w;
+ }
+}
+
+/* Context activation is done by the caller. */
+void buffer_get_memory(struct wined3d_buffer *buffer, const struct wined3d_gl_info *gl_info,
+ struct wined3d_bo_address *data)
+{
+ data->buffer_object = buffer->buffer_object;
+ if (!buffer->buffer_object)
+ {
+ if ((buffer->flags & WINED3D_BUFFER_CREATEBO) && !buffer->resource.map_count)
+ {
+ buffer_create_buffer_object(buffer, gl_info);
+ buffer->flags &= ~WINED3D_BUFFER_CREATEBO;
+ if (buffer->buffer_object)
+ {
+ data->buffer_object = buffer->buffer_object;
+ data->addr = NULL;
+ return;
+ }
+ }
+ data->addr = buffer->resource.allocatedMemory;
+ }
+ else
+ {
+ data->addr = NULL;
+ }
+}
+
+ULONG CDECL wined3d_buffer_incref(struct wined3d_buffer *buffer)
+{
+ ULONG refcount = InterlockedIncrement(&buffer->resource.ref);
+
+ TRACE("%p increasing refcount to %u.\n", buffer, refcount);
+
+ return refcount;
+}
+
+/* Context activation is done by the caller. */
+BYTE *buffer_get_sysmem(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info)
+{
+ /* AllocatedMemory exists if the buffer is double buffered or has no buffer object at all */
+ if(This->resource.allocatedMemory) return This->resource.allocatedMemory;
+
+ This->resource.heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->resource.size + RESOURCE_ALIGNMENT);
+ This->resource.allocatedMemory = (BYTE *)(((ULONG_PTR)This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
+
+ if (This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
+ device_invalidate_state(This->resource.device, STATE_INDEXBUFFER);
+
+ GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
+ GL_EXTCALL(glGetBufferSubDataARB(This->buffer_type_hint, 0, This->resource.size, This->resource.allocatedMemory));
+ This->flags |= WINED3D_BUFFER_DOUBLEBUFFER;
+
+ return This->resource.allocatedMemory;
+}
+
+/* Do not call while under the GL lock. */
+static void buffer_unload(struct wined3d_resource *resource)
+{
+ struct wined3d_buffer *buffer = buffer_from_resource(resource);
+
+ TRACE("buffer %p.\n", buffer);
+
+ if (buffer->buffer_object)
+ {
+ struct wined3d_device *device = resource->device;
+ struct wined3d_context *context;
+
+ context = context_acquire(device, NULL);
+
+ /* Download the buffer, but don't permanently enable double buffering */
+ if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER))
+ {
+ buffer_get_sysmem(buffer, context->gl_info);
+ buffer->flags &= ~WINED3D_BUFFER_DOUBLEBUFFER;
+ }
+
+ delete_gl_buffer(buffer, context->gl_info);
+ buffer->flags |= WINED3D_BUFFER_CREATEBO; /* Recreate the buffer object next load */
+ buffer_clear_dirty_areas(buffer);
+
+ context_release(context);
+
+ HeapFree(GetProcessHeap(), 0, buffer->conversion_map);
+ buffer->conversion_map = NULL;
+ buffer->stride = 0;
+ buffer->conversion_stride = 0;
+ buffer->flags &= ~WINED3D_BUFFER_HASDESC;
+ }
+
+ resource_unload(resource);
+}
+
+/* Do not call while under the GL lock. */
+ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer)
+{
+ ULONG refcount = InterlockedDecrement(&buffer->resource.ref);
+
+ TRACE("%p decreasing refcount to %u.\n", buffer, refcount);
+
+ if (!refcount)
+ {
+ buffer_unload(&buffer->resource);
+ resource_cleanup(&buffer->resource);
+ buffer->resource.parent_ops->wined3d_object_destroyed(buffer->resource.parent);
+ HeapFree(GetProcessHeap(), 0, buffer->maps);
+ HeapFree(GetProcessHeap(), 0, buffer);
+ }
+
+ return refcount;
+}
+
+void * CDECL wined3d_buffer_get_parent(const struct wined3d_buffer *buffer)
+{
+ TRACE("buffer %p.\n", buffer);
+
+ return buffer->resource.parent;
+}
+
+DWORD CDECL wined3d_buffer_set_priority(struct wined3d_buffer *buffer, DWORD priority)
+{
+ return resource_set_priority(&buffer->resource, priority);
+}
+
+DWORD CDECL wined3d_buffer_get_priority(const struct wined3d_buffer *buffer)
+{
+ return resource_get_priority(&buffer->resource);
+}
+
+/* The caller provides a context and binds the buffer */
+static void buffer_sync_apple(struct wined3d_buffer *This, DWORD flags, const struct wined3d_gl_info *gl_info)
+{
+ enum wined3d_event_query_result ret;
+
+ /* No fencing needs to be done if the app promises not to overwrite
+ * existing data. */
+ if (flags & WINED3D_MAP_NOOVERWRITE)
+ return;
+
+ if (flags & WINED3D_MAP_DISCARD)
+ {
+ GL_EXTCALL(glBufferDataARB(This->buffer_type_hint, This->resource.size, NULL, This->buffer_object_usage));
+ checkGLcall("glBufferDataARB\n");
+ return;
+ }
+
+ if(!This->query)
+ {
+ TRACE("Creating event query for buffer %p\n", This);
+
+ if (!wined3d_event_query_supported(gl_info))
+ {
+ FIXME("Event queries not supported, dropping async buffer locks.\n");
+ goto drop_query;
+ }
+
+ This->query = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This->query));
+ if (!This->query)
+ {
+ ERR("Failed to allocate event query memory, dropping async buffer locks.\n");
+ goto drop_query;
+ }
+
+ /* Since we don't know about old draws a glFinish is needed once */
+ gl_info->gl_ops.gl.p_glFinish();
+ return;
+ }
+ TRACE("Synchronizing buffer %p\n", This);
+ ret = wined3d_event_query_finish(This->query, This->resource.device);
+ switch(ret)
+ {
+ case WINED3D_EVENT_QUERY_NOT_STARTED:
+ case WINED3D_EVENT_QUERY_OK:
+ /* All done */
+ return;
+
+ case WINED3D_EVENT_QUERY_WRONG_THREAD:
+ WARN("Cannot synchronize buffer lock due to a thread conflict\n");
+ goto drop_query;
+
+ default:
+ ERR("wined3d_event_query_finish returned %u, dropping async buffer locks\n", ret);
+ goto drop_query;
+ }
+
+drop_query:
+ if(This->query)
+ {
+ wined3d_event_query_destroy(This->query);
+ This->query = NULL;
+ }
+
+ gl_info->gl_ops.gl.p_glFinish();
+ GL_EXTCALL(glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE));
+ checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE)");
+ This->flags &= ~WINED3D_BUFFER_APPLESYNC;
+}
+
+/* The caller provides a GL context */
+static void buffer_direct_upload(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info, DWORD flags)
+{
+ BYTE *map;
+ UINT start = 0, len = 0;
+
+ /* This potentially invalidates the element array buffer binding, but the
+ * caller always takes care of this. */
+ GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
+ checkGLcall("glBindBufferARB");
+ if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
+ {
+ GLbitfield mapflags;
+ mapflags = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
+ if (flags & WINED3D_BUFFER_DISCARD)
+ mapflags |= GL_MAP_INVALIDATE_BUFFER_BIT;
+ if (flags & WINED3D_BUFFER_NOSYNC)
+ mapflags |= GL_MAP_UNSYNCHRONIZED_BIT;
+ map = GL_EXTCALL(glMapBufferRange(This->buffer_type_hint, 0,
+ This->resource.size, mapflags));
+ checkGLcall("glMapBufferRange");
+ }
+ else
+ {
+ if (This->flags & WINED3D_BUFFER_APPLESYNC)
+ {
+ DWORD syncflags = 0;
+ if (flags & WINED3D_BUFFER_DISCARD)
+ syncflags |= WINED3D_MAP_DISCARD;
+ if (flags & WINED3D_BUFFER_NOSYNC)
+ syncflags |= WINED3D_MAP_NOOVERWRITE;
+ buffer_sync_apple(This, syncflags, gl_info);
+ }
+ map = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_WRITE_ONLY_ARB));
+ checkGLcall("glMapBufferARB");
+ }
+ if (!map)
+ {
+ ERR("Failed to map opengl buffer\n");
+ return;
+ }
+
+ while (This->modified_areas)
+ {
+ This->modified_areas--;
+ start = This->maps[This->modified_areas].offset;
+ len = This->maps[This->modified_areas].size;
+
+ memcpy(map + start, This->resource.allocatedMemory + start, len);
+
+ if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
+ {
+ GL_EXTCALL(glFlushMappedBufferRange(This->buffer_type_hint, start, len));
+ checkGLcall("glFlushMappedBufferRange");
+ }
+ else if (This->flags & WINED3D_BUFFER_FLUSH)
+ {
+ GL_EXTCALL(glFlushMappedBufferRangeAPPLE(This->buffer_type_hint, start, len));
+ checkGLcall("glFlushMappedBufferRangeAPPLE");
+ }
+ }
+ GL_EXTCALL(glUnmapBufferARB(This->buffer_type_hint));
+ checkGLcall("glUnmapBufferARB");
+}
+
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+static UINT wined3d_buffer_stream_offset_left(UINT x, UINT offset, UINT stride)
+{
+ UINT off = ((UINT)(RT_ABS((INT)(x - offset))) % stride);
+ if (!off)
+ return x;
+ if (x > offset)
+ return x - off;
+
+ /* x < offset */
+ return x - stride + off;
+}
+
+static UINT wined3d_buffer_stream_offset_right(UINT x, UINT offset, UINT stride)
+{
+ UINT left = wined3d_buffer_stream_offset_left(x, offset, stride);
+
+ if (left == x)
+ return x;
+ return left + stride;
+}
+#endif
+
+/* Do not call while under the GL lock. */
+void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer)
+{
+ DWORD flags = buffer->flags & (WINED3D_BUFFER_NOSYNC | WINED3D_BUFFER_DISCARD);
+ struct wined3d_device *device = buffer->resource.device;
+ UINT start = 0, end = 0, len = 0, vertices;
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+ BOOL decl_changed = FALSE;
+ unsigned int i, j;
+ BYTE *data;
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ BYTE *cur_ptr;
+ UINT conv_start, conv_end;
+#endif
+
+ TRACE("buffer %p.\n", buffer);
+
+ if (buffer->resource.map_count)
+ {
+ WARN("Buffer is mapped, skipping preload.\n");
+ return;
+ }
+
+ buffer->flags &= ~(WINED3D_BUFFER_NOSYNC | WINED3D_BUFFER_DISCARD);
+
+ if (!buffer->buffer_object)
+ {
+ /* TODO: Make converting independent from VBOs */
+ if (buffer->flags & WINED3D_BUFFER_CREATEBO)
+ {
+ context = context_acquire(device, NULL);
+ buffer_create_buffer_object(buffer, context->gl_info);
+ context_release(context);
+ buffer->flags &= ~WINED3D_BUFFER_CREATEBO;
+ }
+ else
+ {
+ /* Not doing any conversion */
+ return;
+ }
+ }
+
+ /* Reading the declaration makes only sense if the stateblock is finalized and the buffer bound to a stream */
+ if (device->isInDraw && buffer->resource.bind_count > 0)
+ {
+ decl_changed = buffer_find_decl(buffer);
+ buffer->flags |= WINED3D_BUFFER_HASDESC;
+ }
+
+ if (!decl_changed && !(buffer->flags & WINED3D_BUFFER_HASDESC && buffer_is_dirty(buffer)))
+ {
+ ++buffer->draw_count;
+ if (buffer->draw_count > VB_RESETDECLCHANGE)
+ buffer->decl_change_count = 0;
+ if (buffer->draw_count > VB_RESETFULLCONVS)
+ buffer->full_conversion_count = 0;
+ return;
+ }
+
+ /* If applications change the declaration over and over, reconverting all the time is a huge
+ * performance hit. So count the declaration changes and release the VBO if there are too many
+ * of them (and thus stop converting)
+ */
+ if (decl_changed)
+ {
+ ++buffer->decl_change_count;
+ buffer->draw_count = 0;
+
+ if (buffer->decl_change_count > VB_MAXDECLCHANGES
+ || (buffer->conversion_map && (buffer->resource.usage & WINED3DUSAGE_DYNAMIC)))
+ {
+ FIXME("Too many declaration changes or converting dynamic buffer, stopping converting\n");
+
+ buffer_unload(&buffer->resource);
+ buffer->flags &= ~WINED3D_BUFFER_CREATEBO;
+
+ /* The stream source state handler might have read the memory of
+ * the vertex buffer already and got the memory in the vbo which
+ * is not valid any longer. Dirtify the stream source to force a
+ * reload. This happens only once per changed vertexbuffer and
+ * should occur rather rarely. */
+ device_invalidate_state(device, STATE_STREAMSRC);
+ return;
+ }
+
+ /* The declaration changed, reload the whole buffer */
+ WARN("Reloading buffer because of decl change\n");
+ buffer_clear_dirty_areas(buffer);
+ if (!buffer_add_dirty_area(buffer, 0, 0))
+ {
+ ERR("buffer_add_dirty_area failed, this is not expected\n");
+ return;
+ }
+ /* Avoid unfenced updates, we might overwrite more areas of the buffer than the application
+ * cleared for unsynchronized updates
+ */
+ flags = 0;
+ }
+ else
+ {
+ /* However, it is perfectly fine to change the declaration every now and then. We don't want a game that
+ * changes it every minute drop the VBO after VB_MAX_DECL_CHANGES minutes. So count draws without
+ * decl changes and reset the decl change count after a specific number of them
+ */
+ if (buffer->conversion_map && buffer_is_fully_dirty(buffer))
+ {
+ ++buffer->full_conversion_count;
+ if (buffer->full_conversion_count > VB_MAXFULLCONVERSIONS)
+ {
+ FIXME("Too many full buffer conversions, stopping converting.\n");
+ buffer_unload(&buffer->resource);
+ buffer->flags &= ~WINED3D_BUFFER_CREATEBO;
+ if (buffer->resource.bind_count)
+ device_invalidate_state(device, STATE_STREAMSRC);
+ return;
+ }
+ }
+ else
+ {
+ ++buffer->draw_count;
+ if (buffer->draw_count > VB_RESETDECLCHANGE)
+ buffer->decl_change_count = 0;
+ if (buffer->draw_count > VB_RESETFULLCONVS)
+ buffer->full_conversion_count = 0;
+ }
+ }
+
+ if (buffer->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
+ device_invalidate_state(device, STATE_INDEXBUFFER);
+
+ if (!buffer->conversion_map)
+ {
+ /* That means that there is nothing to fixup. Just upload from
+ * buffer->resource.allocatedMemory directly into the vbo. Do not
+ * free the system memory copy because drawPrimitive may need it if
+ * the stride is 0, for instancing emulation, vertex blending
+ * emulation or shader emulation. */
+ TRACE("No conversion needed.\n");
+
+ /* Nothing to do because we locked directly into the vbo */
+ if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER))
+ {
+ return;
+ }
+
+ context = context_acquire(device, NULL);
+ buffer_direct_upload(buffer, context->gl_info, flags);
+
+ context_release(context);
+ return;
+ }
+
+ context = context_acquire(device, NULL);
+ gl_info = context->gl_info;
+
+ if(!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER))
+ {
+ buffer_get_sysmem(buffer, gl_info);
+ }
+
+ /* Now for each vertex in the buffer that needs conversion */
+ vertices = buffer->resource.size / buffer->stride;
+
+ data = HeapAlloc(GetProcessHeap(), 0, buffer->resource.size);
+
+ while(buffer->modified_areas)
+ {
+ buffer->modified_areas--;
+ start = buffer->maps[buffer->modified_areas].offset;
+ len = buffer->maps[buffer->modified_areas].size;
+ end = start + len;
+
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ if (buffer->offset > UINT32_MAX)
+ {
+ ERR("negative offset, unexpected!");
+ }
+
+ conv_start = wined3d_buffer_stream_offset_left(start, buffer->offset, buffer->stride);
+ if (conv_start <= start)
+ {
+ start = conv_start;
+ }
+ else
+ {
+ /* <- < 0, add stride */
+ conv_start += buffer->stride;
+ }
+
+ Assert(conv_start < UINT32_MAX/3);
+
+ conv_end = wined3d_buffer_stream_offset_right(end, buffer->offset, buffer->stride);
+ if (conv_end > end)
+ {
+ if (conv_end <= buffer->resource.size)
+ end = conv_end;
+ else
+ conv_end -= buffer->stride;
+ }
+ else if (conv_end < end)
+ {
+ ERR("unexpected!");
+ }
+ else
+ {
+ end = conv_end;
+ }
+#endif
+ memcpy(data + start, buffer->resource.allocatedMemory + start, end - start);
+
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ for (cur_ptr = data + conv_start; cur_ptr < data + conv_end; cur_ptr += buffer->stride)
+#else
+ for (i = start / buffer->stride; i < min((end / buffer->stride) + 1, vertices); ++i)
+#endif
+ {
+ for (j = 0; j < buffer->stride; ++j)
+ {
+ switch (buffer->conversion_map[j])
+ {
+ case CONV_NONE:
+ /* Done already */
+ j += 3;
+ break;
+ case CONV_D3DCOLOR:
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ fixup_d3dcolor((DWORD *) (cur_ptr + j));
+#else
+ fixup_d3dcolor((DWORD *) (data + i * buffer->stride + j));
+#endif
+ j += 3;
+ break;
+
+ case CONV_POSITIONT:
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ fixup_transformed_pos((float *) (cur_ptr + j));
+#else
+ fixup_transformed_pos((float *) (data + i * buffer->stride + j));
+#endif
+ j += 15;
+ break;
+ default:
+ FIXME("Unimplemented conversion %d in shifted conversion\n", buffer->conversion_map[j]);
+ }
+ }
+ }
+
+ GL_EXTCALL(glBindBufferARB(buffer->buffer_type_hint, buffer->buffer_object));
+ checkGLcall("glBindBufferARB");
+ GL_EXTCALL(glBufferSubDataARB(buffer->buffer_type_hint, start, len, data + start));
+ checkGLcall("glBufferSubDataARB");
+ }
+
+ HeapFree(GetProcessHeap(), 0, data);
+ context_release(context);
+}
+
+static DWORD buffer_sanitize_flags(const struct wined3d_buffer *buffer, DWORD flags)
+{
+ /* Not all flags make sense together, but Windows never returns an error.
+ * Catch the cases that could cause issues. */
+ if (flags & WINED3D_MAP_READONLY)
+ {
+ if (flags & WINED3D_MAP_DISCARD)
+ {
+ WARN("WINED3D_MAP_READONLY combined with WINED3D_MAP_DISCARD, ignoring flags.\n");
+ return 0;
+ }
+ if (flags & WINED3D_MAP_NOOVERWRITE)
+ {
+ WARN("WINED3D_MAP_READONLY combined with WINED3D_MAP_NOOVERWRITE, ignoring flags.\n");
+ return 0;
+ }
+ }
+ else if ((flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
+ == (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
+ {
+ WARN("WINED3D_MAP_DISCARD and WINED3D_MAP_NOOVERWRITE used together, ignoring.\n");
+ return 0;
+ }
+ else if (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)
+ && !(buffer->resource.usage & WINED3DUSAGE_DYNAMIC))
+ {
+ WARN("DISCARD or NOOVERWRITE map on non-dynamic buffer, ignoring.\n");
+ return 0;
+ }
+
+ return flags;
+}
+
+static GLbitfield buffer_gl_map_flags(DWORD d3d_flags)
+{
+ GLbitfield ret = 0;
+
+ if (!(d3d_flags & WINED3D_MAP_READONLY))
+ ret |= GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
+ if (!(d3d_flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)))
+ ret |= GL_MAP_READ_BIT;
+
+ if (d3d_flags & WINED3D_MAP_DISCARD)
+ ret |= GL_MAP_INVALIDATE_BUFFER_BIT;
+ if (d3d_flags & WINED3D_MAP_NOOVERWRITE)
+ ret |= GL_MAP_UNSYNCHRONIZED_BIT;
+
+ return ret;
+}
+
+struct wined3d_resource * CDECL wined3d_buffer_get_resource(struct wined3d_buffer *buffer)
+{
+ TRACE("buffer %p.\n", buffer);
+
+ return &buffer->resource;
+}
+
+HRESULT CDECL wined3d_buffer_map(struct wined3d_buffer *buffer, UINT offset, UINT size, BYTE **data, DWORD flags)
+{
+ BOOL dirty = buffer_is_dirty(buffer);
+ LONG count;
+
+ TRACE("buffer %p, offset %u, size %u, data %p, flags %#x\n", buffer, offset, size, data, flags);
+
+ flags = buffer_sanitize_flags(buffer, flags);
+ if (flags & WINED3D_MAP_DISCARD)
+ {
+ /* DISCARD invalidates the entire buffer, regardless of the specified
+ * offset and size. Some applications also depend on the entire buffer
+ * being uploaded in that case. Two such applications are Port Royale
+ * and Darkstar One. */
+ if (!buffer_add_dirty_area(buffer, 0, 0))
+ return E_OUTOFMEMORY;
+ }
+ else if (!(flags & WINED3D_MAP_READONLY))
+ {
+ if (!buffer_add_dirty_area(buffer, offset, size))
+ return E_OUTOFMEMORY;
+ }
+
+ count = ++buffer->resource.map_count;
+
+ if (buffer->buffer_object)
+ {
+ if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER))
+ {
+ if (count == 1)
+ {
+ struct wined3d_device *device = buffer->resource.device;
+ struct wined3d_context *context;
+ const struct wined3d_gl_info *gl_info;
+
+ context = context_acquire(device, NULL);
+ gl_info = context->gl_info;
+
+ if (buffer->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
+ context_invalidate_state(context, STATE_INDEXBUFFER);
+ GL_EXTCALL(glBindBufferARB(buffer->buffer_type_hint, buffer->buffer_object));
+
+ if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
+ {
+ GLbitfield mapflags = buffer_gl_map_flags(flags);
+ buffer->resource.allocatedMemory = GL_EXTCALL(glMapBufferRange(buffer->buffer_type_hint,
+ 0, buffer->resource.size, mapflags));
+ checkGLcall("glMapBufferRange");
+ }
+ else
+ {
+ if (buffer->flags & WINED3D_BUFFER_APPLESYNC)
+ buffer_sync_apple(buffer, flags, gl_info);
+ buffer->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(buffer->buffer_type_hint,
+ GL_READ_WRITE_ARB));
+ checkGLcall("glMapBufferARB");
+ }
+
+ if (((DWORD_PTR)buffer->resource.allocatedMemory) & (RESOURCE_ALIGNMENT - 1))
+ {
+ WARN("Pointer %p is not %u byte aligned.\n", buffer->resource.allocatedMemory, RESOURCE_ALIGNMENT);
+
+ GL_EXTCALL(glUnmapBufferARB(buffer->buffer_type_hint));
+ checkGLcall("glUnmapBufferARB");
+ buffer->resource.allocatedMemory = NULL;
+
+ if (buffer->resource.usage & WINED3DUSAGE_DYNAMIC)
+ {
+ /* The extra copy is more expensive than not using VBOs at
+ * all on the Nvidia Linux driver, which is the only driver
+ * that returns unaligned pointers
+ */
+ TRACE("Dynamic buffer, dropping VBO\n");
+ buffer_unload(&buffer->resource);
+ buffer->flags &= ~WINED3D_BUFFER_CREATEBO;
+ if (buffer->resource.bind_count)
+ device_invalidate_state(device, STATE_STREAMSRC);
+ }
+ else
+ {
+ TRACE("Falling back to doublebuffered operation\n");
+ buffer_get_sysmem(buffer, gl_info);
+ }
+ TRACE("New pointer is %p.\n", buffer->resource.allocatedMemory);
+ }
+ context_release(context);
+ }
+ }
+ else
+ {
+ if (dirty)
+ {
+ if (buffer->flags & WINED3D_BUFFER_NOSYNC && !(flags & WINED3D_MAP_NOOVERWRITE))
+ {
+ buffer->flags &= ~WINED3D_BUFFER_NOSYNC;
+ }
+ }
+ else if(flags & WINED3D_MAP_NOOVERWRITE)
+ {
+ buffer->flags |= WINED3D_BUFFER_NOSYNC;
+ }
+
+ if (flags & WINED3D_MAP_DISCARD)
+ {
+ buffer->flags |= WINED3D_BUFFER_DISCARD;
+ }
+ }
+ }
+
+ *data = buffer->resource.allocatedMemory + offset;
+
+ TRACE("Returning memory at %p (base %p, offset %u).\n", *data, buffer->resource.allocatedMemory, offset);
+ /* TODO: check Flags compatibility with buffer->currentDesc.Usage (see MSDN) */
+
+ return WINED3D_OK;
+}
+
+void CDECL wined3d_buffer_unmap(struct wined3d_buffer *buffer)
+{
+ ULONG i;
+
+ TRACE("buffer %p.\n", buffer);
+
+ /* In the case that the number of Unmap calls > the
+ * number of Map calls, d3d returns always D3D_OK.
+ * This is also needed to prevent Map from returning garbage on
+ * the next call (this will happen if the lock_count is < 0). */
+ if (!buffer->resource.map_count)
+ {
+ WARN("Unmap called without a previous map call.\n");
+ return;
+ }
+
+ if (--buffer->resource.map_count)
+ {
+ /* Delay loading the buffer until everything is unlocked */
+ TRACE("Ignoring unmap.\n");
+ return;
+ }
+
+ if (!(buffer->flags & WINED3D_BUFFER_DOUBLEBUFFER) && buffer->buffer_object)
+ {
+ struct wined3d_device *device = buffer->resource.device;
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+
+ context = context_acquire(device, NULL);
+ gl_info = context->gl_info;
+
+ if (buffer->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
+ context_invalidate_state(context, STATE_INDEXBUFFER);
+ GL_EXTCALL(glBindBufferARB(buffer->buffer_type_hint, buffer->buffer_object));
+
+ if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
+ {
+ for (i = 0; i < buffer->modified_areas; ++i)
+ {
+ GL_EXTCALL(glFlushMappedBufferRange(buffer->buffer_type_hint,
+ buffer->maps[i].offset, buffer->maps[i].size));
+ checkGLcall("glFlushMappedBufferRange");
+ }
+ }
+ else if (buffer->flags & WINED3D_BUFFER_FLUSH)
+ {
+ for (i = 0; i < buffer->modified_areas; ++i)
+ {
+ GL_EXTCALL(glFlushMappedBufferRangeAPPLE(buffer->buffer_type_hint,
+ buffer->maps[i].offset, buffer->maps[i].size));
+ checkGLcall("glFlushMappedBufferRangeAPPLE");
+ }
+ }
+
+ GL_EXTCALL(glUnmapBufferARB(buffer->buffer_type_hint));
+ if (wined3d_settings.strict_draw_ordering)
+ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
+ context_release(context);
+
+ buffer->resource.allocatedMemory = NULL;
+ buffer_clear_dirty_areas(buffer);
+ }
+ else if (buffer->flags & WINED3D_BUFFER_HASDESC)
+ {
+ wined3d_buffer_preload(buffer);
+ }
+}
+
+static const struct wined3d_resource_ops buffer_resource_ops =
+{
+ buffer_unload,
+};
+
+static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device *device,
+ UINT size, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool, GLenum bind_hint,
+ const char *data, void *parent, const struct wined3d_parent_ops *parent_ops)
+{
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ const struct wined3d_format *format = wined3d_get_format(gl_info, format_id);
+ HRESULT hr;
+ BOOL dynamic_buffer_ok;
+
+ if (!size)
+ {
+ WARN("Size 0 requested, returning WINED3DERR_INVALIDCALL\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ hr = resource_init(&buffer->resource, device, WINED3D_RTYPE_BUFFER, format,
+ WINED3D_MULTISAMPLE_NONE, 0, usage, pool, size, 1, 1, size,
+ parent, parent_ops, &buffer_resource_ops
+#ifdef VBOX_WITH_WDDM
+ , NULL, NULL /* <- no need this info here so far */
+#endif
+ );
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize resource, hr %#x\n", hr);
+ return hr;
+ }
+ buffer->buffer_type_hint = bind_hint;
+
+ TRACE("size %#x, usage %#x, format %s, memory @ %p, iface @ %p.\n", buffer->resource.size, buffer->resource.usage,
+ debug_d3dformat(buffer->resource.format->id), buffer->resource.allocatedMemory, buffer);
+
+ if (device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING)
+ {
+ /* SWvp always returns the same pointer in buffer maps and retains data in DISCARD maps.
+ * Keep a system memory copy of the buffer to provide the same behavior to the application.
+ * Still use a VBO to support OpenGL 3 core contexts. */
+ TRACE("Using doublebuffer mode because of software vertex processing\n");
+ buffer->flags |= WINED3D_BUFFER_DOUBLEBUFFER;
+ }
+
+ dynamic_buffer_ok = gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] || gl_info->supported[ARB_MAP_BUFFER_RANGE];
+
+ /* Observations show that drawStridedSlow is faster on dynamic VBs than converting +
+ * drawStridedFast (half-life 2 and others).
+ *
+ * Basically converting the vertices in the buffer is quite expensive, and observations
+ * show that drawStridedSlow is faster than converting + uploading + drawStridedFast.
+ * Therefore do not create a VBO for WINED3DUSAGE_DYNAMIC buffers.
+ */
+ if (!gl_info->supported[ARB_VERTEX_BUFFER_OBJECT])
+ {
+ TRACE("Not creating a vbo because GL_ARB_vertex_buffer is not supported\n");
+ }
+#ifndef VBOX_WITH_WDDM /* @todo: extend this to VBOX in general */
+ else if(buffer->resource.pool == WINED3D_POOL_SYSTEM_MEM)
+ {
+ TRACE("Not creating a vbo because the vertex buffer is in system memory\n");
+ }
+ else if(!dynamic_buffer_ok && (buffer->resource.usage & WINED3DUSAGE_DYNAMIC))
+ {
+ TRACE("Not creating a vbo because the buffer has dynamic usage and no GL support\n");
+ }
+#endif
+ else
+ {
+ buffer->flags |= WINED3D_BUFFER_CREATEBO;
+ }
+
+ if (data)
+ {
+ BYTE *ptr;
+
+ hr = wined3d_buffer_map(buffer, 0, size, &ptr, 0);
+ if (FAILED(hr))
+ {
+ ERR("Failed to map buffer, hr %#x\n", hr);
+ buffer_unload(&buffer->resource);
+ resource_cleanup(&buffer->resource);
+ return hr;
+ }
+
+ memcpy(ptr, data, size);
+
+ wined3d_buffer_unmap(buffer);
+ }
+
+ buffer->maps = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer->maps));
+ if (!buffer->maps)
+ {
+ ERR("Out of memory\n");
+ buffer_unload(&buffer->resource);
+ resource_cleanup(&buffer->resource);
+ return E_OUTOFMEMORY;
+ }
+ buffer->maps_size = 1;
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_buffer_create(struct wined3d_device *device, struct wined3d_buffer_desc *desc, const void *data,
+ void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_buffer **buffer)
+{
+ struct wined3d_buffer *object;
+ HRESULT hr;
+
+ TRACE("device %p, desc %p, data %p, parent %p, buffer %p\n", device, desc, data, parent, buffer);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ FIXME("Ignoring access flags (pool)\n");
+
+ hr = buffer_init(object, device, desc->byte_width, desc->usage, WINED3DFMT_UNKNOWN,
+ WINED3D_POOL_MANAGED, GL_ARRAY_BUFFER_ARB, data, parent, parent_ops);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize buffer, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+ object->desc = *desc;
+
+ TRACE("Created buffer %p.\n", object);
+
+ *buffer = object;
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_buffer_create_vb(struct wined3d_device *device, UINT size, DWORD usage, enum wined3d_pool pool,
+ void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_buffer **buffer)
+{
+ struct wined3d_buffer *object;
+ HRESULT hr;
+
+ TRACE("device %p, size %u, usage %#x, pool %#x, parent %p, parent_ops %p, buffer %p.\n",
+ device, size, usage, pool, parent, parent_ops, buffer);
+
+ if (pool == WINED3D_POOL_SCRATCH)
+ {
+ /* The d3d9 tests shows that this is not allowed. It doesn't make much
+ * sense anyway, SCRATCH buffers wouldn't be usable anywhere. */
+ WARN("Vertex buffer in WINED3D_POOL_SCRATCH requested, returning WINED3DERR_INVALIDCALL.\n");
+ *buffer = NULL;
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ {
+ *buffer = NULL;
+ return WINED3DERR_OUTOFVIDEOMEMORY;
+ }
+
+ hr = buffer_init(object, device, size, usage, WINED3DFMT_VERTEXDATA,
+ pool, GL_ARRAY_BUFFER_ARB, NULL, parent, parent_ops);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize buffer, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created buffer %p.\n", object);
+ *buffer = object;
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_buffer_create_ib(struct wined3d_device *device, UINT size, DWORD usage, enum wined3d_pool pool,
+ void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_buffer **buffer)
+{
+ struct wined3d_buffer *object;
+ HRESULT hr;
+
+ TRACE("device %p, size %u, usage %#x, pool %#x, parent %p, parent_ops %p, buffer %p.\n",
+ device, size, usage, pool, parent, parent_ops, buffer);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ {
+ *buffer = NULL;
+ return WINED3DERR_OUTOFVIDEOMEMORY;
+ }
+
+ hr = buffer_init(object, device, size, usage | WINED3DUSAGE_STATICDECL,
+ WINED3DFMT_UNKNOWN, pool, GL_ELEMENT_ARRAY_BUFFER_ARB, NULL,
+ parent, parent_ops);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize buffer, hr %#x\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created buffer %p.\n", object);
+ *buffer = object;
+
+ return WINED3D_OK;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/context.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/context.c
new file mode 100644
index 00000000..d9224a17
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/context.c
@@ -0,0 +1,2987 @@
+/*
+ * Context and render target management in wined3d
+ *
+ * Copyright 2007-2011, 2013 Stefan Dösinger for CodeWeavers
+ * Copyright 2009-2011 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
+#ifdef HAVE_FLOAT_H
+# include <float.h>
+#endif
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_synchronous);
+
+static DWORD wined3d_context_tls_idx;
+
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+# define vboxGetCurrentContext() VBoxTlsRefGetCurrent(struct wined3d_context, wined3d_context_tls_idx)
+# define vboxSetCurrentContext(_ctx) VBoxTlsRefSetCurrent(struct wined3d_context, wined3d_context_tls_idx, (_ctx))
+#endif
+
+/* FBO helper functions */
+
+/* Context activation is done by the caller. */
+static void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint fbo)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ switch (target)
+ {
+ case GL_READ_FRAMEBUFFER:
+ if (context->fbo_read_binding == fbo) return;
+ context->fbo_read_binding = fbo;
+ break;
+
+ case GL_DRAW_FRAMEBUFFER:
+ if (context->fbo_draw_binding == fbo) return;
+ context->fbo_draw_binding = fbo;
+ break;
+
+ case GL_FRAMEBUFFER:
+ if (context->fbo_read_binding == fbo
+ && context->fbo_draw_binding == fbo) return;
+ context->fbo_read_binding = fbo;
+ context->fbo_draw_binding = fbo;
+ break;
+
+ default:
+ FIXME("Unhandled target %#x.\n", target);
+ break;
+ }
+
+ gl_info->fbo_ops.glBindFramebuffer(target, fbo);
+ checkGLcall("glBindFramebuffer()");
+}
+
+/* Context activation is done by the caller. */
+static void context_clean_fbo_attachments(const struct wined3d_gl_info *gl_info, GLenum target)
+{
+ unsigned int i;
+
+ for (i = 0; i < gl_info->limits.buffers; ++i)
+ {
+ gl_info->fbo_ops.glFramebufferTexture2D(target, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 0, 0);
+ checkGLcall("glFramebufferTexture2D()");
+ }
+ gl_info->fbo_ops.glFramebufferTexture2D(target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
+ checkGLcall("glFramebufferTexture2D()");
+
+ gl_info->fbo_ops.glFramebufferTexture2D(target, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
+ checkGLcall("glFramebufferTexture2D()");
+}
+
+/* Context activation is done by the caller. */
+static void context_destroy_fbo(struct wined3d_context *context, GLuint fbo)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ context_bind_fbo(context, GL_FRAMEBUFFER, fbo);
+ context_clean_fbo_attachments(gl_info, GL_FRAMEBUFFER);
+ context_bind_fbo(context, GL_FRAMEBUFFER, 0);
+
+ gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
+ checkGLcall("glDeleteFramebuffers()");
+}
+
+static void context_attach_depth_stencil_rb(const struct wined3d_gl_info *gl_info,
+ GLenum fbo_target, DWORD format_flags, GLuint rb)
+{
+ if (format_flags & WINED3DFMT_FLAG_DEPTH)
+ {
+ gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
+ checkGLcall("glFramebufferRenderbuffer()");
+ }
+
+ if (format_flags & WINED3DFMT_FLAG_STENCIL)
+ {
+ gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
+ checkGLcall("glFramebufferRenderbuffer()");
+ }
+}
+
+/* Context activation is done by the caller. */
+static void context_attach_depth_stencil_fbo(struct wined3d_context *context,
+ GLenum fbo_target, struct wined3d_surface *depth_stencil, DWORD location)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ TRACE("Attach depth stencil %p\n", depth_stencil);
+
+ if (depth_stencil)
+ {
+ DWORD format_flags = depth_stencil->resource.format->flags;
+
+ if (depth_stencil->current_renderbuffer)
+ {
+ context_attach_depth_stencil_rb(gl_info, fbo_target,
+ format_flags, depth_stencil->current_renderbuffer->id);
+ }
+ else
+ {
+ switch (location)
+ {
+ case SFLAG_INTEXTURE:
+ case SFLAG_INSRGBTEX:
+ surface_prepare_texture(depth_stencil, context, FALSE);
+
+ if (format_flags & WINED3DFMT_FLAG_DEPTH)
+ {
+ gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT,
+ depth_stencil->texture_target, depth_stencil->texture_name,
+ depth_stencil->texture_level);
+ checkGLcall("glFramebufferTexture2D()");
+ }
+
+ if (format_flags & WINED3DFMT_FLAG_STENCIL)
+ {
+ gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT,
+ depth_stencil->texture_target, depth_stencil->texture_name,
+ depth_stencil->texture_level);
+ checkGLcall("glFramebufferTexture2D()");
+ }
+ break;
+
+ case SFLAG_INRB_MULTISAMPLE:
+ surface_prepare_rb(depth_stencil, gl_info, TRUE);
+ context_attach_depth_stencil_rb(gl_info, fbo_target,
+ format_flags, depth_stencil->rb_multisample);
+ break;
+
+ case SFLAG_INRB_RESOLVED:
+ surface_prepare_rb(depth_stencil, gl_info, FALSE);
+ context_attach_depth_stencil_rb(gl_info, fbo_target,
+ format_flags, depth_stencil->rb_resolved);
+ break;
+
+ default:
+ ERR("Unsupported location %s (%#x).\n", debug_surflocation(location), location);
+ break;
+ }
+ }
+
+ if (!(format_flags & WINED3DFMT_FLAG_DEPTH))
+ {
+ gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
+ checkGLcall("glFramebufferTexture2D()");
+ }
+
+ if (!(format_flags & WINED3DFMT_FLAG_STENCIL))
+ {
+ gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
+ checkGLcall("glFramebufferTexture2D()");
+ }
+ }
+ else
+ {
+ gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
+ checkGLcall("glFramebufferTexture2D()");
+
+ gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
+ checkGLcall("glFramebufferTexture2D()");
+ }
+}
+
+/* Context activation is done by the caller. */
+static void context_attach_surface_fbo(struct wined3d_context *context,
+ GLenum fbo_target, DWORD idx, struct wined3d_surface *surface, DWORD location)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ TRACE("Attach surface %p to %u\n", surface, idx);
+
+ if (surface && surface->resource.format->id != WINED3DFMT_NULL)
+ {
+ BOOL srgb;
+
+ switch (location)
+ {
+ case SFLAG_INTEXTURE:
+ case SFLAG_INSRGBTEX:
+ srgb = location == SFLAG_INSRGBTEX;
+ surface_prepare_texture(surface, context, srgb);
+ gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx,
+ surface->texture_target, surface_get_texture_name(surface, gl_info, srgb),
+ surface->texture_level);
+ checkGLcall("glFramebufferTexture2D()");
+ break;
+
+ case SFLAG_INRB_MULTISAMPLE:
+ surface_prepare_rb(surface, gl_info, TRUE);
+ gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_COLOR_ATTACHMENT0 + idx,
+ GL_RENDERBUFFER, surface->rb_multisample);
+ checkGLcall("glFramebufferRenderbuffer()");
+ break;
+
+ case SFLAG_INRB_RESOLVED:
+ surface_prepare_rb(surface, gl_info, FALSE);
+ gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_COLOR_ATTACHMENT0 + idx,
+ GL_RENDERBUFFER, surface->rb_resolved);
+ checkGLcall("glFramebufferRenderbuffer()");
+ break;
+
+ default:
+ ERR("Unsupported location %s (%#x).\n", debug_surflocation(location), location);
+ break;
+ }
+ }
+ else
+ {
+ gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, GL_TEXTURE_2D, 0, 0);
+ checkGLcall("glFramebufferTexture2D()");
+ }
+}
+
+/* Context activation is done by the caller. */
+void context_check_fbo_status(const struct wined3d_context *context, GLenum target)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ GLenum status;
+
+ if (!FIXME_ON(d3d)) return;
+
+ status = gl_info->fbo_ops.glCheckFramebufferStatus(target);
+ if (status == GL_FRAMEBUFFER_COMPLETE)
+ {
+ TRACE("FBO complete\n");
+ }
+ else
+ {
+ const struct wined3d_surface *attachment;
+ unsigned int i;
+
+ FIXME("FBO status %s (%#x)\n", debug_fbostatus(status), status);
+
+ if (!context->current_fbo)
+ {
+ ERR("FBO 0 is incomplete, driver bug?\n");
+ return;
+ }
+
+ FIXME("\tLocation %s (%#x).\n", debug_surflocation(context->current_fbo->location),
+ context->current_fbo->location);
+
+ /* Dump the FBO attachments */
+ for (i = 0; i < gl_info->limits.buffers; ++i)
+ {
+ attachment = context->current_fbo->render_targets[i];
+ if (attachment)
+ {
+ FIXME("\tColor attachment %d: (%p) %s %ux%u %u samples.\n",
+ i, attachment, debug_d3dformat(attachment->resource.format->id),
+ attachment->pow2Width, attachment->pow2Height, attachment->resource.multisample_type);
+ }
+ }
+ attachment = context->current_fbo->depth_stencil;
+ if (attachment)
+ {
+ FIXME("\tDepth attachment: (%p) %s %ux%u %u samples.\n",
+ attachment, debug_d3dformat(attachment->resource.format->id),
+ attachment->pow2Width, attachment->pow2Height, attachment->resource.multisample_type);
+ }
+ }
+}
+
+static inline DWORD context_generate_rt_mask(GLenum buffer)
+{
+ /* Should take care of all the GL_FRONT/GL_BACK/GL_AUXi/GL_NONE... cases */
+ return buffer ? (1 << 31) | buffer : 0;
+}
+
+static inline DWORD context_generate_rt_mask_from_surface(const struct wined3d_surface *target)
+{
+ return (1 << 31) | surface_get_gl_buffer(target);
+}
+
+static struct fbo_entry *context_create_fbo_entry(const struct wined3d_context *context,
+ struct wined3d_surface **render_targets, struct wined3d_surface *depth_stencil, DWORD location)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct fbo_entry *entry;
+
+ entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry));
+ entry->render_targets = HeapAlloc(GetProcessHeap(), 0, gl_info->limits.buffers * sizeof(*entry->render_targets));
+ memcpy(entry->render_targets, render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets));
+ entry->depth_stencil = depth_stencil;
+ entry->location = location;
+ entry->rt_mask = context_generate_rt_mask(GL_COLOR_ATTACHMENT0);
+ entry->attached = FALSE;
+ gl_info->fbo_ops.glGenFramebuffers(1, &entry->id);
+ checkGLcall("glGenFramebuffers()");
+ TRACE("Created FBO %u.\n", entry->id);
+
+ return entry;
+}
+
+/* Context activation is done by the caller. */
+static void context_reuse_fbo_entry(struct wined3d_context *context, GLenum target,
+ struct wined3d_surface **render_targets, struct wined3d_surface *depth_stencil,
+ DWORD location, struct fbo_entry *entry)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ context_bind_fbo(context, target, entry->id);
+ context_clean_fbo_attachments(gl_info, target);
+
+ memcpy(entry->render_targets, render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets));
+ entry->depth_stencil = depth_stencil;
+ entry->location = location;
+ entry->attached = FALSE;
+}
+
+/* Context activation is done by the caller. */
+static void context_destroy_fbo_entry(struct wined3d_context *context, struct fbo_entry *entry)
+{
+ if (entry->id)
+ {
+ TRACE("Destroy FBO %u.\n", entry->id);
+ context_destroy_fbo(context, entry->id);
+ }
+ --context->fbo_entry_count;
+ list_remove(&entry->entry);
+ HeapFree(GetProcessHeap(), 0, entry->render_targets);
+ HeapFree(GetProcessHeap(), 0, entry);
+}
+
+
+/* Context activation is done by the caller. */
+static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context, GLenum target,
+ struct wined3d_surface **render_targets, struct wined3d_surface *depth_stencil, DWORD location)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct fbo_entry *entry;
+
+ if (depth_stencil && render_targets && render_targets[0])
+ {
+ if (depth_stencil->resource.width < render_targets[0]->resource.width ||
+ depth_stencil->resource.height < render_targets[0]->resource.height)
+ {
+ WARN("Depth stencil is smaller than the primary color buffer, disabling\n");
+ depth_stencil = NULL;
+ }
+ }
+
+ LIST_FOR_EACH_ENTRY(entry, &context->fbo_list, struct fbo_entry, entry)
+ {
+ if (!memcmp(entry->render_targets,
+ render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets))
+ && entry->depth_stencil == depth_stencil && entry->location == location)
+ {
+ list_remove(&entry->entry);
+ list_add_head(&context->fbo_list, &entry->entry);
+ return entry;
+ }
+ }
+
+ if (context->fbo_entry_count < WINED3D_MAX_FBO_ENTRIES)
+ {
+ entry = context_create_fbo_entry(context, render_targets, depth_stencil, location);
+ list_add_head(&context->fbo_list, &entry->entry);
+ ++context->fbo_entry_count;
+ }
+ else
+ {
+ entry = LIST_ENTRY(list_tail(&context->fbo_list), struct fbo_entry, entry);
+ context_reuse_fbo_entry(context, target, render_targets, depth_stencil, location, entry);
+ list_remove(&entry->entry);
+ list_add_head(&context->fbo_list, &entry->entry);
+ }
+
+ return entry;
+}
+
+/* Context activation is done by the caller. */
+static void context_apply_fbo_entry(struct wined3d_context *context, GLenum target, struct fbo_entry *entry)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ unsigned int i;
+ GLuint read_binding, draw_binding;
+
+ if (entry->attached)
+ {
+ context_bind_fbo(context, target, entry->id);
+ return;
+ }
+
+ read_binding = context->fbo_read_binding;
+ draw_binding = context->fbo_draw_binding;
+ context_bind_fbo(context, GL_FRAMEBUFFER, entry->id);
+
+ /* Apply render targets */
+ for (i = 0; i < gl_info->limits.buffers; ++i)
+ {
+ context_attach_surface_fbo(context, target, i, entry->render_targets[i], entry->location);
+ }
+
+ /* Apply depth targets */
+ if (entry->depth_stencil)
+ surface_set_compatible_renderbuffer(entry->depth_stencil, entry->render_targets[0]);
+ context_attach_depth_stencil_fbo(context, target, entry->depth_stencil, entry->location);
+
+ /* Set valid read and draw buffer bindings to satisfy pedantic pre-ES2_compatibility
+ * GL contexts requirements. */
+ glReadBuffer(GL_NONE);
+ context_set_draw_buffer(context, GL_NONE);
+ if (target != GL_FRAMEBUFFER)
+ {
+ if (target == GL_READ_FRAMEBUFFER)
+ context_bind_fbo(context, GL_DRAW_FRAMEBUFFER, draw_binding);
+ else
+ context_bind_fbo(context, GL_READ_FRAMEBUFFER, read_binding);
+ }
+
+ entry->attached = TRUE;
+}
+
+/* Context activation is done by the caller. */
+static void context_apply_fbo_state(struct wined3d_context *context, GLenum target,
+ struct wined3d_surface **render_targets, struct wined3d_surface *depth_stencil, DWORD location)
+{
+ struct fbo_entry *entry, *entry2;
+
+ LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_destroy_list, struct fbo_entry, entry)
+ {
+ context_destroy_fbo_entry(context, entry);
+ }
+
+ if (context->rebind_fbo)
+ {
+ context_bind_fbo(context, GL_FRAMEBUFFER, 0);
+ context->rebind_fbo = FALSE;
+ }
+
+ if (location == SFLAG_INDRAWABLE)
+ {
+ context->current_fbo = NULL;
+ context_bind_fbo(context, target, 0);
+ }
+ else
+ {
+ context->current_fbo = context_find_fbo_entry(context, target, render_targets, depth_stencil, location);
+ context_apply_fbo_entry(context, target, context->current_fbo);
+ }
+}
+
+/* Context activation is done by the caller. */
+void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target,
+ struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location)
+{
+ UINT clear_size = (context->gl_info->limits.buffers - 1) * sizeof(*context->blit_targets);
+
+ context->blit_targets[0] = render_target;
+ if (clear_size)
+ memset(&context->blit_targets[1], 0, clear_size);
+ context_apply_fbo_state(context, target, context->blit_targets, depth_stencil, location);
+}
+
+/* Context activation is done by the caller. */
+void context_alloc_occlusion_query(struct wined3d_context *context, struct wined3d_occlusion_query *query)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (context->free_occlusion_query_count)
+ {
+ query->id = context->free_occlusion_queries[--context->free_occlusion_query_count];
+ }
+ else
+ {
+ if (gl_info->supported[ARB_OCCLUSION_QUERY])
+ {
+ GL_EXTCALL(glGenQueriesARB(1, &query->id));
+ checkGLcall("glGenQueriesARB");
+
+ TRACE("Allocated occlusion query %u in context %p.\n", query->id, context);
+ }
+ else
+ {
+ WARN("Occlusion queries not supported, not allocating query id.\n");
+ query->id = 0;
+ }
+ }
+
+ query->context = context;
+ list_add_head(&context->occlusion_queries, &query->entry);
+}
+
+void context_free_occlusion_query(struct wined3d_occlusion_query *query)
+{
+ struct wined3d_context *context = query->context;
+
+ list_remove(&query->entry);
+ query->context = NULL;
+
+ if (context->free_occlusion_query_count >= context->free_occlusion_query_size - 1)
+ {
+ UINT new_size = context->free_occlusion_query_size << 1;
+ GLuint *new_data = HeapReAlloc(GetProcessHeap(), 0, context->free_occlusion_queries,
+ new_size * sizeof(*context->free_occlusion_queries));
+
+ if (!new_data)
+ {
+ ERR("Failed to grow free list, leaking query %u in context %p.\n", query->id, context);
+ return;
+ }
+
+ context->free_occlusion_query_size = new_size;
+ context->free_occlusion_queries = new_data;
+ }
+
+ context->free_occlusion_queries[context->free_occlusion_query_count++] = query->id;
+}
+
+/* Context activation is done by the caller. */
+void context_alloc_event_query(struct wined3d_context *context, struct wined3d_event_query *query)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (context->free_event_query_count)
+ {
+ query->object = context->free_event_queries[--context->free_event_query_count];
+ }
+ else
+ {
+ if (gl_info->supported[ARB_SYNC])
+ {
+ /* Using ARB_sync, not much to do here. */
+ query->object.sync = NULL;
+ TRACE("Allocated event query %p in context %p.\n", query->object.sync, context);
+ }
+ else if (gl_info->supported[APPLE_FENCE])
+ {
+ GL_EXTCALL(glGenFencesAPPLE(1, &query->object.id));
+ checkGLcall("glGenFencesAPPLE");
+
+ TRACE("Allocated event query %u in context %p.\n", query->object.id, context);
+ }
+ else if(gl_info->supported[NV_FENCE])
+ {
+ GL_EXTCALL(glGenFencesNV(1, &query->object.id));
+ checkGLcall("glGenFencesNV");
+
+ TRACE("Allocated event query %u in context %p.\n", query->object.id, context);
+ }
+ else
+ {
+ WARN("Event queries not supported, not allocating query id.\n");
+ query->object.id = 0;
+ }
+ }
+
+ query->context = context;
+ list_add_head(&context->event_queries, &query->entry);
+}
+
+void context_free_event_query(struct wined3d_event_query *query)
+{
+ struct wined3d_context *context = query->context;
+
+ list_remove(&query->entry);
+ query->context = NULL;
+
+ if (context->free_event_query_count >= context->free_event_query_size - 1)
+ {
+ UINT new_size = context->free_event_query_size << 1;
+ union wined3d_gl_query_object *new_data = HeapReAlloc(GetProcessHeap(), 0, context->free_event_queries,
+ new_size * sizeof(*context->free_event_queries));
+
+ if (!new_data)
+ {
+ ERR("Failed to grow free list, leaking query %u in context %p.\n", query->object.id, context);
+ return;
+ }
+
+ context->free_event_query_size = new_size;
+ context->free_event_queries = new_data;
+ }
+
+ context->free_event_queries[context->free_event_query_count++] = query->object;
+}
+
+typedef void (context_fbo_entry_func_t)(struct wined3d_context *context, struct fbo_entry *entry);
+
+static void context_enum_surface_fbo_entries(const struct wined3d_device *device,
+ const struct wined3d_surface *surface, context_fbo_entry_func_t *callback)
+{
+ UINT i;
+
+ for (i = 0; i < device->context_count; ++i)
+ {
+ struct wined3d_context *context = device->contexts[i];
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct fbo_entry *entry, *entry2;
+
+ if (context->current_rt == surface) context->current_rt = NULL;
+
+ LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry)
+ {
+ UINT j;
+
+ if (entry->depth_stencil == surface)
+ {
+ callback(context, entry);
+ continue;
+ }
+
+ for (j = 0; j < gl_info->limits.buffers; ++j)
+ {
+ if (entry->render_targets[j] == surface)
+ {
+ callback(context, entry);
+ break;
+ }
+ }
+ }
+ }
+}
+
+static void context_queue_fbo_entry_destruction(struct wined3d_context *context, struct fbo_entry *entry)
+{
+ list_remove(&entry->entry);
+ list_add_head(&context->fbo_destroy_list, &entry->entry);
+}
+
+void context_resource_released(const struct wined3d_device *device,
+ struct wined3d_resource *resource, enum wined3d_resource_type type)
+{
+ if (!device->d3d_initialized) return;
+
+ switch (type)
+ {
+ case WINED3D_RTYPE_SURFACE:
+ context_enum_surface_fbo_entries(device, surface_from_resource(resource),
+ context_queue_fbo_entry_destruction);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void context_detach_fbo_entry(struct wined3d_context *context, struct fbo_entry *entry)
+{
+ entry->attached = FALSE;
+}
+
+void context_resource_unloaded(const struct wined3d_device *device,
+ struct wined3d_resource *resource, enum wined3d_resource_type type)
+{
+ switch (type)
+ {
+ case WINED3D_RTYPE_SURFACE:
+ context_enum_surface_fbo_entries(device, surface_from_resource(resource),
+ context_detach_fbo_entry);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void context_surface_update(struct wined3d_context *context, const struct wined3d_surface *surface)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct fbo_entry *entry = context->current_fbo;
+ unsigned int i;
+
+ if (!entry || context->rebind_fbo) return;
+
+ for (i = 0; i < gl_info->limits.buffers; ++i)
+ {
+ if (surface == entry->render_targets[i])
+ {
+ TRACE("Updated surface %p is bound as color attachment %u to the current FBO.\n", surface, i);
+ context->rebind_fbo = TRUE;
+ return;
+ }
+ }
+
+ if (surface == entry->depth_stencil)
+ {
+ TRACE("Updated surface %p is bound as depth attachment to the current FBO.\n", surface);
+ context->rebind_fbo = TRUE;
+ }
+}
+
+#ifndef VBOX
+static BOOL context_set_pixel_format(const struct wined3d_gl_info *gl_info, HDC dc, int format)
+{
+ int current = GetPixelFormat(dc);
+
+ if (current == format) return TRUE;
+
+ if (!current)
+ {
+ if (!SetPixelFormat(dc, format, NULL))
+ {
+ /* This may also happen if the dc belongs to a destroyed window. */
+ WARN("Failed to set pixel format %d on device context %p, last error %#x.\n",
+ format, dc, GetLastError());
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ /* By default WGL doesn't allow pixel format adjustments but we need it
+ * here. For this reason there's a Wine specific wglSetPixelFormat()
+ * which allows us to set the pixel format multiple times. Only use it
+ * when really needed. */
+ if (gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH])
+ {
+ if (!GL_EXTCALL(wglSetPixelFormatWINE(dc, format)))
+ {
+ ERR("wglSetPixelFormatWINE failed to set pixel format %d on device context %p.\n",
+ format, dc);
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ /* OpenGL doesn't allow pixel format adjustments. Print an error and
+ * continue using the old format. There's a big chance that the old
+ * format works although with a performance hit and perhaps rendering
+ * errors. */
+ ERR("Unable to set pixel format %d on device context %p. Already using format %d.\n",
+ format, dc, current);
+ return TRUE;
+}
+#endif
+
+static BOOL context_set_gl_context(struct wined3d_context *ctx)
+{
+ struct wined3d_swapchain *swapchain = ctx->swapchain;
+#ifndef VBOX
+ BOOL backup = FALSE;
+
+ if (!context_set_pixel_format(ctx->gl_info, ctx->hdc, ctx->pixel_format))
+ {
+ WARN("Failed to set pixel format %d on device context %p.\n",
+ ctx->pixel_format, ctx->hdc);
+ backup = TRUE;
+ }
+
+ if (backup || !wglMakeCurrent(ctx->hdc, ctx->glCtx))
+#else
+ if (!wglMakeCurrent(ctx->swapchain->hDC, ctx->glCtx))
+#endif
+ {
+#ifndef VBOX_WITH_WDDM
+ HDC dc;
+#endif
+
+#ifndef VBOX
+ WARN("Failed to make GL context %p current on device context %p, last error %#x.\n",
+ ctx->glCtx, ctx->hdc, GetLastError());
+#else
+ WARN("Failed to make GL context %p current on device context %p, last error %#x.\n",
+ ctx->glCtx, ctx->swapchain->hDC, GetLastError());
+#endif
+ ctx->valid = 0;
+ WARN("Trying fallback to the backup window.\n");
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ /* FIXME: If the context is destroyed it's no longer associated with
+ * a swapchain, so we can't use the swapchain to get a backup dc. To
+ * make this work windowless contexts would need to be handled by the
+ * device. */
+ if (ctx->destroyed)
+ {
+ FIXME("Unable to get backup dc for destroyed context %p.\n", ctx);
+ context_set_current(NULL);
+ return FALSE;
+ }
+#endif
+#ifndef VBOX_WITH_WDDM
+ if (!(dc = swapchain_get_backup_dc(swapchain)))
+ {
+ context_set_current(NULL);
+ return FALSE;
+ }
+#ifndef VBOX
+ if (!context_set_pixel_format(ctx->gl_info, dc, ctx->pixel_format))
+ {
+ ERR("Failed to set pixel format %d on device context %p.\n",
+ ctx->pixel_format, dc);
+ context_set_current(NULL);
+ return FALSE;
+ }
+#endif
+ if (!wglMakeCurrent(dc, ctx->glCtx))
+ {
+ ERR("Fallback to backup window (dc %p) failed too, last error %#x.\n",
+ dc, GetLastError());
+ context_set_current(NULL);
+ return FALSE;
+ }
+#else
+ return FALSE;
+#endif
+ }
+ return TRUE;
+}
+
+static void context_restore_gl_context(const struct wined3d_gl_info *gl_info, HDC dc, HGLRC gl_ctx, int pf)
+{
+#ifndef VBOX
+ if (!context_set_pixel_format(gl_info, dc, pf))
+ {
+ ERR("Failed to restore pixel format %d on device context %p.\n", pf, dc);
+ context_set_current(NULL);
+ return;
+ }
+#endif
+ if (!wglMakeCurrent(dc, gl_ctx))
+ {
+ ERR("Failed to restore GL context %p on device context %p, last error %#x.\n",
+ gl_ctx, dc, GetLastError());
+ context_set_current(NULL);
+ }
+#ifdef VBOX
+ else
+ {
+ /* success branch */
+ /* sync back our tls with gl settings */
+ const struct wined3d_context *current_context = context_get_current();
+ if (current_context && current_context->glCtx != gl_ctx)
+ {
+ UINT i = 0;
+ struct wined3d_device *device = current_context->swapchain->device;
+ for (; i < device->context_count; ++i)
+ {
+ struct wined3d_context *ctx = device->contexts[i];
+ if (ctx->glCtx == gl_ctx)
+ {
+ context_set_current(ctx);
+ break;
+ }
+ }
+
+ if (i == device->context_count)
+ {
+ context_set_current(NULL);
+ }
+ }
+ }
+#endif
+}
+
+#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
+static BOOL swapchain_validate(const struct wined3d_swapchain *swapchain)
+{
+ if (!swapchain->hDC)
+ {
+ ERR("NULL hDC");
+ return FALSE;
+ }
+
+#if defined(DEBUG) || !defined(VBOX_WITH_WDDM)
+ {
+ HWND hWnd = WindowFromDC(swapchain->hDC);
+ if (hWnd != swapchain->win_handle)
+ {
+# if defined(VBOX_WITH_WDDM)
+ ERR("Unexpected swapchain for dc %p window expected %p, but was %p.\n", swapchain->hDC, swapchain->win_handle, hWnd);
+# else
+ ERR("Swapchain for dc %p window expected %p, but was %p.\n", swapchain->hDC, swapchain->win_handle, hWnd);
+ return FALSE;
+# endif
+ }
+ }
+#endif
+ return TRUE;
+}
+
+static struct wined3d_swapchain* swapchain_find_valid(const struct wined3d_device *device)
+{
+ int i;
+ struct wined3d_context * context = device->contexts[0];
+ struct wined3d_swapchain* swapchain = NULL;
+ if (context)
+ {
+ swapchain = context->swapchain;
+ if (swapchain && swapchain_validate(swapchain))
+ {
+ return swapchain;
+ }
+ }
+ for (i = device->swapchain_count - 1; i >= 0 ; --i)
+ {
+ Assert(device->swapchains[i]);
+ if (swapchain != device->swapchains[i] /* the current context swapchain is known to be invalid */
+ && swapchain_validate(device->swapchains[i]))
+ {
+ return device->swapchains[i];
+ }
+ }
+
+ return NULL;
+}
+
+static struct wined3d_swapchain* swapchain_find_valid_or_any(const struct wined3d_device *device)
+{
+ struct wined3d_swapchain* swapchain = swapchain_find_valid(device);
+ if (swapchain)
+ return swapchain;
+
+ ERR("no valid swapchain found!");
+ swapchain = device->swapchains[0];
+ Assert(swapchain);
+ return swapchain;
+}
+
+struct wined3d_context *context_find_create(struct wined3d_device *device,
+ struct wined3d_swapchain *swapchain,
+ const struct wined3d_format *ds_format)
+{
+ struct wined3d_context *context;
+ struct wined3d_surface *target = swapchain->back_buffers ? swapchain->back_buffers[0] : swapchain->front_buffer;
+ if (!device->context_count)
+ {
+ Assert(!device->swapchain_count);
+ context = context_create(swapchain, target, ds_format
+#ifdef VBOX_WITH_WDDM
+ , device->pHgsmi
+#endif
+ );
+ if(!context)
+ {
+ ERR("Failed to create the context.\n");
+ }
+ else
+ {
+ Assert(context->valid);
+ }
+ }
+ else
+ {
+ context = context_acquire(device, target);
+ if(!context)
+ {
+ ERR("Failed to acquire the context.\n");
+ }
+ else
+ {
+ Assert(context->valid);
+ }
+ }
+
+ return context;
+}
+
+#endif
+
+static void context_update_window(struct wined3d_context *context
+#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
+ , struct wined3d_swapchain *swapchain
+#endif
+ )
+{
+#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
+ TRACE("Updating context %p swapchain from %p to %p.\n",
+ context, context->swapchain, swapchain);
+
+ if (context->swapchain == swapchain)
+ return;
+
+ if (!swapchain_validate(swapchain))
+ {
+ ERR("invalid swapchain %p\n", swapchain);
+ goto err;
+ }
+ context->swapchain = swapchain;
+
+ context->valid = 1;
+
+ context_set_gl_context(context);
+#else
+ if (context->win_handle == context->swapchain->win_handle)
+ return;
+
+ TRACE("Updating context %p window from %p to %p.\n",
+ context, context->win_handle, context->swapchain->win_handle);
+
+ if (context->valid)
+ {
+ /* You'd figure ReleaseDC() would fail if the DC doesn't match the
+ * window. However, that's not what actually happens, and there are
+ * user32 tests that confirm ReleaseDC() with the wrong window is
+ * supposed to succeed. So explicitly check that the DC belongs to
+ * the window, since we want to avoid releasing a DC that belongs to
+ * some other window if the original window was already destroyed. */
+ if (WindowFromDC(context->hdc) != context->win_handle)
+ {
+ WARN("DC %p does not belong to window %p.\n",
+ context->hdc, context->win_handle);
+ }
+#ifndef VBOX
+ else if (!ReleaseDC(context->win_handle, context->hdc))
+#else
+ else if (!VBoxExtReleaseDC(context->win_handle, context->hdc))
+#endif
+ {
+ ERR("Failed to release device context %p, last error %#x.\n",
+ context->hdc, GetLastError());
+ }
+ }
+ else context->valid = 1;
+
+ context->win_handle = context->swapchain->win_handle;
+
+#ifndef VBOX
+ if (!(context->hdc = GetDC(context->win_handle)))
+#else
+ if (!(context->hdc = VBoxExtGetDC(context->win_handle)))
+#endif
+ {
+ ERR("Failed to get a device context for window %p.\n", context->win_handle);
+ goto err;
+ }
+#ifndef VBOX
+ if (!context_set_pixel_format(context->gl_info, context->hdc, context->pixel_format))
+ {
+ ERR("Failed to set pixel format %d on device context %p.\n",
+ context->pixel_format, context->hdc);
+ goto err;
+ }
+#endif
+ context_set_gl_context(context);
+#endif
+ return;
+
+err:
+ context->valid = 0;
+}
+
+#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
+static void context_adjust_any_valid(struct wined3d_context *context)
+{
+ struct wined3d_swapchain* swapchain = context->swapchain;
+
+ if (context->valid && swapchain && swapchain_validate(swapchain))
+ return;
+
+ swapchain = swapchain_find_valid(context->device);
+ if (!swapchain)
+ {
+ ERR("no valid swapchain found");
+ Assert(!context->valid);
+ return;
+ }
+
+ context_update_window(context, swapchain);
+}
+#endif
+
+/* Do not call while under the GL lock. */
+static void context_destroy_gl_resources(struct wined3d_context *context)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct wined3d_occlusion_query *occlusion_query;
+ struct wined3d_event_query *event_query;
+ struct fbo_entry *entry, *entry2;
+ HGLRC restore_ctx;
+ HDC restore_dc;
+ unsigned int i;
+ int restore_pf;
+
+ restore_ctx = wglGetCurrentContext();
+ restore_dc = wglGetCurrentDC();
+ restore_pf = GetPixelFormat(restore_dc);
+
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ if (context->valid && restore_ctx != context->glCtx)
+ context_set_gl_context(context);
+#else
+ if (restore_ctx != context->glCtx)
+ context_adjust_any_valid(context);
+#endif
+ else
+ restore_ctx = NULL;
+
+
+ LIST_FOR_EACH_ENTRY(occlusion_query, &context->occlusion_queries, struct wined3d_occlusion_query, entry)
+ {
+ if (context->valid && gl_info->supported[ARB_OCCLUSION_QUERY])
+ GL_EXTCALL(glDeleteQueriesARB(1, &occlusion_query->id));
+ occlusion_query->context = NULL;
+ }
+
+ LIST_FOR_EACH_ENTRY(event_query, &context->event_queries, struct wined3d_event_query, entry)
+ {
+ if (context->valid)
+ {
+ if (gl_info->supported[ARB_SYNC])
+ {
+ if (event_query->object.sync) GL_EXTCALL(glDeleteSync(event_query->object.sync));
+ }
+ else if (gl_info->supported[APPLE_FENCE]) GL_EXTCALL(glDeleteFencesAPPLE(1, &event_query->object.id));
+ else if (gl_info->supported[NV_FENCE]) GL_EXTCALL(glDeleteFencesNV(1, &event_query->object.id));
+ }
+ event_query->context = NULL;
+ }
+
+ LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_destroy_list, struct fbo_entry, entry)
+ {
+ if (!context->valid) entry->id = 0;
+ context_destroy_fbo_entry(context, entry);
+ }
+
+ LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry)
+ {
+ if (!context->valid) entry->id = 0;
+ context_destroy_fbo_entry(context, entry);
+ }
+
+ if (context->valid)
+ {
+ if (context->dummy_arbfp_prog)
+ {
+ GL_EXTCALL(glDeleteProgramsARB(1, &context->dummy_arbfp_prog));
+ }
+
+ if (gl_info->supported[ARB_OCCLUSION_QUERY])
+ GL_EXTCALL(glDeleteQueriesARB(context->free_occlusion_query_count, context->free_occlusion_queries));
+
+ if (gl_info->supported[ARB_SYNC])
+ {
+ for (i = 0; i < context->free_event_query_count; ++i)
+ {
+ GL_EXTCALL(glDeleteSync(context->free_event_queries[i].sync));
+ }
+ }
+ else if (gl_info->supported[APPLE_FENCE])
+ {
+ for (i = 0; i < context->free_event_query_count; ++i)
+ {
+ GL_EXTCALL(glDeleteFencesAPPLE(1, &context->free_event_queries[i].id));
+ }
+ }
+ else if (gl_info->supported[NV_FENCE])
+ {
+ for (i = 0; i < context->free_event_query_count; ++i)
+ {
+ GL_EXTCALL(glDeleteFencesNV(1, &context->free_event_queries[i].id));
+ }
+ }
+
+ checkGLcall("context cleanup");
+ }
+
+ HeapFree(GetProcessHeap(), 0, context->free_occlusion_queries);
+ HeapFree(GetProcessHeap(), 0, context->free_event_queries);
+
+ if (restore_ctx)
+ {
+ context_restore_gl_context(gl_info, restore_dc, restore_ctx, restore_pf);
+ }
+ else if (wglGetCurrentContext() && !wglMakeCurrent(NULL, NULL))
+ {
+ ERR("Failed to disable GL context.\n");
+ }
+
+#ifndef VBOX_WITH_WDDM
+# ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+# ifndef VBOX
+ ReleaseDC(context->win_handle, context->hdc);
+# else
+ VBoxExtReleaseDC(context->win_handle, context->hdc);
+# endif
+# endif
+#endif
+
+ if (!wglDeleteContext(context->glCtx))
+ {
+ DWORD err = GetLastError();
+ ERR("wglDeleteContext(%p) failed, last error %#x.\n", context->glCtx, err);
+ }
+}
+
+DWORD context_get_tls_idx(void)
+{
+ return wined3d_context_tls_idx;
+}
+
+void context_set_tls_idx(DWORD idx)
+{
+ wined3d_context_tls_idx = idx;
+}
+
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+static struct wined3d_context *context_get_current_ex(DWORD adjustTid)
+{
+ struct wined3d_context *ctx = vboxGetCurrentContext();
+ if (ctx && !VBoxTlsRefIsFunctional(ctx))
+ {
+ /* this is a destroyed context left in the tls of the current thread */
+ /* 1. this releases the context and clears the tls */
+ vboxSetCurrentContext(NULL);
+ /* return there is no context current */
+ return NULL;
+ }
+ if (!adjustTid)
+ return ctx;
+ if (!ctx || ctx->tid == adjustTid)
+ return ctx;
+ /* the context may have cleared swapchain (if swapchain was destroyed), ensure it has some valid swapchain set */
+ if (context_set_current(ctx))
+ {
+ Assert(ctx->tid == adjustTid);
+ return ctx;
+ }
+ ERR("context_set_current failed\n");
+ return NULL;
+}
+#endif
+
+struct wined3d_context *context_get_current(void)
+{
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ return TlsGetValue(wined3d_context_tls_idx);
+#else
+ DWORD tid = GetCurrentThreadId();
+ return context_get_current_ex(tid);
+#endif
+}
+
+/* Do not call while under the GL lock. */
+BOOL context_set_current(struct wined3d_context *ctx)
+{
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ struct wined3d_context *old = context_get_current_ex(0);
+ DWORD tid = GetCurrentThreadId();
+#else
+ struct wined3d_context *old = context_get_current();
+#endif
+
+ if (old == ctx)
+ {
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ if (ctx && ctx->tid != tid)
+ {
+ old = NULL;
+ }
+ else
+#endif
+ {
+ TRACE("Already using D3D context %p.\n", ctx);
+ return TRUE;
+ }
+ }
+
+ if (old)
+ {
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ old->tid = 0;
+ old->current = 0;
+#else
+ if (old->destroyed)
+ {
+ TRACE("Switching away from destroyed context %p.\n", old);
+ context_destroy_gl_resources(old);
+ HeapFree(GetProcessHeap(), 0, (void *)old->gl_info);
+ HeapFree(GetProcessHeap(), 0, old);
+ }
+ else
+ {
+ old->current = 0;
+ }
+#endif
+ }
+
+ if (ctx)
+ {
+ if (!ctx->valid)
+ {
+ ERR("Trying to make invalid context %p current\n", ctx);
+ return FALSE;
+ }
+
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ TRACE("Switching to D3D context %p, GL context %p, device context %p.\n", ctx, ctx->glCtx, ctx->hdc);
+#else
+ TRACE("Switching to D3D context %p, GL context %p, device context %p.\n", ctx, ctx->glCtx, ctx->swapchain->hDC);
+#endif
+ if (!context_set_gl_context(ctx))
+ return FALSE;
+ ctx->current = 1;
+ }
+ else if(wglGetCurrentContext())
+ {
+ TRACE("Clearing current D3D context.\n");
+ if (!wglMakeCurrent(NULL, NULL))
+ {
+ DWORD err = GetLastError();
+ ERR("Failed to clear current GL context, last error %#x.\n", err);
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ vboxSetCurrentContext(NULL);
+#else
+ TlsSetValue(wined3d_context_tls_idx, NULL);
+#endif
+ return FALSE;
+ }
+ }
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ vboxSetCurrentContext(ctx);
+ if (ctx)
+ ctx->tid = tid;
+ return TRUE;
+#else
+ return TlsSetValue(wined3d_context_tls_idx, ctx);
+#endif
+}
+
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+void context_clear_on_thread_detach()
+{
+ /* In theory, we should do context_set_current(NULL) here,
+ * but since it may result in calling a context dtor, it should be done under wined3d lock.
+ * We can not acquire a wined3d lock here since this routine is called in a DllMain context
+ * and this would result in a lock order violation, which may result in a deadlock.
+ * In other words, wined3d may internally call Win32 API functions which result in
+ * a DLL lock acquisition while holding wined3d lock.
+ * So lock order should always be "wined3d lock" -> "dll lock".
+ *
+ * This is why we do the following:
+ * */
+
+ /* 1. get the current context w/o adjusting its thread id, etc. */
+ struct wined3d_context *old = context_get_current_ex(0);
+ if (!old)
+ return;
+
+// /* there is a currently assigned context,
+// * 2. now increase its ref count to ensure its dtor routine is not called while making set_current(NULL).
+// * This is needed since dtor can only be run with a wined3d lock held */
+// VBoxTlsRefAddRef(old);
+
+ /* context_tls_dtor now does only memfree, so just call it right away */
+
+ /* 3. now we can call context_set_current(NULL) */
+ context_set_current(NULL);
+
+// /* 4. to avoid possible deadlocks we make an asynchronous call to a worker thread to make
+// * wined3d lock - context release - wined3d unlock from there. */
+// VBoxExtReleaseContextAsync(old);
+}
+#endif
+
+void context_release(struct wined3d_context *context)
+{
+ TRACE("Releasing context %p, level %u.\n", context, context->level);
+
+ if (WARN_ON(d3d))
+ {
+ if (!context->level)
+ WARN("Context %p is not active.\n", context);
+ else if (context != context_get_current())
+ WARN("Context %p is not the current context.\n", context);
+ }
+
+ if (!--context->level && context->restore_ctx)
+ {
+ TRACE("Restoring GL context %p on device context %p.\n", context->restore_ctx, context->restore_dc);
+ context_restore_gl_context(context->gl_info, context->restore_dc, context->restore_ctx, context->restore_pf);
+ context->restore_ctx = NULL;
+ context->restore_dc = NULL;
+ }
+}
+
+static void context_enter(struct wined3d_context *context)
+{
+ TRACE("Entering context %p, level %u.\n", context, context->level + 1);
+
+ if (!context->level++)
+ {
+ const struct wined3d_context *current_context = context_get_current();
+ HGLRC current_gl = wglGetCurrentContext();
+
+ if (current_gl && (!current_context || current_context->glCtx != current_gl))
+ {
+ TRACE("Another GL context (%p on device context %p) is already current.\n",
+ current_gl, wglGetCurrentDC());
+ context->restore_ctx = current_gl;
+ context->restore_dc = wglGetCurrentDC();
+ context->restore_pf = GetPixelFormat(context->restore_dc);
+ }
+ }
+}
+
+void context_invalidate_state(struct wined3d_context *context, DWORD state)
+{
+ DWORD rep = context->state_table[state].representative;
+ DWORD idx;
+ BYTE shift;
+
+ if (isStateDirty(context, rep)) return;
+
+ context->dirtyArray[context->numDirtyEntries++] = rep;
+ idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT);
+ shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1);
+ context->isStateDirty[idx] |= (1 << shift);
+}
+
+/* This function takes care of wined3d pixel format selection. */
+static int context_choose_pixel_format(const struct wined3d_device *device, HDC hdc,
+ const struct wined3d_format *color_format, const struct wined3d_format *ds_format,
+ BOOL auxBuffers, BOOL findCompatible)
+{
+ int iPixelFormat=0;
+ BYTE redBits, greenBits, blueBits, alphaBits, colorBits;
+ BYTE depthBits=0, stencilBits=0;
+ unsigned int current_value;
+ unsigned int cfg_count = device->adapter->cfg_count;
+ unsigned int i;
+
+ TRACE("device %p, dc %p, color_format %s, ds_format %s, aux_buffers %#x, find_compatible %#x.\n",
+ device, hdc, debug_d3dformat(color_format->id), debug_d3dformat(ds_format->id),
+ auxBuffers, findCompatible);
+
+ if (!getColorBits(color_format, &redBits, &greenBits, &blueBits, &alphaBits, &colorBits))
+ {
+ ERR("Unable to get color bits for format %s (%#x)!\n",
+ debug_d3dformat(color_format->id), color_format->id);
+ return 0;
+ }
+
+ getDepthStencilBits(ds_format, &depthBits, &stencilBits);
+
+ current_value = 0;
+ for (i = 0; i < cfg_count; ++i)
+ {
+ const struct wined3d_pixel_format *cfg = &device->adapter->cfgs[i];
+ unsigned int value;
+
+ /* For now only accept RGBA formats. Perhaps some day we will
+ * allow floating point formats for pbuffers. */
+ if (cfg->iPixelType != WGL_TYPE_RGBA_ARB)
+ continue;
+ /* In window mode we need a window drawable format and double buffering. */
+ if (!(cfg->windowDrawable && cfg->doubleBuffer))
+ continue;
+ if (cfg->redSize < redBits)
+ continue;
+ if (cfg->greenSize < greenBits)
+ continue;
+ if (cfg->blueSize < blueBits)
+ continue;
+ if (cfg->alphaSize < alphaBits)
+ continue;
+ if (cfg->depthSize < depthBits)
+ continue;
+ if (stencilBits && cfg->stencilSize != stencilBits)
+ continue;
+ /* Check multisampling support. */
+ if (cfg->numSamples)
+ continue;
+
+ value = 1;
+ /* We try to locate a format which matches our requirements exactly. In case of
+ * depth it is no problem to emulate 16-bit using e.g. 24-bit, so accept that. */
+ if (cfg->depthSize == depthBits)
+ value += 1;
+ if (cfg->stencilSize == stencilBits)
+ value += 2;
+ if (cfg->alphaSize == alphaBits)
+ value += 4;
+ /* We like to have aux buffers in backbuffer mode */
+ if (auxBuffers && cfg->auxBuffers)
+ value += 8;
+ if (cfg->redSize == redBits
+ && cfg->greenSize == greenBits
+ && cfg->blueSize == blueBits)
+ value += 16;
+
+ if (value > current_value)
+ {
+ iPixelFormat = cfg->iPixelFormat;
+ current_value = value;
+ }
+ }
+
+ /* When findCompatible is set and no suitable format was found, let ChoosePixelFormat choose a pixel format in order not to crash. */
+ if(!iPixelFormat && !findCompatible) {
+ ERR("Can't find a suitable iPixelFormat\n");
+ return FALSE;
+ } else if(!iPixelFormat) {
+ PIXELFORMATDESCRIPTOR pfd;
+
+ TRACE("Falling back to ChoosePixelFormat as we weren't able to find an exactly matching pixel format\n");
+ /* PixelFormat selection */
+ ZeroMemory(&pfd, sizeof(pfd));
+ pfd.nSize = sizeof(pfd);
+ pfd.nVersion = 1;
+ pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;/*PFD_GENERIC_ACCELERATED*/
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.cAlphaBits = alphaBits;
+ pfd.cColorBits = colorBits;
+ pfd.cDepthBits = depthBits;
+ pfd.cStencilBits = stencilBits;
+ pfd.iLayerType = PFD_MAIN_PLANE;
+
+ iPixelFormat = ChoosePixelFormat(hdc, &pfd);
+ if(!iPixelFormat) {
+ /* If this happens something is very wrong as ChoosePixelFormat barely fails */
+ ERR("Can't find a suitable iPixelFormat\n");
+ return FALSE;
+ }
+ }
+
+ TRACE("Found iPixelFormat=%d for ColorFormat=%s, DepthStencilFormat=%s\n",
+ iPixelFormat, debug_d3dformat(color_format->id), debug_d3dformat(ds_format->id));
+ return iPixelFormat;
+}
+
+/* Context activation is done by the caller. */
+static void bind_dummy_textures(const struct wined3d_device *device, const struct wined3d_context *context)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ unsigned int i, count = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers);
+
+ for (i = 0; i < count; ++i)
+ {
+ GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
+ checkGLcall("glActiveTextureARB");
+
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, device->dummy_texture_2d[i]);
+ checkGLcall("glBindTexture");
+
+ if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ {
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_texture_rect[i]);
+ checkGLcall("glBindTexture");
+ }
+
+ if (gl_info->supported[EXT_TEXTURE3D])
+ {
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, device->dummy_texture_3d[i]);
+ checkGLcall("glBindTexture");
+ }
+
+ if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+ {
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_texture_cube[i]);
+ checkGLcall("glBindTexture");
+ }
+ }
+}
+
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+static DECLCALLBACK(void) context_tls_dtor(void* pvCtx)
+{
+ struct wined3d_context * context = (struct wined3d_context *)pvCtx;
+ HeapFree(GetProcessHeap(), 0, context);
+}
+#endif
+
+BOOL context_debug_output_enabled(const struct wined3d_gl_info *gl_info)
+{
+ return gl_info->supported[ARB_DEBUG_OUTPUT]
+ && (ERR_ON(d3d) || FIXME_ON(d3d) || WARN_ON(d3d_perf));
+}
+
+static void WINE_GLAPI wined3d_debug_callback(GLenum source, GLenum type, GLuint id,
+ GLenum severity, GLsizei length, const char *message, void *ctx)
+{
+ switch (type)
+ {
+ case GL_DEBUG_TYPE_ERROR_ARB:
+ ERR("%p: %s.\n", ctx, debugstr_an(message, length));
+ break;
+
+ case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
+ case GL_DEBUG_TYPE_PORTABILITY_ARB:
+ FIXME("%p: %s.\n", ctx, debugstr_an(message, length));
+ break;
+
+ case GL_DEBUG_TYPE_PERFORMANCE_ARB:
+ WARN_(d3d_perf)("%p: %s.\n", ctx, debugstr_an(message, length));
+ break;
+
+ default:
+ FIXME("ctx %p, type %#x: %s.\n", ctx, type, debugstr_an(message, length));
+ break;
+ }
+}
+
+/* Do not call while under the GL lock. */
+struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
+ struct wined3d_surface *target, const struct wined3d_format *ds_format
+#ifdef VBOX_WITH_WDDM
+ , struct VBOXUHGSMI *pHgsmi
+#endif
+ )
+{
+ struct wined3d_device *device = swapchain->device;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ const struct wined3d_format *color_format;
+ struct wined3d_context *ret;
+ BOOL auxBuffers = FALSE;
+ HGLRC ctx, share_ctx;
+ int pixel_format;
+ unsigned int s;
+ int swap_interval;
+ DWORD state;
+ HDC hdc;
+
+ TRACE("swapchain %p, target %p, window %p.\n", swapchain, target, swapchain->win_handle);
+
+#ifdef VBOX_WITH_WDDM
+ if (!pHgsmi)
+ {
+ ERR("HGSMI should be specified!");
+ return NULL;
+ }
+#endif
+
+ ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->blit_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ gl_info->limits.buffers * sizeof(*ret->blit_targets));
+ if (!ret->blit_targets)
+ goto out;
+
+ ret->draw_buffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ gl_info->limits.buffers * sizeof(*ret->draw_buffers));
+ if (!ret->draw_buffers)
+ goto out;
+
+ ret->free_occlusion_query_size = 4;
+ ret->free_occlusion_queries = HeapAlloc(GetProcessHeap(), 0,
+ ret->free_occlusion_query_size * sizeof(*ret->free_occlusion_queries));
+ if (!ret->free_occlusion_queries)
+ goto out;
+
+ list_init(&ret->occlusion_queries);
+
+ ret->free_event_query_size = 4;
+ ret->free_event_queries = HeapAlloc(GetProcessHeap(), 0,
+ ret->free_event_query_size * sizeof(*ret->free_event_queries));
+ if (!ret->free_event_queries)
+ goto out;
+
+ list_init(&ret->event_queries);
+ list_init(&ret->fbo_list);
+ list_init(&ret->fbo_destroy_list);
+
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ VBoxTlsRefInit(ret, context_tls_dtor);
+#endif
+
+#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
+ ret->device = device;
+ if (!swapchain->hDC)
+ {
+ ERR("Swapchain hDC is null");
+ goto out;
+ }
+ hdc = swapchain->hDC;
+#else
+ if (!(hdc = GetDC(swapchain->win_handle)))
+ {
+ WARN("Failed to retireve device context, trying swapchain backup.\n");
+ if (!(hdc = swapchain_get_backup_dc(swapchain)))
+ {
+ ERR("Failed to retrieve a device context.\n");
+ goto out;
+ }
+ }
+#endif
+
+ color_format = target->resource.format;
+
+ /* In case of ORM_BACKBUFFER, make sure to request an alpha component for
+ * X4R4G4B4/X8R8G8B8 as we might need it for the backbuffer. */
+ if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER)
+ {
+ auxBuffers = TRUE;
+
+ if (color_format->id == WINED3DFMT_B4G4R4X4_UNORM)
+ color_format = wined3d_get_format(gl_info, WINED3DFMT_B4G4R4A4_UNORM);
+ else if (color_format->id == WINED3DFMT_B8G8R8X8_UNORM)
+ color_format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM);
+ }
+
+ /* DirectDraw supports 8bit paletted render targets and these are used by
+ * old games like StarCraft and C&C. Most modern hardware doesn't support
+ * 8bit natively so we perform some form of 8bit -> 32bit conversion. The
+ * conversion (ab)uses the alpha component for storing the palette index.
+ * For this reason we require a format with 8bit alpha, so request
+ * A8R8G8B8. */
+ if (color_format->id == WINED3DFMT_P8_UINT)
+ color_format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM);
+
+ /* Try to find a pixel format which matches our requirements. */
+ pixel_format = context_choose_pixel_format(device, hdc, color_format, ds_format, auxBuffers, FALSE);
+
+ /* Try to locate a compatible format if we weren't able to find anything. */
+ if (!pixel_format)
+ {
+ TRACE("Trying to locate a compatible pixel format because an exact match failed.\n");
+ pixel_format = context_choose_pixel_format(device, hdc, color_format, ds_format, auxBuffers, TRUE);
+ }
+
+ /* If we still don't have a pixel format, something is very wrong as ChoosePixelFormat barely fails */
+ if (!pixel_format)
+ {
+ ERR("Can't find a suitable pixel format.\n");
+ goto out;
+ }
+
+ context_enter(ret);
+#ifndef VBOX
+ if (!context_set_pixel_format(gl_info, hdc, pixel_format))
+ {
+ ERR("Failed to set pixel format %d on device context %p.\n", pixel_format, hdc);
+ context_release(ret);
+ goto out;
+ }
+
+ share_ctx = device->context_count ? device->contexts[0]->glCtx : NULL;
+ if (gl_info->p_wglCreateContextAttribsARB)
+ {
+ unsigned int ctx_attrib_idx = 0;
+ GLint ctx_attribs[3];
+
+ if (context_debug_output_enabled(gl_info))
+ {
+ ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_FLAGS_ARB;
+ ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_DEBUG_BIT_ARB;
+ }
+ ctx_attribs[ctx_attrib_idx] = 0;
+
+ if (!(ctx = gl_info->p_wglCreateContextAttribsARB(hdc, share_ctx, ctx_attribs)))
+ {
+ ERR("Failed to create a WGL context.\n");
+ context_release(ret);
+ goto out;
+ }
+ }
+ else
+ {
+ if (!(ctx = wglCreateContext(hdc)))
+#else
+ ctx = pVBoxCreateContext(hdc
+#ifdef VBOX_WITH_WDDM
+ , pHgsmi
+#else
+ , NULL
+#endif
+ );
+ if (!ctx)
+#endif
+ {
+ ERR("Failed to create a WGL context.\n");
+ context_release(ret);
+ goto out;
+ }
+
+#ifdef VBOX_WITH_WDDM
+ pVBoxCtxChromiumParameteriCR(ctx, GL_HOST_WND_CREATED_HIDDEN_CR, GL_TRUE);
+#endif
+
+#ifndef VBOX
+ if (share_ctx && !wglShareLists(share_ctx, ctx))
+ {
+ ERR("wglShareLists(%p, %p) failed, last error %#x.\n", share_ctx, ctx, GetLastError());
+ context_release(ret);
+ if (!wglDeleteContext(ctx))
+ ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, GetLastError());
+ goto out;
+ }
+ }
+#endif
+
+ if (!device_context_add(device, ret))
+ {
+ ERR("Failed to add the newly created context to the context list\n");
+ context_release(ret);
+ if (!wglDeleteContext(ctx))
+ ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, GetLastError());
+ goto out;
+ }
+
+ ret->gl_info = gl_info;
+ ret->d3d_info = &device->adapter->d3d_info;
+ ret->state_table = device->StateTable;
+
+ /* Mark all states dirty to force a proper initialization of the states
+ * on the first use of the context. */
+ for (state = 0; state <= STATE_HIGHEST; ++state)
+ {
+ if (ret->state_table[state].representative)
+ context_invalidate_state(ret, state);
+ }
+
+ ret->swapchain = swapchain;
+ ret->current_rt = target;
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ ret->tid = GetCurrentThreadId();
+#else
+ ret->tid = 0;
+#endif
+
+ ret->render_offscreen = surface_is_offscreen(target);
+ ret->draw_buffers_mask = context_generate_rt_mask(GL_BACK);
+ ret->valid = 1;
+
+ ret->glCtx = ctx;
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ ret->win_handle = swapchain->win_handle;
+ ret->hdc = hdc;
+#endif
+ ret->pixel_format = pixel_format;
+
+ /* Set up the context defaults */
+ if (!context_set_current(ret))
+ {
+ ERR("Cannot activate context to set up defaults.\n");
+ device_context_remove(device, ret);
+ context_release(ret);
+ if (!wglDeleteContext(ctx))
+ ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, GetLastError());
+ goto out;
+ }
+
+ if (context_debug_output_enabled(gl_info))
+ {
+ GL_EXTCALL(glDebugMessageCallbackARB(wined3d_debug_callback, ret));
+ if (TRACE_ON(d3d_synchronous))
+ gl_info->gl_ops.gl.p_glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
+ GL_EXTCALL(glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_FALSE));
+ if (ERR_ON(d3d))
+ {
+ GL_EXTCALL(glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_ERROR_ARB,
+ GL_DONT_CARE, 0, NULL, GL_TRUE));
+ }
+ if (FIXME_ON(d3d))
+ {
+ GL_EXTCALL(glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB,
+ GL_DONT_CARE, 0, NULL, GL_TRUE));
+ GL_EXTCALL(glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB,
+ GL_DONT_CARE, 0, NULL, GL_TRUE));
+ GL_EXTCALL(glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_PORTABILITY_ARB,
+ GL_DONT_CARE, 0, NULL, GL_TRUE));
+ }
+ if (WARN_ON(d3d_perf))
+ {
+ GL_EXTCALL(glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_PERFORMANCE_ARB,
+ GL_DONT_CARE, 0, NULL, GL_TRUE));
+ }
+ }
+
+ switch (swapchain->desc.swap_interval)
+ {
+ case WINED3DPRESENT_INTERVAL_IMMEDIATE:
+ swap_interval = 0;
+ break;
+ case WINED3DPRESENT_INTERVAL_DEFAULT:
+ case WINED3DPRESENT_INTERVAL_ONE:
+ swap_interval = 1;
+ break;
+ case WINED3DPRESENT_INTERVAL_TWO:
+ swap_interval = 2;
+ break;
+ case WINED3DPRESENT_INTERVAL_THREE:
+ swap_interval = 3;
+ break;
+ case WINED3DPRESENT_INTERVAL_FOUR:
+ swap_interval = 4;
+ break;
+ default:
+ FIXME("Unknown swap interval %#x.\n", swapchain->desc.swap_interval);
+ swap_interval = 1;
+ }
+
+ if (gl_info->supported[WGL_EXT_SWAP_CONTROL])
+ {
+ if (!GL_EXTCALL(wglSwapIntervalEXT(swap_interval)))
+ ERR("wglSwapIntervalEXT failed to set swap interval %d for context %p, last error %#x\n",
+ swap_interval, ret, GetLastError());
+ }
+
+#ifdef VBOX
+ /* for WDDM case this is used for shared resource handling
+ *
+ * for XPDM this is needed to at least support texture sharing between device contexts.
+ * this is a kinda hack, but it is needed since our ogl driver currently does not support ShareLists */
+ pglChromiumParameteriCR(GL_SHARE_CONTEXT_RESOURCES_CR, GL_TRUE);
+# if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ pglChromiumParameteriCR(GL_FLUSH_ON_THREAD_SWITCH_CR, GL_TRUE);
+# endif
+# if defined(VBOX_WITH_WDDM)
+ pglChromiumParameteriCR(GL_HOST_WND_CREATED_HIDDEN_CR, GL_TRUE);
+# endif
+#endif
+
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_AUX_BUFFERS, &ret->aux_buffers);
+
+ TRACE("Setting up the screen\n");
+
+ gl_info->gl_ops.gl.p_glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
+ checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
+
+ gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
+ checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);");
+
+ gl_info->gl_ops.gl.p_glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
+ checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");
+
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ALIGNMENT, device->surface_alignment);
+ checkGLcall("glPixelStorei(GL_PACK_ALIGNMENT, device->surface_alignment);");
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ALIGNMENT, device->surface_alignment);
+ checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, device->surface_alignment);");
+
+ if (gl_info->supported[APPLE_CLIENT_STORAGE])
+ {
+ /* Most textures will use client storage if supported. Exceptions are
+ * non-native power of 2 textures and textures in DIB sections. */
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
+ checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
+ }
+ if (gl_info->supported[ARB_VERTEX_BLEND])
+ {
+ /* Direct3D always uses n-1 weights for n world matrices and uses
+ * 1 - sum for the last one this is equal to GL_WEIGHT_SUM_UNITY_ARB.
+ * Enabling it doesn't do anything unless GL_VERTEX_BLEND_ARB isn't
+ * enabled as well. */
+ gl_info->gl_ops.gl.p_glEnable(GL_WEIGHT_SUM_UNITY_ARB);
+ checkGLcall("glEnable(GL_WEIGHT_SUM_UNITY_ARB)");
+ }
+ if (gl_info->supported[NV_TEXTURE_SHADER2])
+ {
+ /* Set up the previous texture input for all shader units. This applies to bump mapping, and in d3d
+ * the previous texture where to source the offset from is always unit - 1.
+ */
+ for (s = 1; s < gl_info->limits.textures; ++s)
+ {
+ context_active_texture(ret, gl_info, s);
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV,
+ GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + s - 1);
+ checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, ...");
+ }
+ }
+ if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
+ {
+ /* MacOS(radeon X1600 at least, but most likely others too) refuses to draw if GLSL and ARBFP are
+ * enabled, but the currently bound arbfp program is 0. Enabling ARBFP with prog 0 is invalid, but
+ * GLSL should bypass this. This causes problems in programs that never use the fixed function pipeline,
+ * because the ARBFP extension is enabled by the ARBFP pipeline at context creation, but no program
+ * is ever assigned.
+ *
+ * So make sure a program is assigned to each context. The first real ARBFP use will set a different
+ * program and the dummy program is destroyed when the context is destroyed.
+ */
+ const char *dummy_program =
+ "!!ARBfp1.0\n"
+ "MOV result.color, fragment.color.primary;\n"
+ "END\n";
+ GL_EXTCALL(glGenProgramsARB(1, &ret->dummy_arbfp_prog));
+ GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, ret->dummy_arbfp_prog));
+ GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(dummy_program), dummy_program));
+ }
+
+ if (gl_info->supported[ARB_POINT_SPRITE])
+ {
+ for (s = 0; s < gl_info->limits.textures; ++s)
+ {
+ context_active_texture(ret, gl_info, s);
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
+ checkGLcall("glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE)");
+ }
+ }
+
+ if (gl_info->supported[ARB_PROVOKING_VERTEX])
+ {
+ GL_EXTCALL(glProvokingVertex(GL_FIRST_VERTEX_CONVENTION));
+ }
+ else if (gl_info->supported[EXT_PROVOKING_VERTEX])
+ {
+ GL_EXTCALL(glProvokingVertexEXT(GL_FIRST_VERTEX_CONVENTION_EXT));
+ }
+ ret->select_shader = 1;
+
+ /* If this happens to be the first context for the device, dummy textures
+ * are not created yet. In that case, they will be created (and bound) by
+ * create_dummy_textures right after this context is initialized. */
+ if (device->dummy_texture_2d[0])
+ bind_dummy_textures(device, ret);
+
+ TRACE("Created context %p.\n", ret);
+
+ return ret;
+
+out:
+ HeapFree(GetProcessHeap(), 0, ret->free_event_queries);
+ HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries);
+ HeapFree(GetProcessHeap(), 0, ret->draw_buffers);
+ HeapFree(GetProcessHeap(), 0, ret->blit_targets);
+ HeapFree(GetProcessHeap(), 0, ret);
+ return NULL;
+}
+
+/* Do not call while under the GL lock. */
+void context_destroy(struct wined3d_device *device, struct wined3d_context *context)
+{
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ BOOL destroy;
+#endif
+
+ TRACE("Destroying ctx %p\n", context);
+
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ if (context->tid == GetCurrentThreadId() || !context->current)
+ {
+ context_destroy_gl_resources(context);
+ TlsSetValue(wined3d_context_tls_idx, NULL);
+ destroy = TRUE;
+ }
+ else
+ {
+ /* Make a copy of gl_info for context_destroy_gl_resources use, the one
+ in wined3d_adapter may go away in the meantime */
+ struct wined3d_gl_info *gl_info = HeapAlloc(GetProcessHeap(), 0, sizeof(*gl_info));
+ *gl_info = *context->gl_info;
+ context->gl_info = gl_info;
+ context->destroyed = 1;
+ destroy = FALSE;
+ }
+#else
+ context_destroy_gl_resources(context);
+#endif
+
+ HeapFree(GetProcessHeap(), 0, context->draw_buffers);
+ HeapFree(GetProcessHeap(), 0, context->blit_targets);
+ device_context_remove(device, context);
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ if (destroy) HeapFree(GetProcessHeap(), 0, context);
+#else
+ context->swapchain = NULL;
+
+ VBoxTlsRefMarkDestroy(context);
+ VBoxTlsRefRelease(context);
+#endif
+}
+
+/* Context activation is done by the caller. */
+static void set_blit_dimension(const struct wined3d_gl_info *gl_info, UINT width, UINT height)
+{
+ const GLdouble projection[] =
+ {
+ 2.0 / width, 0.0, 0.0, 0.0,
+ 0.0, 2.0 / height, 0.0, 0.0,
+ 0.0, 0.0, 2.0, 0.0,
+ -1.0, -1.0, -1.0, 1.0,
+ };
+
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
+ checkGLcall("glMatrixMode(GL_PROJECTION)");
+ gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
+ checkGLcall("glLoadMatrixd");
+ gl_info->gl_ops.gl.p_glViewport(0, 0, width, height);
+ checkGLcall("glViewport");
+}
+
+static void context_get_rt_size(const struct wined3d_context *context, SIZE *size)
+{
+ const struct wined3d_surface *rt = context->current_rt;
+
+ if (rt->swapchain && rt->swapchain->front_buffer == rt)
+ {
+ RECT window_size;
+#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
+ ERR("not tested!");
+ GetClientRect(rt->swapchain->win_handle, &window_size);
+#else
+ GetClientRect(context->win_handle, &window_size);
+#endif
+#ifdef DEBUG_misha
+ Assert(window_size.right - window_size.left == rt->resource.width);
+ Assert(window_size.bottom - window_size.top == rt->resource.height);
+#endif
+ size->cx = window_size.right - window_size.left;
+ size->cy = window_size.bottom - window_size.top;
+
+ return;
+ }
+ size->cx = rt->resource.width;
+ size->cy = rt->resource.height;
+}
+
+/*****************************************************************************
+ * SetupForBlit
+ *
+ * Sets up a context for DirectDraw blitting.
+ * All texture units are disabled, texture unit 0 is set as current unit
+ * fog, lighting, blending, alpha test, z test, scissor test, culling disabled
+ * color writing enabled for all channels
+ * register combiners disabled, shaders disabled
+ * world matrix is set to identity, texture matrix 0 too
+ * projection matrix is setup for drawing screen coordinates
+ *
+ * Params:
+ * This: Device to activate the context for
+ * context: Context to setup
+ *
+ *****************************************************************************/
+/* Context activation is done by the caller. */
+static void SetupForBlit(const struct wined3d_device *device, struct wined3d_context *context)
+{
+ int i;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ DWORD sampler;
+ SIZE rt_size;
+
+ TRACE("Setting up context %p for blitting\n", context);
+
+ context_get_rt_size(context, &rt_size);
+
+ if (context->last_was_blit)
+ {
+ if (context->blit_w != rt_size.cx || context->blit_h != rt_size.cy)
+ {
+ set_blit_dimension(gl_info, rt_size.cx, rt_size.cy);
+ context->blit_w = rt_size.cx;
+ context->blit_h = rt_size.cy;
+ /* No need to dirtify here, the states are still dirtified because
+ * they weren't applied since the last SetupForBlit() call. */
+ }
+ TRACE("Context is already set up for blitting, nothing to do\n");
+ return;
+ }
+ context->last_was_blit = TRUE;
+
+ /* Disable all textures. The caller can then bind a texture it wants to blit
+ * from
+ *
+ * The blitting code uses (for now) the fixed function pipeline, so make sure to reset all fixed
+ * function texture unit. No need to care for higher samplers
+ */
+ for (i = gl_info->limits.textures - 1; i > 0 ; --i)
+ {
+ sampler = device->rev_tex_unit_map[i];
+ context_active_texture(context, gl_info, i);
+
+ if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+ checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB");
+ }
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
+ checkGLcall("glDisable GL_TEXTURE_3D");
+ if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
+ checkGLcall("glDisable GL_TEXTURE_RECTANGLE_ARB");
+ }
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
+ checkGLcall("glDisable GL_TEXTURE_2D");
+
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);");
+
+ if (sampler != WINED3D_UNMAPPED_STAGE)
+ {
+ if (sampler < MAX_TEXTURES)
+ context_invalidate_state(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP));
+ context_invalidate_state(context, STATE_SAMPLER(sampler));
+ }
+ }
+ context_active_texture(context, gl_info, 0);
+
+ sampler = device->rev_tex_unit_map[0];
+
+ if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+ checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB");
+ }
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
+ checkGLcall("glDisable GL_TEXTURE_3D");
+ if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
+ checkGLcall("glDisable GL_TEXTURE_RECTANGLE_ARB");
+ }
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
+ checkGLcall("glDisable GL_TEXTURE_2D");
+
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE);
+ checkGLcall("glMatrixMode(GL_TEXTURE)");
+ gl_info->gl_ops.gl.p_glLoadIdentity();
+ checkGLcall("glLoadIdentity()");
+
+ if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
+ {
+ gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
+ GL_TEXTURE_LOD_BIAS_EXT, 0.0f);
+ checkGLcall("glTexEnvf GL_TEXTURE_LOD_BIAS_EXT ...");
+ }
+
+ if (sampler != WINED3D_UNMAPPED_STAGE)
+ {
+ if (sampler < MAX_TEXTURES)
+ {
+ context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + sampler));
+ context_invalidate_state(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP));
+ }
+ context_invalidate_state(context, STATE_SAMPLER(sampler));
+ }
+
+ /* Other misc states */
+ gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST);
+ checkGLcall("glDisable(GL_ALPHA_TEST)");
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHATESTENABLE));
+ gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
+ checkGLcall("glDisable GL_LIGHTING");
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_LIGHTING));
+ gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST);
+ checkGLcall("glDisable GL_DEPTH_TEST");
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZENABLE));
+ glDisableWINE(GL_FOG);
+ checkGLcall("glDisable GL_FOG");
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_FOGENABLE));
+ gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
+ checkGLcall("glDisable GL_BLEND");
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE));
+ gl_info->gl_ops.gl.p_glDisable(GL_CULL_FACE);
+ checkGLcall("glDisable GL_CULL_FACE");
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CULLMODE));
+ gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
+ checkGLcall("glDisable GL_STENCIL_TEST");
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_STENCILENABLE));
+ gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
+ checkGLcall("glDisable GL_SCISSOR_TEST");
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE));
+ if (gl_info->supported[ARB_POINT_SPRITE])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_POINT_SPRITE_ARB);
+ checkGLcall("glDisable GL_POINT_SPRITE_ARB");
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE));
+ }
+ gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE);
+ checkGLcall("glColorMask");
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE));
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1));
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2));
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3));
+ if (gl_info->supported[EXT_SECONDARY_COLOR])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT);
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SPECULARENABLE));
+ checkGLcall("glDisable(GL_COLOR_SUM_EXT)");
+ }
+
+ /* Setup transforms */
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
+ checkGLcall("glMatrixMode(GL_MODELVIEW)");
+ gl_info->gl_ops.gl.p_glLoadIdentity();
+ checkGLcall("glLoadIdentity()");
+ context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
+
+ context->last_was_rhw = TRUE;
+ context_invalidate_state(context, STATE_VDECL); /* because of last_was_rhw = TRUE */
+
+ gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)");
+ gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)");
+ gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)");
+ gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)");
+ gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)");
+ gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)");
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CLIPPING));
+
+ set_blit_dimension(gl_info, rt_size.cx, rt_size.cy);
+
+ /* Disable shaders */
+ device->shader_backend->shader_disable(device->shader_priv, context);
+ context->select_shader = 1;
+ context->load_constants = 1;
+
+ context->blit_w = rt_size.cx;
+ context->blit_h = rt_size.cy;
+ context_invalidate_state(context, STATE_VIEWPORT);
+ context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
+}
+
+static inline BOOL is_rt_mask_onscreen(DWORD rt_mask)
+{
+ return rt_mask & (1 << 31);
+}
+
+static inline GLenum draw_buffer_from_rt_mask(DWORD rt_mask)
+{
+ return rt_mask & ~(1 << 31);
+}
+
+/* Context activation is done by the caller. */
+static void context_apply_draw_buffers(struct wined3d_context *context, DWORD rt_mask)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (!rt_mask)
+ {
+ gl_info->gl_ops.gl.p_glDrawBuffer(GL_NONE);
+ checkGLcall("glDrawBuffer()");
+ }
+ else if (is_rt_mask_onscreen(rt_mask))
+ {
+ gl_info->gl_ops.gl.p_glDrawBuffer(draw_buffer_from_rt_mask(rt_mask));
+ checkGLcall("glDrawBuffer()");
+ }
+ else
+ {
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ unsigned int i = 0;
+
+ while (rt_mask)
+ {
+ if (rt_mask & 1)
+ context->draw_buffers[i] = GL_COLOR_ATTACHMENT0 + i;
+ else
+ context->draw_buffers[i] = GL_NONE;
+
+ rt_mask >>= 1;
+ ++i;
+ }
+
+ if (gl_info->supported[ARB_DRAW_BUFFERS])
+ {
+ GL_EXTCALL(glDrawBuffersARB(i, context->draw_buffers));
+ checkGLcall("glDrawBuffers()");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDrawBuffer(context->draw_buffers[0]);
+ checkGLcall("glDrawBuffer()");
+ }
+ }
+ else
+ {
+ ERR("Unexpected draw buffers mask with backbuffer ORM.\n");
+ }
+ }
+}
+
+/* Context activation is done by the caller. */
+void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ DWORD *current_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask;
+ DWORD new_mask = context_generate_rt_mask(buffer);
+
+ if (new_mask == *current_mask)
+ return;
+
+ gl_info->gl_ops.gl.p_glDrawBuffer(buffer);
+ checkGLcall("glDrawBuffer()");
+
+ *current_mask = new_mask;
+}
+
+/* Context activation is done by the caller. */
+void context_active_texture(struct wined3d_context *context, const struct wined3d_gl_info *gl_info, unsigned int unit)
+{
+ GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0 + unit));
+ checkGLcall("glActiveTextureARB");
+ context->active_texture = unit;
+}
+
+void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint name)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ DWORD unit = context->active_texture;
+ DWORD old_texture_type = context->texture_type[unit];
+
+ if (name)
+ {
+ gl_info->gl_ops.gl.p_glBindTexture(target, name);
+ checkGLcall("glBindTexture");
+ }
+ else
+ {
+ target = GL_NONE;
+ }
+
+ if (old_texture_type != target)
+ {
+ const struct wined3d_device *device = context->swapchain->device;
+
+ switch (old_texture_type)
+ {
+ case GL_NONE:
+ /* nothing to do */
+ break;
+ case GL_TEXTURE_2D:
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, device->dummy_texture_2d[unit]);
+ checkGLcall("glBindTexture");
+ break;
+ case GL_TEXTURE_RECTANGLE_ARB:
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_texture_rect[unit]);
+ checkGLcall("glBindTexture");
+ break;
+ case GL_TEXTURE_CUBE_MAP:
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_texture_cube[unit]);
+ checkGLcall("glBindTexture");
+ break;
+ case GL_TEXTURE_3D:
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, device->dummy_texture_3d[unit]);
+ checkGLcall("glBindTexture");
+ break;
+ default:
+ ERR("Unexpected texture target %#x\n", old_texture_type);
+ }
+
+ context->texture_type[unit] = target;
+ }
+}
+
+static void context_set_render_offscreen(struct wined3d_context *context, BOOL offscreen)
+{
+ if (context->render_offscreen == offscreen) return;
+
+ context_invalidate_state(context, STATE_POINTSPRITECOORDORIGIN);
+ context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
+ context_invalidate_state(context, STATE_VIEWPORT);
+ context_invalidate_state(context, STATE_SCISSORRECT);
+ context_invalidate_state(context, STATE_FRONTFACE);
+ context->render_offscreen = offscreen;
+}
+
+static BOOL match_depth_stencil_format(const struct wined3d_format *existing,
+ const struct wined3d_format *required)
+{
+ BYTE existing_depth, existing_stencil, required_depth, required_stencil;
+
+ if (existing == required) return TRUE;
+ if ((existing->flags & WINED3DFMT_FLAG_FLOAT) != (required->flags & WINED3DFMT_FLAG_FLOAT)) return FALSE;
+
+ getDepthStencilBits(existing, &existing_depth, &existing_stencil);
+ getDepthStencilBits(required, &required_depth, &required_stencil);
+
+ if(existing_depth < required_depth) return FALSE;
+ /* If stencil bits are used the exact amount is required - otherwise wrapping
+ * won't work correctly */
+ if(required_stencil && required_stencil != existing_stencil) return FALSE;
+ return TRUE;
+}
+
+/* The caller provides a context */
+static void context_validate_onscreen_formats(struct wined3d_context *context,
+ const struct wined3d_surface *depth_stencil)
+{
+ /* Onscreen surfaces are always in a swapchain */
+ struct wined3d_swapchain *swapchain = context->current_rt->swapchain;
+
+ if (context->render_offscreen || !depth_stencil) return;
+ if (match_depth_stencil_format(swapchain->ds_format, depth_stencil->resource.format)) return;
+
+ /* TODO: If the requested format would satisfy the needs of the existing one(reverse match),
+ * or no onscreen depth buffer was created, the OpenGL drawable could be changed to the new
+ * format. */
+ WARN("Depth stencil format is not supported by WGL, rendering the backbuffer in an FBO\n");
+
+ /* The currently active context is the necessary context to access the swapchain's onscreen buffers */
+ surface_load_location(context->current_rt, SFLAG_INTEXTURE, NULL);
+ swapchain->render_to_fbo = TRUE;
+ swapchain_update_draw_bindings(swapchain);
+ context_set_render_offscreen(context, TRUE);
+}
+
+static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_device *device, const struct wined3d_surface *rt)
+{
+ if (!rt || rt->resource.format->id == WINED3DFMT_NULL)
+ return 0;
+ else if (rt->swapchain)
+ return context_generate_rt_mask_from_surface(rt);
+ else
+ return context_generate_rt_mask(device->offscreenBuffer);
+}
+
+/* Context activation is done by the caller. */
+void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device)
+{
+ struct wined3d_surface *rt = context->current_rt;
+ DWORD rt_mask, *cur_mask;
+
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ context_validate_onscreen_formats(context, NULL);
+
+ if (context->render_offscreen)
+ {
+ surface_internal_preload(rt, SRGB_RGB);
+
+ context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, rt, NULL, rt->draw_binding);
+ if (rt->resource.format->id != WINED3DFMT_NULL)
+ rt_mask = 1;
+ else
+ rt_mask = 0;
+ }
+ else
+ {
+ context->current_fbo = NULL;
+ context_bind_fbo(context, GL_FRAMEBUFFER, 0);
+ rt_mask = context_generate_rt_mask_from_surface(rt);
+ }
+ }
+ else
+ {
+ rt_mask = context_generate_rt_mask_no_fbo(device, rt);
+ }
+
+ cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask;
+
+ if (rt_mask != *cur_mask)
+ {
+ context_apply_draw_buffers(context, rt_mask);
+ *cur_mask = rt_mask;
+ }
+
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ context_check_fbo_status(context, GL_FRAMEBUFFER);
+ }
+
+ SetupForBlit(device, context);
+ context_invalidate_state(context, STATE_FRAMEBUFFER);
+}
+
+static BOOL context_validate_rt_config(UINT rt_count,
+ struct wined3d_surface * const *rts, const struct wined3d_surface *ds)
+{
+ unsigned int i;
+
+ if (ds) return TRUE;
+
+ for (i = 0; i < rt_count; ++i)
+ {
+ if (rts[i] && rts[i]->resource.format->id != WINED3DFMT_NULL)
+ return TRUE;
+ }
+
+ WARN("Invalid render target config, need at least one attachment.\n");
+ return FALSE;
+}
+
+/* Context activation is done by the caller. */
+BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_device *device,
+ UINT rt_count, const struct wined3d_fb_state *fb)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ DWORD rt_mask = 0, *cur_mask;
+ UINT i;
+ struct wined3d_surface **rts = fb->render_targets;
+
+ if (isStateDirty(context, STATE_FRAMEBUFFER) || fb != &device->fb
+ || rt_count != context->gl_info->limits.buffers)
+ {
+ if (!context_validate_rt_config(rt_count, rts, fb->depth_stencil))
+ return FALSE;
+
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ context_validate_onscreen_formats(context, fb->depth_stencil);
+
+ if (!rt_count || surface_is_offscreen(rts[0]))
+ {
+ for (i = 0; i < rt_count; ++i)
+ {
+ context->blit_targets[i] = rts[i];
+ if (rts[i] && rts[i]->resource.format->id != WINED3DFMT_NULL)
+ rt_mask |= (1 << i);
+ }
+ while (i < context->gl_info->limits.buffers)
+ {
+ context->blit_targets[i] = NULL;
+ ++i;
+ }
+ context_apply_fbo_state(context, GL_FRAMEBUFFER, context->blit_targets, fb->depth_stencil,
+ rt_count ? rts[0]->draw_binding : SFLAG_INTEXTURE);
+ }
+ else
+ {
+ context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL, SFLAG_INDRAWABLE);
+ rt_mask = context_generate_rt_mask_from_surface(rts[0]);
+ }
+
+ /* If the framebuffer is not the device's fb the device's fb has to be reapplied
+ * next draw. Otherwise we could mark the framebuffer state clean here, once the
+ * state management allows this */
+ context_invalidate_state(context, STATE_FRAMEBUFFER);
+ }
+ else
+ {
+ rt_mask = context_generate_rt_mask_no_fbo(device, rt_count ? rts[0] : NULL);
+ }
+ }
+ else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO
+ && (!rt_count || surface_is_offscreen(rts[0])))
+ {
+ for (i = 0; i < rt_count; ++i)
+ {
+ if (rts[i] && rts[i]->resource.format->id != WINED3DFMT_NULL) rt_mask |= (1 << i);
+ }
+ }
+ else
+ {
+ rt_mask = context_generate_rt_mask_no_fbo(device, rt_count ? rts[0] : NULL);
+ }
+
+ cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask;
+
+ if (rt_mask != *cur_mask)
+ {
+ context_apply_draw_buffers(context, rt_mask);
+ *cur_mask = rt_mask;
+ context_invalidate_state(context, STATE_FRAMEBUFFER);
+ }
+
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ context_check_fbo_status(context, GL_FRAMEBUFFER);
+ }
+
+ if (context->last_was_blit)
+ context->last_was_blit = FALSE;
+
+ /* Blending and clearing should be orthogonal, but tests on the nvidia
+ * driver show that disabling blending when clearing improves the clearing
+ * performance incredibly. */
+ gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
+ gl_info->gl_ops.gl.p_glEnable(GL_SCISSOR_TEST);
+ checkGLcall("glEnable GL_SCISSOR_TEST");
+
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE));
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE));
+ context_invalidate_state(context, STATE_SCISSORRECT);
+
+ return TRUE;
+}
+
+static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const struct wined3d_device *device)
+{
+ const struct wined3d_state *state = &device->stateBlock->state;
+ struct wined3d_surface **rts = state->fb->render_targets;
+ struct wined3d_shader *ps = state->pixel_shader;
+ DWORD rt_mask, rt_mask_bits;
+ unsigned int i;
+
+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return context_generate_rt_mask_no_fbo(device, rts[0]);
+ else if (!context->render_offscreen) return context_generate_rt_mask_from_surface(rts[0]);
+
+ rt_mask = ps ? ps->reg_maps.rt_mask : 1;
+ rt_mask &= context->d3d_info->valid_rt_mask;
+ rt_mask_bits = rt_mask;
+ i = 0;
+ while (rt_mask_bits)
+ {
+ rt_mask_bits &= ~(1 << i);
+ if (!rts[i] || rts[i]->resource.format->id == WINED3DFMT_NULL)
+ rt_mask &= ~(1 << i);
+
+ i++;
+ }
+
+ return rt_mask;
+}
+
+/* Context activation is done by the caller. */
+void context_state_fb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_device *device = context->swapchain->device;
+ const struct wined3d_fb_state *fb = state->fb;
+ DWORD rt_mask = find_draw_buffers_mask(context, device);
+ DWORD *cur_mask;
+
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ if (!context->render_offscreen)
+ {
+ context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL, SFLAG_INDRAWABLE);
+ }
+ else
+ {
+ context_apply_fbo_state(context, GL_FRAMEBUFFER, fb->render_targets, fb->depth_stencil,
+ fb->render_targets[0]->draw_binding);
+ }
+ }
+
+ cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask;
+ if (rt_mask != *cur_mask)
+ {
+ context_apply_draw_buffers(context, rt_mask);
+ *cur_mask = rt_mask;
+ }
+}
+
+/* Context activation is done by the caller. */
+void context_state_drawbuf(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_device *device = context->swapchain->device;
+ DWORD rt_mask, *cur_mask;
+
+ if (isStateDirty(context, STATE_FRAMEBUFFER)) return;
+
+ cur_mask = context->current_fbo ? &context->current_fbo->rt_mask : &context->draw_buffers_mask;
+ rt_mask = find_draw_buffers_mask(context, device);
+ if (rt_mask != *cur_mask)
+ {
+ context_apply_draw_buffers(context, rt_mask);
+ *cur_mask = rt_mask;
+ }
+}
+
+/* Context activation is done by the caller. */
+BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_device *device)
+{
+ const struct wined3d_state *state = &device->stateBlock->state;
+ const struct StateEntry *state_table = context->state_table;
+ const struct wined3d_fb_state *fb = state->fb;
+ unsigned int i;
+
+ if (!context_validate_rt_config(context->gl_info->limits.buffers,
+ fb->render_targets, fb->depth_stencil))
+ return FALSE;
+
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && isStateDirty(context, STATE_FRAMEBUFFER))
+ {
+ context_validate_onscreen_formats(context, fb->depth_stencil);
+ }
+
+ /* Preload resources before FBO setup. Texture preload in particular may
+ * result in changes to the current FBO, due to using e.g. FBO blits for
+ * updating a resource location. */
+ device_update_tex_unit_map(device);
+ device_preload_textures(device);
+ if (isStateDirty(context, STATE_VDECL) || isStateDirty(context, STATE_STREAMSRC))
+ device_update_stream_info(device, context->gl_info);
+ if (state->index_buffer)
+ {
+ if (device->stream_info.all_vbo)
+ wined3d_buffer_preload(state->index_buffer);
+ else
+ buffer_get_sysmem(state->index_buffer, context->gl_info);
+ }
+
+ for (i = 0; i < context->numDirtyEntries; ++i)
+ {
+ DWORD rep = context->dirtyArray[i];
+ DWORD idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT);
+ BYTE shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1);
+ context->isStateDirty[idx] &= ~(1 << shift);
+ state_table[rep].apply(context, state, rep);
+ }
+
+ if (context->select_shader)
+ {
+ device->shader_backend->shader_select(device->shader_priv, context, state);
+ context->select_shader = 0;
+ }
+
+ if (context->load_constants)
+ {
+ device->shader_backend->shader_load_constants(device->shader_priv,
+ context, state);
+ context->load_constants = 0;
+ }
+
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ context_check_fbo_status(context, GL_FRAMEBUFFER);
+ }
+
+ context->numDirtyEntries = 0; /* This makes the whole list clean */
+ context->last_was_blit = FALSE;
+
+ return TRUE;
+}
+
+static void context_setup_target(struct wined3d_context *context, struct wined3d_surface *target)
+{
+ BOOL old_render_offscreen = context->render_offscreen, render_offscreen;
+
+ render_offscreen = surface_is_offscreen(target);
+ if (context->current_rt == target && render_offscreen == old_render_offscreen) return;
+
+ /* To compensate the lack of format switching with some offscreen rendering methods and on onscreen buffers
+ * the alpha blend state changes with different render target formats. */
+ if (!context->current_rt)
+ {
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE));
+ }
+ else
+ {
+ const struct wined3d_format *old = context->current_rt->resource.format;
+ const struct wined3d_format *new = target->resource.format;
+
+ if (old->id != new->id)
+ {
+ /* Disable blending when the alpha mask has changed and when a format doesn't support blending. */
+ if ((old->alpha_size && !new->alpha_size) || (!old->alpha_size && new->alpha_size)
+ || !(new->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE));
+
+ /* Update sRGB writing when switching between formats that do/do not support sRGB writing */
+ if ((old->flags & WINED3DFMT_FLAG_SRGB_WRITE) != (new->flags & WINED3DFMT_FLAG_SRGB_WRITE))
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE));
+ }
+
+ /* When switching away from an offscreen render target, and we're not
+ * using FBOs, we have to read the drawable into the texture. This is
+ * done via PreLoad (and SFLAG_INDRAWABLE set on the surface). There
+ * are some things that need care though. PreLoad needs a GL context,
+ * and FindContext is called before the context is activated. It also
+ * has to be called with the old rendertarget active, otherwise a
+ * wrong drawable is read. */
+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
+ && old_render_offscreen && context->current_rt != target)
+ {
+ /* Read the back buffer of the old drawable into the destination texture. */
+ if (context->current_rt->texture_name_srgb)
+ surface_internal_preload(context->current_rt, SRGB_SRGB);
+ surface_internal_preload(context->current_rt, SRGB_RGB);
+ surface_modify_location(context->current_rt, SFLAG_INDRAWABLE, FALSE);
+ }
+ }
+
+ context->current_rt = target;
+ context_set_render_offscreen(context, render_offscreen);
+}
+
+/* Do not call while under the GL lock. */
+struct wined3d_context *context_acquire(const struct wined3d_device *device, struct wined3d_surface *target)
+{
+ struct wined3d_context *current_context = context_get_current();
+ struct wined3d_context *context;
+#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
+ struct wined3d_swapchain *swapchain = NULL;
+#endif
+
+ TRACE("device %p, target %p.\n", device, target);
+
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ if (current_context && current_context->destroyed)
+ current_context = NULL;
+#endif
+
+ if (!target)
+ {
+ if (current_context
+ && current_context->current_rt
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ && current_context->swapchain->device == device
+#else
+ && current_context->device == device
+#endif
+ )
+ {
+ target = current_context->current_rt;
+ }
+ else
+ {
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ struct wined3d_swapchain *swapchain = device->swapchains[0];
+#else
+ swapchain = swapchain_find_valid_or_any(device);
+ if (!swapchain)
+ {
+ ERR("no valid swapchain found!");
+ swapchain = device->swapchains[0];
+ Assert(swapchain);
+ }
+#endif
+ if (swapchain->back_buffers)
+ target = swapchain->back_buffers[0];
+ else
+ target = swapchain->front_buffer;
+ }
+ }
+
+#ifdef VBOX_WITH_WINE_DBG
+ Assert(target);
+#endif
+
+ if (current_context && current_context->current_rt == target)
+ {
+ context = current_context;
+ }
+ else if (target->swapchain)
+ {
+ TRACE("Rendering onscreen.\n");
+
+ context = swapchain_get_context(target->swapchain);
+#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
+ swapchain = target->swapchain;
+ Assert(swapchain);
+#endif
+ }
+ else
+ {
+ TRACE("Rendering offscreen.\n");
+
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ /* Stay with the current context if possible. Otherwise use the
+ * context for the primary swapchain. */
+ if (current_context && current_context->swapchain->device == device)
+ context = current_context;
+ else
+#endif
+ context = swapchain_get_context(device->swapchains[0]);
+ }
+
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ context_update_window(context);
+#else
+ if (!swapchain)
+ swapchain = swapchain_find_valid_or_any(device);
+ context_update_window(context, swapchain);
+#endif
+ context_setup_target(context, target);
+ context_enter(context);
+ if (!context->valid) return context;
+
+ if (context != current_context)
+ {
+ if (!context_set_current(context))
+ ERR("Failed to activate the new context.\n");
+ }
+ else if (context->restore_ctx)
+ {
+ context_set_gl_context(context);
+ }
+
+ return context;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/device.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/device.c
new file mode 100644
index 00000000..9f7c5f6b
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/device.c
@@ -0,0 +1,5835 @@
+/*
+ * Copyright 2002 Lionel Ulmer
+ * Copyright 2002-2005 Jason Edmeades
+ * Copyright 2003-2004 Raphael Junqueira
+ * Copyright 2004 Christian Costa
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2006-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2006-2008 Henri Verbeet
+ * Copyright 2007 Andrew Riedi
+ * Copyright 2009-2011 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
+#ifdef HAVE_FLOAT_H
+# include <float.h>
+#endif
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
+
+/* Define the default light parameters as specified by MSDN. */
+const struct wined3d_light WINED3D_default_light =
+{
+ WINED3D_LIGHT_DIRECTIONAL, /* Type */
+ { 1.0f, 1.0f, 1.0f, 0.0f }, /* Diffuse r,g,b,a */
+ { 0.0f, 0.0f, 0.0f, 0.0f }, /* Specular r,g,b,a */
+ { 0.0f, 0.0f, 0.0f, 0.0f }, /* Ambient r,g,b,a, */
+ { 0.0f, 0.0f, 0.0f }, /* Position x,y,z */
+ { 0.0f, 0.0f, 1.0f }, /* Direction x,y,z */
+ 0.0f, /* Range */
+ 0.0f, /* Falloff */
+ 0.0f, 0.0f, 0.0f, /* Attenuation 0,1,2 */
+ 0.0f, /* Theta */
+ 0.0f /* Phi */
+};
+
+/* Note that except for WINED3DPT_POINTLIST and WINED3DPT_LINELIST these
+ * actually have the same values in GL and D3D. */
+GLenum gl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type)
+{
+ switch(primitive_type)
+ {
+ case WINED3D_PT_POINTLIST:
+ return GL_POINTS;
+
+ case WINED3D_PT_LINELIST:
+ return GL_LINES;
+
+ case WINED3D_PT_LINESTRIP:
+ return GL_LINE_STRIP;
+
+ case WINED3D_PT_TRIANGLELIST:
+ return GL_TRIANGLES;
+
+ case WINED3D_PT_TRIANGLESTRIP:
+ return GL_TRIANGLE_STRIP;
+
+ case WINED3D_PT_TRIANGLEFAN:
+ return GL_TRIANGLE_FAN;
+
+ case WINED3D_PT_LINELIST_ADJ:
+ return GL_LINES_ADJACENCY_ARB;
+
+ case WINED3D_PT_LINESTRIP_ADJ:
+ return GL_LINE_STRIP_ADJACENCY_ARB;
+
+ case WINED3D_PT_TRIANGLELIST_ADJ:
+ return GL_TRIANGLES_ADJACENCY_ARB;
+
+ case WINED3D_PT_TRIANGLESTRIP_ADJ:
+ return GL_TRIANGLE_STRIP_ADJACENCY_ARB;
+
+ default:
+ FIXME("Unhandled primitive type %s\n", debug_d3dprimitivetype(primitive_type));
+ return GL_NONE;
+ }
+}
+
+static enum wined3d_primitive_type d3d_primitive_type_from_gl(GLenum primitive_type)
+{
+ switch(primitive_type)
+ {
+ case GL_POINTS:
+ return WINED3D_PT_POINTLIST;
+
+ case GL_LINES:
+ return WINED3D_PT_LINELIST;
+
+ case GL_LINE_STRIP:
+ return WINED3D_PT_LINESTRIP;
+
+ case GL_TRIANGLES:
+ return WINED3D_PT_TRIANGLELIST;
+
+ case GL_TRIANGLE_STRIP:
+ return WINED3D_PT_TRIANGLESTRIP;
+
+ case GL_TRIANGLE_FAN:
+ return WINED3D_PT_TRIANGLEFAN;
+
+ case GL_LINES_ADJACENCY_ARB:
+ return WINED3D_PT_LINELIST_ADJ;
+
+ case GL_LINE_STRIP_ADJACENCY_ARB:
+ return WINED3D_PT_LINESTRIP_ADJ;
+
+ case GL_TRIANGLES_ADJACENCY_ARB:
+ return WINED3D_PT_TRIANGLELIST_ADJ;
+
+ case GL_TRIANGLE_STRIP_ADJACENCY_ARB:
+ return WINED3D_PT_TRIANGLESTRIP_ADJ;
+
+ default:
+ FIXME("Unhandled primitive type %s\n", debug_d3dprimitivetype(primitive_type));
+ return WINED3D_PT_UNDEFINED;
+ }
+}
+
+static BOOL fixed_get_input(BYTE usage, BYTE usage_idx, unsigned int *regnum)
+{
+ if ((usage == WINED3D_DECL_USAGE_POSITION || usage == WINED3D_DECL_USAGE_POSITIONT) && !usage_idx)
+ *regnum = WINED3D_FFP_POSITION;
+ else if (usage == WINED3D_DECL_USAGE_BLEND_WEIGHT && !usage_idx)
+ *regnum = WINED3D_FFP_BLENDWEIGHT;
+ else if (usage == WINED3D_DECL_USAGE_BLEND_INDICES && !usage_idx)
+ *regnum = WINED3D_FFP_BLENDINDICES;
+ else if (usage == WINED3D_DECL_USAGE_NORMAL && !usage_idx)
+ *regnum = WINED3D_FFP_NORMAL;
+ else if (usage == WINED3D_DECL_USAGE_PSIZE && !usage_idx)
+ *regnum = WINED3D_FFP_PSIZE;
+ else if (usage == WINED3D_DECL_USAGE_COLOR && !usage_idx)
+ *regnum = WINED3D_FFP_DIFFUSE;
+ else if (usage == WINED3D_DECL_USAGE_COLOR && usage_idx == 1)
+ *regnum = WINED3D_FFP_SPECULAR;
+ else if (usage == WINED3D_DECL_USAGE_TEXCOORD && usage_idx < WINED3DDP_MAXTEXCOORD)
+ *regnum = WINED3D_FFP_TEXCOORD0 + usage_idx;
+ else
+ {
+ FIXME("Unsupported input stream [usage=%s, usage_idx=%u]\n", debug_d3ddeclusage(usage), usage_idx);
+ *regnum = ~0U;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Context activation is done by the caller. */
+static void device_stream_info_from_declaration(struct wined3d_device *device, struct wined3d_stream_info *stream_info)
+{
+ const struct wined3d_state *state = &device->stateBlock->state;
+ /* We need to deal with frequency data! */
+ struct wined3d_vertex_declaration *declaration = state->vertex_declaration;
+ BOOL use_vshader;
+ unsigned int i;
+ WORD map;
+
+ stream_info->use_map = 0;
+ stream_info->swizzle_map = 0;
+ stream_info->all_vbo = 1;
+
+ /* Check for transformed vertices, disable vertex shader if present. */
+ stream_info->position_transformed = declaration->position_transformed;
+ use_vshader = state->vertex_shader && !declaration->position_transformed;
+
+ /* Translate the declaration into strided data. */
+ for (i = 0; i < declaration->element_count; ++i)
+ {
+ const struct wined3d_vertex_declaration_element *element = &declaration->elements[i];
+ const struct wined3d_stream_state *stream = &state->streams[element->input_slot];
+ struct wined3d_buffer *buffer = stream->buffer;
+ struct wined3d_bo_address data;
+ BOOL stride_used;
+ unsigned int idx;
+ DWORD stride;
+
+ TRACE("%p Element %p (%u of %u)\n", declaration->elements,
+ element, i + 1, declaration->element_count);
+
+ if (!buffer) continue;
+
+ stride = stream->stride;
+
+ TRACE("Stream %u, buffer %p.\n", element->input_slot, buffer);
+ buffer_get_memory(buffer, &device->adapter->gl_info, &data);
+
+ /* We can't use VBOs if the base vertex index is negative. OpenGL
+ * doesn't accept negative offsets (or rather offsets bigger than the
+ * VBO, because the pointer is unsigned), so use system memory
+ * sources. In most sane cases the pointer - offset will still be > 0,
+ * otherwise it will wrap around to some big value. Hope that with the
+ * indices, the driver wraps it back internally. If not,
+ * drawStridedSlow() is needed, including a vertex buffer path. */
+
+ if (state->load_base_vertex_index < 0)
+ {
+ WARN_(d3d_perf)("load_base_vertex_index is < 0 (%d), not using VBOs.\n", state->load_base_vertex_index);
+ data.buffer_object = 0;
+ data.addr = buffer_get_sysmem(buffer, &device->adapter->gl_info);
+ if ((UINT_PTR)data.addr < -state->load_base_vertex_index * stride)
+ FIXME("System memory vertex data load offset is negative!\n");
+ }
+ data.addr += element->offset;
+
+ TRACE("offset %u input_slot %u usage_idx %d\n", element->offset, element->input_slot, element->usage_idx);
+
+ if (use_vshader)
+ {
+ if (element->output_slot == ~0U)
+ {
+ /* TODO: Assuming vertexdeclarations are usually used with the
+ * same or a similar shader, it might be worth it to store the
+ * last used output slot and try that one first. */
+ stride_used = vshader_get_input(state->vertex_shader,
+ element->usage, element->usage_idx, &idx);
+ }
+ else
+ {
+ idx = element->output_slot;
+ stride_used = TRUE;
+ }
+ }
+ else
+ {
+ if (!element->ffp_valid)
+ {
+ WARN("Skipping unsupported fixed function element of format %s and usage %s\n",
+ debug_d3dformat(element->format->id), debug_d3ddeclusage(element->usage));
+ stride_used = FALSE;
+ }
+ else
+ {
+ stride_used = fixed_get_input(element->usage, element->usage_idx, &idx);
+ }
+ }
+
+ if (stride_used)
+ {
+ TRACE("Load %s array %u [usage %s, usage_idx %u, "
+ "input_slot %u, offset %u, stride %u, format %s, buffer_object %u]\n",
+ use_vshader ? "shader": "fixed function", idx,
+ debug_d3ddeclusage(element->usage), element->usage_idx, element->input_slot,
+ element->offset, stride, debug_d3dformat(element->format->id), data.buffer_object);
+
+ data.addr += stream->offset;
+
+ stream_info->elements[idx].format = element->format;
+ stream_info->elements[idx].data = data;
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ stream_info->elements[idx].offset = element->offset;
+#endif
+ stream_info->elements[idx].stride = stride;
+ stream_info->elements[idx].stream_idx = element->input_slot;
+
+ if (!device->adapter->gl_info.supported[ARB_VERTEX_ARRAY_BGRA]
+ && element->format->id == WINED3DFMT_B8G8R8A8_UNORM)
+ {
+ stream_info->swizzle_map |= 1 << idx;
+ }
+ stream_info->use_map |= 1 << idx;
+ }
+ }
+
+ /* Preload the vertex buffers. */
+ device->num_buffer_queries = 0;
+ for (i = 0, map = stream_info->use_map; map; map >>= 1, ++i)
+ {
+ struct wined3d_stream_info_element *element;
+ struct wined3d_buffer *buffer;
+
+ if (!(map & 1))
+ continue;
+
+ element = &stream_info->elements[i];
+ buffer = state->streams[element->stream_idx].buffer;
+ wined3d_buffer_preload(buffer);
+
+ /* If the preload dropped the buffer object, update the stream info. */
+ if (
+#ifdef VBOX_WITH_WINE_FIX_STRINFOBUF
+ element->data.buffer_object &&
+#endif
+ buffer->buffer_object != element->data.buffer_object)
+ {
+ element->data.buffer_object = 0;
+ element->data.addr = buffer_get_sysmem(buffer, &device->adapter->gl_info) + (ptrdiff_t)element->data.addr;
+ }
+
+ if (!buffer->buffer_object)
+ stream_info->all_vbo = 0;
+
+ if (buffer->query)
+ device->buffer_queries[device->num_buffer_queries++] = buffer->query;
+ }
+}
+
+/* Context activation is done by the caller. */
+void device_update_stream_info(struct wined3d_device *device, const struct wined3d_gl_info *gl_info)
+{
+ struct wined3d_stream_info *stream_info = &device->stream_info;
+ const struct wined3d_state *state = &device->stateBlock->state;
+ DWORD prev_all_vbo = stream_info->all_vbo;
+
+ TRACE("============================= Vertex Declaration =============================\n");
+ device_stream_info_from_declaration(device, stream_info);
+
+ if (state->vertex_shader && !stream_info->position_transformed)
+ {
+ if (state->vertex_declaration->half_float_conv_needed && !stream_info->all_vbo)
+ {
+ TRACE("Using drawStridedSlow with vertex shaders for FLOAT16 conversion.\n");
+ device->useDrawStridedSlow = TRUE;
+ }
+ else
+ {
+ device->useDrawStridedSlow = FALSE;
+ }
+ }
+ else
+ {
+ WORD slow_mask = (1 << WINED3D_FFP_PSIZE);
+ slow_mask |= -!gl_info->supported[ARB_VERTEX_ARRAY_BGRA]
+ & ((1 << WINED3D_FFP_DIFFUSE) | (1 << WINED3D_FFP_SPECULAR));
+
+ if (((stream_info->position_transformed && !device->adapter->d3d_info.xyzrhw)
+ || (stream_info->use_map & slow_mask)) && !stream_info->all_vbo)
+ device->useDrawStridedSlow = TRUE;
+ else
+ device->useDrawStridedSlow = FALSE;
+ }
+
+ if (prev_all_vbo != stream_info->all_vbo)
+ device_invalidate_state(device, STATE_INDEXBUFFER);
+}
+
+static void device_preload_texture(const struct wined3d_state *state, unsigned int idx)
+{
+ struct wined3d_texture *texture;
+ enum WINED3DSRGB srgb;
+
+ if (!(texture = state->textures[idx])) return;
+ srgb = state->sampler_states[idx][WINED3D_SAMP_SRGB_TEXTURE] ? SRGB_SRGB : SRGB_RGB;
+ texture->texture_ops->texture_preload(texture, srgb);
+}
+
+void device_preload_textures(const struct wined3d_device *device)
+{
+ const struct wined3d_state *state = &device->stateBlock->state;
+ unsigned int i;
+
+ if (use_vs(state))
+ {
+ for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i)
+ {
+ if (state->vertex_shader->reg_maps.sampler_type[i])
+ device_preload_texture(state, MAX_FRAGMENT_SAMPLERS + i);
+ }
+ }
+
+ if (use_ps(state))
+ {
+ for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
+ {
+ if (state->pixel_shader->reg_maps.sampler_type[i])
+ device_preload_texture(state, i);
+ }
+ }
+ else
+ {
+ WORD ffu_map = device->fixed_function_usage_map;
+
+ for (i = 0; ffu_map; ffu_map >>= 1, ++i)
+ {
+ if (ffu_map & 1)
+ device_preload_texture(state, i);
+ }
+ }
+}
+
+BOOL device_context_add(struct wined3d_device *device, struct wined3d_context *context)
+{
+ struct wined3d_context **new_array;
+
+ TRACE("Adding context %p.\n", context);
+
+ if (!device->contexts) new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_array));
+ else new_array = HeapReAlloc(GetProcessHeap(), 0, device->contexts,
+ sizeof(*new_array) * (device->context_count + 1));
+
+ if (!new_array)
+ {
+ ERR("Failed to grow the context array.\n");
+ return FALSE;
+ }
+
+ new_array[device->context_count++] = context;
+ device->contexts = new_array;
+ return TRUE;
+}
+
+void device_context_remove(struct wined3d_device *device, struct wined3d_context *context)
+{
+ struct wined3d_context **new_array;
+ BOOL found = FALSE;
+ UINT i;
+
+ TRACE("Removing context %p.\n", context);
+
+ for (i = 0; i < device->context_count; ++i)
+ {
+ if (device->contexts[i] == context)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ ERR("Context %p doesn't exist in context array.\n", context);
+ return;
+ }
+
+ if (!--device->context_count)
+ {
+ HeapFree(GetProcessHeap(), 0, device->contexts);
+ device->contexts = NULL;
+ return;
+ }
+
+ memmove(&device->contexts[i], &device->contexts[i + 1], (device->context_count - i) * sizeof(*device->contexts));
+ new_array = HeapReAlloc(GetProcessHeap(), 0, device->contexts, device->context_count * sizeof(*device->contexts));
+ if (!new_array)
+ {
+ ERR("Failed to shrink context array. Oh well.\n");
+ return;
+ }
+
+ device->contexts = new_array;
+}
+
+/* Do not call while under the GL lock. */
+void device_switch_onscreen_ds(struct wined3d_device *device,
+ struct wined3d_context *context, struct wined3d_surface *depth_stencil)
+{
+ if (device->onscreen_depth_stencil)
+ {
+ surface_load_ds_location(device->onscreen_depth_stencil, context, SFLAG_INTEXTURE);
+
+ surface_modify_ds_location(device->onscreen_depth_stencil, SFLAG_INTEXTURE,
+ device->onscreen_depth_stencil->ds_current_size.cx,
+ device->onscreen_depth_stencil->ds_current_size.cy);
+ wined3d_surface_decref(device->onscreen_depth_stencil);
+ }
+ device->onscreen_depth_stencil = depth_stencil;
+ wined3d_surface_incref(device->onscreen_depth_stencil);
+}
+
+static BOOL is_full_clear(const struct wined3d_surface *target, const RECT *draw_rect, const RECT *clear_rect)
+{
+ /* partial draw rect */
+ if (draw_rect->left || draw_rect->top
+ || draw_rect->right < target->resource.width
+ || draw_rect->bottom < target->resource.height)
+ return FALSE;
+
+ /* partial clear rect */
+ if (clear_rect && (clear_rect->left > 0 || clear_rect->top > 0
+ || clear_rect->right < target->resource.width
+ || clear_rect->bottom < target->resource.height))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void prepare_ds_clear(struct wined3d_surface *ds, struct wined3d_context *context,
+ DWORD location, const RECT *draw_rect, UINT rect_count, const RECT *clear_rect, RECT *out_rect)
+{
+ RECT current_rect, r;
+
+ if (ds->flags & SFLAG_DISCARDED)
+ {
+ /* Depth buffer was discarded, make it entirely current in its new location since
+ * there is no other place where we would get data anyway. */
+ SetRect(out_rect, 0, 0, ds->resource.width, ds->resource.height);
+ return;
+ }
+
+ if (ds->flags & location)
+ SetRect(&current_rect, 0, 0,
+ ds->ds_current_size.cx,
+ ds->ds_current_size.cy);
+ else
+ SetRectEmpty(&current_rect);
+
+ IntersectRect(&r, draw_rect, &current_rect);
+ if (EqualRect(&r, draw_rect))
+ {
+ /* current_rect ⊇ draw_rect, modify only. */
+ SetRect(out_rect, 0, 0, ds->ds_current_size.cx, ds->ds_current_size.cy);
+ return;
+ }
+
+ if (EqualRect(&r, &current_rect))
+ {
+ /* draw_rect ⊇ current_rect, test if we're doing a full clear. */
+
+ if (!clear_rect)
+ {
+ /* Full clear, modify only. */
+ *out_rect = *draw_rect;
+ return;
+ }
+
+ IntersectRect(&r, draw_rect, clear_rect);
+ if (EqualRect(&r, draw_rect))
+ {
+ /* clear_rect ⊇ draw_rect, modify only. */
+ *out_rect = *draw_rect;
+ return;
+ }
+ }
+
+ /* Full load. */
+ surface_load_ds_location(ds, context, location);
+ SetRect(out_rect, 0, 0, ds->ds_current_size.cx, ds->ds_current_size.cy);
+}
+
+/* Do not call while under the GL lock. */
+void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, const struct wined3d_fb_state *fb,
+ UINT rect_count, const RECT *rects, const RECT *draw_rect, DWORD flags, const struct wined3d_color *color,
+ float depth, DWORD stencil)
+{
+ const RECT *clear_rect = (rect_count > 0 && rects) ? (const RECT *)rects : NULL;
+ struct wined3d_surface *target = rt_count ? fb->render_targets[0] : NULL;
+ const struct wined3d_gl_info *gl_info;
+ UINT drawable_width, drawable_height;
+ struct wined3d_context *context;
+ GLbitfield clear_mask = 0;
+ BOOL render_offscreen;
+ unsigned int i;
+ RECT ds_rect;
+
+ /* When we're clearing parts of the drawable, make sure that the target surface is well up to date in the
+ * drawable. After the clear we'll mark the drawable up to date, so we have to make sure that this is true
+ * for the cleared parts, and the untouched parts.
+ *
+ * If we're clearing the whole target there is no need to copy it into the drawable, it will be overwritten
+ * anyway. If we're not clearing the color buffer we don't have to copy either since we're not going to set
+ * the drawable up to date. We have to check all settings that limit the clear area though. Do not bother
+ * checking all this if the dest surface is in the drawable anyway. */
+ if (flags & WINED3DCLEAR_TARGET && !is_full_clear(target, draw_rect, clear_rect))
+ {
+ for (i = 0; i < rt_count; ++i)
+ {
+ struct wined3d_surface *rt = fb->render_targets[i];
+ if (rt)
+ surface_load_location(rt, rt->draw_binding, NULL);
+ }
+ }
+
+ context = context_acquire(device, target);
+ if (!context->valid)
+ {
+ context_release(context);
+ WARN("Invalid context, skipping clear.\n");
+ return;
+ }
+ gl_info = context->gl_info;
+
+ if (target)
+ {
+ render_offscreen = context->render_offscreen;
+ target->get_drawable_size(context, &drawable_width, &drawable_height);
+ }
+ else
+ {
+ render_offscreen = TRUE;
+ drawable_width = fb->depth_stencil->pow2Width;
+ drawable_height = fb->depth_stencil->pow2Height;
+ }
+
+ if (flags & WINED3DCLEAR_ZBUFFER)
+ {
+ DWORD location = render_offscreen ? fb->depth_stencil->draw_binding : SFLAG_INDRAWABLE;
+
+ if (!render_offscreen && fb->depth_stencil != device->onscreen_depth_stencil)
+ device_switch_onscreen_ds(device, context, fb->depth_stencil);
+ prepare_ds_clear(fb->depth_stencil, context, location,
+ draw_rect, rect_count, clear_rect, &ds_rect);
+ }
+
+ if (!context_apply_clear_state(context, device, rt_count, fb))
+ {
+ context_release(context);
+ WARN("Failed to apply clear state, skipping clear.\n");
+ return;
+ }
+
+ /* Only set the values up once, as they are not changing. */
+ if (flags & WINED3DCLEAR_STENCIL)
+ {
+ if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE));
+ }
+ gl_info->gl_ops.gl.p_glStencilMask(~0U);
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK));
+ gl_info->gl_ops.gl.p_glClearStencil(stencil);
+ checkGLcall("glClearStencil");
+ clear_mask = clear_mask | GL_STENCIL_BUFFER_BIT;
+ }
+
+ if (flags & WINED3DCLEAR_ZBUFFER)
+ {
+ DWORD location = render_offscreen ? fb->depth_stencil->draw_binding : SFLAG_INDRAWABLE;
+
+ surface_modify_ds_location(fb->depth_stencil, location, ds_rect.right, ds_rect.bottom);
+
+ gl_info->gl_ops.gl.p_glDepthMask(GL_TRUE);
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZWRITEENABLE));
+ gl_info->gl_ops.gl.p_glClearDepth(depth);
+ checkGLcall("glClearDepth");
+ clear_mask = clear_mask | GL_DEPTH_BUFFER_BIT;
+ }
+
+ if (flags & WINED3DCLEAR_TARGET)
+ {
+ for (i = 0; i < rt_count; ++i)
+ {
+ struct wined3d_surface *rt = fb->render_targets[i];
+
+ if (rt)
+ surface_modify_location(rt, rt->draw_binding, TRUE);
+ }
+
+ gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE));
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1));
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2));
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3));
+ gl_info->gl_ops.gl.p_glClearColor(color->r, color->g, color->b, color->a);
+ checkGLcall("glClearColor");
+ clear_mask = clear_mask | GL_COLOR_BUFFER_BIT;
+ }
+
+ if (!clear_rect)
+ {
+ if (render_offscreen)
+ {
+ gl_info->gl_ops.gl.p_glScissor(draw_rect->left, draw_rect->top,
+ draw_rect->right - draw_rect->left, draw_rect->bottom - draw_rect->top);
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glScissor(draw_rect->left, drawable_height - draw_rect->bottom,
+ draw_rect->right - draw_rect->left, draw_rect->bottom - draw_rect->top);
+ }
+ checkGLcall("glScissor");
+ gl_info->gl_ops.gl.p_glClear(clear_mask);
+ checkGLcall("glClear");
+ }
+ else
+ {
+ RECT current_rect;
+
+ /* Now process each rect in turn. */
+ for (i = 0; i < rect_count; ++i)
+ {
+ /* Note that GL uses lower left, width/height. */
+ IntersectRect(&current_rect, draw_rect, &clear_rect[i]);
+
+ TRACE("clear_rect[%u] %s, current_rect %s.\n", i,
+ wine_dbgstr_rect(&clear_rect[i]),
+ wine_dbgstr_rect(&current_rect));
+
+ /* Tests show that rectangles where x1 > x2 or y1 > y2 are ignored silently.
+ * The rectangle is not cleared, no error is returned, but further rectangles are
+ * still cleared if they are valid. */
+ if (current_rect.left > current_rect.right || current_rect.top > current_rect.bottom)
+ {
+ TRACE("Rectangle with negative dimensions, ignoring.\n");
+ continue;
+ }
+
+ if (render_offscreen)
+ {
+ gl_info->gl_ops.gl.p_glScissor(current_rect.left, current_rect.top,
+ current_rect.right - current_rect.left, current_rect.bottom - current_rect.top);
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glScissor(current_rect.left, drawable_height - current_rect.bottom,
+ current_rect.right - current_rect.left, current_rect.bottom - current_rect.top);
+ }
+ checkGLcall("glScissor");
+
+ gl_info->gl_ops.gl.p_glClear(clear_mask);
+ checkGLcall("glClear");
+ }
+ }
+
+ if (wined3d_settings.strict_draw_ordering || (flags & WINED3DCLEAR_TARGET
+ && target->swapchain && target->swapchain->front_buffer == target))
+ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
+
+ context_release(context);
+}
+
+ULONG CDECL wined3d_device_incref(struct wined3d_device *device)
+{
+ ULONG refcount = InterlockedIncrement(&device->ref);
+
+ TRACE("%p increasing refcount to %u.\n", device, refcount);
+
+ return refcount;
+}
+
+ULONG CDECL wined3d_device_decref(struct wined3d_device *device)
+{
+ ULONG refcount = InterlockedDecrement(&device->ref);
+
+ TRACE("%p decreasing refcount to %u.\n", device, refcount);
+
+ if (!refcount)
+ {
+ struct wined3d_stateblock *stateblock;
+ UINT i;
+
+ if (wined3d_stateblock_decref(device->updateStateBlock)
+ && device->updateStateBlock != device->stateBlock)
+ FIXME("Something's still holding the update stateblock.\n");
+ device->updateStateBlock = NULL;
+
+ stateblock = device->stateBlock;
+ device->stateBlock = NULL;
+ if (wined3d_stateblock_decref(stateblock))
+ FIXME("Something's still holding the stateblock.\n");
+
+ for (i = 0; i < sizeof(device->multistate_funcs) / sizeof(device->multistate_funcs[0]); ++i)
+ {
+ HeapFree(GetProcessHeap(), 0, device->multistate_funcs[i]);
+ device->multistate_funcs[i] = NULL;
+ }
+
+ if (!list_empty(&device->resources))
+ {
+ struct wined3d_resource *resource;
+
+ FIXME("Device released with resources still bound, acceptable but unexpected.\n");
+
+ LIST_FOR_EACH_ENTRY(resource, &device->resources, struct wined3d_resource, resource_list_entry)
+ {
+ FIXME("Leftover resource %p with type %s (%#x).\n",
+ resource, debug_d3dresourcetype(resource->type), resource->type);
+ }
+ }
+
+ if (device->contexts)
+ ERR("Context array not freed!\n");
+ if (device->hardwareCursor)
+ DestroyCursor(device->hardwareCursor);
+ device->hardwareCursor = 0;
+
+ wined3d_decref(device->wined3d);
+ device->wined3d = NULL;
+ HeapFree(GetProcessHeap(), 0, device);
+ TRACE("Freed device %p.\n", device);
+ }
+
+ return refcount;
+}
+
+UINT CDECL wined3d_device_get_swapchain_count(const struct wined3d_device *device)
+{
+ TRACE("device %p.\n", device);
+
+ return device->swapchain_count;
+}
+
+struct wined3d_swapchain * CDECL wined3d_device_get_swapchain(const struct wined3d_device *device, UINT swapchain_idx)
+{
+ TRACE("device %p, swapchain_idx %u.\n", device, swapchain_idx);
+
+ if (swapchain_idx >= device->swapchain_count)
+ {
+ WARN("swapchain_idx %u >= swapchain_count %u.\n",
+ swapchain_idx, device->swapchain_count);
+ return NULL;
+ }
+
+ return device->swapchains[swapchain_idx];
+}
+
+#ifndef VBOX
+static void device_load_logo(struct wined3d_device *device, const char *filename)
+{
+ struct wined3d_color_key color_key;
+ HBITMAP hbm;
+ BITMAP bm;
+ HRESULT hr;
+ HDC dcb = NULL, dcs = NULL;
+
+ hbm = LoadImageA(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
+ if(hbm)
+ {
+ GetObjectA(hbm, sizeof(BITMAP), &bm);
+ dcb = CreateCompatibleDC(NULL);
+ if(!dcb) goto out;
+ SelectObject(dcb, hbm);
+ }
+ else
+ {
+ /* Create a 32x32 white surface to indicate that wined3d is used, but the specified image
+ * couldn't be loaded
+ */
+ memset(&bm, 0, sizeof(bm));
+ bm.bmWidth = 32;
+ bm.bmHeight = 32;
+ }
+
+ hr = wined3d_surface_create(device, bm.bmWidth, bm.bmHeight, WINED3DFMT_B5G6R5_UNORM, 0,
+ WINED3D_POOL_SYSTEM_MEM, WINED3D_MULTISAMPLE_NONE, 0, WINED3D_SURFACE_MAPPABLE,
+ NULL, &wined3d_null_parent_ops, &device->logo_surface);
+ if (FAILED(hr))
+ {
+ ERR("Wine logo requested, but failed to create surface, hr %#x.\n", hr);
+ goto out;
+ }
+
+ if (dcb)
+ {
+ if (FAILED(hr = wined3d_surface_getdc(device->logo_surface, &dcs)))
+ goto out;
+ BitBlt(dcs, 0, 0, bm.bmWidth, bm.bmHeight, dcb, 0, 0, SRCCOPY);
+ wined3d_surface_releasedc(device->logo_surface, dcs);
+
+ color_key.color_space_low_value = 0;
+ color_key.color_space_high_value = 0;
+ wined3d_surface_set_color_key(device->logo_surface, WINEDDCKEY_SRCBLT, &color_key);
+ }
+ else
+ {
+ const struct wined3d_color c = {1.0f, 1.0f, 1.0f, 1.0f};
+ /* Fill the surface with a white color to show that wined3d is there */
+ wined3d_device_color_fill(device, device->logo_surface, NULL, &c);
+ }
+
+out:
+ if (dcb) DeleteDC(dcb);
+ if (hbm) DeleteObject(hbm);
+}
+#endif
+
+/* Context activation is done by the caller. */
+static void create_dummy_textures(struct wined3d_device *device, struct wined3d_context *context)
+{
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ unsigned int i, j, count;
+ /* Under DirectX you can sample even if no texture is bound, whereas
+ * OpenGL will only allow that when a valid texture is bound.
+ * We emulate this by creating dummy textures and binding them
+ * to each texture stage when the currently set D3D texture is NULL. */
+
+ if (gl_info->supported[APPLE_CLIENT_STORAGE])
+ {
+ /* The dummy texture does not have client storage backing */
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
+ checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)");
+ }
+
+ count = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers);
+ for (i = 0; i < count; ++i)
+ {
+ DWORD color = 0x000000ff;
+
+ /* Make appropriate texture active */
+ context_active_texture(context, gl_info, i);
+
+ gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_texture_2d[i]);
+ checkGLcall("glGenTextures");
+ TRACE("Dummy 2D texture %u given name %u.\n", i, device->dummy_texture_2d[i]);
+
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, device->dummy_texture_2d[i]);
+ checkGLcall("glBindTexture");
+
+ gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0,
+ GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
+ checkGLcall("glTexImage2D");
+
+ if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ {
+ gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_texture_rect[i]);
+ checkGLcall("glGenTextures");
+ TRACE("Dummy rectangle texture %u given name %u.\n", i, device->dummy_texture_rect[i]);
+
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_RECTANGLE_ARB, device->dummy_texture_rect[i]);
+ checkGLcall("glBindTexture");
+
+ gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, 1, 1, 0,
+ GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
+ checkGLcall("glTexImage2D");
+ }
+
+ if (gl_info->supported[EXT_TEXTURE3D])
+ {
+ gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_texture_3d[i]);
+ checkGLcall("glGenTextures");
+ TRACE("Dummy 3D texture %u given name %u.\n", i, device->dummy_texture_3d[i]);
+
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_3D, device->dummy_texture_3d[i]);
+ checkGLcall("glBindTexture");
+
+ GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color));
+ checkGLcall("glTexImage3D");
+ }
+
+ if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+ {
+ gl_info->gl_ops.gl.p_glGenTextures(1, &device->dummy_texture_cube[i]);
+ checkGLcall("glGenTextures");
+ TRACE("Dummy cube texture %u given name %u.\n", i, device->dummy_texture_cube[i]);
+
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_CUBE_MAP, device->dummy_texture_cube[i]);
+ checkGLcall("glBindTexture");
+
+ for (j = GL_TEXTURE_CUBE_MAP_POSITIVE_X; j <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++j)
+ {
+ gl_info->gl_ops.gl.p_glTexImage2D(j, 0, GL_RGBA8, 1, 1, 0,
+ GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &color);
+ checkGLcall("glTexImage2D");
+ }
+ }
+ }
+
+ if (gl_info->supported[APPLE_CLIENT_STORAGE])
+ {
+ /* Re-enable because if supported it is enabled by default */
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
+ checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
+ }
+}
+
+/* Context activation is done by the caller. */
+static void destroy_dummy_textures(struct wined3d_device *device, const struct wined3d_gl_info *gl_info)
+{
+ unsigned int count = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers);
+
+ if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+ {
+ gl_info->gl_ops.gl.p_glDeleteTextures(count, device->dummy_texture_cube);
+ checkGLcall("glDeleteTextures(count, device->dummy_texture_cube)");
+ }
+
+ if (gl_info->supported[EXT_TEXTURE3D])
+ {
+ gl_info->gl_ops.gl.p_glDeleteTextures(count, device->dummy_texture_3d);
+ checkGLcall("glDeleteTextures(count, device->dummy_texture_3d)");
+ }
+
+ if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ {
+ gl_info->gl_ops.gl.p_glDeleteTextures(count, device->dummy_texture_rect);
+ checkGLcall("glDeleteTextures(count, device->dummy_texture_rect)");
+ }
+
+ gl_info->gl_ops.gl.p_glDeleteTextures(count, device->dummy_texture_2d);
+ checkGLcall("glDeleteTextures(count, device->dummy_texture_2d)");
+
+ memset(device->dummy_texture_cube, 0, count * sizeof(*device->dummy_texture_cube));
+ memset(device->dummy_texture_3d, 0, count * sizeof(*device->dummy_texture_3d));
+ memset(device->dummy_texture_rect, 0, count * sizeof(*device->dummy_texture_rect));
+ memset(device->dummy_texture_2d, 0, count * sizeof(*device->dummy_texture_2d));
+}
+
+static LONG fullscreen_style(LONG style)
+{
+ /* Make sure the window is managed, otherwise we won't get keyboard input. */
+ style |= WS_POPUP | WS_SYSMENU;
+ style &= ~(WS_CAPTION | WS_THICKFRAME);
+
+ return style;
+}
+
+static LONG fullscreen_exstyle(LONG exstyle)
+{
+ /* Filter out window decorations. */
+ exstyle &= ~(WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE);
+
+ return exstyle;
+}
+
+void CDECL wined3d_device_setup_fullscreen_window(struct wined3d_device *device, HWND window, UINT w, UINT h)
+{
+ BOOL filter_messages;
+ LONG style, exstyle;
+
+ TRACE("Setting up window %p for fullscreen mode.\n", window);
+
+ if (device->style || device->exStyle)
+ {
+ ERR("Changing the window style for window %p, but another style (%08x, %08x) is already stored.\n",
+ window, device->style, device->exStyle);
+ }
+
+ device->style = GetWindowLongW(window, GWL_STYLE);
+ device->exStyle = GetWindowLongW(window, GWL_EXSTYLE);
+
+ style = fullscreen_style(device->style);
+ exstyle = fullscreen_exstyle(device->exStyle);
+
+ TRACE("Old style was %08x, %08x, setting to %08x, %08x.\n",
+ device->style, device->exStyle, style, exstyle);
+
+ filter_messages = device->filter_messages;
+ device->filter_messages = TRUE;
+
+ SetWindowLongW(window, GWL_STYLE, style);
+ SetWindowLongW(window, GWL_EXSTYLE, exstyle);
+ SetWindowPos(window, HWND_TOPMOST, 0, 0, w, h, SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE);
+
+ device->filter_messages = filter_messages;
+}
+
+void CDECL wined3d_device_restore_fullscreen_window(struct wined3d_device *device, HWND window)
+{
+ BOOL filter_messages;
+ LONG style, exstyle;
+
+ if (!device->style && !device->exStyle) return;
+
+ style = GetWindowLongW(window, GWL_STYLE);
+ exstyle = GetWindowLongW(window, GWL_EXSTYLE);
+
+ /* These flags are set by wined3d_device_setup_fullscreen_window, not the
+ * application, and we want to ignore them in the test below, since it's
+ * not the application's fault that they changed. Additionally, we want to
+ * preserve the current status of these flags (i.e. don't restore them) to
+ * more closely emulate the behavior of Direct3D, which leaves these flags
+ * alone when returning to windowed mode. */
+ device->style ^= (device->style ^ style) & WS_VISIBLE;
+ device->exStyle ^= (device->exStyle ^ exstyle) & WS_EX_TOPMOST;
+
+ TRACE("Restoring window style of window %p to %08x, %08x.\n",
+ window, device->style, device->exStyle);
+
+ filter_messages = device->filter_messages;
+ device->filter_messages = TRUE;
+
+ /* Only restore the style if the application didn't modify it during the
+ * fullscreen phase. Some applications change it before calling Reset()
+ * when switching between windowed and fullscreen modes (HL2), some
+ * depend on the original style (Eve Online). */
+ if (style == fullscreen_style(device->style) && exstyle == fullscreen_exstyle(device->exStyle))
+ {
+ SetWindowLongW(window, GWL_STYLE, device->style);
+ SetWindowLongW(window, GWL_EXSTYLE, device->exStyle);
+ }
+ SetWindowPos(window, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
+
+ device->filter_messages = filter_messages;
+
+ /* Delete the old values. */
+ device->style = 0;
+ device->exStyle = 0;
+}
+
+HRESULT CDECL wined3d_device_acquire_focus_window(struct wined3d_device *device, HWND window)
+{
+#ifndef VBOX_WITH_WDDM
+ TRACE("device %p, window %p.\n", device, window);
+
+ if (!wined3d_register_window(window, device))
+ {
+ ERR("Failed to register window %p.\n", window);
+ return E_FAIL;
+ }
+
+ InterlockedExchangePointer((void **)&device->focus_window, window);
+ SetWindowPos(window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
+
+ return WINED3D_OK;
+#else
+ ERR("unsupported!");
+ return E_FAIL;
+#endif
+}
+
+void CDECL wined3d_device_release_focus_window(struct wined3d_device *device)
+{
+#ifndef VBOX_WITH_WDDM
+ TRACE("device %p.\n", device);
+
+ if (device->focus_window) wined3d_unregister_window(device->focus_window);
+ InterlockedExchangePointer((void **)&device->focus_window, NULL);
+#else
+ ERR("unsupported!");
+#endif
+}
+
+HRESULT CDECL wined3d_device_init_3d(struct wined3d_device *device,
+ struct wined3d_swapchain_desc *swapchain_desc)
+{
+ static const struct wined3d_color black = {0.0f, 0.0f, 0.0f, 0.0f};
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ struct wined3d_swapchain *swapchain = NULL;
+ struct wined3d_context *context;
+ HRESULT hr;
+ DWORD state;
+
+ TRACE("device %p, swapchain_desc %p.\n", device, swapchain_desc);
+
+ if (device->d3d_initialized)
+ return WINED3DERR_INVALIDCALL;
+ if (device->wined3d->flags & WINED3D_NO3D)
+ return WINED3DERR_INVALIDCALL;
+
+#ifdef VBOX_WITH_WDDM
+ if (!swapchain_desc->pHgsmi)
+ {
+ ERR("hgsmi not specified!");
+ return WINED3DERR_INVALIDCALL;
+ }
+ device->pHgsmi = swapchain_desc->pHgsmi;
+#endif
+
+ device->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof(*device->fb.render_targets) * gl_info->limits.buffers);
+
+ /* Initialize the texture unit mapping to a 1:1 mapping */
+ for (state = 0; state < MAX_COMBINED_SAMPLERS; ++state)
+ {
+ if (state < gl_info->limits.fragment_samplers)
+ {
+ device->texUnitMap[state] = state;
+ device->rev_tex_unit_map[state] = state;
+ }
+ else
+ {
+ device->texUnitMap[state] = WINED3D_UNMAPPED_STAGE;
+ device->rev_tex_unit_map[state] = WINED3D_UNMAPPED_STAGE;
+ }
+ }
+
+ if (FAILED(hr = device->shader_backend->shader_alloc_private(device,
+ device->adapter->vertex_pipe, device->adapter->fragment_pipe)))
+ {
+ TRACE("Shader private data couldn't be allocated\n");
+ goto err_out;
+ }
+ if (FAILED(hr = device->blitter->alloc_private(device)))
+ {
+ TRACE("Blitter private data couldn't be allocated\n");
+ goto err_out;
+ }
+
+ /* Setup the implicit swapchain. This also initializes a context. */
+ TRACE("Creating implicit swapchain\n");
+ hr = device->device_parent->ops->create_swapchain(device->device_parent,
+ swapchain_desc, &swapchain);
+ if (FAILED(hr))
+ {
+ WARN("Failed to create implicit swapchain\n");
+ goto err_out;
+ }
+
+ device->swapchain_count = 1;
+ device->swapchains = HeapAlloc(GetProcessHeap(), 0, device->swapchain_count * sizeof(*device->swapchains));
+ if (!device->swapchains)
+ {
+ ERR("Out of memory!\n");
+ goto err_out;
+ }
+ device->swapchains[0] = swapchain;
+
+ if (swapchain->back_buffers && swapchain->back_buffers[0])
+ {
+ TRACE("Setting rendertarget to %p.\n", swapchain->back_buffers);
+ device->fb.render_targets[0] = swapchain->back_buffers[0];
+ }
+ else
+ {
+ TRACE("Setting rendertarget to %p.\n", swapchain->front_buffer);
+ device->fb.render_targets[0] = swapchain->front_buffer;
+ }
+ wined3d_surface_incref(device->fb.render_targets[0]);
+
+ /* Depth Stencil support */
+ device->fb.depth_stencil = device->auto_depth_stencil;
+ if (device->fb.depth_stencil)
+ wined3d_surface_incref(device->fb.depth_stencil);
+
+ /* Set up some starting GL setup */
+
+ /* Setup all the devices defaults */
+ stateblock_init_default_state(device->stateBlock);
+
+ context = context_acquire(device, swapchain->front_buffer);
+
+ create_dummy_textures(device, context);
+
+ device->contexts[0]->last_was_rhw = 0;
+
+ switch (wined3d_settings.offscreen_rendering_mode)
+ {
+ case ORM_FBO:
+ device->offscreenBuffer = GL_COLOR_ATTACHMENT0;
+ break;
+
+ case ORM_BACKBUFFER:
+ {
+ if (context_get_current()->aux_buffers > 0)
+ {
+ TRACE("Using auxiliary buffer for offscreen rendering\n");
+ device->offscreenBuffer = GL_AUX0;
+ }
+ else
+ {
+ TRACE("Using back buffer for offscreen rendering\n");
+ device->offscreenBuffer = GL_BACK;
+ }
+ }
+ }
+
+ TRACE("All defaults now set up, leaving 3D init.\n");
+
+ context_release(context);
+
+ /* Clear the screen */
+ wined3d_device_clear(device, 0, NULL, WINED3DCLEAR_TARGET
+ | (swapchain_desc->enable_auto_depth_stencil ? WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL : 0),
+ &black, 1.0f, 0);
+
+ device->d3d_initialized = TRUE;
+
+#ifndef VBOX
+ if (wined3d_settings.logo)
+ device_load_logo(device, wined3d_settings.logo);
+#endif
+ return WINED3D_OK;
+
+err_out:
+ HeapFree(GetProcessHeap(), 0, device->fb.render_targets);
+ HeapFree(GetProcessHeap(), 0, device->swapchains);
+ device->swapchain_count = 0;
+ if (swapchain)
+ wined3d_swapchain_decref(swapchain);
+ if (device->blit_priv)
+ device->blitter->free_private(device);
+ if (device->shader_priv)
+ device->shader_backend->shader_free_private(device);
+
+ return hr;
+}
+
+HRESULT CDECL wined3d_device_init_gdi(struct wined3d_device *device,
+ struct wined3d_swapchain_desc *swapchain_desc)
+{
+ struct wined3d_swapchain *swapchain = NULL;
+ HRESULT hr;
+
+ TRACE("device %p, swapchain_desc %p.\n", device, swapchain_desc);
+
+ /* Setup the implicit swapchain */
+ TRACE("Creating implicit swapchain\n");
+ hr = device->device_parent->ops->create_swapchain(device->device_parent,
+ swapchain_desc, &swapchain);
+ if (FAILED(hr))
+ {
+ WARN("Failed to create implicit swapchain\n");
+ goto err_out;
+ }
+
+ device->swapchain_count = 1;
+ device->swapchains = HeapAlloc(GetProcessHeap(), 0, device->swapchain_count * sizeof(*device->swapchains));
+ if (!device->swapchains)
+ {
+ ERR("Out of memory!\n");
+ goto err_out;
+ }
+ device->swapchains[0] = swapchain;
+ return WINED3D_OK;
+
+err_out:
+ wined3d_swapchain_decref(swapchain);
+ return hr;
+}
+
+HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device)
+{
+ struct wined3d_resource *resource, *cursor;
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+ struct wined3d_surface *surface;
+ UINT i;
+
+ TRACE("device %p.\n", device);
+
+ if (!device->d3d_initialized)
+ return WINED3DERR_INVALIDCALL;
+
+#ifdef VBOX_WINE_WITH_PROFILE
+ VBOXWINEPROFILE_DRAWPRIM_TERM(&device->DrawPrimProfile);
+#endif
+
+ /* Force making the context current again, to verify it is still valid
+ * (workaround for broken drivers) */
+ context_set_current(NULL);
+ /* I don't think that the interface guarantees that the device is destroyed from the same thread
+ * it was created. Thus make sure a context is active for the glDelete* calls
+ */
+ context = context_acquire(device, NULL);
+ gl_info = context->gl_info;
+
+ zv_destroy(device);
+
+ if (device->logo_surface)
+ wined3d_surface_decref(device->logo_surface);
+
+ stateblock_unbind_resources(device->stateBlock);
+
+ /* Unload resources */
+ LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry)
+ {
+ TRACE("Unloading resource %p.\n", resource);
+
+ resource->resource_ops->resource_unload(resource);
+ }
+
+ /* Delete the mouse cursor texture */
+ if (device->cursorTexture)
+ {
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->cursorTexture);
+ device->cursorTexture = 0;
+ }
+
+ /* Destroy the depth blt resources, they will be invalid after the reset. Also free shader
+ * private data, it might contain opengl pointers
+ */
+ if (device->depth_blt_texture)
+ {
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->depth_blt_texture);
+ device->depth_blt_texture = 0;
+ }
+
+#ifdef VBOX_WINE_WITH_SHADER_CACHE
+ shader_chaches_term(device);
+#endif
+
+ /* Destroy the shader backend. Note that this has to happen after all shaders are destroyed. */
+ device->blitter->free_private(device);
+ device->shader_backend->shader_free_private(device);
+
+ /* Release the buffers (with sanity checks)*/
+ if (device->onscreen_depth_stencil)
+ {
+ surface = device->onscreen_depth_stencil;
+ device->onscreen_depth_stencil = NULL;
+ wined3d_surface_decref(surface);
+ }
+
+ if (device->fb.depth_stencil)
+ {
+ surface = device->fb.depth_stencil;
+
+ TRACE("Releasing depth/stencil buffer %p.\n", surface);
+
+ device->fb.depth_stencil = NULL;
+ wined3d_surface_decref(surface);
+ }
+
+ if (device->auto_depth_stencil)
+ {
+ surface = device->auto_depth_stencil;
+ device->auto_depth_stencil = NULL;
+ if (wined3d_surface_decref(surface))
+ FIXME("Something's still holding the auto depth stencil buffer (%p).\n", surface);
+ }
+
+ for (i = 1; i < gl_info->limits.buffers; ++i)
+ {
+ wined3d_device_set_render_target(device, i, NULL, FALSE);
+ }
+
+ surface = device->fb.render_targets[0];
+ TRACE("Setting rendertarget 0 to NULL\n");
+ device->fb.render_targets[0] = NULL;
+ TRACE("Releasing the render target at %p\n", surface);
+ wined3d_surface_decref(surface);
+
+ context_release(context);
+
+ for (i = 0; i < device->swapchain_count; ++i)
+ {
+ TRACE("Releasing the implicit swapchain %u.\n", i);
+ if (wined3d_swapchain_decref(device->swapchains[i]))
+ FIXME("Something's still holding the implicit swapchain.\n");
+ }
+
+#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
+ while (device->context_count)
+ {
+ context_destroy(device, device->contexts[0]);
+ }
+#endif
+
+ HeapFree(GetProcessHeap(), 0, device->swapchains);
+ device->swapchains = NULL;
+ device->swapchain_count = 0;
+
+ HeapFree(GetProcessHeap(), 0, device->fb.render_targets);
+ device->fb.render_targets = NULL;
+
+ device->d3d_initialized = FALSE;
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_uninit_gdi(struct wined3d_device *device)
+{
+ unsigned int i;
+
+ for (i = 0; i < device->swapchain_count; ++i)
+ {
+ TRACE("Releasing the implicit swapchain %u.\n", i);
+ if (wined3d_swapchain_decref(device->swapchains[i]))
+ FIXME("Something's still holding the implicit swapchain.\n");
+ }
+
+ HeapFree(GetProcessHeap(), 0, device->swapchains);
+ device->swapchains = NULL;
+ device->swapchain_count = 0;
+ return WINED3D_OK;
+}
+
+/* Enables thread safety in the wined3d device and its resources. Called by DirectDraw
+ * from SetCooperativeLevel if DDSCL_MULTITHREADED is specified, and by d3d8/9 from
+ * CreateDevice if D3DCREATE_MULTITHREADED is passed.
+ *
+ * There is no way to deactivate thread safety once it is enabled.
+ */
+void CDECL wined3d_device_set_multithreaded(struct wined3d_device *device)
+{
+ TRACE("device %p.\n", device);
+
+ /* For now just store the flag (needed in case of ddraw). */
+ device->create_parms.flags |= WINED3DCREATE_MULTITHREADED;
+}
+
+
+UINT CDECL wined3d_device_get_available_texture_mem(const struct wined3d_device *device)
+{
+#ifndef VBOX_WITH_WDDM
+ TRACE("device %p.\n", device);
+
+ TRACE("Emulating %d MB, returning %d MB left.\n",
+ device->adapter->TextureRam / (1024 * 1024),
+ (device->adapter->TextureRam - device->adapter->UsedTextureRam) / (1024 * 1024));
+
+ return device->adapter->TextureRam - device->adapter->UsedTextureRam;
+#else
+ ERR("unsupported!");
+ return ~0UL;
+#endif
+}
+
+void CDECL wined3d_device_set_stream_output(struct wined3d_device *device, UINT idx,
+ struct wined3d_buffer *buffer, UINT offset)
+{
+ struct wined3d_buffer *prev_buffer;
+
+ TRACE("device %p, idx %u, buffer %p, offset %u.\n", device, idx, buffer, offset);
+
+ if (idx >= MAX_STREAM_OUT)
+ {
+ WARN("Invalid stream output %u.\n", idx);
+ return;
+ }
+
+ prev_buffer = device->updateStateBlock->state.stream_output[idx].buffer;
+ device->updateStateBlock->state.stream_output[idx].buffer = buffer;
+ device->updateStateBlock->state.stream_output[idx].offset = offset;
+
+ if (device->isRecordingState)
+ {
+ if (buffer)
+ wined3d_buffer_incref(buffer);
+ if (prev_buffer)
+ wined3d_buffer_decref(prev_buffer);
+ return;
+ }
+
+ if (prev_buffer != buffer)
+ {
+ if (buffer)
+ {
+ InterlockedIncrement(&buffer->resource.bind_count);
+ wined3d_buffer_incref(buffer);
+ }
+ if (prev_buffer)
+ {
+ InterlockedDecrement(&prev_buffer->resource.bind_count);
+ wined3d_buffer_decref(prev_buffer);
+ }
+ }
+}
+
+struct wined3d_buffer * CDECL wined3d_device_get_stream_output(struct wined3d_device *device,
+ UINT idx, UINT *offset)
+{
+ TRACE("device %p, idx %u, offset %p.\n", device, idx, offset);
+
+ if (idx >= MAX_STREAM_OUT)
+ {
+ WARN("Invalid stream output %u.\n", idx);
+ return NULL;
+ }
+
+ *offset = device->stateBlock->state.stream_output[idx].offset;
+ return device->stateBlock->state.stream_output[idx].buffer;
+}
+
+HRESULT CDECL wined3d_device_set_stream_source(struct wined3d_device *device, UINT stream_idx,
+ struct wined3d_buffer *buffer, UINT offset, UINT stride)
+{
+ struct wined3d_stream_state *stream;
+ struct wined3d_buffer *prev_buffer;
+
+ TRACE("device %p, stream_idx %u, buffer %p, offset %u, stride %u.\n",
+ device, stream_idx, buffer, offset, stride);
+
+ if (stream_idx >= MAX_STREAMS)
+ {
+ WARN("Stream index %u out of range.\n", stream_idx);
+ return WINED3DERR_INVALIDCALL;
+ }
+ else if (offset & 0x3)
+ {
+ WARN("Offset %u is not 4 byte aligned.\n", offset);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ stream = &device->updateStateBlock->state.streams[stream_idx];
+ prev_buffer = stream->buffer;
+
+ device->updateStateBlock->changed.streamSource |= 1 << stream_idx;
+
+ if (prev_buffer == buffer
+ && stream->stride == stride
+ && stream->offset == offset)
+ {
+ TRACE("Application is setting the old values over, nothing to do.\n");
+ return WINED3D_OK;
+ }
+
+ stream->buffer = buffer;
+ if (buffer)
+ {
+ stream->stride = stride;
+ stream->offset = offset;
+ }
+
+ /* Handle recording of state blocks. */
+ if (device->isRecordingState)
+ {
+ TRACE("Recording... not performing anything.\n");
+ if (buffer)
+ wined3d_buffer_incref(buffer);
+ if (prev_buffer)
+ wined3d_buffer_decref(prev_buffer);
+ return WINED3D_OK;
+ }
+
+ if (buffer)
+ {
+ InterlockedIncrement(&buffer->resource.bind_count);
+ wined3d_buffer_incref(buffer);
+ }
+ if (prev_buffer)
+ {
+ InterlockedDecrement(&prev_buffer->resource.bind_count);
+ wined3d_buffer_decref(prev_buffer);
+ }
+
+ device_invalidate_state(device, STATE_STREAMSRC);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_get_stream_source(const struct wined3d_device *device,
+ UINT stream_idx, struct wined3d_buffer **buffer, UINT *offset, UINT *stride)
+{
+ struct wined3d_stream_state *stream;
+
+ TRACE("device %p, stream_idx %u, buffer %p, offset %p, stride %p.\n",
+ device, stream_idx, buffer, offset, stride);
+
+ if (stream_idx >= MAX_STREAMS)
+ {
+ WARN("Stream index %u out of range.\n", stream_idx);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ stream = &device->stateBlock->state.streams[stream_idx];
+ *buffer = stream->buffer;
+ if (*buffer)
+ wined3d_buffer_incref(*buffer);
+ if (offset)
+ *offset = stream->offset;
+ *stride = stream->stride;
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_set_stream_source_freq(struct wined3d_device *device, UINT stream_idx, UINT divider)
+{
+ struct wined3d_stream_state *stream;
+ UINT old_flags, old_freq;
+
+ TRACE("device %p, stream_idx %u, divider %#x.\n", device, stream_idx, divider);
+
+ /* Verify input. At least in d3d9 this is invalid. */
+ if ((divider & WINED3DSTREAMSOURCE_INSTANCEDATA) && (divider & WINED3DSTREAMSOURCE_INDEXEDDATA))
+ {
+ WARN("INSTANCEDATA and INDEXEDDATA were set, returning D3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+ if ((divider & WINED3DSTREAMSOURCE_INSTANCEDATA) && !stream_idx)
+ {
+ WARN("INSTANCEDATA used on stream 0, returning D3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+ if (!divider)
+ {
+ WARN("Divider is 0, returning D3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ stream = &device->updateStateBlock->state.streams[stream_idx];
+ old_flags = stream->flags;
+ old_freq = stream->frequency;
+
+ stream->flags = divider & (WINED3DSTREAMSOURCE_INSTANCEDATA | WINED3DSTREAMSOURCE_INDEXEDDATA);
+ stream->frequency = divider & 0x7fffff;
+
+ device->updateStateBlock->changed.streamFreq |= 1 << stream_idx;
+
+ if (stream->frequency != old_freq || stream->flags != old_flags)
+ device_invalidate_state(device, STATE_STREAMSRC);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_get_stream_source_freq(const struct wined3d_device *device,
+ UINT stream_idx, UINT *divider)
+{
+ struct wined3d_stream_state *stream;
+
+ TRACE("device %p, stream_idx %u, divider %p.\n", device, stream_idx, divider);
+
+ stream = &device->updateStateBlock->state.streams[stream_idx];
+ *divider = stream->flags | stream->frequency;
+
+ TRACE("Returning %#x.\n", *divider);
+
+ return WINED3D_OK;
+}
+
+void CDECL wined3d_device_set_transform(struct wined3d_device *device,
+ enum wined3d_transform_state d3dts, const struct wined3d_matrix *matrix)
+{
+ TRACE("device %p, state %s, matrix %p.\n",
+ device, debug_d3dtstype(d3dts), matrix);
+ TRACE("%.8e %.8e %.8e %.8e\n", matrix->u.s._11, matrix->u.s._12, matrix->u.s._13, matrix->u.s._14);
+ TRACE("%.8e %.8e %.8e %.8e\n", matrix->u.s._21, matrix->u.s._22, matrix->u.s._23, matrix->u.s._24);
+ TRACE("%.8e %.8e %.8e %.8e\n", matrix->u.s._31, matrix->u.s._32, matrix->u.s._33, matrix->u.s._34);
+ TRACE("%.8e %.8e %.8e %.8e\n", matrix->u.s._41, matrix->u.s._42, matrix->u.s._43, matrix->u.s._44);
+
+ /* Handle recording of state blocks. */
+ if (device->isRecordingState)
+ {
+ TRACE("Recording... not performing anything.\n");
+ device->updateStateBlock->changed.transform[d3dts >> 5] |= 1 << (d3dts & 0x1f);
+ device->updateStateBlock->state.transforms[d3dts] = *matrix;
+ return;
+ }
+
+ /* If the new matrix is the same as the current one,
+ * we cut off any further processing. this seems to be a reasonable
+ * optimization because as was noticed, some apps (warcraft3 for example)
+ * tend towards setting the same matrix repeatedly for some reason.
+ *
+ * From here on we assume that the new matrix is different, wherever it matters. */
+ if (!memcmp(&device->stateBlock->state.transforms[d3dts].u.m[0][0], matrix, sizeof(*matrix)))
+ {
+ TRACE("The application is setting the same matrix over again.\n");
+ return;
+ }
+
+ device->stateBlock->state.transforms[d3dts] = *matrix;
+
+ if (d3dts < WINED3D_TS_WORLD_MATRIX(device->adapter->gl_info.limits.blends))
+ device_invalidate_state(device, STATE_TRANSFORM(d3dts));
+}
+
+void CDECL wined3d_device_get_transform(const struct wined3d_device *device,
+ enum wined3d_transform_state state, struct wined3d_matrix *matrix)
+{
+ TRACE("device %p, state %s, matrix %p.\n", device, debug_d3dtstype(state), matrix);
+
+ *matrix = device->stateBlock->state.transforms[state];
+}
+
+void CDECL wined3d_device_multiply_transform(struct wined3d_device *device,
+ enum wined3d_transform_state state, const struct wined3d_matrix *matrix)
+{
+ const struct wined3d_matrix *mat;
+ struct wined3d_matrix temp;
+
+ TRACE("device %p, state %s, matrix %p.\n", device, debug_d3dtstype(state), matrix);
+
+ /* Note: Using 'updateStateBlock' rather than 'stateblock' in the code
+ * below means it will be recorded in a state block change, but it
+ * works regardless where it is recorded.
+ * If this is found to be wrong, change to StateBlock. */
+ if (state > HIGHEST_TRANSFORMSTATE)
+ {
+ WARN("Unhandled transform state %#x.\n", state);
+ return;
+ }
+
+ mat = &device->updateStateBlock->state.transforms[state];
+ multiply_matrix(&temp, mat, matrix);
+
+ /* Apply change via set transform - will reapply to eg. lights this way. */
+ wined3d_device_set_transform(device, state, &temp);
+}
+
+/* Note lights are real special cases. Although the device caps state only
+ * e.g. 8 are supported, you can reference any indexes you want as long as
+ * that number max are enabled at any one point in time. Therefore since the
+ * indices can be anything, we need a hashmap of them. However, this causes
+ * stateblock problems. When capturing the state block, I duplicate the
+ * hashmap, but when recording, just build a chain pretty much of commands to
+ * be replayed. */
+HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device,
+ UINT light_idx, const struct wined3d_light *light)
+{
+ UINT hash_idx = LIGHTMAP_HASHFUNC(light_idx);
+ struct wined3d_light_info *object = NULL;
+ struct list *e;
+ float rho;
+
+ TRACE("device %p, light_idx %u, light %p.\n", device, light_idx, light);
+
+ /* Check the parameter range. Need for speed most wanted sets junk lights
+ * which confuse the GL driver. */
+ if (!light)
+ return WINED3DERR_INVALIDCALL;
+
+ switch (light->type)
+ {
+ case WINED3D_LIGHT_POINT:
+ case WINED3D_LIGHT_SPOT:
+ case WINED3D_LIGHT_PARALLELPOINT:
+ case WINED3D_LIGHT_GLSPOT:
+ /* Incorrect attenuation values can cause the gl driver to crash.
+ * Happens with Need for speed most wanted. */
+ if (light->attenuation0 < 0.0f || light->attenuation1 < 0.0f || light->attenuation2 < 0.0f)
+ {
+ WARN("Attenuation is negative, returning WINED3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+ break;
+
+ case WINED3D_LIGHT_DIRECTIONAL:
+ /* Ignores attenuation */
+ break;
+
+ default:
+ WARN("Light type out of range, returning WINED3DERR_INVALIDCALL\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ LIST_FOR_EACH(e, &device->updateStateBlock->state.light_map[hash_idx])
+ {
+ object = LIST_ENTRY(e, struct wined3d_light_info, entry);
+ if (object->OriginalIndex == light_idx)
+ break;
+ object = NULL;
+ }
+
+ if (!object)
+ {
+ TRACE("Adding new light\n");
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ list_add_head(&device->updateStateBlock->state.light_map[hash_idx], &object->entry);
+ object->glIndex = -1;
+ object->OriginalIndex = light_idx;
+ }
+
+ /* Initialize the object. */
+ TRACE("Light %d setting to type %d, Diffuse(%f,%f,%f,%f), Specular(%f,%f,%f,%f), Ambient(%f,%f,%f,%f)\n",
+ light_idx, light->type,
+ light->diffuse.r, light->diffuse.g, light->diffuse.b, light->diffuse.a,
+ light->specular.r, light->specular.g, light->specular.b, light->specular.a,
+ light->ambient.r, light->ambient.g, light->ambient.b, light->ambient.a);
+ TRACE("... Pos(%f,%f,%f), Dir(%f,%f,%f)\n", light->position.x, light->position.y, light->position.z,
+ light->direction.x, light->direction.y, light->direction.z);
+ TRACE("... Range(%f), Falloff(%f), Theta(%f), Phi(%f)\n",
+ light->range, light->falloff, light->theta, light->phi);
+
+ /* Update the live definitions if the light is currently assigned a glIndex. */
+ if (object->glIndex != -1 && !device->isRecordingState)
+ {
+ if (object->OriginalParms.type != light->type)
+ device_invalidate_state(device, STATE_LIGHT_TYPE);
+ device_invalidate_state(device, STATE_ACTIVELIGHT(object->glIndex));
+ }
+
+ /* Save away the information. */
+ object->OriginalParms = *light;
+
+ switch (light->type)
+ {
+ case WINED3D_LIGHT_POINT:
+ /* Position */
+ object->lightPosn[0] = light->position.x;
+ object->lightPosn[1] = light->position.y;
+ object->lightPosn[2] = light->position.z;
+ object->lightPosn[3] = 1.0f;
+ object->cutoff = 180.0f;
+ /* FIXME: Range */
+ break;
+
+ case WINED3D_LIGHT_DIRECTIONAL:
+ /* Direction */
+ object->lightPosn[0] = -light->direction.x;
+ object->lightPosn[1] = -light->direction.y;
+ object->lightPosn[2] = -light->direction.z;
+ object->lightPosn[3] = 0.0f;
+ object->exponent = 0.0f;
+ object->cutoff = 180.0f;
+ break;
+
+ case WINED3D_LIGHT_SPOT:
+ /* Position */
+ object->lightPosn[0] = light->position.x;
+ object->lightPosn[1] = light->position.y;
+ object->lightPosn[2] = light->position.z;
+ object->lightPosn[3] = 1.0f;
+
+ /* Direction */
+ object->lightDirn[0] = light->direction.x;
+ object->lightDirn[1] = light->direction.y;
+ object->lightDirn[2] = light->direction.z;
+ object->lightDirn[3] = 1.0f;
+
+ /* opengl-ish and d3d-ish spot lights use too different models
+ * for the light "intensity" as a function of the angle towards
+ * the main light direction, so we only can approximate very
+ * roughly. However, spot lights are rather rarely used in games
+ * (if ever used at all). Furthermore if still used, probably
+ * nobody pays attention to such details. */
+ if (!light->falloff)
+ {
+ /* Falloff = 0 is easy, because d3d's and opengl's spot light
+ * equations have the falloff resp. exponent parameter as an
+ * exponent, so the spot light lighting will always be 1.0 for
+ * both of them, and we don't have to care for the rest of the
+ * rather complex calculation. */
+ object->exponent = 0.0f;
+ }
+ else
+ {
+ rho = light->theta + (light->phi - light->theta) / (2 * light->falloff);
+ if (rho < 0.0001f)
+ rho = 0.0001f;
+#ifdef VBOX_WITH_WINE_FIXES
+ object->exponent = -0.3f / log(cos(rho / 2));
+#else
+ object->exponent = -0.3f / logf(cosf(rho / 2));
+#endif
+ }
+
+ if (object->exponent > 128.0f)
+ object->exponent = 128.0f;
+
+ object->cutoff = (float)(light->phi * 90 / M_PI);
+ /* FIXME: Range */
+ break;
+
+ default:
+ FIXME("Unrecognized light type %#x.\n", light->type);
+ }
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_get_light(const struct wined3d_device *device,
+ UINT light_idx, struct wined3d_light *light)
+{
+ UINT hash_idx = LIGHTMAP_HASHFUNC(light_idx);
+ struct wined3d_light_info *light_info = NULL;
+ struct list *e;
+
+ TRACE("device %p, light_idx %u, light %p.\n", device, light_idx, light);
+
+ LIST_FOR_EACH(e, &device->stateBlock->state.light_map[hash_idx])
+ {
+ light_info = LIST_ENTRY(e, struct wined3d_light_info, entry);
+ if (light_info->OriginalIndex == light_idx)
+ break;
+ light_info = NULL;
+ }
+
+ if (!light_info)
+ {
+ TRACE("Light information requested but light not defined\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ *light = light_info->OriginalParms;
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_set_light_enable(struct wined3d_device *device, UINT light_idx, BOOL enable)
+{
+ UINT hash_idx = LIGHTMAP_HASHFUNC(light_idx);
+ struct wined3d_light_info *light_info = NULL;
+ struct list *e;
+
+ TRACE("device %p, light_idx %u, enable %#x.\n", device, light_idx, enable);
+
+ LIST_FOR_EACH(e, &device->updateStateBlock->state.light_map[hash_idx])
+ {
+ light_info = LIST_ENTRY(e, struct wined3d_light_info, entry);
+ if (light_info->OriginalIndex == light_idx)
+ break;
+ light_info = NULL;
+ }
+ TRACE("Found light %p.\n", light_info);
+
+ /* Special case - enabling an undefined light creates one with a strict set of parameters. */
+ if (!light_info)
+ {
+ TRACE("Light enabled requested but light not defined, so defining one!\n");
+ wined3d_device_set_light(device, light_idx, &WINED3D_default_light);
+
+ /* Search for it again! Should be fairly quick as near head of list. */
+ LIST_FOR_EACH(e, &device->updateStateBlock->state.light_map[hash_idx])
+ {
+ light_info = LIST_ENTRY(e, struct wined3d_light_info, entry);
+ if (light_info->OriginalIndex == light_idx)
+ break;
+ light_info = NULL;
+ }
+ if (!light_info)
+ {
+ FIXME("Adding default lights has failed dismally\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+ }
+
+ if (!enable)
+ {
+ if (light_info->glIndex != -1)
+ {
+ if (!device->isRecordingState)
+ {
+ device_invalidate_state(device, STATE_LIGHT_TYPE);
+ device_invalidate_state(device, STATE_ACTIVELIGHT(light_info->glIndex));
+ }
+
+ device->updateStateBlock->state.lights[light_info->glIndex] = NULL;
+ light_info->glIndex = -1;
+ }
+ else
+ {
+ TRACE("Light already disabled, nothing to do\n");
+ }
+ light_info->enabled = FALSE;
+ }
+ else
+ {
+ light_info->enabled = TRUE;
+ if (light_info->glIndex != -1)
+ {
+ TRACE("Nothing to do as light was enabled\n");
+ }
+ else
+ {
+ unsigned int i;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ /* Find a free GL light. */
+ for (i = 0; i < gl_info->limits.lights; ++i)
+ {
+ if (!device->updateStateBlock->state.lights[i])
+ {
+ device->updateStateBlock->state.lights[i] = light_info;
+ light_info->glIndex = i;
+ break;
+ }
+ }
+ if (light_info->glIndex == -1)
+ {
+ /* Our tests show that Windows returns D3D_OK in this situation, even with
+ * D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE devices. This
+ * is consistent among ddraw, d3d8 and d3d9. GetLightEnable returns TRUE
+ * as well for those lights.
+ *
+ * TODO: Test how this affects rendering. */
+ WARN("Too many concurrently active lights\n");
+ return WINED3D_OK;
+ }
+
+ /* i == light_info->glIndex */
+ if (!device->isRecordingState)
+ {
+ device_invalidate_state(device, STATE_LIGHT_TYPE);
+ device_invalidate_state(device, STATE_ACTIVELIGHT(i));
+ }
+ }
+ }
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_get_light_enable(const struct wined3d_device *device, UINT light_idx, BOOL *enable)
+{
+ UINT hash_idx = LIGHTMAP_HASHFUNC(light_idx);
+ struct wined3d_light_info *light_info = NULL;
+ struct list *e;
+
+ TRACE("device %p, light_idx %u, enable %p.\n", device, light_idx, enable);
+
+ LIST_FOR_EACH(e, &device->stateBlock->state.light_map[hash_idx])
+ {
+ light_info = LIST_ENTRY(e, struct wined3d_light_info, entry);
+ if (light_info->OriginalIndex == light_idx)
+ break;
+ light_info = NULL;
+ }
+
+ if (!light_info)
+ {
+ TRACE("Light enabled state requested but light not defined.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+ /* true is 128 according to SetLightEnable */
+ *enable = light_info->enabled ? 128 : 0;
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_set_clip_plane(struct wined3d_device *device,
+ UINT plane_idx, const struct wined3d_vec4 *plane)
+{
+ TRACE("device %p, plane_idx %u, plane %p.\n", device, plane_idx, plane);
+
+ /* Validate plane_idx. */
+ if (plane_idx >= device->adapter->gl_info.limits.clipplanes)
+ {
+ TRACE("Application has requested clipplane this device doesn't support.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ device->updateStateBlock->changed.clipplane |= 1 << plane_idx;
+
+ if (!memcmp(&device->updateStateBlock->state.clip_planes[plane_idx], plane, sizeof(*plane)))
+ {
+ TRACE("Application is setting old values over, nothing to do.\n");
+ return WINED3D_OK;
+ }
+
+ device->updateStateBlock->state.clip_planes[plane_idx] = *plane;
+
+ /* Handle recording of state blocks. */
+ if (device->isRecordingState)
+ {
+ TRACE("Recording... not performing anything.\n");
+ return WINED3D_OK;
+ }
+
+ device_invalidate_state(device, STATE_CLIPPLANE(plane_idx));
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_get_clip_plane(const struct wined3d_device *device,
+ UINT plane_idx, struct wined3d_vec4 *plane)
+{
+ TRACE("device %p, plane_idx %u, plane %p.\n", device, plane_idx, plane);
+
+ /* Validate plane_idx. */
+ if (plane_idx >= device->adapter->gl_info.limits.clipplanes)
+ {
+ TRACE("Application has requested clipplane this device doesn't support.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ *plane = device->stateBlock->state.clip_planes[plane_idx];
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_set_clip_status(struct wined3d_device *device,
+ const struct wined3d_clip_status *clip_status)
+{
+ FIXME("device %p, clip_status %p stub!\n", device, clip_status);
+
+ if (!clip_status)
+ return WINED3DERR_INVALIDCALL;
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_get_clip_status(const struct wined3d_device *device,
+ struct wined3d_clip_status *clip_status)
+{
+ FIXME("device %p, clip_status %p stub!\n", device, clip_status);
+
+ if (!clip_status)
+ return WINED3DERR_INVALIDCALL;
+
+ return WINED3D_OK;
+}
+
+void CDECL wined3d_device_set_material(struct wined3d_device *device, const struct wined3d_material *material)
+{
+ TRACE("device %p, material %p.\n", device, material);
+
+ device->updateStateBlock->changed.material = TRUE;
+ device->updateStateBlock->state.material = *material;
+
+ /* Handle recording of state blocks */
+ if (device->isRecordingState)
+ {
+ TRACE("Recording... not performing anything.\n");
+ return;
+ }
+
+ device_invalidate_state(device, STATE_MATERIAL);
+}
+
+void CDECL wined3d_device_get_material(const struct wined3d_device *device, struct wined3d_material *material)
+{
+ TRACE("device %p, material %p.\n", device, material);
+
+ *material = device->updateStateBlock->state.material;
+
+ TRACE("diffuse {%.8e, %.8e, %.8e, %.8e}\n",
+ material->diffuse.r, material->diffuse.g,
+ material->diffuse.b, material->diffuse.a);
+ TRACE("ambient {%.8e, %.8e, %.8e, %.8e}\n",
+ material->ambient.r, material->ambient.g,
+ material->ambient.b, material->ambient.a);
+ TRACE("specular {%.8e, %.8e, %.8e, %.8e}\n",
+ material->specular.r, material->specular.g,
+ material->specular.b, material->specular.a);
+ TRACE("emissive {%.8e, %.8e, %.8e, %.8e}\n",
+ material->emissive.r, material->emissive.g,
+ material->emissive.b, material->emissive.a);
+ TRACE("power %.8e.\n", material->power);
+}
+
+void CDECL wined3d_device_set_index_buffer(struct wined3d_device *device,
+ struct wined3d_buffer *buffer, enum wined3d_format_id format_id)
+{
+ struct wined3d_buffer *prev_buffer;
+
+ TRACE("device %p, buffer %p, format %s.\n",
+ device, buffer, debug_d3dformat(format_id));
+
+ prev_buffer = device->updateStateBlock->state.index_buffer;
+
+ device->updateStateBlock->changed.indices = TRUE;
+ device->updateStateBlock->state.index_buffer = buffer;
+ device->updateStateBlock->state.index_format = format_id;
+
+ /* Handle recording of state blocks. */
+ if (device->isRecordingState)
+ {
+ TRACE("Recording... not performing anything.\n");
+ if (buffer)
+ wined3d_buffer_incref(buffer);
+ if (prev_buffer)
+ wined3d_buffer_decref(prev_buffer);
+ return;
+ }
+
+ if (prev_buffer != buffer)
+ {
+ device_invalidate_state(device, STATE_INDEXBUFFER);
+ if (buffer)
+ {
+ InterlockedIncrement(&buffer->resource.bind_count);
+ wined3d_buffer_incref(buffer);
+ }
+ if (prev_buffer)
+ {
+ InterlockedDecrement(&prev_buffer->resource.bind_count);
+ wined3d_buffer_decref(prev_buffer);
+ }
+ }
+}
+
+struct wined3d_buffer * CDECL wined3d_device_get_index_buffer(const struct wined3d_device *device,
+ enum wined3d_format_id *format)
+{
+ TRACE("device %p, format %p.\n", device, format);
+
+ *format = device->stateBlock->state.index_format;
+ return device->stateBlock->state.index_buffer;
+}
+
+void CDECL wined3d_device_set_base_vertex_index(struct wined3d_device *device, INT base_index)
+{
+ TRACE("device %p, base_index %d.\n", device, base_index);
+
+ device->updateStateBlock->state.base_vertex_index = base_index;
+}
+
+INT CDECL wined3d_device_get_base_vertex_index(const struct wined3d_device *device)
+{
+ TRACE("device %p.\n", device);
+
+ return device->stateBlock->state.base_vertex_index;
+}
+
+void CDECL wined3d_device_set_viewport(struct wined3d_device *device, const struct wined3d_viewport *viewport)
+{
+ TRACE("device %p, viewport %p.\n", device, viewport);
+ TRACE("x %u, y %u, w %u, h %u, min_z %.8e, max_z %.8e.\n",
+ viewport->x, viewport->y, viewport->width, viewport->height, viewport->min_z, viewport->max_z);
+
+ device->updateStateBlock->changed.viewport = TRUE;
+ device->updateStateBlock->state.viewport = *viewport;
+
+ /* Handle recording of state blocks */
+ if (device->isRecordingState)
+ {
+ TRACE("Recording... not performing anything\n");
+ return;
+ }
+
+ device_invalidate_state(device, STATE_VIEWPORT);
+}
+
+void CDECL wined3d_device_get_viewport(const struct wined3d_device *device, struct wined3d_viewport *viewport)
+{
+ TRACE("device %p, viewport %p.\n", device, viewport);
+
+ *viewport = device->stateBlock->state.viewport;
+}
+
+static void resolve_depth_buffer(struct wined3d_state *state)
+{
+ struct wined3d_texture *texture = state->textures[0];
+ struct wined3d_surface *depth_stencil, *surface;
+
+ if (!texture || texture->resource.type != WINED3D_RTYPE_TEXTURE
+ || !(texture->resource.format->flags & WINED3DFMT_FLAG_DEPTH))
+ return;
+ surface = surface_from_resource(texture->sub_resources[0]);
+ depth_stencil = state->fb->depth_stencil;
+ if (!depth_stencil)
+ return;
+
+ wined3d_surface_blt(surface, NULL, depth_stencil, NULL, 0, NULL, WINED3D_TEXF_POINT);
+}
+
+void CDECL wined3d_device_set_render_state(struct wined3d_device *device,
+ enum wined3d_render_state state, DWORD value)
+{
+ DWORD old_value = device->stateBlock->state.render_states[state];
+
+ TRACE("device %p, state %s (%#x), value %#x.\n", device, debug_d3drenderstate(state), state, value);
+
+ device->updateStateBlock->changed.renderState[state >> 5] |= 1 << (state & 0x1f);
+ device->updateStateBlock->state.render_states[state] = value;
+
+ /* Handle recording of state blocks. */
+ if (device->isRecordingState)
+ {
+ TRACE("Recording... not performing anything.\n");
+ return;
+ }
+
+ /* Compared here and not before the assignment to allow proper stateblock recording. */
+ if (value == old_value)
+ TRACE("Application is setting the old value over, nothing to do.\n");
+ else
+ device_invalidate_state(device, STATE_RENDER(state));
+
+ if (state == WINED3D_RS_POINTSIZE && value == WINED3D_RESZ_CODE)
+ {
+ TRACE("RESZ multisampled depth buffer resolve triggered.\n");
+ resolve_depth_buffer(&device->stateBlock->state);
+ }
+}
+
+DWORD CDECL wined3d_device_get_render_state(const struct wined3d_device *device, enum wined3d_render_state state)
+{
+ TRACE("device %p, state %s (%#x).\n", device, debug_d3drenderstate(state), state);
+
+ return device->stateBlock->state.render_states[state];
+}
+
+void CDECL wined3d_device_set_sampler_state(struct wined3d_device *device,
+ UINT sampler_idx, enum wined3d_sampler_state state, DWORD value)
+{
+ DWORD old_value;
+
+ TRACE("device %p, sampler_idx %u, state %s, value %#x.\n",
+ device, sampler_idx, debug_d3dsamplerstate(state), value);
+
+ if (sampler_idx >= WINED3DVERTEXTEXTURESAMPLER0 && sampler_idx <= WINED3DVERTEXTEXTURESAMPLER3)
+ sampler_idx -= (WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS);
+
+ if (sampler_idx >= sizeof(device->stateBlock->state.sampler_states)
+ / sizeof(*device->stateBlock->state.sampler_states))
+ {
+ WARN("Invalid sampler %u.\n", sampler_idx);
+ return; /* Windows accepts overflowing this array ... we do not. */
+ }
+
+ old_value = device->stateBlock->state.sampler_states[sampler_idx][state];
+ device->updateStateBlock->state.sampler_states[sampler_idx][state] = value;
+ device->updateStateBlock->changed.samplerState[sampler_idx] |= 1 << state;
+
+ /* Handle recording of state blocks. */
+ if (device->isRecordingState)
+ {
+ TRACE("Recording... not performing anything.\n");
+ return;
+ }
+
+ if (old_value == value)
+ {
+ TRACE("Application is setting the old value over, nothing to do.\n");
+ return;
+ }
+
+ device_invalidate_state(device, STATE_SAMPLER(sampler_idx));
+}
+
+DWORD CDECL wined3d_device_get_sampler_state(const struct wined3d_device *device,
+ UINT sampler_idx, enum wined3d_sampler_state state)
+{
+ TRACE("device %p, sampler_idx %u, state %s.\n",
+ device, sampler_idx, debug_d3dsamplerstate(state));
+
+ if (sampler_idx >= WINED3DVERTEXTEXTURESAMPLER0 && sampler_idx <= WINED3DVERTEXTEXTURESAMPLER3)
+ sampler_idx -= (WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS);
+
+ if (sampler_idx >= sizeof(device->stateBlock->state.sampler_states)
+ / sizeof(*device->stateBlock->state.sampler_states))
+ {
+ WARN("Invalid sampler %u.\n", sampler_idx);
+ return 0; /* Windows accepts overflowing this array ... we do not. */
+ }
+
+ return device->stateBlock->state.sampler_states[sampler_idx][state];
+}
+
+void CDECL wined3d_device_set_scissor_rect(struct wined3d_device *device, const RECT *rect)
+{
+ TRACE("device %p, rect %s.\n", device, wine_dbgstr_rect(rect));
+
+ device->updateStateBlock->changed.scissorRect = TRUE;
+ if (EqualRect(&device->updateStateBlock->state.scissor_rect, rect))
+ {
+ TRACE("App is setting the old scissor rectangle over, nothing to do.\n");
+ return;
+ }
+ CopyRect(&device->updateStateBlock->state.scissor_rect, rect);
+
+ if (device->isRecordingState)
+ {
+ TRACE("Recording... not performing anything.\n");
+ return;
+ }
+
+ device_invalidate_state(device, STATE_SCISSORRECT);
+}
+
+void CDECL wined3d_device_get_scissor_rect(const struct wined3d_device *device, RECT *rect)
+{
+ TRACE("device %p, rect %p.\n", device, rect);
+
+ *rect = device->updateStateBlock->state.scissor_rect;
+ TRACE("Returning rect %s.\n", wine_dbgstr_rect(rect));
+}
+
+void CDECL wined3d_device_set_vertex_declaration(struct wined3d_device *device,
+ struct wined3d_vertex_declaration *declaration)
+{
+ struct wined3d_vertex_declaration *prev = device->updateStateBlock->state.vertex_declaration;
+
+ TRACE("device %p, declaration %p.\n", device, declaration);
+
+ if (declaration)
+ wined3d_vertex_declaration_incref(declaration);
+ if (prev)
+ wined3d_vertex_declaration_decref(prev);
+
+ device->updateStateBlock->state.vertex_declaration = declaration;
+ device->updateStateBlock->changed.vertexDecl = TRUE;
+
+ if (device->isRecordingState)
+ {
+ TRACE("Recording... not performing anything.\n");
+ return;
+ }
+
+ if (declaration == prev)
+ {
+ /* Checked after the assignment to allow proper stateblock recording. */
+ TRACE("Application is setting the old declaration over, nothing to do.\n");
+ return;
+ }
+
+ device_invalidate_state(device, STATE_VDECL);
+}
+
+struct wined3d_vertex_declaration * CDECL wined3d_device_get_vertex_declaration(const struct wined3d_device *device)
+{
+ TRACE("device %p.\n", device);
+
+ return device->stateBlock->state.vertex_declaration;
+}
+
+void CDECL wined3d_device_set_vertex_shader(struct wined3d_device *device, struct wined3d_shader *shader)
+{
+ struct wined3d_shader *prev = device->updateStateBlock->state.vertex_shader;
+
+ TRACE("device %p, shader %p.\n", device, shader);
+
+ if (shader)
+ wined3d_shader_incref(shader);
+ if (prev)
+ wined3d_shader_decref(prev);
+
+ device->updateStateBlock->state.vertex_shader = shader;
+ device->updateStateBlock->changed.vertexShader = TRUE;
+
+ if (device->isRecordingState)
+ {
+ TRACE("Recording... not performing anything.\n");
+ return;
+ }
+
+ if (shader == prev)
+ {
+ TRACE("Application is setting the old shader over, nothing to do.\n");
+ return;
+ }
+
+ device_invalidate_state(device, STATE_VSHADER);
+}
+
+struct wined3d_shader * CDECL wined3d_device_get_vertex_shader(const struct wined3d_device *device)
+{
+ TRACE("device %p.\n", device);
+
+ return device->stateBlock->state.vertex_shader;
+}
+
+void CDECL wined3d_device_set_vs_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer)
+{
+ struct wined3d_buffer *prev;
+
+ TRACE("device %p, idx %u, buffer %p.\n", device, idx, buffer);
+
+ if (idx >= MAX_CONSTANT_BUFFERS)
+ {
+ WARN("Invalid constant buffer index %u.\n", idx);
+ return;
+ }
+
+ prev = device->updateStateBlock->state.vs_cb[idx];
+ device->updateStateBlock->state.vs_cb[idx] = buffer;
+
+ if (device->isRecordingState)
+ {
+ if (buffer)
+ wined3d_buffer_incref(buffer);
+ if (prev)
+ wined3d_buffer_decref(prev);
+ return;
+ }
+
+ if (prev != buffer)
+ {
+ if (buffer)
+ {
+ InterlockedIncrement(&buffer->resource.bind_count);
+ wined3d_buffer_incref(buffer);
+ }
+ if (prev)
+ {
+ InterlockedDecrement(&prev->resource.bind_count);
+ wined3d_buffer_decref(prev);
+ }
+ }
+}
+
+struct wined3d_buffer * CDECL wined3d_device_get_vs_cb(const struct wined3d_device *device, UINT idx)
+{
+ TRACE("device %p, idx %u.\n", device, idx);
+
+ if (idx >= MAX_CONSTANT_BUFFERS)
+ {
+ WARN("Invalid constant buffer index %u.\n", idx);
+ return NULL;
+ }
+
+ return device->stateBlock->state.vs_cb[idx];
+}
+
+void CDECL wined3d_device_set_vs_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler)
+{
+ struct wined3d_sampler *prev;
+
+ TRACE("device %p, idx %u, sampler %p.\n", device, idx, sampler);
+
+ if (idx >= MAX_SAMPLER_OBJECTS)
+ {
+ WARN("Invalid sampler index %u.\n", idx);
+ return;
+ }
+
+ prev = device->updateStateBlock->state.vs_sampler[idx];
+ device->updateStateBlock->state.vs_sampler[idx] = sampler;
+
+ if (sampler)
+ wined3d_sampler_incref(sampler);
+ if (prev)
+ wined3d_sampler_decref(prev);
+}
+
+struct wined3d_sampler * CDECL wined3d_device_get_vs_sampler(const struct wined3d_device *device, UINT idx)
+{
+ TRACE("device %p, idx %u.\n", device, idx);
+
+ if (idx >= MAX_SAMPLER_OBJECTS)
+ {
+ WARN("Invalid sampler index %u.\n", idx);
+ return NULL;
+ }
+
+ return device->stateBlock->state.vs_sampler[idx];
+}
+
+HRESULT CDECL wined3d_device_set_vs_consts_b(struct wined3d_device *device,
+ UINT start_register, const BOOL *constants, UINT bool_count)
+{
+ UINT count = min(bool_count, MAX_CONST_B - start_register);
+ UINT i;
+
+ TRACE("device %p, start_register %u, constants %p, bool_count %u.\n",
+ device, start_register, constants, bool_count);
+
+ if (!constants || start_register >= MAX_CONST_B)
+ return WINED3DERR_INVALIDCALL;
+
+ memcpy(&device->updateStateBlock->state.vs_consts_b[start_register], constants, count * sizeof(BOOL));
+ for (i = 0; i < count; ++i)
+ TRACE("Set BOOL constant %u to %s.\n", start_register + i, constants[i] ? "true" : "false");
+
+ for (i = start_register; i < count + start_register; ++i)
+ device->updateStateBlock->changed.vertexShaderConstantsB |= (1 << i);
+
+ if (!device->isRecordingState)
+ device_invalidate_state(device, STATE_VERTEXSHADERCONSTANT);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_get_vs_consts_b(const struct wined3d_device *device,
+ UINT start_register, BOOL *constants, UINT bool_count)
+{
+ UINT count = min(bool_count, MAX_CONST_B - start_register);
+
+ TRACE("device %p, start_register %u, constants %p, bool_count %u.\n",
+ device, start_register, constants, bool_count);
+
+ if (!constants || start_register >= MAX_CONST_B)
+ return WINED3DERR_INVALIDCALL;
+
+ memcpy(constants, &device->stateBlock->state.vs_consts_b[start_register], count * sizeof(BOOL));
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_set_vs_consts_i(struct wined3d_device *device,
+ UINT start_register, const int *constants, UINT vector4i_count)
+{
+ UINT count = min(vector4i_count, MAX_CONST_I - start_register);
+ UINT i;
+
+ TRACE("device %p, start_register %u, constants %p, vector4i_count %u.\n",
+ device, start_register, constants, vector4i_count);
+
+ if (!constants || start_register >= MAX_CONST_I)
+ return WINED3DERR_INVALIDCALL;
+
+ memcpy(&device->updateStateBlock->state.vs_consts_i[start_register * 4], constants, count * sizeof(int) * 4);
+ for (i = 0; i < count; ++i)
+ TRACE("Set INT constant %u to {%d, %d, %d, %d}.\n", start_register + i,
+ constants[i * 4], constants[i * 4 + 1],
+ constants[i * 4 + 2], constants[i * 4 + 3]);
+
+ for (i = start_register; i < count + start_register; ++i)
+ device->updateStateBlock->changed.vertexShaderConstantsI |= (1 << i);
+
+ if (!device->isRecordingState)
+ device_invalidate_state(device, STATE_VERTEXSHADERCONSTANT);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_get_vs_consts_i(const struct wined3d_device *device,
+ UINT start_register, int *constants, UINT vector4i_count)
+{
+ UINT count = min(vector4i_count, MAX_CONST_I - start_register);
+
+ TRACE("device %p, start_register %u, constants %p, vector4i_count %u.\n",
+ device, start_register, constants, vector4i_count);
+
+ if (!constants || start_register >= MAX_CONST_I)
+ return WINED3DERR_INVALIDCALL;
+
+ memcpy(constants, &device->stateBlock->state.vs_consts_i[start_register * 4], count * sizeof(int) * 4);
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_set_vs_consts_f(struct wined3d_device *device,
+ UINT start_register, const float *constants, UINT vector4f_count)
+{
+ UINT i;
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+
+ TRACE("device %p, start_register %u, constants %p, vector4f_count %u.\n",
+ device, start_register, constants, vector4f_count);
+
+ /* Specifically test start_register > limit to catch MAX_UINT overflows
+ * when adding start_register + vector4f_count. */
+ if (!constants
+ || start_register + vector4f_count > d3d_info->limits.vs_uniform_count
+ || start_register > d3d_info->limits.vs_uniform_count)
+ return WINED3DERR_INVALIDCALL;
+
+ memcpy(&device->updateStateBlock->state.vs_consts_f[start_register * 4],
+ constants, vector4f_count * sizeof(float) * 4);
+ if (TRACE_ON(d3d))
+ {
+ for (i = 0; i < vector4f_count; ++i)
+ TRACE("Set FLOAT constant %u to {%.8e, %.8e, %.8e, %.8e}.\n", start_register + i,
+ constants[i * 4], constants[i * 4 + 1],
+ constants[i * 4 + 2], constants[i * 4 + 3]);
+ }
+
+ if (!device->isRecordingState)
+ {
+ device->shader_backend->shader_update_float_vertex_constants(device, start_register, vector4f_count);
+ device_invalidate_state(device, STATE_VERTEXSHADERCONSTANT);
+ }
+
+ memset(device->updateStateBlock->changed.vertexShaderConstantsF + start_register, 1,
+ sizeof(*device->updateStateBlock->changed.vertexShaderConstantsF) * vector4f_count);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_get_vs_consts_f(const struct wined3d_device *device,
+ UINT start_register, float *constants, UINT vector4f_count)
+{
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+ int count = min(vector4f_count, d3d_info->limits.vs_uniform_count - start_register);
+
+ TRACE("device %p, start_register %u, constants %p, vector4f_count %u.\n",
+ device, start_register, constants, vector4f_count);
+
+ if (!constants || count < 0)
+ return WINED3DERR_INVALIDCALL;
+
+ memcpy(constants, &device->stateBlock->state.vs_consts_f[start_register * 4], count * sizeof(float) * 4);
+
+ return WINED3D_OK;
+}
+
+static void device_invalidate_texture_stage(const struct wined3d_device *device, DWORD stage)
+{
+ DWORD i;
+
+ for (i = 0; i <= WINED3D_HIGHEST_TEXTURE_STATE; ++i)
+ {
+ device_invalidate_state(device, STATE_TEXTURESTAGE(stage, i));
+ }
+}
+
+static void device_map_stage(struct wined3d_device *device, DWORD stage, DWORD unit)
+{
+ DWORD i = device->rev_tex_unit_map[unit];
+ DWORD j = device->texUnitMap[stage];
+
+ device->texUnitMap[stage] = unit;
+ if (i != WINED3D_UNMAPPED_STAGE && i != stage)
+ device->texUnitMap[i] = WINED3D_UNMAPPED_STAGE;
+
+ device->rev_tex_unit_map[unit] = stage;
+ if (j != WINED3D_UNMAPPED_STAGE && j != unit)
+ device->rev_tex_unit_map[j] = WINED3D_UNMAPPED_STAGE;
+}
+
+static void device_update_fixed_function_usage_map(struct wined3d_device *device)
+{
+ UINT i;
+
+ device->fixed_function_usage_map = 0;
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ const struct wined3d_state *state = &device->stateBlock->state;
+ enum wined3d_texture_op color_op = state->texture_states[i][WINED3D_TSS_COLOR_OP];
+ enum wined3d_texture_op alpha_op = state->texture_states[i][WINED3D_TSS_ALPHA_OP];
+ DWORD color_arg1 = state->texture_states[i][WINED3D_TSS_COLOR_ARG1] & WINED3DTA_SELECTMASK;
+ DWORD color_arg2 = state->texture_states[i][WINED3D_TSS_COLOR_ARG2] & WINED3DTA_SELECTMASK;
+ DWORD color_arg3 = state->texture_states[i][WINED3D_TSS_COLOR_ARG0] & WINED3DTA_SELECTMASK;
+ DWORD alpha_arg1 = state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] & WINED3DTA_SELECTMASK;
+ DWORD alpha_arg2 = state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] & WINED3DTA_SELECTMASK;
+ DWORD alpha_arg3 = state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] & WINED3DTA_SELECTMASK;
+
+ /* Not used, and disable higher stages. */
+ if (color_op == WINED3D_TOP_DISABLE)
+ break;
+
+ if (((color_arg1 == WINED3DTA_TEXTURE) && color_op != WINED3D_TOP_SELECT_ARG2)
+ || ((color_arg2 == WINED3DTA_TEXTURE) && color_op != WINED3D_TOP_SELECT_ARG1)
+ || ((color_arg3 == WINED3DTA_TEXTURE)
+ && (color_op == WINED3D_TOP_MULTIPLY_ADD || color_op == WINED3D_TOP_LERP))
+ || ((alpha_arg1 == WINED3DTA_TEXTURE) && alpha_op != WINED3D_TOP_SELECT_ARG2)
+ || ((alpha_arg2 == WINED3DTA_TEXTURE) && alpha_op != WINED3D_TOP_SELECT_ARG1)
+ || ((alpha_arg3 == WINED3DTA_TEXTURE)
+ && (alpha_op == WINED3D_TOP_MULTIPLY_ADD || alpha_op == WINED3D_TOP_LERP)))
+ device->fixed_function_usage_map |= (1 << i);
+
+ if ((color_op == WINED3D_TOP_BUMPENVMAP || color_op == WINED3D_TOP_BUMPENVMAP_LUMINANCE)
+ && i < MAX_TEXTURES - 1)
+ device->fixed_function_usage_map |= (1 << (i + 1));
+ }
+}
+
+static void device_map_fixed_function_samplers(struct wined3d_device *device, const struct wined3d_d3d_info *d3d_info)
+{
+ unsigned int i, tex;
+ WORD ffu_map;
+
+ device_update_fixed_function_usage_map(device);
+ ffu_map = device->fixed_function_usage_map;
+
+ if (d3d_info->limits.ffp_textures == d3d_info->limits.ffp_blend_stages
+ || device->stateBlock->state.lowest_disabled_stage <= d3d_info->limits.ffp_textures)
+ {
+ for (i = 0; ffu_map; ffu_map >>= 1, ++i)
+ {
+ if (!(ffu_map & 1)) continue;
+
+ if (device->texUnitMap[i] != i)
+ {
+ device_map_stage(device, i, i);
+ device_invalidate_state(device, STATE_SAMPLER(i));
+ device_invalidate_texture_stage(device, i);
+ }
+ }
+ return;
+ }
+
+ /* Now work out the mapping */
+ tex = 0;
+ for (i = 0; ffu_map; ffu_map >>= 1, ++i)
+ {
+ if (!(ffu_map & 1)) continue;
+
+ if (device->texUnitMap[i] != tex)
+ {
+ device_map_stage(device, i, tex);
+ device_invalidate_state(device, STATE_SAMPLER(i));
+ device_invalidate_texture_stage(device, i);
+ }
+
+ ++tex;
+ }
+}
+
+static void device_map_psamplers(struct wined3d_device *device, const struct wined3d_d3d_info *d3d_info)
+{
+ const enum wined3d_sampler_texture_type *sampler_type =
+ device->stateBlock->state.pixel_shader->reg_maps.sampler_type;
+ unsigned int i;
+
+ for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
+ {
+ if (sampler_type[i] && device->texUnitMap[i] != i)
+ {
+ device_map_stage(device, i, i);
+ device_invalidate_state(device, STATE_SAMPLER(i));
+ if (i < d3d_info->limits.ffp_blend_stages)
+ device_invalidate_texture_stage(device, i);
+ }
+ }
+}
+
+static BOOL device_unit_free_for_vs(const struct wined3d_device *device,
+ const enum wined3d_sampler_texture_type *pshader_sampler_tokens,
+ const enum wined3d_sampler_texture_type *vshader_sampler_tokens, DWORD unit)
+{
+ DWORD current_mapping = device->rev_tex_unit_map[unit];
+
+ /* Not currently used */
+ if (current_mapping == WINED3D_UNMAPPED_STAGE) return TRUE;
+
+ if (current_mapping < MAX_FRAGMENT_SAMPLERS) {
+ /* Used by a fragment sampler */
+
+ if (!pshader_sampler_tokens) {
+ /* No pixel shader, check fixed function */
+ return current_mapping >= MAX_TEXTURES || !(device->fixed_function_usage_map & (1 << current_mapping));
+ }
+
+ /* Pixel shader, check the shader's sampler map */
+ return !pshader_sampler_tokens[current_mapping];
+ }
+
+ /* Used by a vertex sampler */
+ return !vshader_sampler_tokens[current_mapping - MAX_FRAGMENT_SAMPLERS];
+}
+
+static void device_map_vsamplers(struct wined3d_device *device, BOOL ps, const struct wined3d_gl_info *gl_info)
+{
+ const enum wined3d_sampler_texture_type *vshader_sampler_type =
+ device->stateBlock->state.vertex_shader->reg_maps.sampler_type;
+ const enum wined3d_sampler_texture_type *pshader_sampler_type = NULL;
+ int start = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers) - 1;
+ int i;
+
+ if (ps)
+ {
+ /* Note that we only care if a sampler is sampled or not, not the sampler's specific type.
+ * Otherwise we'd need to call shader_update_samplers() here for 1.x pixelshaders. */
+ pshader_sampler_type = device->stateBlock->state.pixel_shader->reg_maps.sampler_type;
+ }
+
+ for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) {
+ DWORD vsampler_idx = i + MAX_FRAGMENT_SAMPLERS;
+ if (vshader_sampler_type[i])
+ {
+ if (device->texUnitMap[vsampler_idx] != WINED3D_UNMAPPED_STAGE)
+ {
+ /* Already mapped somewhere */
+ continue;
+ }
+
+ while (start >= 0)
+ {
+ if (device_unit_free_for_vs(device, pshader_sampler_type, vshader_sampler_type, start))
+ {
+ device_map_stage(device, vsampler_idx, start);
+ device_invalidate_state(device, STATE_SAMPLER(vsampler_idx));
+
+ --start;
+ break;
+ }
+
+ --start;
+ }
+ }
+ }
+}
+
+void device_update_tex_unit_map(struct wined3d_device *device)
+{
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+ const struct wined3d_state *state = &device->stateBlock->state;
+ BOOL vs = use_vs(state);
+ BOOL ps = use_ps(state);
+ /*
+ * Rules are:
+ * -> Pixel shaders need a 1:1 map. In theory the shader input could be mapped too, but
+ * that would be really messy and require shader recompilation
+ * -> When the mapping of a stage is changed, sampler and ALL texture stage states have
+ * to be reset. Because of that try to work with a 1:1 mapping as much as possible
+ */
+ if (ps)
+ device_map_psamplers(device, d3d_info);
+ else
+ device_map_fixed_function_samplers(device, d3d_info);
+
+ if (vs)
+ device_map_vsamplers(device, ps, gl_info);
+}
+
+void CDECL wined3d_device_set_pixel_shader(struct wined3d_device *device, struct wined3d_shader *shader)
+{
+ struct wined3d_shader *prev = device->updateStateBlock->state.pixel_shader;
+
+ TRACE("device %p, shader %p.\n", device, shader);
+
+ if (shader)
+ wined3d_shader_incref(shader);
+ if (prev)
+ wined3d_shader_decref(prev);
+
+ device->updateStateBlock->state.pixel_shader = shader;
+ device->updateStateBlock->changed.pixelShader = TRUE;
+
+ if (device->isRecordingState)
+ {
+ TRACE("Recording... not performing anything.\n");
+ return;
+ }
+
+ if (shader == prev)
+ {
+ TRACE("Application is setting the old shader over, nothing to do.\n");
+ return;
+ }
+
+ device_invalidate_state(device, STATE_PIXELSHADER);
+}
+
+struct wined3d_shader * CDECL wined3d_device_get_pixel_shader(const struct wined3d_device *device)
+{
+ TRACE("device %p.\n", device);
+
+ return device->stateBlock->state.pixel_shader;
+}
+
+void CDECL wined3d_device_set_ps_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer)
+{
+ struct wined3d_buffer *prev;
+
+ TRACE("device %p, idx %u, buffer %p.\n", device, idx, buffer);
+
+ if (idx >= MAX_CONSTANT_BUFFERS)
+ {
+ WARN("Invalid constant buffer index %u.\n", idx);
+ return;
+ }
+
+ prev = device->updateStateBlock->state.ps_cb[idx];
+ device->updateStateBlock->state.ps_cb[idx] = buffer;
+
+ if (device->isRecordingState)
+ {
+ if (buffer)
+ wined3d_buffer_incref(buffer);
+ if (prev)
+ wined3d_buffer_decref(prev);
+ return;
+ }
+
+ if (prev != buffer)
+ {
+ if (buffer)
+ {
+ InterlockedIncrement(&buffer->resource.bind_count);
+ wined3d_buffer_incref(buffer);
+ }
+ if (prev)
+ {
+ InterlockedDecrement(&prev->resource.bind_count);
+ wined3d_buffer_decref(prev);
+ }
+ }
+}
+
+struct wined3d_buffer * CDECL wined3d_device_get_ps_cb(const struct wined3d_device *device, UINT idx)
+{
+ TRACE("device %p, idx %u.\n", device, idx);
+
+ if (idx >= MAX_CONSTANT_BUFFERS)
+ {
+ WARN("Invalid constant buffer index %u.\n", idx);
+ return NULL;
+ }
+
+ return device->stateBlock->state.ps_cb[idx];
+}
+
+void CDECL wined3d_device_set_ps_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler)
+{
+ struct wined3d_sampler *prev;
+
+ TRACE("device %p, idx %u, sampler %p.\n", device, idx, sampler);
+
+ if (idx >= MAX_SAMPLER_OBJECTS)
+ {
+ WARN("Invalid sampler index %u.\n", idx);
+ return;
+ }
+
+ prev = device->updateStateBlock->state.ps_sampler[idx];
+ device->updateStateBlock->state.ps_sampler[idx] = sampler;
+
+ if (sampler)
+ wined3d_sampler_incref(sampler);
+ if (prev)
+ wined3d_sampler_decref(prev);
+}
+
+struct wined3d_sampler * CDECL wined3d_device_get_ps_sampler(const struct wined3d_device *device, UINT idx)
+{
+ TRACE("device %p, idx %u.\n", device, idx);
+
+ if (idx >= MAX_SAMPLER_OBJECTS)
+ {
+ WARN("Invalid sampler index %u.\n", idx);
+ return NULL;
+ }
+
+ return device->stateBlock->state.ps_sampler[idx];
+}
+
+HRESULT CDECL wined3d_device_set_ps_consts_b(struct wined3d_device *device,
+ UINT start_register, const BOOL *constants, UINT bool_count)
+{
+ UINT count = min(bool_count, MAX_CONST_B - start_register);
+ UINT i;
+
+ TRACE("device %p, start_register %u, constants %p, bool_count %u.\n",
+ device, start_register, constants, bool_count);
+
+ if (!constants || start_register >= MAX_CONST_B)
+ return WINED3DERR_INVALIDCALL;
+
+ memcpy(&device->updateStateBlock->state.ps_consts_b[start_register], constants, count * sizeof(BOOL));
+ for (i = 0; i < count; ++i)
+ TRACE("Set BOOL constant %u to %s.\n", start_register + i, constants[i] ? "true" : "false");
+
+ for (i = start_register; i < count + start_register; ++i)
+ device->updateStateBlock->changed.pixelShaderConstantsB |= (1 << i);
+
+ if (!device->isRecordingState)
+ device_invalidate_state(device, STATE_PIXELSHADERCONSTANT);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_get_ps_consts_b(const struct wined3d_device *device,
+ UINT start_register, BOOL *constants, UINT bool_count)
+{
+ UINT count = min(bool_count, MAX_CONST_B - start_register);
+
+ TRACE("device %p, start_register %u, constants %p, bool_count %u.\n",
+ device, start_register, constants, bool_count);
+
+ if (!constants || start_register >= MAX_CONST_B)
+ return WINED3DERR_INVALIDCALL;
+
+ memcpy(constants, &device->stateBlock->state.ps_consts_b[start_register], count * sizeof(BOOL));
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_set_ps_consts_i(struct wined3d_device *device,
+ UINT start_register, const int *constants, UINT vector4i_count)
+{
+ UINT count = min(vector4i_count, MAX_CONST_I - start_register);
+ UINT i;
+
+ TRACE("device %p, start_register %u, constants %p, vector4i_count %u.\n",
+ device, start_register, constants, vector4i_count);
+
+ if (!constants || start_register >= MAX_CONST_I)
+ return WINED3DERR_INVALIDCALL;
+
+ memcpy(&device->updateStateBlock->state.ps_consts_i[start_register * 4], constants, count * sizeof(int) * 4);
+ for (i = 0; i < count; ++i)
+ TRACE("Set INT constant %u to {%d, %d, %d, %d}.\n", start_register + i,
+ constants[i * 4], constants[i * 4 + 1],
+ constants[i * 4 + 2], constants[i * 4 + 3]);
+
+ for (i = start_register; i < count + start_register; ++i)
+ device->updateStateBlock->changed.pixelShaderConstantsI |= (1 << i);
+
+ if (!device->isRecordingState)
+ device_invalidate_state(device, STATE_PIXELSHADERCONSTANT);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_get_ps_consts_i(const struct wined3d_device *device,
+ UINT start_register, int *constants, UINT vector4i_count)
+{
+ UINT count = min(vector4i_count, MAX_CONST_I - start_register);
+
+ TRACE("device %p, start_register %u, constants %p, vector4i_count %u.\n",
+ device, start_register, constants, vector4i_count);
+
+ if (!constants || start_register >= MAX_CONST_I)
+ return WINED3DERR_INVALIDCALL;
+
+ memcpy(constants, &device->stateBlock->state.ps_consts_i[start_register * 4], count * sizeof(int) * 4);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_set_ps_consts_f(struct wined3d_device *device,
+ UINT start_register, const float *constants, UINT vector4f_count)
+{
+ UINT i;
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+
+ TRACE("device %p, start_register %u, constants %p, vector4f_count %u.\n",
+ device, start_register, constants, vector4f_count);
+
+ /* Specifically test start_register > limit to catch MAX_UINT overflows
+ * when adding start_register + vector4f_count. */
+ if (!constants
+ || start_register + vector4f_count > d3d_info->limits.ps_uniform_count
+ || start_register > d3d_info->limits.ps_uniform_count)
+ return WINED3DERR_INVALIDCALL;
+
+ memcpy(&device->updateStateBlock->state.ps_consts_f[start_register * 4],
+ constants, vector4f_count * sizeof(float) * 4);
+ if (TRACE_ON(d3d))
+ {
+ for (i = 0; i < vector4f_count; ++i)
+ TRACE("Set FLOAT constant %u to {%.8e, %.8e, %.8e, %.8e}.\n", start_register + i,
+ constants[i * 4], constants[i * 4 + 1],
+ constants[i * 4 + 2], constants[i * 4 + 3]);
+ }
+
+ if (!device->isRecordingState)
+ {
+ device->shader_backend->shader_update_float_pixel_constants(device, start_register, vector4f_count);
+ device_invalidate_state(device, STATE_PIXELSHADERCONSTANT);
+ }
+
+ memset(device->updateStateBlock->changed.pixelShaderConstantsF + start_register, 1,
+ sizeof(*device->updateStateBlock->changed.pixelShaderConstantsF) * vector4f_count);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_get_ps_consts_f(const struct wined3d_device *device,
+ UINT start_register, float *constants, UINT vector4f_count)
+{
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+ int count = min(vector4f_count, d3d_info->limits.ps_uniform_count - start_register);
+
+ TRACE("device %p, start_register %u, constants %p, vector4f_count %u.\n",
+ device, start_register, constants, vector4f_count);
+
+ if (!constants || count < 0)
+ return WINED3DERR_INVALIDCALL;
+
+ memcpy(constants, &device->stateBlock->state.ps_consts_f[start_register * 4], count * sizeof(float) * 4);
+
+ return WINED3D_OK;
+}
+
+void CDECL wined3d_device_set_geometry_shader(struct wined3d_device *device, struct wined3d_shader *shader)
+{
+ struct wined3d_shader *prev = device->updateStateBlock->state.geometry_shader;
+
+ TRACE("device %p, shader %p.\n", device, shader);
+
+ if (shader)
+ wined3d_shader_incref(shader);
+ if (prev)
+ wined3d_shader_decref(prev);
+
+ device->updateStateBlock->state.geometry_shader = shader;
+
+ if (device->isRecordingState || shader == prev)
+ return;
+
+ device_invalidate_state(device, STATE_GEOMETRY_SHADER);
+}
+
+struct wined3d_shader * CDECL wined3d_device_get_geometry_shader(const struct wined3d_device *device)
+{
+ TRACE("device %p.\n", device);
+
+ return device->stateBlock->state.geometry_shader;
+}
+
+void CDECL wined3d_device_set_gs_cb(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer)
+{
+ struct wined3d_buffer *prev;
+
+ TRACE("device %p, idx %u, buffer %p.\n", device, idx, buffer);
+
+ if (idx >= MAX_CONSTANT_BUFFERS)
+ {
+ WARN("Invalid constant buffer index %u.\n", idx);
+ return;
+ }
+
+ prev = device->updateStateBlock->state.gs_cb[idx];
+ device->updateStateBlock->state.gs_cb[idx] = buffer;
+
+ if (device->isRecordingState)
+ {
+ if (buffer)
+ wined3d_buffer_incref(buffer);
+ if (prev)
+ wined3d_buffer_decref(prev);
+ return;
+ }
+
+ if (prev != buffer)
+ {
+ if (buffer)
+ {
+ InterlockedIncrement(&buffer->resource.bind_count);
+ wined3d_buffer_incref(buffer);
+ }
+ if (prev)
+ {
+ InterlockedDecrement(&prev->resource.bind_count);
+ wined3d_buffer_decref(prev);
+ }
+ }
+}
+
+struct wined3d_buffer * CDECL wined3d_device_get_gs_cb(const struct wined3d_device *device, UINT idx)
+{
+ TRACE("device %p, idx %u.\n", device, idx);
+
+ if (idx >= MAX_CONSTANT_BUFFERS)
+ {
+ WARN("Invalid constant buffer index %u.\n", idx);
+ return NULL;
+ }
+
+ return device->stateBlock->state.gs_cb[idx];
+}
+
+void CDECL wined3d_device_set_gs_sampler(struct wined3d_device *device, UINT idx, struct wined3d_sampler *sampler)
+{
+ struct wined3d_sampler *prev;
+
+ TRACE("device %p, idx %u, sampler %p.\n", device, idx, sampler);
+
+ if (idx >= MAX_SAMPLER_OBJECTS)
+ {
+ WARN("Invalid sampler index %u.\n", idx);
+ return;
+ }
+
+ prev = device->updateStateBlock->state.gs_sampler[idx];
+ device->updateStateBlock->state.gs_sampler[idx] = sampler;
+
+ if (sampler)
+ wined3d_sampler_incref(sampler);
+ if (prev)
+ wined3d_sampler_decref(prev);
+}
+
+struct wined3d_sampler * CDECL wined3d_device_get_gs_sampler(const struct wined3d_device *device, UINT idx)
+{
+ TRACE("device %p, idx %u.\n", device, idx);
+
+ if (idx >= MAX_SAMPLER_OBJECTS)
+ {
+ WARN("Invalid sampler index %u.\n", idx);
+ return NULL;
+ }
+
+ return device->stateBlock->state.gs_sampler[idx];
+}
+
+/* Context activation is done by the caller. */
+/* Do not call while under the GL lock. */
+#define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
+static HRESULT process_vertices_strided(const struct wined3d_device *device, DWORD dwDestIndex, DWORD dwCount,
+ const struct wined3d_stream_info *stream_info, struct wined3d_buffer *dest, DWORD flags,
+ DWORD DestFVF)
+{
+ struct wined3d_matrix mat, proj_mat, view_mat, world_mat;
+ struct wined3d_viewport vp;
+ UINT vertex_size;
+ unsigned int i;
+ BYTE *dest_ptr;
+ BOOL doClip;
+ DWORD numTextures;
+ HRESULT hr;
+
+ if (stream_info->use_map & (1 << WINED3D_FFP_NORMAL))
+ {
+ WARN(" lighting state not saved yet... Some strange stuff may happen !\n");
+ }
+
+ if (!(stream_info->use_map & (1 << WINED3D_FFP_POSITION)))
+ {
+ ERR("Source has no position mask\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (device->stateBlock->state.render_states[WINED3D_RS_CLIPPING])
+ {
+ static BOOL warned = FALSE;
+ /*
+ * The clipping code is not quite correct. Some things need
+ * to be checked against IDirect3DDevice3 (!), d3d8 and d3d9,
+ * so disable clipping for now.
+ * (The graphics in Half-Life are broken, and my processvertices
+ * test crashes with IDirect3DDevice3)
+ doClip = TRUE;
+ */
+ doClip = FALSE;
+ if(!warned) {
+ warned = TRUE;
+ FIXME("Clipping is broken and disabled for now\n");
+ }
+ }
+ else
+ doClip = FALSE;
+
+ vertex_size = get_flexible_vertex_size(DestFVF);
+ if (FAILED(hr = wined3d_buffer_map(dest, dwDestIndex * vertex_size, dwCount * vertex_size, &dest_ptr, 0)))
+ {
+ WARN("Failed to map buffer, hr %#x.\n", hr);
+ return hr;
+ }
+
+ wined3d_device_get_transform(device, WINED3D_TS_VIEW, &view_mat);
+ wined3d_device_get_transform(device, WINED3D_TS_PROJECTION, &proj_mat);
+ wined3d_device_get_transform(device, WINED3D_TS_WORLD_MATRIX(0), &world_mat);
+
+ TRACE("View mat:\n");
+ TRACE("%f %f %f %f\n", view_mat.u.s._11, view_mat.u.s._12, view_mat.u.s._13, view_mat.u.s._14);
+ TRACE("%f %f %f %f\n", view_mat.u.s._21, view_mat.u.s._22, view_mat.u.s._23, view_mat.u.s._24);
+ TRACE("%f %f %f %f\n", view_mat.u.s._31, view_mat.u.s._32, view_mat.u.s._33, view_mat.u.s._34);
+ TRACE("%f %f %f %f\n", view_mat.u.s._41, view_mat.u.s._42, view_mat.u.s._43, view_mat.u.s._44);
+
+ TRACE("Proj mat:\n");
+ TRACE("%f %f %f %f\n", proj_mat.u.s._11, proj_mat.u.s._12, proj_mat.u.s._13, proj_mat.u.s._14);
+ TRACE("%f %f %f %f\n", proj_mat.u.s._21, proj_mat.u.s._22, proj_mat.u.s._23, proj_mat.u.s._24);
+ TRACE("%f %f %f %f\n", proj_mat.u.s._31, proj_mat.u.s._32, proj_mat.u.s._33, proj_mat.u.s._34);
+ TRACE("%f %f %f %f\n", proj_mat.u.s._41, proj_mat.u.s._42, proj_mat.u.s._43, proj_mat.u.s._44);
+
+ TRACE("World mat:\n");
+ TRACE("%f %f %f %f\n", world_mat.u.s._11, world_mat.u.s._12, world_mat.u.s._13, world_mat.u.s._14);
+ TRACE("%f %f %f %f\n", world_mat.u.s._21, world_mat.u.s._22, world_mat.u.s._23, world_mat.u.s._24);
+ TRACE("%f %f %f %f\n", world_mat.u.s._31, world_mat.u.s._32, world_mat.u.s._33, world_mat.u.s._34);
+ TRACE("%f %f %f %f\n", world_mat.u.s._41, world_mat.u.s._42, world_mat.u.s._43, world_mat.u.s._44);
+
+ /* Get the viewport */
+ wined3d_device_get_viewport(device, &vp);
+ TRACE("viewport x %u, y %u, width %u, height %u, min_z %.8e, max_z %.8e.\n",
+ vp.x, vp.y, vp.width, vp.height, vp.min_z, vp.max_z);
+
+ multiply_matrix(&mat,&view_mat,&world_mat);
+ multiply_matrix(&mat,&proj_mat,&mat);
+
+ numTextures = (DestFVF & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
+
+ for (i = 0; i < dwCount; i+= 1) {
+ unsigned int tex_index;
+
+ if ( ((DestFVF & WINED3DFVF_POSITION_MASK) == WINED3DFVF_XYZ ) ||
+ ((DestFVF & WINED3DFVF_POSITION_MASK) == WINED3DFVF_XYZRHW ) ) {
+ /* The position first */
+ const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_POSITION];
+ const float *p = (const float *)(element->data.addr + i * element->stride);
+ float x, y, z, rhw;
+ TRACE("In: ( %06.2f %06.2f %06.2f )\n", p[0], p[1], p[2]);
+
+ /* Multiplication with world, view and projection matrix */
+ x = (p[0] * mat.u.s._11) + (p[1] * mat.u.s._21) + (p[2] * mat.u.s._31) + (1.0f * mat.u.s._41);
+ y = (p[0] * mat.u.s._12) + (p[1] * mat.u.s._22) + (p[2] * mat.u.s._32) + (1.0f * mat.u.s._42);
+ z = (p[0] * mat.u.s._13) + (p[1] * mat.u.s._23) + (p[2] * mat.u.s._33) + (1.0f * mat.u.s._43);
+ rhw = (p[0] * mat.u.s._14) + (p[1] * mat.u.s._24) + (p[2] * mat.u.s._34) + (1.0f * mat.u.s._44);
+
+ TRACE("x=%f y=%f z=%f rhw=%f\n", x, y, z, rhw);
+
+ /* WARNING: The following things are taken from d3d7 and were not yet checked
+ * against d3d8 or d3d9!
+ */
+
+ /* Clipping conditions: From msdn
+ *
+ * A vertex is clipped if it does not match the following requirements
+ * -rhw < x <= rhw
+ * -rhw < y <= rhw
+ * 0 < z <= rhw
+ * 0 < rhw ( Not in d3d7, but tested in d3d7)
+ *
+ * If clipping is on is determined by the D3DVOP_CLIP flag in D3D7, and
+ * by the D3DRS_CLIPPING in D3D9(according to the msdn, not checked)
+ *
+ */
+
+ if( !doClip ||
+ ( (-rhw -eps < x) && (-rhw -eps < y) && ( -eps < z) &&
+ (x <= rhw + eps) && (y <= rhw + eps ) && (z <= rhw + eps) &&
+ ( rhw > eps ) ) ) {
+
+ /* "Normal" viewport transformation (not clipped)
+ * 1) The values are divided by rhw
+ * 2) The y axis is negative, so multiply it with -1
+ * 3) Screen coordinates go from -(Width/2) to +(Width/2) and
+ * -(Height/2) to +(Height/2). The z range is MinZ to MaxZ
+ * 4) Multiply x with Width/2 and add Width/2
+ * 5) The same for the height
+ * 6) Add the viewpoint X and Y to the 2D coordinates and
+ * The minimum Z value to z
+ * 7) rhw = 1 / rhw Reciprocal of Homogeneous W....
+ *
+ * Well, basically it's simply a linear transformation into viewport
+ * coordinates
+ */
+
+ x /= rhw;
+ y /= rhw;
+ z /= rhw;
+
+ y *= -1;
+
+ x *= vp.width / 2;
+ y *= vp.height / 2;
+ z *= vp.max_z - vp.min_z;
+
+ x += vp.width / 2 + vp.x;
+ y += vp.height / 2 + vp.y;
+ z += vp.min_z;
+
+ rhw = 1 / rhw;
+ } else {
+ /* That vertex got clipped
+ * Contrary to OpenGL it is not dropped completely, it just
+ * undergoes a different calculation.
+ */
+ TRACE("Vertex got clipped\n");
+ x += rhw;
+ y += rhw;
+
+ x /= 2;
+ y /= 2;
+
+ /* Msdn mentions that Direct3D9 keeps a list of clipped vertices
+ * outside of the main vertex buffer memory. That needs some more
+ * investigation...
+ */
+ }
+
+ TRACE("Writing (%f %f %f) %f\n", x, y, z, rhw);
+
+
+ ( (float *) dest_ptr)[0] = x;
+ ( (float *) dest_ptr)[1] = y;
+ ( (float *) dest_ptr)[2] = z;
+ ( (float *) dest_ptr)[3] = rhw; /* SIC, see ddraw test! */
+
+ dest_ptr += 3 * sizeof(float);
+
+ if ((DestFVF & WINED3DFVF_POSITION_MASK) == WINED3DFVF_XYZRHW)
+ dest_ptr += sizeof(float);
+ }
+
+ if (DestFVF & WINED3DFVF_PSIZE)
+ dest_ptr += sizeof(DWORD);
+
+ if (DestFVF & WINED3DFVF_NORMAL)
+ {
+ const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_NORMAL];
+ const float *normal = (const float *)(element->data.addr + i * element->stride);
+ /* AFAIK this should go into the lighting information */
+ FIXME("Didn't expect the destination to have a normal\n");
+ copy_and_next(dest_ptr, normal, 3 * sizeof(float));
+ }
+
+ if (DestFVF & WINED3DFVF_DIFFUSE)
+ {
+ const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_DIFFUSE];
+ const DWORD *color_d = (const DWORD *)(element->data.addr + i * element->stride);
+ if (!(stream_info->use_map & (1 << WINED3D_FFP_DIFFUSE)))
+ {
+ static BOOL warned = FALSE;
+
+ if(!warned) {
+ ERR("No diffuse color in source, but destination has one\n");
+ warned = TRUE;
+ }
+
+ *( (DWORD *) dest_ptr) = 0xffffffff;
+ dest_ptr += sizeof(DWORD);
+ }
+ else
+ {
+ copy_and_next(dest_ptr, color_d, sizeof(DWORD));
+ }
+ }
+
+ if (DestFVF & WINED3DFVF_SPECULAR)
+ {
+ /* What's the color value in the feedback buffer? */
+ const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_SPECULAR];
+ const DWORD *color_s = (const DWORD *)(element->data.addr + i * element->stride);
+ if (!(stream_info->use_map & (1 << WINED3D_FFP_SPECULAR)))
+ {
+ static BOOL warned = FALSE;
+
+ if(!warned) {
+ ERR("No specular color in source, but destination has one\n");
+ warned = TRUE;
+ }
+
+ *(DWORD *)dest_ptr = 0xff000000;
+ dest_ptr += sizeof(DWORD);
+ }
+ else
+ {
+ copy_and_next(dest_ptr, color_s, sizeof(DWORD));
+ }
+ }
+
+ for (tex_index = 0; tex_index < numTextures; ++tex_index)
+ {
+ const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_TEXCOORD0 + tex_index];
+ const float *tex_coord = (const float *)(element->data.addr + i * element->stride);
+ if (!(stream_info->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + tex_index))))
+ {
+ ERR("No source texture, but destination requests one\n");
+ dest_ptr += GET_TEXCOORD_SIZE_FROM_FVF(DestFVF, tex_index) * sizeof(float);
+ }
+ else
+ {
+ copy_and_next(dest_ptr, tex_coord, GET_TEXCOORD_SIZE_FROM_FVF(DestFVF, tex_index) * sizeof(float));
+ }
+ }
+ }
+
+ wined3d_buffer_unmap(dest);
+
+ return WINED3D_OK;
+}
+#undef copy_and_next
+
+/* Do not call while under the GL lock. */
+HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device,
+ UINT src_start_idx, UINT dst_idx, UINT vertex_count, struct wined3d_buffer *dst_buffer,
+ const struct wined3d_vertex_declaration *declaration, DWORD flags, DWORD dst_fvf)
+{
+ struct wined3d_state *state = &device->stateBlock->state;
+ struct wined3d_stream_info stream_info;
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+ struct wined3d_shader *vs;
+ unsigned int i;
+ HRESULT hr;
+
+ TRACE("device %p, src_start_idx %u, dst_idx %u, vertex_count %u, "
+ "dst_buffer %p, declaration %p, flags %#x, dst_fvf %#x.\n",
+ device, src_start_idx, dst_idx, vertex_count,
+ dst_buffer, declaration, flags, dst_fvf);
+
+ if (declaration)
+ FIXME("Output vertex declaration not implemented yet.\n");
+
+ /* Need any context to write to the vbo. */
+ context = context_acquire(device, NULL);
+ gl_info = context->gl_info;
+
+ vs = state->vertex_shader;
+ state->vertex_shader = NULL;
+ device_stream_info_from_declaration(device, &stream_info);
+ state->vertex_shader = vs;
+
+ /* We can't convert FROM a VBO, and vertex buffers used to source into
+ * process_vertices() are unlikely to ever be used for drawing. Release
+ * VBOs in those buffers and fix up the stream_info structure.
+ *
+ * Also apply the start index. */
+ for (i = 0; i < (sizeof(stream_info.elements) / sizeof(*stream_info.elements)); ++i)
+ {
+ struct wined3d_stream_info_element *e;
+
+ if (!(stream_info.use_map & (1 << i)))
+ continue;
+
+ e = &stream_info.elements[i];
+ if (e->data.buffer_object)
+ {
+ struct wined3d_buffer *vb = state->streams[e->stream_idx].buffer;
+ e->data.buffer_object = 0;
+ e->data.addr = (BYTE *)((ULONG_PTR)e->data.addr + (ULONG_PTR)buffer_get_sysmem(vb, gl_info));
+ GL_EXTCALL(glDeleteBuffersARB(1, &vb->buffer_object));
+ vb->buffer_object = 0;
+ }
+ if (e->data.addr)
+ e->data.addr += e->stride * src_start_idx;
+ }
+
+ hr = process_vertices_strided(device, dst_idx, vertex_count,
+ &stream_info, dst_buffer, flags, dst_fvf);
+
+ context_release(context);
+
+ return hr;
+}
+
+void CDECL wined3d_device_set_texture_stage_state(struct wined3d_device *device,
+ UINT stage, enum wined3d_texture_stage_state state, DWORD value)
+{
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+ DWORD old_value;
+
+ TRACE("device %p, stage %u, state %s, value %#x.\n",
+ device, stage, debug_d3dtexturestate(state), value);
+
+ if (state > WINED3D_HIGHEST_TEXTURE_STATE)
+ {
+ WARN("Invalid state %#x passed.\n", state);
+ return;
+ }
+
+ if (stage >= d3d_info->limits.ffp_blend_stages)
+ {
+ WARN("Attempting to set stage %u which is higher than the max stage %u, ignoring.\n",
+ stage, d3d_info->limits.ffp_blend_stages - 1);
+ return;
+ }
+
+ old_value = device->updateStateBlock->state.texture_states[stage][state];
+ device->updateStateBlock->changed.textureState[stage] |= 1 << state;
+ device->updateStateBlock->state.texture_states[stage][state] = value;
+
+ if (device->isRecordingState)
+ {
+ TRACE("Recording... not performing anything.\n");
+ return;
+ }
+
+ /* Checked after the assignments to allow proper stateblock recording. */
+ if (old_value == value)
+ {
+ TRACE("Application is setting the old value over, nothing to do.\n");
+ return;
+ }
+
+ if (stage > device->stateBlock->state.lowest_disabled_stage
+ && device->StateTable[STATE_TEXTURESTAGE(0, state)].representative
+ == STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP))
+ {
+ /* Colorop change above lowest disabled stage? That won't change
+ * anything in the GL setup. Changes in other states are important on
+ * disabled stages too. */
+ return;
+ }
+
+ if (state == WINED3D_TSS_COLOR_OP)
+ {
+ unsigned int i;
+
+ if (value == WINED3D_TOP_DISABLE && old_value != WINED3D_TOP_DISABLE)
+ {
+ /* Previously enabled stage disabled now. Make sure to dirtify
+ * all enabled stages above stage, they have to be disabled.
+ *
+ * The current stage is dirtified below. */
+ for (i = stage + 1; i < device->stateBlock->state.lowest_disabled_stage; ++i)
+ {
+ TRACE("Additionally dirtifying stage %u.\n", i);
+ device_invalidate_state(device, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP));
+ }
+ device->stateBlock->state.lowest_disabled_stage = stage;
+ TRACE("New lowest disabled: %u.\n", stage);
+ }
+ else if (value != WINED3D_TOP_DISABLE && old_value == WINED3D_TOP_DISABLE)
+ {
+ /* Previously disabled stage enabled. Stages above it may need
+ * enabling. Stage must be lowest_disabled_stage here, if it's
+ * bigger success is returned above, and stages below the lowest
+ * disabled stage can't be enabled (because they are enabled
+ * already).
+ *
+ * Again stage stage doesn't need to be dirtified here, it is
+ * handled below. */
+ for (i = stage + 1; i < d3d_info->limits.ffp_blend_stages; ++i)
+ {
+ if (device->updateStateBlock->state.texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE)
+ break;
+ TRACE("Additionally dirtifying stage %u due to enable.\n", i);
+ device_invalidate_state(device, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP));
+ }
+ device->stateBlock->state.lowest_disabled_stage = i;
+ TRACE("New lowest disabled: %u.\n", i);
+ }
+ }
+
+ device_invalidate_state(device, STATE_TEXTURESTAGE(stage, state));
+}
+
+DWORD CDECL wined3d_device_get_texture_stage_state(const struct wined3d_device *device,
+ UINT stage, enum wined3d_texture_stage_state state)
+{
+ TRACE("device %p, stage %u, state %s.\n",
+ device, stage, debug_d3dtexturestate(state));
+
+ if (state > WINED3D_HIGHEST_TEXTURE_STATE)
+ {
+ WARN("Invalid state %#x passed.\n", state);
+ return 0;
+ }
+
+ return device->updateStateBlock->state.texture_states[stage][state];
+}
+
+HRESULT CDECL wined3d_device_set_texture(struct wined3d_device *device,
+ UINT stage, struct wined3d_texture *texture)
+{
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+ struct wined3d_texture *prev;
+
+ TRACE("device %p, stage %u, texture %p.\n", device, stage, texture);
+
+ if (stage >= WINED3DVERTEXTEXTURESAMPLER0 && stage <= WINED3DVERTEXTEXTURESAMPLER3)
+ stage -= (WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS);
+
+ /* Windows accepts overflowing this array... we do not. */
+ if (stage >= sizeof(device->stateBlock->state.textures) / sizeof(*device->stateBlock->state.textures))
+ {
+ WARN("Ignoring invalid stage %u.\n", stage);
+ return WINED3D_OK;
+ }
+
+ if (texture && texture->resource.pool == WINED3D_POOL_SCRATCH)
+ {
+ WARN("Rejecting attempt to set scratch texture.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ device->updateStateBlock->changed.textures |= 1 << stage;
+
+ prev = device->updateStateBlock->state.textures[stage];
+ TRACE("Previous texture %p.\n", prev);
+
+ if (texture == prev)
+ {
+ TRACE("App is setting the same texture again, nothing to do.\n");
+ return WINED3D_OK;
+ }
+
+ TRACE("Setting new texture to %p.\n", texture);
+ device->updateStateBlock->state.textures[stage] = texture;
+
+ if (device->isRecordingState)
+ {
+ TRACE("Recording... not performing anything\n");
+
+ if (texture) wined3d_texture_incref(texture);
+ if (prev) wined3d_texture_decref(prev);
+
+ return WINED3D_OK;
+ }
+
+ if (texture)
+ {
+ LONG bind_count = InterlockedIncrement(&texture->resource.bind_count);
+
+ wined3d_texture_incref(texture);
+
+ if (!prev || texture->target != prev->target)
+ device_invalidate_state(device, STATE_PIXELSHADER);
+
+ if (!prev && stage < d3d_info->limits.ffp_blend_stages)
+ {
+ /* The source arguments for color and alpha ops have different
+ * meanings when a NULL texture is bound, so the COLOR_OP and
+ * ALPHA_OP have to be dirtified. */
+ device_invalidate_state(device, STATE_TEXTURESTAGE(stage, WINED3D_TSS_COLOR_OP));
+ device_invalidate_state(device, STATE_TEXTURESTAGE(stage, WINED3D_TSS_ALPHA_OP));
+ }
+
+ if (bind_count == 1)
+ texture->sampler = stage;
+ }
+
+ if (prev)
+ {
+ LONG bind_count = InterlockedDecrement(&prev->resource.bind_count);
+
+ if (!texture && stage < d3d_info->limits.ffp_blend_stages)
+ {
+ device_invalidate_state(device, STATE_TEXTURESTAGE(stage, WINED3D_TSS_COLOR_OP));
+ device_invalidate_state(device, STATE_TEXTURESTAGE(stage, WINED3D_TSS_ALPHA_OP));
+ }
+
+ if (bind_count && prev->sampler == stage)
+ {
+ unsigned int i;
+
+ /* Search for other stages the texture is bound to. Shouldn't
+ * happen if applications bind textures to a single stage only. */
+ TRACE("Searching for other stages the texture is bound to.\n");
+ for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
+ {
+ if (device->updateStateBlock->state.textures[i] == prev)
+ {
+ TRACE("Texture is also bound to stage %u.\n", i);
+ prev->sampler = i;
+ break;
+ }
+ }
+ }
+
+ wined3d_texture_decref(prev);
+ }
+
+ device_invalidate_state(device, STATE_SAMPLER(stage));
+
+ return WINED3D_OK;
+}
+
+struct wined3d_texture * CDECL wined3d_device_get_texture(const struct wined3d_device *device, UINT stage)
+{
+ TRACE("device %p, stage %u.\n", device, stage);
+
+ if (stage >= WINED3DVERTEXTEXTURESAMPLER0 && stage <= WINED3DVERTEXTEXTURESAMPLER3)
+ stage -= (WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS);
+
+ if (stage >= sizeof(device->stateBlock->state.textures) / sizeof(*device->stateBlock->state.textures))
+ {
+ WARN("Ignoring invalid stage %u.\n", stage);
+ return NULL; /* Windows accepts overflowing this array ... we do not. */
+ }
+
+ return device->stateBlock->state.textures[stage];
+}
+
+HRESULT CDECL wined3d_device_get_back_buffer(const struct wined3d_device *device, UINT swapchain_idx,
+ UINT backbuffer_idx, enum wined3d_backbuffer_type backbuffer_type, struct wined3d_surface **backbuffer)
+{
+ struct wined3d_swapchain *swapchain;
+
+ TRACE("device %p, swapchain_idx %u, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n",
+ device, swapchain_idx, backbuffer_idx, backbuffer_type, backbuffer);
+
+ if (!(swapchain = wined3d_device_get_swapchain(device, swapchain_idx)))
+ return WINED3DERR_INVALIDCALL;
+
+ if (!(*backbuffer = wined3d_swapchain_get_back_buffer(swapchain, backbuffer_idx, backbuffer_type)))
+ return WINED3DERR_INVALIDCALL;
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_get_device_caps(const struct wined3d_device *device, WINED3DCAPS *caps)
+{
+ TRACE("device %p, caps %p.\n", device, caps);
+
+ return wined3d_get_device_caps(device->wined3d, device->adapter->ordinal,
+ device->create_parms.device_type, caps);
+}
+
+HRESULT CDECL wined3d_device_get_display_mode(const struct wined3d_device *device, UINT swapchain_idx,
+ struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation)
+{
+ struct wined3d_swapchain *swapchain;
+
+ TRACE("device %p, swapchain_idx %u, mode %p, rotation %p.\n",
+ device, swapchain_idx, mode, rotation);
+
+ if (!(swapchain = wined3d_device_get_swapchain(device, swapchain_idx)))
+ return WINED3DERR_INVALIDCALL;
+
+ return wined3d_swapchain_get_display_mode(swapchain, mode, rotation);
+}
+
+HRESULT CDECL wined3d_device_begin_stateblock(struct wined3d_device *device)
+{
+ struct wined3d_stateblock *stateblock;
+ HRESULT hr;
+
+ TRACE("device %p.\n", device);
+
+ if (device->isRecordingState)
+ return WINED3DERR_INVALIDCALL;
+
+ hr = wined3d_stateblock_create(device, WINED3D_SBT_RECORDED, &stateblock);
+ if (FAILED(hr))
+ return hr;
+
+ wined3d_stateblock_decref(device->updateStateBlock);
+ device->updateStateBlock = stateblock;
+ device->isRecordingState = TRUE;
+
+ TRACE("Recording stateblock %p.\n", stateblock);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_end_stateblock(struct wined3d_device *device,
+ struct wined3d_stateblock **stateblock)
+{
+ struct wined3d_stateblock *object = device->updateStateBlock;
+
+ TRACE("device %p, stateblock %p.\n", device, stateblock);
+
+ if (!device->isRecordingState)
+ {
+ WARN("Not recording.\n");
+ *stateblock = NULL;
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ stateblock_init_contained_states(object);
+
+ *stateblock = object;
+ device->isRecordingState = FALSE;
+ device->updateStateBlock = device->stateBlock;
+ wined3d_stateblock_incref(device->updateStateBlock);
+
+ TRACE("Returning stateblock %p.\n", *stateblock);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_begin_scene(struct wined3d_device *device)
+{
+ /* At the moment we have no need for any functionality at the beginning
+ * of a scene. */
+ TRACE("device %p.\n", device);
+
+ if (device->inScene)
+ {
+ WARN("Already in scene, returning WINED3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+ device->inScene = TRUE;
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_end_scene(struct wined3d_device *device)
+{
+ struct wined3d_context *context;
+
+ TRACE("device %p.\n", device);
+
+ if (!device->inScene)
+ {
+ WARN("Not in scene, returning WINED3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ context = context_acquire(device, NULL);
+ /* We only have to do this if we need to read the, swapbuffers performs a flush for us */
+ context->gl_info->gl_ops.gl.p_glFlush();
+ /* No checkGLcall here to avoid locking the lock just for checking a call that hardly ever
+ * fails. */
+ context_release(context);
+
+ device->inScene = FALSE;
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_present(const struct wined3d_device *device, const RECT *src_rect,
+ const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region, DWORD flags)
+{
+ UINT i;
+
+ TRACE("device %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p, flags %#x.\n",
+ device, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect),
+ dst_window_override, dirty_region, flags);
+
+ for (i = 0; i < device->swapchain_count; ++i)
+ {
+ wined3d_swapchain_present(device->swapchains[i], src_rect,
+ dst_rect, dst_window_override, dirty_region, flags);
+ }
+
+ return WINED3D_OK;
+}
+
+/* Do not call while under the GL lock. */
+HRESULT CDECL wined3d_device_clear(struct wined3d_device *device, DWORD rect_count,
+ const RECT *rects, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil)
+{
+ RECT draw_rect;
+
+ TRACE("device %p, rect_count %u, rects %p, flags %#x, color {%.8e, %.8e, %.8e, %.8e}, depth %.8e, stencil %u.\n",
+ device, rect_count, rects, flags, color->r, color->g, color->b, color->a, depth, stencil);
+
+ if (!rect_count && rects)
+ {
+ WARN("Rects is %p, but rect_count is 0, ignoring clear\n", rects);
+ return WINED3D_OK;
+ }
+
+ if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL))
+ {
+ struct wined3d_surface *ds = device->fb.depth_stencil;
+ if (!ds)
+ {
+ WARN("Clearing depth and/or stencil without a depth stencil buffer attached, returning WINED3DERR_INVALIDCALL\n");
+ /* TODO: What about depth stencil buffers without stencil bits? */
+ return WINED3DERR_INVALIDCALL;
+ }
+ else if (flags & WINED3DCLEAR_TARGET)
+ {
+ if (ds->resource.width < device->fb.render_targets[0]->resource.width
+ || ds->resource.height < device->fb.render_targets[0]->resource.height)
+ {
+ WARN("Silently ignoring depth and target clear with mismatching sizes\n");
+ return WINED3D_OK;
+ }
+ }
+ }
+
+ wined3d_get_draw_rect(&device->stateBlock->state, &draw_rect);
+ device_clear_render_targets(device, device->adapter->gl_info.limits.buffers,
+ &device->fb, rect_count, rects, &draw_rect, flags, color, depth, stencil);
+
+ return WINED3D_OK;
+}
+
+void CDECL wined3d_device_set_primitive_type(struct wined3d_device *device,
+ enum wined3d_primitive_type primitive_type)
+{
+ GLenum gl_primitive_type, prev;
+
+ TRACE("device %p, primitive_type %s\n", device, debug_d3dprimitivetype(primitive_type));
+
+ device->updateStateBlock->changed.primitive_type = TRUE;
+ gl_primitive_type = gl_primitive_type_from_d3d(primitive_type);
+ prev = device->updateStateBlock->state.gl_primitive_type;
+ device->updateStateBlock->state.gl_primitive_type = gl_primitive_type;
+ if (!device->isRecordingState && gl_primitive_type != prev
+ && (gl_primitive_type == GL_POINTS || prev == GL_POINTS))
+ device_invalidate_state(device, STATE_POINT_SIZE_ENABLE);
+}
+
+void CDECL wined3d_device_get_primitive_type(const struct wined3d_device *device,
+ enum wined3d_primitive_type *primitive_type)
+{
+ TRACE("device %p, primitive_type %p\n", device, primitive_type);
+
+ *primitive_type = d3d_primitive_type_from_gl(device->stateBlock->state.gl_primitive_type);
+
+ TRACE("Returning %s\n", debug_d3dprimitivetype(*primitive_type));
+}
+
+HRESULT CDECL wined3d_device_draw_primitive(struct wined3d_device *device, UINT start_vertex, UINT vertex_count)
+{
+ TRACE("device %p, start_vertex %u, vertex_count %u.\n", device, start_vertex, vertex_count);
+
+ if (!device->stateBlock->state.vertex_declaration)
+ {
+ WARN("Called without a valid vertex declaration set.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (device->stateBlock->state.load_base_vertex_index)
+ {
+ device->stateBlock->state.load_base_vertex_index = 0;
+ device_invalidate_state(device, STATE_BASEVERTEXINDEX);
+ }
+
+ /* Account for the loading offset due to index buffers. Instead of
+ * reloading all sources correct it with the startvertex parameter. */
+ draw_primitive(device, start_vertex, vertex_count, 0, 0, FALSE);
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count)
+{
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+
+ TRACE("device %p, start_idx %u, index_count %u.\n", device, start_idx, index_count);
+
+ if (!device->stateBlock->state.index_buffer)
+ {
+ /* D3D9 returns D3DERR_INVALIDCALL when DrawIndexedPrimitive is called
+ * without an index buffer set. (The first time at least...)
+ * D3D8 simply dies, but I doubt it can do much harm to return
+ * D3DERR_INVALIDCALL there as well. */
+ WARN("Called without a valid index buffer set, returning WINED3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (!device->stateBlock->state.vertex_declaration)
+ {
+ WARN("Called without a valid vertex declaration set.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (!gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX] &&
+ device->stateBlock->state.load_base_vertex_index != device->stateBlock->state.base_vertex_index)
+ {
+ device->stateBlock->state.load_base_vertex_index = device->stateBlock->state.base_vertex_index;
+ device_invalidate_state(device, STATE_BASEVERTEXINDEX);
+ }
+
+ draw_primitive(device, start_idx, index_count, 0, 0, TRUE);
+
+ return WINED3D_OK;
+}
+
+void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device *device,
+ UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count)
+{
+ TRACE("device %p, start_idx %u, index_count %u.\n", device, start_idx, index_count);
+
+ draw_primitive(device, start_idx, index_count, start_instance, instance_count, TRUE);
+}
+
+/* This is a helper function for UpdateTexture, there is no UpdateVolume method in D3D. */
+static HRESULT device_update_volume(struct wined3d_device *device,
+ struct wined3d_volume *src_volume, struct wined3d_volume *dst_volume)
+{
+ struct wined3d_map_desc src;
+ struct wined3d_map_desc dst;
+ HRESULT hr;
+
+ TRACE("device %p, src_volume %p, dst_volume %p.\n",
+ device, src_volume, dst_volume);
+
+ /* TODO: Implement direct loading into the gl volume instead of using
+ * memcpy and dirtification to improve loading performance. */
+ if (FAILED(hr = wined3d_volume_map(src_volume, &src, NULL, WINED3D_MAP_READONLY)))
+ return hr;
+ if (FAILED(hr = wined3d_volume_map(dst_volume, &dst, NULL, WINED3D_MAP_DISCARD)))
+ {
+ wined3d_volume_unmap(src_volume);
+ return hr;
+ }
+
+ memcpy(dst.data, src.data, dst_volume->resource.size);
+
+ hr = wined3d_volume_unmap(dst_volume);
+ if (FAILED(hr))
+ wined3d_volume_unmap(src_volume);
+ else
+ hr = wined3d_volume_unmap(src_volume);
+
+ return hr;
+}
+
+HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device,
+ struct wined3d_texture *src_texture, struct wined3d_texture *dst_texture)
+{
+ enum wined3d_resource_type type;
+ unsigned int level_count, i;
+ HRESULT hr;
+
+ TRACE("device %p, src_texture %p, dst_texture %p.\n", device, src_texture, dst_texture);
+
+ /* Verify that the source and destination textures are non-NULL. */
+ if (!src_texture || !dst_texture)
+ {
+ WARN("Source and destination textures must be non-NULL, returning WINED3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (src_texture == dst_texture)
+ {
+ WARN("Source and destination are the same object, returning WINED3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ /* Verify that the source and destination textures are the same type. */
+ type = src_texture->resource.type;
+ if (dst_texture->resource.type != type)
+ {
+ WARN("Source and destination have different types, returning WINED3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ /* Check that both textures have the identical numbers of levels. */
+ level_count = wined3d_texture_get_level_count(src_texture);
+ if (wined3d_texture_get_level_count(dst_texture) != level_count)
+ {
+ WARN("Source and destination have different level counts, returning WINED3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ /* Make sure that the destination texture is loaded. */
+ dst_texture->texture_ops->texture_preload(dst_texture, SRGB_RGB);
+
+ /* Update every surface level of the texture. */
+ switch (type)
+ {
+ case WINED3D_RTYPE_TEXTURE:
+ {
+ struct wined3d_surface *src_surface;
+ struct wined3d_surface *dst_surface;
+
+ for (i = 0; i < level_count; ++i)
+ {
+ src_surface = surface_from_resource(wined3d_texture_get_sub_resource(src_texture, i));
+ dst_surface = surface_from_resource(wined3d_texture_get_sub_resource(dst_texture, i));
+ hr = wined3d_device_update_surface(device, src_surface, NULL, dst_surface, NULL);
+ if (FAILED(hr))
+ {
+ WARN("Failed to update surface, hr %#x.\n", hr);
+ return hr;
+ }
+ }
+ break;
+ }
+
+ case WINED3D_RTYPE_CUBE_TEXTURE:
+ {
+ struct wined3d_surface *src_surface;
+ struct wined3d_surface *dst_surface;
+
+ for (i = 0; i < level_count * 6; ++i)
+ {
+ src_surface = surface_from_resource(wined3d_texture_get_sub_resource(src_texture, i));
+ dst_surface = surface_from_resource(wined3d_texture_get_sub_resource(dst_texture, i));
+ hr = wined3d_device_update_surface(device, src_surface, NULL, dst_surface, NULL);
+ if (FAILED(hr))
+ {
+ WARN("Failed to update surface, hr %#x.\n", hr);
+ return hr;
+ }
+ }
+ break;
+ }
+
+ case WINED3D_RTYPE_VOLUME_TEXTURE:
+ {
+ for (i = 0; i < level_count; ++i)
+ {
+ hr = device_update_volume(device,
+ volume_from_resource(wined3d_texture_get_sub_resource(src_texture, i)),
+ volume_from_resource(wined3d_texture_get_sub_resource(dst_texture, i)));
+ if (FAILED(hr))
+ {
+ WARN("Failed to update volume, hr %#x.\n", hr);
+ return hr;
+ }
+ }
+ break;
+ }
+
+ default:
+ FIXME("Unsupported texture type %#x.\n", type);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_get_front_buffer_data(const struct wined3d_device *device,
+ UINT swapchain_idx, struct wined3d_surface *dst_surface)
+{
+ struct wined3d_swapchain *swapchain;
+
+ TRACE("device %p, swapchain_idx %u, dst_surface %p.\n", device, swapchain_idx, dst_surface);
+
+ if (!(swapchain = wined3d_device_get_swapchain(device, swapchain_idx)))
+ return WINED3DERR_INVALIDCALL;
+
+ return wined3d_swapchain_get_front_buffer_data(swapchain, dst_surface);
+}
+
+HRESULT CDECL wined3d_device_validate_device(const struct wined3d_device *device, DWORD *num_passes)
+{
+ const struct wined3d_state *state = &device->stateBlock->state;
+ struct wined3d_texture *texture;
+ DWORD i;
+
+ TRACE("device %p, num_passes %p.\n", device, num_passes);
+
+ for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
+ {
+ if (state->sampler_states[i][WINED3D_SAMP_MIN_FILTER] == WINED3D_TEXF_NONE)
+ {
+ WARN("Sampler state %u has minfilter D3DTEXF_NONE, returning D3DERR_UNSUPPORTEDTEXTUREFILTER\n", i);
+ return WINED3DERR_UNSUPPORTEDTEXTUREFILTER;
+ }
+ if (state->sampler_states[i][WINED3D_SAMP_MAG_FILTER] == WINED3D_TEXF_NONE)
+ {
+ WARN("Sampler state %u has magfilter D3DTEXF_NONE, returning D3DERR_UNSUPPORTEDTEXTUREFILTER\n", i);
+ return WINED3DERR_UNSUPPORTEDTEXTUREFILTER;
+ }
+
+ texture = state->textures[i];
+ if (!texture || texture->resource.format->flags & WINED3DFMT_FLAG_FILTERING) continue;
+
+ if (state->sampler_states[i][WINED3D_SAMP_MAG_FILTER] != WINED3D_TEXF_POINT)
+ {
+ WARN("Non-filterable texture and mag filter enabled on samper %u, returning E_FAIL\n", i);
+ return E_FAIL;
+ }
+ if (state->sampler_states[i][WINED3D_SAMP_MIN_FILTER] != WINED3D_TEXF_POINT)
+ {
+ WARN("Non-filterable texture and min filter enabled on samper %u, returning E_FAIL\n", i);
+ return E_FAIL;
+ }
+ if (state->sampler_states[i][WINED3D_SAMP_MIP_FILTER] != WINED3D_TEXF_NONE
+ && state->sampler_states[i][WINED3D_SAMP_MIP_FILTER] != WINED3D_TEXF_POINT)
+ {
+ WARN("Non-filterable texture and mip filter enabled on samper %u, returning E_FAIL\n", i);
+ return E_FAIL;
+ }
+ }
+
+ if (state->render_states[WINED3D_RS_ZENABLE] || state->render_states[WINED3D_RS_ZWRITEENABLE]
+ || state->render_states[WINED3D_RS_STENCILENABLE])
+ {
+ struct wined3d_surface *ds = device->fb.depth_stencil;
+ struct wined3d_surface *target = device->fb.render_targets[0];
+
+ if(ds && target
+ && (ds->resource.width < target->resource.width || ds->resource.height < target->resource.height))
+ {
+ WARN("Depth stencil is smaller than the color buffer, returning D3DERR_CONFLICTINGRENDERSTATE\n");
+ return WINED3DERR_CONFLICTINGRENDERSTATE;
+ }
+ }
+
+ /* return a sensible default */
+ *num_passes = 1;
+
+ TRACE("returning D3D_OK\n");
+ return WINED3D_OK;
+}
+
+void CDECL wined3d_device_set_software_vertex_processing(struct wined3d_device *device, BOOL software)
+{
+ static BOOL warned;
+
+ TRACE("device %p, software %#x.\n", device, software);
+
+ if (!warned)
+ {
+ FIXME("device %p, software %#x stub!\n", device, software);
+ warned = TRUE;
+ }
+
+ device->softwareVertexProcessing = software;
+}
+
+BOOL CDECL wined3d_device_get_software_vertex_processing(const struct wined3d_device *device)
+{
+ static BOOL warned;
+
+ TRACE("device %p.\n", device);
+
+ if (!warned)
+ {
+ TRACE("device %p stub!\n", device);
+ warned = TRUE;
+ }
+
+ return device->softwareVertexProcessing;
+}
+
+HRESULT CDECL wined3d_device_get_raster_status(const struct wined3d_device *device,
+ UINT swapchain_idx, struct wined3d_raster_status *raster_status)
+{
+ struct wined3d_swapchain *swapchain;
+
+ TRACE("device %p, swapchain_idx %u, raster_status %p.\n",
+ device, swapchain_idx, raster_status);
+
+ if (!(swapchain = wined3d_device_get_swapchain(device, swapchain_idx)))
+ return WINED3DERR_INVALIDCALL;
+
+ return wined3d_swapchain_get_raster_status(swapchain, raster_status);
+}
+
+HRESULT CDECL wined3d_device_set_npatch_mode(struct wined3d_device *device, float segments)
+{
+ static BOOL warned;
+
+ TRACE("device %p, segments %.8e.\n", device, segments);
+
+ if (segments != 0.0f)
+ {
+ if (!warned)
+ {
+ FIXME("device %p, segments %.8e stub!\n", device, segments);
+ warned = TRUE;
+ }
+ }
+
+ return WINED3D_OK;
+}
+
+float CDECL wined3d_device_get_npatch_mode(const struct wined3d_device *device)
+{
+ static BOOL warned;
+
+ TRACE("device %p.\n", device);
+
+ if (!warned)
+ {
+ FIXME("device %p stub!\n", device);
+ warned = TRUE;
+ }
+
+ return 0.0f;
+}
+
+HRESULT CDECL wined3d_device_update_surface(struct wined3d_device *device,
+ struct wined3d_surface *src_surface, const RECT *src_rect,
+ struct wined3d_surface *dst_surface, const POINT *dst_point)
+{
+ TRACE("device %p, src_surface %p, src_rect %s, dst_surface %p, dst_point %s.\n",
+ device, src_surface, wine_dbgstr_rect(src_rect),
+ dst_surface, wine_dbgstr_point(dst_point));
+
+ if (src_surface->resource.pool != WINED3D_POOL_SYSTEM_MEM || dst_surface->resource.pool != WINED3D_POOL_DEFAULT)
+ {
+ WARN("source %p must be SYSTEMMEM and dest %p must be DEFAULT, returning WINED3DERR_INVALIDCALL\n",
+ src_surface, dst_surface);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ return surface_upload_from_surface(dst_surface, dst_point, src_surface, src_rect);
+}
+
+/* Do not call while under the GL lock. */
+HRESULT CDECL wined3d_device_color_fill(struct wined3d_device *device,
+ struct wined3d_surface *surface, const RECT *rect, const struct wined3d_color *color)
+{
+ RECT r;
+
+ TRACE("device %p, surface %p, rect %s, color {%.8e, %.8e, %.8e, %.8e}.\n",
+ device, surface, wine_dbgstr_rect(rect),
+ color->r, color->g, color->b, color->a);
+
+ if (surface->resource.pool != WINED3D_POOL_DEFAULT && surface->resource.pool != WINED3D_POOL_SYSTEM_MEM)
+ {
+ WARN("Color-fill not allowed on %s surfaces.\n", debug_d3dpool(surface->resource.pool));
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (!rect)
+ {
+ SetRect(&r, 0, 0, surface->resource.width, surface->resource.height);
+ rect = &r;
+ }
+
+ return surface_color_fill(surface, rect, color);
+}
+
+/* Do not call while under the GL lock. */
+void CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *device,
+ struct wined3d_rendertarget_view *rendertarget_view, const struct wined3d_color *color)
+{
+ struct wined3d_resource *resource;
+ HRESULT hr;
+ RECT rect;
+
+ resource = rendertarget_view->resource;
+ if (resource->type != WINED3D_RTYPE_SURFACE)
+ {
+ FIXME("Only supported on surface resources\n");
+ return;
+ }
+
+ SetRect(&rect, 0, 0, resource->width, resource->height);
+ hr = surface_color_fill(surface_from_resource(resource), &rect, color);
+ if (FAILED(hr)) ERR("Color fill failed, hr %#x.\n", hr);
+}
+
+struct wined3d_surface * CDECL wined3d_device_get_render_target(const struct wined3d_device *device,
+ UINT render_target_idx)
+{
+ TRACE("device %p, render_target_idx %u.\n", device, render_target_idx);
+
+ if (render_target_idx >= device->adapter->gl_info.limits.buffers)
+ {
+ WARN("Only %u render targets are supported.\n", device->adapter->gl_info.limits.buffers);
+ return NULL;
+ }
+
+ return device->fb.render_targets[render_target_idx];
+}
+
+struct wined3d_surface * CDECL wined3d_device_get_depth_stencil(const struct wined3d_device *device)
+{
+ TRACE("device %p.\n", device);
+
+ return device->fb.depth_stencil;
+}
+
+HRESULT CDECL wined3d_device_set_render_target(struct wined3d_device *device,
+ UINT render_target_idx, struct wined3d_surface *render_target, BOOL set_viewport)
+{
+ struct wined3d_surface *prev;
+
+ TRACE("device %p, render_target_idx %u, render_target %p, set_viewport %#x.\n",
+ device, render_target_idx, render_target, set_viewport);
+
+ if (render_target_idx >= device->adapter->gl_info.limits.buffers)
+ {
+ WARN("Only %u render targets are supported.\n", device->adapter->gl_info.limits.buffers);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ /* Render target 0 can't be set to NULL. */
+ if (!render_target && !render_target_idx)
+ {
+ WARN("Trying to set render target 0 to NULL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (render_target && !(render_target->resource.usage & WINED3DUSAGE_RENDERTARGET))
+ {
+ FIXME("Surface %p doesn't have render target usage.\n", render_target);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ /* Set the viewport and scissor rectangles, if requested. Tests show that
+ * stateblock recording is ignored, the change goes directly into the
+ * primary stateblock. */
+ if (!render_target_idx && set_viewport)
+ {
+ struct wined3d_state *state = &device->stateBlock->state;
+
+ state->viewport.x = 0;
+ state->viewport.y = 0;
+ state->viewport.width = render_target->resource.width;
+ state->viewport.height = render_target->resource.height;
+ state->viewport.min_z = 0.0f;
+ state->viewport.max_z = 1.0f;
+ device_invalidate_state(device, STATE_VIEWPORT);
+
+ state->scissor_rect.top = 0;
+ state->scissor_rect.left = 0;
+ state->scissor_rect.right = render_target->resource.width;
+ state->scissor_rect.bottom = render_target->resource.height;
+ device_invalidate_state(device, STATE_SCISSORRECT);
+ }
+
+
+ prev = device->fb.render_targets[render_target_idx];
+ if (render_target == prev)
+ return WINED3D_OK;
+
+ if (render_target)
+ wined3d_surface_incref(render_target);
+ device->fb.render_targets[render_target_idx] = render_target;
+ /* Release after the assignment, to prevent device_resource_released()
+ * from seeing the surface as still in use. */
+ if (prev)
+ wined3d_surface_decref(prev);
+
+ device_invalidate_state(device, STATE_FRAMEBUFFER);
+
+ return WINED3D_OK;
+}
+
+void CDECL wined3d_device_set_depth_stencil(struct wined3d_device *device, struct wined3d_surface *depth_stencil)
+{
+ struct wined3d_surface *prev = device->fb.depth_stencil;
+
+ TRACE("device %p, depth_stencil %p, old depth_stencil %p.\n",
+ device, depth_stencil, prev);
+
+ if (prev == depth_stencil)
+ {
+ TRACE("Trying to do a NOP SetRenderTarget operation.\n");
+ return;
+ }
+
+ if (prev)
+ {
+ if (device->swapchains[0]->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL
+ || prev->flags & SFLAG_DISCARD)
+ {
+ surface_modify_ds_location(prev, SFLAG_DISCARDED,
+ prev->resource.width, prev->resource.height);
+ if (prev == device->onscreen_depth_stencil)
+ {
+ wined3d_surface_decref(device->onscreen_depth_stencil);
+ device->onscreen_depth_stencil = NULL;
+ }
+ }
+ }
+
+ device->fb.depth_stencil = depth_stencil;
+ if (depth_stencil)
+ wined3d_surface_incref(depth_stencil);
+
+ if (!prev != !depth_stencil)
+ {
+ /* Swapping NULL / non NULL depth stencil affects the depth and tests */
+ device_invalidate_state(device, STATE_RENDER(WINED3D_RS_ZENABLE));
+ device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILENABLE));
+ device_invalidate_state(device, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK));
+ device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
+ }
+ else if (prev && prev->resource.format->depth_size != depth_stencil->resource.format->depth_size)
+ {
+ device_invalidate_state(device, STATE_RENDER(WINED3D_RS_DEPTHBIAS));
+ }
+ if (prev)
+ wined3d_surface_decref(prev);
+
+ device_invalidate_state(device, STATE_FRAMEBUFFER);
+
+ return;
+}
+
+HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device,
+ UINT x_hotspot, UINT y_hotspot, struct wined3d_surface *cursor_image)
+{
+ TRACE("device %p, x_hotspot %u, y_hotspot %u, cursor_image %p.\n",
+ device, x_hotspot, y_hotspot, cursor_image);
+
+ /* some basic validation checks */
+ if (device->cursorTexture)
+ {
+ struct wined3d_context *context = context_acquire(device, NULL);
+ context->gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->cursorTexture);
+ context_release(context);
+ device->cursorTexture = 0;
+ }
+
+ if (cursor_image)
+ {
+ struct wined3d_display_mode mode;
+ struct wined3d_map_desc map_desc;
+ HRESULT hr;
+
+ /* MSDN: Cursor must be A8R8G8B8 */
+ if (cursor_image->resource.format->id != WINED3DFMT_B8G8R8A8_UNORM)
+ {
+ WARN("surface %p has an invalid format.\n", cursor_image);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (FAILED(hr = wined3d_get_adapter_display_mode(device->wined3d, device->adapter->ordinal, &mode, NULL)))
+ {
+ ERR("Failed to get display mode, hr %#x.\n", hr);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ /* MSDN: Cursor must be smaller than the display mode */
+ if (cursor_image->resource.width > mode.width || cursor_image->resource.height > mode.height)
+ {
+ WARN("Surface %p dimensions are %ux%u, but screen dimensions are %ux%u.\n",
+ cursor_image, cursor_image->resource.width, cursor_image->resource.height,
+ mode.width, mode.height);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ /* TODO: MSDN: Cursor sizes must be a power of 2 */
+
+ /* Do not store the surface's pointer because the application may
+ * release it after setting the cursor image. Windows doesn't
+ * addref the set surface, so we can't do this either without
+ * creating circular refcount dependencies. Copy out the gl texture
+ * instead. */
+ device->cursorWidth = cursor_image->resource.width;
+ device->cursorHeight = cursor_image->resource.height;
+ if (SUCCEEDED(wined3d_surface_map(cursor_image, &map_desc, NULL, WINED3D_MAP_READONLY)))
+ {
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ const struct wined3d_format *format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM);
+ struct wined3d_context *context;
+ char *mem, *bits = map_desc.data;
+ GLint intfmt = format->glInternal;
+ GLint gl_format = format->glFormat;
+ GLint type = format->glType;
+ INT height = device->cursorHeight;
+ INT width = device->cursorWidth;
+ INT bpp = format->byte_count;
+ INT i;
+
+ /* Reformat the texture memory (pitch and width can be
+ * different) */
+ mem = HeapAlloc(GetProcessHeap(), 0, width * height * bpp);
+ for (i = 0; i < height; ++i)
+ memcpy(&mem[width * bpp * i], &bits[map_desc.row_pitch * i], width * bpp);
+ wined3d_surface_unmap(cursor_image);
+
+ context = context_acquire(device, NULL);
+
+ if (gl_info->supported[APPLE_CLIENT_STORAGE])
+ {
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
+ checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)");
+ }
+
+ invalidate_active_texture(device, context);
+ /* Create a new cursor texture */
+ gl_info->gl_ops.gl.p_glGenTextures(1, &device->cursorTexture);
+ checkGLcall("glGenTextures");
+ context_bind_texture(context, GL_TEXTURE_2D, device->cursorTexture);
+ /* Copy the bitmap memory into the cursor texture */
+ gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, intfmt, width, height, 0, gl_format, type, mem);
+ checkGLcall("glTexImage2D");
+ HeapFree(GetProcessHeap(), 0, mem);
+
+ if (gl_info->supported[APPLE_CLIENT_STORAGE])
+ {
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
+ checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
+ }
+
+ context_release(context);
+ }
+ else
+ {
+ FIXME("A cursor texture was not returned.\n");
+ device->cursorTexture = 0;
+ }
+
+ if (cursor_image->resource.width == 32 && cursor_image->resource.height == 32)
+ {
+ UINT mask_size = cursor_image->resource.width * cursor_image->resource.height / 8;
+ ICONINFO cursorInfo;
+ DWORD *maskBits;
+ HCURSOR cursor;
+
+ /* 32-bit user32 cursors ignore the alpha channel if it's all
+ * zeroes, and use the mask instead. Fill the mask with all ones
+ * to ensure we still get a fully transparent cursor. */
+ maskBits = HeapAlloc(GetProcessHeap(), 0, mask_size);
+ memset(maskBits, 0xff, mask_size);
+ wined3d_surface_map(cursor_image, &map_desc, NULL,
+ WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY);
+ TRACE("width: %u height: %u.\n", cursor_image->resource.width, cursor_image->resource.height);
+
+ cursorInfo.fIcon = FALSE;
+ cursorInfo.xHotspot = x_hotspot;
+ cursorInfo.yHotspot = y_hotspot;
+ cursorInfo.hbmMask = CreateBitmap(cursor_image->resource.width, cursor_image->resource.height,
+ 1, 1, maskBits);
+ cursorInfo.hbmColor = CreateBitmap(cursor_image->resource.width, cursor_image->resource.height,
+ 1, 32, map_desc.data);
+ wined3d_surface_unmap(cursor_image);
+ /* Create our cursor and clean up. */
+ cursor = CreateIconIndirect(&cursorInfo);
+ if (cursorInfo.hbmMask) DeleteObject(cursorInfo.hbmMask);
+ if (cursorInfo.hbmColor) DeleteObject(cursorInfo.hbmColor);
+ if (device->hardwareCursor) DestroyCursor(device->hardwareCursor);
+ device->hardwareCursor = cursor;
+ if (device->bCursorVisible) SetCursor( cursor );
+ HeapFree(GetProcessHeap(), 0, maskBits);
+ }
+ }
+
+ device->xHotSpot = x_hotspot;
+ device->yHotSpot = y_hotspot;
+ return WINED3D_OK;
+}
+
+void CDECL wined3d_device_set_cursor_position(struct wined3d_device *device,
+ int x_screen_space, int y_screen_space, DWORD flags)
+{
+ TRACE("device %p, x %d, y %d, flags %#x.\n",
+ device, x_screen_space, y_screen_space, flags);
+
+ device->xScreenSpace = x_screen_space;
+ device->yScreenSpace = y_screen_space;
+
+ if (device->hardwareCursor)
+ {
+ POINT pt;
+
+ GetCursorPos( &pt );
+ if (x_screen_space == pt.x && y_screen_space == pt.y)
+ return;
+ SetCursorPos( x_screen_space, y_screen_space );
+
+ /* Switch to the software cursor if position diverges from the hardware one. */
+ GetCursorPos( &pt );
+ if (x_screen_space != pt.x || y_screen_space != pt.y)
+ {
+ if (device->bCursorVisible) SetCursor( NULL );
+ DestroyCursor( device->hardwareCursor );
+ device->hardwareCursor = 0;
+ }
+ }
+}
+
+BOOL CDECL wined3d_device_show_cursor(struct wined3d_device *device, BOOL show)
+{
+ BOOL oldVisible = device->bCursorVisible;
+
+ TRACE("device %p, show %#x.\n", device, show);
+
+ /*
+ * When ShowCursor is first called it should make the cursor appear at the OS's last
+ * known cursor position.
+ */
+ if (show && !oldVisible)
+ {
+ POINT pt;
+ GetCursorPos(&pt);
+ device->xScreenSpace = pt.x;
+ device->yScreenSpace = pt.y;
+ }
+
+ if (device->hardwareCursor)
+ {
+ device->bCursorVisible = show;
+ if (show)
+ SetCursor(device->hardwareCursor);
+ else
+ SetCursor(NULL);
+ }
+ else
+ {
+ if (device->cursorTexture)
+ device->bCursorVisible = show;
+ }
+
+ return oldVisible;
+}
+
+void CDECL wined3d_device_evict_managed_resources(struct wined3d_device *device)
+{
+ struct wined3d_resource *resource, *cursor;
+
+ TRACE("device %p.\n", device);
+
+ LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry)
+ {
+ TRACE("Checking resource %p for eviction.\n", resource);
+
+ if (resource->pool == WINED3D_POOL_MANAGED && !resource->map_count)
+ {
+ TRACE("Evicting %p.\n", resource);
+ resource->resource_ops->resource_unload(resource);
+ }
+ }
+
+ /* Invalidate stream sources, the buffer(s) may have been evicted. */
+ device_invalidate_state(device, STATE_STREAMSRC);
+}
+
+#ifndef VBOX_WITH_WDDM
+/* Do not call while under the GL lock. */
+static void delete_opengl_contexts(struct wined3d_device *device, struct wined3d_swapchain *swapchain)
+{
+ struct wined3d_resource *resource, *cursor;
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+ struct wined3d_shader *shader;
+
+ context = context_acquire(device, NULL);
+ gl_info = context->gl_info;
+
+ LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry)
+ {
+ TRACE("Unloading resource %p.\n", resource);
+
+ resource->resource_ops->resource_unload(resource);
+ }
+
+ LIST_FOR_EACH_ENTRY(shader, &device->shaders, struct wined3d_shader, shader_list_entry)
+ {
+ device->shader_backend->shader_destroy(shader);
+ }
+
+ if (device->depth_blt_texture)
+ {
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->depth_blt_texture);
+ device->depth_blt_texture = 0;
+ }
+ if (device->cursorTexture)
+ {
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &device->cursorTexture);
+ device->cursorTexture = 0;
+ }
+
+ device->blitter->free_private(device);
+ device->shader_backend->shader_free_private(device);
+ destroy_dummy_textures(device, gl_info);
+
+ context_release(context);
+
+ while (device->context_count)
+ {
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ swapchain_destroy_contexts(device->contexts[0]->swapchain);
+#else
+ context_destroy(device, device->contexts[0]);
+#endif
+ }
+
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ HeapFree(GetProcessHeap(), 0, swapchain->context);
+ swapchain->context = NULL;
+#else
+#endif
+}
+
+/* Do not call while under the GL lock. */
+static HRESULT create_primary_opengl_context(struct wined3d_device *device, struct wined3d_swapchain *swapchain)
+{
+ struct wined3d_context *context;
+ struct wined3d_surface *target;
+ HRESULT hr;
+
+ if (FAILED(hr = device->shader_backend->shader_alloc_private(device,
+ device->adapter->vertex_pipe, device->adapter->fragment_pipe)))
+ {
+ ERR("Failed to allocate shader private data, hr %#x.\n", hr);
+ return hr;
+ }
+
+ if (FAILED(hr = device->blitter->alloc_private(device)))
+ {
+ ERR("Failed to allocate blitter private data, hr %#x.\n", hr);
+ device->shader_backend->shader_free_private(device);
+ return hr;
+ }
+
+ /* Recreate the primary swapchain's context */
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context));
+ if (!swapchain->context)
+#else
+ device->contexts = HeapAlloc(GetProcessHeap(), 0, sizeof(*device->contexts));
+ if (!device->contexts)
+#endif
+ {
+ ERR("Failed to allocate memory for swapchain context array.\n");
+ device->blitter->free_private(device);
+ device->shader_backend->shader_free_private(device);
+ return E_OUTOFMEMORY;
+ }
+
+ target = swapchain->back_buffers ? swapchain->back_buffers[0] : swapchain->front_buffer;
+ if (!(context = context_create(swapchain, target, swapchain->ds_format)))
+ {
+ WARN("Failed to create context.\n");
+ device->blitter->free_private(device);
+ device->shader_backend->shader_free_private(device);
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ HeapFree(GetProcessHeap(), 0, swapchain->context);
+#else
+ HeapFree(GetProcessHeap(), 0, device->contexts);
+#endif
+ return E_FAIL;
+ }
+
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ swapchain->context[0] = context;
+ swapchain->num_contexts = 1;
+#endif
+ create_dummy_textures(device, context);
+ context_release(context);
+
+ return WINED3D_OK;
+}
+#endif
+/* Do not call while under the GL lock. */
+HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
+ const struct wined3d_swapchain_desc *swapchain_desc, const struct wined3d_display_mode *mode,
+ wined3d_device_reset_cb callback, BOOL reset_state)
+{
+#ifndef VBOX_WITH_WDDM
+ struct wined3d_resource *resource, *cursor;
+ struct wined3d_swapchain *swapchain;
+ struct wined3d_display_mode m;
+ BOOL DisplayModeChanged = FALSE;
+ BOOL update_desc = FALSE;
+ UINT backbuffer_width = swapchain_desc->backbuffer_width;
+ UINT backbuffer_height = swapchain_desc->backbuffer_height;
+ HRESULT hr = WINED3D_OK;
+ unsigned int i;
+
+ TRACE("device %p, swapchain_desc %p, mode %p, callback %p.\n", device, swapchain_desc, mode, callback);
+
+ if (!(swapchain = wined3d_device_get_swapchain(device, 0)))
+ {
+ ERR("Failed to get the first implicit swapchain.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (reset_state)
+ stateblock_unbind_resources(device->stateBlock);
+
+ if (device->fb.render_targets)
+ {
+ if (swapchain->back_buffers && swapchain->back_buffers[0])
+ wined3d_device_set_render_target(device, 0, swapchain->back_buffers[0], FALSE);
+ else
+ wined3d_device_set_render_target(device, 0, swapchain->front_buffer, FALSE);
+ for (i = 1; i < device->adapter->gl_info.limits.buffers; ++i)
+ {
+ wined3d_device_set_render_target(device, i, NULL, FALSE);
+ }
+ }
+ wined3d_device_set_depth_stencil(device, NULL);
+
+ if (device->onscreen_depth_stencil)
+ {
+ wined3d_surface_decref(device->onscreen_depth_stencil);
+ device->onscreen_depth_stencil = NULL;
+ }
+
+ if (reset_state)
+ {
+ LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry)
+ {
+ TRACE("Enumerating resource %p.\n", resource);
+ if (FAILED(hr = callback(resource)))
+ return hr;
+ }
+ }
+
+ /* Is it necessary to recreate the gl context? Actually every setting can be changed
+ * on an existing gl context, so there's no real need for recreation.
+ *
+ * TODO: Figure out how Reset influences resources in D3DPOOL_DEFAULT, D3DPOOL_SYSTEMMEMORY and D3DPOOL_MANAGED
+ *
+ * TODO: Figure out what happens to explicit swapchains, or if we have more than one implicit swapchain
+ */
+ TRACE("New params:\n");
+ TRACE("backbuffer_width %u\n", swapchain_desc->backbuffer_width);
+ TRACE("backbuffer_height %u\n", swapchain_desc->backbuffer_height);
+ TRACE("backbuffer_format %s\n", debug_d3dformat(swapchain_desc->backbuffer_format));
+ TRACE("backbuffer_count %u\n", swapchain_desc->backbuffer_count);
+ TRACE("multisample_type %#x\n", swapchain_desc->multisample_type);
+ TRACE("multisample_quality %u\n", swapchain_desc->multisample_quality);
+ TRACE("swap_effect %#x\n", swapchain_desc->swap_effect);
+ TRACE("device_window %p\n", swapchain_desc->device_window);
+ TRACE("windowed %#x\n", swapchain_desc->windowed);
+ TRACE("enable_auto_depth_stencil %#x\n", swapchain_desc->enable_auto_depth_stencil);
+ if (swapchain_desc->enable_auto_depth_stencil)
+ TRACE("auto_depth_stencil_format %s\n", debug_d3dformat(swapchain_desc->auto_depth_stencil_format));
+ TRACE("flags %#x\n", swapchain_desc->flags);
+ TRACE("refresh_rate %u\n", swapchain_desc->refresh_rate);
+ TRACE("swap_interval %u\n", swapchain_desc->swap_interval);
+ TRACE("auto_restore_display_mode %#x\n", swapchain_desc->auto_restore_display_mode);
+
+ /* No special treatment of these parameters. Just store them */
+ swapchain->desc.swap_effect = swapchain_desc->swap_effect;
+ swapchain->desc.flags = swapchain_desc->flags;
+ swapchain->desc.swap_interval = swapchain_desc->swap_interval;
+ swapchain->desc.refresh_rate = swapchain_desc->refresh_rate;
+
+ /* What to do about these? */
+ if (swapchain_desc->backbuffer_count
+ && swapchain_desc->backbuffer_count != swapchain->desc.backbuffer_count)
+ FIXME("Cannot change the back buffer count yet.\n");
+
+ if (swapchain_desc->device_window
+ && swapchain_desc->device_window != swapchain->desc.device_window)
+ {
+ TRACE("Changing the device window from %p to %p.\n",
+ swapchain->desc.device_window, swapchain_desc->device_window);
+ swapchain->desc.device_window = swapchain_desc->device_window;
+ swapchain->device_window = swapchain_desc->device_window;
+ wined3d_swapchain_set_window(swapchain, NULL);
+ }
+
+ if (swapchain_desc->enable_auto_depth_stencil && !device->auto_depth_stencil)
+ {
+ struct wined3d_resource_desc surface_desc;
+
+ TRACE("Creating the depth stencil buffer\n");
+
+ surface_desc.resource_type = WINED3D_RTYPE_SURFACE;
+ surface_desc.format = swapchain_desc->auto_depth_stencil_format;
+ surface_desc.multisample_type = swapchain_desc->multisample_type;
+ surface_desc.multisample_quality = swapchain_desc->multisample_quality;
+ surface_desc.usage = WINED3DUSAGE_DEPTHSTENCIL;
+ surface_desc.pool = WINED3D_POOL_DEFAULT;
+ surface_desc.width = swapchain_desc->backbuffer_width;
+ surface_desc.height = swapchain_desc->backbuffer_height;
+ surface_desc.depth = 1;
+ surface_desc.size = 0;
+
+ if (FAILED(hr = device->device_parent->ops->create_swapchain_surface(device->device_parent,
+ device->device_parent, &surface_desc, &device->auto_depth_stencil)))
+ {
+ ERR("Failed to create the depth stencil buffer, hr %#x.\n", hr);
+ return WINED3DERR_INVALIDCALL;
+ }
+ }
+
+ /* Reset the depth stencil */
+ if (swapchain_desc->enable_auto_depth_stencil)
+ wined3d_device_set_depth_stencil(device, device->auto_depth_stencil);
+
+ if (mode)
+ {
+ DisplayModeChanged = TRUE;
+ m = *mode;
+ }
+ else if (swapchain_desc->windowed)
+ {
+ m.width = swapchain->orig_width;
+ m.height = swapchain->orig_height;
+ m.refresh_rate = 0;
+ m.format_id = swapchain->desc.backbuffer_format;
+ m.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
+ }
+ else
+ {
+ m.width = swapchain_desc->backbuffer_width;
+ m.height = swapchain_desc->backbuffer_height;
+ m.refresh_rate = swapchain_desc->refresh_rate;
+ m.format_id = swapchain_desc->backbuffer_format;
+ m.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
+ }
+
+ if (!backbuffer_width || !backbuffer_height)
+ {
+ /* The application is requesting that either the swapchain width or
+ * height be set to the corresponding dimension in the window's
+ * client rect. */
+
+ RECT client_rect;
+
+ if (!swapchain_desc->windowed)
+ return WINED3DERR_INVALIDCALL;
+
+ if (!GetClientRect(swapchain->device_window, &client_rect))
+ {
+ ERR("Failed to get client rect, last error %#x.\n", GetLastError());
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (!backbuffer_width)
+ backbuffer_width = client_rect.right;
+
+ if (!backbuffer_height)
+ backbuffer_height = client_rect.bottom;
+ }
+
+ if (backbuffer_width != swapchain->desc.backbuffer_width
+ || backbuffer_height != swapchain->desc.backbuffer_height)
+ {
+ if (!swapchain_desc->windowed)
+ DisplayModeChanged = TRUE;
+
+ swapchain->desc.backbuffer_width = backbuffer_width;
+ swapchain->desc.backbuffer_height = backbuffer_height;
+ update_desc = TRUE;
+ }
+
+ if (swapchain_desc->backbuffer_format != WINED3DFMT_UNKNOWN
+ && swapchain_desc->backbuffer_format != swapchain->desc.backbuffer_format)
+ {
+ swapchain->desc.backbuffer_format = swapchain_desc->backbuffer_format;
+ update_desc = TRUE;
+ }
+
+ if (swapchain_desc->multisample_type != swapchain->desc.multisample_type
+ || swapchain_desc->multisample_quality != swapchain->desc.multisample_quality)
+ {
+ swapchain->desc.multisample_type = swapchain_desc->multisample_type;
+ swapchain->desc.multisample_quality = swapchain_desc->multisample_quality;
+ update_desc = TRUE;
+ }
+
+ if (update_desc)
+ {
+ UINT i;
+
+ if (FAILED(hr = wined3d_surface_update_desc(swapchain->front_buffer, swapchain->desc.backbuffer_width,
+ swapchain->desc.backbuffer_height, swapchain->desc.backbuffer_format,
+ swapchain->desc.multisample_type, swapchain->desc.multisample_quality)))
+ return hr;
+
+ for (i = 0; i < swapchain->desc.backbuffer_count; ++i)
+ {
+ if (FAILED(hr = wined3d_surface_update_desc(swapchain->back_buffers[i], swapchain->desc.backbuffer_width,
+ swapchain->desc.backbuffer_height, swapchain->desc.backbuffer_format,
+ swapchain->desc.multisample_type, swapchain->desc.multisample_quality)))
+ return hr;
+ }
+ if (device->auto_depth_stencil)
+ {
+ if (FAILED(hr = wined3d_surface_update_desc(device->auto_depth_stencil, swapchain->desc.backbuffer_width,
+ swapchain->desc.backbuffer_height, device->auto_depth_stencil->resource.format->id,
+ swapchain->desc.multisample_type, swapchain->desc.multisample_quality)))
+ return hr;
+ }
+ }
+
+ if (!swapchain_desc->windowed != !swapchain->desc.windowed
+ || DisplayModeChanged)
+ {
+ if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, device->adapter->ordinal, &m)))
+ {
+ WARN("Failed to set display mode, hr %#x.\n", hr);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (!swapchain_desc->windowed)
+ {
+ if (swapchain->desc.windowed)
+ {
+ HWND focus_window = device->create_parms.focus_window;
+ if (!focus_window)
+ focus_window = swapchain_desc->device_window;
+ if (FAILED(hr = wined3d_device_acquire_focus_window(device, focus_window)))
+ {
+ ERR("Failed to acquire focus window, hr %#x.\n", hr);
+ return hr;
+ }
+
+ /* switch from windowed to fs */
+ wined3d_device_setup_fullscreen_window(device, swapchain->device_window,
+ swapchain_desc->backbuffer_width,
+ swapchain_desc->backbuffer_height);
+ }
+ else
+ {
+ /* Fullscreen -> fullscreen mode change */
+ MoveWindow(swapchain->device_window, 0, 0,
+ swapchain_desc->backbuffer_width,
+ swapchain_desc->backbuffer_height,
+ TRUE);
+ }
+ }
+ else if (!swapchain->desc.windowed)
+ {
+ /* Fullscreen -> windowed switch */
+ wined3d_device_restore_fullscreen_window(device, swapchain->device_window);
+ wined3d_device_release_focus_window(device);
+ }
+ swapchain->desc.windowed = swapchain_desc->windowed;
+ }
+ else if (!swapchain_desc->windowed)
+ {
+ DWORD style = device->style;
+ DWORD exStyle = device->exStyle;
+ /* If we're in fullscreen, and the mode wasn't changed, we have to get the window back into
+ * the right position. Some applications(Battlefield 2, Guild Wars) move it and then call
+ * Reset to clear up their mess. Guild Wars also loses the device during that.
+ */
+ device->style = 0;
+ device->exStyle = 0;
+ wined3d_device_setup_fullscreen_window(device, swapchain->device_window,
+ swapchain_desc->backbuffer_width,
+ swapchain_desc->backbuffer_height);
+ device->style = style;
+ device->exStyle = exStyle;
+ }
+
+ if (reset_state)
+ {
+ TRACE("Resetting stateblock.\n");
+ wined3d_stateblock_decref(device->updateStateBlock);
+ wined3d_stateblock_decref(device->stateBlock);
+
+ if (device->d3d_initialized)
+ delete_opengl_contexts(device, swapchain);
+
+ /* Note: No parent needed for initial internal stateblock */
+ hr = wined3d_stateblock_create(device, WINED3D_SBT_INIT, &device->stateBlock);
+ if (FAILED(hr))
+ ERR("Resetting the stateblock failed with error %#x.\n", hr);
+ else
+ TRACE("Created stateblock %p.\n", device->stateBlock);
+ device->updateStateBlock = device->stateBlock;
+ wined3d_stateblock_incref(device->updateStateBlock);
+
+ stateblock_init_default_state(device->stateBlock);
+ }
+ else
+ {
+ struct wined3d_surface *rt = device->fb.render_targets[0];
+ struct wined3d_state *state = &device->stateBlock->state;
+
+ /* Note the min_z / max_z is not reset. */
+ state->viewport.x = 0;
+ state->viewport.y = 0;
+ state->viewport.width = rt->resource.width;
+ state->viewport.height = rt->resource.height;
+ device_invalidate_state(device, STATE_VIEWPORT);
+
+ state->scissor_rect.top = 0;
+ state->scissor_rect.left = 0;
+ state->scissor_rect.right = rt->resource.width;
+ state->scissor_rect.bottom = rt->resource.height;
+ device_invalidate_state(device, STATE_SCISSORRECT);
+ }
+
+ swapchain_update_render_to_fbo(swapchain);
+ swapchain_update_draw_bindings(swapchain);
+
+ if (reset_state && device->d3d_initialized)
+ hr = create_primary_opengl_context(device, swapchain);
+
+ /* All done. There is no need to reload resources or shaders, this will happen automatically on the
+ * first use
+ */
+ return hr;
+#else
+ ERR("not supported!");
+ return E_FAIL;
+#endif
+}
+
+HRESULT CDECL wined3d_device_set_dialog_box_mode(struct wined3d_device *device, BOOL enable_dialogs)
+{
+ TRACE("device %p, enable_dialogs %#x.\n", device, enable_dialogs);
+
+ if (!enable_dialogs) FIXME("Dialogs cannot be disabled yet.\n");
+
+ return WINED3D_OK;
+}
+
+
+void CDECL wined3d_device_get_creation_parameters(const struct wined3d_device *device,
+ struct wined3d_device_creation_parameters *parameters)
+{
+ TRACE("device %p, parameters %p.\n", device, parameters);
+
+ *parameters = device->create_parms;
+}
+
+void CDECL wined3d_device_set_gamma_ramp(const struct wined3d_device *device,
+ UINT swapchain_idx, DWORD flags, const struct wined3d_gamma_ramp *ramp)
+{
+ struct wined3d_swapchain *swapchain;
+
+ TRACE("device %p, swapchain_idx %u, flags %#x, ramp %p.\n",
+ device, swapchain_idx, flags, ramp);
+
+ if ((swapchain = wined3d_device_get_swapchain(device, swapchain_idx)))
+ wined3d_swapchain_set_gamma_ramp(swapchain, flags, ramp);
+}
+
+void CDECL wined3d_device_get_gamma_ramp(const struct wined3d_device *device,
+ UINT swapchain_idx, struct wined3d_gamma_ramp *ramp)
+{
+ struct wined3d_swapchain *swapchain;
+
+ TRACE("device %p, swapchain_idx %u, ramp %p.\n",
+ device, swapchain_idx, ramp);
+
+ if ((swapchain = wined3d_device_get_swapchain(device, swapchain_idx)))
+ wined3d_swapchain_get_gamma_ramp(swapchain, ramp);
+}
+
+void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource)
+{
+ TRACE("device %p, resource %p.\n", device, resource);
+
+ list_add_head(&device->resources, &resource->resource_list_entry);
+}
+
+static void device_resource_remove(struct wined3d_device *device, struct wined3d_resource *resource)
+{
+ TRACE("device %p, resource %p.\n", device, resource);
+
+ list_remove(&resource->resource_list_entry);
+}
+
+void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource)
+{
+ enum wined3d_resource_type type = resource->type;
+ unsigned int i;
+
+ TRACE("device %p, resource %p, type %s.\n", device, resource, debug_d3dresourcetype(type));
+
+ context_resource_released(device, resource, type);
+
+ switch (type)
+ {
+ case WINED3D_RTYPE_SURFACE:
+ {
+ struct wined3d_surface *surface = surface_from_resource(resource);
+
+ if (!device->d3d_initialized) break;
+
+ for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i)
+ {
+ if (device->fb.render_targets[i] == surface)
+ {
+ ERR("Surface %p is still in use as render target %u.\n", surface, i);
+ device->fb.render_targets[i] = NULL;
+ }
+ }
+
+ if (device->fb.depth_stencil == surface)
+ {
+ ERR("Surface %p is still in use as depth/stencil buffer.\n", surface);
+ device->fb.depth_stencil = NULL;
+ }
+ }
+ break;
+
+ case WINED3D_RTYPE_TEXTURE:
+ case WINED3D_RTYPE_CUBE_TEXTURE:
+ case WINED3D_RTYPE_VOLUME_TEXTURE:
+ for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
+ {
+ struct wined3d_texture *texture = wined3d_texture_from_resource(resource);
+
+ if (device->stateBlock && device->stateBlock->state.textures[i] == texture)
+ {
+ ERR("Texture %p is still in use by stateblock %p, stage %u.\n",
+ texture, device->stateBlock, i);
+ device->stateBlock->state.textures[i] = NULL;
+ }
+
+ if (device->updateStateBlock != device->stateBlock
+ && device->updateStateBlock->state.textures[i] == texture)
+ {
+ ERR("Texture %p is still in use by stateblock %p, stage %u.\n",
+ texture, device->updateStateBlock, i);
+ device->updateStateBlock->state.textures[i] = NULL;
+ }
+ }
+ break;
+
+ case WINED3D_RTYPE_BUFFER:
+ {
+ struct wined3d_buffer *buffer = buffer_from_resource(resource);
+
+ for (i = 0; i < MAX_STREAMS; ++i)
+ {
+ if (device->stateBlock && device->stateBlock->state.streams[i].buffer == buffer)
+ {
+ ERR("Buffer %p is still in use by stateblock %p, stream %u.\n",
+ buffer, device->stateBlock, i);
+ device->stateBlock->state.streams[i].buffer = NULL;
+ }
+
+ if (device->updateStateBlock != device->stateBlock
+ && device->updateStateBlock->state.streams[i].buffer == buffer)
+ {
+ ERR("Buffer %p is still in use by stateblock %p, stream %u.\n",
+ buffer, device->updateStateBlock, i);
+ device->updateStateBlock->state.streams[i].buffer = NULL;
+ }
+
+ }
+
+ if (device->stateBlock && device->stateBlock->state.index_buffer == buffer)
+ {
+ ERR("Buffer %p is still in use by stateblock %p as index buffer.\n",
+ buffer, device->stateBlock);
+ device->stateBlock->state.index_buffer = NULL;
+ }
+
+ if (device->updateStateBlock != device->stateBlock
+ && device->updateStateBlock->state.index_buffer == buffer)
+ {
+ ERR("Buffer %p is still in use by stateblock %p as index buffer.\n",
+ buffer, device->updateStateBlock);
+ device->updateStateBlock->state.index_buffer = NULL;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Remove the resource from the resourceStore */
+ device_resource_remove(device, resource);
+
+ TRACE("Resource released.\n");
+}
+
+struct wined3d_surface * CDECL wined3d_device_get_surface_from_dc(const struct wined3d_device *device, HDC dc)
+{
+ struct wined3d_resource *resource;
+
+ TRACE("device %p, dc %p.\n", device, dc);
+
+ if (!dc)
+ return NULL;
+
+ LIST_FOR_EACH_ENTRY(resource, &device->resources, struct wined3d_resource, resource_list_entry)
+ {
+ if (resource->type == WINED3D_RTYPE_SURFACE)
+ {
+ struct wined3d_surface *s = surface_from_resource(resource);
+
+ if (s->hDC == dc)
+ {
+ TRACE("Found surface %p for dc %p.\n", s, dc);
+ return s;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
+ UINT adapter_idx, enum wined3d_device_type device_type, HWND focus_window, DWORD flags,
+ BYTE surface_alignment, struct wined3d_device_parent *device_parent)
+{
+ struct wined3d_adapter *adapter = &wined3d->adapters[adapter_idx];
+ const struct fragment_pipeline *fragment_pipeline;
+ const struct wined3d_vertex_pipe_ops *vertex_pipeline;
+ unsigned int i;
+ HRESULT hr;
+
+ device->ref = 1;
+ device->wined3d = wined3d;
+ wined3d_incref(device->wined3d);
+ device->adapter = wined3d->adapter_count ? adapter : NULL;
+ device->device_parent = device_parent;
+ list_init(&device->resources);
+ list_init(&device->shaders);
+ device->surface_alignment = surface_alignment;
+
+ /* Save the creation parameters. */
+ device->create_parms.adapter_idx = adapter_idx;
+ device->create_parms.device_type = device_type;
+ device->create_parms.focus_window = focus_window;
+ device->create_parms.flags = flags;
+
+#ifdef VBOX_WINE_WITH_PROFILE
+ VBOXWINEPROFILE_DRAWPRIM_INIT(&device->DrawPrimProfile);
+#endif
+
+ device->shader_backend = adapter->shader_backend;
+
+ vertex_pipeline = adapter->vertex_pipe;
+
+ fragment_pipeline = adapter->fragment_pipe;
+
+ if (vertex_pipeline->vp_states && fragment_pipeline->states
+ && FAILED(hr = compile_state_table(device->StateTable, device->multistate_funcs,
+ &adapter->gl_info, &adapter->d3d_info, vertex_pipeline,
+ fragment_pipeline, misc_state_template)))
+ {
+ ERR("Failed to compile state table, hr %#x.\n", hr);
+ wined3d_decref(device->wined3d);
+ return hr;
+ }
+
+ device->blitter = adapter->blitter;
+
+ hr = wined3d_stateblock_create(device, WINED3D_SBT_INIT, &device->stateBlock);
+ if (FAILED(hr))
+ {
+ WARN("Failed to create stateblock.\n");
+ for (i = 0; i < sizeof(device->multistate_funcs) / sizeof(device->multistate_funcs[0]); ++i)
+ {
+ HeapFree(GetProcessHeap(), 0, device->multistate_funcs[i]);
+ }
+ wined3d_decref(device->wined3d);
+ return hr;
+ }
+
+ TRACE("Created stateblock %p.\n", device->stateBlock);
+ device->updateStateBlock = device->stateBlock;
+ wined3d_stateblock_incref(device->updateStateBlock);
+
+#ifdef VBOX_WINE_WITH_SHADER_CACHE
+ shader_chaches_init(device);
+#endif
+
+ return WINED3D_OK;
+}
+
+
+void device_invalidate_state(const struct wined3d_device *device, DWORD state)
+{
+ DWORD rep = device->StateTable[state].representative;
+ struct wined3d_context *context;
+ DWORD idx;
+ BYTE shift;
+ UINT i;
+
+ for (i = 0; i < device->context_count; ++i)
+ {
+ context = device->contexts[i];
+ if(isStateDirty(context, rep)) continue;
+
+ context->dirtyArray[context->numDirtyEntries++] = rep;
+ idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT);
+ shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1);
+ context->isStateDirty[idx] |= (1 << shift);
+ }
+}
+
+void get_drawable_size_fbo(const struct wined3d_context *context, UINT *width, UINT *height)
+{
+ /* The drawable size of a fbo target is the opengl texture size, which is the power of two size. */
+ *width = context->current_rt->pow2Width;
+ *height = context->current_rt->pow2Height;
+}
+
+void get_drawable_size_backbuffer(const struct wined3d_context *context, UINT *width, UINT *height)
+{
+ const struct wined3d_swapchain *swapchain = context->swapchain;
+ /* The drawable size of a backbuffer / aux buffer offscreen target is the size of the
+ * current context's drawable, which is the size of the back buffer of the swapchain
+ * the active context belongs to. */
+ *width = swapchain->desc.backbuffer_width;
+ *height = swapchain->desc.backbuffer_height;
+}
+
+#ifndef VBOX_WITH_WDDM
+LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL unicode,
+ UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc)
+{
+ if (device->filter_messages)
+ {
+ TRACE("Filtering message: window %p, message %#x, wparam %#lx, lparam %#lx.\n",
+ window, message, wparam, lparam);
+ if (unicode)
+ return DefWindowProcW(window, message, wparam, lparam);
+ else
+ return DefWindowProcA(window, message, wparam, lparam);
+ }
+
+ if (message == WM_DESTROY)
+ {
+ TRACE("unregister window %p.\n", window);
+ wined3d_unregister_window(window);
+
+ if (InterlockedCompareExchangePointer((void **)&device->focus_window, NULL, window) != window)
+ ERR("Window %p is not the focus window for device %p.\n", window, device);
+ }
+ else if (message == WM_DISPLAYCHANGE)
+ {
+ device->device_parent->ops->mode_changed(device->device_parent);
+ }
+
+ if (unicode)
+ return CallWindowProcW(proc, window, message, wparam, lparam);
+ else
+ return CallWindowProcA(proc, window, message, wparam, lparam);
+}
+
+#else
+HRESULT CDECL wined3d_device_flush(struct wined3d_device *device)
+{
+ /* we use only one context, so just acquiring it here should do the job,
+ * @todo: perhaps we should introduce the mechanism similar to the one used in flush_to_host
+ * to avoid context acquisition */
+ struct wined3d_context *context = context_acquire(device, NULL);
+ Assert(context->valid);
+ context->gl_info->gl_ops.gl.p_glFlush();
+ context_release(context);
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_flush_to_host(struct wined3d_device *device)
+{
+ struct wined3d_context *context;
+ int i;
+
+ /* no context acquisition is needed */
+ for (i = 0; i < device->context_count; ++i)
+ {
+ context = device->contexts[i];
+ pVBoxFlushToHost(context->glCtx);
+ }
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_finish(struct wined3d_device *device)
+{
+ /* we use only one context, so just acquiring it here should do the job,
+ * @todo: perhaps we should introduce the mechanism similar to the one used in flush_to_host
+ * to avoid context acquisition */
+ struct wined3d_context *context = context_acquire(device, NULL);
+ Assert(context->valid);
+ context->gl_info->gl_ops.gl.p_glFinish();
+ context_release(context);
+ return WINED3D_OK;
+
+}
+
+HRESULT CDECL wined3d_device_get_host_id(struct wined3d_device *device, int32_t *pid)
+{
+ int32_t id = pVBoxGetContextId(device->contexts[0]->glCtx);
+ if (!id)
+ {
+ *pid = 0;
+ ERR("pVBoxGetContextId to get id for context 0x%x", device->contexts[0]->glCtx);
+ return E_FAIL;
+ }
+
+ *pid = id;
+ return WINED3D_OK;
+}
+#endif
+
+
+#ifdef VBOX_WITH_WINE_FIX_ZEROVERTATTR
+static GLuint zv_value_el_size(GLenum enmzvValue)
+{
+ switch (enmzvValue)
+ {
+ case GL_FLOAT:
+ return 4;
+ case GL_UNSIGNED_SHORT:
+ case GL_SHORT:
+ return 2;
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ return 1;
+ default:
+ ERR("unexpected value type %#x\n", enmzvValue);
+ return 0;
+ }
+}
+
+static void zv_create(struct wined3d_device *device, GLenum enmzvValue, GLuint czvValue, GLuint czvValueElements, const GLvoid *pzvValue)
+{
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ GLuint cbValel = zv_value_el_size(enmzvValue);
+ GLuint cbVal = cbValel * czvValueElements;
+ GLuint cbBuf = cbVal * czvValue;
+ GLvoid *pvBuf;
+ GLubyte *pubBuf;
+ GLuint i;
+
+ /* quickly sort out if we can use the current value */
+ if (device->zvBuffer
+ && device->enmzvValue == enmzvValue
+ && device->czvValue >= czvValue
+ && device->czvValueElements == czvValueElements
+ && !memcmp(pzvValue, &device->zvValue, cbVal))
+ return;
+
+ if (czvValueElements > 4)
+ {
+ ERR("invalid czvValueElements %d\n", czvValueElements);
+ return;
+ }
+
+ pvBuf = HeapAlloc(GetProcessHeap(), 0, cbBuf);
+ pubBuf = (GLubyte*)pvBuf;
+
+ for (i = 0; i < czvValue; ++i)
+ {
+ memcpy(pubBuf, pzvValue, cbVal);
+ pubBuf += cbVal;
+ }
+
+ /* */
+ if (!device->zvBuffer)
+ {
+ GL_EXTCALL(glGenBuffersARB(1, &device->zvBuffer));
+ Assert(device->zvBuffer);
+ }
+
+ GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, device->zvBuffer));
+
+ if (device->cbzvBuffer < cbBuf)
+ {
+ GL_EXTCALL(glBufferDataARB(GL_ARRAY_BUFFER_ARB, cbBuf, pvBuf, GL_DYNAMIC_DRAW_ARB));
+ device->cbzvBuffer = cbBuf;
+ }
+ else
+ {
+ GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, cbBuf, pvBuf));
+ }
+
+ device->enmzvValue = enmzvValue;
+ device->czvValue = czvValue;
+ device->czvValueElements = czvValueElements;
+ memcpy(&device->zvValue, pzvValue, cbVal);
+
+ HeapFree(GetProcessHeap(), 0, pvBuf);
+}
+
+void zv_destroy(struct wined3d_device *device)
+{
+ if (device->zvBuffer)
+ {
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ GL_EXTCALL(glDeleteBuffersARB(1, &device->zvBuffer));
+ }
+
+ device->zvBuffer = 0;
+ device->cbzvBuffer = 0;
+}
+
+void zv_bind(struct wined3d_context *context, GLenum enmzvValue, GLuint czvValue, GLuint czvValueElements, GLboolean bzvNormalized, const GLvoid *pzvValue)
+{
+ struct wined3d_device *device = context->swapchain->device;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ zv_create(device, enmzvValue, czvValue, czvValueElements, pzvValue);
+
+ Assert(device->zvBuffer);
+
+ GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, device->zvBuffer));
+
+ GL_EXTCALL(glVertexAttribPointerARB(0, czvValueElements,
+ enmzvValue,
+ bzvNormalized,
+ 0, /*stride*/
+ NULL /*addr*/));
+
+ if (!(context->numbered_array_mask & (1 << 0)))
+ {
+ GL_EXTCALL(glEnableVertexAttribArrayARB(0));
+ context->numbered_array_mask |= (1 << 0);
+ }
+}
+
+void zv_bind_by_element(struct wined3d_context *context, const struct wined3d_stream_info_element *element, GLuint czvValue, const GLvoid *pzvValue)
+{
+ zv_bind(context, element->format->gl_vtx_type, czvValue, element->format->gl_vtx_format, element->format->gl_normalized, pzvValue);
+}
+
+#endif
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/directx.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/directx.c
new file mode 100644
index 00000000..5d5ad21c
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/directx.c
@@ -0,0 +1,5503 @@
+/*
+ * Copyright 2002-2004 Jason Edmeades
+ * Copyright 2003-2004 Raphael Junqueira
+ * Copyright 2004 Christian Costa
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2009-2011 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
+
+#include "wined3d_private.h"
+#include "winternl.h"
+#ifdef VBOX_WITH_WDDM
+#include <VBox/VBoxCrHgsmi.h>
+#endif
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
+
+#define WINE_DEFAULT_VIDMEM (64 * 1024 * 1024)
+
+/* The driver names reflect the lowest GPU supported
+ * by a certain driver, so DRIVER_AMD_R300 supports
+ * R3xx, R4xx and R5xx GPUs. */
+enum wined3d_display_driver
+{
+ DRIVER_AMD_RAGE_128PRO,
+ DRIVER_AMD_R100,
+ DRIVER_AMD_R300,
+ DRIVER_AMD_R600,
+ DRIVER_INTEL_GMA800,
+ DRIVER_INTEL_GMA900,
+ DRIVER_INTEL_GMA950,
+ DRIVER_INTEL_GMA3000,
+ DRIVER_NVIDIA_TNT,
+ DRIVER_NVIDIA_GEFORCE2MX,
+ DRIVER_NVIDIA_GEFORCEFX,
+ DRIVER_NVIDIA_GEFORCE6,
+ DRIVER_UNKNOWN
+};
+
+enum wined3d_driver_model
+{
+ DRIVER_MODEL_WIN9X,
+ DRIVER_MODEL_NT40,
+ DRIVER_MODEL_NT5X,
+ DRIVER_MODEL_NT6X
+};
+
+enum wined3d_gl_vendor
+{
+ GL_VENDOR_UNKNOWN,
+ GL_VENDOR_APPLE,
+ GL_VENDOR_FGLRX,
+ GL_VENDOR_INTEL,
+ GL_VENDOR_MESA,
+ GL_VENDOR_NVIDIA,
+};
+
+/* The d3d device ID */
+static const GUID IID_D3DDEVICE_D3DUID = { 0xaeb2cdd4, 0x6e41, 0x43ea, { 0x94,0x1c,0x83,0x61,0xcc,0x76,0x07,0x81 } };
+
+/* Extension detection */
+struct wined3d_extension_map
+{
+ const char *extension_string;
+ enum wined3d_gl_extension extension;
+};
+
+static const struct wined3d_extension_map gl_extension_map[] =
+{
+ /* APPLE */
+ {"GL_APPLE_client_storage", APPLE_CLIENT_STORAGE },
+ {"GL_APPLE_fence", APPLE_FENCE },
+ {"GL_APPLE_float_pixels", APPLE_FLOAT_PIXELS },
+ {"GL_APPLE_flush_buffer_range", APPLE_FLUSH_BUFFER_RANGE },
+ {"GL_APPLE_ycbcr_422", APPLE_YCBCR_422 },
+
+ /* ARB */
+ {"GL_ARB_color_buffer_float", ARB_COLOR_BUFFER_FLOAT },
+ {"GL_ARB_debug_output", ARB_DEBUG_OUTPUT },
+ {"GL_ARB_depth_buffer_float", ARB_DEPTH_BUFFER_FLOAT },
+ {"GL_ARB_depth_clamp", ARB_DEPTH_CLAMP },
+ {"GL_ARB_depth_texture", ARB_DEPTH_TEXTURE },
+ {"GL_ARB_draw_buffers", ARB_DRAW_BUFFERS },
+ {"GL_ARB_draw_elements_base_vertex", ARB_DRAW_ELEMENTS_BASE_VERTEX },
+ {"GL_ARB_draw_instanced", ARB_DRAW_INSTANCED },
+ {"GL_ARB_fragment_program", ARB_FRAGMENT_PROGRAM },
+ {"GL_ARB_fragment_shader", ARB_FRAGMENT_SHADER },
+ {"GL_ARB_framebuffer_object", ARB_FRAMEBUFFER_OBJECT },
+ {"GL_ARB_framebuffer_sRGB", ARB_FRAMEBUFFER_SRGB },
+ {"GL_ARB_geometry_shader4", ARB_GEOMETRY_SHADER4 },
+ {"GL_ARB_half_float_pixel", ARB_HALF_FLOAT_PIXEL },
+ {"GL_ARB_half_float_vertex", ARB_HALF_FLOAT_VERTEX },
+ {"GL_ARB_instanced_arrays", ARB_INSTANCED_ARRAYS, },
+ {"GL_ARB_internalformat_query2", ARB_INTERNALFORMAT_QUERY2, },
+ {"GL_ARB_map_buffer_alignment", ARB_MAP_BUFFER_ALIGNMENT },
+ {"GL_ARB_map_buffer_range", ARB_MAP_BUFFER_RANGE },
+ {"GL_ARB_multisample", ARB_MULTISAMPLE }, /* needs GLX_ARB_MULTISAMPLE as well */
+ {"GL_ARB_multitexture", ARB_MULTITEXTURE },
+ {"GL_ARB_occlusion_query", ARB_OCCLUSION_QUERY },
+ {"GL_ARB_pixel_buffer_object", ARB_PIXEL_BUFFER_OBJECT },
+ {"GL_ARB_point_parameters", ARB_POINT_PARAMETERS },
+ {"GL_ARB_point_sprite", ARB_POINT_SPRITE },
+ {"GL_ARB_provoking_vertex", ARB_PROVOKING_VERTEX },
+ {"GL_ARB_shader_bit_encoding", ARB_SHADER_BIT_ENCODING },
+ {"GL_ARB_shader_objects", ARB_SHADER_OBJECTS },
+ {"GL_ARB_shader_texture_lod", ARB_SHADER_TEXTURE_LOD },
+ {"GL_ARB_shading_language_100", ARB_SHADING_LANGUAGE_100 },
+ {"GL_ARB_shadow", ARB_SHADOW },
+ {"GL_ARB_sync", ARB_SYNC },
+ {"GL_ARB_texture_border_clamp", ARB_TEXTURE_BORDER_CLAMP },
+ {"GL_ARB_texture_compression", ARB_TEXTURE_COMPRESSION },
+ {"GL_ARB_texture_compression_rgtc", ARB_TEXTURE_COMPRESSION_RGTC },
+ {"GL_ARB_texture_cube_map", ARB_TEXTURE_CUBE_MAP },
+ {"GL_ARB_texture_env_add", ARB_TEXTURE_ENV_ADD },
+ {"GL_ARB_texture_env_combine", ARB_TEXTURE_ENV_COMBINE },
+ {"GL_ARB_texture_env_dot3", ARB_TEXTURE_ENV_DOT3 },
+ {"GL_ARB_texture_float", ARB_TEXTURE_FLOAT },
+ {"GL_ARB_texture_mirrored_repeat", ARB_TEXTURE_MIRRORED_REPEAT },
+#ifdef VBOX_WITH_WINE_FIX_IBMTMR
+ {"GL_IBM_texture_mirrored_repeat", ARB_TEXTURE_MIRRORED_REPEAT },
+#endif
+ {"GL_ARB_texture_non_power_of_two", ARB_TEXTURE_NON_POWER_OF_TWO },
+ {"GL_ARB_texture_rectangle", ARB_TEXTURE_RECTANGLE },
+ {"GL_ARB_texture_rg", ARB_TEXTURE_RG },
+ {"GL_ARB_vertex_array_bgra", ARB_VERTEX_ARRAY_BGRA },
+ {"GL_ARB_vertex_blend", ARB_VERTEX_BLEND },
+ {"GL_ARB_vertex_buffer_object", ARB_VERTEX_BUFFER_OBJECT },
+ {"GL_ARB_vertex_program", ARB_VERTEX_PROGRAM },
+ {"GL_ARB_vertex_shader", ARB_VERTEX_SHADER },
+
+ /* ATI */
+ {"GL_ATI_fragment_shader", ATI_FRAGMENT_SHADER },
+ {"GL_ATI_separate_stencil", ATI_SEPARATE_STENCIL },
+ {"GL_ATI_texture_compression_3dc", ATI_TEXTURE_COMPRESSION_3DC },
+ {"GL_ATI_texture_env_combine3", ATI_TEXTURE_ENV_COMBINE3 },
+ {"GL_ATI_texture_mirror_once", ATI_TEXTURE_MIRROR_ONCE },
+
+ /* EXT */
+ {"GL_EXT_blend_color", EXT_BLEND_COLOR },
+ {"GL_EXT_blend_equation_separate", EXT_BLEND_EQUATION_SEPARATE },
+ {"GL_EXT_blend_func_separate", EXT_BLEND_FUNC_SEPARATE },
+ {"GL_EXT_blend_minmax", EXT_BLEND_MINMAX },
+ {"GL_EXT_blend_subtract", EXT_BLEND_SUBTRACT },
+ {"GL_EXT_depth_bounds_test", EXT_DEPTH_BOUNDS_TEST },
+ {"GL_EXT_draw_buffers2", EXT_DRAW_BUFFERS2 },
+ {"GL_EXT_fog_coord", EXT_FOG_COORD },
+ {"GL_EXT_framebuffer_blit", EXT_FRAMEBUFFER_BLIT },
+ {"GL_EXT_framebuffer_multisample", EXT_FRAMEBUFFER_MULTISAMPLE },
+ {"GL_EXT_framebuffer_object", EXT_FRAMEBUFFER_OBJECT },
+ {"GL_EXT_gpu_program_parameters", EXT_GPU_PROGRAM_PARAMETERS },
+ {"GL_EXT_gpu_shader4", EXT_GPU_SHADER4 },
+ {"GL_EXT_packed_depth_stencil", EXT_PACKED_DEPTH_STENCIL },
+ {"GL_EXT_paletted_texture", EXT_PALETTED_TEXTURE },
+ {"GL_EXT_point_parameters", EXT_POINT_PARAMETERS },
+ {"GL_EXT_provoking_vertex", EXT_PROVOKING_VERTEX },
+ {"GL_EXT_secondary_color", EXT_SECONDARY_COLOR },
+ {"GL_EXT_stencil_two_side", EXT_STENCIL_TWO_SIDE },
+ {"GL_EXT_stencil_wrap", EXT_STENCIL_WRAP },
+ {"GL_EXT_texture3D", EXT_TEXTURE3D },
+ {"GL_EXT_texture_compression_rgtc", EXT_TEXTURE_COMPRESSION_RGTC },
+ {"GL_EXT_texture_compression_s3tc", EXT_TEXTURE_COMPRESSION_S3TC },
+ {"GL_EXT_texture_env_add", EXT_TEXTURE_ENV_ADD },
+ {"GL_EXT_texture_env_combine", EXT_TEXTURE_ENV_COMBINE },
+ {"GL_EXT_texture_env_dot3", EXT_TEXTURE_ENV_DOT3 },
+ {"GL_EXT_texture_filter_anisotropic", EXT_TEXTURE_FILTER_ANISOTROPIC},
+ {"GL_EXT_texture_lod_bias", EXT_TEXTURE_LOD_BIAS },
+ {"GL_EXT_texture_sRGB", EXT_TEXTURE_SRGB },
+ {"GL_EXT_texture_sRGB_decode", EXT_TEXTURE_SRGB_DECODE },
+ {"GL_EXT_vertex_array_bgra", EXT_VERTEX_ARRAY_BGRA },
+
+ /* NV */
+ {"GL_NV_depth_clamp", NV_DEPTH_CLAMP },
+ {"GL_NV_fence", NV_FENCE },
+ {"GL_NV_fog_distance", NV_FOG_DISTANCE },
+ {"GL_NV_fragment_program", NV_FRAGMENT_PROGRAM },
+ {"GL_NV_fragment_program2", NV_FRAGMENT_PROGRAM2 },
+ {"GL_NV_fragment_program_option", NV_FRAGMENT_PROGRAM_OPTION },
+ {"GL_NV_half_float", NV_HALF_FLOAT },
+ {"GL_NV_light_max_exponent", NV_LIGHT_MAX_EXPONENT },
+ {"GL_NV_point_sprite", NV_POINT_SPRITE },
+ {"GL_NV_register_combiners", NV_REGISTER_COMBINERS },
+ {"GL_NV_register_combiners2", NV_REGISTER_COMBINERS2 },
+ {"GL_NV_texgen_reflection", NV_TEXGEN_REFLECTION },
+ {"GL_NV_texture_env_combine4", NV_TEXTURE_ENV_COMBINE4 },
+ {"GL_NV_texture_shader", NV_TEXTURE_SHADER },
+ {"GL_NV_texture_shader2", NV_TEXTURE_SHADER2 },
+ {"GL_NV_vertex_program", NV_VERTEX_PROGRAM },
+ {"GL_NV_vertex_program1_1", NV_VERTEX_PROGRAM1_1 },
+ {"GL_NV_vertex_program2", NV_VERTEX_PROGRAM2 },
+ {"GL_NV_vertex_program2_option", NV_VERTEX_PROGRAM2_OPTION },
+ {"GL_NV_vertex_program3", NV_VERTEX_PROGRAM3 },
+
+ /* SGI */
+ {"GL_SGIS_generate_mipmap", SGIS_GENERATE_MIPMAP },
+};
+
+static const struct wined3d_extension_map wgl_extension_map[] =
+{
+ {"WGL_ARB_pixel_format", WGL_ARB_PIXEL_FORMAT },
+ {"WGL_EXT_swap_control", WGL_EXT_SWAP_CONTROL },
+ {"WGL_WINE_pixel_format_passthrough", WGL_WINE_PIXEL_FORMAT_PASSTHROUGH},
+};
+
+/**********************************************************
+ * Utility functions follow
+ **********************************************************/
+
+const struct min_lookup minMipLookup[] =
+{
+ /* NONE POINT LINEAR */
+ {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* NONE */
+ {{GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR}}, /* POINT*/
+ {{GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR}}, /* LINEAR */
+};
+
+const struct min_lookup minMipLookup_noFilter[] =
+{
+ /* NONE POINT LINEAR */
+ {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* NONE */
+ {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* POINT */
+ {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* LINEAR */
+};
+
+const struct min_lookup minMipLookup_noMip[] =
+{
+ /* NONE POINT LINEAR */
+ {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* NONE */
+ {{GL_NEAREST, GL_NEAREST, GL_NEAREST}}, /* POINT */
+ {{GL_LINEAR, GL_LINEAR, GL_LINEAR }}, /* LINEAR */
+};
+
+const GLenum magLookup[] =
+{
+ /* NONE POINT LINEAR */
+ GL_NEAREST, GL_NEAREST, GL_LINEAR,
+};
+
+const GLenum magLookup_noFilter[] =
+{
+ /* NONE POINT LINEAR */
+ GL_NEAREST, GL_NEAREST, GL_NEAREST,
+};
+
+/* drawStridedSlow attributes */
+glAttribFunc position_funcs[WINED3D_FFP_EMIT_COUNT];
+glAttribFunc diffuse_funcs[WINED3D_FFP_EMIT_COUNT];
+glAttribFunc specular_func_3ubv;
+glAttribFunc specular_funcs[WINED3D_FFP_EMIT_COUNT];
+glAttribFunc normal_funcs[WINED3D_FFP_EMIT_COUNT];
+glMultiTexCoordFunc multi_texcoord_funcs[WINED3D_FFP_EMIT_COUNT];
+
+/**
+ * Note: GL seems to trap if GetDeviceCaps is called before any HWND's created,
+ * i.e., there is no GL Context - Get a default rendering context to enable the
+ * function query some info from GL.
+ */
+
+struct wined3d_fake_gl_ctx
+{
+ HDC dc;
+ HWND wnd;
+ HGLRC gl_ctx;
+ HDC restore_dc;
+ HGLRC restore_gl_ctx;
+};
+
+static void WineD3D_ReleaseFakeGLContext(const struct wined3d_fake_gl_ctx *ctx)
+{
+ TRACE("Destroying fake GL context.\n");
+
+ if (!wglMakeCurrent(NULL, NULL))
+ ERR("Failed to disable fake GL context.\n");
+
+ if (!wglDeleteContext(ctx->gl_ctx))
+ {
+ DWORD err = GetLastError();
+ ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx->gl_ctx, err);
+ }
+
+ ReleaseDC(ctx->wnd, ctx->dc);
+ DestroyWindow(ctx->wnd);
+
+ if (ctx->restore_gl_ctx && !wglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx))
+ ERR("Failed to restore previous GL context.\n");
+}
+
+static void wined3d_create_fake_gl_context_attribs(struct wined3d_fake_gl_ctx *fake_gl_ctx,
+ struct wined3d_gl_info *gl_info, const GLint *ctx_attribs)
+{
+ HGLRC new_ctx;
+
+ if (!(gl_info->p_wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB")))
+ return;
+
+ if (!(new_ctx = gl_info->p_wglCreateContextAttribsARB(fake_gl_ctx->dc, NULL, ctx_attribs)))
+ {
+ ERR("Failed to create a context using wglCreateContextAttribsARB(), last error %#x.\n", GetLastError());
+ gl_info->p_wglCreateContextAttribsARB = NULL;
+ return;
+ }
+
+ if (!wglMakeCurrent(fake_gl_ctx->dc, new_ctx))
+ {
+ ERR("Failed to make new context current, last error %#x.\n", GetLastError());
+ if (!wglDeleteContext(new_ctx))
+ ERR("Failed to delete new context, last error %#x.\n", GetLastError());
+ gl_info->p_wglCreateContextAttribsARB = NULL;
+ return;
+ }
+
+ if (!wglDeleteContext(fake_gl_ctx->gl_ctx))
+ ERR("Failed to delete old context, last error %#x.\n", GetLastError());
+ fake_gl_ctx->gl_ctx = new_ctx;
+}
+
+/* Do not call while under the GL lock. */
+#ifdef VBOX
+static BOOL WineD3D_CreateFakeGLContext(struct wined3d_fake_gl_ctx *ctx, struct VBOXUHGSMI *pHgsmi)
+#else
+static BOOL WineD3D_CreateFakeGLContext(struct wined3d_fake_gl_ctx *ctx)
+#endif
+{
+ PIXELFORMATDESCRIPTOR pfd;
+ int iPixelFormat;
+
+ TRACE("getting context...\n");
+
+ ctx->restore_dc = wglGetCurrentDC();
+ ctx->restore_gl_ctx = wglGetCurrentContext();
+
+ /* We need a fake window as a hdc retrieved using GetDC(0) can't be used for much GL purposes. */
+ ctx->wnd = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D fake window",
+ WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL);
+ if (!ctx->wnd)
+ {
+ ERR("Failed to create a window.\n");
+ goto fail;
+ }
+
+ ctx->dc = GetDC(ctx->wnd);
+ if (!ctx->dc)
+ {
+ ERR("Failed to get a DC.\n");
+ goto fail;
+ }
+
+ /* PixelFormat selection */
+ ZeroMemory(&pfd, sizeof(pfd));
+ pfd.nSize = sizeof(pfd);
+ pfd.nVersion = 1;
+ pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW; /* PFD_GENERIC_ACCELERATED */
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.cColorBits = 32;
+ pfd.iLayerType = PFD_MAIN_PLANE;
+
+ if (!(iPixelFormat = ChoosePixelFormat(ctx->dc, &pfd)))
+ {
+ /* If this happens something is very wrong as ChoosePixelFormat barely fails. */
+ ERR("Failed to find a suitable pixel format.\n");
+ goto fail;
+ }
+ DescribePixelFormat(ctx->dc, iPixelFormat, sizeof(pfd), &pfd);
+ SetPixelFormat(ctx->dc, iPixelFormat, &pfd);
+
+ /* Create a GL context. */
+#ifdef VBOX
+ if (!(ctx->gl_ctx = pVBoxCreateContext(ctx->dc, pHgsmi)))
+#else
+ if (!(ctx->gl_ctx = wglCreateContext(ctx->dc)))
+#endif
+ {
+ WARN("Failed to create default context for capabilities initialization.\n");
+ goto fail;
+ }
+
+#ifdef VBOX_WITH_WDDM
+ pVBoxCtxChromiumParameteriCR(ctx->gl_ctx, GL_HOST_WND_CREATED_HIDDEN_CR, GL_TRUE);
+#endif
+
+ /* Make it the current GL context. */
+ if (!wglMakeCurrent(ctx->dc, ctx->gl_ctx))
+ {
+ ERR("Failed to make fake GL context current.\n");
+ goto fail;
+ }
+
+ return TRUE;
+
+fail:
+ if (ctx->gl_ctx) wglDeleteContext(ctx->gl_ctx);
+ ctx->gl_ctx = NULL;
+ if (ctx->dc) ReleaseDC(ctx->wnd, ctx->dc);
+ ctx->dc = NULL;
+ if (ctx->wnd) DestroyWindow(ctx->wnd);
+ ctx->wnd = NULL;
+ if (ctx->restore_gl_ctx && !wglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx))
+ ERR("Failed to restore previous GL context.\n");
+
+ return FALSE;
+}
+
+/* Adjust the amount of used texture memory */
+#ifndef VBOX_WITH_WDDM
+unsigned int adapter_adjust_memory(struct wined3d_adapter *adapter, int amount)
+{
+ adapter->UsedTextureRam += amount;
+ TRACE("Adjusted adapter memory by %d to %d.\n", amount, adapter->UsedTextureRam);
+ return adapter->UsedTextureRam;
+}
+#endif
+
+static void wined3d_adapter_cleanup(struct wined3d_adapter *adapter)
+{
+ HeapFree(GetProcessHeap(), 0, adapter->gl_info.formats);
+ HeapFree(GetProcessHeap(), 0, adapter->cfgs);
+}
+
+ULONG CDECL wined3d_incref(struct wined3d *wined3d)
+{
+ ULONG refcount = InterlockedIncrement(&wined3d->ref);
+
+ TRACE("%p increasing refcount to %u.\n", wined3d, refcount);
+
+ return refcount;
+}
+
+ULONG CDECL wined3d_decref(struct wined3d *wined3d)
+{
+ ULONG refcount = InterlockedDecrement(&wined3d->ref);
+
+ TRACE("%p decreasing refcount to %u.\n", wined3d, refcount);
+
+ if (!refcount)
+ {
+ unsigned int i;
+
+ for (i = 0; i < wined3d->adapter_count; ++i)
+ {
+ wined3d_adapter_cleanup(&wined3d->adapters[i]);
+ }
+ HeapFree(GetProcessHeap(), 0, wined3d);
+
+#ifdef VBOX_WITH_WDDM
+ VBoxExtCheckTerm();
+#endif
+ }
+
+ return refcount;
+}
+
+/* Context activation is done by the caller. */
+static BOOL test_arb_vs_offset_limit(const struct wined3d_gl_info *gl_info)
+{
+ GLuint prog;
+ BOOL ret = FALSE;
+ const char *testcode =
+ "!!ARBvp1.0\n"
+ "PARAM C[66] = { program.env[0..65] };\n"
+ "ADDRESS A0;"
+ "PARAM zero = {0.0, 0.0, 0.0, 0.0};\n"
+ "ARL A0.x, zero.x;\n"
+ "MOV result.position, C[A0.x + 65];\n"
+ "END\n";
+
+ while (gl_info->gl_ops.gl.p_glGetError());
+ GL_EXTCALL(glGenProgramsARB(1, &prog));
+ if(!prog) {
+ ERR("Failed to create an ARB offset limit test program\n");
+ }
+ GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog));
+ GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+ strlen(testcode), testcode));
+ if (gl_info->gl_ops.gl.p_glGetError())
+ {
+ TRACE("OpenGL implementation does not allow indirect addressing offsets > 63\n");
+ TRACE("error: %s\n", debugstr_a((const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
+ ret = TRUE;
+ } else TRACE("OpenGL implementation allows offsets > 63\n");
+
+ GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
+ GL_EXTCALL(glDeleteProgramsARB(1, &prog));
+ checkGLcall("ARB vp offset limit test cleanup");
+
+ return ret;
+}
+
+static BOOL match_amd_r300_to_500(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
+{
+ if (card_vendor != HW_VENDOR_AMD) return FALSE;
+ if (device == CARD_AMD_RADEON_9500) return TRUE;
+ if (device == CARD_AMD_RADEON_X700) return TRUE;
+ if (device == CARD_AMD_RADEON_X1600) return TRUE;
+ return FALSE;
+}
+
+static BOOL match_geforce5(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
+{
+ if (card_vendor == HW_VENDOR_NVIDIA)
+ {
+ if (device == CARD_NVIDIA_GEFORCEFX_5200 ||
+ device == CARD_NVIDIA_GEFORCEFX_5600 ||
+ device == CARD_NVIDIA_GEFORCEFX_5800)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static BOOL match_apple(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
+{
+ /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
+ * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
+ * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
+ *
+ * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
+ * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
+ * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
+ * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
+ * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
+ * the chance that other implementations support them is rather small since Win32 QuickTime uses
+ * DirectDraw, not OpenGL.
+ *
+ * This test has been moved into wined3d_guess_gl_vendor()
+ */
+ if (gl_vendor == GL_VENDOR_APPLE)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* Context activation is done by the caller. */
+static void test_pbo_functionality(struct wined3d_gl_info *gl_info)
+{
+ /* Some OpenGL implementations, namely Apple's Geforce 8 driver, advertises PBOs,
+ * but glTexSubImage from a PBO fails miserably, with the first line repeated over
+ * all the texture. This function detects this bug by its symptom and disables PBOs
+ * if the test fails.
+ *
+ * The test uploads a 4x4 texture via the PBO in the "native" format GL_BGRA,
+ * GL_UNSIGNED_INT_8_8_8_8_REV. This format triggers the bug, and it is what we use
+ * for D3DFMT_A8R8G8B8. Then the texture is read back without any PBO and the data
+ * read back is compared to the original. If they are equal PBOs are assumed to work,
+ * otherwise the PBO extension is disabled. */
+ GLuint texture, pbo;
+ static const unsigned int pattern[] =
+ {
+ 0x00000000, 0x000000ff, 0x0000ff00, 0x40ff0000,
+ 0x80ffffff, 0x40ffff00, 0x00ff00ff, 0x0000ffff,
+ 0x00ffff00, 0x00ff00ff, 0x0000ffff, 0x000000ff,
+ 0x80ff00ff, 0x0000ffff, 0x00ff00ff, 0x40ff00ff
+ };
+ unsigned int check[sizeof(pattern) / sizeof(pattern[0])];
+
+ /* No PBO -> No point in testing them. */
+ if (!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) return;
+
+ while (gl_info->gl_ops.gl.p_glGetError());
+ gl_info->gl_ops.gl.p_glGenTextures(1, &texture);
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, texture);
+
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
+ gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
+ checkGLcall("Specifying the PBO test texture");
+
+ GL_EXTCALL(glGenBuffersARB(1, &pbo));
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo));
+ GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, sizeof(pattern), pattern, GL_STREAM_DRAW_ARB));
+ checkGLcall("Specifying the PBO test pbo");
+
+ gl_info->gl_ops.gl.p_glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
+ checkGLcall("Loading the PBO test texture");
+
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+
+ gl_info->gl_ops.gl.p_glFinish(); /* just to be sure */
+
+ memset(check, 0, sizeof(check));
+
+ gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, check);
+ checkGLcall("Reading back the PBO test texture");
+
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &texture);
+ GL_EXTCALL(glDeleteBuffersARB(1, &pbo));
+ checkGLcall("PBO test cleanup");
+
+ if (memcmp(check, pattern, sizeof(check)))
+ {
+ WARN_(d3d_perf)("PBO test failed, read back data doesn't match original.\n"
+ "Disabling PBOs. This may result in slower performance.\n");
+ gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] = FALSE;
+ }
+ else
+ {
+ TRACE("PBO test successful.\n");
+ }
+}
+
+static BOOL match_apple_intel(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
+{
+ return (card_vendor == HW_VENDOR_INTEL) && (gl_vendor == GL_VENDOR_APPLE);
+}
+
+static BOOL match_apple_nonr500ati(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
+{
+ if (gl_vendor != GL_VENDOR_APPLE) return FALSE;
+ if (card_vendor != HW_VENDOR_AMD) return FALSE;
+ if (device == CARD_AMD_RADEON_X1600) return FALSE;
+ return TRUE;
+}
+
+static BOOL match_dx10_capable(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
+{
+ /* DX9 cards support 40 single float varyings in hardware, most drivers report 32. ATI misreports
+ * 44 varyings. So assume that if we have more than 44 varyings we have a dx10 card.
+ * This detection is for the gl_ClipPos varying quirk. If a d3d9 card really supports more than 44
+ * varyings and we subtract one in dx9 shaders its not going to hurt us because the dx9 limit is
+ * hardcoded
+ *
+ * dx10 cards usually have 64 varyings */
+ return gl_info->limits.glsl_varyings > 44;
+}
+
+static BOOL match_not_dx10_capable(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
+{
+ return !match_dx10_capable(gl_info, gl_renderer, gl_vendor, card_vendor, device);
+}
+
+/* A GL context is provided by the caller */
+static BOOL match_allows_spec_alpha(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
+{
+ GLenum error;
+ DWORD data[16];
+
+ if (!gl_info->supported[EXT_SECONDARY_COLOR])
+ return FALSE;
+
+ while (gl_info->gl_ops.gl.p_glGetError());
+ GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE, 4, data);
+ error = gl_info->gl_ops.gl.p_glGetError();
+
+ if (error == GL_NO_ERROR)
+ {
+ TRACE("GL Implementation accepts 4 component specular color pointers\n");
+ return TRUE;
+ }
+ else
+ {
+ TRACE("GL implementation does not accept 4 component specular colors, error %s\n",
+ debug_glerror(error));
+ return FALSE;
+ }
+}
+
+/* A GL context is provided by the caller */
+static BOOL match_broken_nv_clip(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
+{
+ GLuint prog;
+ BOOL ret = FALSE;
+ GLint pos;
+ const char *testcode =
+ "!!ARBvp1.0\n"
+ "OPTION NV_vertex_program2;\n"
+ "MOV result.clip[0], 0.0;\n"
+ "MOV result.position, 0.0;\n"
+ "END\n";
+
+ if (!gl_info->supported[NV_VERTEX_PROGRAM2_OPTION]) return FALSE;
+
+ while (gl_info->gl_ops.gl.p_glGetError());
+
+ GL_EXTCALL(glGenProgramsARB(1, &prog));
+ if(!prog)
+ {
+ ERR("Failed to create the NVvp clip test program\n");
+ return FALSE;
+ }
+ GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog));
+ GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+ strlen(testcode), testcode));
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
+ if(pos != -1)
+ {
+ WARN("GL_NV_vertex_program2_option result.clip[] test failed\n");
+ TRACE("error: %s\n", debugstr_a((const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
+ ret = TRUE;
+ while (gl_info->gl_ops.gl.p_glGetError());
+ }
+ else TRACE("GL_NV_vertex_program2_option result.clip[] test passed\n");
+
+ GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
+ GL_EXTCALL(glDeleteProgramsARB(1, &prog));
+ checkGLcall("GL_NV_vertex_program2_option result.clip[] test cleanup");
+
+ return ret;
+}
+
+/* Context activation is done by the caller. */
+static BOOL match_fbo_tex_update(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
+{
+ char data[4 * 4 * 4];
+ GLuint tex, fbo;
+ GLenum status;
+
+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return FALSE;
+
+ memset(data, 0xcc, sizeof(data));
+
+ gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
+ checkGLcall("glTexImage2D");
+
+ gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
+ gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
+ checkGLcall("glFramebufferTexture2D");
+
+ status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) ERR("FBO status %#x\n", status);
+ checkGLcall("glCheckFramebufferStatus");
+
+ memset(data, 0x11, sizeof(data));
+ gl_info->gl_ops.gl.p_glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
+ checkGLcall("glTexSubImage2D");
+
+ gl_info->gl_ops.gl.p_glClearColor(0.996f, 0.729f, 0.745f, 0.792f);
+ gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
+ checkGLcall("glClear");
+
+ gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
+ checkGLcall("glGetTexImage");
+
+ gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
+ gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, 0);
+ checkGLcall("glBindTexture");
+
+ gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
+ checkGLcall("glDeleteTextures");
+
+ return *(DWORD *)data == 0x11111111;
+}
+
+/* Context activation is done by the caller. */
+static BOOL match_broken_rgba16(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
+{
+ /* GL_RGBA16 uses GL_RGBA8 internally on Geforce 7 and older cards.
+ * This leads to graphical bugs in Half Life 2 and Unreal engine games. */
+ GLuint tex;
+ GLint size;
+
+ gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
+ gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT, NULL);
+ checkGLcall("glTexImage2D");
+
+ gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &size);
+ checkGLcall("glGetTexLevelParameteriv");
+ TRACE("Real color depth is %d\n", size);
+
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, 0);
+ checkGLcall("glBindTexture");
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
+ checkGLcall("glDeleteTextures");
+
+ return size < 16;
+}
+
+static BOOL match_fglrx(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
+{
+ return gl_vendor == GL_VENDOR_FGLRX;
+}
+
+static BOOL match_r200(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
+{
+ if (card_vendor != HW_VENDOR_AMD) return FALSE;
+ if (device == CARD_AMD_RADEON_8500) return TRUE;
+ return FALSE;
+}
+
+static BOOL match_broken_arb_fog(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
+{
+ DWORD data[4];
+ GLuint tex, fbo;
+ GLenum status;
+ float color[4] = {0.0f, 1.0f, 0.0f, 0.0f};
+ GLuint prog;
+ GLint err_pos;
+ static const char *program_code =
+ "!!ARBfp1.0\n"
+ "OPTION ARB_fog_linear;\n"
+ "MOV result.color, {1.0, 0.0, 0.0, 0.0};\n"
+ "END\n";
+
+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO)
+ return FALSE;
+ if (!gl_info->supported[ARB_FRAGMENT_PROGRAM])
+ return FALSE;
+
+ gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 4, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
+ checkGLcall("glTexImage2D");
+
+ gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
+ gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
+ checkGLcall("glFramebufferTexture2D");
+
+ status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) ERR("FBO status %#x\n", status);
+ checkGLcall("glCheckFramebufferStatus");
+
+ gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
+ gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
+ checkGLcall("glClear");
+ gl_info->gl_ops.gl.p_glViewport(0, 0, 4, 1);
+ checkGLcall("glViewport");
+
+ gl_info->gl_ops.gl.p_glEnable(GL_FOG);
+ gl_info->gl_ops.gl.p_glFogf(GL_FOG_START, 0.5f);
+ gl_info->gl_ops.gl.p_glFogf(GL_FOG_END, 0.5f);
+ gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
+ gl_info->gl_ops.gl.p_glHint(GL_FOG_HINT, GL_NICEST);
+ gl_info->gl_ops.gl.p_glFogfv(GL_FOG_COLOR, color);
+ checkGLcall("fog setup");
+
+ GL_EXTCALL(glGenProgramsARB(1, &prog));
+ GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prog));
+ GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+ strlen(program_code), program_code));
+ gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB);
+ checkGLcall("Test fragment program setup");
+
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &err_pos);
+ if (err_pos != -1)
+ {
+ const char *error_str;
+ error_str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB);
+ FIXME("Fog test program error at position %d: %s\n\n", err_pos, debugstr_a(error_str));
+ }
+
+ gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
+ gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
+ gl_info->gl_ops.gl.p_glVertex3f( 1.0f, -1.0f, 1.0f);
+ gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
+ gl_info->gl_ops.gl.p_glVertex3f( 1.0f, 1.0f, 1.0f);
+ gl_info->gl_ops.gl.p_glEnd();
+ checkGLcall("ARBfp fog test draw");
+
+ gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
+ checkGLcall("glGetTexImage");
+ data[0] &= 0x00ffffff;
+ data[1] &= 0x00ffffff;
+ data[2] &= 0x00ffffff;
+ data[3] &= 0x00ffffff;
+
+ gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, 0);
+
+ gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
+ gl_info->gl_ops.gl.p_glDisable(GL_FOG);
+ GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0));
+ gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_PROGRAM_ARB);
+ GL_EXTCALL(glDeleteProgramsARB(1, &prog));
+ checkGLcall("ARBfp fog test teardown");
+
+ TRACE("Fog test data: %08x %08x %08x %08x\n", data[0], data[1], data[2], data[3]);
+ return data[0] != 0x00ff0000 || data[3] != 0x0000ff00;
+}
+
+static void quirk_apple_glsl_constants(struct wined3d_gl_info *gl_info)
+{
+ /* MacOS needs uniforms for relative addressing offsets. This can accumulate to quite a few uniforms.
+ * Beyond that the general uniform isn't optimal, so reserve a number of uniforms. 12 vec4's should
+ * allow 48 different offsets or other helper immediate values. */
+ TRACE("Reserving 12 GLSL constants for compiler private use.\n");
+ gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 12);
+}
+
+static void quirk_amd_dx9(struct wined3d_gl_info *gl_info)
+{
+ /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although
+ * these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).
+ * If real NP2 textures are used, the driver falls back to software. We could just remove the
+ * extension and use GL_ARB_texture_rectangle instead, but texture_rectangle is inconvenient
+ * due to the non-normalized texture coordinates. Thus set an internal extension flag,
+ * GL_WINE_normalized_texrect, which signals the code that it can use non power of two textures
+ * as per GL_ARB_texture_non_power_of_two, but has to stick to the texture_rectangle limits.
+ *
+ * fglrx doesn't advertise GL_ARB_texture_non_power_of_two, but it advertises opengl 2.0 which
+ * has this extension promoted to core. The extension loading code sets this extension supported
+ * due to that, so this code works on fglrx as well. */
+ if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
+ {
+ TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing.\n");
+ gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
+ gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT] = TRUE;
+ }
+}
+
+static void quirk_no_np2(struct wined3d_gl_info *gl_info)
+{
+ /* The nVidia GeForceFX series reports OpenGL 2.0 capabilities with the latest drivers versions, but
+ * doesn't explicitly advertise the ARB_tex_npot extension in the GL extension string.
+ * This usually means that ARB_tex_npot is supported in hardware as long as the application is staying
+ * within the limits enforced by the ARB_texture_rectangle extension. This however is not true for the
+ * FX series, which instantly falls back to a slower software path as soon as ARB_tex_npot is used.
+ * We therefore completely remove ARB_tex_npot from the list of supported extensions.
+ *
+ * Note that wine_normalized_texrect can't be used in this case because internally it uses ARB_tex_npot,
+ * triggering the software fallback. There is not much we can do here apart from disabling the
+ * software-emulated extension and re-enable ARB_tex_rect (which was previously disabled
+ * in wined3d_adapter_init_gl_caps).
+ * This fixup removes performance problems on both the FX 5900 and FX 5700 (e.g. for framebuffer
+ * post-processing effects in the game "Max Payne 2").
+ * The behaviour can be verified through a simple test app attached in bugreport #14724. */
+ TRACE("GL_ARB_texture_non_power_of_two advertised through OpenGL 2.0 on NV FX card, removing.\n");
+ gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
+ gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE;
+}
+
+static void quirk_texcoord_w(struct wined3d_gl_info *gl_info)
+{
+ /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
+ * with fixed function fragment processing. Ideally this flag should be detected with a test shader
+ * and OpenGL feedback mode, but some GL implementations (MacOS ATI at least, probably all MacOS ones)
+ * do not like vertex shaders in feedback mode and return an error, even though it should be valid
+ * according to the spec.
+ *
+ * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This
+ * makes the shader slower and eats instruction slots which should be available to the d3d app.
+ *
+ * ATI Radeon HD 2xxx cards on MacOS have the issue. Instead of checking for the buggy cards, blacklist
+ * all radeon cards on Macs and whitelist the good ones. That way we're prepared for the future. If
+ * this workaround is activated on cards that do not need it, it won't break things, just affect
+ * performance negatively. */
+ TRACE("Enabling vertex texture coord fixes in vertex shaders.\n");
+ gl_info->quirks |= WINED3D_QUIRK_SET_TEXCOORD_W;
+}
+
+static void quirk_clip_varying(struct wined3d_gl_info *gl_info)
+{
+ gl_info->quirks |= WINED3D_QUIRK_GLSL_CLIP_VARYING;
+}
+
+static void quirk_allows_specular_alpha(struct wined3d_gl_info *gl_info)
+{
+ gl_info->quirks |= WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA;
+}
+
+static void quirk_disable_nvvp_clip(struct wined3d_gl_info *gl_info)
+{
+ gl_info->quirks |= WINED3D_QUIRK_NV_CLIP_BROKEN;
+}
+
+static void quirk_fbo_tex_update(struct wined3d_gl_info *gl_info)
+{
+ gl_info->quirks |= WINED3D_QUIRK_FBO_TEX_UPDATE;
+}
+
+static void quirk_broken_rgba16(struct wined3d_gl_info *gl_info)
+{
+ gl_info->quirks |= WINED3D_QUIRK_BROKEN_RGBA16;
+}
+
+static void quirk_infolog_spam(struct wined3d_gl_info *gl_info)
+{
+ gl_info->quirks |= WINED3D_QUIRK_INFO_LOG_SPAM;
+}
+
+static void quirk_limited_tex_filtering(struct wined3d_gl_info *gl_info)
+{
+ /* Nvidia GeForce 6xxx and 7xxx support accelerated VTF only on a few
+ selected texture formats. They are apparently the only DX9 class GPUs
+ supporting VTF.
+ Also, DX9-era GPUs are somewhat limited with float textures
+ filtering and blending. */
+ gl_info->quirks |= WINED3D_QUIRK_LIMITED_TEX_FILTERING;
+}
+
+static void quirk_r200_constants(struct wined3d_gl_info *gl_info)
+{
+ /* The Mesa r200 driver (and there is no other driver for this GPU Wine would run on)
+ * loads some fog parameters (start, end, exponent, but not the color) into the
+ * program.
+ *
+ * Apparently the fog hardware is only able to handle linear fog with a range of 0.0;1.0,
+ * and it is the responsibility of the vertex pipeline to handle non-linear fog and
+ * linear fog with start and end other than 0.0 and 1.0. */
+ TRACE("Reserving 1 ARB constant for compiler private use.\n");
+ gl_info->reserved_arb_constants = max(gl_info->reserved_arb_constants, 1);
+}
+
+static void quirk_broken_arb_fog(struct wined3d_gl_info *gl_info)
+{
+ gl_info->quirks |= WINED3D_QUIRK_BROKEN_ARB_FOG;
+}
+
+#ifdef VBOX_WITH_WINE_FIX_QUIRKS
+static BOOL match_ati_hd4800(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
+{
+ if (card_vendor != HW_VENDOR_AMD) return FALSE;
+ if (device == CARD_AMD_RADEON_HD4800) return TRUE;
+ return FALSE;
+}
+
+static void quirk_fullsize_blit(struct wined3d_gl_info *gl_info)
+{
+ gl_info->quirks |= WINED3D_QUIRK_FULLSIZE_BLIT;
+}
+
+#ifdef VBOX_WITH_WDDM
+# if 0
+static BOOL match_mesa_nvidia(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
+{
+ if (card_vendor != HW_VENDOR_NVIDIA) return FALSE;
+ if (gl_vendor != GL_VENDOR_MESA) return FALSE;
+ return TRUE;
+}
+
+static void quirk_no_shader_3(struct wined3d_gl_info *gl_info)
+{
+ int vs_selected_mode, ps_selected_mode;
+ select_shader_mode(gl_info, &ps_selected_mode, &vs_selected_mode);
+ if (vs_selected_mode != SHADER_GLSL && ps_selected_mode != SHADER_GLSL)
+ return;
+
+ gl_info->quirks |= WINED3D_QUIRK_NO_SHADER_V3;
+}
+# endif
+#endif
+
+static BOOL match_intel(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
+{
+ if (card_vendor == HW_VENDOR_INTEL) return TRUE;
+ if (gl_vendor == HW_VENDOR_INTEL) return TRUE;
+ return FALSE;
+}
+
+static void quirk_force_blit(struct wined3d_gl_info *gl_info)
+{
+ gl_info->quirks |= WINED3D_QUIRK_FORCE_BLIT;
+}
+#endif
+
+struct driver_quirk
+{
+ BOOL (*match)(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device);
+ void (*apply)(struct wined3d_gl_info *gl_info);
+ const char *description;
+};
+
+static const struct driver_quirk quirk_table[] =
+{
+ {
+ match_amd_r300_to_500,
+ quirk_amd_dx9,
+ "AMD normalized texrect quirk"
+ },
+ {
+ match_apple,
+ quirk_apple_glsl_constants,
+ "Apple GLSL uniform override"
+ },
+ {
+ match_geforce5,
+ quirk_no_np2,
+ "Geforce 5 NP2 disable"
+ },
+ {
+ match_apple_intel,
+ quirk_texcoord_w,
+ "Init texcoord .w for Apple Intel GPU driver"
+ },
+ {
+ match_apple_nonr500ati,
+ quirk_texcoord_w,
+ "Init texcoord .w for Apple ATI >= r600 GPU driver"
+ },
+ {
+ match_dx10_capable,
+ quirk_clip_varying,
+ "Reserved varying for gl_ClipPos"
+ },
+ {
+ /* GL_EXT_secondary_color does not allow 4 component secondary colors, but most
+ * GL implementations accept it. The Mac GL is the only implementation known to
+ * reject it.
+ *
+ * If we can pass 4 component specular colors, do it, because (a) we don't have
+ * to screw around with the data, and (b) the D3D fixed function vertex pipeline
+ * passes specular alpha to the pixel shader if any is used. Otherwise the
+ * specular alpha is used to pass the fog coordinate, which we pass to opengl
+ * via GL_EXT_fog_coord.
+ */
+ match_allows_spec_alpha,
+ quirk_allows_specular_alpha,
+ "Allow specular alpha quirk"
+ },
+ {
+ match_broken_nv_clip,
+ quirk_disable_nvvp_clip,
+ "Apple NV_vertex_program clip bug quirk"
+ },
+ {
+ match_fbo_tex_update,
+ quirk_fbo_tex_update,
+ "FBO rebind for attachment updates"
+ },
+ {
+ match_broken_rgba16,
+ quirk_broken_rgba16,
+ "True RGBA16 is not available"
+ },
+ {
+ match_fglrx,
+ quirk_infolog_spam,
+ "Not printing GLSL infolog"
+ },
+ {
+ match_not_dx10_capable,
+ quirk_limited_tex_filtering,
+ "Texture filtering, blending and VTF support is limited"
+ },
+ {
+ match_r200,
+ quirk_r200_constants,
+ "r200 vertex shader constants"
+ },
+ {
+ match_broken_arb_fog,
+ quirk_broken_arb_fog,
+ "ARBfp fogstart == fogend workaround"
+ },
+#ifdef VBOX_WITH_WINE_FIX_QUIRKS
+ {
+ match_ati_hd4800,
+ quirk_fullsize_blit,
+ "Fullsize blit"
+ },
+#if 0 //def VBOX_WITH_WDDM
+ {
+ match_mesa_nvidia,
+ quirk_no_shader_3,
+ "disable shader 3 support"
+ },
+#endif
+ {
+ match_intel,
+ quirk_force_blit,
+ "force framebuffer blit when possible"
+ }
+#endif
+};
+
+/* Certain applications (Steam) complain if we report an outdated driver version. In general,
+ * reporting a driver version is moot because we are not the Windows driver, and we have different
+ * bugs, features, etc.
+ *
+ * The driver version has the form "x.y.z.w".
+ *
+ * "x" is the Windows version the driver is meant for:
+ * 4 -> 95/98/NT4
+ * 5 -> 2000
+ * 6 -> 2000/XP
+ * 7 -> Vista
+ * 8 -> Win 7
+ *
+ * "y" is the maximum Direct3D version the driver supports.
+ * y -> d3d version mapping:
+ * 11 -> d3d6
+ * 12 -> d3d7
+ * 13 -> d3d8
+ * 14 -> d3d9
+ * 15 -> d3d10
+ * 16 -> d3d10.1
+ * 17 -> d3d11
+ *
+ * "z" is the subversion number.
+ *
+ * "w" is the vendor specific driver build number.
+ */
+
+struct driver_version_information
+{
+ enum wined3d_display_driver driver;
+ enum wined3d_driver_model driver_model;
+ const char *driver_name; /* name of Windows driver */
+ WORD version; /* version word ('y'), contained in low word of DriverVersion.HighPart */
+ WORD subversion; /* subversion word ('z'), contained in high word of DriverVersion.LowPart */
+ WORD build; /* build number ('w'), contained in low word of DriverVersion.LowPart */
+};
+
+/* The driver version table contains driver information for different devices on several OS versions. */
+static const struct driver_version_information driver_version_table[] =
+{
+ /* AMD
+ * - Radeon HD2x00 (R600) and up supported by current drivers.
+ * - Radeon 9500 (R300) - X1*00 (R5xx) supported up to Catalyst 9.3 (Linux) and 10.2 (XP/Vista/Win7)
+ * - Radeon 7xxx (R100) - 9250 (RV250) supported up to Catalyst 6.11 (XP)
+ * - Rage 128 supported up to XP, latest official build 6.13.3279 dated October 2001 */
+ {DRIVER_AMD_RAGE_128PRO, DRIVER_MODEL_NT5X, "ati2dvaa.dll", 13, 3279, 0},
+ {DRIVER_AMD_R100, DRIVER_MODEL_NT5X, "ati2dvag.dll", 14, 10, 6614},
+ {DRIVER_AMD_R300, DRIVER_MODEL_NT5X, "ati2dvag.dll", 14, 10, 6764},
+ {DRIVER_AMD_R600, DRIVER_MODEL_NT5X, "ati2dvag.dll", 14, 10, 8681},
+ {DRIVER_AMD_R300, DRIVER_MODEL_NT6X, "atiumdag.dll", 14, 10, 741 },
+ {DRIVER_AMD_R600, DRIVER_MODEL_NT6X, "atiumdag.dll", 14, 10, 741 },
+
+ /* Intel
+ * The drivers are unified but not all versions support all GPUs. At some point the 2k/xp
+ * drivers used ialmrnt5.dll for GMA800/GMA900 but at some point the file was renamed to
+ * igxprd32.dll but the GMA800 driver was never updated. */
+ {DRIVER_INTEL_GMA800, DRIVER_MODEL_NT5X, "ialmrnt5.dll", 14, 10, 3889},
+ {DRIVER_INTEL_GMA900, DRIVER_MODEL_NT5X, "igxprd32.dll", 14, 10, 4764},
+ {DRIVER_INTEL_GMA950, DRIVER_MODEL_NT5X, "igxprd32.dll", 14, 10, 4926},
+ {DRIVER_INTEL_GMA3000, DRIVER_MODEL_NT5X, "igxprd32.dll", 14, 10, 5218},
+ {DRIVER_INTEL_GMA950, DRIVER_MODEL_NT6X, "igdumd32.dll", 14, 10, 1504},
+ {DRIVER_INTEL_GMA3000, DRIVER_MODEL_NT6X, "igdumd32.dll", 15, 10, 1666},
+
+ /* Nvidia
+ * - Geforce6 and newer cards are supported by the current driver (197.x) on XP-Win7
+ * - GeforceFX support is up to 173.x on <= XP
+ * - Geforce2MX/3/4 up to 96.x on <= XP
+ * - TNT/Geforce1/2 up to 71.x on <= XP
+ * All version numbers used below are from the Linux nvidia drivers. */
+ {DRIVER_NVIDIA_TNT, DRIVER_MODEL_NT5X, "nv4_disp.dll", 14, 10, 7186},
+ {DRIVER_NVIDIA_GEFORCE2MX, DRIVER_MODEL_NT5X, "nv4_disp.dll", 14, 10, 9371},
+ {DRIVER_NVIDIA_GEFORCEFX, DRIVER_MODEL_NT5X, "nv4_disp.dll", 14, 11, 7516},
+ {DRIVER_NVIDIA_GEFORCE6, DRIVER_MODEL_NT5X, "nv4_disp.dll", 15, 12, 6658},
+ {DRIVER_NVIDIA_GEFORCE6, DRIVER_MODEL_NT6X, "nvd3dum.dll", 15, 12, 6658},
+};
+
+struct gpu_description
+{
+ WORD vendor; /* reported PCI card vendor ID */
+ WORD card; /* reported PCI card device ID */
+ const char *description; /* Description of the card e.g. NVIDIA RIVA TNT */
+ enum wined3d_display_driver driver;
+ unsigned int vidmem;
+};
+
+/* The amount of video memory stored in the gpu description table is the minimum amount of video memory
+ * found on a board containing a specific GPU. */
+static const struct gpu_description gpu_description_table[] =
+{
+ /* Nvidia cards */
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_RIVA_TNT, "NVIDIA RIVA TNT", DRIVER_NVIDIA_TNT, 16 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_RIVA_TNT2, "NVIDIA RIVA TNT2/TNT2 Pro", DRIVER_NVIDIA_TNT, 32 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE, "NVIDIA GeForce 256", DRIVER_NVIDIA_TNT, 32 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE2, "NVIDIA GeForce2 GTS/GeForce2 Pro", DRIVER_NVIDIA_TNT, 32 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE2_MX, "NVIDIA GeForce2 MX/MX 400", DRIVER_NVIDIA_GEFORCE2MX,32 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE3, "NVIDIA GeForce3", DRIVER_NVIDIA_GEFORCE2MX,64 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE4_MX, "NVIDIA GeForce4 MX 460", DRIVER_NVIDIA_GEFORCE2MX,64 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE4_TI4200, "NVIDIA GeForce4 Ti 4200", DRIVER_NVIDIA_GEFORCE2MX,64, },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5200, "NVIDIA GeForce FX 5200", DRIVER_NVIDIA_GEFORCEFX, 64 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5600, "NVIDIA GeForce FX 5600", DRIVER_NVIDIA_GEFORCEFX, 128 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5800, "NVIDIA GeForce FX 5800", DRIVER_NVIDIA_GEFORCEFX, 256 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6200, "NVIDIA GeForce 6200", DRIVER_NVIDIA_GEFORCE6, 64 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6600GT, "NVIDIA GeForce 6600 GT", DRIVER_NVIDIA_GEFORCE6, 128 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6800, "NVIDIA GeForce 6800", DRIVER_NVIDIA_GEFORCE6, 128 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7300, "NVIDIA GeForce Go 7300", DRIVER_NVIDIA_GEFORCE6, 256 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7400, "NVIDIA GeForce Go 7400", DRIVER_NVIDIA_GEFORCE6, 256 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7600, "NVIDIA GeForce 7600 GT", DRIVER_NVIDIA_GEFORCE6, 256 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7800GT, "NVIDIA GeForce 7800 GT", DRIVER_NVIDIA_GEFORCE6, 256 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8300GS, "NVIDIA GeForce 8300 GS", DRIVER_NVIDIA_GEFORCE6, 128 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8400GS, "NVIDIA GeForce 8400 GS", DRIVER_NVIDIA_GEFORCE6, 128 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600GT, "NVIDIA GeForce 8600 GT", DRIVER_NVIDIA_GEFORCE6, 256 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600MGT, "NVIDIA GeForce 8600M GT", DRIVER_NVIDIA_GEFORCE6, 512 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8800GTS, "NVIDIA GeForce 8800 GTS", DRIVER_NVIDIA_GEFORCE6, 320 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8800GTX, "NVIDIA GeForce 8800 GTX", DRIVER_NVIDIA_GEFORCE6, 768 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9200, "NVIDIA GeForce 9200", DRIVER_NVIDIA_GEFORCE6, 256 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9300, "NVIDIA GeForce 9300", DRIVER_NVIDIA_GEFORCE6, 256 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9400M, "NVIDIA GeForce 9400M", DRIVER_NVIDIA_GEFORCE6, 256 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9400GT, "NVIDIA GeForce 9400 GT", DRIVER_NVIDIA_GEFORCE6, 256 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9500GT, "NVIDIA GeForce 9500 GT", DRIVER_NVIDIA_GEFORCE6, 256 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9600GT, "NVIDIA GeForce 9600 GT", DRIVER_NVIDIA_GEFORCE6, 384 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9800GT, "NVIDIA GeForce 9800 GT", DRIVER_NVIDIA_GEFORCE6, 512 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_210, "NVIDIA GeForce 210", DRIVER_NVIDIA_GEFORCE6, 512 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT220, "NVIDIA GeForce GT 220", DRIVER_NVIDIA_GEFORCE6, 512 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT240, "NVIDIA GeForce GT 240", DRIVER_NVIDIA_GEFORCE6, 512 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX260, "NVIDIA GeForce GTX 260", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX275, "NVIDIA GeForce GTX 275", DRIVER_NVIDIA_GEFORCE6, 896 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX280, "NVIDIA GeForce GTX 280", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_315M, "NVIDIA GeForce 315M", DRIVER_NVIDIA_GEFORCE6, 512 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_320M, "NVIDIA GeForce 320M", DRIVER_NVIDIA_GEFORCE6, 256},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_410M, "NVIDIA GeForce 410M", DRIVER_NVIDIA_GEFORCE6, 512},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT320M, "NVIDIA GeForce GT 320M", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT325M, "NVIDIA GeForce GT 325M", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT330, "NVIDIA GeForce GT 330", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTS350M, "NVIDIA GeForce GTS 350M", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT420, "NVIDIA GeForce GT 420", DRIVER_NVIDIA_GEFORCE6, 2048},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT430, "NVIDIA GeForce GT 430", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT440, "NVIDIA GeForce GT 440", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTS450, "NVIDIA GeForce GTS 450", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX460, "NVIDIA GeForce GTX 460", DRIVER_NVIDIA_GEFORCE6, 768 },
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX460M, "NVIDIA GeForce GTX 460M", DRIVER_NVIDIA_GEFORCE6, 1536},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX465, "NVIDIA GeForce GTX 465", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX470, "NVIDIA GeForce GTX 470", DRIVER_NVIDIA_GEFORCE6, 1280},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX480, "NVIDIA GeForce GTX 480", DRIVER_NVIDIA_GEFORCE6, 1536},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT520, "NVIDIA GeForce GT 520", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT540M, "NVIDIA GeForce GT 540M", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX550, "NVIDIA GeForce GTX 550 Ti", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT555M, "NVIDIA GeForce GT 555M", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX560TI, "NVIDIA GeForce GTX 560 Ti", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX560, "NVIDIA GeForce GTX 560", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX570, "NVIDIA GeForce GTX 570", DRIVER_NVIDIA_GEFORCE6, 1280},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX580, "NVIDIA GeForce GTX 580", DRIVER_NVIDIA_GEFORCE6, 1536},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT610, "NVIDIA GeForce GT 610", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT630, "NVIDIA GeForce GT 630", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT630M, "NVIDIA GeForce GT 630M", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT640M, "NVIDIA GeForce GT 640M", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GT650M, "NVIDIA GeForce GT 650M", DRIVER_NVIDIA_GEFORCE6, 2048},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX650, "NVIDIA GeForce GTX 650", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX650TI, "NVIDIA GeForce GTX 650 Ti", DRIVER_NVIDIA_GEFORCE6, 1024},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX660, "NVIDIA GeForce GTX 660", DRIVER_NVIDIA_GEFORCE6, 2048},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX660TI, "NVIDIA GeForce GTX 660 Ti", DRIVER_NVIDIA_GEFORCE6, 2048},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX670, "NVIDIA GeForce GTX 670", DRIVER_NVIDIA_GEFORCE6, 2048},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX670MX, "NVIDIA GeForce GTX 670MX", DRIVER_NVIDIA_GEFORCE6, 3072},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX680, "NVIDIA GeForce GTX 680", DRIVER_NVIDIA_GEFORCE6, 2048},
+ {HW_VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX770M, "NVIDIA GeForce GTX 770M", DRIVER_NVIDIA_GEFORCE6, 3072},
+
+ /* AMD cards */
+ {HW_VENDOR_AMD, CARD_AMD_RAGE_128PRO, "ATI Rage Fury", DRIVER_AMD_RAGE_128PRO, 16 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_7200, "ATI RADEON 7200 SERIES", DRIVER_AMD_R100, 32 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_8500, "ATI RADEON 8500 SERIES", DRIVER_AMD_R100, 64 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_9500, "ATI Radeon 9500", DRIVER_AMD_R300, 64 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_XPRESS_200M, "ATI RADEON XPRESS 200M Series", DRIVER_AMD_R300, 64 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_X700, "ATI Radeon X700 SE", DRIVER_AMD_R300, 128 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_X1600, "ATI Radeon X1600 Series", DRIVER_AMD_R300, 128 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD2350, "ATI Mobility Radeon HD 2350", DRIVER_AMD_R600, 256 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD2600, "ATI Mobility Radeon HD 2600", DRIVER_AMD_R600, 256 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD2900, "ATI Radeon HD 2900 XT", DRIVER_AMD_R600, 512 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD3200, "ATI Radeon HD 3200 Graphics", DRIVER_AMD_R600, 128 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD4200M, "ATI Mobility Radeon HD 4200", DRIVER_AMD_R600, 256 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD4350, "ATI Radeon HD 4350", DRIVER_AMD_R600, 256 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD4600, "ATI Radeon HD 4600 Series", DRIVER_AMD_R600, 512 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD4700, "ATI Radeon HD 4700 Series", DRIVER_AMD_R600, 512 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD4800, "ATI Radeon HD 4800 Series", DRIVER_AMD_R600, 512 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD5400, "ATI Radeon HD 5400 Series", DRIVER_AMD_R600, 512 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD5600, "ATI Radeon HD 5600 Series", DRIVER_AMD_R600, 512 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD5700, "ATI Radeon HD 5700 Series", DRIVER_AMD_R600, 512 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD5800, "ATI Radeon HD 5800 Series", DRIVER_AMD_R600, 1024},
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD5900, "ATI Radeon HD 5900 Series", DRIVER_AMD_R600, 1024},
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6300, "AMD Radeon HD 6300 series Graphics", DRIVER_AMD_R600, 1024},
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6400, "AMD Radeon HD 6400 Series", DRIVER_AMD_R600, 1024},
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6410D, "AMD Radeon HD 6410D", DRIVER_AMD_R600, 1024},
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6550D, "AMD Radeon HD 6550D", DRIVER_AMD_R600, 1024},
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6600, "AMD Radeon HD 6600 Series", DRIVER_AMD_R600, 1024},
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6600M, "AMD Radeon HD 6600M Series", DRIVER_AMD_R600, 512 },
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6700, "AMD Radeon HD 6700 Series", DRIVER_AMD_R600, 1024},
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6800, "AMD Radeon HD 6800 Series", DRIVER_AMD_R600, 1024},
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD6900, "AMD Radeon HD 6900 Series", DRIVER_AMD_R600, 2048},
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD7700, "AMD Radeon HD 7700 Series", DRIVER_AMD_R600, 1024},
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD7800, "AMD Radeon HD 7800 Series", DRIVER_AMD_R600, 2048},
+ {HW_VENDOR_AMD, CARD_AMD_RADEON_HD7900, "AMD Radeon HD 7900 Series", DRIVER_AMD_R600, 2048},
+ /* Intel cards */
+ {HW_VENDOR_INTEL, CARD_INTEL_830M, "Intel(R) 82830M Graphics Controller", DRIVER_INTEL_GMA800, 32 },
+ {HW_VENDOR_INTEL, CARD_INTEL_855GM, "Intel(R) 82852/82855 GM/GME Graphics Controller", DRIVER_INTEL_GMA800, 32 },
+ {HW_VENDOR_INTEL, CARD_INTEL_845G, "Intel(R) 845G", DRIVER_INTEL_GMA800, 32 },
+ {HW_VENDOR_INTEL, CARD_INTEL_865G, "Intel(R) 82865G Graphics Controller", DRIVER_INTEL_GMA800, 32 },
+ {HW_VENDOR_INTEL, CARD_INTEL_915G, "Intel(R) 82915G/GV/910GL Express Chipset Family", DRIVER_INTEL_GMA900, 64 },
+ {HW_VENDOR_INTEL, CARD_INTEL_E7221G, "Intel(R) E7221G", DRIVER_INTEL_GMA900, 64 },
+ {HW_VENDOR_INTEL, CARD_INTEL_915GM, "Mobile Intel(R) 915GM/GMS,910GML Express Chipset Family", DRIVER_INTEL_GMA900, 64 },
+ {HW_VENDOR_INTEL, CARD_INTEL_945G, "Intel(R) 945G", DRIVER_INTEL_GMA950, 64 },
+ {HW_VENDOR_INTEL, CARD_INTEL_945GM, "Mobile Intel(R) 945GM Express Chipset Family", DRIVER_INTEL_GMA950, 64 },
+ {HW_VENDOR_INTEL, CARD_INTEL_945GME, "Intel(R) 945GME", DRIVER_INTEL_GMA950, 64 },
+ {HW_VENDOR_INTEL, CARD_INTEL_Q35, "Intel(R) Q35", DRIVER_INTEL_GMA950, 64 },
+ {HW_VENDOR_INTEL, CARD_INTEL_G33, "Intel(R) G33", DRIVER_INTEL_GMA950, 64 },
+ {HW_VENDOR_INTEL, CARD_INTEL_Q33, "Intel(R) Q33", DRIVER_INTEL_GMA950, 64 },
+ {HW_VENDOR_INTEL, CARD_INTEL_PNVG, "Intel(R) IGD", DRIVER_INTEL_GMA950, 64 },
+ {HW_VENDOR_INTEL, CARD_INTEL_PNVM, "Intel(R) IGD", DRIVER_INTEL_GMA950, 64 },
+ {HW_VENDOR_INTEL, CARD_INTEL_965Q, "Intel(R) 965Q", DRIVER_INTEL_GMA3000, 128},
+ {HW_VENDOR_INTEL, CARD_INTEL_965G, "Intel(R) 965G", DRIVER_INTEL_GMA3000, 128},
+ {HW_VENDOR_INTEL, CARD_INTEL_946GZ, "Intel(R) 946GZ", DRIVER_INTEL_GMA3000, 128},
+ {HW_VENDOR_INTEL, CARD_INTEL_965GM, "Mobile Intel(R) 965 Express Chipset Family", DRIVER_INTEL_GMA3000, 128},
+ {HW_VENDOR_INTEL, CARD_INTEL_965GME, "Intel(R) 965GME", DRIVER_INTEL_GMA3000, 128},
+ {HW_VENDOR_INTEL, CARD_INTEL_GM45, "Mobile Intel(R) GM45 Express Chipset Family", DRIVER_INTEL_GMA3000, 512},
+ {HW_VENDOR_INTEL, CARD_INTEL_IGD, "Intel(R) Integrated Graphics Device", DRIVER_INTEL_GMA3000, 512},
+ {HW_VENDOR_INTEL, CARD_INTEL_G45, "Intel(R) G45/G43", DRIVER_INTEL_GMA3000, 512},
+ {HW_VENDOR_INTEL, CARD_INTEL_Q45, "Intel(R) Q45/Q43", DRIVER_INTEL_GMA3000, 512},
+ {HW_VENDOR_INTEL, CARD_INTEL_G41, "Intel(R) G41", DRIVER_INTEL_GMA3000, 512},
+ {HW_VENDOR_INTEL, CARD_INTEL_B43, "Intel(R) B43", DRIVER_INTEL_GMA3000, 512},
+ {HW_VENDOR_INTEL, CARD_INTEL_ILKD, "Intel(R) Ironlake Desktop", DRIVER_INTEL_GMA3000, 1024},
+ {HW_VENDOR_INTEL, CARD_INTEL_ILKM, "Intel(R) Ironlake Mobile", DRIVER_INTEL_GMA3000, 1024},
+ {HW_VENDOR_INTEL, CARD_INTEL_SNBD, "Intel(R) Sandybridge Desktop", DRIVER_INTEL_GMA3000, 1024},
+ {HW_VENDOR_INTEL, CARD_INTEL_SNBM, "Intel(R) Sandybridge Mobile", DRIVER_INTEL_GMA3000, 1024},
+ {HW_VENDOR_INTEL, CARD_INTEL_SNBS, "Intel(R) Sandybridge Server", DRIVER_INTEL_GMA3000, 1024},
+ {HW_VENDOR_INTEL, CARD_INTEL_IVBD, "Intel(R) Ivybridge Desktop", DRIVER_INTEL_GMA3000, 1024},
+ {HW_VENDOR_INTEL, CARD_INTEL_IVBM, "Intel(R) Ivybridge Mobile", DRIVER_INTEL_GMA3000, 1024},
+ {HW_VENDOR_INTEL, CARD_INTEL_IVBS, "Intel(R) Ivybridge Server", DRIVER_INTEL_GMA3000, 1024},
+};
+
+static const struct driver_version_information *get_driver_version_info(enum wined3d_display_driver driver,
+ enum wined3d_driver_model driver_model)
+{
+ unsigned int i;
+
+ TRACE("Looking up version info for driver=%d driver_model=%d\n", driver, driver_model);
+ for (i = 0; i < (sizeof(driver_version_table) / sizeof(driver_version_table[0])); i++)
+ {
+ const struct driver_version_information *entry = &driver_version_table[i];
+
+ if (entry->driver == driver && entry->driver_model == driver_model)
+ {
+ TRACE("Found driver \"%s\", version %u, subversion %u, build %u.\n",
+ entry->driver_name, entry->version, entry->subversion, entry->build);
+ return entry;
+ }
+ }
+ return NULL;
+}
+
+static void init_driver_info(struct wined3d_driver_info *driver_info,
+ enum wined3d_pci_vendor vendor, enum wined3d_pci_device device)
+{
+ OSVERSIONINFOW os_version;
+ WORD driver_os_version;
+ unsigned int i;
+ enum wined3d_display_driver driver = DRIVER_UNKNOWN;
+ enum wined3d_driver_model driver_model;
+ const struct driver_version_information *version_info;
+
+ if (wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE)
+ {
+ TRACE("Overriding PCI vendor ID with 0x%04x.\n", wined3d_settings.pci_vendor_id);
+ vendor = wined3d_settings.pci_vendor_id;
+ }
+ driver_info->vendor = vendor;
+
+ if (wined3d_settings.pci_device_id != PCI_DEVICE_NONE)
+ {
+ TRACE("Overriding PCI device ID with 0x%04x.\n", wined3d_settings.pci_device_id);
+ device = wined3d_settings.pci_device_id;
+ }
+ driver_info->device = device;
+
+ /* Set a default amount of video memory (64MB). In general this code isn't used unless the user
+ * overrides the pci ids to a card which is not in our database. */
+ driver_info->vidmem = WINE_DEFAULT_VIDMEM;
+
+ memset(&os_version, 0, sizeof(os_version));
+ os_version.dwOSVersionInfoSize = sizeof(os_version);
+ if (!GetVersionExW(&os_version))
+ {
+ ERR("Failed to get OS version, reporting 2000/XP.\n");
+ driver_os_version = 6;
+ driver_model = DRIVER_MODEL_NT5X;
+ }
+ else
+ {
+ TRACE("OS version %u.%u.\n", os_version.dwMajorVersion, os_version.dwMinorVersion);
+ switch (os_version.dwMajorVersion)
+ {
+ case 4:
+ /* If needed we could distinguish between 9x and NT4, but this code won't make
+ * sense for NT4 since it had no way to obtain this info through DirectDraw 3.0.
+ */
+ driver_os_version = 4;
+ driver_model = DRIVER_MODEL_WIN9X;
+ break;
+
+ case 5:
+ driver_os_version = 6;
+ driver_model = DRIVER_MODEL_NT5X;
+ break;
+
+ case 6:
+ if (os_version.dwMinorVersion == 0)
+ {
+ driver_os_version = 7;
+ driver_model = DRIVER_MODEL_NT6X;
+ }
+ else if (os_version.dwMinorVersion == 1)
+ {
+ driver_os_version = 8;
+ driver_model = DRIVER_MODEL_NT6X;
+ }
+ else
+ {
+ if (os_version.dwMinorVersion > 2)
+ {
+ FIXME("Unhandled OS version %u.%u, reporting Win 8.\n",
+ os_version.dwMajorVersion, os_version.dwMinorVersion);
+ }
+ driver_os_version = 9;
+ driver_model = DRIVER_MODEL_NT6X;
+ }
+ break;
+
+ default:
+ FIXME("Unhandled OS version %u.%u, reporting 2000/XP.\n",
+ os_version.dwMajorVersion, os_version.dwMinorVersion);
+ driver_os_version = 6;
+ driver_model = DRIVER_MODEL_NT5X;
+ break;
+ }
+ }
+
+ /* When we reach this stage we always have a vendor or device id (it can be a default one).
+ * This means that unless the ids are overridden, we will always find a GPU description. */
+ for (i = 0; i < (sizeof(gpu_description_table) / sizeof(gpu_description_table[0])); i++)
+ {
+ if (vendor == gpu_description_table[i].vendor && device == gpu_description_table[i].card)
+ {
+ TRACE("Found card %04x:%04x in driver DB.\n", vendor, device);
+
+ driver_info->description = gpu_description_table[i].description;
+ driver_info->vidmem = gpu_description_table[i].vidmem * 1024*1024;
+ driver = gpu_description_table[i].driver;
+ break;
+ }
+ }
+
+ if (wined3d_settings.emulated_textureram)
+ {
+ TRACE("Overriding amount of video memory with %u bytes.\n", wined3d_settings.emulated_textureram);
+ driver_info->vidmem = wined3d_settings.emulated_textureram;
+ }
+
+ /* Try to obtain driver version information for the current Windows version. This fails in
+ * some cases:
+ * - the gpu is not available on the currently selected OS version:
+ * - Geforce GTX480 on Win98. When running applications in compatibility mode on Windows,
+ * version information for the current Windows version is returned instead of faked info.
+ * We do the same and assume the default Windows version to emulate is WinXP.
+ *
+ * - Videocard is a Riva TNT but winver is set to win7 (there are no drivers for this beast)
+ * For now return the XP driver info. Perhaps later on we should return VESA.
+ *
+ * - the gpu is not in our database (can happen when the user overrides the vendor_id / device_id)
+ * This could be an indication that our database is not up to date, so this should be fixed.
+ */
+ version_info = get_driver_version_info(driver, driver_model);
+ if (version_info)
+ {
+ driver_info->name = version_info->driver_name;
+ driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, version_info->version);
+ driver_info->version_low = MAKEDWORD_VERSION(version_info->subversion, version_info->build);
+ }
+ else
+ {
+ version_info = get_driver_version_info(driver, DRIVER_MODEL_NT5X);
+ if (version_info)
+ {
+ driver_info->name = version_info->driver_name;
+ driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, version_info->version);
+ driver_info->version_low = MAKEDWORD_VERSION(version_info->subversion, version_info->build);
+ }
+ else
+ {
+ driver_info->description = "Direct3D HAL";
+ driver_info->name = "Display";
+ driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, 15);
+ driver_info->version_low = MAKEDWORD_VERSION(8, 6); /* Nvidia RIVA TNT, arbitrary */
+
+ FIXME("Unable to find a driver/device info for vendor_id=%#x device_id=%#x for driver_model=%d\n",
+ vendor, device, driver_model);
+ }
+ }
+
+ TRACE("Reporting (fake) driver version 0x%08x-0x%08x.\n",
+ driver_info->version_high, driver_info->version_low);
+}
+
+/* Context activation is done by the caller. */
+static void fixup_extensions(struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
+{
+ unsigned int i;
+
+ for (i = 0; i < (sizeof(quirk_table) / sizeof(*quirk_table)); ++i)
+ {
+ if (!quirk_table[i].match(gl_info, gl_renderer, gl_vendor, card_vendor, device)) continue;
+ TRACE("Applying driver quirk \"%s\".\n", quirk_table[i].description);
+ quirk_table[i].apply(gl_info);
+ }
+
+ /* Find out if PBOs work as they are supposed to. */
+ test_pbo_functionality(gl_info);
+}
+
+static DWORD wined3d_parse_gl_version(const char *gl_version)
+{
+ const char *ptr = gl_version;
+ int major, minor;
+
+ major = atoi(ptr);
+ if (major <= 0)
+ ERR("Invalid OpenGL major version %d.\n", major);
+
+ while (isdigit(*ptr)) ++ptr;
+ if (*ptr++ != '.')
+ ERR("Invalid OpenGL version string %s.\n", debugstr_a(gl_version));
+
+ minor = atoi(ptr);
+
+ TRACE("Found OpenGL version %d.%d.\n", major, minor);
+
+ return MAKEDWORD_VERSION(major, minor);
+}
+
+static enum wined3d_gl_vendor wined3d_guess_gl_vendor(const struct wined3d_gl_info *gl_info,
+ const char *gl_vendor_string, const char *gl_renderer)
+{
+
+ /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
+ * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
+ * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
+ *
+ * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
+ * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
+ * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
+ * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
+ * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
+ * the chance that other implementations support them is rather small since Win32 QuickTime uses
+ * DirectDraw, not OpenGL. */
+ if (gl_info->supported[APPLE_FENCE]
+ && gl_info->supported[APPLE_CLIENT_STORAGE]
+ && gl_info->supported[APPLE_YCBCR_422])
+ return GL_VENDOR_APPLE;
+
+ if (strstr(gl_vendor_string, "NVIDIA"))
+ return GL_VENDOR_NVIDIA;
+
+ if (strstr(gl_vendor_string, "ATI"))
+ return GL_VENDOR_FGLRX;
+
+ if (strstr(gl_vendor_string, "Intel(R)")
+ /* Intel switched from Intel(R) to Intel® recently, so just match Intel. */
+ || strstr(gl_renderer, "Intel")
+ || strstr(gl_vendor_string, "Intel Inc."))
+ {
+#if 0//def VBOX_WITH_WINE_FIX_QUIRKS /* check if we still need this: device detection was improved significantly with wine */
+ if (strstr(gl_renderer, "Mesa"))
+ return GL_VENDOR_MESA;
+#endif
+ return GL_VENDOR_INTEL;
+ }
+
+ if (strstr(gl_vendor_string, "Mesa")
+ || strstr(gl_vendor_string, "X.Org")
+ || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.")
+ || strstr(gl_vendor_string, "DRI R300 Project")
+ || strstr(gl_vendor_string, "Tungsten Graphics, Inc")
+ || strstr(gl_vendor_string, "VMware, Inc.")
+ || strstr(gl_renderer, "Mesa")
+ || strstr(gl_renderer, "Gallium"))
+ return GL_VENDOR_MESA;
+
+ FIXME("Received unrecognized GL_VENDOR %s. Returning GL_VENDOR_UNKNOWN.\n",
+ debugstr_a(gl_vendor_string));
+
+ return GL_VENDOR_UNKNOWN;
+}
+
+static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_string, const char *gl_renderer)
+{
+ if (strstr(gl_vendor_string, "NVIDIA")
+ || strstr(gl_vendor_string, "Nouveau")
+ || strstr(gl_vendor_string, "nouveau"))
+ return HW_VENDOR_NVIDIA;
+
+ if (strstr(gl_vendor_string, "ATI")
+ || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.")
+ || strstr(gl_vendor_string, "X.Org R300 Project")
+ || strstr(gl_renderer, "AMD")
+ || strstr(gl_renderer, "R100")
+ || strstr(gl_renderer, "R200")
+ || strstr(gl_renderer, "R300")
+ || strstr(gl_renderer, "R600")
+ || strstr(gl_renderer, "R700"))
+ return HW_VENDOR_AMD;
+
+ if (strstr(gl_vendor_string, "Intel(R)")
+ /* Intel switched from Intel(R) to Intel® recently, so just match Intel. */
+ || strstr(gl_renderer, "Intel")
+ || strstr(gl_renderer, "i915")
+ || strstr(gl_vendor_string, "Intel Inc."))
+ return HW_VENDOR_INTEL;
+
+ if (strstr(gl_vendor_string, "Mesa")
+ || strstr(gl_vendor_string, "Brian Paul")
+ || strstr(gl_vendor_string, "Tungsten Graphics, Inc")
+ || strstr(gl_vendor_string, "VMware, Inc."))
+ return HW_VENDOR_SOFTWARE;
+
+ FIXME("Received unrecognized GL_VENDOR %s. Returning HW_VENDOR_NVIDIA.\n", debugstr_a(gl_vendor_string));
+
+ return HW_VENDOR_NVIDIA;
+}
+
+static UINT d3d_level_from_gl_info(const struct wined3d_gl_info *gl_info)
+{
+ UINT level = 0;
+
+ if (gl_info->supported[ARB_MULTITEXTURE])
+ level = 6;
+ if (gl_info->supported[ARB_TEXTURE_COMPRESSION]
+ && gl_info->supported[ARB_TEXTURE_CUBE_MAP]
+ && gl_info->supported[ARB_TEXTURE_ENV_DOT3])
+ level = 7;
+ if (level == 7 && gl_info->supported[ARB_MULTISAMPLE]
+ && gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
+ level = 8;
+ if (level == 8 && gl_info->supported[ARB_FRAGMENT_PROGRAM]
+ && gl_info->supported[ARB_VERTEX_SHADER])
+ level = 9;
+ if (level == 9 && gl_info->supported[EXT_GPU_SHADER4])
+ level = 10;
+
+ return level;
+}
+
+static enum wined3d_pci_device select_card_nvidia_binary(const struct wined3d_gl_info *gl_info,
+ const char *gl_renderer)
+{
+ UINT d3d_level = d3d_level_from_gl_info(gl_info);
+ unsigned int i;
+
+#ifndef VBOX_WITH_WDDM
+ if (d3d_level >= 10)
+#endif
+ {
+ static const struct
+ {
+ const char *renderer;
+ enum wined3d_pci_device id;
+ }
+ cards[] =
+ {
+ {"GTX 770M", CARD_NVIDIA_GEFORCE_GTX770M}, /* Geforce 700 - midend high mobile */
+ {"GTX 680", CARD_NVIDIA_GEFORCE_GTX680}, /* Geforce 600 - highend */
+ {"GTX 670MX", CARD_NVIDIA_GEFORCE_GTX670MX}, /* Geforce 600 - highend */
+ {"GTX 670", CARD_NVIDIA_GEFORCE_GTX670}, /* Geforce 600 - midend high */
+ {"GTX 660 Ti", CARD_NVIDIA_GEFORCE_GTX660TI}, /* Geforce 600 - midend high */
+ {"GTX 660", CARD_NVIDIA_GEFORCE_GTX660}, /* Geforce 600 - midend high */
+ {"GTX 650 Ti", CARD_NVIDIA_GEFORCE_GTX650TI}, /* Geforce 600 - lowend */
+ {"GTX 650", CARD_NVIDIA_GEFORCE_GTX650}, /* Geforce 600 - lowend */
+ {"GT 650M", CARD_NVIDIA_GEFORCE_GT650M}, /* Geforce 600 - midend mobile */
+ {"GT 640M", CARD_NVIDIA_GEFORCE_GT640M}, /* Geforce 600 - midend mobile */
+ {"GT 630M", CARD_NVIDIA_GEFORCE_GT630M}, /* Geforce 600 - midend mobile */
+ {"GT 630", CARD_NVIDIA_GEFORCE_GT630}, /* Geforce 600 - lowend */
+ {"GT 610", CARD_NVIDIA_GEFORCE_GT610}, /* Geforce 600 - lowend */
+ {"GTX 580", CARD_NVIDIA_GEFORCE_GTX580}, /* Geforce 500 - highend */
+ {"GTX 570", CARD_NVIDIA_GEFORCE_GTX570}, /* Geforce 500 - midend high */
+ {"GTX 560 Ti", CARD_NVIDIA_GEFORCE_GTX560TI}, /* Geforce 500 - midend */
+ {"GTX 560", CARD_NVIDIA_GEFORCE_GTX560}, /* Geforce 500 - midend */
+ {"GT 555M", CARD_NVIDIA_GEFORCE_GT555M}, /* Geforce 500 - midend mobile */
+ {"GTX 550 Ti", CARD_NVIDIA_GEFORCE_GTX550}, /* Geforce 500 - midend */
+ {"GT 540M", CARD_NVIDIA_GEFORCE_GT540M}, /* Geforce 500 - midend mobile */
+ {"GT 520", CARD_NVIDIA_GEFORCE_GT520}, /* Geforce 500 - lowend */
+ {"GTX 480", CARD_NVIDIA_GEFORCE_GTX480}, /* Geforce 400 - highend */
+ {"GTX 470", CARD_NVIDIA_GEFORCE_GTX470}, /* Geforce 400 - midend high */
+ {"GTX 465", CARD_NVIDIA_GEFORCE_GTX465}, /* Geforce 400 - midend */
+ {"GTX 460M", CARD_NVIDIA_GEFORCE_GTX460M}, /* Geforce 400 - highend mobile */
+ {"GTX 460", CARD_NVIDIA_GEFORCE_GTX460}, /* Geforce 400 - midend */
+ {"GTS 450", CARD_NVIDIA_GEFORCE_GTS450}, /* Geforce 400 - midend low */
+ {"GT 440", CARD_NVIDIA_GEFORCE_GT440}, /* Geforce 400 - lowend */
+ {"GT 430", CARD_NVIDIA_GEFORCE_GT430}, /* Geforce 400 - lowend */
+ {"GT 420", CARD_NVIDIA_GEFORCE_GT420}, /* Geforce 400 - lowend */
+ {"410M", CARD_NVIDIA_GEFORCE_410M}, /* Geforce 400 - lowend mobile */
+ {"GT 330", CARD_NVIDIA_GEFORCE_GT330}, /* Geforce 300 - highend */
+ {"GTS 360M", CARD_NVIDIA_GEFORCE_GTS350M}, /* Geforce 300 - highend mobile */
+ {"GTS 350M", CARD_NVIDIA_GEFORCE_GTS350M}, /* Geforce 300 - highend mobile */
+ {"GT 330M", CARD_NVIDIA_GEFORCE_GT325M}, /* Geforce 300 - midend mobile */
+ {"GT 325M", CARD_NVIDIA_GEFORCE_GT325M}, /* Geforce 300 - midend mobile */
+ {"GT 320M", CARD_NVIDIA_GEFORCE_GT320M}, /* Geforce 300 - midend mobile */
+ {"320M", CARD_NVIDIA_GEFORCE_320M}, /* Geforce 300 - midend mobile */
+ {"315M", CARD_NVIDIA_GEFORCE_315M}, /* Geforce 300 - midend mobile */
+ {"GTX 295", CARD_NVIDIA_GEFORCE_GTX280}, /* Geforce 200 - highend */
+ {"GTX 285", CARD_NVIDIA_GEFORCE_GTX280}, /* Geforce 200 - highend */
+ {"GTX 280", CARD_NVIDIA_GEFORCE_GTX280}, /* Geforce 200 - highend */
+ {"GTX 275", CARD_NVIDIA_GEFORCE_GTX275}, /* Geforce 200 - midend high */
+ {"GTX 260", CARD_NVIDIA_GEFORCE_GTX260}, /* Geforce 200 - midend */
+ {"GT 240", CARD_NVIDIA_GEFORCE_GT240}, /* Geforce 200 - midend */
+ {"GT 220", CARD_NVIDIA_GEFORCE_GT220}, /* Geforce 200 - lowend */
+ {"Geforce 310", CARD_NVIDIA_GEFORCE_210}, /* Geforce 200 - lowend */
+ {"Geforce 305", CARD_NVIDIA_GEFORCE_210}, /* Geforce 200 - lowend */
+ {"Geforce 210", CARD_NVIDIA_GEFORCE_210}, /* Geforce 200 - lowend */
+ {"G 210", CARD_NVIDIA_GEFORCE_210}, /* Geforce 200 - lowend */
+ {"GTS 250", CARD_NVIDIA_GEFORCE_9800GT}, /* Geforce 9 - highend / Geforce 200 - midend */
+ {"GTS 150", CARD_NVIDIA_GEFORCE_9800GT}, /* Geforce 9 - highend / Geforce 200 - midend */
+ {"9800", CARD_NVIDIA_GEFORCE_9800GT}, /* Geforce 9 - highend / Geforce 200 - midend */
+ {"GT 140", CARD_NVIDIA_GEFORCE_9600GT}, /* Geforce 9 - midend */
+ {"9600", CARD_NVIDIA_GEFORCE_9600GT}, /* Geforce 9 - midend */
+ {"GT 130", CARD_NVIDIA_GEFORCE_9500GT}, /* Geforce 9 - midend low / Geforce 200 - low */
+ {"GT 120", CARD_NVIDIA_GEFORCE_9500GT}, /* Geforce 9 - midend low / Geforce 200 - low */
+ {"9500", CARD_NVIDIA_GEFORCE_9500GT}, /* Geforce 9 - midend low / Geforce 200 - low */
+ {"9400M", CARD_NVIDIA_GEFORCE_9400M}, /* Geforce 9 - lowend */
+ {"9400", CARD_NVIDIA_GEFORCE_9400GT}, /* Geforce 9 - lowend */
+ {"9300", CARD_NVIDIA_GEFORCE_9300}, /* Geforce 9 - lowend low */
+ {"9200", CARD_NVIDIA_GEFORCE_9200}, /* Geforce 9 - lowend low */
+ {"9100", CARD_NVIDIA_GEFORCE_9200}, /* Geforce 9 - lowend low */
+ {"G 100", CARD_NVIDIA_GEFORCE_9200}, /* Geforce 9 - lowend low */
+ {"8800 GTX", CARD_NVIDIA_GEFORCE_8800GTX}, /* Geforce 8 - highend high */
+ {"8800", CARD_NVIDIA_GEFORCE_8800GTS}, /* Geforce 8 - highend */
+ {"8600M", CARD_NVIDIA_GEFORCE_8600MGT}, /* Geforce 8 - midend mobile */
+ {"8600 M", CARD_NVIDIA_GEFORCE_8600MGT}, /* Geforce 8 - midend mobile */
+ {"8700", CARD_NVIDIA_GEFORCE_8600GT}, /* Geforce 8 - midend */
+ {"8600", CARD_NVIDIA_GEFORCE_8600GT}, /* Geforce 8 - midend */
+ {"8500", CARD_NVIDIA_GEFORCE_8400GS}, /* Geforce 8 - mid-lowend */
+ {"8400", CARD_NVIDIA_GEFORCE_8400GS}, /* Geforce 8 - mid-lowend */
+ {"8300", CARD_NVIDIA_GEFORCE_8300GS}, /* Geforce 8 - lowend */
+ {"8200", CARD_NVIDIA_GEFORCE_8300GS}, /* Geforce 8 - lowend */
+ {"8100", CARD_NVIDIA_GEFORCE_8300GS}, /* Geforce 8 - lowend */
+ };
+
+ for (i = 0; i < sizeof(cards) / sizeof(*cards); ++i)
+ {
+ if (strstr(gl_renderer, cards[i].renderer))
+ return cards[i].id;
+ }
+
+ return PCI_DEVICE_NONE;
+ }
+
+ /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more
+ * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
+ */
+ if (d3d_level >= 9 && gl_info->supported[NV_VERTEX_PROGRAM3])
+ {
+ static const struct
+ {
+ const char *renderer;
+ enum wined3d_pci_device id;
+ }
+ cards[] =
+ {
+ {"Quadro FX 5", CARD_NVIDIA_GEFORCE_7800GT}, /* Geforce 7 - highend */
+ {"Quadro FX 4", CARD_NVIDIA_GEFORCE_7800GT}, /* Geforce 7 - highend */
+ {"7950", CARD_NVIDIA_GEFORCE_7800GT}, /* Geforce 7 - highend */
+ {"7900", CARD_NVIDIA_GEFORCE_7800GT}, /* Geforce 7 - highend */
+ {"7800", CARD_NVIDIA_GEFORCE_7800GT}, /* Geforce 7 - highend */
+ {"7700", CARD_NVIDIA_GEFORCE_7600}, /* Geforce 7 - midend */
+ {"7600", CARD_NVIDIA_GEFORCE_7600}, /* Geforce 7 - midend */
+ {"7400", CARD_NVIDIA_GEFORCE_7400}, /* Geforce 7 - lower medium */
+ {"7300", CARD_NVIDIA_GEFORCE_7300}, /* Geforce 7 - lowend */
+ {"6800", CARD_NVIDIA_GEFORCE_6800}, /* Geforce 6 - highend */
+ {"6700", CARD_NVIDIA_GEFORCE_6600GT}, /* Geforce 6 - midend */
+ {"6610", CARD_NVIDIA_GEFORCE_6600GT}, /* Geforce 6 - midend */
+ {"6600", CARD_NVIDIA_GEFORCE_6600GT}, /* Geforce 6 - midend */
+ };
+
+ for (i = 0; i < sizeof(cards) / sizeof(*cards); ++i)
+ {
+ if (strstr(gl_renderer, cards[i].renderer))
+ return cards[i].id;
+ }
+
+ return PCI_DEVICE_NONE;
+ }
+
+ if (d3d_level >= 9)
+ {
+ /* GeforceFX - highend */
+ if (strstr(gl_renderer, "5800")
+ || strstr(gl_renderer, "5900")
+ || strstr(gl_renderer, "5950")
+ || strstr(gl_renderer, "Quadro FX"))
+ {
+ return CARD_NVIDIA_GEFORCEFX_5800;
+ }
+
+ /* GeforceFX - midend */
+ if (strstr(gl_renderer, "5600")
+ || strstr(gl_renderer, "5650")
+ || strstr(gl_renderer, "5700")
+ || strstr(gl_renderer, "5750"))
+ {
+ return CARD_NVIDIA_GEFORCEFX_5600;
+ }
+
+ /* GeforceFX - lowend */
+ return CARD_NVIDIA_GEFORCEFX_5200; /* GeforceFX 5100/5200/5250/5300/5500 */
+ }
+
+ if (d3d_level >= 8)
+ {
+ if (strstr(gl_renderer, "GeForce4 Ti") || strstr(gl_renderer, "Quadro4"))
+ {
+ return CARD_NVIDIA_GEFORCE4_TI4200; /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800, Quadro4 */
+ }
+
+ return CARD_NVIDIA_GEFORCE3; /* Geforce3 standard/Ti200/Ti500, Quadro DCC */
+ }
+
+ if (d3d_level >= 7)
+ {
+ if (strstr(gl_renderer, "GeForce4 MX"))
+ {
+ return CARD_NVIDIA_GEFORCE4_MX; /* MX420/MX440/MX460/MX4000 */
+ }
+
+ if (strstr(gl_renderer, "GeForce2 MX") || strstr(gl_renderer, "Quadro2 MXR"))
+ {
+ return CARD_NVIDIA_GEFORCE2_MX; /* Geforce2 standard/MX100/MX200/MX400, Quadro2 MXR */
+ }
+
+ if (strstr(gl_renderer, "GeForce2") || strstr(gl_renderer, "Quadro2"))
+ {
+ return CARD_NVIDIA_GEFORCE2; /* Geforce2 GTS/Pro/Ti/Ultra, Quadro2 */
+ }
+
+ return CARD_NVIDIA_GEFORCE; /* Geforce 256/DDR, Quadro */
+ }
+
+ if (strstr(gl_renderer, "TNT2"))
+ {
+ return CARD_NVIDIA_RIVA_TNT2; /* Riva TNT2 standard/M64/Pro/Ultra */
+ }
+
+ return CARD_NVIDIA_RIVA_TNT; /* Riva TNT, Vanta */
+}
+
+static enum wined3d_pci_device select_card_amd_binary(const struct wined3d_gl_info *gl_info,
+ const char *gl_renderer)
+{
+ UINT d3d_level = d3d_level_from_gl_info(gl_info);
+
+ /* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx
+ *
+ * Beware: renderer string do not match exact card model,
+ * eg HD 4800 is returned for multiple cards, even for RV790 based ones. */
+#ifndef VBOX_WITH_WDDM
+ if (d3d_level >= 10)
+#endif
+ {
+ unsigned int i;
+
+ static const struct
+ {
+ const char *renderer;
+ enum wined3d_pci_device id;
+ }
+ cards[] =
+ {
+ /* Southern Islands */
+ {"HD 7900", CARD_AMD_RADEON_HD7900},
+ {"HD 7800", CARD_AMD_RADEON_HD7800},
+ {"HD 7700", CARD_AMD_RADEON_HD7700},
+ /* Northern Islands */
+ {"HD 6970", CARD_AMD_RADEON_HD6900},
+ {"HD 6900", CARD_AMD_RADEON_HD6900},
+ {"HD 6800", CARD_AMD_RADEON_HD6800},
+ {"HD 6770M",CARD_AMD_RADEON_HD6600M},
+ {"HD 6750M",CARD_AMD_RADEON_HD6600M},
+ {"HD 6700", CARD_AMD_RADEON_HD6700},
+ {"HD 6670", CARD_AMD_RADEON_HD6600},
+ {"HD 6630M",CARD_AMD_RADEON_HD6600M},
+ {"HD 6600M",CARD_AMD_RADEON_HD6600M},
+ {"HD 6600", CARD_AMD_RADEON_HD6600},
+ {"HD 6570", CARD_AMD_RADEON_HD6600},
+ {"HD 6500M",CARD_AMD_RADEON_HD6600M},
+ {"HD 6500", CARD_AMD_RADEON_HD6600},
+ {"HD 6400", CARD_AMD_RADEON_HD6400},
+ {"HD 6300", CARD_AMD_RADEON_HD6300},
+ {"HD 6200", CARD_AMD_RADEON_HD6300},
+ /* Evergreen */
+ {"HD 5870", CARD_AMD_RADEON_HD5800}, /* Radeon EG CYPRESS PRO */
+ {"HD 5850", CARD_AMD_RADEON_HD5800}, /* Radeon EG CYPRESS XT */
+ {"HD 5800", CARD_AMD_RADEON_HD5800}, /* Radeon EG CYPRESS HD58xx generic renderer string */
+ {"HD 5770", CARD_AMD_RADEON_HD5700}, /* Radeon EG JUNIPER XT */
+ {"HD 5750", CARD_AMD_RADEON_HD5700}, /* Radeon EG JUNIPER LE */
+ {"HD 5700", CARD_AMD_RADEON_HD5700}, /* Radeon EG JUNIPER HD57xx generic renderer string */
+ {"HD 5670", CARD_AMD_RADEON_HD5600}, /* Radeon EG REDWOOD XT */
+ {"HD 5570", CARD_AMD_RADEON_HD5600}, /* Radeon EG REDWOOD PRO mapped to HD5600 series */
+ {"HD 5550", CARD_AMD_RADEON_HD5600}, /* Radeon EG REDWOOD LE mapped to HD5600 series */
+ {"HD 5450", CARD_AMD_RADEON_HD5400}, /* Radeon EG CEDAR PRO */
+ {"HD 5000", CARD_AMD_RADEON_HD5600}, /* Defaulting to HD 5600 */
+ /* R700 */
+ {"HD 4890", CARD_AMD_RADEON_HD4800}, /* Radeon RV790 */
+ {"HD 4870", CARD_AMD_RADEON_HD4800}, /* Radeon RV770 */
+ {"HD 4850", CARD_AMD_RADEON_HD4800}, /* Radeon RV770 */
+ {"HD 4830", CARD_AMD_RADEON_HD4800}, /* Radeon RV770 */
+ {"HD 4800", CARD_AMD_RADEON_HD4800}, /* Radeon RV7xx HD48xx generic renderer string */
+ {"HD 4770", CARD_AMD_RADEON_HD4700}, /* Radeon RV740 */
+ {"HD 4700", CARD_AMD_RADEON_HD4700}, /* Radeon RV7xx HD47xx generic renderer string */
+ {"HD 4670", CARD_AMD_RADEON_HD4600}, /* Radeon RV730 */
+ {"HD 4650", CARD_AMD_RADEON_HD4600}, /* Radeon RV730 */
+ {"HD 4600", CARD_AMD_RADEON_HD4600}, /* Radeon RV730 */
+ {"HD 4550", CARD_AMD_RADEON_HD4350}, /* Radeon RV710 */
+ {"HD 4350", CARD_AMD_RADEON_HD4350}, /* Radeon RV710 */
+ /* R600/R700 integrated */
+ {"HD 4200M", CARD_AMD_RADEON_HD4200M},
+ {"HD 3300", CARD_AMD_RADEON_HD3200},
+ {"HD 3200", CARD_AMD_RADEON_HD3200},
+ {"HD 3100", CARD_AMD_RADEON_HD3200},
+ /* R600 */
+ {"HD 3870", CARD_AMD_RADEON_HD2900}, /* HD2900/HD3800 - highend */
+ {"HD 3850", CARD_AMD_RADEON_HD2900}, /* HD2900/HD3800 - highend */
+ {"HD 2900", CARD_AMD_RADEON_HD2900}, /* HD2900/HD3800 - highend */
+ {"HD 3830", CARD_AMD_RADEON_HD2600}, /* China-only midend */
+ {"HD 3690", CARD_AMD_RADEON_HD2600}, /* HD2600/HD3600 - midend */
+ {"HD 3650", CARD_AMD_RADEON_HD2600}, /* HD2600/HD3600 - midend */
+ {"HD 2600", CARD_AMD_RADEON_HD2600}, /* HD2600/HD3600 - midend */
+ {"HD 3470", CARD_AMD_RADEON_HD2350}, /* HD2350/HD2400/HD3400 - lowend */
+ {"HD 3450", CARD_AMD_RADEON_HD2350}, /* HD2350/HD2400/HD3400 - lowend */
+ {"HD 3430", CARD_AMD_RADEON_HD2350}, /* HD2350/HD2400/HD3400 - lowend */
+ {"HD 3400", CARD_AMD_RADEON_HD2350}, /* HD2350/HD2400/HD3400 - lowend */
+ {"HD 2400", CARD_AMD_RADEON_HD2350}, /* HD2350/HD2400/HD3400 - lowend */
+ {"HD 2350", CARD_AMD_RADEON_HD2350}, /* HD2350/HD2400/HD3400 - lowend */
+ };
+
+ for (i = 0; i < sizeof(cards) / sizeof(*cards); ++i)
+ {
+ if (strstr(gl_renderer, cards[i].renderer))
+ return cards[i].id;
+ }
+
+ return PCI_DEVICE_NONE;
+ }
+
+ if (d3d_level >= 9)
+ {
+ /* Radeon R5xx */
+ if (strstr(gl_renderer, "X1600")
+ || strstr(gl_renderer, "X1650")
+ || strstr(gl_renderer, "X1800")
+ || strstr(gl_renderer, "X1900")
+ || strstr(gl_renderer, "X1950"))
+ {
+ return CARD_AMD_RADEON_X1600;
+ }
+
+ /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300/X2500/HD2300 (lowend R5xx)
+ * Note X2300/X2500/HD2300 are R5xx GPUs with a 2xxx naming but they are still DX9-only */
+ if (strstr(gl_renderer, "X700")
+ || strstr(gl_renderer, "X800")
+ || strstr(gl_renderer, "X850")
+ || strstr(gl_renderer, "X1300")
+ || strstr(gl_renderer, "X1400")
+ || strstr(gl_renderer, "X1450")
+ || strstr(gl_renderer, "X1550")
+ || strstr(gl_renderer, "X2300")
+ || strstr(gl_renderer, "X2500")
+ || strstr(gl_renderer, "HD 2300")
+ )
+ {
+ return CARD_AMD_RADEON_X700;
+ }
+
+ /* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400MHz */
+ if (strstr(gl_renderer, "Radeon Xpress"))
+ {
+ return CARD_AMD_RADEON_XPRESS_200M;
+ }
+ }
+
+ return PCI_DEVICE_NONE;
+}
+
+static enum wined3d_pci_device select_card_intel(const struct wined3d_gl_info *gl_info,
+ const char *gl_renderer)
+{
+ unsigned int i;
+
+ static const struct
+ {
+ const char *renderer;
+ enum wined3d_pci_device id;
+ }
+ cards[] =
+ {
+ /* Ivybridge */
+ {"Ivybridge Server", CARD_INTEL_IVBS},
+ {"Ivybridge Mobile", CARD_INTEL_IVBM},
+ {"Ivybridge Desktop", CARD_INTEL_IVBD},
+ /* Sandybridge */
+ {"Sandybridge Server", CARD_INTEL_SNBS},
+ {"Sandybridge Mobile", CARD_INTEL_SNBM},
+ {"Sandybridge Desktop", CARD_INTEL_SNBD},
+ /* Ironlake */
+ {"Ironlake Mobile", CARD_INTEL_ILKM},
+ {"Ironlake Desktop", CARD_INTEL_ILKD},
+ /* G4x */
+ {"B43", CARD_INTEL_B43},
+ {"G41", CARD_INTEL_G41},
+ {"G45", CARD_INTEL_G45},
+ {"Q45", CARD_INTEL_Q45},
+ {"Integrated Graphics Device", CARD_INTEL_IGD},
+ {"GM45", CARD_INTEL_GM45},
+ /* i965 */
+ {"965GME", CARD_INTEL_965GME},
+ {"965GM", CARD_INTEL_965GM},
+ {"X3100", CARD_INTEL_965GM}, /* MacOS */
+ {"946GZ", CARD_INTEL_946GZ},
+ {"965G", CARD_INTEL_965G},
+ {"965Q", CARD_INTEL_965Q},
+ /* i945 */
+ {"Pineview M", CARD_INTEL_PNVM},
+ {"Pineview G", CARD_INTEL_PNVG},
+ {"IGD", CARD_INTEL_PNVG},
+ {"Q33", CARD_INTEL_Q33},
+ {"G33", CARD_INTEL_G33},
+ {"Q35", CARD_INTEL_Q35},
+ {"945GME", CARD_INTEL_945GME},
+ {"945GM", CARD_INTEL_945GM},
+ {"GMA 950", CARD_INTEL_945GM}, /* MacOS */
+ {"945G", CARD_INTEL_945G},
+ /* i915 */
+ {"915GM", CARD_INTEL_915GM},
+ {"E7221G", CARD_INTEL_E7221G},
+ {"915G", CARD_INTEL_915G},
+ /* i8xx */
+ {"865G", CARD_INTEL_865G},
+ {"845G", CARD_INTEL_845G},
+ {"855GM", CARD_INTEL_855GM},
+ {"830M", CARD_INTEL_830M},
+#ifdef VBOX_WITH_WINE_FIX_QUIRKS
+ {"HD Graphics", CARD_INTEL_SNBM},
+#endif
+ };
+
+ for (i = 0; i < sizeof(cards) / sizeof(*cards); ++i)
+ {
+ if (strstr(gl_renderer, cards[i].renderer))
+ return cards[i].id;
+ }
+
+ return PCI_DEVICE_NONE;
+}
+
+static enum wined3d_pci_device select_card_amd_mesa(const struct wined3d_gl_info *gl_info,
+ const char *gl_renderer)
+{
+ unsigned int i;
+
+ /* 20101109 - These are never returned by current Gallium radeon
+ * drivers: R700, RV790, R680, RV535, RV516, R410, RS485, RV360, RV351.
+ *
+ * These are returned but not handled: RC410, RV380. */
+ static const struct
+ {
+ const char *renderer;
+ enum wined3d_pci_device id;
+ }
+ cards[] =
+ {
+ /* Southern Islands */
+ {"TAHITI", CARD_AMD_RADEON_HD7900},
+ {"PITCAIRN", CARD_AMD_RADEON_HD7800},
+ {"CAPE VERDE", CARD_AMD_RADEON_HD7700},
+ /* Northern Islands */
+ {"CAYMAN", CARD_AMD_RADEON_HD6900},
+ {"BARTS", CARD_AMD_RADEON_HD6800},
+ {"TURKS", CARD_AMD_RADEON_HD6600},
+ {"SUMO2", CARD_AMD_RADEON_HD6410D}, /* SUMO2 first, because we do a strstr(). */
+ {"SUMO", CARD_AMD_RADEON_HD6550D},
+ {"CAICOS", CARD_AMD_RADEON_HD6400},
+ {"PALM", CARD_AMD_RADEON_HD6300},
+ /* Evergreen */
+ {"HEMLOCK", CARD_AMD_RADEON_HD5900},
+ {"CYPRESS", CARD_AMD_RADEON_HD5800},
+ {"JUNIPER", CARD_AMD_RADEON_HD5700},
+ {"REDWOOD", CARD_AMD_RADEON_HD5600},
+ {"CEDAR", CARD_AMD_RADEON_HD5400},
+ /* R700 */
+ {"R700", CARD_AMD_RADEON_HD4800},
+ {"RV790", CARD_AMD_RADEON_HD4800},
+ {"RV770", CARD_AMD_RADEON_HD4800},
+ {"RV740", CARD_AMD_RADEON_HD4700},
+ {"RV730", CARD_AMD_RADEON_HD4600},
+ {"RV710", CARD_AMD_RADEON_HD4350},
+ /* R600/R700 integrated */
+ {"RS880", CARD_AMD_RADEON_HD4200M},
+ {"RS780", CARD_AMD_RADEON_HD3200},
+ /* R600 */
+ {"R680", CARD_AMD_RADEON_HD2900},
+ {"R600", CARD_AMD_RADEON_HD2900},
+ {"RV670", CARD_AMD_RADEON_HD2900},
+ {"RV635", CARD_AMD_RADEON_HD2600},
+ {"RV630", CARD_AMD_RADEON_HD2600},
+ {"RV620", CARD_AMD_RADEON_HD2350},
+ {"RV610", CARD_AMD_RADEON_HD2350},
+ /* R500 */
+ {"R580", CARD_AMD_RADEON_X1600},
+ {"R520", CARD_AMD_RADEON_X1600},
+ {"RV570", CARD_AMD_RADEON_X1600},
+ {"RV560", CARD_AMD_RADEON_X1600},
+ {"RV535", CARD_AMD_RADEON_X1600},
+ {"RV530", CARD_AMD_RADEON_X1600},
+ {"RV516", CARD_AMD_RADEON_X700},
+ {"RV515", CARD_AMD_RADEON_X700},
+ /* R400 */
+ {"R481", CARD_AMD_RADEON_X700},
+ {"R480", CARD_AMD_RADEON_X700},
+ {"R430", CARD_AMD_RADEON_X700},
+ {"R423", CARD_AMD_RADEON_X700},
+ {"R420", CARD_AMD_RADEON_X700},
+ {"R410", CARD_AMD_RADEON_X700},
+ {"RV410", CARD_AMD_RADEON_X700},
+ /* Radeon Xpress - onboard, DX9b, Shader 2.0, 300-400MHz */
+ {"RS740", CARD_AMD_RADEON_XPRESS_200M},
+ {"RS690", CARD_AMD_RADEON_XPRESS_200M},
+ {"RS600", CARD_AMD_RADEON_XPRESS_200M},
+ {"RS485", CARD_AMD_RADEON_XPRESS_200M},
+ {"RS482", CARD_AMD_RADEON_XPRESS_200M},
+ {"RS480", CARD_AMD_RADEON_XPRESS_200M},
+ {"RS400", CARD_AMD_RADEON_XPRESS_200M},
+ /* R300 */
+ {"R360", CARD_AMD_RADEON_9500},
+ {"R350", CARD_AMD_RADEON_9500},
+ {"R300", CARD_AMD_RADEON_9500},
+ {"RV370", CARD_AMD_RADEON_9500},
+ {"RV360", CARD_AMD_RADEON_9500},
+ {"RV351", CARD_AMD_RADEON_9500},
+ {"RV350", CARD_AMD_RADEON_9500},
+ };
+
+ for (i = 0; i < sizeof(cards) / sizeof(*cards); ++i)
+ {
+ if (strstr(gl_renderer, cards[i].renderer))
+ return cards[i].id;
+ }
+
+ return PCI_DEVICE_NONE;
+}
+
+static enum wined3d_pci_device select_card_nvidia_mesa(const struct wined3d_gl_info *gl_info,
+ const char *gl_renderer)
+{
+ unsigned int i;
+
+ static const struct
+ {
+ const char *renderer;
+ enum wined3d_pci_device id;
+ }
+ cards[] =
+ {
+ /* Kepler */
+ {"NVE6", CARD_NVIDIA_GEFORCE_GTX770M},
+ {"NVE4", CARD_NVIDIA_GEFORCE_GTX680},
+ /* Fermi */
+ {"NVD9", CARD_NVIDIA_GEFORCE_GT520},
+ {"NVCF", CARD_NVIDIA_GEFORCE_GTX550},
+ {"NVCE", CARD_NVIDIA_GEFORCE_GTX560},
+ {"NVC8", CARD_NVIDIA_GEFORCE_GTX570},
+ {"NVC4", CARD_NVIDIA_GEFORCE_GTX460},
+ {"NVC3", CARD_NVIDIA_GEFORCE_GT440},
+ {"NVC1", CARD_NVIDIA_GEFORCE_GT420},
+ {"NVC0", CARD_NVIDIA_GEFORCE_GTX480},
+ /* Tesla */
+ {"NVAF", CARD_NVIDIA_GEFORCE_GT320M},
+ {"NVAC", CARD_NVIDIA_GEFORCE_8200},
+ {"NVAA", CARD_NVIDIA_GEFORCE_8200},
+ {"NVA8", CARD_NVIDIA_GEFORCE_210},
+ {"NVA5", CARD_NVIDIA_GEFORCE_GT220},
+ {"NVA3", CARD_NVIDIA_GEFORCE_GT240},
+ {"NVA0", CARD_NVIDIA_GEFORCE_GTX280},
+ {"NV98", CARD_NVIDIA_GEFORCE_9200},
+ {"NV96", CARD_NVIDIA_GEFORCE_9400GT},
+ {"NV94", CARD_NVIDIA_GEFORCE_9600GT},
+ {"NV92", CARD_NVIDIA_GEFORCE_9800GT},
+ {"NV86", CARD_NVIDIA_GEFORCE_8500GT},
+ {"NV84", CARD_NVIDIA_GEFORCE_8600GT},
+ {"NV50", CARD_NVIDIA_GEFORCE_8800GTX},
+ /* Curie */
+ {"NV68", CARD_NVIDIA_GEFORCE_6200}, /* 7050 */
+ {"NV67", CARD_NVIDIA_GEFORCE_6200}, /* 7000M */
+ {"NV63", CARD_NVIDIA_GEFORCE_6200}, /* 7100 */
+ {"NV4E", CARD_NVIDIA_GEFORCE_6200}, /* 6100 Go / 6150 Go */
+ {"NV4C", CARD_NVIDIA_GEFORCE_6200}, /* 6150SE */
+ {"NV4B", CARD_NVIDIA_GEFORCE_7600},
+ {"NV4A", CARD_NVIDIA_GEFORCE_6200},
+ {"NV49", CARD_NVIDIA_GEFORCE_7800GT}, /* 7900 */
+ {"NV47", CARD_NVIDIA_GEFORCE_7800GT},
+ {"NV46", CARD_NVIDIA_GEFORCE_7400},
+ {"NV45", CARD_NVIDIA_GEFORCE_6800},
+ {"NV44", CARD_NVIDIA_GEFORCE_6200},
+ {"NV43", CARD_NVIDIA_GEFORCE_6600GT},
+ {"NV42", CARD_NVIDIA_GEFORCE_6800},
+ {"NV41", CARD_NVIDIA_GEFORCE_6800},
+ {"NV40", CARD_NVIDIA_GEFORCE_6800},
+ /* Rankine */
+ {"NV38", CARD_NVIDIA_GEFORCEFX_5800}, /* FX 5950 Ultra */
+ {"NV36", CARD_NVIDIA_GEFORCEFX_5800}, /* FX 5700/5750 */
+ {"NV35", CARD_NVIDIA_GEFORCEFX_5800}, /* FX 5900 */
+ {"NV34", CARD_NVIDIA_GEFORCEFX_5200},
+ {"NV31", CARD_NVIDIA_GEFORCEFX_5600},
+ {"NV30", CARD_NVIDIA_GEFORCEFX_5800},
+ /* Kelvin */
+ {"nv28", CARD_NVIDIA_GEFORCE4_TI4200},
+ {"nv25", CARD_NVIDIA_GEFORCE4_TI4200},
+ {"nv20", CARD_NVIDIA_GEFORCE3},
+ /* Celsius */
+ {"nv1F", CARD_NVIDIA_GEFORCE4_MX}, /* GF4 MX IGP */
+ {"nv1A", CARD_NVIDIA_GEFORCE2}, /* GF2 IGP */
+ {"nv18", CARD_NVIDIA_GEFORCE4_MX},
+ {"nv17", CARD_NVIDIA_GEFORCE4_MX},
+ {"nv16", CARD_NVIDIA_GEFORCE2},
+ {"nv15", CARD_NVIDIA_GEFORCE2},
+ {"nv11", CARD_NVIDIA_GEFORCE2_MX},
+ {"nv10", CARD_NVIDIA_GEFORCE},
+ /* Fahrenheit */
+ {"nv05", CARD_NVIDIA_RIVA_TNT2},
+ {"nv04", CARD_NVIDIA_RIVA_TNT},
+ {"nv03", CARD_NVIDIA_RIVA_128},
+ };
+
+ for (i = 0; i < sizeof(cards) / sizeof(*cards); ++i)
+ {
+ if (strstr(gl_renderer, cards[i].renderer))
+ return cards[i].id;
+ }
+
+ return PCI_DEVICE_NONE;
+}
+
+static const struct gl_vendor_selection
+{
+ enum wined3d_gl_vendor gl_vendor;
+ const char *description; /* Description of the card selector i.e. Apple OS/X Intel */
+ enum wined3d_pci_device (*select_card)(const struct wined3d_gl_info *gl_info, const char *gl_renderer);
+}
+nvidia_gl_vendor_table[] =
+{
+ {GL_VENDOR_NVIDIA, "Nvidia binary driver", select_card_nvidia_binary},
+ {GL_VENDOR_APPLE, "Apple OSX NVidia binary driver", select_card_nvidia_binary},
+ {GL_VENDOR_MESA, "Mesa Nouveau driver", select_card_nvidia_mesa},
+},
+amd_gl_vendor_table[] =
+{
+ {GL_VENDOR_APPLE, "Apple OSX AMD/ATI binary driver", select_card_amd_binary},
+ {GL_VENDOR_FGLRX, "AMD/ATI binary driver", select_card_amd_binary},
+ {GL_VENDOR_MESA, "Mesa AMD/ATI driver", select_card_amd_mesa},
+},
+intel_gl_vendor_table[] =
+{
+ {GL_VENDOR_APPLE, "Apple OSX Intel binary driver", select_card_intel},
+ {GL_VENDOR_INTEL, "Mesa Intel driver", select_card_intel},
+ {GL_VENDOR_MESA, "Mesa Intel driver", select_card_intel},
+};
+
+static enum wined3d_pci_device select_card_fallback_nvidia(const struct wined3d_gl_info *gl_info)
+{
+ UINT d3d_level = d3d_level_from_gl_info(gl_info);
+ if (d3d_level >= 10)
+ return CARD_NVIDIA_GEFORCE_8800GTX;
+ if (d3d_level >= 9 && gl_info->supported[NV_VERTEX_PROGRAM3])
+ return CARD_NVIDIA_GEFORCE_6800;
+ if (d3d_level >= 9)
+#ifndef VBOX_WITH_WDDM
+ return CARD_NVIDIA_GEFORCEFX_5800;
+#else
+ return CARD_NVIDIA_GEFORCE_6200;
+#endif
+ if (d3d_level >= 8)
+ return CARD_NVIDIA_GEFORCE3;
+ if (d3d_level >= 7)
+ return CARD_NVIDIA_GEFORCE;
+ if (d3d_level >= 6)
+ return CARD_NVIDIA_RIVA_TNT;
+ return CARD_NVIDIA_RIVA_128;
+}
+
+static enum wined3d_pci_device select_card_fallback_amd(const struct wined3d_gl_info *gl_info)
+{
+ UINT d3d_level = d3d_level_from_gl_info(gl_info);
+ if (d3d_level >= 10)
+ return CARD_AMD_RADEON_HD2900;
+ if (d3d_level >= 9)
+ return CARD_AMD_RADEON_9500;
+ if (d3d_level >= 8)
+ return CARD_AMD_RADEON_8500;
+ if (d3d_level >= 7)
+ return CARD_AMD_RADEON_7200;
+ return CARD_AMD_RAGE_128PRO;
+}
+
+static enum wined3d_pci_device select_card_fallback_intel(const struct wined3d_gl_info *gl_info)
+{
+ UINT d3d_level = d3d_level_from_gl_info(gl_info);
+ if (d3d_level >= 10)
+ return CARD_INTEL_G45;
+ return CARD_INTEL_915G;
+}
+
+static enum wined3d_pci_device select_card_handler(const struct gl_vendor_selection *table,
+ unsigned int table_size, enum wined3d_gl_vendor gl_vendor,
+ const struct wined3d_gl_info *gl_info, const char *gl_renderer)
+{
+ unsigned int i;
+
+ for (i = 0; i < table_size; ++i)
+ {
+ if (table[i].gl_vendor != gl_vendor)
+ continue;
+
+ TRACE("Applying card selector \"%s\".\n", table[i].description);
+ return table[i].select_card(gl_info, gl_renderer);
+ }
+ FIXME("Couldn't find a suitable card selector for GL vendor %04x (using GL_RENDERER %s)\n",
+ gl_vendor, debugstr_a(gl_renderer));
+
+ return PCI_DEVICE_NONE;
+}
+
+static const struct
+{
+ enum wined3d_pci_vendor card_vendor;
+ const char *description; /* Description of the card selector i.e. Apple OS/X Intel */
+ const struct gl_vendor_selection *gl_vendor_selection;
+ unsigned int gl_vendor_count;
+ enum wined3d_pci_device (*select_card_fallback)(const struct wined3d_gl_info *gl_info);
+}
+card_vendor_table[] =
+{
+ {HW_VENDOR_NVIDIA, "Nvidia", nvidia_gl_vendor_table,
+ sizeof(nvidia_gl_vendor_table) / sizeof(nvidia_gl_vendor_table[0]),
+ select_card_fallback_nvidia},
+ {HW_VENDOR_AMD, "AMD", amd_gl_vendor_table,
+ sizeof(amd_gl_vendor_table) / sizeof(amd_gl_vendor_table[0]),
+ select_card_fallback_amd},
+ {HW_VENDOR_INTEL, "Intel", intel_gl_vendor_table,
+ sizeof(intel_gl_vendor_table) / sizeof(intel_gl_vendor_table[0]),
+ select_card_fallback_intel},
+};
+
+
+static enum wined3d_pci_device wined3d_guess_card(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
+ enum wined3d_gl_vendor *gl_vendor, enum wined3d_pci_vendor *card_vendor)
+{
+ /* A Direct3D device object contains the PCI id (vendor + device) of the
+ * videocard which is used for rendering. Various applications use this
+ * information to get a rough estimation of the features of the card and
+ * some might use it for enabling 3d effects only on certain types of
+ * videocards. In some cases games might even use it to work around bugs
+ * which happen on certain videocards/driver combinations. The problem is
+ * that OpenGL only exposes a rendering string containing the name of the
+ * videocard and not the PCI id.
+ *
+ * Various games depend on the PCI id, so somehow we need to provide one.
+ * A simple option is to parse the renderer string and translate this to
+ * the right PCI id. This is a lot of work because there are more than 200
+ * GPUs just for Nvidia. Various cards share the same renderer string, so
+ * the amount of code might be 'small' but there are quite a number of
+ * exceptions which would make this a pain to maintain. Another way would
+ * be to query the PCI id from the operating system (assuming this is the
+ * videocard which is used for rendering which is not always the case).
+ * This would work but it is not very portable. Second it would not work
+ * well in, let's say, a remote X situation in which the amount of 3d
+ * features which can be used is limited.
+ *
+ * As said most games only use the PCI id to get an indication of the
+ * capabilities of the card. It doesn't really matter if the given id is
+ * the correct one if we return the id of a card with similar 3d features.
+ *
+ * The code below checks the OpenGL capabilities of a videocard and matches
+ * that to a certain level of Direct3D functionality. Once a card passes
+ * the Direct3D9 check, we know that the card (in case of Nvidia) is at
+ * least a GeforceFX. To give a better estimate we do a basic check on the
+ * renderer string but if that won't pass we return a default card. This
+ * way is better than maintaining a full card database as even without a
+ * full database we can return a card with similar features. Second the
+ * size of the database can be made quite small because when you know what
+ * type of 3d functionality a card has, you know to which GPU family the
+ * GPU must belong. Because of this you only have to check a small part of
+ * the renderer string to distinguishes between different models from that
+ * family.
+ *
+ * The code also selects a default amount of video memory which we will
+ * use for an estimation of the amount of free texture memory. In case of
+ * real D3D the amount of texture memory includes video memory and system
+ * memory (to be specific AGP memory or in case of PCIE TurboCache /
+ * HyperMemory). We don't know how much system memory can be addressed by
+ * the system but we can make a reasonable estimation about the amount of
+ * video memory. If the value is slightly wrong it doesn't matter as we
+ * didn't include AGP-like memory which makes the amount of addressable
+ * memory higher and second OpenGL isn't that critical it moves to system
+ * memory behind our backs if really needed. Note that the amount of video
+ * memory can be overruled using a registry setting. */
+
+ unsigned int i;
+ enum wined3d_pci_device device;
+
+ for (i = 0; i < (sizeof(card_vendor_table) / sizeof(*card_vendor_table)); ++i)
+ {
+ if (card_vendor_table[i].card_vendor != *card_vendor)
+ continue;
+
+ TRACE("Applying card selector \"%s\".\n", card_vendor_table[i].description);
+ device = select_card_handler(card_vendor_table[i].gl_vendor_selection,
+ card_vendor_table[i].gl_vendor_count, *gl_vendor, gl_info, gl_renderer);
+ if (device != PCI_DEVICE_NONE)
+ return device;
+
+ TRACE("Unrecognized renderer %s, falling back to default.\n", debugstr_a(gl_renderer));
+ return card_vendor_table[i].select_card_fallback(gl_info);
+ }
+
+ FIXME("No card selector available for card vendor %04x (using GL_RENDERER %s).\n",
+ *card_vendor, debugstr_a(gl_renderer));
+
+ /* Default to generic Nvidia hardware based on the supported OpenGL extensions. */
+ *card_vendor = HW_VENDOR_NVIDIA;
+ return select_card_fallback_nvidia(gl_info);
+}
+
+static const struct wined3d_vertex_pipe_ops *select_vertex_implementation(const struct wined3d_gl_info *gl_info,
+ const struct wined3d_shader_backend_ops *shader_backend_ops)
+{
+ if (shader_backend_ops == &glsl_shader_backend)
+ return &glsl_vertex_pipe;
+ return &ffp_vertex_pipe;
+}
+
+static const struct fragment_pipeline *select_fragment_implementation(const struct wined3d_gl_info *gl_info,
+ const struct wined3d_shader_backend_ops *shader_backend_ops)
+{
+ if (shader_backend_ops == &glsl_shader_backend)
+ return &glsl_fragment_pipe;
+ if (shader_backend_ops == &arb_program_shader_backend && gl_info->supported[ARB_FRAGMENT_PROGRAM])
+ return &arbfp_fragment_pipeline;
+ if (gl_info->supported[ATI_FRAGMENT_SHADER])
+ return &atifs_fragment_pipeline;
+ if (gl_info->supported[NV_REGISTER_COMBINERS] && gl_info->supported[NV_TEXTURE_SHADER2])
+ return &nvts_fragment_pipeline;
+ if (gl_info->supported[NV_REGISTER_COMBINERS])
+ return &nvrc_fragment_pipeline;
+ return &ffp_fragment_pipeline;
+}
+
+static const struct wined3d_shader_backend_ops *select_shader_backend(const struct wined3d_gl_info *gl_info)
+{
+ BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
+
+ if (glsl && gl_info->supported[ARB_FRAGMENT_SHADER])
+ return &glsl_shader_backend;
+ if (glsl && gl_info->supported[ARB_VERTEX_SHADER])
+ {
+ /* Geforce4 cards support GLSL but for vertex shaders only. Further
+ * its reported GLSL caps are wrong. This combined with the fact that
+ * GLSL won't offer more features or performance, use ARB shaders only
+ * on this card. */
+ if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2])
+ return &arb_program_shader_backend;
+ return &glsl_shader_backend;
+ }
+ if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
+ return &arb_program_shader_backend;
+ return &none_shader_backend;
+}
+
+static const struct blit_shader *select_blit_implementation(const struct wined3d_gl_info *gl_info,
+ const struct wined3d_shader_backend_ops *shader_backend_ops)
+{
+ if ((shader_backend_ops == &glsl_shader_backend
+ || shader_backend_ops == &arb_program_shader_backend)
+ && gl_info->supported[ARB_FRAGMENT_PROGRAM])
+ return &arbfp_blit;
+ return &ffp_blit;
+}
+
+static void parse_extension_string(struct wined3d_gl_info *gl_info, const char *extensions,
+ const struct wined3d_extension_map *map, UINT entry_count)
+{
+ while (*extensions)
+ {
+ const char *start;
+ size_t len;
+ UINT i;
+
+ while (isspace(*extensions))
+ ++extensions;
+ start = extensions;
+ while (!isspace(*extensions) && *extensions)
+ ++extensions;
+
+ len = extensions - start;
+ if (!len)
+ continue;
+
+ TRACE("- %s.\n", debugstr_an(start, len));
+
+ for (i = 0; i < entry_count; ++i)
+ {
+ if (len == strlen(map[i].extension_string)
+ && !memcmp(start, map[i].extension_string, len))
+ {
+ TRACE(" FOUND: %s support.\n", map[i].extension_string);
+ gl_info->supported[map[i].extension] = TRUE;
+ break;
+ }
+ }
+ }
+}
+
+static void load_gl_funcs(struct wined3d_gl_info *gl_info)
+{
+#define USE_GL_FUNC(pfn) gl_info->gl_ops.ext.p_##pfn = (void *)wglGetProcAddress(#pfn);
+ GL_EXT_FUNCS_GEN;
+#undef USE_GL_FUNC
+
+#ifndef USE_WIN32_OPENGL
+ /* hack: use the functions directly from the TEB table to bypass the thunks */
+ /* note that we still need the above wglGetProcAddress calls to initialize the table */
+ gl_info->gl_ops.ext = ((struct opengl_funcs *)NtCurrentTeb()->glTable)->ext;
+#endif
+}
+
+static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info)
+{
+ GLfloat gl_floatv[2];
+ GLint gl_max;
+
+ gl_info->limits.blends = 1;
+ gl_info->limits.buffers = 1;
+ gl_info->limits.textures = 1;
+ gl_info->limits.texture_coords = 1;
+ gl_info->limits.fragment_samplers = 1;
+ gl_info->limits.vertex_samplers = 0;
+ gl_info->limits.combined_samplers = gl_info->limits.fragment_samplers + gl_info->limits.vertex_samplers;
+ gl_info->limits.vertex_attribs = 16;
+ gl_info->limits.glsl_vs_float_constants = 0;
+ gl_info->limits.glsl_ps_float_constants = 0;
+ gl_info->limits.arb_vs_float_constants = 0;
+ gl_info->limits.arb_vs_native_constants = 0;
+ gl_info->limits.arb_vs_instructions = 0;
+ gl_info->limits.arb_vs_temps = 0;
+ gl_info->limits.arb_ps_float_constants = 0;
+ gl_info->limits.arb_ps_local_constants = 0;
+ gl_info->limits.arb_ps_instructions = 0;
+ gl_info->limits.arb_ps_temps = 0;
+
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
+ gl_info->limits.clipplanes = min(WINED3DMAXUSERCLIPPLANES, gl_max);
+ TRACE("Clip plane support - max planes %d.\n", gl_max);
+
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
+ gl_info->limits.lights = gl_max;
+ TRACE("Light support - max lights %d.\n", gl_max);
+
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max);
+ gl_info->limits.texture_size = gl_max;
+ TRACE("Maximum texture size support - max texture size %d.\n", gl_max);
+
+ gl_info->gl_ops.gl.p_glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, gl_floatv);
+ gl_info->limits.pointsize_min = gl_floatv[0];
+ gl_info->limits.pointsize_max = gl_floatv[1];
+ TRACE("Maximum point size support - max point size %f.\n", gl_floatv[1]);
+
+ if (gl_info->supported[ARB_MAP_BUFFER_ALIGNMENT])
+ {
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MIN_MAP_BUFFER_ALIGNMENT, &gl_max);
+ TRACE("Minimum buffer map alignment: %d.\n", gl_max);
+ }
+ else
+ {
+ WARN_(d3d_perf)("Driver doesn't guarantee a minimum buffer map alignment.\n");
+ }
+ if (gl_info->supported[NV_REGISTER_COMBINERS])
+ {
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &gl_max);
+ gl_info->limits.general_combiners = gl_max;
+ TRACE("Max general combiners: %d.\n", gl_max);
+ }
+ if (gl_info->supported[ARB_DRAW_BUFFERS] && wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max);
+ gl_info->limits.buffers = gl_max;
+ TRACE("Max draw buffers: %u.\n", gl_max);
+ }
+ if (gl_info->supported[ARB_MULTITEXTURE])
+ {
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
+ gl_info->limits.textures = min(MAX_TEXTURES, gl_max);
+ TRACE("Max textures: %d.\n", gl_info->limits.textures);
+
+ if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
+ {
+ GLint tmp;
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_COORDS_ARB, &gl_max);
+ gl_info->limits.texture_coords = min(MAX_TEXTURES, gl_max);
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
+ gl_info->limits.fragment_samplers = min(MAX_FRAGMENT_SAMPLERS, tmp);
+ }
+ else
+ {
+ gl_info->limits.texture_coords = max(gl_info->limits.texture_coords, gl_max);
+ gl_info->limits.fragment_samplers = max(gl_info->limits.fragment_samplers, gl_max);
+ }
+ TRACE("Max texture coords: %d.\n", gl_info->limits.texture_coords);
+ TRACE("Max fragment samplers: %d.\n", gl_info->limits.fragment_samplers);
+
+ if (gl_info->supported[ARB_VERTEX_SHADER])
+ {
+ GLint tmp;
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
+ gl_info->limits.vertex_samplers = tmp;
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &tmp);
+ gl_info->limits.combined_samplers = tmp;
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &tmp);
+ gl_info->limits.vertex_attribs = tmp;
+
+ /* Loading GLSL sampler uniforms is much simpler if we can assume that the sampler setup
+ * is known at shader link time. In a vertex shader + pixel shader combination this isn't
+ * an issue because then the sampler setup only depends on the two shaders. If a pixel
+ * shader is used with fixed function vertex processing we're fine too because fixed function
+ * vertex processing doesn't use any samplers. If fixed function fragment processing is
+ * used we have to make sure that all vertex sampler setups are valid together with all
+ * possible fixed function fragment processing setups. This is true if vsamplers + MAX_TEXTURES
+ * <= max_samplers. This is true on all d3d9 cards that support vtf(gf 6 and gf7 cards).
+ * dx9 radeon cards do not support vertex texture fetch. DX10 cards have 128 samplers, and
+ * dx9 is limited to 8 fixed function texture stages and 4 vertex samplers. DX10 does not have
+ * a fixed function pipeline anymore.
+ *
+ * So this is just a check to check that our assumption holds true. If not, write a warning
+ * and reduce the number of vertex samplers or probably disable vertex texture fetch. */
+ if (gl_info->limits.vertex_samplers && gl_info->limits.combined_samplers < 12
+ && MAX_TEXTURES + gl_info->limits.vertex_samplers > gl_info->limits.combined_samplers)
+ {
+ FIXME("OpenGL implementation supports %u vertex samplers and %u total samplers.\n",
+ gl_info->limits.vertex_samplers, gl_info->limits.combined_samplers);
+ FIXME("Expected vertex samplers + MAX_TEXTURES(=8) > combined_samplers.\n");
+ if (gl_info->limits.combined_samplers > MAX_TEXTURES)
+ gl_info->limits.vertex_samplers = gl_info->limits.combined_samplers - MAX_TEXTURES;
+ else
+ gl_info->limits.vertex_samplers = 0;
+ }
+ }
+ else
+ {
+ gl_info->limits.combined_samplers = gl_info->limits.fragment_samplers;
+ }
+ TRACE("Max vertex samplers: %u.\n", gl_info->limits.vertex_samplers);
+ TRACE("Max combined samplers: %u.\n", gl_info->limits.combined_samplers);
+ }
+ if (gl_info->supported[ARB_VERTEX_BLEND])
+ {
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
+ gl_info->limits.blends = gl_max;
+ TRACE("Max blends: %u.\n", gl_info->limits.blends);
+ }
+ if (gl_info->supported[EXT_TEXTURE3D])
+ {
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max);
+ gl_info->limits.texture3d_size = gl_max;
+ TRACE("Max texture3D size: %d.\n", gl_info->limits.texture3d_size);
+ }
+ if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
+ {
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max);
+ gl_info->limits.anisotropy = gl_max;
+ TRACE("Max anisotropy: %d.\n", gl_info->limits.anisotropy);
+ }
+ if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
+ {
+ GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
+ gl_info->limits.arb_ps_float_constants = gl_max;
+ TRACE("Max ARB_FRAGMENT_PROGRAM float constants: %d.\n", gl_info->limits.arb_ps_float_constants);
+ GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max));
+ gl_info->limits.arb_ps_native_constants = gl_max;
+ TRACE("Max ARB_FRAGMENT_PROGRAM native float constants: %d.\n",
+ gl_info->limits.arb_ps_native_constants);
+ GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
+ gl_info->limits.arb_ps_temps = gl_max;
+ TRACE("Max ARB_FRAGMENT_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_ps_temps);
+ GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
+ gl_info->limits.arb_ps_instructions = gl_max;
+ TRACE("Max ARB_FRAGMENT_PROGRAM native instructions: %d.\n", gl_info->limits.arb_ps_instructions);
+ GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &gl_max));
+ gl_info->limits.arb_ps_local_constants = gl_max;
+ TRACE("Max ARB_FRAGMENT_PROGRAM local parameters: %d.\n", gl_info->limits.arb_ps_instructions);
+ }
+ if (gl_info->supported[ARB_VERTEX_PROGRAM])
+ {
+ GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
+ gl_info->limits.arb_vs_float_constants = gl_max;
+ TRACE("Max ARB_VERTEX_PROGRAM float constants: %d.\n", gl_info->limits.arb_vs_float_constants);
+ GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max));
+ gl_info->limits.arb_vs_native_constants = gl_max;
+ TRACE("Max ARB_VERTEX_PROGRAM native float constants: %d.\n",
+ gl_info->limits.arb_vs_native_constants);
+ GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
+ gl_info->limits.arb_vs_temps = gl_max;
+ TRACE("Max ARB_VERTEX_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_vs_temps);
+ GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
+ gl_info->limits.arb_vs_instructions = gl_max;
+ TRACE("Max ARB_VERTEX_PROGRAM native instructions: %d.\n", gl_info->limits.arb_vs_instructions);
+ }
+ if (gl_info->supported[ARB_VERTEX_SHADER])
+ {
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max);
+ gl_info->limits.glsl_vs_float_constants = gl_max / 4;
+ TRACE("Max ARB_VERTEX_SHADER float constants: %u.\n", gl_info->limits.glsl_vs_float_constants);
+#ifdef VBOX_WITH_WDDM
+ /* AFAICT the " / 4" here comes from that we're going to use the glsl_vs/ps_float_constants to create vec4 arrays,
+ * thus each array element has 4 components, so the actual number of vec4 arrays is GL_MAX_VERTEX/FRAGMENT_UNIFORM_COMPONENTS_ARB / 4
+ * win8 Aero won't properly work with this constant < 256 in any way,
+ * while Intel drivers I've encountered this problem with supports vec4 arrays of size > GL_MAX_VERTEX/FRAGMENT_UNIFORM_COMPONENTS_ARB / 4
+ * so use it here.
+ * @todo: add logging
+ * @todo: perhaps should be movet to quirks?
+ * */
+ if (gl_info->limits.glsl_vs_float_constants < 256 && gl_max >= 256)
+ {
+ DWORD dwVersion = GetVersion();
+ DWORD dwMajor = (DWORD)(LOBYTE(LOWORD(dwVersion)));
+ DWORD dwMinor = (DWORD)(HIBYTE(LOWORD(dwVersion)));
+ /* tmp workaround Win8 Aero requirement for 256 */
+ if (dwMajor > 6 || dwMinor > 1)
+ {
+ gl_info->limits.glsl_vs_float_constants = 256;
+ }
+ }
+#endif
+ }
+ if (gl_info->supported[ARB_FRAGMENT_SHADER])
+ {
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max);
+ gl_info->limits.glsl_ps_float_constants = gl_max / 4;
+ TRACE("Max ARB_FRAGMENT_SHADER float constants: %u.\n", gl_info->limits.glsl_ps_float_constants);
+#ifdef VBOX_WITH_WDDM
+ /* AFAICT the " / 4" here comes from that we're going to use the glsl_vs/ps_float_constants to create vec4 arrays,
+ * thus each array element has 4 components, so the actual number of vec4 arrays is GL_MAX_VERTEX/FRAGMENT_UNIFORM_COMPONENTS_ARB / 4
+ * win8 Aero won't properly work with this constant < 256 in any way,
+ * while Intel drivers I've encountered this problem with supports vec4 arrays of size > GL_MAX_VERTEX/FRAGMENT_UNIFORM_COMPONENTS_ARB / 4
+ * so use it here.
+ * @todo: add logging
+ * @todo: perhaps should be movet to quirks?
+ * */
+ if (gl_info->limits.glsl_ps_float_constants < 256 && gl_max >= 256)
+ {
+ DWORD dwVersion = GetVersion();
+ DWORD dwMajor = (DWORD)(LOBYTE(LOWORD(dwVersion)));
+ DWORD dwMinor = (DWORD)(HIBYTE(LOWORD(dwVersion)));
+ /* tmp workaround Win8 Aero requirement for 256 */
+ if (dwMajor > 6 || dwMinor > 1)
+ {
+ gl_info->limits.glsl_ps_float_constants = 256;
+ }
+ }
+#endif
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max);
+ gl_info->limits.glsl_varyings = gl_max;
+ TRACE("Max GLSL varyings: %u (%u 4 component varyings).\n", gl_max, gl_max / 4);
+ }
+
+ if (gl_info->supported[NV_LIGHT_MAX_EXPONENT])
+ gl_info->gl_ops.gl.p_glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->limits.shininess);
+ else
+ gl_info->limits.shininess = 128.0f;
+
+ if ((gl_info->supported[ARB_FRAMEBUFFER_OBJECT] || gl_info->supported[EXT_FRAMEBUFFER_MULTISAMPLE])
+ && wined3d_settings.allow_multisampling)
+ {
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_SAMPLES, &gl_max);
+ gl_info->limits.samples = gl_max;
+ }
+}
+
+/* Context activation is done by the caller. */
+static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
+{
+ struct wined3d_driver_info *driver_info = &adapter->driver_info;
+ const char *gl_vendor_str, *gl_renderer_str, *gl_version_str;
+ struct wined3d_gl_info *gl_info = &adapter->gl_info;
+ struct wined3d_vertex_caps vertex_caps;
+ enum wined3d_pci_vendor card_vendor;
+ struct fragment_caps fragment_caps;
+ struct shader_caps shader_caps;
+ const char *WGL_Extensions = NULL;
+ const char *GL_Extensions = NULL;
+ enum wined3d_gl_vendor gl_vendor;
+ enum wined3d_pci_device device;
+ DWORD gl_version;
+ HDC hdc;
+ unsigned int i;
+
+ TRACE("adapter %p.\n", adapter);
+
+ gl_renderer_str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_RENDERER);
+ TRACE("GL_RENDERER: %s.\n", debugstr_a(gl_renderer_str));
+ if (!gl_renderer_str)
+ {
+ ERR("Received a NULL GL_RENDERER.\n");
+ return FALSE;
+ }
+
+ gl_vendor_str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_VENDOR);
+ TRACE("GL_VENDOR: %s.\n", debugstr_a(gl_vendor_str));
+ if (!gl_vendor_str)
+ {
+ ERR("Received a NULL GL_VENDOR.\n");
+ return FALSE;
+ }
+
+ /* Parse the GL_VERSION field into major and minor information */
+ gl_version_str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_VERSION);
+ TRACE("GL_VERSION: %s.\n", debugstr_a(gl_version_str));
+ if (!gl_version_str)
+ {
+ ERR("Received a NULL GL_VERSION.\n");
+ return FALSE;
+ }
+ gl_version = wined3d_parse_gl_version(gl_version_str);
+
+ /* Parse the gl supported features, in theory enabling parts of our code appropriately. */
+ GL_Extensions = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_EXTENSIONS);
+ if (!GL_Extensions)
+ {
+ ERR("Received a NULL GL_EXTENSIONS.\n");
+ return FALSE;
+ }
+
+ memset(gl_info->supported, 0, sizeof(gl_info->supported));
+ gl_info->supported[WINED3D_GL_EXT_NONE] = TRUE;
+
+ TRACE("GL extensions reported:\n");
+ parse_extension_string(gl_info, GL_Extensions, gl_extension_map,
+ sizeof(gl_extension_map) / sizeof(*gl_extension_map));
+
+ /* Now work out what GL support this card really has. */
+ load_gl_funcs( gl_info );
+
+ hdc = wglGetCurrentDC();
+ /* Not all GL drivers might offer WGL extensions e.g. VirtualBox. */
+ if (GL_EXTCALL(wglGetExtensionsStringARB))
+ WGL_Extensions = (const char *)GL_EXTCALL(wglGetExtensionsStringARB(hdc));
+ if (!WGL_Extensions)
+ WARN("WGL extensions not supported.\n");
+ else
+ parse_extension_string(gl_info, WGL_Extensions, wgl_extension_map,
+ sizeof(wgl_extension_map) / sizeof(*wgl_extension_map));
+
+ if (!gl_info->supported[EXT_TEXTURE3D] && gl_version >= MAKEDWORD_VERSION(1, 2))
+ {
+ TRACE("GL CORE: GL_EXT_texture3D support.\n");
+ gl_info->gl_ops.ext.p_glTexImage3DEXT = (void *)gl_info->gl_ops.ext.p_glTexImage3D;
+ gl_info->gl_ops.ext.p_glTexSubImage3DEXT = gl_info->gl_ops.ext.p_glTexSubImage3D;
+ gl_info->supported[EXT_TEXTURE3D] = TRUE;
+ }
+
+ if (!gl_info->supported[NV_POINT_SPRITE] && gl_version >= MAKEDWORD_VERSION(1, 4))
+ {
+ TRACE("GL CORE: GL_NV_point_sprite support.\n");
+ gl_info->gl_ops.ext.p_glPointParameterivNV = gl_info->gl_ops.ext.p_glPointParameteriv;
+ gl_info->gl_ops.ext.p_glPointParameteriNV = gl_info->gl_ops.ext.p_glPointParameteri;
+ gl_info->supported[NV_POINT_SPRITE] = TRUE;
+ }
+
+ if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && gl_version >= MAKEDWORD_VERSION(2, 0))
+ {
+ TRACE("GL CORE: GL_ARB_texture_non_power_of_two support.\n");
+ gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = TRUE;
+ }
+
+ if (gl_version >= MAKEDWORD_VERSION(2, 0)) gl_info->supported[WINED3D_GL_VERSION_2_0] = TRUE;
+
+ if (gl_info->supported[APPLE_FENCE])
+ {
+ /* GL_NV_fence and GL_APPLE_fence provide the same functionality basically.
+ * The apple extension interacts with some other apple exts. Disable the NV
+ * extension if the apple one is support to prevent confusion in other parts
+ * of the code. */
+ gl_info->supported[NV_FENCE] = FALSE;
+ }
+ if (gl_info->supported[APPLE_FLOAT_PIXELS])
+ {
+ /* GL_APPLE_float_pixels == GL_ARB_texture_float + GL_ARB_half_float_pixel
+ *
+ * The enums are the same:
+ * GL_RGBA16F_ARB = GL_RGBA_FLOAT16_APPLE = 0x881a
+ * GL_RGB16F_ARB = GL_RGB_FLOAT16_APPLE = 0x881b
+ * GL_RGBA32F_ARB = GL_RGBA_FLOAT32_APPLE = 0x8814
+ * GL_RGB32F_ARB = GL_RGB_FLOAT32_APPLE = 0x8815
+ * GL_HALF_FLOAT_ARB = GL_HALF_APPLE = 0x140b
+ */
+ if (!gl_info->supported[ARB_TEXTURE_FLOAT])
+ {
+ TRACE(" IMPLIED: GL_ARB_texture_float support (by GL_APPLE_float_pixels).\n");
+ gl_info->supported[ARB_TEXTURE_FLOAT] = TRUE;
+ }
+ if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL])
+ {
+ TRACE(" IMPLIED: GL_ARB_half_float_pixel support (by GL_APPLE_float_pixels).\n");
+ gl_info->supported[ARB_HALF_FLOAT_PIXEL] = TRUE;
+ }
+ }
+ if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
+ {
+ /* GL_ARB_map_buffer_range and GL_APPLE_flush_buffer_range provide the same
+ * functionality. Prefer the ARB extension */
+ gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] = FALSE;
+ }
+ if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+ {
+ TRACE(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support.\n");
+ gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE;
+ }
+ if (!gl_info->supported[ARB_DEPTH_CLAMP] && gl_info->supported[NV_DEPTH_CLAMP])
+ {
+ TRACE(" IMPLIED: ARB_depth_clamp support (by NV_depth_clamp).\n");
+ gl_info->supported[ARB_DEPTH_CLAMP] = TRUE;
+ }
+ if (!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] && gl_info->supported[EXT_VERTEX_ARRAY_BGRA])
+ {
+ TRACE(" IMPLIED: ARB_vertex_array_bgra support (by EXT_vertex_array_bgra).\n");
+ gl_info->supported[ARB_VERTEX_ARRAY_BGRA] = TRUE;
+ }
+ if (!gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] && gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
+ {
+ TRACE(" IMPLIED: ARB_texture_compression_rgtc support (by EXT_texture_compression_rgtc).\n");
+ gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] = TRUE;
+ }
+ if (gl_info->supported[NV_TEXTURE_SHADER2])
+ {
+ if (gl_info->supported[NV_REGISTER_COMBINERS])
+ {
+ /* Also disable ATI_FRAGMENT_SHADER if register combiners and texture_shader2
+ * are supported. The nv extensions provide the same functionality as the
+ * ATI one, and a bit more(signed pixelformats). */
+ gl_info->supported[ATI_FRAGMENT_SHADER] = FALSE;
+ }
+ }
+ if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
+ {
+ /* If we have full NP2 texture support, disable
+ * GL_ARB_texture_rectangle because we will never use it.
+ * This saves a few redundant glDisable calls. */
+ gl_info->supported[ARB_TEXTURE_RECTANGLE] = FALSE;
+ }
+ if (gl_info->supported[ATI_FRAGMENT_SHADER])
+ {
+ /* Disable NV_register_combiners and fragment shader if this is supported.
+ * generally the NV extensions are preferred over the ATI ones, and this
+ * extension is disabled if register_combiners and texture_shader2 are both
+ * supported. So we reach this place only if we have incomplete NV dxlevel 8
+ * fragment processing support. */
+ gl_info->supported[NV_REGISTER_COMBINERS] = FALSE;
+ gl_info->supported[NV_REGISTER_COMBINERS2] = FALSE;
+ gl_info->supported[NV_TEXTURE_SHADER] = FALSE;
+ gl_info->supported[NV_TEXTURE_SHADER2] = FALSE;
+ }
+ if (gl_info->supported[NV_HALF_FLOAT])
+ {
+ /* GL_ARB_half_float_vertex is a subset of GL_NV_half_float. */
+ gl_info->supported[ARB_HALF_FLOAT_VERTEX] = TRUE;
+ }
+ if (gl_info->supported[ARB_FRAMEBUFFER_SRGB] && !gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
+ {
+ /* Current wined3d sRGB infrastructure requires EXT_texture_sRGB_decode
+ * for GL_ARB_framebuffer_sRGB support (without EXT_texture_sRGB_decode
+ * we never render to sRGB surfaces). */
+ gl_info->supported[ARB_FRAMEBUFFER_SRGB] = FALSE;
+ }
+ if (gl_info->supported[ARB_OCCLUSION_QUERY])
+ {
+ GLint counter_bits;
+
+ GL_EXTCALL(glGetQueryivARB(GL_SAMPLES_PASSED_ARB, GL_QUERY_COUNTER_BITS_ARB, &counter_bits));
+ TRACE("Occlusion query counter has %d bits.\n", counter_bits);
+ if (!counter_bits)
+ gl_info->supported[ARB_OCCLUSION_QUERY] = FALSE;
+ }
+
+ wined3d_adapter_init_limits(gl_info);
+
+ if (gl_info->supported[ARB_VERTEX_PROGRAM] && test_arb_vs_offset_limit(gl_info))
+ gl_info->quirks |= WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT;
+
+ if (gl_info->supported[ARB_SHADING_LANGUAGE_100])
+ {
+ const char *str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_SHADING_LANGUAGE_VERSION_ARB);
+ unsigned int major, minor;
+
+ TRACE("GLSL version string: %s.\n", debugstr_a(str));
+
+ /* The format of the GLSL version string is "major.minor[.release] [vendor info]". */
+ sscanf(str, "%u.%u", &major, &minor);
+ gl_info->glsl_version = MAKEDWORD_VERSION(major, minor);
+ }
+
+ checkGLcall("extension detection");
+
+ adapter->shader_backend = select_shader_backend(gl_info);
+ adapter->vertex_pipe = select_vertex_implementation(gl_info, adapter->shader_backend);
+ adapter->fragment_pipe = select_fragment_implementation(gl_info, adapter->shader_backend);
+ adapter->blitter = select_blit_implementation(gl_info, adapter->shader_backend);
+
+ adapter->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
+ adapter->d3d_info.vs_clipping = shader_caps.wined3d_caps & WINED3D_SHADER_CAP_VS_CLIPPING;
+ adapter->d3d_info.limits.vs_version = shader_caps.vs_version;
+ adapter->d3d_info.limits.gs_version = shader_caps.gs_version;
+ adapter->d3d_info.limits.ps_version = shader_caps.ps_version;
+ adapter->d3d_info.limits.vs_uniform_count = shader_caps.vs_uniform_count;
+ adapter->d3d_info.limits.ps_uniform_count = shader_caps.ps_uniform_count;
+
+ adapter->vertex_pipe->vp_get_caps(gl_info, &vertex_caps);
+ adapter->d3d_info.xyzrhw = vertex_caps.xyzrhw;
+
+ adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
+ adapter->d3d_info.limits.ffp_blend_stages = fragment_caps.MaxTextureBlendStages;
+ adapter->d3d_info.limits.ffp_textures = fragment_caps.MaxSimultaneousTextures;
+ TRACE("Max texture stages: %u.\n", adapter->d3d_info.limits.ffp_blend_stages);
+
+ if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
+ {
+ gl_info->fbo_ops.glIsRenderbuffer = gl_info->gl_ops.ext.p_glIsRenderbuffer;
+ gl_info->fbo_ops.glBindRenderbuffer = gl_info->gl_ops.ext.p_glBindRenderbuffer;
+ gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->gl_ops.ext.p_glDeleteRenderbuffers;
+ gl_info->fbo_ops.glGenRenderbuffers = gl_info->gl_ops.ext.p_glGenRenderbuffers;
+ gl_info->fbo_ops.glRenderbufferStorage = gl_info->gl_ops.ext.p_glRenderbufferStorage;
+ gl_info->fbo_ops.glRenderbufferStorageMultisample = gl_info->gl_ops.ext.p_glRenderbufferStorageMultisample;
+ gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->gl_ops.ext.p_glGetRenderbufferParameteriv;
+ gl_info->fbo_ops.glIsFramebuffer = gl_info->gl_ops.ext.p_glIsFramebuffer;
+ gl_info->fbo_ops.glBindFramebuffer = gl_info->gl_ops.ext.p_glBindFramebuffer;
+ gl_info->fbo_ops.glDeleteFramebuffers = gl_info->gl_ops.ext.p_glDeleteFramebuffers;
+ gl_info->fbo_ops.glGenFramebuffers = gl_info->gl_ops.ext.p_glGenFramebuffers;
+ gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->gl_ops.ext.p_glCheckFramebufferStatus;
+ gl_info->fbo_ops.glFramebufferTexture1D = gl_info->gl_ops.ext.p_glFramebufferTexture1D;
+ gl_info->fbo_ops.glFramebufferTexture2D = gl_info->gl_ops.ext.p_glFramebufferTexture2D;
+ gl_info->fbo_ops.glFramebufferTexture3D = gl_info->gl_ops.ext.p_glFramebufferTexture3D;
+ gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->gl_ops.ext.p_glFramebufferRenderbuffer;
+ gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv
+ = gl_info->gl_ops.ext.p_glGetFramebufferAttachmentParameteriv;
+ gl_info->fbo_ops.glBlitFramebuffer = gl_info->gl_ops.ext.p_glBlitFramebuffer;
+ gl_info->fbo_ops.glGenerateMipmap = gl_info->gl_ops.ext.p_glGenerateMipmap;
+ }
+ else
+ {
+ if (gl_info->supported[EXT_FRAMEBUFFER_OBJECT])
+ {
+ gl_info->fbo_ops.glIsRenderbuffer = gl_info->gl_ops.ext.p_glIsRenderbufferEXT;
+ gl_info->fbo_ops.glBindRenderbuffer = gl_info->gl_ops.ext.p_glBindRenderbufferEXT;
+ gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->gl_ops.ext.p_glDeleteRenderbuffersEXT;
+ gl_info->fbo_ops.glGenRenderbuffers = gl_info->gl_ops.ext.p_glGenRenderbuffersEXT;
+ gl_info->fbo_ops.glRenderbufferStorage = gl_info->gl_ops.ext.p_glRenderbufferStorageEXT;
+ gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->gl_ops.ext.p_glGetRenderbufferParameterivEXT;
+ gl_info->fbo_ops.glIsFramebuffer = gl_info->gl_ops.ext.p_glIsFramebufferEXT;
+ gl_info->fbo_ops.glBindFramebuffer = gl_info->gl_ops.ext.p_glBindFramebufferEXT;
+ gl_info->fbo_ops.glDeleteFramebuffers = gl_info->gl_ops.ext.p_glDeleteFramebuffersEXT;
+ gl_info->fbo_ops.glGenFramebuffers = gl_info->gl_ops.ext.p_glGenFramebuffersEXT;
+ gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->gl_ops.ext.p_glCheckFramebufferStatusEXT;
+ gl_info->fbo_ops.glFramebufferTexture1D = gl_info->gl_ops.ext.p_glFramebufferTexture1DEXT;
+ gl_info->fbo_ops.glFramebufferTexture2D = gl_info->gl_ops.ext.p_glFramebufferTexture2DEXT;
+ gl_info->fbo_ops.glFramebufferTexture3D = gl_info->gl_ops.ext.p_glFramebufferTexture3DEXT;
+ gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->gl_ops.ext.p_glFramebufferRenderbufferEXT;
+ gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv
+ = gl_info->gl_ops.ext.p_glGetFramebufferAttachmentParameterivEXT;
+ gl_info->fbo_ops.glGenerateMipmap = gl_info->gl_ops.ext.p_glGenerateMipmapEXT;
+ }
+ else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ WARN_(d3d_perf)("Framebuffer objects not supported, falling back to backbuffer offscreen rendering mode.\n");
+ wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
+ }
+ if (gl_info->supported[EXT_FRAMEBUFFER_BLIT])
+ {
+ gl_info->fbo_ops.glBlitFramebuffer = gl_info->gl_ops.ext.p_glBlitFramebufferEXT;
+ }
+ if (gl_info->supported[EXT_FRAMEBUFFER_MULTISAMPLE])
+ {
+ gl_info->fbo_ops.glRenderbufferStorageMultisample
+ = gl_info->gl_ops.ext.p_glRenderbufferStorageMultisampleEXT;
+ }
+ }
+
+ gl_vendor = wined3d_guess_gl_vendor(gl_info, gl_vendor_str, gl_renderer_str);
+ card_vendor = wined3d_guess_card_vendor(gl_vendor_str, gl_renderer_str);
+ TRACE("Found GL_VENDOR (%s)->(0x%04x/0x%04x).\n", debugstr_a(gl_vendor_str), gl_vendor, card_vendor);
+
+ device = wined3d_guess_card(gl_info, gl_renderer_str, &gl_vendor, &card_vendor);
+ TRACE("Found (fake) card: 0x%x (vendor id), 0x%x (device id).\n", card_vendor, device);
+
+ gl_info->wrap_lookup[WINED3D_TADDRESS_WRAP - WINED3D_TADDRESS_WRAP] = GL_REPEAT;
+ gl_info->wrap_lookup[WINED3D_TADDRESS_MIRROR - WINED3D_TADDRESS_WRAP] =
+ gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT] ? GL_MIRRORED_REPEAT_ARB : GL_REPEAT;
+ gl_info->wrap_lookup[WINED3D_TADDRESS_CLAMP - WINED3D_TADDRESS_WRAP] = GL_CLAMP_TO_EDGE;
+ gl_info->wrap_lookup[WINED3D_TADDRESS_BORDER - WINED3D_TADDRESS_WRAP] =
+ gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
+ gl_info->wrap_lookup[WINED3D_TADDRESS_MIRROR_ONCE - WINED3D_TADDRESS_WRAP] =
+ gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] ? GL_MIRROR_CLAMP_TO_EDGE_ATI : GL_REPEAT;
+
+ adapter->d3d_info.valid_rt_mask = 0;
+ for (i = 0; i < gl_info->limits.buffers; ++i)
+ adapter->d3d_info.valid_rt_mask |= (1 << i);
+
+ fixup_extensions(gl_info, gl_renderer_str, gl_vendor, card_vendor, device);
+ init_driver_info(driver_info, card_vendor, device);
+ add_gl_compat_wrappers(gl_info);
+
+ return TRUE;
+}
+
+UINT CDECL wined3d_get_adapter_count(const struct wined3d *wined3d)
+{
+ TRACE("wined3d %p, reporting %u adapters.\n",
+ wined3d, wined3d->adapter_count);
+
+ return wined3d->adapter_count;
+}
+
+HRESULT CDECL wined3d_register_software_device(struct wined3d *wined3d, void *init_function)
+{
+ FIXME("wined3d %p, init_function %p stub!\n", wined3d, init_function);
+
+ return WINED3D_OK;
+}
+
+HMONITOR CDECL wined3d_get_adapter_monitor(const struct wined3d *wined3d, UINT adapter_idx)
+{
+ TRACE("wined3d %p, adapter_idx %u.\n", wined3d, adapter_idx);
+
+ if (adapter_idx >= wined3d->adapter_count)
+ return NULL;
+
+ return MonitorFromPoint(wined3d->adapters[adapter_idx].monitorPoint, MONITOR_DEFAULTTOPRIMARY);
+}
+
+/* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
+ of the same bpp but different resolutions */
+
+/* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
+UINT CDECL wined3d_get_adapter_mode_count(const struct wined3d *wined3d, UINT adapter_idx,
+ enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering)
+{
+ const struct wined3d_adapter *adapter;
+ const struct wined3d_format *format;
+ unsigned int i = 0;
+ unsigned int j = 0;
+ UINT format_bits;
+ DEVMODEW mode;
+
+ TRACE("wined3d %p, adapter_idx %u, format %s, scanline_ordering %#x.\n",
+ wined3d, adapter_idx, debug_d3dformat(format_id), scanline_ordering);
+
+ if (adapter_idx >= wined3d->adapter_count)
+ return 0;
+
+ adapter = &wined3d->adapters[adapter_idx];
+ format = wined3d_get_format(&adapter->gl_info, format_id);
+ format_bits = format->byte_count * CHAR_BIT;
+
+ memset(&mode, 0, sizeof(mode));
+ mode.dmSize = sizeof(mode);
+
+ while (EnumDisplaySettingsExW(adapter->DeviceName, j++, &mode, 0))
+ {
+ if (mode.dmFields & DM_DISPLAYFLAGS)
+ {
+ if (scanline_ordering == WINED3D_SCANLINE_ORDERING_PROGRESSIVE
+#ifndef VBOX_WINE_WITHOUT_LIBWINE
+ && (mode.u2.dmDisplayFlags & DM_INTERLACED))
+#else
+ && (mode.dmDisplayFlags & DM_INTERLACED))
+#endif
+ continue;
+
+ if (scanline_ordering == WINED3D_SCANLINE_ORDERING_INTERLACED
+#ifndef VBOX_WINE_WITHOUT_LIBWINE
+ && !(mode.u2.dmDisplayFlags & DM_INTERLACED))
+#else
+ && !(mode.dmDisplayFlags & DM_INTERLACED))
+#endif
+ continue;
+ }
+
+ if (format_id == WINED3DFMT_UNKNOWN)
+ {
+ /* This is for d3d8, do not enumerate P8 here. */
+ if (mode.dmBitsPerPel == 32 || mode.dmBitsPerPel == 16) ++i;
+ }
+ else if (mode.dmBitsPerPel == format_bits)
+ {
+ ++i;
+ }
+ }
+
+ TRACE("Returning %u matching modes (out of %u total) for adapter %u.\n", i, j, adapter_idx);
+
+ return i;
+}
+
+/* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
+HRESULT CDECL wined3d_enum_adapter_modes(const struct wined3d *wined3d, UINT adapter_idx,
+ enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering,
+ UINT mode_idx, struct wined3d_display_mode *mode)
+{
+ const struct wined3d_adapter *adapter;
+ const struct wined3d_format *format;
+ UINT format_bits;
+ DEVMODEW m;
+ UINT i = 0;
+ int j = 0;
+
+ TRACE("wined3d %p, adapter_idx %u, format %s, scanline_ordering %#x, mode_idx %u, mode %p.\n",
+ wined3d, adapter_idx, debug_d3dformat(format_id), scanline_ordering, mode_idx, mode);
+
+ if (!mode || adapter_idx >= wined3d->adapter_count)
+ return WINED3DERR_INVALIDCALL;
+
+ adapter = &wined3d->adapters[adapter_idx];
+ format = wined3d_get_format(&adapter->gl_info, format_id);
+ format_bits = format->byte_count * CHAR_BIT;
+
+ memset(&m, 0, sizeof(m));
+ m.dmSize = sizeof(m);
+
+ while (i <= mode_idx)
+ {
+ if (!EnumDisplaySettingsExW(adapter->DeviceName, j++, &m, 0))
+ {
+ WARN("Invalid mode_idx %u.\n", mode_idx);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (m.dmFields & DM_DISPLAYFLAGS)
+ {
+ if (scanline_ordering == WINED3D_SCANLINE_ORDERING_PROGRESSIVE
+#ifndef VBOX_WINE_WITHOUT_LIBWINE
+ && (m.u2.dmDisplayFlags & DM_INTERLACED))
+#else
+ && (m.dmDisplayFlags & DM_INTERLACED))
+#endif
+ continue;
+
+ if (scanline_ordering == WINED3D_SCANLINE_ORDERING_INTERLACED
+#ifndef VBOX_WINE_WITHOUT_LIBWINE
+ && !(m.u2.dmDisplayFlags & DM_INTERLACED))
+#else
+ && !(m.dmDisplayFlags & DM_INTERLACED))
+#endif
+ continue;
+ }
+
+ if (format_id == WINED3DFMT_UNKNOWN)
+ {
+ /* This is for d3d8, do not enumerate P8 here. */
+ if (m.dmBitsPerPel == 32 || m.dmBitsPerPel == 16) ++i;
+ }
+ else if (m.dmBitsPerPel == format_bits)
+ {
+ ++i;
+ }
+ }
+
+ mode->width = m.dmPelsWidth;
+ mode->height = m.dmPelsHeight;
+ mode->refresh_rate = DEFAULT_REFRESH_RATE;
+ if (m.dmFields & DM_DISPLAYFREQUENCY)
+ mode->refresh_rate = m.dmDisplayFrequency;
+
+ if (format_id == WINED3DFMT_UNKNOWN)
+ mode->format_id = pixelformat_for_depth(m.dmBitsPerPel);
+ else
+ mode->format_id = format_id;
+
+ if (!(m.dmFields & DM_DISPLAYFLAGS))
+ mode->scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
+#ifndef VBOX_WINE_WITHOUT_LIBWINE
+ else if (m.u2.dmDisplayFlags & DM_INTERLACED)
+#else
+ else if (m.dmDisplayFlags & DM_INTERLACED)
+#endif
+ mode->scanline_ordering = WINED3D_SCANLINE_ORDERING_INTERLACED;
+ else
+ mode->scanline_ordering = WINED3D_SCANLINE_ORDERING_PROGRESSIVE;
+
+ TRACE("%ux%u@%u %u bpp, %s %#x.\n", mode->width, mode->height, mode->refresh_rate,
+ m.dmBitsPerPel, debug_d3dformat(mode->format_id), mode->scanline_ordering);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_get_adapter_display_mode(const struct wined3d *wined3d, UINT adapter_idx,
+ struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation)
+{
+ const struct wined3d_adapter *adapter;
+ DEVMODEW m;
+
+ TRACE("wined3d %p, adapter_idx %u, display_mode %p, rotation %p.\n",
+ wined3d, adapter_idx, mode, rotation);
+
+ if (!mode || adapter_idx >= wined3d->adapter_count)
+ return WINED3DERR_INVALIDCALL;
+
+ adapter = &wined3d->adapters[adapter_idx];
+
+ memset(&m, 0, sizeof(m));
+ m.dmSize = sizeof(m);
+
+ EnumDisplaySettingsExW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, &m, 0);
+ mode->width = m.dmPelsWidth;
+ mode->height = m.dmPelsHeight;
+ mode->refresh_rate = DEFAULT_REFRESH_RATE;
+ if (m.dmFields & DM_DISPLAYFREQUENCY)
+ mode->refresh_rate = m.dmDisplayFrequency;
+ mode->format_id = pixelformat_for_depth(m.dmBitsPerPel);
+
+ /* Lie about the format. X11 can't change the color depth, and some apps
+ * are pretty angry if they SetDisplayMode from 24 to 16 bpp and find out
+ * that GetDisplayMode still returns 24 bpp. This should probably be
+ * handled in winex11 instead. */
+ if (adapter->screen_format && adapter->screen_format != mode->format_id)
+ {
+ WARN("Overriding format %s with stored format %s.\n",
+ debug_d3dformat(mode->format_id),
+ debug_d3dformat(adapter->screen_format));
+ mode->format_id = adapter->screen_format;
+ }
+
+ if (!(m.dmFields & DM_DISPLAYFLAGS))
+ mode->scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
+#ifndef VBOX_WINE_WITHOUT_LIBWINE
+ else if (m.u2.dmDisplayFlags & DM_INTERLACED)
+#else
+ else if (m.dmDisplayFlags & DM_INTERLACED)
+#endif
+ mode->scanline_ordering = WINED3D_SCANLINE_ORDERING_INTERLACED;
+ else
+ mode->scanline_ordering = WINED3D_SCANLINE_ORDERING_PROGRESSIVE;
+
+ if (rotation)
+ {
+#ifndef VBOX_WINE_WITHOUT_LIBWINE
+ switch (m.u1.s2.dmDisplayOrientation)
+#else
+ switch (m.dmDisplayOrientation)
+#endif
+ {
+ case DMDO_DEFAULT:
+ *rotation = WINED3D_DISPLAY_ROTATION_0;
+ break;
+ case DMDO_90:
+ *rotation = WINED3D_DISPLAY_ROTATION_90;
+ break;
+ case DMDO_180:
+ *rotation = WINED3D_DISPLAY_ROTATION_180;
+ break;
+ case DMDO_270:
+ *rotation = WINED3D_DISPLAY_ROTATION_270;
+ break;
+ default:
+#ifndef VBOX_WINE_WITHOUT_LIBWINE
+ FIXME("Unhandled display rotation %#x.\n", m.u1.s2.dmDisplayOrientation);
+#else
+ FIXME("Unhandled display rotation %#x.\n", m.dmDisplayOrientation);
+#endif
+ *rotation = WINED3D_DISPLAY_ROTATION_UNSPECIFIED;
+ break;
+ }
+ }
+
+ TRACE("Returning %ux%u@%u %s %#x.\n", mode->width, mode->height,
+ mode->refresh_rate, debug_d3dformat(mode->format_id),
+ mode->scanline_ordering);
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_set_adapter_display_mode(struct wined3d *wined3d,
+ UINT adapter_idx, const struct wined3d_display_mode *mode)
+{
+ struct wined3d_display_mode current_mode;
+ const struct wined3d_format *format;
+ struct wined3d_adapter *adapter;
+ DEVMODEW devmode;
+ RECT clip_rc;
+ HRESULT hr;
+ LONG ret;
+
+ TRACE("wined3d %p, adapter_idx %u, mode %p (%ux%u@%u %s %#x).\n", wined3d, adapter_idx, mode,
+ mode->width, mode->height, mode->refresh_rate, debug_d3dformat(mode->format_id),
+ mode->scanline_ordering);
+
+ if (adapter_idx >= wined3d->adapter_count)
+ return WINED3DERR_INVALIDCALL;
+
+ adapter = &wined3d->adapters[adapter_idx];
+ format = wined3d_get_format(&adapter->gl_info, mode->format_id);
+
+ memset(&devmode, 0, sizeof(devmode));
+ devmode.dmSize = sizeof(devmode);
+ devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
+ devmode.dmBitsPerPel = format->byte_count * CHAR_BIT;
+ devmode.dmPelsWidth = mode->width;
+ devmode.dmPelsHeight = mode->height;
+
+ devmode.dmDisplayFrequency = mode->refresh_rate;
+ if (mode->refresh_rate)
+ devmode.dmFields |= DM_DISPLAYFREQUENCY;
+
+ if (mode->scanline_ordering != WINED3D_SCANLINE_ORDERING_UNKNOWN)
+ {
+ devmode.dmFields |= DM_DISPLAYFLAGS;
+ if (mode->scanline_ordering == WINED3D_SCANLINE_ORDERING_INTERLACED)
+#ifndef VBOX_WINE_WITHOUT_LIBWINE
+ devmode.u2.dmDisplayFlags |= DM_INTERLACED;
+#else
+ devmode.dmDisplayFlags |= DM_INTERLACED;
+#endif
+ }
+
+ /* Only change the mode if necessary. */
+ if (FAILED(hr = wined3d_get_adapter_display_mode(wined3d, adapter_idx, &current_mode, NULL)))
+ {
+ ERR("Failed to get current display mode, hr %#x.\n", hr);
+ }
+ else if (current_mode.width == mode->width
+ && current_mode.height == mode->height
+ && current_mode.format_id == mode->format_id
+ && (current_mode.refresh_rate == mode->refresh_rate
+ || !mode->refresh_rate)
+ && (current_mode.scanline_ordering == mode->scanline_ordering
+ || mode->scanline_ordering == WINED3D_SCANLINE_ORDERING_UNKNOWN))
+ {
+ TRACE("Skipping redundant mode setting call.\n");
+ return WINED3D_OK;
+ }
+
+ ret = ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL);
+ if (ret != DISP_CHANGE_SUCCESSFUL)
+ {
+ if (devmode.dmDisplayFrequency)
+ {
+ WARN("ChangeDisplaySettingsExW failed, trying without the refresh rate.\n");
+ devmode.dmFields &= ~DM_DISPLAYFREQUENCY;
+ devmode.dmDisplayFrequency = 0;
+ ret = ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL);
+ }
+ if (ret != DISP_CHANGE_SUCCESSFUL)
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ /* Store the new values. */
+ adapter->screen_format = mode->format_id;
+
+ /* And finally clip mouse to our screen. */
+ SetRect(&clip_rc, 0, 0, mode->width, mode->height);
+ ClipCursor(&clip_rc);
+
+ return WINED3D_OK;
+}
+
+/* NOTE: due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
+ and fields being inserted in the middle, a new structure is used in place */
+HRESULT CDECL wined3d_get_adapter_identifier(const struct wined3d *wined3d,
+ UINT adapter_idx, DWORD flags, struct wined3d_adapter_identifier *identifier)
+{
+#ifndef VBOX_WITH_WDDM
+ const struct wined3d_adapter *adapter;
+ size_t len;
+
+ TRACE("wined3d %p, adapter_idx %u, flags %#x, identifier %p.\n",
+ wined3d, adapter_idx, flags, identifier);
+
+ if (adapter_idx >= wined3d->adapter_count)
+ return WINED3DERR_INVALIDCALL;
+
+ adapter = &wined3d->adapters[adapter_idx];
+
+ if (identifier->driver_size)
+ {
+ const char *name = adapter->driver_info.name;
+ len = min(strlen(name), identifier->driver_size - 1);
+ memcpy(identifier->driver, name, len);
+ identifier->driver[len] = '\0';
+ }
+
+ if (identifier->description_size)
+ {
+ const char *description = adapter->driver_info.description;
+ len = min(strlen(description), identifier->description_size - 1);
+ memcpy(identifier->description, description, len);
+ identifier->description[len] = '\0';
+ }
+
+ /* Note that d3d8 doesn't supply a device name. */
+ if (identifier->device_name_size)
+ {
+ if (!WideCharToMultiByte(CP_ACP, 0, adapter->DeviceName, -1, identifier->device_name,
+ identifier->device_name_size, NULL, NULL))
+ {
+ ERR("Failed to convert device name, last error %#x.\n", GetLastError());
+ return WINED3DERR_INVALIDCALL;
+ }
+ }
+
+ identifier->driver_version.u.HighPart = adapter->driver_info.version_high;
+ identifier->driver_version.u.LowPart = adapter->driver_info.version_low;
+ identifier->vendor_id = adapter->driver_info.vendor;
+ identifier->device_id = adapter->driver_info.device;
+ identifier->subsystem_id = 0;
+ identifier->revision = 0;
+ memcpy(&identifier->device_identifier, &IID_D3DDEVICE_D3DUID, sizeof(identifier->device_identifier));
+ identifier->whql_level = (flags & WINED3DENUM_NO_WHQL_LEVEL) ? 0 : 1;
+ memcpy(&identifier->adapter_luid, &adapter->luid, sizeof(identifier->adapter_luid));
+ identifier->video_memory = adapter->TextureRam;
+
+ return WINED3D_OK;
+#else
+ ERR("not supported!");
+ return E_FAIL;
+#endif
+}
+
+HRESULT CDECL wined3d_get_adapter_raster_status(const struct wined3d *wined3d, UINT adapter_idx,
+ struct wined3d_raster_status *raster_status)
+{
+ LONGLONG freq_per_frame, freq_per_line;
+ LARGE_INTEGER counter, freq_per_sec;
+ struct wined3d_display_mode mode;
+ static UINT once;
+
+ if (!once++)
+ FIXME("wined3d %p, adapter_idx %u, raster_status %p semi-stub!\n",
+ wined3d, adapter_idx, raster_status);
+ else
+ WARN("wined3d %p, adapter_idx %u, raster_status %p semi-stub!\n",
+ wined3d, adapter_idx, raster_status);
+
+ /* Obtaining the raster status is a widely implemented but optional
+ * feature. When this method returns OK StarCraft 2 expects the
+ * raster_status->InVBlank value to actually change over time.
+ * And Endless Alice Crysis doesn't care even if this method fails.
+ * Thus this method returns OK and fakes raster_status by
+ * QueryPerformanceCounter. */
+
+ if (!QueryPerformanceCounter(&counter) || !QueryPerformanceFrequency(&freq_per_sec))
+ return WINED3DERR_INVALIDCALL;
+ if (FAILED(wined3d_get_adapter_display_mode(wined3d, adapter_idx, &mode, NULL)))
+ return WINED3DERR_INVALIDCALL;
+ if (mode.refresh_rate == DEFAULT_REFRESH_RATE)
+ mode.refresh_rate = 60;
+
+ freq_per_frame = freq_per_sec.QuadPart / mode.refresh_rate;
+ /* Assume 20 scan lines in the vertical blank. */
+ freq_per_line = freq_per_frame / (mode.height + 20);
+ raster_status->scan_line = (counter.QuadPart % freq_per_frame) / freq_per_line;
+ if (raster_status->scan_line < mode.height)
+ raster_status->in_vblank = FALSE;
+ else
+ {
+ raster_status->scan_line = 0;
+ raster_status->in_vblank = TRUE;
+ }
+
+ TRACE("Returning fake value, in_vblank %u, scan_line %u.\n",
+ raster_status->in_vblank, raster_status->scan_line);
+
+ return WINED3D_OK;
+}
+
+static BOOL wined3d_check_pixel_format_color(const struct wined3d_gl_info *gl_info,
+ const struct wined3d_pixel_format *cfg, const struct wined3d_format *format)
+{
+ BYTE redSize, greenSize, blueSize, alphaSize, colorBits;
+
+ /* Float formats need FBOs. If FBOs are used this function isn't called */
+ if (format->flags & WINED3DFMT_FLAG_FLOAT) return FALSE;
+
+ if(cfg->iPixelType == WGL_TYPE_RGBA_ARB) { /* Integer RGBA formats */
+ if (!getColorBits(format, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits))
+ {
+ ERR("Unable to check compatibility for format %s.\n", debug_d3dformat(format->id));
+ return FALSE;
+ }
+
+ if(cfg->redSize < redSize)
+ return FALSE;
+
+ if(cfg->greenSize < greenSize)
+ return FALSE;
+
+ if(cfg->blueSize < blueSize)
+ return FALSE;
+
+ if(cfg->alphaSize < alphaSize)
+ return FALSE;
+
+ return TRUE;
+ }
+
+ /* Probably a RGBA_float or color index mode */
+ return FALSE;
+}
+
+static BOOL wined3d_check_pixel_format_depth(const struct wined3d_gl_info *gl_info,
+ const struct wined3d_pixel_format *cfg, const struct wined3d_format *format)
+{
+ BYTE depthSize, stencilSize;
+ BOOL lockable = FALSE;
+
+ if (!getDepthStencilBits(format, &depthSize, &stencilSize))
+ {
+ ERR("Unable to check compatibility for format %s.\n", debug_d3dformat(format->id));
+ return FALSE;
+ }
+
+ /* Float formats need FBOs. If FBOs are used this function isn't called */
+ if (format->flags & WINED3DFMT_FLAG_FLOAT) return FALSE;
+
+ if ((format->id == WINED3DFMT_D16_LOCKABLE) || (format->id == WINED3DFMT_D32_FLOAT))
+ lockable = TRUE;
+
+ /* On some modern cards like the Geforce8/9 GLX doesn't offer some dephthstencil formats which D3D9 reports.
+ * We can safely report 'compatible' formats (e.g. D24 can be used for D16) as long as we aren't dealing with
+ * a lockable format. This also helps D3D <= 7 as they expect D16 which isn't offered without this on Geforce8 cards. */
+ if(!(cfg->depthSize == depthSize || (!lockable && cfg->depthSize > depthSize)))
+ return FALSE;
+
+ /* Some cards like Intel i915 ones only offer D24S8 but lots of games also need a format without stencil, so
+ * allow more stencil bits than requested. */
+ if(cfg->stencilSize < stencilSize)
+ return FALSE;
+
+ return TRUE;
+}
+
+HRESULT CDECL wined3d_check_depth_stencil_match(const struct wined3d *wined3d,
+ UINT adapter_idx, enum wined3d_device_type device_type, enum wined3d_format_id adapter_format_id,
+ enum wined3d_format_id render_target_format_id, enum wined3d_format_id depth_stencil_format_id)
+{
+ const struct wined3d_format *rt_format;
+ const struct wined3d_format *ds_format;
+ const struct wined3d_adapter *adapter;
+
+ TRACE("wined3d %p, adapter_idx %u, device_type %s,\n"
+ "adapter_format %s, render_target_format %s, depth_stencil_format %s.\n",
+ wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(adapter_format_id),
+ debug_d3dformat(render_target_format_id), debug_d3dformat(depth_stencil_format_id));
+
+ if (adapter_idx >= wined3d->adapter_count)
+ return WINED3DERR_INVALIDCALL;
+
+ adapter = &wined3d->adapters[adapter_idx];
+ rt_format = wined3d_get_format(&adapter->gl_info, render_target_format_id);
+ ds_format = wined3d_get_format(&adapter->gl_info, depth_stencil_format_id);
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ if ((rt_format->flags & WINED3DFMT_FLAG_RENDERTARGET)
+ && (ds_format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)))
+ {
+ TRACE("Formats match.\n");
+ return WINED3D_OK;
+ }
+ }
+ else
+ {
+ const struct wined3d_pixel_format *cfgs;
+ unsigned int cfg_count;
+ unsigned int i;
+
+ cfgs = adapter->cfgs;
+ cfg_count = adapter->cfg_count;
+ for (i = 0; i < cfg_count; ++i)
+ {
+ if (wined3d_check_pixel_format_color(&adapter->gl_info, &cfgs[i], rt_format)
+ && wined3d_check_pixel_format_depth(&adapter->gl_info, &cfgs[i], ds_format))
+ {
+ TRACE("Formats match.\n");
+ return WINED3D_OK;
+ }
+ }
+ }
+
+ TRACE("Unsupported format pair: %s and %s.\n",
+ debug_d3dformat(render_target_format_id),
+ debug_d3dformat(depth_stencil_format_id));
+
+ return WINED3DERR_NOTAVAILABLE;
+}
+
+HRESULT CDECL wined3d_check_device_multisample_type(const struct wined3d *wined3d, UINT adapter_idx,
+ enum wined3d_device_type device_type, enum wined3d_format_id surface_format_id, BOOL windowed,
+ enum wined3d_multisample_type multisample_type, DWORD *quality_levels)
+{
+ const struct wined3d_gl_info *gl_info;
+
+ TRACE("wined3d %p, adapter_idx %u, device_type %s, surface_format %s,\n"
+ "windowed %#x, multisample_type %#x, quality_levels %p.\n",
+ wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(surface_format_id),
+ windowed, multisample_type, quality_levels);
+
+ if (adapter_idx >= wined3d->adapter_count)
+ return WINED3DERR_INVALIDCALL;
+
+ gl_info = &wined3d->adapters[adapter_idx].gl_info;
+
+ if (multisample_type > gl_info->limits.samples)
+ {
+ TRACE("Returning not supported.\n");
+ if (quality_levels)
+ *quality_levels = 0;
+
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ if (quality_levels)
+ {
+ if (multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE)
+ /* FIXME: This is probably wrong. */
+ *quality_levels = gl_info->limits.samples;
+ else
+ *quality_levels = 1;
+ }
+
+ return WINED3D_OK;
+}
+
+/* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */
+static BOOL CheckDepthStencilCapability(const struct wined3d_adapter *adapter,
+ const struct wined3d_format *display_format, const struct wined3d_format *ds_format)
+{
+ /* Only allow depth/stencil formats */
+ if (!(ds_format->depth_size || ds_format->stencil_size)) return FALSE;
+
+ /* Blacklist formats not supported on Windows */
+ switch (ds_format->id)
+ {
+ case WINED3DFMT_S1_UINT_D15_UNORM: /* Breaks the shadowvol2 dx7 sdk sample */
+ case WINED3DFMT_S4X4_UINT_D24_UNORM:
+ TRACE("[FAILED] - not supported on windows.\n");
+ return FALSE;
+
+ default:
+ break;
+ }
+
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ /* With FBOs WGL limitations do not apply, but the format needs to be FBO attachable */
+ if (ds_format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) return TRUE;
+ }
+ else
+ {
+ unsigned int i;
+
+ /* Walk through all WGL pixel formats to find a match */
+ for (i = 0; i < adapter->cfg_count; ++i)
+ {
+ const struct wined3d_pixel_format *cfg = &adapter->cfgs[i];
+ if (wined3d_check_pixel_format_color(&adapter->gl_info, cfg, display_format)
+ && wined3d_check_pixel_format_depth(&adapter->gl_info, cfg, ds_format))
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/* Check the render target capabilities of a format */
+static BOOL CheckRenderTargetCapability(const struct wined3d_adapter *adapter,
+ const struct wined3d_format *adapter_format, const struct wined3d_format *check_format)
+{
+ /* Filter out non-RT formats */
+ if (!(check_format->flags & WINED3DFMT_FLAG_RENDERTARGET)) return FALSE;
+ if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER)
+ {
+ BYTE AdapterRed, AdapterGreen, AdapterBlue, AdapterAlpha, AdapterTotalSize;
+ BYTE CheckRed, CheckGreen, CheckBlue, CheckAlpha, CheckTotalSize;
+ const struct wined3d_pixel_format *cfgs = adapter->cfgs;
+ unsigned int i;
+
+ getColorBits(adapter_format, &AdapterRed, &AdapterGreen, &AdapterBlue, &AdapterAlpha, &AdapterTotalSize);
+ getColorBits(check_format, &CheckRed, &CheckGreen, &CheckBlue, &CheckAlpha, &CheckTotalSize);
+
+ /* In backbuffer mode the front and backbuffer share the same WGL pixelformat.
+ * The format must match in RGB, alpha is allowed to be different. (Only the backbuffer can have alpha) */
+ if (!((AdapterRed == CheckRed) && (AdapterGreen == CheckGreen) && (AdapterBlue == CheckBlue)))
+ {
+ TRACE("[FAILED]\n");
+ return FALSE;
+ }
+
+ /* Check if there is a WGL pixel format matching the requirements, the format should also be window
+ * drawable (not offscreen; e.g. Nvidia offers R5G6B5 for pbuffers even when X is running at 24bit) */
+ for (i = 0; i < adapter->cfg_count; ++i)
+ {
+ if (cfgs[i].windowDrawable
+ && wined3d_check_pixel_format_color(&adapter->gl_info, &cfgs[i], check_format))
+ {
+ TRACE("Pixel format %d is compatible with format %s.\n",
+ cfgs[i].iPixelFormat, debug_d3dformat(check_format->id));
+ return TRUE;
+ }
+ }
+ }
+ else if(wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ /* For now return TRUE for FBOs until we have some proper checks.
+ * Note that this function will only be called when the format is around for texturing. */
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static BOOL CheckSurfaceCapability(const struct wined3d_adapter *adapter,
+ const struct wined3d_format *adapter_format,
+ const struct wined3d_format *check_format, BOOL no3d)
+{
+ if (no3d)
+ {
+ switch (check_format->id)
+ {
+ case WINED3DFMT_B8G8R8_UNORM:
+ TRACE("[FAILED] - Not enumerated on Windows.\n");
+ return FALSE;
+ case WINED3DFMT_B8G8R8A8_UNORM:
+ case WINED3DFMT_B8G8R8X8_UNORM:
+ case WINED3DFMT_B5G6R5_UNORM:
+ case WINED3DFMT_B5G5R5X1_UNORM:
+ case WINED3DFMT_B5G5R5A1_UNORM:
+ case WINED3DFMT_B4G4R4A4_UNORM:
+ case WINED3DFMT_B2G3R3_UNORM:
+ case WINED3DFMT_A8_UNORM:
+ case WINED3DFMT_B2G3R3A8_UNORM:
+ case WINED3DFMT_B4G4R4X4_UNORM:
+ case WINED3DFMT_R10G10B10A2_UNORM:
+ case WINED3DFMT_R8G8B8A8_UNORM:
+ case WINED3DFMT_R8G8B8X8_UNORM:
+ case WINED3DFMT_R16G16_UNORM:
+ case WINED3DFMT_B10G10R10A2_UNORM:
+ case WINED3DFMT_R16G16B16A16_UNORM:
+ case WINED3DFMT_P8_UINT:
+ TRACE("[OK]\n");
+ return TRUE;
+ default:
+ TRACE("[FAILED] - Not available on GDI surfaces.\n");
+ return FALSE;
+ }
+ }
+
+ /* All formats that are supported for textures are supported for surfaces
+ * as well. */
+ if (check_format->flags & WINED3DFMT_FLAG_TEXTURE)
+ return TRUE;
+
+ /* All depth stencil formats are supported on surfaces */
+ if (CheckDepthStencilCapability(adapter, adapter_format, check_format)) return TRUE;
+
+ /* If opengl can't process the format natively, the blitter may be able to convert it */
+ if (adapter->blitter->blit_supported(&adapter->gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
+ NULL, WINED3D_POOL_DEFAULT, 0, check_format,
+ NULL, WINED3D_POOL_DEFAULT, 0, adapter_format))
+ {
+ TRACE("[OK]\n");
+ return TRUE;
+ }
+
+ /* Reject other formats */
+ TRACE("[FAILED]\n");
+ return FALSE;
+}
+
+/* OpenGL supports mipmapping on all formats. Wrapping is unsupported, but we
+ * have to report mipmapping so we cannot reject WRAPANDMIP. Tests show that
+ * Windows reports WRAPANDMIP on unfilterable surfaces as well, apparently to
+ * show that wrapping is supported. The lack of filtering will sort out the
+ * mipmapping capability anyway.
+ *
+ * For now lets report this on all formats, but in the future we may want to
+ * restrict it to some should applications need that. */
+HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT adapter_idx,
+ enum wined3d_device_type device_type, enum wined3d_format_id adapter_format_id, DWORD usage,
+ enum wined3d_resource_type resource_type, enum wined3d_format_id check_format_id)
+{
+ const struct wined3d_adapter *adapter = &wined3d->adapters[adapter_idx];
+ const struct wined3d_gl_info *gl_info = &adapter->gl_info;
+ const struct wined3d_format *adapter_format = wined3d_get_format(gl_info, adapter_format_id);
+ const struct wined3d_format *format = wined3d_get_format(gl_info, check_format_id);
+ DWORD format_flags = 0;
+ DWORD allowed_usage;
+
+ TRACE("wined3d %p, adapter_idx %u, device_type %s, adapter_format %s, usage %s, %s,\n"
+ "resource_type %s, check_format %s.\n",
+ wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(adapter_format_id),
+ debug_d3dusage(usage), debug_d3dusagequery(usage), debug_d3dresourcetype(resource_type),
+ debug_d3dformat(check_format_id));
+
+ if (adapter_idx >= wined3d->adapter_count)
+ return WINED3DERR_INVALIDCALL;
+
+ switch (resource_type)
+ {
+ case WINED3D_RTYPE_CUBE_TEXTURE:
+ if (!gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+ {
+ TRACE("[FAILED] - No cube texture support.\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ format_flags |= WINED3DFMT_FLAG_TEXTURE;
+ allowed_usage = WINED3DUSAGE_AUTOGENMIPMAP
+ | WINED3DUSAGE_DYNAMIC
+ | WINED3DUSAGE_RENDERTARGET
+ | WINED3DUSAGE_SOFTWAREPROCESSING
+ | WINED3DUSAGE_QUERY_FILTER
+ | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
+ | WINED3DUSAGE_QUERY_SRGBREAD
+ | WINED3DUSAGE_QUERY_SRGBWRITE
+ | WINED3DUSAGE_QUERY_VERTEXTEXTURE
+ | WINED3DUSAGE_QUERY_WRAPANDMIP;
+ break;
+
+ case WINED3D_RTYPE_SURFACE:
+ if (!CheckSurfaceCapability(adapter, adapter_format, format, wined3d->flags & WINED3D_NO3D))
+ {
+ TRACE("[FAILED] - Not supported for plain surfaces.\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ allowed_usage = WINED3DUSAGE_DEPTHSTENCIL
+ | WINED3DUSAGE_RENDERTARGET
+ | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
+ break;
+
+ case WINED3D_RTYPE_TEXTURE:
+ if ((usage & WINED3DUSAGE_DEPTHSTENCIL) && (format->flags & WINED3DFMT_FLAG_SHADOW)
+ && !gl_info->supported[ARB_SHADOW])
+ {
+ TRACE("[FAILED] - No shadow sampler support.\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ format_flags |= WINED3DFMT_FLAG_TEXTURE;
+ allowed_usage = WINED3DUSAGE_AUTOGENMIPMAP
+ | WINED3DUSAGE_DEPTHSTENCIL
+ | WINED3DUSAGE_DYNAMIC
+ | WINED3DUSAGE_RENDERTARGET
+ | WINED3DUSAGE_SOFTWAREPROCESSING
+ | WINED3DUSAGE_QUERY_FILTER
+ | WINED3DUSAGE_QUERY_LEGACYBUMPMAP
+ | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
+ | WINED3DUSAGE_QUERY_SRGBREAD
+ | WINED3DUSAGE_QUERY_SRGBWRITE
+ | WINED3DUSAGE_QUERY_VERTEXTEXTURE
+ | WINED3DUSAGE_QUERY_WRAPANDMIP;
+ break;
+
+ case WINED3D_RTYPE_VOLUME_TEXTURE:
+ case WINED3D_RTYPE_VOLUME:
+ /* Volume is to VolumeTexture what Surface is to Texture, but its
+ * usage caps are not documented. Most driver seem to offer
+ * (nearly) the same on Volume and VolumeTexture, so do that too. */
+ if (!gl_info->supported[EXT_TEXTURE3D])
+ {
+ TRACE("[FAILED] - No volume texture support.\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ /* Filter formats that need conversion; For one part, this
+ * conversion is unimplemented, and volume textures are huge, so
+ * it would be a big performance hit. Unless we hit an application
+ * needing one of those formats, don't advertize them to avoid
+ * leading applications into temptation. The windows drivers don't
+ * support most of those formats on volumes anyway. */
+ if (format->convert)
+ {
+ TRACE("[FAILED] - No converted formats on volumes.\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ /* The GL_EXT_texture_compression_s3tc spec requires that loading
+ * an s3tc compressed texture results in an error. While the D3D
+ * refrast does support s3tc volumes, at least the nvidia Windows
+ * driver does not, so we're free not to support this format. */
+ switch (check_format_id)
+ {
+ case WINED3DFMT_DXT1:
+ case WINED3DFMT_DXT2:
+ case WINED3DFMT_DXT3:
+ case WINED3DFMT_DXT4:
+ case WINED3DFMT_DXT5:
+ TRACE("[FAILED] - DXTn does not support 3D textures.\n");
+ return WINED3DERR_NOTAVAILABLE;
+
+ default:
+ /* Do nothing, continue with checking the format below */
+ break;
+ }
+
+ format_flags |= WINED3DFMT_FLAG_TEXTURE;
+ allowed_usage = WINED3DUSAGE_DYNAMIC
+ | WINED3DUSAGE_SOFTWAREPROCESSING
+ | WINED3DUSAGE_QUERY_FILTER
+ | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
+ | WINED3DUSAGE_QUERY_SRGBREAD
+ | WINED3DUSAGE_QUERY_SRGBWRITE
+ | WINED3DUSAGE_QUERY_VERTEXTEXTURE
+ | WINED3DUSAGE_QUERY_WRAPANDMIP;
+ break;
+
+ default:
+ FIXME("Unhandled resource type %s.\n", debug_d3dresourcetype(resource_type));
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ if ((usage & allowed_usage) != usage)
+ {
+ TRACE("Requested usage %#x, but resource type %s only allows %#x.\n",
+ usage, debug_d3dresourcetype(resource_type), allowed_usage);
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ if (usage & WINED3DUSAGE_QUERY_FILTER)
+ format_flags |= WINED3DFMT_FLAG_FILTERING;
+ if (usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
+ format_flags |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
+ if (usage & WINED3DUSAGE_QUERY_SRGBREAD)
+ format_flags |= WINED3DFMT_FLAG_SRGB_READ;
+ if (usage & WINED3DUSAGE_QUERY_SRGBWRITE)
+ format_flags |= WINED3DFMT_FLAG_SRGB_WRITE;
+ if (usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE)
+ format_flags |= WINED3DFMT_FLAG_VTF;
+ if (usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP)
+ format_flags |= WINED3DFMT_FLAG_BUMPMAP;
+
+ if ((format->flags & format_flags) != format_flags)
+ {
+ TRACE("Requested format flags %#x, but format %s only has %#x.\n",
+ format_flags, debug_d3dformat(check_format_id), format->flags);
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ if ((format_flags & WINED3DFMT_FLAG_TEXTURE) && (wined3d->flags & WINED3D_NO3D))
+ {
+ TRACE("Requested texturing support, but wined3d was created with WINED3D_NO3D.\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ if ((usage & WINED3DUSAGE_DEPTHSTENCIL)
+ && !CheckDepthStencilCapability(adapter, adapter_format, format))
+ {
+ TRACE("Requested WINED3DUSAGE_DEPTHSTENCIL, but format %s is not supported for depth / stencil buffers.\n",
+ debug_d3dformat(check_format_id));
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ if ((usage & WINED3DUSAGE_RENDERTARGET)
+ && !CheckRenderTargetCapability(adapter, adapter_format, format))
+ {
+ TRACE("Requested WINED3DUSAGE_RENDERTARGET, but format %s is not supported for render targets.\n",
+ debug_d3dformat(check_format_id));
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ if ((usage & WINED3DUSAGE_AUTOGENMIPMAP) && !gl_info->supported[SGIS_GENERATE_MIPMAP])
+ {
+ TRACE("No WINED3DUSAGE_AUTOGENMIPMAP support, returning WINED3DOK_NOAUTOGEN.\n");
+ return WINED3DOK_NOAUTOGEN;
+ }
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_check_device_format_conversion(const struct wined3d *wined3d, UINT adapter_idx,
+ enum wined3d_device_type device_type, enum wined3d_format_id src_format, enum wined3d_format_id dst_format)
+{
+ FIXME("wined3d %p, adapter_idx %u, device_type %s, src_format %s, dst_format %s stub!\n",
+ wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(src_format),
+ debug_d3dformat(dst_format));
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_check_device_type(const struct wined3d *wined3d, UINT adapter_idx,
+ enum wined3d_device_type device_type, enum wined3d_format_id display_format,
+ enum wined3d_format_id backbuffer_format, BOOL windowed)
+{
+ UINT mode_count;
+ HRESULT hr;
+
+ TRACE("wined3d %p, adapter_idx %u, device_type %s, display_format %s, backbuffer_format %s, windowed %#x.\n",
+ wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(display_format),
+ debug_d3dformat(backbuffer_format), windowed);
+
+ if (adapter_idx >= wined3d->adapter_count)
+ return WINED3DERR_INVALIDCALL;
+
+ /* The task of this function is to check whether a certain display / backbuffer format
+ * combination is available on the given adapter. In fullscreen mode microsoft specified
+ * that the display format shouldn't provide alpha and that ignoring alpha the backbuffer
+ * and display format should match exactly.
+ * In windowed mode format conversion can occur and this depends on the driver. When format
+ * conversion is done, this function should nevertheless fail and applications need to use
+ * CheckDeviceFormatConversion.
+ * At the moment we assume that fullscreen and windowed have the same capabilities. */
+
+ /* There are only 4 display formats. */
+ if (!(display_format == WINED3DFMT_B5G6R5_UNORM
+ || display_format == WINED3DFMT_B5G5R5X1_UNORM
+ || display_format == WINED3DFMT_B8G8R8X8_UNORM
+ || display_format == WINED3DFMT_B10G10R10A2_UNORM))
+ {
+ TRACE("Format %s is not supported as display format.\n", debug_d3dformat(display_format));
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ /* If the requested display format is not available, don't continue. */
+ mode_count = wined3d_get_adapter_mode_count(wined3d, adapter_idx,
+ display_format, WINED3D_SCANLINE_ORDERING_UNKNOWN);
+ if (!mode_count)
+ {
+ TRACE("No available modes for display format %s.\n", debug_d3dformat(display_format));
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ /* Windowed mode allows you to specify WINED3DFMT_UNKNOWN for the backbuffer format,
+ * it means 'reuse' the display format for the backbuffer. */
+ if (!windowed && backbuffer_format == WINED3DFMT_UNKNOWN)
+ {
+ TRACE("backbuffer_format WINED3FMT_UNKNOWN only available in windowed mode.\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ /* In FULLSCREEN mode WINED3DFMT_B5G6R5_UNORM can only be mixed with
+ * backbuffer format WINED3DFMT_B5G6R5_UNORM. */
+ if (display_format == WINED3DFMT_B5G6R5_UNORM && backbuffer_format != WINED3DFMT_B5G6R5_UNORM)
+ {
+ TRACE("Unsupported display/backbuffer format combination %s / %s.\n",
+ debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ /* In FULLSCREEN mode WINED3DFMT_B5G5R5X1_UNORM can only be mixed with
+ * backbuffer formats WINED3DFMT_B5G5R5X1_UNORM and
+ * WINED3DFMT_B5G5R5A1_UNORM. */
+ if (display_format == WINED3DFMT_B5G5R5X1_UNORM
+ && !(backbuffer_format == WINED3DFMT_B5G5R5X1_UNORM || backbuffer_format == WINED3DFMT_B5G5R5A1_UNORM))
+ {
+ TRACE("Unsupported display/backbuffer format combination %s / %s.\n",
+ debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ /* In FULLSCREEN mode WINED3DFMT_B8G8R8X8_UNORM can only be mixed with
+ * backbuffer formats WINED3DFMT_B8G8R8X8_UNORM and
+ * WINED3DFMT_B8G8R8A8_UNORM. */
+ if (display_format == WINED3DFMT_B8G8R8X8_UNORM
+ && !(backbuffer_format == WINED3DFMT_B8G8R8X8_UNORM || backbuffer_format == WINED3DFMT_B8G8R8A8_UNORM))
+ {
+ TRACE("Unsupported display/backbuffer format combination %s / %s.\n",
+ debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ /* WINED3DFMT_B10G10R10A2_UNORM is only allowed in fullscreen mode and it
+ * can only be mixed with backbuffer format WINED3DFMT_B10G10R10A2_UNORM. */
+ if (display_format == WINED3DFMT_B10G10R10A2_UNORM
+ && (backbuffer_format != WINED3DFMT_B10G10R10A2_UNORM || windowed))
+ {
+ TRACE("Unsupported display/backbuffer format combination %s / %s.\n",
+ debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ /* Use CheckDeviceFormat to see if the backbuffer_format is usable with the given display_format */
+ hr = wined3d_check_device_format(wined3d, adapter_idx, device_type, display_format,
+ WINED3DUSAGE_RENDERTARGET, WINED3D_RTYPE_SURFACE, backbuffer_format);
+ if (FAILED(hr))
+ TRACE("Unsupported display/backbuffer format combination %s / %s.\n",
+ debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
+
+ return hr;
+}
+
+HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapter_idx,
+ enum wined3d_device_type device_type, WINED3DCAPS *caps)
+{
+ const struct wined3d_adapter *adapter = &wined3d->adapters[adapter_idx];
+ const struct wined3d_gl_info *gl_info = &adapter->gl_info;
+ struct shader_caps shader_caps;
+ struct fragment_caps fragment_caps;
+ struct wined3d_vertex_caps vertex_caps;
+ DWORD ckey_caps, blit_caps, fx_caps, pal_caps;
+
+ TRACE("wined3d %p, adapter_idx %u, device_type %s, caps %p.\n",
+ wined3d, adapter_idx, debug_d3ddevicetype(device_type), caps);
+
+ if (adapter_idx >= wined3d->adapter_count)
+ return WINED3DERR_INVALIDCALL;
+
+ caps->DeviceType = (device_type == WINED3D_DEVICE_TYPE_HAL) ? WINED3D_DEVICE_TYPE_HAL : WINED3D_DEVICE_TYPE_REF;
+ caps->AdapterOrdinal = adapter_idx;
+
+ caps->Caps = 0;
+ caps->Caps2 = WINED3DCAPS2_CANRENDERWINDOWED |
+ WINED3DCAPS2_FULLSCREENGAMMA |
+ WINED3DCAPS2_DYNAMICTEXTURES;
+ if (gl_info->supported[SGIS_GENERATE_MIPMAP])
+ caps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP;
+
+ caps->Caps3 = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD |
+ WINED3DCAPS3_COPY_TO_VIDMEM |
+ WINED3DCAPS3_COPY_TO_SYSTEMMEM;
+
+ caps->PresentationIntervals = WINED3DPRESENT_INTERVAL_IMMEDIATE |
+ WINED3DPRESENT_INTERVAL_ONE;
+
+ caps->CursorCaps = WINED3DCURSORCAPS_COLOR |
+ WINED3DCURSORCAPS_LOWRES;
+
+ caps->DevCaps = WINED3DDEVCAPS_FLOATTLVERTEX |
+ WINED3DDEVCAPS_EXECUTESYSTEMMEMORY |
+ WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY|
+ WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY |
+ WINED3DDEVCAPS_DRAWPRIMTLVERTEX |
+ WINED3DDEVCAPS_HWTRANSFORMANDLIGHT |
+ WINED3DDEVCAPS_EXECUTEVIDEOMEMORY |
+ WINED3DDEVCAPS_PUREDEVICE |
+ WINED3DDEVCAPS_HWRASTERIZATION |
+ WINED3DDEVCAPS_TEXTUREVIDEOMEMORY |
+ WINED3DDEVCAPS_TEXTURESYSTEMMEMORY |
+ WINED3DDEVCAPS_CANRENDERAFTERFLIP |
+ WINED3DDEVCAPS_DRAWPRIMITIVES2 |
+ WINED3DDEVCAPS_DRAWPRIMITIVES2EX;
+
+ caps->PrimitiveMiscCaps = WINED3DPMISCCAPS_CULLNONE |
+ WINED3DPMISCCAPS_CULLCCW |
+ WINED3DPMISCCAPS_CULLCW |
+ WINED3DPMISCCAPS_COLORWRITEENABLE |
+ WINED3DPMISCCAPS_CLIPTLVERTS |
+ WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
+ WINED3DPMISCCAPS_MASKZ |
+ WINED3DPMISCCAPS_BLENDOP |
+ WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING;
+ /* TODO:
+ WINED3DPMISCCAPS_NULLREFERENCE
+ WINED3DPMISCCAPS_FOGANDSPECULARALPHA
+ WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
+ WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
+
+ if (gl_info->supported[EXT_BLEND_EQUATION_SEPARATE] && gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
+ caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_SEPARATEALPHABLEND;
+ if (gl_info->supported[EXT_DRAW_BUFFERS2])
+ caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS;
+ if (gl_info->supported[ARB_FRAMEBUFFER_SRGB])
+ caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_POSTBLENDSRGBCONVERT;
+
+ caps->RasterCaps = WINED3DPRASTERCAPS_DITHER |
+ WINED3DPRASTERCAPS_PAT |
+ WINED3DPRASTERCAPS_WFOG |
+ WINED3DPRASTERCAPS_ZFOG |
+ WINED3DPRASTERCAPS_FOGVERTEX |
+ WINED3DPRASTERCAPS_FOGTABLE |
+ WINED3DPRASTERCAPS_STIPPLE |
+ WINED3DPRASTERCAPS_SUBPIXEL |
+ WINED3DPRASTERCAPS_ZTEST |
+ WINED3DPRASTERCAPS_SCISSORTEST |
+ WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
+ WINED3DPRASTERCAPS_DEPTHBIAS;
+
+ if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
+ {
+ caps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY |
+ WINED3DPRASTERCAPS_ZBIAS |
+ WINED3DPRASTERCAPS_MIPMAPLODBIAS;
+ }
+
+ caps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS |
+ WINED3DPCMPCAPS_EQUAL |
+ WINED3DPCMPCAPS_GREATER |
+ WINED3DPCMPCAPS_GREATEREQUAL |
+ WINED3DPCMPCAPS_LESS |
+ WINED3DPCMPCAPS_LESSEQUAL |
+ WINED3DPCMPCAPS_NEVER |
+ WINED3DPCMPCAPS_NOTEQUAL;
+
+ caps->SrcBlendCaps = WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
+ WINED3DPBLENDCAPS_BOTHSRCALPHA |
+ WINED3DPBLENDCAPS_DESTALPHA |
+ WINED3DPBLENDCAPS_DESTCOLOR |
+ WINED3DPBLENDCAPS_INVDESTALPHA |
+ WINED3DPBLENDCAPS_INVDESTCOLOR |
+ WINED3DPBLENDCAPS_INVSRCALPHA |
+ WINED3DPBLENDCAPS_INVSRCCOLOR |
+ WINED3DPBLENDCAPS_ONE |
+ WINED3DPBLENDCAPS_SRCALPHA |
+ WINED3DPBLENDCAPS_SRCALPHASAT |
+ WINED3DPBLENDCAPS_SRCCOLOR |
+ WINED3DPBLENDCAPS_ZERO;
+
+ caps->DestBlendCaps = WINED3DPBLENDCAPS_DESTALPHA |
+ WINED3DPBLENDCAPS_DESTCOLOR |
+ WINED3DPBLENDCAPS_INVDESTALPHA |
+ WINED3DPBLENDCAPS_INVDESTCOLOR |
+ WINED3DPBLENDCAPS_INVSRCALPHA |
+ WINED3DPBLENDCAPS_INVSRCCOLOR |
+ WINED3DPBLENDCAPS_ONE |
+ WINED3DPBLENDCAPS_SRCALPHA |
+ WINED3DPBLENDCAPS_SRCCOLOR |
+ WINED3DPBLENDCAPS_ZERO;
+ /* NOTE: WINED3DPBLENDCAPS_SRCALPHASAT is not supported as dest blend factor,
+ * according to the glBlendFunc manpage
+ *
+ * WINED3DPBLENDCAPS_BOTHINVSRCALPHA and WINED3DPBLENDCAPS_BOTHSRCALPHA are
+ * legacy settings for srcblend only
+ */
+
+ if (gl_info->supported[EXT_BLEND_COLOR])
+ {
+ caps->SrcBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
+ caps->DestBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
+ }
+
+
+ caps->AlphaCmpCaps = WINED3DPCMPCAPS_ALWAYS |
+ WINED3DPCMPCAPS_EQUAL |
+ WINED3DPCMPCAPS_GREATER |
+ WINED3DPCMPCAPS_GREATEREQUAL |
+ WINED3DPCMPCAPS_LESS |
+ WINED3DPCMPCAPS_LESSEQUAL |
+ WINED3DPCMPCAPS_NEVER |
+ WINED3DPCMPCAPS_NOTEQUAL;
+
+ caps->ShadeCaps = WINED3DPSHADECAPS_SPECULARGOURAUDRGB |
+ WINED3DPSHADECAPS_COLORGOURAUDRGB |
+ WINED3DPSHADECAPS_ALPHAFLATBLEND |
+ WINED3DPSHADECAPS_ALPHAGOURAUDBLEND |
+ WINED3DPSHADECAPS_COLORFLATRGB |
+ WINED3DPSHADECAPS_FOGFLAT |
+ WINED3DPSHADECAPS_FOGGOURAUD |
+ WINED3DPSHADECAPS_SPECULARFLATRGB;
+
+ caps->TextureCaps = WINED3DPTEXTURECAPS_ALPHA |
+ WINED3DPTEXTURECAPS_ALPHAPALETTE |
+ WINED3DPTEXTURECAPS_TRANSPARENCY |
+ WINED3DPTEXTURECAPS_BORDER |
+ WINED3DPTEXTURECAPS_MIPMAP |
+ WINED3DPTEXTURECAPS_PROJECTED |
+ WINED3DPTEXTURECAPS_PERSPECTIVE;
+
+ if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
+ {
+ caps->TextureCaps |= WINED3DPTEXTURECAPS_POW2 |
+ WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
+ }
+
+ if (gl_info->supported[EXT_TEXTURE3D])
+ {
+ caps->TextureCaps |= WINED3DPTEXTURECAPS_VOLUMEMAP |
+ WINED3DPTEXTURECAPS_MIPVOLUMEMAP;
+ if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
+ {
+ caps->TextureCaps |= WINED3DPTEXTURECAPS_VOLUMEMAP_POW2;
+ }
+ }
+
+ if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+ {
+ caps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP |
+ WINED3DPTEXTURECAPS_MIPCUBEMAP;
+ if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
+ {
+ caps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP_POW2;
+ }
+ }
+
+ caps->TextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR |
+ WINED3DPTFILTERCAPS_MAGFPOINT |
+ WINED3DPTFILTERCAPS_MINFLINEAR |
+ WINED3DPTFILTERCAPS_MINFPOINT |
+ WINED3DPTFILTERCAPS_MIPFLINEAR |
+ WINED3DPTFILTERCAPS_MIPFPOINT |
+ WINED3DPTFILTERCAPS_LINEAR |
+ WINED3DPTFILTERCAPS_LINEARMIPLINEAR |
+ WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
+ WINED3DPTFILTERCAPS_MIPLINEAR |
+ WINED3DPTFILTERCAPS_MIPNEAREST |
+ WINED3DPTFILTERCAPS_NEAREST;
+
+ if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
+ {
+ caps->TextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
+ WINED3DPTFILTERCAPS_MINFANISOTROPIC;
+ }
+
+ if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+ {
+ caps->CubeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR |
+ WINED3DPTFILTERCAPS_MAGFPOINT |
+ WINED3DPTFILTERCAPS_MINFLINEAR |
+ WINED3DPTFILTERCAPS_MINFPOINT |
+ WINED3DPTFILTERCAPS_MIPFLINEAR |
+ WINED3DPTFILTERCAPS_MIPFPOINT |
+ WINED3DPTFILTERCAPS_LINEAR |
+ WINED3DPTFILTERCAPS_LINEARMIPLINEAR |
+ WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
+ WINED3DPTFILTERCAPS_MIPLINEAR |
+ WINED3DPTFILTERCAPS_MIPNEAREST |
+ WINED3DPTFILTERCAPS_NEAREST;
+
+ if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
+ {
+ caps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
+ WINED3DPTFILTERCAPS_MINFANISOTROPIC;
+ }
+ }
+ else
+ {
+ caps->CubeTextureFilterCaps = 0;
+ }
+
+ if (gl_info->supported[EXT_TEXTURE3D])
+ {
+ caps->VolumeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR |
+ WINED3DPTFILTERCAPS_MAGFPOINT |
+ WINED3DPTFILTERCAPS_MINFLINEAR |
+ WINED3DPTFILTERCAPS_MINFPOINT |
+ WINED3DPTFILTERCAPS_MIPFLINEAR |
+ WINED3DPTFILTERCAPS_MIPFPOINT |
+ WINED3DPTFILTERCAPS_LINEAR |
+ WINED3DPTFILTERCAPS_LINEARMIPLINEAR |
+ WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
+ WINED3DPTFILTERCAPS_MIPLINEAR |
+ WINED3DPTFILTERCAPS_MIPNEAREST |
+ WINED3DPTFILTERCAPS_NEAREST;
+ }
+ else
+ {
+ caps->VolumeTextureFilterCaps = 0;
+ }
+
+ caps->TextureAddressCaps = WINED3DPTADDRESSCAPS_INDEPENDENTUV |
+ WINED3DPTADDRESSCAPS_CLAMP |
+ WINED3DPTADDRESSCAPS_WRAP;
+
+ if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
+ {
+ caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
+ }
+ if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT])
+ {
+ caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
+ }
+ if (gl_info->supported[ATI_TEXTURE_MIRROR_ONCE])
+ {
+ caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
+ }
+
+ if (gl_info->supported[EXT_TEXTURE3D])
+ {
+ caps->VolumeTextureAddressCaps = WINED3DPTADDRESSCAPS_INDEPENDENTUV |
+ WINED3DPTADDRESSCAPS_CLAMP |
+ WINED3DPTADDRESSCAPS_WRAP;
+ if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
+ {
+ caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
+ }
+ if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT])
+ {
+ caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
+ }
+ if (gl_info->supported[ATI_TEXTURE_MIRROR_ONCE])
+ {
+ caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
+ }
+ }
+ else
+ {
+ caps->VolumeTextureAddressCaps = 0;
+ }
+
+ caps->LineCaps = WINED3DLINECAPS_TEXTURE |
+ WINED3DLINECAPS_ZTEST |
+ WINED3DLINECAPS_BLEND |
+ WINED3DLINECAPS_ALPHACMP |
+ WINED3DLINECAPS_FOG;
+ /* WINED3DLINECAPS_ANTIALIAS is not supported on Windows, and dx and gl seem to have a different
+ * idea how generating the smoothing alpha values works; the result is different
+ */
+
+ caps->MaxTextureWidth = gl_info->limits.texture_size;
+ caps->MaxTextureHeight = gl_info->limits.texture_size;
+
+ if (gl_info->supported[EXT_TEXTURE3D])
+ caps->MaxVolumeExtent = gl_info->limits.texture3d_size;
+ else
+ caps->MaxVolumeExtent = 0;
+
+ caps->MaxTextureRepeat = 32768;
+ caps->MaxTextureAspectRatio = gl_info->limits.texture_size;
+ caps->MaxVertexW = 1.0f;
+
+ caps->GuardBandLeft = 0.0f;
+ caps->GuardBandTop = 0.0f;
+ caps->GuardBandRight = 0.0f;
+ caps->GuardBandBottom = 0.0f;
+
+ caps->ExtentsAdjust = 0.0f;
+
+ caps->StencilCaps = WINED3DSTENCILCAPS_DECRSAT |
+ WINED3DSTENCILCAPS_INCRSAT |
+ WINED3DSTENCILCAPS_INVERT |
+ WINED3DSTENCILCAPS_KEEP |
+ WINED3DSTENCILCAPS_REPLACE |
+ WINED3DSTENCILCAPS_ZERO;
+ if (gl_info->supported[EXT_STENCIL_WRAP])
+ {
+ caps->StencilCaps |= WINED3DSTENCILCAPS_DECR |
+ WINED3DSTENCILCAPS_INCR;
+ }
+ if (gl_info->supported[EXT_STENCIL_TWO_SIDE] || gl_info->supported[ATI_SEPARATE_STENCIL])
+ {
+ caps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
+ }
+
+ caps->MaxAnisotropy = gl_info->limits.anisotropy;
+ caps->MaxPointSize = gl_info->limits.pointsize_max;
+
+ caps->MaxPrimitiveCount = 0xfffff; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
+ caps->MaxVertexIndex = 0xfffff;
+ caps->MaxStreams = MAX_STREAMS;
+ caps->MaxStreamStride = 1024;
+
+ /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */
+ caps->DevCaps2 = WINED3DDEVCAPS2_STREAMOFFSET |
+ WINED3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET;
+ caps->MaxNpatchTessellationLevel = 0;
+ caps->MasterAdapterOrdinal = 0;
+ caps->AdapterOrdinalInGroup = 0;
+ caps->NumberOfAdaptersInGroup = 1;
+
+ caps->NumSimultaneousRTs = gl_info->limits.buffers;
+
+ caps->StretchRectFilterCaps = WINED3DPTFILTERCAPS_MINFPOINT |
+ WINED3DPTFILTERCAPS_MAGFPOINT |
+ WINED3DPTFILTERCAPS_MINFLINEAR |
+ WINED3DPTFILTERCAPS_MAGFLINEAR;
+ caps->VertexTextureFilterCaps = 0;
+
+ adapter->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
+ adapter->fragment_pipe->get_caps(&adapter->gl_info, &fragment_caps);
+ adapter->vertex_pipe->vp_get_caps(&adapter->gl_info, &vertex_caps);
+
+ /* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */
+ caps->PrimitiveMiscCaps |= fragment_caps.PrimitiveMiscCaps;
+
+ caps->VertexShaderVersion = shader_caps.vs_version;
+ caps->MaxVertexShaderConst = shader_caps.vs_uniform_count;
+
+ caps->PixelShaderVersion = shader_caps.ps_version;
+ caps->PixelShader1xMaxValue = shader_caps.ps_1x_max_value;
+
+ caps->TextureOpCaps = fragment_caps.TextureOpCaps;
+ caps->MaxTextureBlendStages = fragment_caps.MaxTextureBlendStages;
+ caps->MaxSimultaneousTextures = fragment_caps.MaxSimultaneousTextures;
+
+ caps->MaxUserClipPlanes = vertex_caps.max_user_clip_planes;
+ caps->MaxActiveLights = vertex_caps.max_active_lights;
+ caps->MaxVertexBlendMatrices = vertex_caps.max_vertex_blend_matrices;
+ caps->MaxVertexBlendMatrixIndex = vertex_caps.max_vertex_blend_matrix_index;
+ caps->VertexProcessingCaps = vertex_caps.vertex_processing_caps;
+ caps->FVFCaps = vertex_caps.fvf_caps;
+ caps->RasterCaps |= vertex_caps.raster_caps;
+
+ /* The following caps are shader specific, but they are things we cannot detect, or which
+ * are the same among all shader models. So to avoid code duplication set the shader version
+ * specific, but otherwise constant caps here
+ */
+ if (caps->VertexShaderVersion >= 3)
+ {
+ /* Where possible set the caps based on OpenGL extensions and if they
+ * aren't set (in case of software rendering) use the VS 3.0 from
+ * MSDN or else if there's OpenGL spec use a hardcoded value minimum
+ * VS3.0 value. */
+ caps->VS20Caps.caps = WINED3DVS20CAPS_PREDICATION;
+ /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
+ caps->VS20Caps.dynamic_flow_control_depth = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH;
+ caps->VS20Caps.temp_count = max(32, adapter->gl_info.limits.arb_vs_temps);
+ /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
+ caps->VS20Caps.static_flow_control_depth = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH;
+
+ caps->MaxVShaderInstructionsExecuted = 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
+ caps->MaxVertexShader30InstructionSlots = max(512, adapter->gl_info.limits.arb_vs_instructions);
+ }
+ else if (caps->VertexShaderVersion == 2)
+ {
+ caps->VS20Caps.caps = 0;
+ caps->VS20Caps.dynamic_flow_control_depth = WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH;
+ caps->VS20Caps.temp_count = max(12, adapter->gl_info.limits.arb_vs_temps);
+ caps->VS20Caps.static_flow_control_depth = 1;
+
+ caps->MaxVShaderInstructionsExecuted = 65535;
+ caps->MaxVertexShader30InstructionSlots = 0;
+ }
+ else
+ { /* VS 1.x */
+ caps->VS20Caps.caps = 0;
+ caps->VS20Caps.dynamic_flow_control_depth = 0;
+ caps->VS20Caps.temp_count = 0;
+ caps->VS20Caps.static_flow_control_depth = 0;
+
+ caps->MaxVShaderInstructionsExecuted = 0;
+ caps->MaxVertexShader30InstructionSlots = 0;
+ }
+
+ if (caps->PixelShaderVersion >= 3)
+ {
+ /* Where possible set the caps based on OpenGL extensions and if they
+ * aren't set (in case of software rendering) use the PS 3.0 from
+ * MSDN or else if there's OpenGL spec use a hardcoded value minimum
+ * PS 3.0 value. */
+
+ /* Caps is more or less undocumented on MSDN but it appears to be
+ * used for PS20Caps based on results from R9600/FX5900/Geforce6800
+ * cards from Windows */
+ caps->PS20Caps.caps = WINED3DPS20CAPS_ARBITRARYSWIZZLE |
+ WINED3DPS20CAPS_GRADIENTINSTRUCTIONS |
+ WINED3DPS20CAPS_PREDICATION |
+ WINED3DPS20CAPS_NODEPENDENTREADLIMIT |
+ WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
+ /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
+ caps->PS20Caps.dynamic_flow_control_depth = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH;
+ caps->PS20Caps.temp_count = max(32, adapter->gl_info.limits.arb_ps_temps);
+ /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
+ caps->PS20Caps.static_flow_control_depth = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH;
+ /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
+ caps->PS20Caps.instruction_slot_count = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS;
+
+ caps->MaxPShaderInstructionsExecuted = 65535;
+ caps->MaxPixelShader30InstructionSlots = max(WINED3DMIN30SHADERINSTRUCTIONS,
+ adapter->gl_info.limits.arb_ps_instructions);
+ }
+ else if(caps->PixelShaderVersion == 2)
+ {
+ /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
+ caps->PS20Caps.caps = 0;
+ caps->PS20Caps.dynamic_flow_control_depth = 0; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
+ caps->PS20Caps.temp_count = max(12, adapter->gl_info.limits.arb_ps_temps);
+ caps->PS20Caps.static_flow_control_depth = WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minimum: 1 */
+ /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
+ caps->PS20Caps.instruction_slot_count = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS;
+
+ caps->MaxPShaderInstructionsExecuted = 512; /* Minimum value, a GeforceFX uses 1024 */
+ caps->MaxPixelShader30InstructionSlots = 0;
+ }
+ else /* PS 1.x */
+ {
+ caps->PS20Caps.caps = 0;
+ caps->PS20Caps.dynamic_flow_control_depth = 0;
+ caps->PS20Caps.temp_count = 0;
+ caps->PS20Caps.static_flow_control_depth = 0;
+ caps->PS20Caps.instruction_slot_count = 0;
+
+ caps->MaxPShaderInstructionsExecuted = 0;
+ caps->MaxPixelShader30InstructionSlots = 0;
+ }
+
+ if (caps->VertexShaderVersion >= 2)
+ {
+ /* OpenGL supports all the formats below, perhaps not always
+ * without conversion, but it supports them.
+ * Further GLSL doesn't seem to have an official unsigned type so
+ * don't advertise it yet as I'm not sure how we handle it.
+ * We might need to add some clamping in the shader engine to
+ * support it.
+ * TODO: WINED3DDTCAPS_USHORT2N, WINED3DDTCAPS_USHORT4N, WINED3DDTCAPS_UDEC3, WINED3DDTCAPS_DEC3N */
+ caps->DeclTypes = WINED3DDTCAPS_UBYTE4 |
+ WINED3DDTCAPS_UBYTE4N |
+ WINED3DDTCAPS_SHORT2N |
+ WINED3DDTCAPS_SHORT4N;
+ if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
+ {
+ caps->DeclTypes |= WINED3DDTCAPS_FLOAT16_2 |
+ WINED3DDTCAPS_FLOAT16_4;
+ }
+ }
+ else
+ {
+ caps->DeclTypes = 0;
+ }
+
+ /* Set DirectDraw helper Caps */
+ ckey_caps = WINEDDCKEYCAPS_DESTBLT |
+ WINEDDCKEYCAPS_SRCBLT;
+ fx_caps = WINEDDFXCAPS_BLTALPHA |
+ WINEDDFXCAPS_BLTMIRRORLEFTRIGHT |
+ WINEDDFXCAPS_BLTMIRRORUPDOWN |
+ WINEDDFXCAPS_BLTROTATION90 |
+ WINEDDFXCAPS_BLTSHRINKX |
+ WINEDDFXCAPS_BLTSHRINKXN |
+ WINEDDFXCAPS_BLTSHRINKY |
+ WINEDDFXCAPS_BLTSHRINKXN |
+ WINEDDFXCAPS_BLTSTRETCHX |
+ WINEDDFXCAPS_BLTSTRETCHXN |
+ WINEDDFXCAPS_BLTSTRETCHY |
+ WINEDDFXCAPS_BLTSTRETCHYN;
+ blit_caps = WINEDDCAPS_BLT |
+ WINEDDCAPS_BLTCOLORFILL |
+ WINEDDCAPS_BLTDEPTHFILL |
+ WINEDDCAPS_BLTSTRETCH |
+ WINEDDCAPS_CANBLTSYSMEM |
+ WINEDDCAPS_CANCLIP |
+ WINEDDCAPS_CANCLIPSTRETCHED |
+ WINEDDCAPS_COLORKEY |
+ WINEDDCAPS_COLORKEYHWASSIST |
+ WINEDDCAPS_ALIGNBOUNDARYSRC;
+ pal_caps = WINEDDPCAPS_8BIT |
+ WINEDDPCAPS_PRIMARYSURFACE;
+
+ /* Fill the ddraw caps structure */
+ caps->ddraw_caps.caps = WINEDDCAPS_GDI |
+ WINEDDCAPS_PALETTE |
+ blit_caps;
+ caps->ddraw_caps.caps2 = WINEDDCAPS2_CERTIFIED |
+ WINEDDCAPS2_NOPAGELOCKREQUIRED |
+ WINEDDCAPS2_PRIMARYGAMMA |
+ WINEDDCAPS2_WIDESURFACES |
+ WINEDDCAPS2_CANRENDERWINDOWED;
+ caps->ddraw_caps.color_key_caps = ckey_caps;
+ caps->ddraw_caps.fx_caps = fx_caps;
+ caps->ddraw_caps.pal_caps = pal_caps;
+ caps->ddraw_caps.svb_caps = blit_caps;
+ caps->ddraw_caps.svb_color_key_caps = ckey_caps;
+ caps->ddraw_caps.svb_fx_caps = fx_caps;
+ caps->ddraw_caps.vsb_caps = blit_caps;
+ caps->ddraw_caps.vsb_color_key_caps = ckey_caps;
+ caps->ddraw_caps.vsb_fx_caps = fx_caps;
+ caps->ddraw_caps.ssb_caps = blit_caps;
+ caps->ddraw_caps.ssb_color_key_caps = ckey_caps;
+ caps->ddraw_caps.ssb_fx_caps = fx_caps;
+
+ caps->ddraw_caps.dds_caps = WINEDDSCAPS_ALPHA |
+ WINEDDSCAPS_BACKBUFFER |
+ WINEDDSCAPS_FLIP |
+ WINEDDSCAPS_FRONTBUFFER |
+ WINEDDSCAPS_OFFSCREENPLAIN |
+ WINEDDSCAPS_PALETTE |
+ WINEDDSCAPS_PRIMARYSURFACE |
+ WINEDDSCAPS_SYSTEMMEMORY |
+ WINEDDSCAPS_VIDEOMEMORY |
+ WINEDDSCAPS_VISIBLE;
+ caps->ddraw_caps.stride_align = DDRAW_PITCH_ALIGNMENT;
+
+ if (!(wined3d->flags & WINED3D_NO3D))
+ {
+ caps->ddraw_caps.dds_caps |= WINEDDSCAPS_3DDEVICE |
+ WINEDDSCAPS_MIPMAP |
+ WINEDDSCAPS_TEXTURE |
+ WINEDDSCAPS_ZBUFFER;
+ caps->ddraw_caps.caps |= WINEDDCAPS_3D;
+ }
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx, enum wined3d_device_type device_type,
+ HWND focus_window, DWORD flags, BYTE surface_alignment, struct wined3d_device_parent *device_parent,
+ struct wined3d_device **device)
+{
+ struct wined3d_device *object;
+ HRESULT hr;
+
+ TRACE("wined3d %p, adapter_idx %u, device_type %#x, focus_window %p, flags %#x, device_parent %p, device %p.\n",
+ wined3d, adapter_idx, device_type, focus_window, flags, device_parent, device);
+
+ /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
+ * number and create a device without a 3D adapter for 2D only operation. */
+ if (wined3d->adapter_count && adapter_idx >= wined3d->adapter_count)
+ return WINED3DERR_INVALIDCALL;
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ hr = device_init(object, wined3d, adapter_idx, device_type,
+ focus_window, flags, surface_alignment, device_parent);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize device, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created device %p.\n", object);
+ *device = object;
+
+ device_parent->ops->wined3d_device_created(device_parent, *device);
+
+ return WINED3D_OK;
+}
+
+static void WINE_GLAPI invalid_func(const void *data)
+{
+ ERR("Invalid vertex attribute function called\n");
+ DebugBreak();
+}
+
+static void WINE_GLAPI invalid_texcoord_func(GLenum unit, const void *data)
+{
+ ERR("Invalid texcoord function called\n");
+ DebugBreak();
+}
+
+/* Helper functions for providing vertex data to opengl. The arrays are initialized based on
+ * the extension detection and are used in drawStridedSlow
+ */
+static void WINE_GLAPI position_d3dcolor(const void *data)
+{
+ DWORD pos = *((const DWORD *)data);
+
+ FIXME("Add a test for fixed function position from d3dcolor type\n");
+ context_get_current()->gl_info->gl_ops.gl.p_glVertex4s(D3DCOLOR_B_R(pos),
+ D3DCOLOR_B_G(pos),
+ D3DCOLOR_B_B(pos),
+ D3DCOLOR_B_A(pos));
+}
+
+static void WINE_GLAPI position_float4(const void *data)
+{
+ const GLfloat *pos = data;
+
+ if (pos[3] != 0.0f && pos[3] != 1.0f)
+ {
+ float w = 1.0f / pos[3];
+
+ context_get_current()->gl_info->gl_ops.gl.p_glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w);
+ }
+ else
+ {
+ context_get_current()->gl_info->gl_ops.gl.p_glVertex3fv(pos);
+ }
+}
+
+static void WINE_GLAPI diffuse_d3dcolor(const void *data)
+{
+ DWORD diffuseColor = *((const DWORD *)data);
+
+ context_get_current()->gl_info->gl_ops.gl.p_glColor4ub(D3DCOLOR_B_R(diffuseColor),
+ D3DCOLOR_B_G(diffuseColor),
+ D3DCOLOR_B_B(diffuseColor),
+ D3DCOLOR_B_A(diffuseColor));
+}
+
+static void WINE_GLAPI specular_d3dcolor(const void *data)
+{
+ DWORD specularColor = *((const DWORD *)data);
+ GLbyte d[] = {D3DCOLOR_B_R(specularColor),
+ D3DCOLOR_B_G(specularColor),
+ D3DCOLOR_B_B(specularColor)};
+
+ specular_func_3ubv(d);
+}
+
+static void WINE_GLAPI warn_no_specular_func(const void *data)
+{
+ WARN("GL_EXT_secondary_color not supported\n");
+}
+
+static void wined3d_adapter_init_ffp_attrib_ops(const struct wined3d_adapter *adapter)
+{
+ const struct wined3d_d3d_info *d3d_info = &adapter->d3d_info;
+ const struct wined3d_gl_info *gl_info = &adapter->gl_info;
+
+ position_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)gl_info->gl_ops.gl.p_glVertex3fv;
+ if (!d3d_info->xyzrhw)
+ position_funcs[WINED3D_FFP_EMIT_FLOAT4] = position_float4;
+ else
+ position_funcs[WINED3D_FFP_EMIT_FLOAT4] = (glAttribFunc)gl_info->gl_ops.gl.p_glVertex4fv;
+ position_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = position_d3dcolor;
+ position_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_SHORT4] = (glAttribFunc)gl_info->gl_ops.gl.p_glVertex2sv;
+ position_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_INVALID] = invalid_func;
+
+ diffuse_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)gl_info->gl_ops.gl.p_glColor3fv;
+ diffuse_funcs[WINED3D_FFP_EMIT_FLOAT4] = (glAttribFunc)gl_info->gl_ops.gl.p_glColor4fv;
+ diffuse_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = diffuse_d3dcolor;
+ diffuse_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_UBYTE4N] = (glAttribFunc)gl_info->gl_ops.gl.p_glColor4ubv;
+ diffuse_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_SHORT4N] = (glAttribFunc)gl_info->gl_ops.gl.p_glColor4sv;
+ diffuse_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_USHORT4N] = (glAttribFunc)gl_info->gl_ops.gl.p_glColor4usv;
+ diffuse_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_INVALID] = invalid_func;
+
+ /* No 4 component entry points here */
+ specular_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
+ if (gl_info->supported[EXT_SECONDARY_COLOR])
+ {
+ specular_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)GL_EXTCALL(glSecondaryColor3fvEXT);
+ }
+ else
+ {
+ specular_funcs[WINED3D_FFP_EMIT_FLOAT3] = warn_no_specular_func;
+ }
+ specular_funcs[WINED3D_FFP_EMIT_FLOAT4] = invalid_func;
+ if (gl_info->supported[EXT_SECONDARY_COLOR])
+ {
+ specular_func_3ubv = (glAttribFunc)GL_EXTCALL(glSecondaryColor3ubvEXT);
+ specular_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = specular_d3dcolor;
+ }
+ else
+ {
+ specular_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = warn_no_specular_func;
+ }
+ specular_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_INVALID] = invalid_func;
+
+ /* Only 3 component entry points here. Test how others behave. Float4 normals are used
+ * by one of our tests, trying to pass it to the pixel shader, which fails on Windows.
+ */
+ normal_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)gl_info->gl_ops.gl.p_glNormal3fv;
+ normal_funcs[WINED3D_FFP_EMIT_FLOAT4] = (glAttribFunc)gl_info->gl_ops.gl.p_glNormal3fv; /* Just ignore the 4th value */
+ normal_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_INVALID] = invalid_func;
+
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT1] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord1fvARB);
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2fvARB);
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord3fvARB);
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4fvARB);
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = invalid_texcoord_func;
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_texcoord_func;
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2svARB);
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4svARB);
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_texcoord_func;
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_texcoord_func;
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_texcoord_func;
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_texcoord_func;
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_texcoord_func;
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_texcoord_func;
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_texcoord_func;
+ if (gl_info->supported[NV_HALF_FLOAT])
+ {
+ /* Not supported by ARB_HALF_FLOAT_VERTEX, so check for NV_HALF_FLOAT */
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2hvNV);
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4hvNV);
+ } else {
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_texcoord_func;
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_texcoord_func;
+ }
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_INVALID] = invalid_texcoord_func;
+}
+
+static void wined3d_adapter_init_fb_cfgs(struct wined3d_adapter *adapter, HDC dc)
+{
+ const struct wined3d_gl_info *gl_info = &adapter->gl_info;
+ int i;
+
+ if (gl_info->supported[WGL_ARB_PIXEL_FORMAT])
+ {
+ UINT attrib_count = 0;
+ GLint cfg_count;
+ int attribs[11];
+ int values[11];
+ int attribute;
+
+ attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
+ GL_EXTCALL(wglGetPixelFormatAttribivARB(dc, 0, 0, 1, &attribute, &cfg_count));
+
+ adapter->cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cfg_count * sizeof(*adapter->cfgs));
+ attribs[attrib_count++] = WGL_RED_BITS_ARB;
+ attribs[attrib_count++] = WGL_GREEN_BITS_ARB;
+ attribs[attrib_count++] = WGL_BLUE_BITS_ARB;
+ attribs[attrib_count++] = WGL_ALPHA_BITS_ARB;
+ attribs[attrib_count++] = WGL_COLOR_BITS_ARB;
+ attribs[attrib_count++] = WGL_DEPTH_BITS_ARB;
+ attribs[attrib_count++] = WGL_STENCIL_BITS_ARB;
+ attribs[attrib_count++] = WGL_DRAW_TO_WINDOW_ARB;
+ attribs[attrib_count++] = WGL_PIXEL_TYPE_ARB;
+ attribs[attrib_count++] = WGL_DOUBLE_BUFFER_ARB;
+ attribs[attrib_count++] = WGL_AUX_BUFFERS_ARB;
+
+ for (i = 0, adapter->cfg_count = 0; i < cfg_count; ++i)
+ {
+ struct wined3d_pixel_format *cfg = &adapter->cfgs[adapter->cfg_count];
+ int format_id = i + 1;
+
+ if (!GL_EXTCALL(wglGetPixelFormatAttribivARB(dc, format_id, 0, attrib_count, attribs, values)))
+ continue;
+
+ cfg->iPixelFormat = format_id;
+ cfg->redSize = values[0];
+ cfg->greenSize = values[1];
+ cfg->blueSize = values[2];
+ cfg->alphaSize = values[3];
+ cfg->colorSize = values[4];
+ cfg->depthSize = values[5];
+ cfg->stencilSize = values[6];
+ cfg->windowDrawable = values[7];
+ cfg->iPixelType = values[8];
+ cfg->doubleBuffer = values[9];
+ cfg->auxBuffers = values[10];
+
+ cfg->numSamples = 0;
+ /* Check multisample support. */
+ if (gl_info->supported[ARB_MULTISAMPLE])
+ {
+ int attribs[2] = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB};
+ int values[2];
+
+ if (GL_EXTCALL(wglGetPixelFormatAttribivARB(dc, format_id, 0, 2, attribs, values)))
+ {
+ /* values[0] = WGL_SAMPLE_BUFFERS_ARB which tells whether
+ * multisampling is supported. values[1] = number of
+ * multisample buffers. */
+ if (values[0])
+ cfg->numSamples = values[1];
+ }
+ }
+
+ TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, "
+ "depth=%d, stencil=%d, samples=%d, windowDrawable=%d\n",
+ cfg->iPixelFormat, cfg->iPixelType, cfg->doubleBuffer,
+ cfg->redSize, cfg->greenSize, cfg->blueSize, cfg->alphaSize,
+ cfg->depthSize, cfg->stencilSize, cfg->numSamples, cfg->windowDrawable);
+
+ ++adapter->cfg_count;
+ }
+ }
+ else
+ {
+ int cfg_count;
+
+ cfg_count = DescribePixelFormat(dc, 0, 0, 0);
+ adapter->cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cfg_count * sizeof(*adapter->cfgs));
+
+ for (i = 0, adapter->cfg_count = 0; i < cfg_count; ++i)
+ {
+ struct wined3d_pixel_format *cfg = &adapter->cfgs[adapter->cfg_count];
+ PIXELFORMATDESCRIPTOR pfd;
+ int format_id = i + 1;
+
+ if (!DescribePixelFormat(dc, format_id, sizeof(pfd), &pfd))
+ continue;
+
+ /* We only want HW acceleration using an OpenGL ICD driver.
+ * PFD_GENERIC_FORMAT = slow opengl 1.1 gdi software rendering.
+ * PFD_GENERIC_ACCELERATED = partial hw acceleration using a MCD
+ * driver (e.g. 3dfx minigl). */
+ if (pfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED))
+ {
+ TRACE("Skipping format %d because it isn't ICD accelerated.\n", format_id);
+ continue;
+ }
+
+ cfg->iPixelFormat = format_id;
+ cfg->redSize = pfd.cRedBits;
+ cfg->greenSize = pfd.cGreenBits;
+ cfg->blueSize = pfd.cBlueBits;
+ cfg->alphaSize = pfd.cAlphaBits;
+ cfg->colorSize = pfd.cColorBits;
+ cfg->depthSize = pfd.cDepthBits;
+ cfg->stencilSize = pfd.cStencilBits;
+ cfg->windowDrawable = (pfd.dwFlags & PFD_DRAW_TO_WINDOW) ? 1 : 0;
+ cfg->iPixelType = (pfd.iPixelType == PFD_TYPE_RGBA) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB;
+ cfg->doubleBuffer = (pfd.dwFlags & PFD_DOUBLEBUFFER) ? 1 : 0;
+ cfg->auxBuffers = pfd.cAuxBuffers;
+ cfg->numSamples = 0;
+
+ TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, "
+ "depth=%d, stencil=%d, windowDrawable=%d\n",
+ cfg->iPixelFormat, cfg->iPixelType, cfg->doubleBuffer,
+ cfg->redSize, cfg->greenSize, cfg->blueSize, cfg->alphaSize,
+ cfg->depthSize, cfg->stencilSize, cfg->windowDrawable);
+
+ ++adapter->cfg_count;
+ }
+ }
+}
+
+/**
+ * Loads a system DLL.
+ *
+ * @returns Module handle or NULL
+ * @param pszName The DLL name.
+ */
+static HMODULE loadSystemDll(const char *pszName)
+{
+ char szPath[MAX_PATH];
+ UINT cchPath = GetSystemDirectoryA(szPath, sizeof(szPath));
+ size_t cbName = strlen(pszName) + 1;
+ if (cchPath + 1 + cbName > sizeof(szPath))
+ return NULL;
+ szPath[cchPath] = '\\';
+ memcpy(&szPath[cchPath + 1], pszName, cbName);
+ return LoadLibraryA(szPath);
+}
+
+/* Do not call while under the GL lock. */
+static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal)
+{
+ struct wined3d_gl_info *gl_info = &adapter->gl_info;
+ struct wined3d_fake_gl_ctx fake_gl_ctx = {0};
+ unsigned int ctx_attrib_idx = 0;
+ DISPLAY_DEVICEW display_device;
+ GLint ctx_attribs[3];
+#ifdef VBOX
+ struct VBOXUHGSMI *pHgsmi = NULL;
+#endif
+
+ TRACE("adapter %p, ordinal %u.\n", adapter, ordinal);
+
+ adapter->ordinal = ordinal;
+ adapter->monitorPoint.x = -1;
+ adapter->monitorPoint.y = -1;
+
+/* Dynamically load all GL core functions */
+#ifdef USE_WIN32_OPENGL
+ {
+# ifndef VBOX
+ HMODULE mod_gl = GetModuleHandleA("opengl32.dll");
+# else
+ BOOL (APIENTRY *pDrvValidateVersion)(DWORD) DECLSPEC_HIDDEN;
+# ifdef VBOX_WDDM_WOW64
+ HMODULE mod_gl = loadSystemDll("VBoxOGL-x86.dll");
+# else
+ HMODULE mod_gl = loadSystemDll("VBoxOGL.dll");
+# endif
+ if (!mod_gl)
+ {
+ ERR("Can't load VBoxOGL.dll!\n");
+ return FALSE;
+ }
+
+ pDrvValidateVersion = (void*)GetProcAddress(mod_gl, "DrvValidateVersion");
+ if(!pDrvValidateVersion) {
+ ERR("Can't get DrvValidateVersion\n");
+ FreeLibrary(mod_gl);
+ return FALSE;
+ }
+ if(!pDrvValidateVersion(1)) {
+ ERR("DrvValidateVersion FAILED\n");
+ FreeLibrary(mod_gl);
+ return FALSE;
+ }
+
+# define VBOX_USE_FUNC(f) p##f = (void *)GetProcAddress(mod_gl, #f);
+ VBOX_GL_FUNCS_GEN
+# undef VBOX_USE_FUNC
+# endif
+# define USE_GL_FUNC(f) gl_info->gl_ops.gl.p_##f = (void *)GetProcAddress(mod_gl, #f);
+ ALL_WGL_FUNCS
+# undef USE_GL_FUNC
+ gl_info->gl_ops.wgl.p_wglSwapBuffers = (void *)GetProcAddress(mod_gl, "wglSwapBuffers");
+ }
+#else
+ /* To bypass the opengl32 thunks retrieve functions from the WGL driver instead of opengl32 */
+ {
+ HDC hdc = GetDC( 0 );
+ const struct opengl_funcs *wgl_driver = __wine_get_wgl_driver( hdc, WINE_WGL_DRIVER_VERSION );
+ ReleaseDC( 0, hdc );
+ if (!wgl_driver || wgl_driver == (void *)-1) return FALSE;
+ gl_info->gl_ops.wgl = wgl_driver->wgl;
+ gl_info->gl_ops.gl = wgl_driver->gl;
+ }
+#endif
+
+ glEnableWINE = gl_info->gl_ops.gl.p_glEnable;
+ glDisableWINE = gl_info->gl_ops.gl.p_glDisable;
+
+#ifdef VBOX_WITH_WDDM
+ pHgsmi = VBoxCrHgsmiCreate();
+ if (!pHgsmi)
+ {
+ ERR("VBoxCrHgsmiCreate failed");
+ return FALSE;
+ }
+#endif
+
+ if (!AllocateLocallyUniqueId(&adapter->luid))
+ {
+ ERR("Failed to set adapter LUID (%#x).\n", GetLastError());
+ return FALSE;
+ }
+ TRACE("Allocated LUID %08x:%08x for adapter %p.\n",
+ adapter->luid.HighPart, adapter->luid.LowPart, adapter);
+
+ if (!WineD3D_CreateFakeGLContext(&fake_gl_ctx
+#ifdef VBOX
+ , pHgsmi
+#endif
+ ))
+ {
+ ERR("Failed to get a GL context for adapter %p.\n", adapter);
+#ifdef VBOX_WITH_WDDM
+ VBoxCrHgsmiDestroy(pHgsmi);
+#endif
+ return FALSE;
+ }
+
+ if (context_debug_output_enabled(gl_info))
+ {
+ ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_FLAGS_ARB;
+ ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_DEBUG_BIT_ARB;
+ }
+ ctx_attribs[ctx_attrib_idx] = 0;
+ wined3d_create_fake_gl_context_attribs(&fake_gl_ctx, gl_info, ctx_attribs);
+
+ if (!wined3d_adapter_init_gl_caps(adapter))
+ {
+ ERR("Failed to initialize GL caps for adapter %p.\n", adapter);
+ WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
+#ifdef VBOX_WITH_WDDM
+ VBoxCrHgsmiDestroy(pHgsmi);
+#endif
+ return FALSE;
+ }
+
+ wined3d_adapter_init_fb_cfgs(adapter, fake_gl_ctx.dc);
+ /* We haven't found any suitable formats. This should only happen in
+ * case of GDI software rendering, which is pretty useless anyway. */
+ if (!adapter->cfg_count)
+ {
+ WARN("No suitable pixel formats found.\n");
+ WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
+ HeapFree(GetProcessHeap(), 0, adapter->cfgs);
+#ifdef VBOX_WITH_WDDM
+ VBoxCrHgsmiDestroy(pHgsmi);
+#endif
+ return FALSE;
+ }
+
+ if (!wined3d_adapter_init_format_info(adapter))
+ {
+ ERR("Failed to initialize GL format info.\n");
+ WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
+ HeapFree(GetProcessHeap(), 0, adapter->cfgs);
+#ifdef VBOX_WITH_WDDM
+ VBoxCrHgsmiDestroy(pHgsmi);
+#endif
+ return FALSE;
+ }
+
+#ifndef VBOX_WITH_WDDM
+ adapter->TextureRam = adapter->driver_info.vidmem;
+ adapter->UsedTextureRam = 0;
+ TRACE("Emulating %u MB of texture ram.\n", adapter->TextureRam / (1024 * 1024));
+#endif
+
+ display_device.cb = sizeof(display_device);
+ EnumDisplayDevicesW(NULL, ordinal, &display_device, 0);
+ TRACE("DeviceName: %s\n", debugstr_w(display_device.DeviceName));
+ strcpyW(adapter->DeviceName, display_device.DeviceName);
+
+ WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
+
+ wined3d_adapter_init_ffp_attrib_ops(adapter);
+
+#ifdef VBOX_WITH_WDDM
+ VBoxCrHgsmiDestroy(pHgsmi);
+#endif
+
+ return TRUE;
+}
+
+static void wined3d_adapter_init_nogl(struct wined3d_adapter *adapter, UINT ordinal)
+{
+ DISPLAY_DEVICEW display_device;
+
+ memset(adapter, 0, sizeof(*adapter));
+ adapter->ordinal = ordinal;
+ adapter->monitorPoint.x = -1;
+ adapter->monitorPoint.y = -1;
+
+ adapter->driver_info.name = "Display";
+ adapter->driver_info.description = "WineD3D DirectDraw Emulation";
+#ifndef VBOX_WITH_WDDM
+ if (wined3d_settings.emulated_textureram)
+ adapter->TextureRam = wined3d_settings.emulated_textureram;
+ else
+ adapter->TextureRam = 128 * 1024 * 1024;
+#endif
+
+ initPixelFormatsNoGL(&adapter->gl_info);
+
+ adapter->vertex_pipe = &none_vertex_pipe;
+ adapter->fragment_pipe = &none_fragment_pipe;
+ adapter->shader_backend = &none_shader_backend;
+ adapter->blitter = &cpu_blit;
+
+ display_device.cb = sizeof(display_device);
+ EnumDisplayDevicesW(NULL, ordinal, &display_device, 0);
+ TRACE("DeviceName: %s\n", debugstr_w(display_device.DeviceName));
+ strcpyW(adapter->DeviceName, display_device.DeviceName);
+}
+
+static void STDMETHODCALLTYPE wined3d_null_wined3d_object_destroyed(void *parent) {}
+
+const struct wined3d_parent_ops wined3d_null_parent_ops =
+{
+ wined3d_null_wined3d_object_destroyed,
+};
+
+/* Do not call while under the GL lock. */
+HRESULT wined3d_init(struct wined3d *wined3d, UINT version, DWORD flags)
+{
+ wined3d->dxVersion = version;
+ wined3d->ref = 1;
+ wined3d->flags = flags;
+
+ TRACE("Initializing adapters.\n");
+
+ if (flags & WINED3D_NO3D)
+ {
+ wined3d_adapter_init_nogl(&wined3d->adapters[0], 0);
+ wined3d->adapter_count = 1;
+ return WINED3D_OK;
+ }
+
+ if (!wined3d_adapter_init(&wined3d->adapters[0], 0))
+ {
+ WARN("Failed to initialize adapter.\n");
+ return E_FAIL;
+ }
+ wined3d->adapter_count = 1;
+
+ return WINED3D_OK;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/drawprim.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/drawprim.c
new file mode 100644
index 00000000..e8196782
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/drawprim.c
@@ -0,0 +1,827 @@
+/*
+ * WINED3D draw functions
+ *
+ * Copyright 2002-2004 Jason Edmeades
+ * Copyright 2002-2004 Raphael Junqueira
+ * Copyright 2004 Christian Costa
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2006, 2008 Henri Verbeet
+ * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2009 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_draw);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
+
+#include <stdio.h>
+#include <math.h>
+
+#ifdef DEBUG_misha
+#include "../VBox/VBoxDbgGl.h"
+#endif
+
+#ifdef VBOX_WITH_WINE_FIXES
+# define ceilf ceil
+#endif
+
+/* Context activation is done by the caller. */
+static void drawStridedFast(const struct wined3d_gl_info *gl_info, GLenum primitive_type, UINT count, UINT idx_size,
+ const void *idx_data, UINT start_idx, INT base_vertex_index, UINT start_instance, UINT instance_count)
+{
+ if (idx_size)
+ {
+ GLenum idxtype = idx_size == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
+ if (instance_count)
+ {
+ if (!gl_info->supported[ARB_DRAW_INSTANCED])
+ {
+ FIXME("Instanced drawing not supported.\n");
+ }
+ else
+ {
+ if (start_instance)
+ FIXME("Start instance (%u) not supported.\n", start_instance);
+ GL_EXTCALL(glDrawElementsInstancedBaseVertex(primitive_type, count, idxtype,
+ (const char *)idx_data + (idx_size * start_idx), instance_count, base_vertex_index));
+ checkGLcall("glDrawElementsInstancedBaseVertex");
+ }
+ }
+ else if (gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX])
+ {
+ GL_EXTCALL(glDrawElementsBaseVertex(primitive_type, count, idxtype,
+ (const char *)idx_data + (idx_size * start_idx), base_vertex_index));
+ checkGLcall("glDrawElementsBaseVertex");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDrawElements(primitive_type, count,
+ idxtype, (const char *)idx_data + (idx_size * start_idx));
+ checkGLcall("glDrawElements");
+ }
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDrawArrays(primitive_type, start_idx, count);
+ checkGLcall("glDrawArrays");
+ }
+}
+
+/*
+ * Actually draw using the supplied information.
+ * Slower GL version which extracts info about each vertex in turn
+ */
+
+/* Context activation is done by the caller. */
+static void drawStridedSlow(const struct wined3d_device *device, const struct wined3d_context *context,
+ const struct wined3d_stream_info *si, UINT NumVertexes, GLenum glPrimType,
+ const void *idxData, UINT idxSize, UINT startIdx)
+{
+ unsigned int textureNo = 0;
+ const WORD *pIdxBufS = NULL;
+ const DWORD *pIdxBufL = NULL;
+ UINT vx_index;
+ const struct wined3d_state *state = &device->stateBlock->state;
+ LONG SkipnStrides = startIdx;
+ BOOL pixelShader = use_ps(state);
+ BOOL specular_fog = FALSE;
+ const BYTE *texCoords[WINED3DDP_MAXTEXCOORD];
+ const BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position = NULL;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const struct wined3d_d3d_info *d3d_info = context->d3d_info;
+ UINT texture_stages = d3d_info->limits.ffp_blend_stages;
+ const struct wined3d_stream_info_element *element;
+ UINT num_untracked_materials;
+ DWORD tex_mask = 0;
+
+ TRACE_(d3d_perf)("Using slow vertex array code\n");
+
+ /* Variable Initialization */
+ if (idxSize)
+ {
+ /* Immediate mode drawing can't make use of indices in a vbo - get the
+ * data from the index buffer. If the index buffer has no vbo (not
+ * supported or other reason), or with user pointer drawing idxData
+ * will be non-NULL. */
+ if (!idxData)
+ idxData = buffer_get_sysmem(state->index_buffer, gl_info);
+
+ if (idxSize == 2) pIdxBufS = idxData;
+ else pIdxBufL = idxData;
+ } else if (idxData) {
+ ERR("non-NULL idxData with 0 idxSize, this should never happen\n");
+ return;
+ }
+
+ /* Start drawing in GL */
+ gl_info->gl_ops.gl.p_glBegin(glPrimType);
+
+ if (si->use_map & (1 << WINED3D_FFP_POSITION))
+ {
+ element = &si->elements[WINED3D_FFP_POSITION];
+ position = element->data.addr;
+ }
+
+ if (si->use_map & (1 << WINED3D_FFP_NORMAL))
+ {
+ element = &si->elements[WINED3D_FFP_NORMAL];
+ normal = element->data.addr;
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glNormal3f(0, 0, 0);
+ }
+
+ num_untracked_materials = context->num_untracked_materials;
+ if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
+ {
+ element = &si->elements[WINED3D_FFP_DIFFUSE];
+ diffuse = element->data.addr;
+
+ if (num_untracked_materials && element->format->id != WINED3DFMT_B8G8R8A8_UNORM)
+ FIXME("Implement diffuse color tracking from %s\n", debug_d3dformat(element->format->id));
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+ }
+
+ if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
+ {
+ element = &si->elements[WINED3D_FFP_SPECULAR];
+ specular = element->data.addr;
+
+ /* special case where the fog density is stored in the specular alpha channel */
+ if (state->render_states[WINED3D_RS_FOGENABLE]
+ && (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE
+ || si->elements[WINED3D_FFP_POSITION].format->id == WINED3DFMT_R32G32B32A32_FLOAT)
+ && state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
+ {
+ if (gl_info->supported[EXT_FOG_COORD])
+ {
+ if (element->format->id == WINED3DFMT_B8G8R8A8_UNORM) specular_fog = TRUE;
+ else FIXME("Implement fog coordinates from %s\n", debug_d3dformat(element->format->id));
+ }
+ else
+ {
+ static BOOL warned;
+
+ if (!warned)
+ {
+ /* TODO: Use the fog table code from old ddraw */
+ FIXME("Implement fog for transformed vertices in software\n");
+ warned = TRUE;
+ }
+ }
+ }
+ }
+ else if (gl_info->supported[EXT_SECONDARY_COLOR])
+ {
+ GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
+ }
+
+ for (textureNo = 0; textureNo < texture_stages; ++textureNo)
+ {
+ int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX];
+ DWORD texture_idx = device->texUnitMap[textureNo];
+
+ if (!gl_info->supported[ARB_MULTITEXTURE] && textureNo > 0)
+ {
+ FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
+ continue;
+ }
+
+ if (!pixelShader && !state->textures[textureNo]) continue;
+
+ if (texture_idx == WINED3D_UNMAPPED_STAGE) continue;
+
+ if (coordIdx > 7)
+ {
+ TRACE("tex: %d - Skip tex coords, as being system generated\n", textureNo);
+ continue;
+ }
+ else if (coordIdx < 0)
+ {
+ FIXME("tex: %d - Coord index %d is less than zero, expect a crash.\n", textureNo, coordIdx);
+ continue;
+ }
+
+ if (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx)))
+ {
+ element = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
+ texCoords[coordIdx] = element->data.addr;
+ tex_mask |= (1 << textureNo);
+ }
+ else
+ {
+ TRACE("tex: %d - Skipping tex coords, as no data supplied\n", textureNo);
+ if (gl_info->supported[ARB_MULTITEXTURE])
+ GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
+ else
+ gl_info->gl_ops.gl.p_glTexCoord4f(0, 0, 0, 1);
+ }
+ }
+
+ /* We shouldn't start this function if any VBO is involved. Should I put a safety check here?
+ * Guess it's not necessary(we crash then anyway) and would only eat CPU time
+ */
+
+ /* For each primitive */
+ for (vx_index = 0; vx_index < NumVertexes; ++vx_index) {
+ UINT texture, tmp_tex_mask;
+ /* Blending data and Point sizes are not supported by this function. They are not supported by the fixed
+ * function pipeline at all. A Fixme for them is printed after decoding the vertex declaration
+ */
+
+ /* For indexed data, we need to go a few more strides in */
+ if (idxData)
+ {
+ /* Indexed so work out the number of strides to skip */
+ if (idxSize == 2)
+ SkipnStrides = pIdxBufS[startIdx + vx_index] + state->base_vertex_index;
+ else
+ SkipnStrides = pIdxBufL[startIdx + vx_index] + state->base_vertex_index;
+ }
+
+ tmp_tex_mask = tex_mask;
+ for (texture = 0; tmp_tex_mask; tmp_tex_mask >>= 1, ++texture)
+ {
+ int coord_idx;
+ const void *ptr;
+ DWORD texture_idx;
+
+ if (!(tmp_tex_mask & 1)) continue;
+
+ coord_idx = state->texture_states[texture][WINED3D_TSS_TEXCOORD_INDEX];
+ ptr = texCoords[coord_idx] + (SkipnStrides * si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].stride);
+
+ texture_idx = device->texUnitMap[texture];
+ multi_texcoord_funcs[si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].format->emit_idx](
+ GL_TEXTURE0_ARB + texture_idx, ptr);
+ }
+
+ /* Diffuse -------------------------------- */
+ if (diffuse) {
+ const void *ptrToCoords = diffuse + SkipnStrides * si->elements[WINED3D_FFP_DIFFUSE].stride;
+
+ diffuse_funcs[si->elements[WINED3D_FFP_DIFFUSE].format->emit_idx](ptrToCoords);
+ if (num_untracked_materials)
+ {
+ DWORD diffuseColor = ((const DWORD *)ptrToCoords)[0];
+ unsigned char i;
+ float color[4];
+
+ color[0] = D3DCOLOR_B_R(diffuseColor) / 255.0f;
+ color[1] = D3DCOLOR_B_G(diffuseColor) / 255.0f;
+ color[2] = D3DCOLOR_B_B(diffuseColor) / 255.0f;
+ color[3] = D3DCOLOR_B_A(diffuseColor) / 255.0f;
+
+ for (i = 0; i < num_untracked_materials; ++i)
+ {
+ gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, context->untracked_materials[i], color);
+ }
+ }
+ }
+
+ /* Specular ------------------------------- */
+ if (specular) {
+ const void *ptrToCoords = specular + SkipnStrides * si->elements[WINED3D_FFP_SPECULAR].stride;
+
+ specular_funcs[si->elements[WINED3D_FFP_SPECULAR].format->emit_idx](ptrToCoords);
+
+ if (specular_fog)
+ {
+ DWORD specularColor = *(const DWORD *)ptrToCoords;
+ GL_EXTCALL(glFogCoordfEXT((float) (specularColor >> 24)));
+ }
+ }
+
+ /* Normal -------------------------------- */
+ if (normal)
+ {
+ const void *ptrToCoords = normal + SkipnStrides * si->elements[WINED3D_FFP_NORMAL].stride;
+ normal_funcs[si->elements[WINED3D_FFP_NORMAL].format->emit_idx](ptrToCoords);
+ }
+
+ /* Position -------------------------------- */
+ if (position) {
+ const void *ptrToCoords = position + SkipnStrides * si->elements[WINED3D_FFP_POSITION].stride;
+ position_funcs[si->elements[WINED3D_FFP_POSITION].format->emit_idx](ptrToCoords);
+ }
+
+ /* For non indexed mode, step onto next parts */
+ if (!idxData) ++SkipnStrides;
+ }
+
+ gl_info->gl_ops.gl.p_glEnd();
+ checkGLcall("glEnd and previous calls");
+}
+
+/* Context activation is done by the caller. */
+static inline void send_attribute(const struct wined3d_gl_info *gl_info,
+ enum wined3d_format_id format, const UINT index, const void *ptr)
+{
+ switch(format)
+ {
+ case WINED3DFMT_R32_FLOAT:
+ GL_EXTCALL(glVertexAttrib1fvARB(index, ptr));
+ break;
+ case WINED3DFMT_R32G32_FLOAT:
+ GL_EXTCALL(glVertexAttrib2fvARB(index, ptr));
+ break;
+ case WINED3DFMT_R32G32B32_FLOAT:
+ GL_EXTCALL(glVertexAttrib3fvARB(index, ptr));
+ break;
+ case WINED3DFMT_R32G32B32A32_FLOAT:
+ GL_EXTCALL(glVertexAttrib4fvARB(index, ptr));
+ break;
+
+ case WINED3DFMT_R8G8B8A8_UINT:
+ GL_EXTCALL(glVertexAttrib4ubvARB(index, ptr));
+ break;
+ case WINED3DFMT_B8G8R8A8_UNORM:
+ if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
+ {
+ const DWORD *src = ptr;
+ DWORD c = *src & 0xff00ff00;
+ c |= (*src & 0xff0000) >> 16;
+ c |= (*src & 0xff) << 16;
+ GL_EXTCALL(glVertexAttrib4NubvARB(index, (GLubyte *)&c));
+ break;
+ }
+ /* else fallthrough */
+ case WINED3DFMT_R8G8B8A8_UNORM:
+ GL_EXTCALL(glVertexAttrib4NubvARB(index, ptr));
+ break;
+
+ case WINED3DFMT_R16G16_SINT:
+ GL_EXTCALL(glVertexAttrib4svARB(index, ptr));
+ break;
+ case WINED3DFMT_R16G16B16A16_SINT:
+ GL_EXTCALL(glVertexAttrib4svARB(index, ptr));
+ break;
+
+ case WINED3DFMT_R16G16_SNORM:
+ {
+ GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
+ GL_EXTCALL(glVertexAttrib4NsvARB(index, s));
+ break;
+ }
+ case WINED3DFMT_R16G16_UNORM:
+ {
+ GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
+ GL_EXTCALL(glVertexAttrib4NusvARB(index, s));
+ break;
+ }
+ case WINED3DFMT_R16G16B16A16_SNORM:
+ GL_EXTCALL(glVertexAttrib4NsvARB(index, ptr));
+ break;
+ case WINED3DFMT_R16G16B16A16_UNORM:
+ GL_EXTCALL(glVertexAttrib4NusvARB(index, ptr));
+ break;
+
+ case WINED3DFMT_R10G10B10A2_UINT:
+ FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
+ /*glVertexAttrib3usvARB(instancedData[j], (GLushort *) ptr); Does not exist */
+ break;
+ case WINED3DFMT_R10G10B10A2_SNORM:
+ FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
+ /*glVertexAttrib3NusvARB(instancedData[j], (GLushort *) ptr); Does not exist */
+ break;
+
+ case WINED3DFMT_R16G16_FLOAT:
+ /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
+ * byte float according to the IEEE standard
+ */
+ if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM])
+ {
+ /* Not supported by GL_ARB_half_float_vertex */
+ GL_EXTCALL(glVertexAttrib2hvNV(index, ptr));
+ }
+ else
+ {
+ float x = float_16_to_32(((const unsigned short *)ptr) + 0);
+ float y = float_16_to_32(((const unsigned short *)ptr) + 1);
+ GL_EXTCALL(glVertexAttrib2fARB(index, x, y));
+ }
+ break;
+ case WINED3DFMT_R16G16B16A16_FLOAT:
+ if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM])
+ {
+ /* Not supported by GL_ARB_half_float_vertex */
+ GL_EXTCALL(glVertexAttrib4hvNV(index, ptr));
+ }
+ else
+ {
+ float x = float_16_to_32(((const unsigned short *)ptr) + 0);
+ float y = float_16_to_32(((const unsigned short *)ptr) + 1);
+ float z = float_16_to_32(((const unsigned short *)ptr) + 2);
+ float w = float_16_to_32(((const unsigned short *)ptr) + 3);
+ GL_EXTCALL(glVertexAttrib4fARB(index, x, y, z, w));
+ }
+ break;
+
+ default:
+ ERR("Unexpected attribute format: %s\n", debug_d3dformat(format));
+ break;
+ }
+}
+
+/* Context activation is done by the caller. */
+static void drawStridedSlowVs(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state,
+ const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType,
+ const void *idxData, UINT idxSize, UINT startIdx)
+{
+ LONG SkipnStrides = startIdx + state->load_base_vertex_index;
+ const DWORD *pIdxBufL = NULL;
+ const WORD *pIdxBufS = NULL;
+ UINT vx_index;
+ int i;
+ const BYTE *ptr;
+
+ if (idxSize)
+ {
+ /* Immediate mode drawing can't make use of indices in a vbo - get the
+ * data from the index buffer. If the index buffer has no vbo (not
+ * supported or other reason), or with user pointer drawing idxData
+ * will be non-NULL. */
+ if (!idxData)
+ idxData = buffer_get_sysmem(state->index_buffer, gl_info);
+
+ if (idxSize == 2) pIdxBufS = idxData;
+ else pIdxBufL = idxData;
+ } else if (idxData) {
+ ERR("non-NULL idxData with 0 idxSize, this should never happen\n");
+ return;
+ }
+
+ /* Start drawing in GL */
+ gl_info->gl_ops.gl.p_glBegin(glPrimitiveType);
+
+ for (vx_index = 0; vx_index < numberOfVertices; ++vx_index)
+ {
+ if (idxData)
+ {
+ /* Indexed so work out the number of strides to skip */
+ if (idxSize == 2)
+ SkipnStrides = pIdxBufS[startIdx + vx_index] + state->load_base_vertex_index;
+ else
+ SkipnStrides = pIdxBufL[startIdx + vx_index] + state->load_base_vertex_index;
+ }
+
+ for (i = MAX_ATTRIBS - 1; i >= 0; i--)
+ {
+ if (!(si->use_map & (1 << i)))
+ {
+#ifdef VBOX_WITH_WINE_FIX_ZEROVERTATTR
+ if (i == 0)
+ {
+# ifdef DEBUG_misha
+ ERR("Test it!\n");
+# endif
+ GL_EXTCALL(glVertexAttrib4fARB(0, 0.0f, 0.0f, 0.0f, 0.0f));
+ }
+#endif
+ continue;
+ }
+
+ ptr = si->elements[i].data.addr + si->elements[i].stride * SkipnStrides;
+
+ send_attribute(gl_info, si->elements[i].format->id, i, ptr);
+ }
+ SkipnStrides++;
+ }
+
+ gl_info->gl_ops.gl.p_glEnd();
+}
+
+/* Context activation is done by the caller. */
+static void drawStridedInstanced(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state,
+ const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType,
+ const void *idxData, UINT idxSize, UINT startIdx, UINT base_vertex_index, UINT instance_count)
+{
+ int numInstancedAttribs = 0, j;
+ UINT instancedData[sizeof(si->elements) / sizeof(*si->elements) /* 16 */];
+ GLenum idxtype = idxSize == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
+ UINT i;
+
+ if (!idxSize)
+ {
+ /* This is a nasty thing. MSDN says no hardware supports that and apps have to use software vertex processing.
+ * We don't support this for now
+ *
+ * Shouldn't be too hard to support with opengl, in theory just call glDrawArrays instead of drawElements.
+ * But the StreamSourceFreq value has a different meaning in that situation.
+ */
+ FIXME("Non-indexed instanced drawing is not supported\n");
+ return;
+ }
+
+ for (i = 0; i < sizeof(si->elements) / sizeof(*si->elements); ++i)
+ {
+ if (!(si->use_map & (1 << i))) continue;
+
+ if (state->streams[si->elements[i].stream_idx].flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
+ {
+ instancedData[numInstancedAttribs] = i;
+ numInstancedAttribs++;
+ }
+ }
+
+ for (i = 0; i < instance_count; ++i)
+ {
+ /* Specify the instanced attributes using immediate mode calls */
+ for(j = 0; j < numInstancedAttribs; j++) {
+ const BYTE *ptr = si->elements[instancedData[j]].data.addr
+ + si->elements[instancedData[j]].stride * i;
+ if (si->elements[instancedData[j]].data.buffer_object)
+ {
+ struct wined3d_buffer *vb = state->streams[si->elements[instancedData[j]].stream_idx].buffer;
+ ptr += (ULONG_PTR)buffer_get_sysmem(vb, gl_info);
+ }
+
+ send_attribute(gl_info, si->elements[instancedData[j]].format->id, instancedData[j], ptr);
+ }
+
+ if (gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX])
+ {
+ GL_EXTCALL(glDrawElementsBaseVertex(glPrimitiveType, numberOfVertices, idxtype,
+ (const char *)idxData+(idxSize * startIdx), base_vertex_index));
+ checkGLcall("glDrawElementsBaseVertex");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDrawElements(glPrimitiveType, numberOfVertices, idxtype,
+ (const char *)idxData + (idxSize * startIdx));
+ checkGLcall("glDrawElements");
+ }
+ }
+}
+
+static void remove_vbos(const struct wined3d_gl_info *gl_info,
+ const struct wined3d_state *state, struct wined3d_stream_info *s)
+{
+ unsigned int i;
+
+ for (i = 0; i < (sizeof(s->elements) / sizeof(*s->elements)); ++i)
+ {
+ struct wined3d_stream_info_element *e;
+
+ if (!(s->use_map & (1 << i))) continue;
+
+ e = &s->elements[i];
+ if (e->data.buffer_object)
+ {
+ struct wined3d_buffer *vb = state->streams[e->stream_idx].buffer;
+ e->data.buffer_object = 0;
+ e->data.addr = (BYTE *)((ULONG_PTR)e->data.addr + (ULONG_PTR)buffer_get_sysmem(vb, gl_info));
+ }
+ }
+}
+
+/* Routine common to the draw primitive and draw indexed primitive routines */
+void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count,
+ UINT start_instance, UINT instance_count, BOOL indexed)
+{
+ const struct wined3d_state *state = &device->stateBlock->state;
+ const struct wined3d_stream_info *stream_info;
+ struct wined3d_event_query *ib_query = NULL;
+ struct wined3d_stream_info si_emulated;
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+ BOOL emulation = FALSE;
+ const void *idx_data = NULL;
+ UINT idx_size = 0;
+ unsigned int i;
+
+ if (!index_count) return;
+
+ if (state->render_states[WINED3D_RS_COLORWRITEENABLE])
+ {
+ /* Invalidate the back buffer memory so LockRect will read it the next time */
+ for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i)
+ {
+ struct wined3d_surface *target = device->fb.render_targets[i];
+ if (target)
+ {
+ surface_load_location(target, target->draw_binding, NULL);
+ surface_modify_location(target, target->draw_binding, TRUE);
+ }
+ }
+ }
+
+ /* Signals other modules that a drawing is in progress and the stateblock finalized */
+ device->isInDraw = TRUE;
+
+ context = context_acquire(device, device->fb.render_targets[0]);
+ if (!context->valid)
+ {
+ context_release(context);
+ WARN("Invalid context, skipping draw.\n");
+ return;
+ }
+ gl_info = context->gl_info;
+
+ if (device->fb.depth_stencil)
+ {
+ /* Note that this depends on the context_acquire() call above to set
+ * context->render_offscreen properly. We don't currently take the
+ * Z-compare function into account, but we could skip loading the
+ * depthstencil for D3DCMP_NEVER and D3DCMP_ALWAYS as well. Also note
+ * that we never copy the stencil data.*/
+ DWORD location = context->render_offscreen ? device->fb.depth_stencil->draw_binding : SFLAG_INDRAWABLE;
+ if (state->render_states[WINED3D_RS_ZWRITEENABLE] || state->render_states[WINED3D_RS_ZENABLE])
+ {
+ struct wined3d_surface *ds = device->fb.depth_stencil;
+ RECT current_rect, draw_rect, r;
+
+ if (!context->render_offscreen && ds != device->onscreen_depth_stencil)
+ device_switch_onscreen_ds(device, context, ds);
+
+ if (ds->flags & location)
+ SetRect(&current_rect, 0, 0, ds->ds_current_size.cx, ds->ds_current_size.cy);
+ else
+ SetRectEmpty(&current_rect);
+
+ wined3d_get_draw_rect(state, &draw_rect);
+
+ IntersectRect(&r, &draw_rect, &current_rect);
+ if (!EqualRect(&r, &draw_rect))
+ surface_load_ds_location(ds, context, location);
+ }
+ }
+
+#ifdef VBOX_WITH_WINE_FIX_ZEROVERTATTR
+ Assert(device->czvDrawVertices == 0);
+ device->czvDrawVertices = index_count;
+#endif
+
+ if (!context_apply_draw_state(context, device))
+ {
+ context_release(context);
+ WARN("Unable to apply draw state, skipping draw.\n");
+#ifdef VBOX_WITH_WINE_FIX_ZEROVERTATTR
+ device->czvDrawVertices = 0;
+#endif
+ return;
+ }
+
+#ifdef VBOX_WITH_WINE_FIX_ZEROVERTATTR
+ device->czvDrawVertices = 0;
+#endif
+
+
+#ifdef DEBUG_misha
+ DBGL_CHECK_DRAWPRIM(context->gl_info, device);
+#endif
+
+ if (device->fb.depth_stencil && state->render_states[WINED3D_RS_ZWRITEENABLE])
+ {
+ struct wined3d_surface *ds = device->fb.depth_stencil;
+ DWORD location = context->render_offscreen ? ds->draw_binding : SFLAG_INDRAWABLE;
+
+ surface_modify_ds_location(ds, location, ds->ds_current_size.cx, ds->ds_current_size.cy);
+ }
+
+ if ((!gl_info->supported[WINED3D_GL_VERSION_2_0]
+ || !gl_info->supported[NV_POINT_SPRITE])
+ && context->render_offscreen
+ && state->render_states[WINED3D_RS_POINTSPRITEENABLE]
+ && state->gl_primitive_type == GL_POINTS)
+ {
+ FIXME("Point sprite coordinate origin switching not supported.\n");
+ }
+
+ stream_info = &device->stream_info;
+ if (device->instance_count)
+ instance_count = device->instance_count;
+
+ if (indexed)
+ {
+ struct wined3d_buffer *index_buffer = state->index_buffer;
+ if (!index_buffer->buffer_object || !stream_info->all_vbo)
+ idx_data = index_buffer->resource.allocatedMemory;
+ else
+ {
+ ib_query = index_buffer->query;
+ idx_data = NULL;
+ }
+
+ if (state->index_format == WINED3DFMT_R16_UINT)
+ idx_size = 2;
+ else
+ idx_size = 4;
+ }
+
+ if (!use_vs(state))
+ {
+ if (!stream_info->position_transformed && context->num_untracked_materials
+ && state->render_states[WINED3D_RS_LIGHTING])
+ {
+ static BOOL warned;
+
+ if (!warned++)
+ FIXME("Using software emulation because not all material properties could be tracked.\n");
+ else
+ WARN_(d3d_perf)("Using software emulation because not all material properties could be tracked.\n");
+ emulation = TRUE;
+ }
+ else if (context->fog_coord && state->render_states[WINED3D_RS_FOGENABLE])
+ {
+ static BOOL warned;
+
+ /* Either write a pipeline replacement shader or convert the
+ * specular alpha from unsigned byte to a float in the vertex
+ * buffer. */
+ if (!warned++)
+ FIXME("Using software emulation because manual fog coordinates are provided.\n");
+ else
+ WARN_(d3d_perf)("Using software emulation because manual fog coordinates are provided.\n");
+ emulation = TRUE;
+ }
+
+ if (emulation)
+ {
+ si_emulated = device->stream_info;
+ remove_vbos(gl_info, state, &si_emulated);
+ stream_info = &si_emulated;
+ }
+ }
+
+ if (device->useDrawStridedSlow || emulation)
+ {
+ /* Immediate mode drawing. */
+ if (use_vs(state))
+ {
+ static BOOL warned;
+
+ if (!warned++)
+ FIXME("Using immediate mode with vertex shaders for half float emulation.\n");
+ else
+ WARN_(d3d_perf)("Using immediate mode with vertex shaders for half float emulation.\n");
+
+ drawStridedSlowVs(gl_info, state, stream_info, index_count,
+ state->gl_primitive_type, idx_data, idx_size, start_idx);
+ }
+ else
+ {
+ drawStridedSlow(device, context, stream_info, index_count,
+ state->gl_primitive_type, idx_data, idx_size, start_idx);
+ }
+ }
+ else if (!gl_info->supported[ARB_INSTANCED_ARRAYS] && instance_count)
+ {
+ /* Instancing emulation by mixing immediate mode and arrays. */
+ drawStridedInstanced(gl_info, state, stream_info, index_count, state->gl_primitive_type,
+ idx_data, idx_size, start_idx, state->base_vertex_index, instance_count);
+ }
+ else
+ {
+ drawStridedFast(gl_info, state->gl_primitive_type, index_count, idx_size, idx_data,
+ start_idx, state->base_vertex_index, start_instance, instance_count);
+ }
+
+ if (ib_query)
+ wined3d_event_query_issue(ib_query, device);
+ for (i = 0; i < device->num_buffer_queries; ++i)
+ {
+ wined3d_event_query_issue(device->buffer_queries[i], device);
+ }
+
+ if (wined3d_settings.strict_draw_ordering)
+ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
+
+ context_release(context);
+
+ TRACE("Done all gl drawing\n");
+
+ /* Control goes back to the device, stateblock values may change again */
+ device->isInDraw = FALSE;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/gl_compat.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/gl_compat.c
new file mode 100644
index 00000000..37c1cc99
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/gl_compat.c
@@ -0,0 +1,552 @@
+/*
+ * Compatibility functions for older GL implementations
+ *
+ * Copyright 2008 Stefan Dösinger for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
+#ifdef HAVE_FLOAT_H
+# include <float.h>
+#endif
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(gl_compat);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
+
+/* Start GL_ARB_multitexture emulation */
+static void WINE_GLAPI wine_glMultiTexCoord1fARB(GLenum target, GLfloat s) {
+ if(target != GL_TEXTURE0) {
+ ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+ return;
+ }
+ context_get_current()->gl_info->gl_ops.gl.p_glTexCoord1f(s);
+}
+
+static void WINE_GLAPI wine_glMultiTexCoord1fvARB(GLenum target, const GLfloat *v) {
+ if(target != GL_TEXTURE0) {
+ ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+ return;
+ }
+ context_get_current()->gl_info->gl_ops.gl.p_glTexCoord1fv(v);
+}
+
+static void WINE_GLAPI wine_glMultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t) {
+ if(target != GL_TEXTURE0) {
+ ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+ return;
+ }
+ context_get_current()->gl_info->gl_ops.gl.p_glTexCoord2f(s, t);
+}
+
+static void WINE_GLAPI wine_glMultiTexCoord2fvARB(GLenum target, const GLfloat *v) {
+ if(target != GL_TEXTURE0) {
+ ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+ return;
+ }
+ context_get_current()->gl_info->gl_ops.gl.p_glTexCoord2fv(v);
+}
+
+static void WINE_GLAPI wine_glMultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r) {
+ if(target != GL_TEXTURE0) {
+ ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+ return;
+ }
+ context_get_current()->gl_info->gl_ops.gl.p_glTexCoord3f(s, t, r);
+}
+
+static void WINE_GLAPI wine_glMultiTexCoord3fvARB(GLenum target, const GLfloat *v) {
+ if(target != GL_TEXTURE0) {
+ ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+ return;
+ }
+ context_get_current()->gl_info->gl_ops.gl.p_glTexCoord3fv(v);
+}
+
+static void WINE_GLAPI wine_glMultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {
+ if(target != GL_TEXTURE0) {
+ ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+ return;
+ }
+ context_get_current()->gl_info->gl_ops.gl.p_glTexCoord4f(s, t, r, q);
+}
+
+static void WINE_GLAPI wine_glMultiTexCoord4fvARB(GLenum target, const GLfloat *v) {
+ if(target != GL_TEXTURE0) {
+ ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+ return;
+ }
+ context_get_current()->gl_info->gl_ops.gl.p_glTexCoord4fv(v);
+}
+
+static void WINE_GLAPI wine_glMultiTexCoord2svARB(GLenum target, const GLshort *v) {
+ if(target != GL_TEXTURE0) {
+ ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+ return;
+ }
+ context_get_current()->gl_info->gl_ops.gl.p_glTexCoord2sv(v);
+}
+
+static void WINE_GLAPI wine_glMultiTexCoord4svARB(GLenum target, const GLshort *v) {
+ if(target != GL_TEXTURE0) {
+ ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+ return;
+ }
+ context_get_current()->gl_info->gl_ops.gl.p_glTexCoord4sv(v);
+}
+
+static void WINE_GLAPI wine_glActiveTextureARB(GLenum texture) {
+ if(texture != GL_TEXTURE0) {
+ ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+ return;
+ }
+}
+
+static void WINE_GLAPI wine_glClientActiveTextureARB(GLenum texture) {
+ if(texture != GL_TEXTURE0) {
+ ERR("Texture unit > 0 used, but GL_ARB_multitexture is not supported\n");
+ return;
+ }
+}
+
+static void (WINE_GLAPI *old_multitex_glGetIntegerv) (GLenum pname, GLint* params) = NULL;
+static void WINE_GLAPI wine_glGetIntegerv(GLenum pname, GLint* params) {
+ switch(pname) {
+ case GL_ACTIVE_TEXTURE: *params = 0; break;
+ case GL_MAX_TEXTURE_UNITS_ARB: *params = 1; break;
+ default: old_multitex_glGetIntegerv(pname, params);
+ }
+}
+
+static void (WINE_GLAPI *old_multitex_glGetFloatv) (GLenum pname, GLfloat* params) = NULL;
+static void WINE_GLAPI wine_glGetFloatv(GLenum pname, GLfloat* params) {
+ if (pname == GL_ACTIVE_TEXTURE) *params = 0.0f;
+ else old_multitex_glGetFloatv(pname, params);
+}
+
+static void (WINE_GLAPI *old_multitex_glGetDoublev) (GLenum pname, GLdouble* params) = NULL;
+static void WINE_GLAPI wine_glGetDoublev(GLenum pname, GLdouble* params) {
+ if(pname == GL_ACTIVE_TEXTURE) *params = 0.0;
+ else old_multitex_glGetDoublev(pname, params);
+}
+
+/* Start GL_EXT_fogcoord emulation */
+static void (WINE_GLAPI *old_fogcoord_glEnable) (GLenum cap) = NULL;
+static void WINE_GLAPI wine_glEnable(GLenum cap) {
+ if(cap == GL_FOG) {
+ struct wined3d_context *ctx = context_get_current();
+ ctx->fog_enabled = 1;
+ if(ctx->gl_fog_source != GL_FRAGMENT_DEPTH_EXT) return;
+ }
+ old_fogcoord_glEnable(cap);
+}
+
+static void (WINE_GLAPI *old_fogcoord_glDisable) (GLenum cap) = NULL;
+static void WINE_GLAPI wine_glDisable(GLenum cap) {
+ if(cap == GL_FOG) {
+ struct wined3d_context *ctx = context_get_current();
+ ctx->fog_enabled = 0;
+ if(ctx->gl_fog_source != GL_FRAGMENT_DEPTH_EXT) return;
+ }
+ old_fogcoord_glDisable(cap);
+}
+
+static void (WINE_GLAPI *old_fogcoord_glFogi) (GLenum pname, GLint param) = NULL;
+static void WINE_GLAPI wine_glFogi(GLenum pname, GLint param) {
+ struct wined3d_context *ctx = context_get_current();
+
+ if(pname == GL_FOG_COORDINATE_SOURCE_EXT) {
+ ctx->gl_fog_source = param;
+ if(param == GL_FRAGMENT_DEPTH_EXT) {
+ if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG);
+ } else {
+ WARN_(d3d_perf)("Fog coords activated, but not supported. Using slow emulation\n");
+ old_fogcoord_glDisable(GL_FOG);
+ }
+ } else {
+ if(pname == GL_FOG_START) {
+ ctx->fogstart = (float) param;
+ } else if(pname == GL_FOG_END) {
+ ctx->fogend = (float) param;
+ }
+ old_fogcoord_glFogi(pname, param);
+ }
+}
+
+static void (WINE_GLAPI *old_fogcoord_glFogiv) (GLenum pname, const GLint *param) = NULL;
+static void WINE_GLAPI wine_glFogiv(GLenum pname, const GLint *param) {
+ struct wined3d_context *ctx = context_get_current();
+ if(pname == GL_FOG_COORDINATE_SOURCE_EXT) {
+ ctx->gl_fog_source = *param;
+ if(*param == GL_FRAGMENT_DEPTH_EXT) {
+ if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG);
+ } else {
+ WARN_(d3d_perf)("Fog coords activated, but not supported. Using slow emulation\n");
+ old_fogcoord_glDisable(GL_FOG);
+ }
+ } else {
+ if(pname == GL_FOG_START) {
+ ctx->fogstart = (float) *param;
+ } else if(pname == GL_FOG_END) {
+ ctx->fogend = (float) *param;
+ }
+ old_fogcoord_glFogiv(pname, param);
+ }
+}
+
+static void (WINE_GLAPI *old_fogcoord_glFogf) (GLenum pname, GLfloat param) = NULL;
+static void WINE_GLAPI wine_glFogf(GLenum pname, GLfloat param) {
+ struct wined3d_context *ctx = context_get_current();
+ if(pname == GL_FOG_COORDINATE_SOURCE_EXT) {
+ ctx->gl_fog_source = (GLint) param;
+ if(param == GL_FRAGMENT_DEPTH_EXT) {
+ if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG);
+ } else {
+ WARN_(d3d_perf)("Fog coords activated, but not supported. Using slow emulation\n");
+ old_fogcoord_glDisable(GL_FOG);
+ }
+ } else {
+ if(pname == GL_FOG_START) {
+ ctx->fogstart = param;
+ } else if(pname == GL_FOG_END) {
+ ctx->fogend = param;
+ }
+ old_fogcoord_glFogf(pname, param);
+ }
+}
+
+static void (WINE_GLAPI *old_fogcoord_glFogfv) (GLenum pname, const GLfloat *param) = NULL;
+static void WINE_GLAPI wine_glFogfv(GLenum pname, const GLfloat *param) {
+ struct wined3d_context *ctx = context_get_current();
+ if(pname == GL_FOG_COORDINATE_SOURCE_EXT) {
+ ctx->gl_fog_source = (GLint) *param;
+ if(*param == GL_FRAGMENT_DEPTH_EXT) {
+ if(ctx->fog_enabled) old_fogcoord_glEnable(GL_FOG);
+ } else {
+ WARN_(d3d_perf)("Fog coords activated, but not supported. Using slow emulation\n");
+ old_fogcoord_glDisable(GL_FOG);
+ }
+ } else {
+ if(pname == GL_FOG_COLOR) {
+ ctx->fogcolor[0] = param[0];
+ ctx->fogcolor[1] = param[1];
+ ctx->fogcolor[2] = param[2];
+ ctx->fogcolor[3] = param[3];
+ } else if(pname == GL_FOG_START) {
+ ctx->fogstart = *param;
+ } else if(pname == GL_FOG_END) {
+ ctx->fogend = *param;
+ }
+ old_fogcoord_glFogfv(pname, param);
+ }
+}
+
+static void (WINE_GLAPI *old_fogcoord_glVertex4f) (GLfloat x, GLfloat y, GLfloat z, GLfloat w) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glVertex4fv) (const GLfloat *pos) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glVertex3f) (GLfloat x, GLfloat y, GLfloat z) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glVertex3fv) (const GLfloat *pos) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glColor4f) (GLfloat r, GLfloat g, GLfloat b, GLfloat a) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glColor4fv) (const GLfloat *color) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glColor3f) (GLfloat r, GLfloat g, GLfloat b) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glColor3fv) (const GLfloat *color) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glColor4ub) (GLubyte r, GLubyte g, GLubyte b, GLubyte a) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glFogCoordfEXT) (GLfloat f) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glFogCoorddEXT) (GLdouble f) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glFogCoordfvEXT) (const GLfloat *f) = NULL;
+static void (WINE_GLAPI *old_fogcoord_glFogCoorddvEXT) (const GLdouble *f) = NULL;
+
+static void WINE_GLAPI wine_glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
+ struct wined3d_context *ctx = context_get_current();
+ if(ctx->gl_fog_source == GL_FOG_COORDINATE_EXT && ctx->fog_enabled) {
+ GLfloat c[4] = {ctx->color[0], ctx->color[1], ctx->color[2], ctx->color[3]};
+ GLfloat i;
+
+ i = (ctx->fogend - ctx->fog_coord_value) / (ctx->fogend - ctx->fogstart);
+ c[0] = i * c[0] + (1.0f - i) * ctx->fogcolor[0];
+ c[1] = i * c[1] + (1.0f - i) * ctx->fogcolor[1];
+ c[2] = i * c[2] + (1.0f - i) * ctx->fogcolor[2];
+
+ old_fogcoord_glColor4f(c[0], c[1], c[2], c[3]);
+ old_fogcoord_glVertex4f(x, y, z, w);
+ } else {
+ old_fogcoord_glVertex4f(x, y, z, w);
+ }
+}
+
+static void WINE_GLAPI wine_glVertex4fv(const GLfloat *pos) {
+ wine_glVertex4f(pos[0], pos[1], pos[2], pos[3]);
+}
+
+static void WINE_GLAPI wine_glVertex3f(GLfloat x, GLfloat y, GLfloat z) {
+ wine_glVertex4f(x, y, z, 1.0f);
+}
+
+static void WINE_GLAPI wine_glVertex3fv(const GLfloat *pos) {
+ wine_glVertex4f(pos[0], pos[1], pos[2], 1.0f);
+}
+
+static void WINE_GLAPI wine_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
+ struct wined3d_context *ctx = context_get_current();
+ ctx->color[0] = r;
+ ctx->color[1] = g;
+ ctx->color[2] = b;
+ ctx->color[3] = a;
+ old_fogcoord_glColor4f(r, g, b, a);
+}
+
+static void WINE_GLAPI wine_glColor4fv(const GLfloat *c) {
+ wine_glColor4f(c[0], c[1], c[2], c[3]);
+}
+
+static void WINE_GLAPI wine_glColor3f(GLfloat r, GLfloat g, GLfloat b) {
+ wine_glColor4f(r, g, b, 1.0f);
+}
+
+static void WINE_GLAPI wine_glColor3fv(const GLfloat *c) {
+ wine_glColor4f(c[0], c[1], c[2], 1.0f);
+}
+
+static void WINE_GLAPI wine_glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a) {
+ wine_glColor4f(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
+}
+
+/* In D3D the fog coord is a UBYTE, so there's no problem with using the single
+ * precision function
+ */
+static void WINE_GLAPI wine_glFogCoordfEXT(GLfloat f) {
+ struct wined3d_context *ctx = context_get_current();
+ ctx->fog_coord_value = f;
+}
+static void WINE_GLAPI wine_glFogCoorddEXT(GLdouble f) {
+ wine_glFogCoordfEXT((GLfloat) f);
+}
+static void WINE_GLAPI wine_glFogCoordfvEXT(const GLfloat *f) {
+ wine_glFogCoordfEXT(*f);
+}
+static void WINE_GLAPI wine_glFogCoorddvEXT(const GLdouble *f) {
+ wine_glFogCoordfEXT((GLfloat) *f);
+}
+
+/* End GL_EXT_fog_coord emulation */
+
+void add_gl_compat_wrappers(struct wined3d_gl_info *gl_info)
+{
+ if (!gl_info->supported[ARB_MULTITEXTURE])
+ {
+ TRACE("Applying GL_ARB_multitexture emulation hooks\n");
+ gl_info->gl_ops.ext.p_glActiveTextureARB = wine_glActiveTextureARB;
+ gl_info->gl_ops.ext.p_glClientActiveTextureARB = wine_glClientActiveTextureARB;
+ gl_info->gl_ops.ext.p_glMultiTexCoord1fARB = wine_glMultiTexCoord1fARB;
+ gl_info->gl_ops.ext.p_glMultiTexCoord1fvARB = wine_glMultiTexCoord1fvARB;
+ gl_info->gl_ops.ext.p_glMultiTexCoord2fARB = wine_glMultiTexCoord2fARB;
+ gl_info->gl_ops.ext.p_glMultiTexCoord2fvARB = wine_glMultiTexCoord2fvARB;
+ gl_info->gl_ops.ext.p_glMultiTexCoord3fARB = wine_glMultiTexCoord3fARB;
+ gl_info->gl_ops.ext.p_glMultiTexCoord3fvARB = wine_glMultiTexCoord3fvARB;
+ gl_info->gl_ops.ext.p_glMultiTexCoord4fARB = wine_glMultiTexCoord4fARB;
+ gl_info->gl_ops.ext.p_glMultiTexCoord4fvARB = wine_glMultiTexCoord4fvARB;
+ gl_info->gl_ops.ext.p_glMultiTexCoord2svARB = wine_glMultiTexCoord2svARB;
+ gl_info->gl_ops.ext.p_glMultiTexCoord4svARB = wine_glMultiTexCoord4svARB;
+ if(old_multitex_glGetIntegerv) {
+ FIXME("GL_ARB_multitexture glGetIntegerv hook already applied\n");
+ } else {
+ old_multitex_glGetIntegerv = gl_info->gl_ops.gl.p_glGetIntegerv;
+ gl_info->gl_ops.gl.p_glGetIntegerv = wine_glGetIntegerv;
+ }
+ if(old_multitex_glGetFloatv) {
+ FIXME("GL_ARB_multitexture glGetGloatv hook already applied\n");
+ } else {
+ old_multitex_glGetFloatv = gl_info->gl_ops.gl.p_glGetFloatv;
+ gl_info->gl_ops.gl.p_glGetFloatv = wine_glGetFloatv;
+ }
+ if(old_multitex_glGetDoublev) {
+ FIXME("GL_ARB_multitexture glGetDoublev hook already applied\n");
+ } else {
+ old_multitex_glGetDoublev = gl_info->gl_ops.gl.p_glGetDoublev;
+ gl_info->gl_ops.gl.p_glGetDoublev = wine_glGetDoublev;
+ }
+ gl_info->supported[ARB_MULTITEXTURE] = TRUE;
+ }
+
+ if (!gl_info->supported[EXT_FOG_COORD])
+ {
+ /* This emulation isn't perfect. There are a number of potential problems, but they should
+ * not matter in practise:
+ *
+ * Fog vs fragment shader: If we are using GL_ARB_fragment_program with the fog option, the
+ * glDisable(GL_FOG) here won't matter. However, if we have GL_ARB_fragment_program, it is pretty
+ * unlikely that we don't have GL_EXT_fog_coord. Besides, we probably have GL_ARB_vertex_program
+ * too, which would allow fog coord emulation in a fixed function vertex pipeline replacement.
+ *
+ * Fog vs texture: We apply the fog in the vertex color. An app could set up texturing settings which
+ * ignore the vertex color, thus effectively disabling our fog. However, in D3D this type of fog is
+ * a per-vertex fog too, so the apps shouldn't do that.
+ *
+ * Fog vs lighting: The app could in theory use D3DFOG_NONE table and D3DFOG_NONE vertex fog with
+ * untransformed vertices. That enables lighting and fog coords at the same time, and the lighting
+ * calculations could affect the already blended in fog color. There's nothing we can do against that,
+ * but most apps using fog color do their own lighting too and often even use RHW vertices. So live
+ * with it.
+ */
+ TRACE("Applying GL_ARB_fog_coord emulation hooks\n");
+
+ /* This probably means that the implementation doesn't advertise the extension, but implicitly supports
+ * it via the GL core version, or someone messed around in the extension table in directx.c. Add version-
+ * dependent loading for this extension if we ever hit this situation
+ */
+ if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
+ {
+ FIXME("GL implementation supports GL_ARB_fragment_program but not GL_EXT_fog_coord\n");
+ FIXME("The fog coord emulation will most likely fail\n");
+ }
+ else if (gl_info->supported[ARB_FRAGMENT_SHADER])
+ {
+ FIXME("GL implementation supports GL_ARB_fragment_shader but not GL_EXT_fog_coord\n");
+ FIXME("The fog coord emulation will most likely fail\n");
+ }
+
+ if(old_fogcoord_glFogi) {
+ FIXME("GL_EXT_fogcoord glFogi hook already applied\n");
+ } else {
+ old_fogcoord_glFogi = gl_info->gl_ops.gl.p_glFogi;
+ gl_info->gl_ops.gl.p_glFogi = wine_glFogi;
+ }
+ if(old_fogcoord_glFogiv) {
+ FIXME("GL_EXT_fogcoord glFogiv hook already applied\n");
+ } else {
+ old_fogcoord_glFogiv = gl_info->gl_ops.gl.p_glFogiv;
+ gl_info->gl_ops.gl.p_glFogiv = wine_glFogiv;
+ }
+ if(old_fogcoord_glFogf) {
+ FIXME("GL_EXT_fogcoord glFogf hook already applied\n");
+ } else {
+ old_fogcoord_glFogf = gl_info->gl_ops.gl.p_glFogf;
+ gl_info->gl_ops.gl.p_glFogf = wine_glFogf;
+ }
+ if(old_fogcoord_glFogfv) {
+ FIXME("GL_EXT_fogcoord glFogfv hook already applied\n");
+ } else {
+ old_fogcoord_glFogfv = gl_info->gl_ops.gl.p_glFogfv;
+ gl_info->gl_ops.gl.p_glFogfv = wine_glFogfv;
+ }
+ if(old_fogcoord_glEnable) {
+ FIXME("GL_EXT_fogcoord glEnable hook already applied\n");
+ } else {
+ old_fogcoord_glEnable = glEnableWINE;
+ glEnableWINE = wine_glEnable;
+ }
+ if(old_fogcoord_glDisable) {
+ FIXME("GL_EXT_fogcoord glDisable hook already applied\n");
+ } else {
+ old_fogcoord_glDisable = glDisableWINE;
+ glDisableWINE = wine_glDisable;
+ }
+
+ if(old_fogcoord_glVertex4f) {
+ FIXME("GL_EXT_fogcoord glVertex4f hook already applied\n");
+ } else {
+ old_fogcoord_glVertex4f = gl_info->gl_ops.gl.p_glVertex4f;
+ gl_info->gl_ops.gl.p_glVertex4f = wine_glVertex4f;
+ }
+ if(old_fogcoord_glVertex4fv) {
+ FIXME("GL_EXT_fogcoord glVertex4fv hook already applied\n");
+ } else {
+ old_fogcoord_glVertex4fv = gl_info->gl_ops.gl.p_glVertex4fv;
+ gl_info->gl_ops.gl.p_glVertex4fv = wine_glVertex4fv;
+ }
+ if(old_fogcoord_glVertex3f) {
+ FIXME("GL_EXT_fogcoord glVertex3f hook already applied\n");
+ } else {
+ old_fogcoord_glVertex3f = gl_info->gl_ops.gl.p_glVertex3f;
+ gl_info->gl_ops.gl.p_glVertex3f = wine_glVertex3f;
+ }
+ if(old_fogcoord_glVertex3fv) {
+ FIXME("GL_EXT_fogcoord glVertex3fv hook already applied\n");
+ } else {
+ old_fogcoord_glVertex3fv = gl_info->gl_ops.gl.p_glVertex3fv;
+ gl_info->gl_ops.gl.p_glVertex3fv = wine_glVertex3fv;
+ }
+
+ if(old_fogcoord_glColor4f) {
+ FIXME("GL_EXT_fogcoord glColor4f hook already applied\n");
+ } else {
+ old_fogcoord_glColor4f = gl_info->gl_ops.gl.p_glColor4f;
+ gl_info->gl_ops.gl.p_glColor4f = wine_glColor4f;
+ }
+ if(old_fogcoord_glColor4fv) {
+ FIXME("GL_EXT_fogcoord glColor4fv hook already applied\n");
+ } else {
+ old_fogcoord_glColor4fv = gl_info->gl_ops.gl.p_glColor4fv;
+ gl_info->gl_ops.gl.p_glColor4fv = wine_glColor4fv;
+ }
+ if(old_fogcoord_glColor3f) {
+ FIXME("GL_EXT_fogcoord glColor3f hook already applied\n");
+ } else {
+ old_fogcoord_glColor3f = gl_info->gl_ops.gl.p_glColor3f;
+ gl_info->gl_ops.gl.p_glColor3f = wine_glColor3f;
+ }
+ if(old_fogcoord_glColor3fv) {
+ FIXME("GL_EXT_fogcoord glColor3fv hook already applied\n");
+ } else {
+ old_fogcoord_glColor3fv = gl_info->gl_ops.gl.p_glColor3fv;
+ gl_info->gl_ops.gl.p_glColor3fv = wine_glColor3fv;
+ }
+ if(old_fogcoord_glColor4ub) {
+ FIXME("GL_EXT_fogcoord glColor4ub hook already applied\n");
+ } else {
+ old_fogcoord_glColor4ub = gl_info->gl_ops.gl.p_glColor4ub;
+ gl_info->gl_ops.gl.p_glColor4ub = wine_glColor4ub;
+ }
+
+ if(old_fogcoord_glFogCoordfEXT) {
+ FIXME("GL_EXT_fogcoord glFogCoordfEXT hook already applied\n");
+ } else {
+ old_fogcoord_glFogCoordfEXT = gl_info->gl_ops.ext.p_glFogCoordfEXT;
+ gl_info->gl_ops.ext.p_glFogCoordfEXT = wine_glFogCoordfEXT;
+ }
+ if(old_fogcoord_glFogCoordfvEXT) {
+ FIXME("GL_EXT_fogcoord glFogCoordfvEXT hook already applied\n");
+ } else {
+ old_fogcoord_glFogCoordfvEXT = gl_info->gl_ops.ext.p_glFogCoordfvEXT;
+ gl_info->gl_ops.ext.p_glFogCoordfvEXT = wine_glFogCoordfvEXT;
+ }
+ if(old_fogcoord_glFogCoorddEXT) {
+ FIXME("GL_EXT_fogcoord glFogCoorddEXT hook already applied\n");
+ } else {
+ old_fogcoord_glFogCoorddEXT = gl_info->gl_ops.ext.p_glFogCoorddEXT;
+ gl_info->gl_ops.ext.p_glFogCoorddEXT = wine_glFogCoorddEXT;
+ }
+ if(old_fogcoord_glFogCoorddvEXT) {
+ FIXME("GL_EXT_fogcoord glFogCoorddvEXT hook already applied\n");
+ } else {
+ old_fogcoord_glFogCoorddvEXT = gl_info->gl_ops.ext.p_glFogCoorddvEXT;
+ gl_info->gl_ops.ext.p_glFogCoorddvEXT = wine_glFogCoorddvEXT;
+ }
+ gl_info->supported[EXT_FOG_COORD] = TRUE;
+ }
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/glsl_shader.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/glsl_shader.c
new file mode 100644
index 00000000..3b14b33c
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/glsl_shader.c
@@ -0,0 +1,7350 @@
+/*
+ * GLSL pixel and vertex shader implementation
+ *
+ * Copyright 2006 Jason Green
+ * Copyright 2006-2007 Henri Verbeet
+ * Copyright 2007-2009, 2013 Stefan Dösinger for CodeWeavers
+ * Copyright 2009-2011 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+/*
+ * D3D shader asm has swizzles on source parameters, and write masks for
+ * destination parameters. GLSL uses swizzles for both. The result of this is
+ * that for example "mov dst.xw, src.zyxw" becomes "dst.xw = src.zw" in GLSL.
+ * Ie, to generate a proper GLSL source swizzle, we need to take the D3D write
+ * mask for the destination parameter into account.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <limits.h>
+#include <stdio.h>
+
+#include "wined3d_private.h"
+
+#if defined(VBOX)
+# if defined(RT_ARCH_AMD64)
+# define copysignf _copysignf
+# else
+# define _VBOX_BITVAL_CAST(_t, _f) (*((const _t*)((const void*)(&(_f)))))
+# define _VBOX_BITVAL_TO_FLOATL(_f) _VBOX_BITVAL_CAST(float, _f)
+# define _VBOX_BITVAL_FROM_FLOAT(_f) _VBOX_BITVAL_CAST(uint32_t, _f)
+DECLINLINE(float) copysignf(float val, float sign)
+{
+ uint32_t u32Val = ((_VBOX_BITVAL_FROM_FLOAT(val) & 0x7fffffff) | (_VBOX_BITVAL_FROM_FLOAT(sign) & 0x80000000));
+ return _VBOX_BITVAL_TO_FLOATL(u32Val);
+}
+# endif
+#endif
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_constants);
+WINE_DECLARE_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(winediag);
+
+#define WINED3D_GLSL_SAMPLE_PROJECTED 0x1
+#define WINED3D_GLSL_SAMPLE_NPOT 0x2
+#define WINED3D_GLSL_SAMPLE_LOD 0x4
+#define WINED3D_GLSL_SAMPLE_GRAD 0x8
+
+static const float srgb_const0[] = {0.41666f, 1.055f, 0.055f, 12.92f}; /* pow, mul_high, sub_high, mul_low */
+static const float srgb_const1[] = {0.0031308f, 0.0f, 0.0f, 0.0f}; /* cmp */
+
+struct glsl_dst_param
+{
+ char reg_name[150];
+ char mask_str[6];
+};
+
+struct glsl_src_param
+{
+ char reg_name[150];
+ char param_str[200];
+};
+
+struct glsl_sample_function
+{
+ const char *name;
+ DWORD coord_mask;
+};
+
+enum heap_node_op
+{
+ HEAP_NODE_TRAVERSE_LEFT,
+ HEAP_NODE_TRAVERSE_RIGHT,
+ HEAP_NODE_POP,
+};
+
+struct constant_entry
+{
+ unsigned int idx;
+ unsigned int version;
+};
+
+struct constant_heap
+{
+ struct constant_entry *entries;
+ unsigned int *positions;
+ unsigned int size;
+};
+
+/* GLSL shader private data */
+struct shader_glsl_priv {
+ struct wined3d_shader_buffer shader_buffer;
+ struct wine_rb_tree program_lookup;
+ struct glsl_shader_prog_link *glsl_program;
+ struct constant_heap vconst_heap;
+ struct constant_heap pconst_heap;
+ unsigned char *stack;
+ GLhandleARB depth_blt_program_full[tex_type_count];
+ GLhandleARB depth_blt_program_masked[tex_type_count];
+ UINT next_constant_version;
+
+ const struct wined3d_vertex_pipe_ops *vertex_pipe;
+ const struct fragment_pipeline *fragment_pipe;
+ struct wine_rb_tree ffp_vertex_shaders;
+ struct wine_rb_tree ffp_fragment_shaders;
+ BOOL ffp_proj_control;
+};
+
+struct glsl_vs_program
+{
+ struct list shader_entry;
+ GLhandleARB id;
+ GLenum vertex_color_clamp;
+ GLint *uniform_f_locations;
+ GLint uniform_i_locations[MAX_CONST_I];
+ GLint pos_fixup_location;
+};
+
+struct glsl_gs_program
+{
+ struct list shader_entry;
+ GLhandleARB id;
+};
+
+struct glsl_ps_program
+{
+ struct list shader_entry;
+ GLhandleARB id;
+ GLint *uniform_f_locations;
+ GLint uniform_i_locations[MAX_CONST_I];
+ GLint bumpenv_mat_location[MAX_TEXTURES];
+ GLint bumpenv_lum_scale_location[MAX_TEXTURES];
+ GLint bumpenv_lum_offset_location[MAX_TEXTURES];
+ GLint tex_factor_location;
+ GLint specular_enable_location;
+ GLint ycorrection_location;
+ GLint np2_fixup_location;
+ const struct ps_np2fixup_info *np2_fixup_info;
+};
+
+/* Struct to maintain data about a linked GLSL program */
+struct glsl_shader_prog_link
+{
+ struct wine_rb_entry program_lookup_entry;
+ struct glsl_vs_program vs;
+ struct glsl_gs_program gs;
+ struct glsl_ps_program ps;
+ GLhandleARB programId;
+ UINT constant_version;
+};
+
+struct glsl_program_key
+{
+ GLhandleARB vs_id;
+ GLhandleARB gs_id;
+ GLhandleARB ps_id;
+};
+
+struct shader_glsl_ctx_priv {
+ const struct vs_compile_args *cur_vs_args;
+ const struct ps_compile_args *cur_ps_args;
+ struct ps_np2fixup_info *cur_np2fixup_info;
+};
+
+struct glsl_ps_compiled_shader
+{
+ struct ps_compile_args args;
+ struct ps_np2fixup_info np2fixup;
+ GLhandleARB prgId;
+};
+
+struct glsl_vs_compiled_shader
+{
+ struct vs_compile_args args;
+ GLhandleARB prgId;
+};
+
+struct glsl_gs_compiled_shader
+{
+ GLhandleARB id;
+};
+
+struct glsl_shader_private
+{
+ union
+ {
+ struct glsl_vs_compiled_shader *vs;
+ struct glsl_gs_compiled_shader *gs;
+ struct glsl_ps_compiled_shader *ps;
+ } gl_shaders;
+ UINT num_gl_shaders, shader_array_size;
+};
+
+struct glsl_ffp_vertex_shader
+{
+ struct wined3d_ffp_vs_desc desc;
+ GLhandleARB id;
+ struct list linked_programs;
+};
+
+struct glsl_ffp_fragment_shader
+{
+ struct ffp_frag_desc entry;
+ GLhandleARB id;
+ struct list linked_programs;
+};
+
+struct glsl_ffp_destroy_ctx
+{
+ struct shader_glsl_priv *priv;
+ const struct wined3d_gl_info *gl_info;
+#ifdef VBOX_WITH_WINE_FIX_SHADERCLEANUP
+ struct wined3d_context *context;
+#endif
+};
+
+static const char *debug_gl_shader_type(GLenum type)
+{
+ switch (type)
+ {
+#define WINED3D_TO_STR(u) case u: return #u
+ WINED3D_TO_STR(GL_VERTEX_SHADER_ARB);
+ WINED3D_TO_STR(GL_GEOMETRY_SHADER_ARB);
+ WINED3D_TO_STR(GL_FRAGMENT_SHADER_ARB);
+#undef WINED3D_TO_STR
+ default:
+ return wine_dbg_sprintf("UNKNOWN(%#x)", type);
+ }
+}
+
+static const char *shader_glsl_get_prefix(enum wined3d_shader_type type)
+{
+ switch (type)
+ {
+ case WINED3D_SHADER_TYPE_VERTEX:
+ return "vs";
+
+ case WINED3D_SHADER_TYPE_GEOMETRY:
+ return "gs";
+
+ case WINED3D_SHADER_TYPE_PIXEL:
+ return "ps";
+
+ default:
+ FIXME("Unhandled shader type %#x.\n", type);
+ return "unknown";
+ }
+}
+
+/* This should be equivalent to using the %.8e format specifier, but always
+ * using '.' as decimal separator. This doesn't handle +/-INF or NAN, since
+ * the GLSL parser wouldn't be able to handle those anyway. */
+static void shader_glsl_ftoa(float value, char *s)
+{
+ int x, frac, exponent;
+ const char *sign = "";
+ double d;
+
+ d = value;
+ if (copysignf(1.0f, value) < 0.0f)
+ {
+ d = -d;
+ sign = "-";
+ }
+
+ if (d == 0.0f)
+ {
+ x = 0;
+ frac = 0;
+ exponent = 0;
+ }
+ else
+ {
+ double t, diff;
+
+ exponent = floorf(log10f(d));
+ d /= pow(10.0, exponent);
+
+ x = d;
+ t = (d - x) * 100000000;
+ frac = t;
+ diff = t - frac;
+
+ if ((diff > 0.5) || (diff == 0.5 && (frac & 1)))
+ {
+ if (++frac >= 100000000)
+ {
+ frac = 0;
+ ++x;
+ }
+ }
+ }
+
+ sprintf(s, "%s%d.%08de%+03d", sign, x, frac, exponent);
+}
+
+static void shader_glsl_append_imm_vec4(struct wined3d_shader_buffer *buffer, const float *values)
+{
+ char str[4][16];
+
+ shader_glsl_ftoa(values[0], str[0]);
+ shader_glsl_ftoa(values[1], str[1]);
+ shader_glsl_ftoa(values[2], str[2]);
+ shader_glsl_ftoa(values[3], str[3]);
+ shader_addline(buffer, "vec4(%s, %s, %s, %s)", str[0], str[1], str[2], str[3]);
+}
+
+/* Extract a line from the info log.
+ * Note that this modifies the source string. */
+static char *get_info_log_line(char **ptr)
+{
+ char *p, *q;
+
+ p = *ptr;
+ if (!(q = strstr(p, "\n")))
+ {
+ if (!*p) return NULL;
+ *ptr += strlen(p);
+ return p;
+ }
+ *q = '\0';
+ *ptr = q + 1;
+
+ return p;
+}
+
+/* Context activation is done by the caller. */
+static void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLhandleARB obj)
+{
+ int infologLength = 0;
+ char *infoLog;
+
+ if (!WARN_ON(d3d_shader) && !FIXME_ON(d3d_shader))
+ return;
+
+ GL_EXTCALL(glGetObjectParameterivARB(obj,
+ GL_OBJECT_INFO_LOG_LENGTH_ARB,
+ &infologLength));
+
+ /* A size of 1 is just a null-terminated string, so the log should be bigger than
+ * that if there are errors. */
+ if (infologLength > 1)
+ {
+ char *ptr, *line;
+
+ infoLog = HeapAlloc(GetProcessHeap(), 0, infologLength);
+ /* The info log is supposed to be zero-terminated, but at least some
+ * versions of fglrx don't terminate the string properly. The reported
+ * length does include the terminator, so explicitly set it to zero
+ * here. */
+ infoLog[infologLength - 1] = 0;
+ GL_EXTCALL(glGetInfoLogARB(obj, infologLength, NULL, infoLog));
+
+ ptr = infoLog;
+ if (gl_info->quirks & WINED3D_QUIRK_INFO_LOG_SPAM)
+ {
+ WARN("Info log received from GLSL shader #%u:\n", obj);
+ while ((line = get_info_log_line(&ptr))) WARN(" %s\n", line);
+ }
+ else
+ {
+ FIXME("Info log received from GLSL shader #%u:\n", obj);
+ while ((line = get_info_log_line(&ptr))) FIXME(" %s\n", line);
+ }
+ HeapFree(GetProcessHeap(), 0, infoLog);
+ }
+}
+
+/* Context activation is done by the caller. */
+static void shader_glsl_compile(const struct wined3d_gl_info *gl_info, GLhandleARB shader, const char *src)
+{
+ TRACE("Compiling shader object %u.\n", shader);
+ GL_EXTCALL(glShaderSourceARB(shader, 1, &src, NULL));
+ checkGLcall("glShaderSourceARB");
+ GL_EXTCALL(glCompileShaderARB(shader));
+ checkGLcall("glCompileShaderARB");
+ print_glsl_info_log(gl_info, shader);
+}
+
+/* Context activation is done by the caller. */
+static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_info, GLhandleARB program)
+{
+ GLint i, object_count, source_size = -1;
+ GLhandleARB *objects;
+ char *source = NULL;
+
+ GL_EXTCALL(glGetObjectParameterivARB(program, GL_OBJECT_ATTACHED_OBJECTS_ARB, &object_count));
+ objects = HeapAlloc(GetProcessHeap(), 0, object_count * sizeof(*objects));
+ if (!objects)
+ {
+ ERR("Failed to allocate object array memory.\n");
+ return;
+ }
+
+ GL_EXTCALL(glGetAttachedObjectsARB(program, object_count, NULL, objects));
+ for (i = 0; i < object_count; ++i)
+ {
+ char *ptr, *line;
+ GLint tmp;
+
+ GL_EXTCALL(glGetObjectParameterivARB(objects[i], GL_OBJECT_SHADER_SOURCE_LENGTH_ARB, &tmp));
+
+ if (source_size < tmp)
+ {
+ HeapFree(GetProcessHeap(), 0, source);
+
+ source = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, tmp);
+ if (!source)
+ {
+ ERR("Failed to allocate %d bytes for shader source.\n", tmp);
+ HeapFree(GetProcessHeap(), 0, objects);
+ return;
+ }
+ source_size = tmp;
+ }
+
+ FIXME("Object %u:\n", objects[i]);
+ GL_EXTCALL(glGetObjectParameterivARB(objects[i], GL_OBJECT_SUBTYPE_ARB, &tmp));
+ FIXME(" GL_OBJECT_SUBTYPE_ARB: %s.\n", debug_gl_shader_type(tmp));
+ GL_EXTCALL(glGetObjectParameterivARB(objects[i], GL_OBJECT_COMPILE_STATUS_ARB, &tmp));
+ FIXME(" GL_OBJECT_COMPILE_STATUS_ARB: %d.\n", tmp);
+ FIXME("\n");
+
+ ptr = source;
+ GL_EXTCALL(glGetShaderSourceARB(objects[i], source_size, NULL, source));
+ while ((line = get_info_log_line(&ptr))) FIXME(" %s\n", line);
+ FIXME("\n");
+ }
+
+ HeapFree(GetProcessHeap(), 0, source);
+ HeapFree(GetProcessHeap(), 0, objects);
+}
+
+/* Context activation is done by the caller. */
+static void shader_glsl_validate_link(const struct wined3d_gl_info *gl_info, GLhandleARB program)
+{
+ GLint tmp;
+
+ if (!TRACE_ON(d3d_shader) && !FIXME_ON(d3d_shader)) return;
+
+ GL_EXTCALL(glGetObjectParameterivARB(program, GL_OBJECT_TYPE_ARB, &tmp));
+ if (tmp == GL_PROGRAM_OBJECT_ARB)
+ {
+ GL_EXTCALL(glGetObjectParameterivARB(program, GL_OBJECT_LINK_STATUS_ARB, &tmp));
+ if (!tmp)
+ {
+ FIXME("Program %u link status invalid.\n", program);
+ shader_glsl_dump_program_source(gl_info, program);
+ }
+ }
+
+ print_glsl_info_log(gl_info, program);
+}
+
+/* Context activation is done by the caller. */
+static void shader_glsl_load_psamplers(const struct wined3d_gl_info *gl_info,
+ const DWORD *tex_unit_map, GLhandleARB programId)
+{
+ GLint name_loc;
+ char sampler_name[20];
+ unsigned int i;
+
+ for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
+ {
+ snprintf(sampler_name, sizeof(sampler_name), "ps_sampler%u", i);
+ name_loc = GL_EXTCALL(glGetUniformLocationARB(programId, sampler_name));
+ if (name_loc != -1) {
+ DWORD mapped_unit = tex_unit_map[i];
+ if (mapped_unit != WINED3D_UNMAPPED_STAGE && mapped_unit < gl_info->limits.fragment_samplers)
+ {
+ TRACE("Loading %s for texture %d\n", sampler_name, mapped_unit);
+ GL_EXTCALL(glUniform1iARB(name_loc, mapped_unit));
+ checkGLcall("glUniform1iARB");
+ } else {
+ ERR("Trying to load sampler %s on unsupported unit %d\n", sampler_name, mapped_unit);
+ }
+ }
+ }
+}
+
+/* Context activation is done by the caller. */
+static void shader_glsl_load_vsamplers(const struct wined3d_gl_info *gl_info,
+ const DWORD *tex_unit_map, GLhandleARB programId)
+{
+ GLint name_loc;
+ char sampler_name[20];
+ unsigned int i;
+
+ for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i)
+ {
+ snprintf(sampler_name, sizeof(sampler_name), "vs_sampler%u", i);
+ name_loc = GL_EXTCALL(glGetUniformLocationARB(programId, sampler_name));
+ if (name_loc != -1) {
+ DWORD mapped_unit = tex_unit_map[MAX_FRAGMENT_SAMPLERS + i];
+ if (mapped_unit != WINED3D_UNMAPPED_STAGE && mapped_unit < gl_info->limits.combined_samplers)
+ {
+ TRACE("Loading %s for texture %d\n", sampler_name, mapped_unit);
+ GL_EXTCALL(glUniform1iARB(name_loc, mapped_unit));
+ checkGLcall("glUniform1iARB");
+ } else {
+ ERR("Trying to load sampler %s on unsupported unit %d\n", sampler_name, mapped_unit);
+ }
+ }
+ }
+}
+
+/* Context activation is done by the caller. */
+static inline void walk_constant_heap(const struct wined3d_gl_info *gl_info, const float *constants,
+ const GLint *constant_locations, const struct constant_heap *heap, unsigned char *stack, DWORD version)
+{
+ int stack_idx = 0;
+ unsigned int heap_idx = 1;
+ unsigned int idx;
+
+ if (heap->entries[heap_idx].version <= version) return;
+
+ idx = heap->entries[heap_idx].idx;
+ if (constant_locations[idx] != -1) GL_EXTCALL(glUniform4fvARB(constant_locations[idx], 1, &constants[idx * 4]));
+ stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
+
+ while (stack_idx >= 0)
+ {
+ /* Note that we fall through to the next case statement. */
+ switch(stack[stack_idx])
+ {
+ case HEAP_NODE_TRAVERSE_LEFT:
+ {
+ unsigned int left_idx = heap_idx << 1;
+ if (left_idx < heap->size && heap->entries[left_idx].version > version)
+ {
+ heap_idx = left_idx;
+ idx = heap->entries[heap_idx].idx;
+ if (constant_locations[idx] != -1)
+ GL_EXTCALL(glUniform4fvARB(constant_locations[idx], 1, &constants[idx * 4]));
+
+ stack[stack_idx++] = HEAP_NODE_TRAVERSE_RIGHT;
+ stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
+ break;
+ }
+ }
+
+ case HEAP_NODE_TRAVERSE_RIGHT:
+ {
+ unsigned int right_idx = (heap_idx << 1) + 1;
+ if (right_idx < heap->size && heap->entries[right_idx].version > version)
+ {
+ heap_idx = right_idx;
+ idx = heap->entries[heap_idx].idx;
+ if (constant_locations[idx] != -1)
+ GL_EXTCALL(glUniform4fvARB(constant_locations[idx], 1, &constants[idx * 4]));
+
+ stack[stack_idx++] = HEAP_NODE_POP;
+ stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
+ break;
+ }
+ }
+
+ case HEAP_NODE_POP:
+ heap_idx >>= 1;
+ --stack_idx;
+ break;
+ }
+ }
+ checkGLcall("walk_constant_heap()");
+}
+
+/* Context activation is done by the caller. */
+static inline void apply_clamped_constant(const struct wined3d_gl_info *gl_info, GLint location, const GLfloat *data)
+{
+ GLfloat clamped_constant[4];
+
+ if (location == -1) return;
+
+ clamped_constant[0] = data[0] < -1.0f ? -1.0f : data[0] > 1.0f ? 1.0f : data[0];
+ clamped_constant[1] = data[1] < -1.0f ? -1.0f : data[1] > 1.0f ? 1.0f : data[1];
+ clamped_constant[2] = data[2] < -1.0f ? -1.0f : data[2] > 1.0f ? 1.0f : data[2];
+ clamped_constant[3] = data[3] < -1.0f ? -1.0f : data[3] > 1.0f ? 1.0f : data[3];
+
+ GL_EXTCALL(glUniform4fvARB(location, 1, clamped_constant));
+}
+
+/* Context activation is done by the caller. */
+static inline void walk_constant_heap_clamped(const struct wined3d_gl_info *gl_info, const float *constants,
+ const GLint *constant_locations, const struct constant_heap *heap, unsigned char *stack, DWORD version)
+{
+ int stack_idx = 0;
+ unsigned int heap_idx = 1;
+ unsigned int idx;
+
+ if (heap->entries[heap_idx].version <= version) return;
+
+ idx = heap->entries[heap_idx].idx;
+ apply_clamped_constant(gl_info, constant_locations[idx], &constants[idx * 4]);
+ stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
+
+ while (stack_idx >= 0)
+ {
+ /* Note that we fall through to the next case statement. */
+ switch(stack[stack_idx])
+ {
+ case HEAP_NODE_TRAVERSE_LEFT:
+ {
+ unsigned int left_idx = heap_idx << 1;
+ if (left_idx < heap->size && heap->entries[left_idx].version > version)
+ {
+ heap_idx = left_idx;
+ idx = heap->entries[heap_idx].idx;
+ apply_clamped_constant(gl_info, constant_locations[idx], &constants[idx * 4]);
+
+ stack[stack_idx++] = HEAP_NODE_TRAVERSE_RIGHT;
+ stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
+ break;
+ }
+ }
+
+ case HEAP_NODE_TRAVERSE_RIGHT:
+ {
+ unsigned int right_idx = (heap_idx << 1) + 1;
+ if (right_idx < heap->size && heap->entries[right_idx].version > version)
+ {
+ heap_idx = right_idx;
+ idx = heap->entries[heap_idx].idx;
+ apply_clamped_constant(gl_info, constant_locations[idx], &constants[idx * 4]);
+
+ stack[stack_idx++] = HEAP_NODE_POP;
+ stack[stack_idx] = HEAP_NODE_TRAVERSE_LEFT;
+ break;
+ }
+ }
+
+ case HEAP_NODE_POP:
+ heap_idx >>= 1;
+ --stack_idx;
+ break;
+ }
+ }
+ checkGLcall("walk_constant_heap_clamped()");
+}
+
+/* Context activation is done by the caller. */
+static void shader_glsl_load_constantsF(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info,
+ const float *constants, const GLint *constant_locations, const struct constant_heap *heap,
+ unsigned char *stack, UINT version)
+{
+ const struct wined3d_shader_lconst *lconst;
+
+ /* 1.X pshaders have the constants clamped to [-1;1] implicitly. */
+ if (shader->reg_maps.shader_version.major == 1
+ && shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
+ walk_constant_heap_clamped(gl_info, constants, constant_locations, heap, stack, version);
+ else
+ walk_constant_heap(gl_info, constants, constant_locations, heap, stack, version);
+
+ if (!shader->load_local_constsF)
+ {
+ TRACE("No need to load local float constants for this shader\n");
+ return;
+ }
+
+ /* Immediate constants are clamped to [-1;1] at shader creation time if needed */
+ LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
+ {
+ GL_EXTCALL(glUniform4fvARB(constant_locations[lconst->idx], 1, (const GLfloat *)lconst->value));
+ }
+ checkGLcall("glUniform4fvARB()");
+}
+
+/* Context activation is done by the caller. */
+static void shader_glsl_load_constantsI(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info,
+ const GLint locations[MAX_CONST_I], const int *constants, WORD constants_set)
+{
+ unsigned int i;
+ struct list* ptr;
+
+ for (i = 0; constants_set; constants_set >>= 1, ++i)
+ {
+ if (!(constants_set & 1)) continue;
+
+ TRACE_(d3d_constants)("Loading constants %u: %i, %i, %i, %i\n",
+ i, constants[i*4], constants[i*4+1], constants[i*4+2], constants[i*4+3]);
+
+ /* We found this uniform name in the program - go ahead and send the data */
+ GL_EXTCALL(glUniform4ivARB(locations[i], 1, &constants[i*4]));
+ checkGLcall("glUniform4ivARB");
+ }
+
+ /* Load immediate constants */
+ ptr = list_head(&shader->constantsI);
+ while (ptr)
+ {
+ const struct wined3d_shader_lconst *lconst = LIST_ENTRY(ptr, const struct wined3d_shader_lconst, entry);
+ unsigned int idx = lconst->idx;
+ const GLint *values = (const GLint *)lconst->value;
+
+ TRACE_(d3d_constants)("Loading local constants %i: %i, %i, %i, %i\n", idx,
+ values[0], values[1], values[2], values[3]);
+
+ /* We found this uniform name in the program - go ahead and send the data */
+ GL_EXTCALL(glUniform4ivARB(locations[idx], 1, values));
+ checkGLcall("glUniform4ivARB");
+ ptr = list_next(&shader->constantsI, ptr);
+ }
+}
+
+/* Context activation is done by the caller. */
+static void shader_glsl_load_constantsB(const struct wined3d_shader *shader, const struct wined3d_gl_info *gl_info,
+ GLhandleARB programId, const BOOL *constants, WORD constants_set)
+{
+ GLint tmp_loc;
+ unsigned int i;
+ char tmp_name[10];
+ const char *prefix;
+ struct list* ptr;
+
+ prefix = shader_glsl_get_prefix(shader->reg_maps.shader_version.type);
+
+ /* TODO: Benchmark and see if it would be beneficial to store the
+ * locations of the constants to avoid looking up each time */
+ for (i = 0; constants_set; constants_set >>= 1, ++i)
+ {
+ if (!(constants_set & 1)) continue;
+
+ TRACE_(d3d_constants)("Loading constants %i: %i;\n", i, constants[i]);
+
+ /* TODO: Benchmark and see if it would be beneficial to store the
+ * locations of the constants to avoid looking up each time */
+ snprintf(tmp_name, sizeof(tmp_name), "%s_b[%i]", prefix, i);
+ tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
+ GL_EXTCALL(glUniform1ivARB(tmp_loc, 1, &constants[i]));
+ }
+
+ /* Load immediate constants */
+ ptr = list_head(&shader->constantsB);
+ while (ptr)
+ {
+ const struct wined3d_shader_lconst *lconst = LIST_ENTRY(ptr, const struct wined3d_shader_lconst, entry);
+ unsigned int idx = lconst->idx;
+ const GLint *values = (const GLint *)lconst->value;
+
+ TRACE_(d3d_constants)("Loading local constants %i: %i\n", idx, values[0]);
+
+ snprintf(tmp_name, sizeof(tmp_name), "%s_b[%i]", prefix, idx);
+ tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
+ GL_EXTCALL(glUniform1ivARB(tmp_loc, 1, values));
+ ptr = list_next(&shader->constantsB, ptr);
+ }
+
+ checkGLcall("shader_glsl_load_constantsB()");
+}
+
+static void reset_program_constant_version(struct wine_rb_entry *entry, void *context)
+{
+ WINE_RB_ENTRY_VALUE(entry, struct glsl_shader_prog_link, program_lookup_entry)->constant_version = 0;
+}
+
+/* Context activation is done by the caller (state handler). */
+static void shader_glsl_load_np2fixup_constants(void *shader_priv,
+ const struct wined3d_gl_info *gl_info, const struct wined3d_state *state)
+{
+ struct shader_glsl_priv *glsl_priv = shader_priv;
+ const struct glsl_shader_prog_link *prog = glsl_priv->glsl_program;
+
+ /* No GLSL program set - nothing to do. */
+ if (!prog) return;
+
+ /* NP2 texcoord fixup is (currently) only done for pixelshaders. */
+ if (!use_ps(state)) return;
+
+ if (prog->ps.np2_fixup_info && prog->ps.np2_fixup_location != -1)
+ {
+ UINT i;
+ UINT fixup = prog->ps.np2_fixup_info->active;
+ GLfloat np2fixup_constants[4 * MAX_FRAGMENT_SAMPLERS];
+
+ for (i = 0; fixup; fixup >>= 1, ++i)
+ {
+ const struct wined3d_texture *tex = state->textures[i];
+ const unsigned char idx = prog->ps.np2_fixup_info->idx[i];
+ GLfloat *tex_dim = &np2fixup_constants[(idx >> 1) * 4];
+
+ if (!tex)
+ {
+ ERR("Nonexistent texture is flagged for NP2 texcoord fixup.\n");
+ continue;
+ }
+
+ if (idx % 2)
+ {
+ tex_dim[2] = tex->pow2_matrix[0];
+ tex_dim[3] = tex->pow2_matrix[5];
+ }
+ else
+ {
+ tex_dim[0] = tex->pow2_matrix[0];
+ tex_dim[1] = tex->pow2_matrix[5];
+ }
+ }
+
+ GL_EXTCALL(glUniform4fvARB(prog->ps.np2_fixup_location,
+ prog->ps.np2_fixup_info->num_consts, np2fixup_constants));
+ }
+}
+
+/* Context activation is done by the caller (state handler). */
+static void shader_glsl_load_constants(void *shader_priv, const struct wined3d_context *context,
+ const struct wined3d_state *state)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct shader_glsl_priv *priv = shader_priv;
+ float position_fixup[4];
+
+ GLhandleARB programId;
+ struct glsl_shader_prog_link *prog = priv->glsl_program;
+ UINT constant_version;
+ int i;
+
+ if (!prog) {
+ /* No GLSL program set - nothing to do. */
+ return;
+ }
+ programId = prog->programId;
+ constant_version = prog->constant_version;
+
+ if (use_vs(state))
+ {
+ const struct wined3d_shader *vshader = state->vertex_shader;
+
+ /* Load DirectX 9 float constants/uniforms for vertex shader */
+ shader_glsl_load_constantsF(vshader, gl_info, state->vs_consts_f,
+ prog->vs.uniform_f_locations, &priv->vconst_heap, priv->stack, constant_version);
+
+ /* Load DirectX 9 integer constants/uniforms for vertex shader */
+ shader_glsl_load_constantsI(vshader, gl_info, prog->vs.uniform_i_locations, state->vs_consts_i,
+ vshader->reg_maps.integer_constants);
+
+ /* Load DirectX 9 boolean constants/uniforms for vertex shader */
+ shader_glsl_load_constantsB(vshader, gl_info, programId, state->vs_consts_b,
+ vshader->reg_maps.boolean_constants);
+
+ /* Upload the position fixup params */
+ shader_get_position_fixup(context, state, position_fixup);
+ GL_EXTCALL(glUniform4fvARB(prog->vs.pos_fixup_location, 1, position_fixup));
+ checkGLcall("glUniform4fvARB");
+ }
+
+ if (use_ps(state))
+ {
+ const struct wined3d_shader *pshader = state->pixel_shader;
+
+ /* Load DirectX 9 float constants/uniforms for pixel shader */
+ shader_glsl_load_constantsF(pshader, gl_info, state->ps_consts_f,
+ prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version);
+
+ /* Load DirectX 9 integer constants/uniforms for pixel shader */
+ shader_glsl_load_constantsI(pshader, gl_info, prog->ps.uniform_i_locations, state->ps_consts_i,
+ pshader->reg_maps.integer_constants);
+
+ /* Load DirectX 9 boolean constants/uniforms for pixel shader */
+ shader_glsl_load_constantsB(pshader, gl_info, programId, state->ps_consts_b,
+ pshader->reg_maps.boolean_constants);
+
+ /* Upload the environment bump map matrix if needed. The needsbumpmat
+ * member specifies the texture stage to load the matrix from. It
+ * can't be 0 for a valid texbem instruction. */
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ const float *data;
+
+ if (prog->ps.bumpenv_mat_location[i] == -1)
+ continue;
+
+ data = (const float *)&state->texture_states[i][WINED3D_TSS_BUMPENV_MAT00];
+ GL_EXTCALL(glUniformMatrix2fvARB(prog->ps.bumpenv_mat_location[i], 1, 0, data));
+ checkGLcall("glUniformMatrix2fvARB");
+
+ /* texbeml needs the luminance scale and offset too. If texbeml
+ * is used, needsbumpmat is set too, so we can check that in the
+ * needsbumpmat check. */
+ if (prog->ps.bumpenv_lum_scale_location[i] != -1)
+ {
+ const GLfloat *scale = (const GLfloat *)&state->texture_states[i][WINED3D_TSS_BUMPENV_LSCALE];
+ const GLfloat *offset = (const GLfloat *)&state->texture_states[i][WINED3D_TSS_BUMPENV_LOFFSET];
+
+ GL_EXTCALL(glUniform1fvARB(prog->ps.bumpenv_lum_scale_location[i], 1, scale));
+ checkGLcall("glUniform1fvARB");
+ GL_EXTCALL(glUniform1fvARB(prog->ps.bumpenv_lum_offset_location[i], 1, offset));
+ checkGLcall("glUniform1fvARB");
+ }
+ }
+
+ if (prog->ps.ycorrection_location != -1)
+ {
+ float correction_params[4];
+
+ if (context->render_offscreen)
+ {
+ correction_params[0] = 0.0f;
+ correction_params[1] = 1.0f;
+ } else {
+ /* position is window relative, not viewport relative */
+ correction_params[0] = (float) context->current_rt->resource.height;
+ correction_params[1] = -1.0f;
+ }
+ GL_EXTCALL(glUniform4fvARB(prog->ps.ycorrection_location, 1, correction_params));
+ }
+ }
+ else if (priv->fragment_pipe == &glsl_fragment_pipe)
+ {
+ float col[4];
+
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ GL_EXTCALL(glUniformMatrix2fvARB(prog->ps.bumpenv_mat_location[i], 1, 0,
+ (const float *)&state->texture_states[i][WINED3D_TSS_BUMPENV_MAT00]));
+ GL_EXTCALL(glUniform1fARB(prog->ps.bumpenv_lum_scale_location[i],
+ *(const float *)&state->texture_states[i][WINED3D_TSS_BUMPENV_LSCALE]));
+ GL_EXTCALL(glUniform1fARB(prog->ps.bumpenv_lum_offset_location[i],
+ *(const float *)&state->texture_states[i][WINED3D_TSS_BUMPENV_LOFFSET]));
+ }
+
+ D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col);
+ GL_EXTCALL(glUniform4fARB(prog->ps.tex_factor_location, col[0], col[1], col[2], col[3]));
+
+ if (state->render_states[WINED3D_RS_SPECULARENABLE])
+ GL_EXTCALL(glUniform4fARB(prog->ps.specular_enable_location, 1.0f, 1.0f, 1.0f, 0.0f));
+ else
+ GL_EXTCALL(glUniform4fARB(prog->ps.specular_enable_location, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ checkGLcall("fixed function uniforms");
+ }
+
+ if (priv->next_constant_version == UINT_MAX)
+ {
+ TRACE("Max constant version reached, resetting to 0.\n");
+ wine_rb_for_each_entry(&priv->program_lookup, reset_program_constant_version, NULL);
+ priv->next_constant_version = 1;
+ }
+ else
+ {
+ prog->constant_version = priv->next_constant_version++;
+ }
+}
+
+static void update_heap_entry(const struct constant_heap *heap, unsigned int idx,
+ unsigned int heap_idx, DWORD new_version)
+{
+ struct constant_entry *entries = heap->entries;
+ unsigned int *positions = heap->positions;
+ unsigned int parent_idx;
+
+ while (heap_idx > 1)
+ {
+ parent_idx = heap_idx >> 1;
+
+ if (new_version <= entries[parent_idx].version) break;
+
+ entries[heap_idx] = entries[parent_idx];
+ positions[entries[parent_idx].idx] = heap_idx;
+ heap_idx = parent_idx;
+ }
+
+ entries[heap_idx].version = new_version;
+ entries[heap_idx].idx = idx;
+ positions[idx] = heap_idx;
+}
+
+static void shader_glsl_update_float_vertex_constants(struct wined3d_device *device, UINT start, UINT count)
+{
+ struct shader_glsl_priv *priv = device->shader_priv;
+ struct constant_heap *heap = &priv->vconst_heap;
+ UINT i;
+
+ for (i = start; i < count + start; ++i)
+ {
+ if (!device->stateBlock->changed.vertexShaderConstantsF[i])
+ update_heap_entry(heap, i, heap->size++, priv->next_constant_version);
+ else
+ update_heap_entry(heap, i, heap->positions[i], priv->next_constant_version);
+ }
+}
+
+static void shader_glsl_update_float_pixel_constants(struct wined3d_device *device, UINT start, UINT count)
+{
+ struct shader_glsl_priv *priv = device->shader_priv;
+ struct constant_heap *heap = &priv->pconst_heap;
+ UINT i;
+
+ for (i = start; i < count + start; ++i)
+ {
+ if (!device->stateBlock->changed.pixelShaderConstantsF[i])
+ update_heap_entry(heap, i, heap->size++, priv->next_constant_version);
+ else
+ update_heap_entry(heap, i, heap->positions[i], priv->next_constant_version);
+ }
+}
+
+static unsigned int vec4_varyings(DWORD shader_major, const struct wined3d_gl_info *gl_info)
+{
+ unsigned int ret = gl_info->limits.glsl_varyings / 4;
+ /* 4.0 shaders do not write clip coords because d3d10 does not support user clipplanes */
+ if(shader_major > 3) return ret;
+
+ /* 3.0 shaders may need an extra varying for the clip coord on some cards(mostly dx10 ones) */
+ if (gl_info->quirks & WINED3D_QUIRK_GLSL_CLIP_VARYING) ret -= 1;
+ return ret;
+}
+
+/** Generate the variable & register declarations for the GLSL output target */
+static void shader_generate_glsl_declarations(const struct wined3d_context *context,
+ struct wined3d_shader_buffer *buffer, const struct wined3d_shader *shader,
+ const struct wined3d_shader_reg_maps *reg_maps, const struct shader_glsl_ctx_priv *ctx_priv)
+{
+ const struct wined3d_shader_version *version = &reg_maps->shader_version;
+ const struct wined3d_state *state = &shader->device->stateBlock->state;
+ const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const struct wined3d_fb_state *fb = &shader->device->fb;
+ unsigned int i, extra_constants_needed = 0;
+ const struct wined3d_shader_lconst *lconst;
+ const char *prefix;
+ DWORD map;
+
+ prefix = shader_glsl_get_prefix(version->type);
+
+ /* Prototype the subroutines */
+ for (i = 0, map = reg_maps->labels; map; map >>= 1, ++i)
+ {
+ if (map & 1) shader_addline(buffer, "void subroutine%u();\n", i);
+ }
+
+ /* Declare the constants (aka uniforms) */
+ if (shader->limits.constant_float > 0)
+ {
+ unsigned max_constantsF;
+
+ /* Unless the shader uses indirect addressing, always declare the
+ * maximum array size and ignore that we need some uniforms privately.
+ * E.g. if GL supports 256 uniforms, and we need 2 for the pos fixup
+ * and immediate values, still declare VC[256]. If the shader needs
+ * more uniforms than we have it won't work in any case. If it uses
+ * less, the compiler will figure out which uniforms are really used
+ * and strip them out. This allows a shader to use c255 on a dx9 card,
+ * as long as it doesn't also use all the other constants.
+ *
+ * If the shader uses indirect addressing the compiler must assume
+ * that all declared uniforms are used. In this case, declare only the
+ * amount that we're assured to have.
+ *
+ * Thus we run into problems in these two cases:
+ * 1) The shader really uses more uniforms than supported.
+ * 2) The shader uses indirect addressing, less constants than
+ * supported, but uses a constant index > #supported consts. */
+ if (version->type == WINED3D_SHADER_TYPE_PIXEL)
+ {
+ /* No indirect addressing here. */
+ max_constantsF = gl_info->limits.glsl_ps_float_constants;
+ }
+ else
+ {
+ if (reg_maps->usesrelconstF)
+ {
+ /* Subtract the other potential uniforms from the max
+ * available (bools, ints, and 1 row of projection matrix).
+ * Subtract another uniform for immediate values, which have
+ * to be loaded via uniform by the driver as well. The shader
+ * code only uses 0.5, 2.0, 1.0, 128 and -128 in vertex
+ * shader code, so one vec4 should be enough. (Unfortunately
+ * the Nvidia driver doesn't store 128 and -128 in one float).
+ *
+ * Writing gl_ClipVertex requires one uniform for each
+ * clipplane as well. */
+ max_constantsF = gl_info->limits.glsl_vs_float_constants - 3;
+ if(ctx_priv->cur_vs_args->clip_enabled)
+ {
+ max_constantsF -= gl_info->limits.clipplanes;
+ }
+ max_constantsF -= count_bits(reg_maps->integer_constants);
+ /* Strictly speaking a bool only uses one scalar, but the nvidia(Linux) compiler doesn't pack them properly,
+ * so each scalar requires a full vec4. We could work around this by packing the booleans ourselves, but
+ * for now take this into account when calculating the number of available constants
+ */
+ max_constantsF -= count_bits(reg_maps->boolean_constants);
+ /* Set by driver quirks in directx.c */
+ max_constantsF -= gl_info->reserved_glsl_constants;
+
+ if (max_constantsF < shader->limits.constant_float)
+ {
+ static unsigned int once;
+
+ if (!once++)
+ ERR_(winediag)("The hardware does not support enough uniform components to run this shader,"
+ " it may not render correctly.\n");
+ else
+ WARN("The hardware does not support enough uniform components to run this shader.\n");
+ }
+ }
+ else
+ {
+ max_constantsF = gl_info->limits.glsl_vs_float_constants;
+ }
+ }
+ max_constantsF = min(shader->limits.constant_float, max_constantsF);
+ shader_addline(buffer, "uniform vec4 %s_c[%u];\n", prefix, max_constantsF);
+ }
+
+ /* Always declare the full set of constants, the compiler can remove the
+ * unused ones because d3d doesn't (yet) support indirect int and bool
+ * constant addressing. This avoids problems if the app uses e.g. i0 and i9. */
+ if (shader->limits.constant_int > 0 && reg_maps->integer_constants)
+ shader_addline(buffer, "uniform ivec4 %s_i[%u];\n", prefix, shader->limits.constant_int);
+
+ if (shader->limits.constant_bool > 0 && reg_maps->boolean_constants)
+ shader_addline(buffer, "uniform bool %s_b[%u];\n", prefix, shader->limits.constant_bool);
+
+ for (i = 0; i < WINED3D_MAX_CBS; ++i)
+ {
+ if (reg_maps->cb_sizes[i])
+ shader_addline(buffer, "uniform vec4 %s_cb%u[%u];\n", prefix, i, reg_maps->cb_sizes[i]);
+ }
+
+ /* Declare texture samplers */
+ for (i = 0; i < shader->limits.sampler; ++i)
+ {
+ if (reg_maps->sampler_type[i])
+ {
+ BOOL shadow_sampler = version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->shadow & (1 << i));
+ BOOL tex_rect;
+
+ switch (reg_maps->sampler_type[i])
+ {
+ case WINED3DSTT_1D:
+ if (shadow_sampler)
+ shader_addline(buffer, "uniform sampler1DShadow %s_sampler%u;\n", prefix, i);
+ else
+ shader_addline(buffer, "uniform sampler1D %s_sampler%u;\n", prefix, i);
+ break;
+ case WINED3DSTT_2D:
+ tex_rect = version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->np2_fixup & (1 << i));
+ tex_rect = tex_rect && gl_info->supported[ARB_TEXTURE_RECTANGLE];
+ if (shadow_sampler)
+ {
+ if (tex_rect)
+ shader_addline(buffer, "uniform sampler2DRectShadow %s_sampler%u;\n", prefix, i);
+ else
+ shader_addline(buffer, "uniform sampler2DShadow %s_sampler%u;\n", prefix, i);
+ }
+ else
+ {
+ if (tex_rect)
+ shader_addline(buffer, "uniform sampler2DRect %s_sampler%u;\n", prefix, i);
+ else
+ shader_addline(buffer, "uniform sampler2D %s_sampler%u;\n", prefix, i);
+ }
+ break;
+ case WINED3DSTT_CUBE:
+ if (shadow_sampler)
+ FIXME("Unsupported Cube shadow sampler.\n");
+ shader_addline(buffer, "uniform samplerCube %s_sampler%u;\n", prefix, i);
+ break;
+ case WINED3DSTT_VOLUME:
+ if (shadow_sampler)
+ FIXME("Unsupported 3D shadow sampler.\n");
+ shader_addline(buffer, "uniform sampler3D %s_sampler%u;\n", prefix, i);
+ break;
+ default:
+ shader_addline(buffer, "uniform unsupported_sampler %s_sampler%u;\n", prefix, i);
+ FIXME("Unrecognized sampler type: %#x\n", reg_maps->sampler_type[i]);
+ break;
+ }
+ }
+ }
+
+ /* Declare uniforms for NP2 texcoord fixup:
+ * This is NOT done inside the loop that declares the texture samplers
+ * since the NP2 fixup code is currently only used for the GeforceFX
+ * series and when forcing the ARB_npot extension off. Modern cards just
+ * skip the code anyway, so put it inside a separate loop. */
+ if (version->type == WINED3D_SHADER_TYPE_PIXEL && ps_args->np2_fixup)
+ {
+ struct ps_np2fixup_info *fixup = ctx_priv->cur_np2fixup_info;
+ UINT cur = 0;
+
+ /* NP2/RECT textures in OpenGL use texcoords in the range [0,width]x[0,height]
+ * while D3D has them in the (normalized) [0,1]x[0,1] range.
+ * samplerNP2Fixup stores texture dimensions and is updated through
+ * shader_glsl_load_np2fixup_constants when the sampler changes. */
+
+ for (i = 0; i < shader->limits.sampler; ++i)
+ {
+ if (reg_maps->sampler_type[i])
+ {
+ if (!(ps_args->np2_fixup & (1 << i))) continue;
+
+ if (WINED3DSTT_2D != reg_maps->sampler_type[i]) {
+ FIXME("Non-2D texture is flagged for NP2 texcoord fixup.\n");
+ continue;
+ }
+
+ fixup->idx[i] = cur++;
+ }
+ }
+
+ fixup->num_consts = (cur + 1) >> 1;
+ fixup->active = ps_args->np2_fixup;
+ shader_addline(buffer, "uniform vec4 %s_samplerNP2Fixup[%u];\n", prefix, fixup->num_consts);
+ }
+
+ /* Declare address variables */
+ for (i = 0, map = reg_maps->address; map; map >>= 1, ++i)
+ {
+ if (map & 1) shader_addline(buffer, "ivec4 A%u;\n", i);
+ }
+
+ /* Declare texture coordinate temporaries and initialize them */
+ for (i = 0, map = reg_maps->texcoord; map; map >>= 1, ++i)
+ {
+ if (map & 1) shader_addline(buffer, "vec4 T%u = gl_TexCoord[%u];\n", i, i);
+ }
+
+ if (version->type == WINED3D_SHADER_TYPE_VERTEX)
+ {
+ /* Declare attributes. */
+ for (i = 0, map = reg_maps->input_registers; map; map >>= 1, ++i)
+ {
+ if (map & 1)
+ shader_addline(buffer, "attribute vec4 %s_in%u;\n", prefix, i);
+ }
+
+ shader_addline(buffer, "uniform vec4 posFixup;\n");
+ shader_addline(buffer, "void order_ps_input(in vec4[%u]);\n", shader->limits.packed_output);
+ }
+ else if (version->type == WINED3D_SHADER_TYPE_GEOMETRY)
+ {
+ shader_addline(buffer, "varying in vec4 gs_in[][%u];\n", shader->limits.packed_input);
+ }
+ else if (version->type == WINED3D_SHADER_TYPE_PIXEL)
+ {
+ if (version->major >= 3)
+ {
+ UINT in_count = min(vec4_varyings(version->major, gl_info), shader->limits.packed_input);
+
+ if (use_vs(state))
+ shader_addline(buffer, "varying vec4 %s_in[%u];\n", prefix, in_count);
+ else
+ /* TODO: Write a replacement shader for the fixed function
+ * vertex pipeline, so this isn't needed. For fixed function
+ * vertex processing + 3.0 pixel shader we need a separate
+ * function in the pixel shader that reads the fixed function
+ * color into the packed input registers. */
+ shader_addline(buffer, "vec4 %s_in[%u];\n", prefix, in_count);
+ }
+
+ for (i = 0, map = reg_maps->bumpmat; map; map >>= 1, ++i)
+ {
+ if (!(map & 1))
+ continue;
+
+ shader_addline(buffer, "uniform mat2 bumpenv_mat%u;\n", i);
+
+ if (reg_maps->luminanceparams & (1 << i))
+ {
+ shader_addline(buffer, "uniform float bumpenv_lum_scale%u;\n", i);
+ shader_addline(buffer, "uniform float bumpenv_lum_offset%u;\n", i);
+ extra_constants_needed++;
+ }
+
+ extra_constants_needed++;
+ }
+
+ if (ps_args->srgb_correction)
+ {
+ shader_addline(buffer, "const vec4 srgb_const0 = ");
+ shader_glsl_append_imm_vec4(buffer, srgb_const0);
+ shader_addline(buffer, ";\n");
+ shader_addline(buffer, "const vec4 srgb_const1 = ");
+ shader_glsl_append_imm_vec4(buffer, srgb_const1);
+ shader_addline(buffer, ";\n");
+ }
+ if (reg_maps->vpos || reg_maps->usesdsy)
+ {
+ if (shader->limits.constant_float + extra_constants_needed
+ + 1 < gl_info->limits.glsl_ps_float_constants)
+ {
+ shader_addline(buffer, "uniform vec4 ycorrection;\n");
+ extra_constants_needed++;
+ }
+ else
+ {
+ float ycorrection[] =
+ {
+ context->render_offscreen ? 0.0f : fb->render_targets[0]->resource.height,
+ context->render_offscreen ? 1.0f : -1.0f,
+ 0.0f,
+ 0.0f,
+ };
+
+ /* This happens because we do not have proper tracking of the
+ * constant registers that are actually used, only the max
+ * limit of the shader version. */
+ FIXME("Cannot find a free uniform for vpos correction params\n");
+ shader_addline(buffer, "const vec4 ycorrection = ");
+ shader_glsl_append_imm_vec4(buffer, ycorrection);
+ shader_addline(buffer, ";\n");
+ }
+ shader_addline(buffer, "vec4 vpos;\n");
+ }
+ }
+
+ /* Declare output register temporaries */
+ if (shader->limits.packed_output)
+ shader_addline(buffer, "vec4 %s_out[%u];\n", prefix, shader->limits.packed_output);
+
+ /* Declare temporary variables */
+ for (i = 0, map = reg_maps->temporary; map; map >>= 1, ++i)
+ {
+ if (map & 1) shader_addline(buffer, "vec4 R%u;\n", i);
+ }
+
+ /* Declare loop registers aLx */
+ if (version->major < 4)
+ {
+ for (i = 0; i < reg_maps->loop_depth; ++i)
+ {
+ shader_addline(buffer, "int aL%u;\n", i);
+ shader_addline(buffer, "int tmpInt%u;\n", i);
+ }
+ }
+
+ /* Temporary variables for matrix operations */
+ shader_addline(buffer, "vec4 tmp0;\n");
+ shader_addline(buffer, "vec4 tmp1;\n");
+
+ if (!shader->load_local_constsF)
+ {
+ LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
+ {
+ shader_addline(buffer, "const vec4 %s_lc%u = ", prefix, lconst->idx);
+ shader_glsl_append_imm_vec4(buffer, (const float *)lconst->value);
+ shader_addline(buffer, ";\n");
+ }
+ }
+
+ /* Start the main program. */
+ shader_addline(buffer, "void main()\n{\n");
+
+ /* Direct3D applications expect integer vPos values, while OpenGL drivers
+ * add approximately 0.5. This causes off-by-one problems as spotted by
+ * the vPos d3d9 visual test. Unfortunately ATI cards do not add exactly
+ * 0.5, but rather something like 0.49999999 or 0.50000001, which still
+ * causes precision troubles when we just subtract 0.5.
+ *
+ * To deal with that, just floor() the position. This will eliminate the
+ * fraction on all cards.
+ *
+ * TODO: Test how this behaves with multisampling.
+ *
+ * An advantage of floor is that it works even if the driver doesn't add
+ * 0.5. It is somewhat questionable if 1.5, 2.5, ... are the proper values
+ * to return in gl_FragCoord, even though coordinates specify the pixel
+ * centers instead of the pixel corners. This code will behave correctly
+ * on drivers that returns integer values. */
+ if (version->type == WINED3D_SHADER_TYPE_PIXEL && reg_maps->vpos)
+ shader_addline(buffer,
+ "vpos = floor(vec4(0, ycorrection[0], 0, 0) + gl_FragCoord * vec4(1, ycorrection[1], 1, 1));\n");
+}
+
+/*****************************************************************************
+ * Functions to generate GLSL strings from DirectX Shader bytecode begin here.
+ *
+ * For more information, see http://wiki.winehq.org/DirectX-Shaders
+ ****************************************************************************/
+
+/* Prototypes */
+static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *ins,
+ const struct wined3d_shader_src_param *wined3d_src, DWORD mask, struct glsl_src_param *glsl_src);
+
+/** Used for opcode modifiers - They multiply the result by the specified amount */
+static const char * const shift_glsl_tab[] = {
+ "", /* 0 (none) */
+ "2.0 * ", /* 1 (x2) */
+ "4.0 * ", /* 2 (x4) */
+ "8.0 * ", /* 3 (x8) */
+ "16.0 * ", /* 4 (x16) */
+ "32.0 * ", /* 5 (x32) */
+ "", /* 6 (x64) */
+ "", /* 7 (x128) */
+ "", /* 8 (d256) */
+ "", /* 9 (d128) */
+ "", /* 10 (d64) */
+ "", /* 11 (d32) */
+ "0.0625 * ", /* 12 (d16) */
+ "0.125 * ", /* 13 (d8) */
+ "0.25 * ", /* 14 (d4) */
+ "0.5 * " /* 15 (d2) */
+};
+
+/* Generate a GLSL parameter that does the input modifier computation and return the input register/mask to use */
+static void shader_glsl_gen_modifier(enum wined3d_shader_src_modifier src_modifier,
+ const char *in_reg, const char *in_regswizzle, char *out_str)
+{
+ out_str[0] = 0;
+
+ switch (src_modifier)
+ {
+ case WINED3DSPSM_DZ: /* Need to handle this in the instructions itself (texld & texcrd). */
+ case WINED3DSPSM_DW:
+ case WINED3DSPSM_NONE:
+ sprintf(out_str, "%s%s", in_reg, in_regswizzle);
+ break;
+ case WINED3DSPSM_NEG:
+ sprintf(out_str, "-%s%s", in_reg, in_regswizzle);
+ break;
+ case WINED3DSPSM_NOT:
+ sprintf(out_str, "!%s%s", in_reg, in_regswizzle);
+ break;
+ case WINED3DSPSM_BIAS:
+ sprintf(out_str, "(%s%s - vec4(0.5)%s)", in_reg, in_regswizzle, in_regswizzle);
+ break;
+ case WINED3DSPSM_BIASNEG:
+ sprintf(out_str, "-(%s%s - vec4(0.5)%s)", in_reg, in_regswizzle, in_regswizzle);
+ break;
+ case WINED3DSPSM_SIGN:
+ sprintf(out_str, "(2.0 * (%s%s - 0.5))", in_reg, in_regswizzle);
+ break;
+ case WINED3DSPSM_SIGNNEG:
+ sprintf(out_str, "-(2.0 * (%s%s - 0.5))", in_reg, in_regswizzle);
+ break;
+ case WINED3DSPSM_COMP:
+ sprintf(out_str, "(1.0 - %s%s)", in_reg, in_regswizzle);
+ break;
+ case WINED3DSPSM_X2:
+ sprintf(out_str, "(2.0 * %s%s)", in_reg, in_regswizzle);
+ break;
+ case WINED3DSPSM_X2NEG:
+ sprintf(out_str, "-(2.0 * %s%s)", in_reg, in_regswizzle);
+ break;
+ case WINED3DSPSM_ABS:
+ sprintf(out_str, "abs(%s%s)", in_reg, in_regswizzle);
+ break;
+ case WINED3DSPSM_ABSNEG:
+ sprintf(out_str, "-abs(%s%s)", in_reg, in_regswizzle);
+ break;
+ default:
+ FIXME("Unhandled modifier %u\n", src_modifier);
+ sprintf(out_str, "%s%s", in_reg, in_regswizzle);
+ }
+}
+
+/** Writes the GLSL variable name that corresponds to the register that the
+ * DX opcode parameter is trying to access */
+static void shader_glsl_get_register_name(const struct wined3d_shader_register *reg,
+ char *register_name, BOOL *is_color, const struct wined3d_shader_instruction *ins)
+{
+ /* oPos, oFog and oPts in D3D */
+ static const char * const hwrastout_reg_names[] = {"vs_out[10]", "vs_out[11].x", "vs_out[11].y"};
+
+ const struct wined3d_shader *shader = ins->ctx->shader;
+ const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
+ const struct wined3d_shader_version *version = &reg_maps->shader_version;
+ const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
+ const char *prefix = shader_glsl_get_prefix(version->type);
+ struct glsl_src_param rel_param0, rel_param1;
+ char imm_str[4][16];
+
+ if (reg->idx[0].offset != ~0U && reg->idx[0].rel_addr)
+ shader_glsl_add_src_param(ins, reg->idx[0].rel_addr, WINED3DSP_WRITEMASK_0, &rel_param0);
+ if (reg->idx[1].offset != ~0U && reg->idx[1].rel_addr)
+ shader_glsl_add_src_param(ins, reg->idx[1].rel_addr, WINED3DSP_WRITEMASK_0, &rel_param1);
+ *is_color = FALSE;
+
+ switch (reg->type)
+ {
+ case WINED3DSPR_TEMP:
+ sprintf(register_name, "R%u", reg->idx[0].offset);
+ break;
+
+ case WINED3DSPR_INPUT:
+ /* vertex shaders */
+ if (version->type == WINED3D_SHADER_TYPE_VERTEX)
+ {
+ struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
+ if (priv->cur_vs_args->swizzle_map & (1 << reg->idx[0].offset))
+ *is_color = TRUE;
+ sprintf(register_name, "%s_in%u", prefix, reg->idx[0].offset);
+ break;
+ }
+
+ if (version->type == WINED3D_SHADER_TYPE_GEOMETRY)
+ {
+ if (reg->idx[0].rel_addr)
+ {
+ if (reg->idx[1].rel_addr)
+ sprintf(register_name, "gs_in[%s + %u][%s + %u]",
+ rel_param0.param_str, reg->idx[0].offset, rel_param1.param_str, reg->idx[1].offset);
+ else
+ sprintf(register_name, "gs_in[%s + %u][%u]",
+ rel_param0.param_str, reg->idx[0].offset, reg->idx[1].offset);
+ }
+ else if (reg->idx[1].rel_addr)
+ sprintf(register_name, "gs_in[%u][%s + %u]",
+ reg->idx[0].offset, rel_param1.param_str, reg->idx[1].offset);
+ else
+ sprintf(register_name, "gs_in[%u][%u]", reg->idx[0].offset, reg->idx[1].offset);
+ break;
+ }
+
+ /* pixel shaders >= 3.0 */
+ if (version->major >= 3)
+ {
+ DWORD idx = shader->u.ps.input_reg_map[reg->idx[0].offset];
+ unsigned int in_count = vec4_varyings(version->major, gl_info);
+
+ if (reg->idx[0].rel_addr)
+ {
+ /* Removing a + 0 would be an obvious optimization, but
+ * OS X doesn't see the NOP operation there. */
+ if (idx)
+ {
+ if (shader->u.ps.declared_in_count > in_count)
+ {
+ sprintf(register_name,
+ "((%s + %u) > %u ? (%s + %u) > %u ? gl_SecondaryColor : gl_Color : %s_in[%s + %u])",
+ rel_param0.param_str, idx, in_count - 1, rel_param0.param_str, idx, in_count,
+ prefix, rel_param0.param_str, idx);
+ }
+ else
+ {
+ sprintf(register_name, "%s_in[%s + %u]", prefix, rel_param0.param_str, idx);
+ }
+ }
+ else
+ {
+ if (shader->u.ps.declared_in_count > in_count)
+ {
+ sprintf(register_name, "((%s) > %u ? (%s) > %u ? gl_SecondaryColor : gl_Color : %s_in[%s])",
+ rel_param0.param_str, in_count - 1, rel_param0.param_str, in_count,
+ prefix, rel_param0.param_str);
+ }
+ else
+ {
+ sprintf(register_name, "%s_in[%s]", prefix, rel_param0.param_str);
+ }
+ }
+ }
+ else
+ {
+ if (idx == in_count) sprintf(register_name, "gl_Color");
+ else if (idx == in_count + 1) sprintf(register_name, "gl_SecondaryColor");
+ else sprintf(register_name, "%s_in[%u]", prefix, idx);
+ }
+ }
+ else
+ {
+ if (!reg->idx[0].offset)
+ strcpy(register_name, "gl_Color");
+ else
+ strcpy(register_name, "gl_SecondaryColor");
+ break;
+ }
+ break;
+
+ case WINED3DSPR_CONST:
+ {
+ /* Relative addressing */
+ if (reg->idx[0].rel_addr)
+ {
+ if (reg->idx[0].offset)
+ sprintf(register_name, "%s_c[%s + %u]", prefix, rel_param0.param_str, reg->idx[0].offset);
+ else
+ sprintf(register_name, "%s_c[%s]", prefix, rel_param0.param_str);
+ }
+ else
+ {
+ if (shader_constant_is_local(shader, reg->idx[0].offset))
+ sprintf(register_name, "%s_lc%u", prefix, reg->idx[0].offset);
+ else
+ sprintf(register_name, "%s_c[%u]", prefix, reg->idx[0].offset);
+ }
+ }
+ break;
+
+ case WINED3DSPR_CONSTINT:
+ sprintf(register_name, "%s_i[%u]", prefix, reg->idx[0].offset);
+ break;
+
+ case WINED3DSPR_CONSTBOOL:
+ sprintf(register_name, "%s_b[%u]", prefix, reg->idx[0].offset);
+ break;
+
+ case WINED3DSPR_TEXTURE: /* case WINED3DSPR_ADDR: */
+ if (version->type == WINED3D_SHADER_TYPE_PIXEL)
+ sprintf(register_name, "T%u", reg->idx[0].offset);
+ else
+ sprintf(register_name, "A%u", reg->idx[0].offset);
+ break;
+
+ case WINED3DSPR_LOOP:
+ sprintf(register_name, "aL%u", ins->ctx->loop_state->current_reg - 1);
+ break;
+
+ case WINED3DSPR_SAMPLER:
+ sprintf(register_name, "%s_sampler%u", prefix, reg->idx[0].offset);
+ break;
+
+ case WINED3DSPR_COLOROUT:
+ if (reg->idx[0].offset >= gl_info->limits.buffers)
+ WARN("Write to render target %u, only %d supported.\n",
+ reg->idx[0].offset, gl_info->limits.buffers);
+
+ sprintf(register_name, "gl_FragData[%u]", reg->idx[0].offset);
+ break;
+
+ case WINED3DSPR_RASTOUT:
+ sprintf(register_name, "%s", hwrastout_reg_names[reg->idx[0].offset]);
+ break;
+
+ case WINED3DSPR_DEPTHOUT:
+ sprintf(register_name, "gl_FragDepth");
+ break;
+
+ case WINED3DSPR_ATTROUT:
+ if (!reg->idx[0].offset)
+ sprintf(register_name, "%s_out[8]", prefix);
+ else
+ sprintf(register_name, "%s_out[9]", prefix);
+ break;
+
+ case WINED3DSPR_TEXCRDOUT:
+ /* Vertex shaders >= 3.0: WINED3DSPR_OUTPUT */
+ sprintf(register_name, "%s_out[%u]", prefix, reg->idx[0].offset);
+ break;
+
+ case WINED3DSPR_MISCTYPE:
+ if (!reg->idx[0].offset)
+ {
+ /* vPos */
+ sprintf(register_name, "vpos");
+ }
+ else if (reg->idx[0].offset == 1)
+ {
+ /* Note that gl_FrontFacing is a bool, while vFace is
+ * a float for which the sign determines front/back */
+ sprintf(register_name, "(gl_FrontFacing ? 1.0 : -1.0)");
+ }
+ else
+ {
+ FIXME("Unhandled misctype register %u.\n", reg->idx[0].offset);
+ sprintf(register_name, "unrecognized_register");
+ }
+ break;
+
+ case WINED3DSPR_IMMCONST:
+ switch (reg->immconst_type)
+ {
+ case WINED3D_IMMCONST_SCALAR:
+ switch (reg->data_type)
+ {
+ case WINED3D_DATA_FLOAT:
+ shader_glsl_ftoa(*(const float *)reg->immconst_data, register_name);
+ break;
+ case WINED3D_DATA_INT:
+ sprintf(register_name, "%#x", reg->immconst_data[0]);
+ break;
+ case WINED3D_DATA_RESOURCE:
+ case WINED3D_DATA_SAMPLER:
+ case WINED3D_DATA_UINT:
+ sprintf(register_name, "%#xu", reg->immconst_data[0]);
+ break;
+ default:
+ sprintf(register_name, "<unhandled data type %#x>", reg->data_type);
+ break;
+ }
+ break;
+
+ case WINED3D_IMMCONST_VEC4:
+ switch (reg->data_type)
+ {
+ case WINED3D_DATA_FLOAT:
+ shader_glsl_ftoa(*(const float *)&reg->immconst_data[0], imm_str[0]);
+ shader_glsl_ftoa(*(const float *)&reg->immconst_data[1], imm_str[1]);
+ shader_glsl_ftoa(*(const float *)&reg->immconst_data[2], imm_str[2]);
+ shader_glsl_ftoa(*(const float *)&reg->immconst_data[3], imm_str[3]);
+ sprintf(register_name, "vec4(%s, %s, %s, %s)",
+ imm_str[0], imm_str[1], imm_str[2], imm_str[3]);
+ break;
+ case WINED3D_DATA_INT:
+ sprintf(register_name, "ivec4(%#x, %#x, %#x, %#x)",
+ reg->immconst_data[0], reg->immconst_data[1],
+ reg->immconst_data[2], reg->immconst_data[3]);
+ break;
+ case WINED3D_DATA_RESOURCE:
+ case WINED3D_DATA_SAMPLER:
+ case WINED3D_DATA_UINT:
+ sprintf(register_name, "uvec4(%#xu, %#xu, %#xu, %#xu)",
+ reg->immconst_data[0], reg->immconst_data[1],
+ reg->immconst_data[2], reg->immconst_data[3]);
+ break;
+ default:
+ sprintf(register_name, "<unhandled data type %#x>", reg->data_type);
+ break;
+ }
+ break;
+
+ default:
+ FIXME("Unhandled immconst type %#x\n", reg->immconst_type);
+ sprintf(register_name, "<unhandled_immconst_type %#x>", reg->immconst_type);
+ }
+ break;
+
+ case WINED3DSPR_CONSTBUFFER:
+ if (reg->idx[1].rel_addr)
+ sprintf(register_name, "%s_cb%u[%s + %u]",
+ prefix, reg->idx[0].offset, rel_param1.param_str, reg->idx[1].offset);
+ else
+ sprintf(register_name, "%s_cb%u[%u]", prefix, reg->idx[0].offset, reg->idx[1].offset);
+ break;
+
+ case WINED3DSPR_PRIMID:
+ sprintf(register_name, "uint(gl_PrimitiveIDIn)");
+ break;
+
+ default:
+ FIXME("Unhandled register type %#x.\n", reg->type);
+ sprintf(register_name, "unrecognized_register");
+ break;
+ }
+}
+
+static void shader_glsl_write_mask_to_str(DWORD write_mask, char *str)
+{
+ *str++ = '.';
+ if (write_mask & WINED3DSP_WRITEMASK_0) *str++ = 'x';
+ if (write_mask & WINED3DSP_WRITEMASK_1) *str++ = 'y';
+ if (write_mask & WINED3DSP_WRITEMASK_2) *str++ = 'z';
+ if (write_mask & WINED3DSP_WRITEMASK_3) *str++ = 'w';
+ *str = '\0';
+}
+
+/* Get the GLSL write mask for the destination register */
+static DWORD shader_glsl_get_write_mask(const struct wined3d_shader_dst_param *param, char *write_mask)
+{
+ DWORD mask = param->write_mask;
+
+ if (shader_is_scalar(&param->reg))
+ {
+ mask = WINED3DSP_WRITEMASK_0;
+ *write_mask = '\0';
+ }
+ else
+ {
+ shader_glsl_write_mask_to_str(mask, write_mask);
+ }
+
+ return mask;
+}
+
+static unsigned int shader_glsl_get_write_mask_size(DWORD write_mask) {
+ unsigned int size = 0;
+
+ if (write_mask & WINED3DSP_WRITEMASK_0) ++size;
+ if (write_mask & WINED3DSP_WRITEMASK_1) ++size;
+ if (write_mask & WINED3DSP_WRITEMASK_2) ++size;
+ if (write_mask & WINED3DSP_WRITEMASK_3) ++size;
+
+ return size;
+}
+
+static void shader_glsl_swizzle_to_str(const DWORD swizzle, BOOL fixup, DWORD mask, char *str)
+{
+ /* For registers of type WINED3DDECLTYPE_D3DCOLOR, data is stored as "bgra",
+ * but addressed as "rgba". To fix this we need to swap the register's x
+ * and z components. */
+ const char *swizzle_chars = fixup ? "zyxw" : "xyzw";
+
+ *str++ = '.';
+ /* swizzle bits fields: wwzzyyxx */
+ if (mask & WINED3DSP_WRITEMASK_0) *str++ = swizzle_chars[swizzle & 0x03];
+ if (mask & WINED3DSP_WRITEMASK_1) *str++ = swizzle_chars[(swizzle >> 2) & 0x03];
+ if (mask & WINED3DSP_WRITEMASK_2) *str++ = swizzle_chars[(swizzle >> 4) & 0x03];
+ if (mask & WINED3DSP_WRITEMASK_3) *str++ = swizzle_chars[(swizzle >> 6) & 0x03];
+ *str = '\0';
+}
+
+static void shader_glsl_get_swizzle(const struct wined3d_shader_src_param *param,
+ BOOL fixup, DWORD mask, char *swizzle_str)
+{
+ if (shader_is_scalar(&param->reg))
+ *swizzle_str = '\0';
+ else
+ shader_glsl_swizzle_to_str(param->swizzle, fixup, mask, swizzle_str);
+}
+
+/* From a given parameter token, generate the corresponding GLSL string.
+ * Also, return the actual register name and swizzle in case the
+ * caller needs this information as well. */
+static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *ins,
+ const struct wined3d_shader_src_param *wined3d_src, DWORD mask, struct glsl_src_param *glsl_src)
+{
+ BOOL is_color = FALSE;
+ char swizzle_str[6];
+
+ glsl_src->reg_name[0] = '\0';
+ glsl_src->param_str[0] = '\0';
+ swizzle_str[0] = '\0';
+
+ shader_glsl_get_register_name(&wined3d_src->reg, glsl_src->reg_name, &is_color, ins);
+ shader_glsl_get_swizzle(wined3d_src, is_color, mask, swizzle_str);
+
+ if (wined3d_src->reg.type == WINED3DSPR_IMMCONST || wined3d_src->reg.type == WINED3DSPR_PRIMID)
+ {
+ shader_glsl_gen_modifier(wined3d_src->modifiers, glsl_src->reg_name, swizzle_str, glsl_src->param_str);
+ }
+ else
+ {
+ char param_str[200];
+
+ shader_glsl_gen_modifier(wined3d_src->modifiers, glsl_src->reg_name, swizzle_str, param_str);
+
+ switch (wined3d_src->reg.data_type)
+ {
+ case WINED3D_DATA_FLOAT:
+ sprintf(glsl_src->param_str, "%s", param_str);
+ break;
+ case WINED3D_DATA_INT:
+ sprintf(glsl_src->param_str, "floatBitsToInt(%s)", param_str);
+ break;
+ case WINED3D_DATA_RESOURCE:
+ case WINED3D_DATA_SAMPLER:
+ case WINED3D_DATA_UINT:
+ sprintf(glsl_src->param_str, "floatBitsToUint(%s)", param_str);
+ break;
+ default:
+ FIXME("Unhandled data type %#x.\n", wined3d_src->reg.data_type);
+ sprintf(glsl_src->param_str, "%s", param_str);
+ break;
+ }
+ }
+}
+
+/* From a given parameter token, generate the corresponding GLSL string.
+ * Also, return the actual register name and swizzle in case the
+ * caller needs this information as well. */
+static DWORD shader_glsl_add_dst_param(const struct wined3d_shader_instruction *ins,
+ const struct wined3d_shader_dst_param *wined3d_dst, struct glsl_dst_param *glsl_dst)
+{
+ BOOL is_color = FALSE;
+
+ glsl_dst->mask_str[0] = '\0';
+ glsl_dst->reg_name[0] = '\0';
+
+ shader_glsl_get_register_name(&wined3d_dst->reg, glsl_dst->reg_name, &is_color, ins);
+ return shader_glsl_get_write_mask(wined3d_dst, glsl_dst->mask_str);
+}
+
+/* Append the destination part of the instruction to the buffer, return the effective write mask */
+static DWORD shader_glsl_append_dst_ext(struct wined3d_shader_buffer *buffer,
+ const struct wined3d_shader_instruction *ins, const struct wined3d_shader_dst_param *dst)
+{
+ struct glsl_dst_param glsl_dst;
+ DWORD mask;
+
+ if ((mask = shader_glsl_add_dst_param(ins, dst, &glsl_dst)))
+ {
+ switch (dst->reg.data_type)
+ {
+ case WINED3D_DATA_FLOAT:
+ shader_addline(buffer, "%s%s = %s(",
+ glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
+ break;
+ case WINED3D_DATA_INT:
+ shader_addline(buffer, "%s%s = %sintBitsToFloat(",
+ glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
+ break;
+ case WINED3D_DATA_RESOURCE:
+ case WINED3D_DATA_SAMPLER:
+ case WINED3D_DATA_UINT:
+ shader_addline(buffer, "%s%s = %suintBitsToFloat(",
+ glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
+ break;
+ default:
+ FIXME("Unhandled data type %#x.\n", dst->reg.data_type);
+ shader_addline(buffer, "%s%s = %s(",
+ glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
+ break;
+ }
+ }
+
+ return mask;
+}
+
+/* Append the destination part of the instruction to the buffer, return the effective write mask */
+static DWORD shader_glsl_append_dst(struct wined3d_shader_buffer *buffer, const struct wined3d_shader_instruction *ins)
+{
+ return shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0]);
+}
+
+/** Process GLSL instruction modifiers */
+static void shader_glsl_add_instruction_modifiers(const struct wined3d_shader_instruction *ins)
+{
+ struct glsl_dst_param dst_param;
+ DWORD modifiers;
+
+ if (!ins->dst_count) return;
+
+ modifiers = ins->dst[0].modifiers;
+ if (!modifiers) return;
+
+ shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param);
+
+ if (modifiers & WINED3DSPDM_SATURATE)
+ {
+ /* _SAT means to clamp the value of the register to between 0 and 1 */
+ shader_addline(ins->ctx->buffer, "%s%s = clamp(%s%s, 0.0, 1.0);\n", dst_param.reg_name,
+ dst_param.mask_str, dst_param.reg_name, dst_param.mask_str);
+ }
+
+ if (modifiers & WINED3DSPDM_MSAMPCENTROID)
+ {
+ FIXME("_centroid modifier not handled\n");
+ }
+
+ if (modifiers & WINED3DSPDM_PARTIALPRECISION)
+ {
+ /* MSDN says this modifier can be safely ignored, so that's what we'll do. */
+ }
+}
+
+static const char *shader_glsl_get_rel_op(enum wined3d_shader_rel_op op)
+{
+ switch (op)
+ {
+ case WINED3D_SHADER_REL_OP_GT: return ">";
+ case WINED3D_SHADER_REL_OP_EQ: return "==";
+ case WINED3D_SHADER_REL_OP_GE: return ">=";
+ case WINED3D_SHADER_REL_OP_LT: return "<";
+ case WINED3D_SHADER_REL_OP_NE: return "!=";
+ case WINED3D_SHADER_REL_OP_LE: return "<=";
+ default:
+ FIXME("Unrecognized operator %#x.\n", op);
+ return "(\?\?)";
+ }
+}
+
+static void shader_glsl_get_sample_function(const struct wined3d_shader_context *ctx,
+ DWORD sampler_idx, DWORD flags, struct glsl_sample_function *sample_function)
+{
+ enum wined3d_sampler_texture_type sampler_type = ctx->reg_maps->sampler_type[sampler_idx];
+ const struct wined3d_gl_info *gl_info = ctx->gl_info;
+ BOOL shadow = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL
+ && (((const struct shader_glsl_ctx_priv *)ctx->backend_data)->cur_ps_args->shadow & (1 << sampler_idx));
+ BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED;
+ BOOL texrect = flags & WINED3D_GLSL_SAMPLE_NPOT && gl_info->supported[ARB_TEXTURE_RECTANGLE];
+ BOOL lod = flags & WINED3D_GLSL_SAMPLE_LOD;
+ BOOL grad = flags & WINED3D_GLSL_SAMPLE_GRAD;
+
+ /* Note that there's no such thing as a projected cube texture. */
+ switch(sampler_type) {
+ case WINED3DSTT_1D:
+ if (shadow)
+ {
+ if (lod)
+ {
+ sample_function->name = projected ? "shadow1DProjLod" : "shadow1DLod";
+ }
+ else if (grad)
+ {
+ if (gl_info->supported[EXT_GPU_SHADER4])
+ sample_function->name = projected ? "shadow1DProjGrad" : "shadow1DGrad";
+ else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+ sample_function->name = projected ? "shadow1DProjGradARB" : "shadow1DGradARB";
+ else
+ {
+ FIXME("Unsupported 1D shadow grad function.\n");
+ sample_function->name = "unsupported1DGrad";
+ }
+ }
+ else
+ {
+ sample_function->name = projected ? "shadow1DProj" : "shadow1D";
+ }
+ sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1;
+ }
+ else
+ {
+ if (lod)
+ {
+ sample_function->name = projected ? "texture1DProjLod" : "texture1DLod";
+ }
+ else if (grad)
+ {
+ if (gl_info->supported[EXT_GPU_SHADER4])
+ sample_function->name = projected ? "texture1DProjGrad" : "texture1DGrad";
+ else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+ sample_function->name = projected ? "texture1DProjGradARB" : "texture1DGradARB";
+ else
+ {
+ FIXME("Unsupported 1D grad function.\n");
+ sample_function->name = "unsupported1DGrad";
+ }
+ }
+ else
+ {
+ sample_function->name = projected ? "texture1DProj" : "texture1D";
+ }
+ sample_function->coord_mask = WINED3DSP_WRITEMASK_0;
+ }
+ break;
+
+ case WINED3DSTT_2D:
+ if (shadow)
+ {
+ if (texrect)
+ {
+ if (lod)
+ {
+ sample_function->name = projected ? "shadow2DRectProjLod" : "shadow2DRectLod";
+ }
+ else if (grad)
+ {
+ if (gl_info->supported[EXT_GPU_SHADER4])
+ sample_function->name = projected ? "shadow2DRectProjGrad" : "shadow2DRectGrad";
+ else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+ sample_function->name = projected ? "shadow2DRectProjGradARB" : "shadow2DRectGradARB";
+ else
+ {
+ FIXME("Unsupported RECT shadow grad function.\n");
+ sample_function->name = "unsupported2DRectGrad";
+ }
+ }
+ else
+ {
+ sample_function->name = projected ? "shadow2DRectProj" : "shadow2DRect";
+ }
+ }
+ else
+ {
+ if (lod)
+ {
+ sample_function->name = projected ? "shadow2DProjLod" : "shadow2DLod";
+ }
+ else if (grad)
+ {
+ if (gl_info->supported[EXT_GPU_SHADER4])
+ sample_function->name = projected ? "shadow2DProjGrad" : "shadow2DGrad";
+ else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+ sample_function->name = projected ? "shadow2DProjGradARB" : "shadow2DGradARB";
+ else
+ {
+ FIXME("Unsupported 2D shadow grad function.\n");
+ sample_function->name = "unsupported2DGrad";
+ }
+ }
+ else
+ {
+ sample_function->name = projected ? "shadow2DProj" : "shadow2D";
+ }
+ }
+ sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
+ }
+ else
+ {
+ if (texrect)
+ {
+ if (lod)
+ {
+ sample_function->name = projected ? "texture2DRectProjLod" : "texture2DRectLod";
+ }
+ else if (grad)
+ {
+ if (gl_info->supported[EXT_GPU_SHADER4])
+ sample_function->name = projected ? "texture2DRectProjGrad" : "texture2DRectGrad";
+ else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+ sample_function->name = projected ? "texture2DRectProjGradARB" : "texture2DRectGradARB";
+ else
+ {
+ FIXME("Unsupported RECT grad function.\n");
+ sample_function->name = "unsupported2DRectGrad";
+ }
+ }
+ else
+ {
+ sample_function->name = projected ? "texture2DRectProj" : "texture2DRect";
+ }
+ }
+ else
+ {
+ if (lod)
+ {
+ sample_function->name = projected ? "texture2DProjLod" : "texture2DLod";
+ }
+ else if (grad)
+ {
+ if (gl_info->supported[EXT_GPU_SHADER4])
+ sample_function->name = projected ? "texture2DProjGrad" : "texture2DGrad";
+ else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+ sample_function->name = projected ? "texture2DProjGradARB" : "texture2DGradARB";
+ else
+ {
+ FIXME("Unsupported 2D grad function.\n");
+ sample_function->name = "unsupported2DGrad";
+ }
+ }
+ else
+ {
+ sample_function->name = projected ? "texture2DProj" : "texture2D";
+ }
+ }
+ sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1;
+ }
+ break;
+
+ case WINED3DSTT_CUBE:
+ if (shadow)
+ {
+ FIXME("Unsupported Cube shadow function.\n");
+ sample_function->name = "unsupportedCubeShadow";
+ sample_function->coord_mask = 0;
+ }
+ else
+ {
+ if (lod)
+ {
+ sample_function->name = "textureCubeLod";
+ }
+ else if (grad)
+ {
+ if (gl_info->supported[EXT_GPU_SHADER4])
+ sample_function->name = "textureCubeGrad";
+ else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+ sample_function->name = "textureCubeGradARB";
+ else
+ {
+ FIXME("Unsupported Cube grad function.\n");
+ sample_function->name = "unsupportedCubeGrad";
+ }
+ }
+ else
+ {
+ sample_function->name = "textureCube";
+ }
+ sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
+ }
+ break;
+
+ case WINED3DSTT_VOLUME:
+ if (shadow)
+ {
+ FIXME("Unsupported 3D shadow function.\n");
+ sample_function->name = "unsupported3DShadow";
+ sample_function->coord_mask = 0;
+ }
+ else
+ {
+ if (lod)
+ {
+ sample_function->name = projected ? "texture3DProjLod" : "texture3DLod";
+ }
+ else if (grad)
+ {
+ if (gl_info->supported[EXT_GPU_SHADER4])
+ sample_function->name = projected ? "texture3DProjGrad" : "texture3DGrad";
+ else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+ sample_function->name = projected ? "texture3DProjGradARB" : "texture3DGradARB";
+ else
+ {
+ FIXME("Unsupported 3D grad function.\n");
+ sample_function->name = "unsupported3DGrad";
+ }
+ }
+ else
+ {
+ sample_function->name = projected ? "texture3DProj" : "texture3D";
+ }
+ sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
+ }
+ break;
+
+ default:
+ sample_function->name = "";
+ sample_function->coord_mask = 0;
+ FIXME("Unrecognized sampler type: %#x;\n", sampler_type);
+ break;
+ }
+}
+
+static void shader_glsl_append_fixup_arg(char *arguments, const char *reg_name,
+ BOOL sign_fixup, enum fixup_channel_source channel_source)
+{
+ switch(channel_source)
+ {
+ case CHANNEL_SOURCE_ZERO:
+ strcat(arguments, "0.0");
+ break;
+
+ case CHANNEL_SOURCE_ONE:
+ strcat(arguments, "1.0");
+ break;
+
+ case CHANNEL_SOURCE_X:
+ strcat(arguments, reg_name);
+ strcat(arguments, ".x");
+ break;
+
+ case CHANNEL_SOURCE_Y:
+ strcat(arguments, reg_name);
+ strcat(arguments, ".y");
+ break;
+
+ case CHANNEL_SOURCE_Z:
+ strcat(arguments, reg_name);
+ strcat(arguments, ".z");
+ break;
+
+ case CHANNEL_SOURCE_W:
+ strcat(arguments, reg_name);
+ strcat(arguments, ".w");
+ break;
+
+ default:
+ FIXME("Unhandled channel source %#x\n", channel_source);
+ strcat(arguments, "undefined");
+ break;
+ }
+
+ if (sign_fixup) strcat(arguments, " * 2.0 - 1.0");
+}
+
+static void shader_glsl_color_correction_ext(struct wined3d_shader_buffer *buffer,
+ const char *reg_name, DWORD mask, struct color_fixup_desc fixup)
+{
+ unsigned int mask_size, remaining;
+ DWORD fixup_mask = 0;
+ char arguments[256];
+ char mask_str[6];
+
+ if (fixup.x_sign_fixup || fixup.x_source != CHANNEL_SOURCE_X) fixup_mask |= WINED3DSP_WRITEMASK_0;
+ if (fixup.y_sign_fixup || fixup.y_source != CHANNEL_SOURCE_Y) fixup_mask |= WINED3DSP_WRITEMASK_1;
+ if (fixup.z_sign_fixup || fixup.z_source != CHANNEL_SOURCE_Z) fixup_mask |= WINED3DSP_WRITEMASK_2;
+ if (fixup.w_sign_fixup || fixup.w_source != CHANNEL_SOURCE_W) fixup_mask |= WINED3DSP_WRITEMASK_3;
+ if (!(mask &= fixup_mask))
+ return;
+
+ if (is_complex_fixup(fixup))
+ {
+ enum complex_fixup complex_fixup = get_complex_fixup(fixup);
+ FIXME("Complex fixup (%#x) not supported\n",complex_fixup);
+ return;
+ }
+
+ shader_glsl_write_mask_to_str(mask, mask_str);
+ mask_size = shader_glsl_get_write_mask_size(mask);
+
+ arguments[0] = '\0';
+ remaining = mask_size;
+ if (mask & WINED3DSP_WRITEMASK_0)
+ {
+ shader_glsl_append_fixup_arg(arguments, reg_name, fixup.x_sign_fixup, fixup.x_source);
+ if (--remaining) strcat(arguments, ", ");
+ }
+ if (mask & WINED3DSP_WRITEMASK_1)
+ {
+ shader_glsl_append_fixup_arg(arguments, reg_name, fixup.y_sign_fixup, fixup.y_source);
+ if (--remaining) strcat(arguments, ", ");
+ }
+ if (mask & WINED3DSP_WRITEMASK_2)
+ {
+ shader_glsl_append_fixup_arg(arguments, reg_name, fixup.z_sign_fixup, fixup.z_source);
+ if (--remaining) strcat(arguments, ", ");
+ }
+ if (mask & WINED3DSP_WRITEMASK_3)
+ {
+ shader_glsl_append_fixup_arg(arguments, reg_name, fixup.w_sign_fixup, fixup.w_source);
+ if (--remaining) strcat(arguments, ", ");
+ }
+
+ if (mask_size > 1)
+ shader_addline(buffer, "%s%s = vec%u(%s);\n", reg_name, mask_str, mask_size, arguments);
+ else
+ shader_addline(buffer, "%s%s = %s;\n", reg_name, mask_str, arguments);
+}
+
+static void shader_glsl_color_correction(const struct wined3d_shader_instruction *ins, struct color_fixup_desc fixup)
+{
+ char reg_name[256];
+ BOOL is_color;
+
+ shader_glsl_get_register_name(&ins->dst[0].reg, reg_name, &is_color, ins);
+ shader_glsl_color_correction_ext(ins->ctx->buffer, reg_name, ins->dst[0].write_mask, fixup);
+}
+
+static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_shader_instruction *ins,
+ DWORD sampler, const struct glsl_sample_function *sample_function, DWORD swizzle,
+ const char *dx, const char *dy, const char *bias, const char *coord_reg_fmt, ...)
+{
+ const struct wined3d_shader_version *version = &ins->ctx->reg_maps->shader_version;
+ char dst_swizzle[6];
+ struct color_fixup_desc fixup;
+ BOOL np2_fixup = FALSE;
+ va_list args;
+
+ shader_glsl_swizzle_to_str(swizzle, FALSE, ins->dst[0].write_mask, dst_swizzle);
+
+ if (version->type == WINED3D_SHADER_TYPE_PIXEL)
+ {
+ const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
+ fixup = priv->cur_ps_args->color_fixup[sampler];
+
+ if(priv->cur_ps_args->np2_fixup & (1 << sampler)) {
+ if(bias) {
+ FIXME("Biased sampling from NP2 textures is unsupported\n");
+ } else {
+ np2_fixup = TRUE;
+ }
+ }
+ }
+ else
+ {
+ fixup = COLOR_FIXUP_IDENTITY; /* FIXME: Vshader color fixup */
+ }
+
+ shader_glsl_append_dst(ins->ctx->buffer, ins);
+
+ shader_addline(ins->ctx->buffer, "%s(%s_sampler%u, ",
+ sample_function->name, shader_glsl_get_prefix(version->type), sampler);
+
+ va_start(args, coord_reg_fmt);
+ shader_vaddline(ins->ctx->buffer, coord_reg_fmt, args);
+ va_end(args);
+
+ if(bias) {
+ shader_addline(ins->ctx->buffer, ", %s)%s);\n", bias, dst_swizzle);
+ } else {
+ if (np2_fixup) {
+ const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
+ const unsigned char idx = priv->cur_np2fixup_info->idx[sampler];
+
+ shader_addline(ins->ctx->buffer, " * ps_samplerNP2Fixup[%u].%s)%s);\n", idx >> 1,
+ (idx % 2) ? "zw" : "xy", dst_swizzle);
+ } else if(dx && dy) {
+ shader_addline(ins->ctx->buffer, ", %s, %s)%s);\n", dx, dy, dst_swizzle);
+ } else {
+ shader_addline(ins->ctx->buffer, ")%s);\n", dst_swizzle);
+ }
+ }
+
+ if(!is_identity_fixup(fixup)) {
+ shader_glsl_color_correction(ins, fixup);
+ }
+}
+
+/*****************************************************************************
+ * Begin processing individual instruction opcodes
+ ****************************************************************************/
+
+static void shader_glsl_binop(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct glsl_src_param src0_param;
+ struct glsl_src_param src1_param;
+ DWORD write_mask;
+ const char *op;
+
+ /* Determine the GLSL operator to use based on the opcode */
+ switch (ins->handler_idx)
+ {
+ case WINED3DSIH_ADD: op = "+"; break;
+ case WINED3DSIH_AND: op = "&"; break;
+ case WINED3DSIH_DIV: op = "/"; break;
+ case WINED3DSIH_IADD: op = "+"; break;
+ case WINED3DSIH_MUL: op = "*"; break;
+ case WINED3DSIH_SUB: op = "-"; break;
+ case WINED3DSIH_USHR: op = ">>"; break;
+ case WINED3DSIH_XOR: op = "^"; break;
+ default:
+ op = "<unhandled operator>";
+ FIXME("Opcode %#x not yet handled in GLSL\n", ins->handler_idx);
+ break;
+ }
+
+ write_mask = shader_glsl_append_dst(buffer, ins);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+ shader_addline(buffer, "%s %s %s);\n", src0_param.param_str, op, src1_param.param_str);
+}
+
+static void shader_glsl_relop(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct glsl_src_param src0_param;
+ struct glsl_src_param src1_param;
+ unsigned int mask_size;
+ DWORD write_mask;
+ const char *op;
+
+ write_mask = shader_glsl_append_dst(buffer, ins);
+ mask_size = shader_glsl_get_write_mask_size(write_mask);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+
+ if (mask_size > 1)
+ {
+ switch (ins->handler_idx)
+ {
+ case WINED3DSIH_EQ: op = "equal"; break;
+ case WINED3DSIH_GE: op = "greaterThanEqual"; break;
+ case WINED3DSIH_IGE: op = "greaterThanEqual"; break;
+ case WINED3DSIH_LT: op = "lessThan"; break;
+ default:
+ op = "<unhandled operator>";
+ ERR("Unhandled opcode %#x.\n", ins->handler_idx);
+ break;
+ }
+
+ shader_addline(buffer, "uvec%u(%s(%s, %s)) * 0xffffffffu);\n",
+ mask_size, op, src0_param.param_str, src1_param.param_str);
+ }
+ else
+ {
+ switch (ins->handler_idx)
+ {
+ case WINED3DSIH_EQ: op = "=="; break;
+ case WINED3DSIH_GE: op = ">="; break;
+ case WINED3DSIH_IGE: op = ">="; break;
+ case WINED3DSIH_LT: op = "<"; break;
+ default:
+ op = "<unhandled operator>";
+ ERR("Unhandled opcode %#x.\n", ins->handler_idx);
+ break;
+ }
+
+ shader_addline(buffer, "%s %s %s ? 0xffffffffu : 0u);\n",
+ src0_param.param_str, op, src1_param.param_str);
+ }
+}
+
+static void shader_glsl_imul(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct glsl_src_param src0_param;
+ struct glsl_src_param src1_param;
+ DWORD write_mask;
+
+ /* If we have ARB_gpu_shader5 or GLSL 4.0, we can use imulExtended(). If
+ * not, we can emulate it. */
+ if (ins->dst[0].reg.type != WINED3DSPR_NULL)
+ FIXME("64-bit integer multiplies not implemented.\n");
+
+ if (ins->dst[1].reg.type != WINED3DSPR_NULL)
+ {
+ write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1]);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+
+ shader_addline(ins->ctx->buffer, "%s * %s);\n",
+ src0_param.param_str, src1_param.param_str);
+ }
+}
+
+static void shader_glsl_udiv(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct glsl_src_param src0_param, src1_param;
+ DWORD write_mask;
+
+ if (ins->dst[0].reg.type != WINED3DSPR_NULL)
+ {
+
+ if (ins->dst[1].reg.type != WINED3DSPR_NULL)
+ {
+ char dst_mask[6];
+
+ write_mask = shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+ shader_addline(buffer, "tmp0%s = %s / %s;\n",
+ dst_mask, src0_param.param_str, src1_param.param_str);
+
+ write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1]);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+ shader_addline(buffer, "%s %% %s));\n", src0_param.param_str, src1_param.param_str);
+
+ shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0]);
+ shader_addline(buffer, "tmp0%s);\n", dst_mask);
+ }
+ else
+ {
+ write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0]);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+ shader_addline(buffer, "%s / %s);\n", src0_param.param_str, src1_param.param_str);
+ }
+ }
+ else if (ins->dst[1].reg.type != WINED3DSPR_NULL)
+ {
+ write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1]);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+ shader_addline(buffer, "%s %% %s);\n", src0_param.param_str, src1_param.param_str);
+ }
+}
+
+/* Process the WINED3DSIO_MOV opcode using GLSL (dst = src) */
+static void shader_glsl_mov(const struct wined3d_shader_instruction *ins)
+{
+ const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct glsl_src_param src0_param;
+ DWORD write_mask;
+
+ write_mask = shader_glsl_append_dst(buffer, ins);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+
+ /* In vs_1_1 WINED3DSIO_MOV can write to the address register. In later
+ * shader versions WINED3DSIO_MOVA is used for this. */
+ if (ins->ctx->reg_maps->shader_version.major == 1
+ && ins->ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_VERTEX
+ && ins->dst[0].reg.type == WINED3DSPR_ADDR)
+ {
+ /* This is a simple floor() */
+ unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
+ if (mask_size > 1) {
+ shader_addline(buffer, "ivec%d(floor(%s)));\n", mask_size, src0_param.param_str);
+ } else {
+ shader_addline(buffer, "int(floor(%s)));\n", src0_param.param_str);
+ }
+ }
+ else if(ins->handler_idx == WINED3DSIH_MOVA)
+ {
+ /* We need to *round* to the nearest int here. */
+ unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
+
+ if (gl_info->supported[EXT_GPU_SHADER4])
+ {
+ if (mask_size > 1)
+ shader_addline(buffer, "ivec%d(round(%s)));\n", mask_size, src0_param.param_str);
+ else
+ shader_addline(buffer, "int(round(%s)));\n", src0_param.param_str);
+ }
+ else
+ {
+ if (mask_size > 1)
+ shader_addline(buffer, "ivec%d(floor(abs(%s) + vec%d(0.5)) * sign(%s)));\n",
+ mask_size, src0_param.param_str, mask_size, src0_param.param_str);
+ else
+ shader_addline(buffer, "int(floor(abs(%s) + 0.5) * sign(%s)));\n",
+ src0_param.param_str, src0_param.param_str);
+ }
+ }
+ else
+ {
+ shader_addline(buffer, "%s);\n", src0_param.param_str);
+ }
+}
+
+/* Process the dot product operators DP3 and DP4 in GLSL (dst = dot(src0, src1)) */
+static void shader_glsl_dot(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct glsl_src_param src0_param;
+ struct glsl_src_param src1_param;
+ DWORD dst_write_mask, src_write_mask;
+ unsigned int dst_size = 0;
+
+ dst_write_mask = shader_glsl_append_dst(buffer, ins);
+ dst_size = shader_glsl_get_write_mask_size(dst_write_mask);
+
+ /* dp3 works on vec3, dp4 on vec4 */
+ if (ins->handler_idx == WINED3DSIH_DP4)
+ {
+ src_write_mask = WINED3DSP_WRITEMASK_ALL;
+ } else {
+ src_write_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
+ }
+
+ shader_glsl_add_src_param(ins, &ins->src[0], src_write_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], src_write_mask, &src1_param);
+
+ if (dst_size > 1) {
+ shader_addline(buffer, "vec%d(dot(%s, %s)));\n", dst_size, src0_param.param_str, src1_param.param_str);
+ } else {
+ shader_addline(buffer, "dot(%s, %s));\n", src0_param.param_str, src1_param.param_str);
+ }
+}
+
+/* Note that this instruction has some restrictions. The destination write mask
+ * can't contain the w component, and the source swizzles have to be .xyzw */
+static void shader_glsl_cross(const struct wined3d_shader_instruction *ins)
+{
+ DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
+ struct glsl_src_param src0_param;
+ struct glsl_src_param src1_param;
+ char dst_mask[6];
+
+ shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
+ shader_glsl_append_dst(ins->ctx->buffer, ins);
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], src_mask, &src1_param);
+ shader_addline(ins->ctx->buffer, "cross(%s, %s)%s);\n", src0_param.param_str, src1_param.param_str, dst_mask);
+}
+
+static void shader_glsl_cut(const struct wined3d_shader_instruction *ins)
+{
+ shader_addline(ins->ctx->buffer, "EndPrimitive();\n");
+}
+
+/* Process the WINED3DSIO_POW instruction in GLSL (dst = |src0|^src1)
+ * Src0 and src1 are scalars. Note that D3D uses the absolute of src0, while
+ * GLSL uses the value as-is. */
+static void shader_glsl_pow(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct glsl_src_param src0_param;
+ struct glsl_src_param src1_param;
+ DWORD dst_write_mask;
+ unsigned int dst_size;
+
+ dst_write_mask = shader_glsl_append_dst(buffer, ins);
+ dst_size = shader_glsl_get_write_mask_size(dst_write_mask);
+
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &src1_param);
+
+ if (dst_size > 1)
+ {
+ shader_addline(buffer, "vec%u(%s == 0.0 ? 1.0 : pow(abs(%s), %s)));\n",
+ dst_size, src1_param.param_str, src0_param.param_str, src1_param.param_str);
+ }
+ else
+ {
+ shader_addline(buffer, "%s == 0.0 ? 1.0 : pow(abs(%s), %s));\n",
+ src1_param.param_str, src0_param.param_str, src1_param.param_str);
+ }
+}
+
+/* Process the WINED3DSIO_LOG instruction in GLSL (dst = log2(|src0|))
+ * Src0 is a scalar. Note that D3D uses the absolute of src0, while
+ * GLSL uses the value as-is. */
+static void shader_glsl_log(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct glsl_src_param src0_param;
+ DWORD dst_write_mask;
+ unsigned int dst_size;
+
+ dst_write_mask = shader_glsl_append_dst(buffer, ins);
+ dst_size = shader_glsl_get_write_mask_size(dst_write_mask);
+
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+
+ if (dst_size > 1)
+ {
+ shader_addline(buffer, "vec%u(log2(abs(%s))));\n",
+ dst_size, src0_param.param_str);
+ }
+ else
+ {
+ shader_addline(buffer, "log2(abs(%s)));\n",
+ src0_param.param_str);
+ }
+}
+
+/* Map the opcode 1-to-1 to the GL code (arg->dst = instruction(src0, src1, ...) */
+static void shader_glsl_map2gl(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct glsl_src_param src_param;
+ const char *instruction;
+ DWORD write_mask;
+ unsigned i;
+
+ /* Determine the GLSL function to use based on the opcode */
+ /* TODO: Possibly make this a table for faster lookups */
+ switch (ins->handler_idx)
+ {
+ case WINED3DSIH_MIN: instruction = "min"; break;
+ case WINED3DSIH_MAX: instruction = "max"; break;
+ case WINED3DSIH_ABS: instruction = "abs"; break;
+ case WINED3DSIH_FRC: instruction = "fract"; break;
+ case WINED3DSIH_EXP: instruction = "exp2"; break;
+ case WINED3DSIH_DSX: instruction = "dFdx"; break;
+ case WINED3DSIH_DSY: instruction = "ycorrection.y * dFdy"; break;
+ case WINED3DSIH_ROUND_NI: instruction = "floor"; break;
+ default: instruction = "";
+ FIXME("Opcode %#x not yet handled in GLSL\n", ins->handler_idx);
+ break;
+ }
+
+ write_mask = shader_glsl_append_dst(buffer, ins);
+
+ shader_addline(buffer, "%s(", instruction);
+
+ if (ins->src_count)
+ {
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src_param);
+ shader_addline(buffer, "%s", src_param.param_str);
+ for (i = 1; i < ins->src_count; ++i)
+ {
+ shader_glsl_add_src_param(ins, &ins->src[i], write_mask, &src_param);
+ shader_addline(buffer, ", %s", src_param.param_str);
+ }
+ }
+
+ shader_addline(buffer, "));\n");
+}
+
+static void shader_glsl_nop(const struct wined3d_shader_instruction *ins) {}
+
+static void shader_glsl_nrm(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct glsl_src_param src_param;
+ unsigned int mask_size;
+ DWORD write_mask;
+ char dst_mask[6];
+
+ write_mask = shader_glsl_get_write_mask(ins->dst, dst_mask);
+ mask_size = shader_glsl_get_write_mask_size(write_mask);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src_param);
+
+ shader_addline(buffer, "tmp0.x = dot(%s, %s);\n",
+ src_param.param_str, src_param.param_str);
+ shader_glsl_append_dst(buffer, ins);
+
+ if (mask_size > 1)
+ {
+ shader_addline(buffer, "tmp0.x == 0.0 ? vec%u(0.0) : (%s * inversesqrt(tmp0.x)));\n",
+ mask_size, src_param.param_str);
+ }
+ else
+ {
+ shader_addline(buffer, "tmp0.x == 0.0 ? 0.0 : (%s * inversesqrt(tmp0.x)));\n",
+ src_param.param_str);
+ }
+}
+
+/** Process the WINED3DSIO_EXPP instruction in GLSL:
+ * For shader model 1.x, do the following (and honor the writemask, so use a temporary variable):
+ * dst.x = 2^(floor(src))
+ * dst.y = src - floor(src)
+ * dst.z = 2^src (partial precision is allowed, but optional)
+ * dst.w = 1.0;
+ * For 2.0 shaders, just do this (honoring writemask and swizzle):
+ * dst = 2^src; (partial precision is allowed, but optional)
+ */
+static void shader_glsl_expp(const struct wined3d_shader_instruction *ins)
+{
+ struct glsl_src_param src_param;
+
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src_param);
+
+ if (ins->ctx->reg_maps->shader_version.major < 2)
+ {
+ char dst_mask[6];
+
+ shader_addline(ins->ctx->buffer, "tmp0.x = exp2(floor(%s));\n", src_param.param_str);
+ shader_addline(ins->ctx->buffer, "tmp0.y = %s - floor(%s);\n", src_param.param_str, src_param.param_str);
+ shader_addline(ins->ctx->buffer, "tmp0.z = exp2(%s);\n", src_param.param_str);
+ shader_addline(ins->ctx->buffer, "tmp0.w = 1.0;\n");
+
+ shader_glsl_append_dst(ins->ctx->buffer, ins);
+ shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
+ shader_addline(ins->ctx->buffer, "tmp0%s);\n", dst_mask);
+ } else {
+ DWORD write_mask;
+ unsigned int mask_size;
+
+ write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
+ mask_size = shader_glsl_get_write_mask_size(write_mask);
+
+ if (mask_size > 1) {
+ shader_addline(ins->ctx->buffer, "vec%d(exp2(%s)));\n", mask_size, src_param.param_str);
+ } else {
+ shader_addline(ins->ctx->buffer, "exp2(%s));\n", src_param.param_str);
+ }
+ }
+}
+
+static void shader_glsl_to_int(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct glsl_src_param src_param;
+ unsigned int mask_size;
+ DWORD write_mask;
+
+ write_mask = shader_glsl_append_dst(buffer, ins);
+ mask_size = shader_glsl_get_write_mask_size(write_mask);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src_param);
+
+ if (mask_size > 1)
+ shader_addline(buffer, "ivec%u(%s));\n", mask_size, src_param.param_str);
+ else
+ shader_addline(buffer, "int(%s));\n", src_param.param_str);
+}
+
+static void shader_glsl_to_float(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct glsl_src_param src_param;
+ unsigned int mask_size;
+ DWORD write_mask;
+
+ write_mask = shader_glsl_append_dst(buffer, ins);
+ mask_size = shader_glsl_get_write_mask_size(write_mask);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src_param);
+
+ if (mask_size > 1)
+ shader_addline(buffer, "vec%u(%s));\n", mask_size, src_param.param_str);
+ else
+ shader_addline(buffer, "float(%s));\n", src_param.param_str);
+}
+
+/** Process the RCP (reciprocal or inverse) opcode in GLSL (dst = 1 / src) */
+static void shader_glsl_rcp(const struct wined3d_shader_instruction *ins)
+{
+ struct glsl_src_param src_param;
+ DWORD write_mask;
+ unsigned int mask_size;
+
+ write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
+ mask_size = shader_glsl_get_write_mask_size(write_mask);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &src_param);
+
+ if (mask_size > 1)
+ {
+ shader_addline(ins->ctx->buffer, "vec%u(1.0 / %s));\n",
+ mask_size, src_param.param_str);
+ }
+ else
+ {
+ shader_addline(ins->ctx->buffer, "1.0 / %s);\n",
+ src_param.param_str);
+ }
+}
+
+static void shader_glsl_rsq(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct glsl_src_param src_param;
+ DWORD write_mask;
+ unsigned int mask_size;
+
+ write_mask = shader_glsl_append_dst(buffer, ins);
+ mask_size = shader_glsl_get_write_mask_size(write_mask);
+
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &src_param);
+
+ if (mask_size > 1)
+ {
+ shader_addline(buffer, "vec%u(inversesqrt(abs(%s))));\n",
+ mask_size, src_param.param_str);
+ }
+ else
+ {
+ shader_addline(buffer, "inversesqrt(abs(%s)));\n",
+ src_param.param_str);
+ }
+}
+
+/** Process signed comparison opcodes in GLSL. */
+static void shader_glsl_compare(const struct wined3d_shader_instruction *ins)
+{
+ struct glsl_src_param src0_param;
+ struct glsl_src_param src1_param;
+ DWORD write_mask;
+ unsigned int mask_size;
+
+ write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
+ mask_size = shader_glsl_get_write_mask_size(write_mask);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+
+ if (mask_size > 1) {
+ const char *compare;
+
+ switch(ins->handler_idx)
+ {
+ case WINED3DSIH_SLT: compare = "lessThan"; break;
+ case WINED3DSIH_SGE: compare = "greaterThanEqual"; break;
+ default: compare = "";
+ FIXME("Can't handle opcode %#x\n", ins->handler_idx);
+ }
+
+ shader_addline(ins->ctx->buffer, "vec%d(%s(%s, %s)));\n", mask_size, compare,
+ src0_param.param_str, src1_param.param_str);
+ } else {
+ switch(ins->handler_idx)
+ {
+ case WINED3DSIH_SLT:
+ /* Step(src0, src1) is not suitable here because if src0 == src1 SLT is supposed,
+ * to return 0.0 but step returns 1.0 because step is not < x
+ * An alternative is a bvec compare padded with an unused second component.
+ * step(src1 * -1.0, src0 * -1.0) is not an option because it suffers from the same
+ * issue. Playing with not() is not possible either because not() does not accept
+ * a scalar.
+ */
+ shader_addline(ins->ctx->buffer, "(%s < %s) ? 1.0 : 0.0);\n",
+ src0_param.param_str, src1_param.param_str);
+ break;
+ case WINED3DSIH_SGE:
+ /* Here we can use the step() function and safe a conditional */
+ shader_addline(ins->ctx->buffer, "step(%s, %s));\n", src1_param.param_str, src0_param.param_str);
+ break;
+ default:
+ FIXME("Can't handle opcode %#x\n", ins->handler_idx);
+ }
+
+ }
+}
+
+static void shader_glsl_conditional_move(const struct wined3d_shader_instruction *ins)
+{
+ const char *condition_prefix, *condition_suffix;
+ struct wined3d_shader_dst_param dst;
+ struct glsl_src_param src0_param;
+ struct glsl_src_param src1_param;
+ struct glsl_src_param src2_param;
+ BOOL temp_destination = FALSE;
+ DWORD cmp_channel = 0;
+ unsigned int i, j;
+ char mask_char[6];
+ DWORD write_mask;
+
+ switch (ins->handler_idx)
+ {
+ case WINED3DSIH_CMP:
+ condition_prefix = "";
+ condition_suffix = " >= 0.0";
+ break;
+
+ case WINED3DSIH_CND:
+ condition_prefix = "";
+ condition_suffix = " > 0.5";
+ break;
+
+ case WINED3DSIH_MOVC:
+ condition_prefix = "bool(";
+ condition_suffix = ")";
+ break;
+
+ default:
+ FIXME("Unhandled instruction %#x.\n", ins->handler_idx);
+ condition_prefix = "<unhandled prefix>";
+ condition_suffix = "<unhandled suffix>";
+ break;
+ }
+
+ if (shader_is_scalar(&ins->dst[0].reg) || shader_is_scalar(&ins->src[0].reg))
+ {
+ write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
+
+ shader_addline(ins->ctx->buffer, "%s%s%s ? %s : %s);\n",
+ condition_prefix, src0_param.param_str, condition_suffix,
+ src1_param.param_str, src2_param.param_str);
+ return;
+ }
+
+ dst = ins->dst[0];
+
+ /* Splitting the instruction up in multiple lines imposes a problem:
+ * The first lines may overwrite source parameters of the following lines.
+ * Deal with that by using a temporary destination register if needed. */
+ if ((ins->src[0].reg.idx[0].offset == dst.reg.idx[0].offset
+ && ins->src[0].reg.type == dst.reg.type)
+ || (ins->src[1].reg.idx[0].offset == dst.reg.idx[0].offset
+ && ins->src[1].reg.type == dst.reg.type)
+ || (ins->src[2].reg.idx[0].offset == dst.reg.idx[0].offset
+ && ins->src[2].reg.type == dst.reg.type))
+ temp_destination = TRUE;
+
+ /* Cycle through all source0 channels. */
+ for (i = 0; i < 4; ++i)
+ {
+ write_mask = 0;
+ /* Find the destination channels which use the current source0 channel. */
+ for (j = 0; j < 4; ++j)
+ {
+ if (((ins->src[0].swizzle >> (2 * j)) & 0x3) == i)
+ {
+ write_mask |= WINED3DSP_WRITEMASK_0 << j;
+ cmp_channel = WINED3DSP_WRITEMASK_0 << j;
+ }
+ }
+ dst.write_mask = ins->dst[0].write_mask & write_mask;
+
+ if (temp_destination)
+ {
+ if (!(write_mask = shader_glsl_get_write_mask(&dst, mask_char)))
+ continue;
+ shader_addline(ins->ctx->buffer, "tmp0%s = (", mask_char);
+ }
+ else if (!(write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &dst)))
+ continue;
+
+ shader_glsl_add_src_param(ins, &ins->src[0], cmp_channel, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
+
+ shader_addline(ins->ctx->buffer, "%s%s%s ? %s : %s);\n",
+ condition_prefix, src0_param.param_str, condition_suffix,
+ src1_param.param_str, src2_param.param_str);
+ }
+
+ if (temp_destination)
+ {
+ shader_glsl_get_write_mask(&ins->dst[0], mask_char);
+ shader_glsl_append_dst(ins->ctx->buffer, ins);
+ shader_addline(ins->ctx->buffer, "tmp0%s);\n", mask_char);
+ }
+}
+
+/** Process the CND opcode in GLSL (dst = (src0 > 0.5) ? src1 : src2) */
+/* For ps 1.1-1.3, only a single component of src0 is used. For ps 1.4
+ * the compare is done per component of src0. */
+static void shader_glsl_cnd(const struct wined3d_shader_instruction *ins)
+{
+ struct glsl_src_param src0_param;
+ struct glsl_src_param src1_param;
+ struct glsl_src_param src2_param;
+ DWORD write_mask;
+ DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
+ ins->ctx->reg_maps->shader_version.minor);
+
+ if (shader_version < WINED3D_SHADER_VERSION(1, 4))
+ {
+ write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
+
+ if (ins->coissue && ins->dst->write_mask != WINED3DSP_WRITEMASK_3)
+ shader_addline(ins->ctx->buffer, "%s /* COISSUE! */);\n", src1_param.param_str);
+ else
+ shader_addline(ins->ctx->buffer, "%s > 0.5 ? %s : %s);\n",
+ src0_param.param_str, src1_param.param_str, src2_param.param_str);
+ return;
+ }
+
+ shader_glsl_conditional_move(ins);
+}
+
+/** GLSL code generation for WINED3DSIO_MAD: Multiply the first 2 opcodes, then add the last */
+static void shader_glsl_mad(const struct wined3d_shader_instruction *ins)
+{
+ struct glsl_src_param src0_param;
+ struct glsl_src_param src1_param;
+ struct glsl_src_param src2_param;
+ DWORD write_mask;
+
+ write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
+ shader_addline(ins->ctx->buffer, "(%s * %s) + %s);\n",
+ src0_param.param_str, src1_param.param_str, src2_param.param_str);
+}
+
+/* Handles transforming all WINED3DSIO_M?x? opcodes for
+ Vertex shaders to GLSL codes */
+static void shader_glsl_mnxn(const struct wined3d_shader_instruction *ins)
+{
+ int i;
+ int nComponents = 0;
+ struct wined3d_shader_dst_param tmp_dst = {{0}};
+ struct wined3d_shader_src_param tmp_src[2] = {{{0}}};
+ struct wined3d_shader_instruction tmp_ins;
+
+ memset(&tmp_ins, 0, sizeof(tmp_ins));
+
+ /* Set constants for the temporary argument */
+ tmp_ins.ctx = ins->ctx;
+ tmp_ins.dst_count = 1;
+ tmp_ins.dst = &tmp_dst;
+ tmp_ins.src_count = 2;
+ tmp_ins.src = tmp_src;
+
+ switch(ins->handler_idx)
+ {
+ case WINED3DSIH_M4x4:
+ nComponents = 4;
+ tmp_ins.handler_idx = WINED3DSIH_DP4;
+ break;
+ case WINED3DSIH_M4x3:
+ nComponents = 3;
+ tmp_ins.handler_idx = WINED3DSIH_DP4;
+ break;
+ case WINED3DSIH_M3x4:
+ nComponents = 4;
+ tmp_ins.handler_idx = WINED3DSIH_DP3;
+ break;
+ case WINED3DSIH_M3x3:
+ nComponents = 3;
+ tmp_ins.handler_idx = WINED3DSIH_DP3;
+ break;
+ case WINED3DSIH_M3x2:
+ nComponents = 2;
+ tmp_ins.handler_idx = WINED3DSIH_DP3;
+ break;
+ default:
+ break;
+ }
+
+ tmp_dst = ins->dst[0];
+ tmp_src[0] = ins->src[0];
+ tmp_src[1] = ins->src[1];
+ for (i = 0; i < nComponents; ++i)
+ {
+ tmp_dst.write_mask = WINED3DSP_WRITEMASK_0 << i;
+ shader_glsl_dot(&tmp_ins);
+ ++tmp_src[1].reg.idx[0].offset;
+ }
+}
+
+/**
+ The LRP instruction performs a component-wise linear interpolation
+ between the second and third operands using the first operand as the
+ blend factor. Equation: (dst = src2 + src0 * (src1 - src2))
+ This is equivalent to mix(src2, src1, src0);
+*/
+static void shader_glsl_lrp(const struct wined3d_shader_instruction *ins)
+{
+ struct glsl_src_param src0_param;
+ struct glsl_src_param src1_param;
+ struct glsl_src_param src2_param;
+ DWORD write_mask;
+
+ write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
+
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
+
+ shader_addline(ins->ctx->buffer, "mix(%s, %s, %s));\n",
+ src2_param.param_str, src1_param.param_str, src0_param.param_str);
+}
+
+/** Process the WINED3DSIO_LIT instruction in GLSL:
+ * dst.x = dst.w = 1.0
+ * dst.y = (src0.x > 0) ? src0.x
+ * dst.z = (src0.x > 0) ? ((src0.y > 0) ? pow(src0.y, src.w) : 0) : 0
+ * where src.w is clamped at +- 128
+ */
+static void shader_glsl_lit(const struct wined3d_shader_instruction *ins)
+{
+ struct glsl_src_param src0_param;
+ struct glsl_src_param src1_param;
+ struct glsl_src_param src3_param;
+ char dst_mask[6];
+
+ shader_glsl_append_dst(ins->ctx->buffer, ins);
+ shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
+
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_1, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &src3_param);
+
+ /* The sdk specifies the instruction like this
+ * dst.x = 1.0;
+ * if(src.x > 0.0) dst.y = src.x
+ * else dst.y = 0.0.
+ * if(src.x > 0.0 && src.y > 0.0) dst.z = pow(src.y, power);
+ * else dst.z = 0.0;
+ * dst.w = 1.0;
+ * (where power = src.w clamped between -128 and 128)
+ *
+ * Obviously that has quite a few conditionals in it which we don't like. So the first step is this:
+ * dst.x = 1.0 ... No further explanation needed
+ * dst.y = max(src.y, 0.0); ... If x < 0.0, use 0.0, otherwise x. Same as the conditional
+ * dst.z = x > 0.0 ? pow(max(y, 0.0), p) : 0; ... 0 ^ power is 0, and otherwise we use y anyway
+ * dst.w = 1.0. ... Nothing fancy.
+ *
+ * So we still have one conditional in there. So do this:
+ * dst.z = pow(max(0.0, src.y) * step(0.0, src.x), power);
+ *
+ * step(0.0, x) will return 1 if src.x > 0.0, and 0 otherwise. So if y is 0 we get pow(0.0 * 1.0, power),
+ * which sets dst.z to 0. If y > 0, but x = 0.0, we get pow(y * 0.0, power), which results in 0 too.
+ * if both x and y are > 0, we get pow(y * 1.0, power), as it is supposed to.
+ *
+ * Unfortunately pow(0.0 ^ 0.0) returns NaN on most GPUs, but lit with src.y = 0 and src.w = 0 returns
+ * a non-NaN value in dst.z. What we return doesn't matter, as long as it is not NaN. Return 0, which is
+ * what all Windows HW drivers and GL_ARB_vertex_program's LIT do.
+ */
+ shader_addline(ins->ctx->buffer,
+ "vec4(1.0, max(%s, 0.0), %s == 0.0 ? 0.0 : "
+ "pow(max(0.0, %s) * step(0.0, %s), clamp(%s, -128.0, 128.0)), 1.0)%s);\n",
+ src0_param.param_str, src3_param.param_str, src1_param.param_str,
+ src0_param.param_str, src3_param.param_str, dst_mask);
+}
+
+/** Process the WINED3DSIO_DST instruction in GLSL:
+ * dst.x = 1.0
+ * dst.y = src0.x * src0.y
+ * dst.z = src0.z
+ * dst.w = src1.w
+ */
+static void shader_glsl_dst(const struct wined3d_shader_instruction *ins)
+{
+ struct glsl_src_param src0y_param;
+ struct glsl_src_param src0z_param;
+ struct glsl_src_param src1y_param;
+ struct glsl_src_param src1w_param;
+ char dst_mask[6];
+
+ shader_glsl_append_dst(ins->ctx->buffer, ins);
+ shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
+
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_1, &src0y_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_2, &src0z_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_1, &src1y_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_3, &src1w_param);
+
+ shader_addline(ins->ctx->buffer, "vec4(1.0, %s * %s, %s, %s))%s;\n",
+ src0y_param.param_str, src1y_param.param_str, src0z_param.param_str, src1w_param.param_str, dst_mask);
+}
+
+/** Process the WINED3DSIO_SINCOS instruction in GLSL:
+ * VS 2.0 requires that specific cosine and sine constants be passed to this instruction so the hardware
+ * can handle it. But, these functions are built-in for GLSL, so we can just ignore the last 2 params.
+ *
+ * dst.x = cos(src0.?)
+ * dst.y = sin(src0.?)
+ * dst.z = dst.z
+ * dst.w = dst.w
+ */
+static void shader_glsl_sincos(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct glsl_src_param src0_param;
+ DWORD write_mask;
+
+ if (ins->ctx->reg_maps->shader_version.major < 4)
+ {
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+
+ write_mask = shader_glsl_append_dst(buffer, ins);
+ switch (write_mask)
+ {
+ case WINED3DSP_WRITEMASK_0:
+ shader_addline(buffer, "cos(%s));\n", src0_param.param_str);
+ break;
+
+ case WINED3DSP_WRITEMASK_1:
+ shader_addline(buffer, "sin(%s));\n", src0_param.param_str);
+ break;
+
+ case (WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1):
+ shader_addline(buffer, "vec2(cos(%s), sin(%s)));\n",
+ src0_param.param_str, src0_param.param_str);
+ break;
+
+ default:
+ ERR("Write mask should be .x, .y or .xy\n");
+ break;
+ }
+
+ return;
+ }
+
+ if (ins->dst[0].reg.type != WINED3DSPR_NULL)
+ {
+
+ if (ins->dst[1].reg.type != WINED3DSPR_NULL)
+ {
+ char dst_mask[6];
+
+ write_mask = shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+ shader_addline(buffer, "tmp0%s = sin(%s);\n", dst_mask, src0_param.param_str);
+
+ write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1]);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+ shader_addline(buffer, "cos(%s));\n", src0_param.param_str);
+
+ shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0]);
+ shader_addline(buffer, "tmp0%s);\n", dst_mask);
+ }
+ else
+ {
+ write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0]);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+ shader_addline(buffer, "sin(%s));\n", src0_param.param_str);
+ }
+ }
+ else if (ins->dst[1].reg.type != WINED3DSPR_NULL)
+ {
+ write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[1]);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+ shader_addline(buffer, "cos(%s));\n", src0_param.param_str);
+ }
+}
+
+/* sgn in vs_2_0 has 2 extra parameters(registers for temporary storage) which we don't use
+ * here. But those extra parameters require a dedicated function for sgn, since map2gl would
+ * generate invalid code
+ */
+static void shader_glsl_sgn(const struct wined3d_shader_instruction *ins)
+{
+ struct glsl_src_param src0_param;
+ DWORD write_mask;
+
+ write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
+ shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
+
+ shader_addline(ins->ctx->buffer, "sign(%s));\n", src0_param.param_str);
+}
+
+/** Process the WINED3DSIO_LOOP instruction in GLSL:
+ * Start a for() loop where src1.y is the initial value of aL,
+ * increment aL by src1.z for a total of src1.x iterations.
+ * Need to use a temporary variable for this operation.
+ */
+/* FIXME: I don't think nested loops will work correctly this way. */
+static void shader_glsl_loop(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_loop_state *loop_state = ins->ctx->loop_state;
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ const struct wined3d_shader *shader = ins->ctx->shader;
+ const struct wined3d_shader_lconst *constant;
+ struct glsl_src_param src1_param;
+ const DWORD *control_values = NULL;
+
+ if (ins->ctx->reg_maps->shader_version.major < 4)
+ {
+ shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_ALL, &src1_param);
+
+ /* Try to hardcode the loop control parameters if possible. Direct3D 9
+ * class hardware doesn't support real varying indexing, but Microsoft
+ * designed this feature for Shader model 2.x+. If the loop control is
+ * known at compile time, the GLSL compiler can unroll the loop, and
+ * replace indirect addressing with direct addressing. */
+ if (ins->src[1].reg.type == WINED3DSPR_CONSTINT)
+ {
+ LIST_FOR_EACH_ENTRY(constant, &shader->constantsI, struct wined3d_shader_lconst, entry)
+ {
+ if (constant->idx == ins->src[1].reg.idx[0].offset)
+ {
+ control_values = constant->value;
+ break;
+ }
+ }
+ }
+
+ if (control_values)
+ {
+ struct wined3d_shader_loop_control loop_control;
+ loop_control.count = control_values[0];
+ loop_control.start = control_values[1];
+ loop_control.step = (int)control_values[2];
+
+ if (loop_control.step > 0)
+ {
+ shader_addline(buffer, "for (aL%u = %u; aL%u < (%u * %d + %u); aL%u += %d)\n{\n",
+ loop_state->current_depth, loop_control.start,
+ loop_state->current_depth, loop_control.count, loop_control.step, loop_control.start,
+ loop_state->current_depth, loop_control.step);
+ }
+ else if (loop_control.step < 0)
+ {
+ shader_addline(buffer, "for (aL%u = %u; aL%u > (%u * %d + %u); aL%u += %d)\n{\n",
+ loop_state->current_depth, loop_control.start,
+ loop_state->current_depth, loop_control.count, loop_control.step, loop_control.start,
+ loop_state->current_depth, loop_control.step);
+ }
+ else
+ {
+ shader_addline(buffer, "for (aL%u = %u, tmpInt%u = 0; tmpInt%u < %u; tmpInt%u++)\n{\n",
+ loop_state->current_depth, loop_control.start, loop_state->current_depth,
+ loop_state->current_depth, loop_control.count,
+ loop_state->current_depth);
+ }
+ }
+ else
+ {
+ shader_addline(buffer, "for (tmpInt%u = 0, aL%u = %s.y; tmpInt%u < %s.x; tmpInt%u++, aL%u += %s.z)\n{\n",
+ loop_state->current_depth, loop_state->current_reg,
+ src1_param.reg_name, loop_state->current_depth, src1_param.reg_name,
+ loop_state->current_depth, loop_state->current_reg, src1_param.reg_name);
+ }
+
+ ++loop_state->current_reg;
+ }
+ else
+ {
+ shader_addline(buffer, "for (;;)\n{\n");
+ }
+
+ ++loop_state->current_depth;
+}
+
+static void shader_glsl_end(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_loop_state *loop_state = ins->ctx->loop_state;
+
+ shader_addline(ins->ctx->buffer, "}\n");
+
+ if (ins->handler_idx == WINED3DSIH_ENDLOOP)
+ {
+ --loop_state->current_depth;
+ --loop_state->current_reg;
+ }
+
+ if (ins->handler_idx == WINED3DSIH_ENDREP)
+ {
+ --loop_state->current_depth;
+ }
+}
+
+static void shader_glsl_rep(const struct wined3d_shader_instruction *ins)
+{
+ const struct wined3d_shader *shader = ins->ctx->shader;
+ struct wined3d_shader_loop_state *loop_state = ins->ctx->loop_state;
+ const struct wined3d_shader_lconst *constant;
+ struct glsl_src_param src0_param;
+ const DWORD *control_values = NULL;
+
+ /* Try to hardcode local values to help the GLSL compiler to unroll and optimize the loop */
+ if (ins->src[0].reg.type == WINED3DSPR_CONSTINT)
+ {
+ LIST_FOR_EACH_ENTRY(constant, &shader->constantsI, struct wined3d_shader_lconst, entry)
+ {
+ if (constant->idx == ins->src[0].reg.idx[0].offset)
+ {
+ control_values = constant->value;
+ break;
+ }
+ }
+ }
+
+ if (control_values)
+ {
+ shader_addline(ins->ctx->buffer, "for (tmpInt%d = 0; tmpInt%d < %d; tmpInt%d++) {\n",
+ loop_state->current_depth, loop_state->current_depth,
+ control_values[0], loop_state->current_depth);
+ }
+ else
+ {
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+ shader_addline(ins->ctx->buffer, "for (tmpInt%d = 0; tmpInt%d < %s; tmpInt%d++) {\n",
+ loop_state->current_depth, loop_state->current_depth,
+ src0_param.param_str, loop_state->current_depth);
+ }
+
+ ++loop_state->current_depth;
+}
+
+static void shader_glsl_if(const struct wined3d_shader_instruction *ins)
+{
+ struct glsl_src_param src0_param;
+
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+ shader_addline(ins->ctx->buffer, "if (%s) {\n", src0_param.param_str);
+}
+
+static void shader_glsl_ifc(const struct wined3d_shader_instruction *ins)
+{
+ struct glsl_src_param src0_param;
+ struct glsl_src_param src1_param;
+
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &src1_param);
+
+ shader_addline(ins->ctx->buffer, "if (%s %s %s) {\n",
+ src0_param.param_str, shader_glsl_get_rel_op(ins->flags), src1_param.param_str);
+}
+
+static void shader_glsl_else(const struct wined3d_shader_instruction *ins)
+{
+ shader_addline(ins->ctx->buffer, "} else {\n");
+}
+
+static void shader_glsl_emit(const struct wined3d_shader_instruction *ins)
+{
+ shader_addline(ins->ctx->buffer, "EmitVertex();\n");
+}
+
+static void shader_glsl_break(const struct wined3d_shader_instruction *ins)
+{
+ shader_addline(ins->ctx->buffer, "break;\n");
+}
+
+/* FIXME: According to MSDN the compare is done per component. */
+static void shader_glsl_breakc(const struct wined3d_shader_instruction *ins)
+{
+ struct glsl_src_param src0_param;
+ struct glsl_src_param src1_param;
+
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &src1_param);
+
+ shader_addline(ins->ctx->buffer, "if (%s %s %s) break;\n",
+ src0_param.param_str, shader_glsl_get_rel_op(ins->flags), src1_param.param_str);
+}
+
+static void shader_glsl_breakp(const struct wined3d_shader_instruction *ins)
+{
+ struct glsl_src_param src_param;
+
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src_param);
+ shader_addline(ins->ctx->buffer, "if (bool(%s)) break;\n", src_param.param_str);
+}
+
+static void shader_glsl_label(const struct wined3d_shader_instruction *ins)
+{
+ shader_addline(ins->ctx->buffer, "}\n");
+ shader_addline(ins->ctx->buffer, "void subroutine%u()\n{\n", ins->src[0].reg.idx[0].offset);
+}
+
+static void shader_glsl_call(const struct wined3d_shader_instruction *ins)
+{
+ shader_addline(ins->ctx->buffer, "subroutine%u();\n", ins->src[0].reg.idx[0].offset);
+}
+
+static void shader_glsl_callnz(const struct wined3d_shader_instruction *ins)
+{
+ struct glsl_src_param src1_param;
+
+ shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0, &src1_param);
+ shader_addline(ins->ctx->buffer, "if (%s) subroutine%u();\n",
+ src1_param.param_str, ins->src[0].reg.idx[0].offset);
+}
+
+static void shader_glsl_ret(const struct wined3d_shader_instruction *ins)
+{
+ /* No-op. The closing } is written when a new function is started, and at the end of the shader. This
+ * function only suppresses the unhandled instruction warning
+ */
+}
+
+/*********************************************
+ * Pixel Shader Specific Code begins here
+ ********************************************/
+static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
+{
+ DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
+ ins->ctx->reg_maps->shader_version.minor);
+ struct glsl_sample_function sample_function;
+ DWORD sample_flags = 0;
+ DWORD sampler_idx;
+ DWORD mask = 0, swizzle;
+ const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
+
+ /* 1.0-1.4: Use destination register as sampler source.
+ * 2.0+: Use provided sampler source. */
+ if (shader_version < WINED3D_SHADER_VERSION(2,0))
+ sampler_idx = ins->dst[0].reg.idx[0].offset;
+ else
+ sampler_idx = ins->src[1].reg.idx[0].offset;
+
+ if (shader_version < WINED3D_SHADER_VERSION(1,4))
+ {
+ DWORD flags = (priv->cur_ps_args->tex_transform >> sampler_idx * WINED3D_PSARGS_TEXTRANSFORM_SHIFT)
+ & WINED3D_PSARGS_TEXTRANSFORM_MASK;
+ enum wined3d_sampler_texture_type sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
+
+ /* Projected cube textures don't make a lot of sense, the resulting coordinates stay the same. */
+ if (flags & WINED3D_PSARGS_PROJECTED && sampler_type != WINED3DSTT_CUBE)
+ {
+ sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED;
+ switch (flags & ~WINED3D_PSARGS_PROJECTED)
+ {
+ case WINED3D_TTFF_COUNT1:
+ FIXME("WINED3D_TTFF_PROJECTED with WINED3D_TTFF_COUNT1?\n");
+ break;
+ case WINED3D_TTFF_COUNT2:
+ mask = WINED3DSP_WRITEMASK_1;
+ break;
+ case WINED3D_TTFF_COUNT3:
+ mask = WINED3DSP_WRITEMASK_2;
+ break;
+ case WINED3D_TTFF_COUNT4:
+ case WINED3D_TTFF_DISABLE:
+ mask = WINED3DSP_WRITEMASK_3;
+ break;
+ }
+ }
+ }
+ else if (shader_version < WINED3D_SHADER_VERSION(2,0))
+ {
+ enum wined3d_shader_src_modifier src_mod = ins->src[0].modifiers;
+
+ if (src_mod == WINED3DSPSM_DZ) {
+ sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED;
+ mask = WINED3DSP_WRITEMASK_2;
+ } else if (src_mod == WINED3DSPSM_DW) {
+ sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED;
+ mask = WINED3DSP_WRITEMASK_3;
+ }
+ }
+ else
+ {
+ if ((ins->flags & WINED3DSI_TEXLD_PROJECT)
+ && ins->ctx->reg_maps->sampler_type[sampler_idx] != WINED3DSTT_CUBE)
+ {
+ /* ps 2.0 texldp instruction always divides by the fourth component. */
+ sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED;
+ mask = WINED3DSP_WRITEMASK_3;
+ }
+ }
+
+ if (priv->cur_ps_args->np2_fixup & (1 << sampler_idx))
+ sample_flags |= WINED3D_GLSL_SAMPLE_NPOT;
+
+ shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function);
+ mask |= sample_function.coord_mask;
+
+ if (shader_version < WINED3D_SHADER_VERSION(2,0)) swizzle = WINED3DSP_NOSWIZZLE;
+ else swizzle = ins->src[1].swizzle;
+
+ /* 1.0-1.3: Use destination register as coordinate source.
+ 1.4+: Use provided coordinate source register. */
+ if (shader_version < WINED3D_SHADER_VERSION(1,4))
+ {
+ char coord_mask[6];
+ shader_glsl_write_mask_to_str(mask, coord_mask);
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, NULL,
+ "T%u%s", sampler_idx, coord_mask);
+ }
+ else
+ {
+ struct glsl_src_param coord_param;
+ shader_glsl_add_src_param(ins, &ins->src[0], mask, &coord_param);
+ if (ins->flags & WINED3DSI_TEXLD_BIAS)
+ {
+ struct glsl_src_param bias;
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &bias);
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, bias.param_str,
+ "%s", coord_param.param_str);
+ } else {
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, NULL,
+ "%s", coord_param.param_str);
+ }
+ }
+}
+
+static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins)
+{
+ const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
+ struct glsl_src_param coord_param, dx_param, dy_param;
+ DWORD sample_flags = WINED3D_GLSL_SAMPLE_GRAD;
+ struct glsl_sample_function sample_function;
+ DWORD sampler_idx;
+ DWORD swizzle = ins->src[1].swizzle;
+ const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
+
+ if (!gl_info->supported[ARB_SHADER_TEXTURE_LOD] && !gl_info->supported[EXT_GPU_SHADER4])
+ {
+ FIXME("texldd used, but not supported by hardware. Falling back to regular tex\n");
+ shader_glsl_tex(ins);
+ return;
+ }
+
+ sampler_idx = ins->src[1].reg.idx[0].offset;
+ if (priv->cur_ps_args->np2_fixup & (1 << sampler_idx))
+ sample_flags |= WINED3D_GLSL_SAMPLE_NPOT;
+
+ shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function);
+ shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
+ shader_glsl_add_src_param(ins, &ins->src[2], sample_function.coord_mask, &dx_param);
+ shader_glsl_add_src_param(ins, &ins->src[3], sample_function.coord_mask, &dy_param);
+
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, dx_param.param_str, dy_param.param_str, NULL,
+ "%s", coord_param.param_str);
+}
+
+static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins)
+{
+ const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
+ struct glsl_src_param coord_param, lod_param;
+ DWORD sample_flags = WINED3D_GLSL_SAMPLE_LOD;
+ struct glsl_sample_function sample_function;
+ DWORD sampler_idx;
+ DWORD swizzle = ins->src[1].swizzle;
+ const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
+
+ sampler_idx = ins->src[1].reg.idx[0].offset;
+ if (ins->ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL
+ && priv->cur_ps_args->np2_fixup & (1 << sampler_idx))
+ sample_flags |= WINED3D_GLSL_SAMPLE_NPOT;
+
+ shader_glsl_get_sample_function(ins->ctx, sampler_idx, sample_flags, &sample_function);
+ shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
+
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &lod_param);
+
+ if (!gl_info->supported[ARB_SHADER_TEXTURE_LOD] && !gl_info->supported[EXT_GPU_SHADER4]
+ && ins->ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
+ {
+ /* Plain GLSL only supports Lod sampling functions in vertex shaders.
+ * However, the NVIDIA drivers allow them in fragment shaders as well,
+ * even without the appropriate extension. */
+ WARN("Using %s in fragment shader.\n", sample_function.name);
+ }
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, lod_param.param_str,
+ "%s", coord_param.param_str);
+}
+
+static void shader_glsl_texcoord(const struct wined3d_shader_instruction *ins)
+{
+ /* FIXME: Make this work for more than just 2D textures */
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ DWORD write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
+
+ if (!(ins->ctx->reg_maps->shader_version.major == 1 && ins->ctx->reg_maps->shader_version.minor == 4))
+ {
+ char dst_mask[6];
+
+ shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
+ shader_addline(buffer, "clamp(gl_TexCoord[%u], 0.0, 1.0)%s);\n",
+ ins->dst[0].reg.idx[0].offset, dst_mask);
+ }
+ else
+ {
+ enum wined3d_shader_src_modifier src_mod = ins->src[0].modifiers;
+ DWORD reg = ins->src[0].reg.idx[0].offset;
+ char dst_swizzle[6];
+
+ shader_glsl_get_swizzle(&ins->src[0], FALSE, write_mask, dst_swizzle);
+
+ if (src_mod == WINED3DSPSM_DZ)
+ {
+ unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
+ struct glsl_src_param div_param;
+
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_2, &div_param);
+
+ if (mask_size > 1) {
+ shader_addline(buffer, "gl_TexCoord[%u]%s / vec%d(%s));\n", reg, dst_swizzle, mask_size, div_param.param_str);
+ } else {
+ shader_addline(buffer, "gl_TexCoord[%u]%s / %s);\n", reg, dst_swizzle, div_param.param_str);
+ }
+ }
+ else if (src_mod == WINED3DSPSM_DW)
+ {
+ unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
+ struct glsl_src_param div_param;
+
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &div_param);
+
+ if (mask_size > 1) {
+ shader_addline(buffer, "gl_TexCoord[%u]%s / vec%d(%s));\n", reg, dst_swizzle, mask_size, div_param.param_str);
+ } else {
+ shader_addline(buffer, "gl_TexCoord[%u]%s / %s);\n", reg, dst_swizzle, div_param.param_str);
+ }
+ } else {
+ shader_addline(buffer, "gl_TexCoord[%u]%s);\n", reg, dst_swizzle);
+ }
+ }
+}
+
+/** Process the WINED3DSIO_TEXDP3TEX instruction in GLSL:
+ * Take a 3-component dot product of the TexCoord[dstreg] and src,
+ * then perform a 1D texture lookup from stage dstregnum, place into dst. */
+static void shader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins)
+{
+ DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
+ DWORD sampler_idx = ins->dst[0].reg.idx[0].offset;
+ struct glsl_sample_function sample_function;
+ struct glsl_src_param src0_param;
+ UINT mask_size;
+
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
+
+ /* Do I have to take care about the projected bit? I don't think so, since the dp3 returns only one
+ * scalar, and projected sampling would require 4.
+ *
+ * It is a dependent read - not valid with conditional NP2 textures
+ */
+ shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function);
+ mask_size = shader_glsl_get_write_mask_size(sample_function.coord_mask);
+
+ switch(mask_size)
+ {
+ case 1:
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
+ "dot(gl_TexCoord[%u].xyz, %s)", sampler_idx, src0_param.param_str);
+ break;
+
+ case 2:
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
+ "vec2(dot(gl_TexCoord[%u].xyz, %s), 0.0)", sampler_idx, src0_param.param_str);
+ break;
+
+ case 3:
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
+ "vec3(dot(gl_TexCoord[%u].xyz, %s), 0.0, 0.0)", sampler_idx, src0_param.param_str);
+ break;
+
+ default:
+ FIXME("Unexpected mask size %u\n", mask_size);
+ break;
+ }
+}
+
+/** Process the WINED3DSIO_TEXDP3 instruction in GLSL:
+ * Take a 3-component dot product of the TexCoord[dstreg] and src. */
+static void shader_glsl_texdp3(const struct wined3d_shader_instruction *ins)
+{
+ DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
+ DWORD dstreg = ins->dst[0].reg.idx[0].offset;
+ struct glsl_src_param src0_param;
+ DWORD dst_mask;
+ unsigned int mask_size;
+
+ dst_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
+ mask_size = shader_glsl_get_write_mask_size(dst_mask);
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
+
+ if (mask_size > 1) {
+ shader_addline(ins->ctx->buffer, "vec%d(dot(T%u.xyz, %s)));\n", mask_size, dstreg, src0_param.param_str);
+ } else {
+ shader_addline(ins->ctx->buffer, "dot(T%u.xyz, %s));\n", dstreg, src0_param.param_str);
+ }
+}
+
+/** Process the WINED3DSIO_TEXDEPTH instruction in GLSL:
+ * Calculate the depth as dst.x / dst.y */
+static void shader_glsl_texdepth(const struct wined3d_shader_instruction *ins)
+{
+ struct glsl_dst_param dst_param;
+
+ shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param);
+
+ /* Tests show that texdepth never returns anything below 0.0, and that r5.y is clamped to 1.0.
+ * Negative input is accepted, -0.25 / -0.5 returns 0.5. GL should clamp gl_FragDepth to [0;1], but
+ * this doesn't always work, so clamp the results manually. Whether or not the x value is clamped at 1
+ * too is irrelevant, since if x = 0, any y value < 1.0 (and > 1.0 is not allowed) results in a result
+ * >= 1.0 or < 0.0
+ */
+ shader_addline(ins->ctx->buffer, "gl_FragDepth = clamp((%s.x / min(%s.y, 1.0)), 0.0, 1.0);\n",
+ dst_param.reg_name, dst_param.reg_name);
+}
+
+/** Process the WINED3DSIO_TEXM3X2DEPTH instruction in GLSL:
+ * Last row of a 3x2 matrix multiply, use the result to calculate the depth:
+ * Calculate tmp0.y = TexCoord[dstreg] . src.xyz; (tmp0.x has already been calculated)
+ * depth = (tmp0.y == 0.0) ? 1.0 : tmp0.x / tmp0.y
+ */
+static void shader_glsl_texm3x2depth(const struct wined3d_shader_instruction *ins)
+{
+ DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
+ DWORD dstreg = ins->dst[0].reg.idx[0].offset;
+ struct glsl_src_param src0_param;
+
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
+
+ shader_addline(ins->ctx->buffer, "tmp0.y = dot(T%u.xyz, %s);\n", dstreg, src0_param.param_str);
+ shader_addline(ins->ctx->buffer, "gl_FragDepth = (tmp0.y == 0.0) ? 1.0 : clamp(tmp0.x / tmp0.y, 0.0, 1.0);\n");
+}
+
+/** Process the WINED3DSIO_TEXM3X2PAD instruction in GLSL
+ * Calculate the 1st of a 2-row matrix multiplication. */
+static void shader_glsl_texm3x2pad(const struct wined3d_shader_instruction *ins)
+{
+ DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
+ DWORD reg = ins->dst[0].reg.idx[0].offset;
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct glsl_src_param src0_param;
+
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
+ shader_addline(buffer, "tmp0.x = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
+}
+
+/** Process the WINED3DSIO_TEXM3X3PAD instruction in GLSL
+ * Calculate the 1st or 2nd row of a 3-row matrix multiplication. */
+static void shader_glsl_texm3x3pad(const struct wined3d_shader_instruction *ins)
+{
+ DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
+ DWORD reg = ins->dst[0].reg.idx[0].offset;
+ struct glsl_src_param src0_param;
+
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
+ shader_addline(buffer, "tmp0.%c = dot(T%u.xyz, %s);\n", 'x' + tex_mx->current_row, reg, src0_param.param_str);
+ tex_mx->texcoord_w[tex_mx->current_row++] = reg;
+}
+
+static void shader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins)
+{
+ DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct glsl_sample_function sample_function;
+ DWORD reg = ins->dst[0].reg.idx[0].offset;
+ struct glsl_src_param src0_param;
+
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
+ shader_addline(buffer, "tmp0.y = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
+
+ shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function);
+
+ /* Sample the texture using the calculated coordinates */
+ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xy");
+}
+
+/** Process the WINED3DSIO_TEXM3X3TEX instruction in GLSL
+ * Perform the 3rd row of a 3x3 matrix multiply, then sample the texture using the calculated coordinates */
+static void shader_glsl_texm3x3tex(const struct wined3d_shader_instruction *ins)
+{
+ DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
+ struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
+ struct glsl_sample_function sample_function;
+ DWORD reg = ins->dst[0].reg.idx[0].offset;
+ struct glsl_src_param src0_param;
+
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
+ shader_addline(ins->ctx->buffer, "tmp0.z = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
+
+ /* Dependent read, not valid with conditional NP2 */
+ shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function);
+
+ /* Sample the texture using the calculated coordinates */
+ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
+
+ tex_mx->current_row = 0;
+}
+
+/** Process the WINED3DSIO_TEXM3X3 instruction in GLSL
+ * Perform the 3rd row of a 3x3 matrix multiply */
+static void shader_glsl_texm3x3(const struct wined3d_shader_instruction *ins)
+{
+ DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
+ struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
+ DWORD reg = ins->dst[0].reg.idx[0].offset;
+ struct glsl_src_param src0_param;
+ char dst_mask[6];
+
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
+
+ shader_glsl_append_dst(ins->ctx->buffer, ins);
+ shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
+ shader_addline(ins->ctx->buffer, "vec4(tmp0.xy, dot(T%u.xyz, %s), 1.0)%s);\n", reg, src0_param.param_str, dst_mask);
+
+ tex_mx->current_row = 0;
+}
+
+/* Process the WINED3DSIO_TEXM3X3SPEC instruction in GLSL
+ * Perform the final texture lookup based on the previous 2 3x3 matrix multiplies */
+static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins)
+{
+ struct glsl_src_param src0_param;
+ struct glsl_src_param src1_param;
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
+ DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
+ struct glsl_sample_function sample_function;
+ DWORD reg = ins->dst[0].reg.idx[0].offset;
+ char coord_mask[6];
+
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], src_mask, &src1_param);
+
+ /* Perform the last matrix multiply operation */
+ shader_addline(buffer, "tmp0.z = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
+ /* Reflection calculation */
+ shader_addline(buffer, "tmp0.xyz = -reflect((%s), normalize(tmp0.xyz));\n", src1_param.param_str);
+
+ /* Dependent read, not valid with conditional NP2 */
+ shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function);
+ shader_glsl_write_mask_to_str(sample_function.coord_mask, coord_mask);
+
+ /* Sample the texture */
+ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE,
+ NULL, NULL, NULL, "tmp0%s", coord_mask);
+
+ tex_mx->current_row = 0;
+}
+
+/* Process the WINED3DSIO_TEXM3X3VSPEC instruction in GLSL
+ * Perform the final texture lookup based on the previous 2 3x3 matrix multiplies */
+static void shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *ins)
+{
+ struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
+ struct wined3d_shader_tex_mx *tex_mx = ins->ctx->tex_mx;
+ DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
+ struct glsl_sample_function sample_function;
+ DWORD reg = ins->dst[0].reg.idx[0].offset;
+ struct glsl_src_param src0_param;
+ char coord_mask[6];
+
+ shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
+
+ /* Perform the last matrix multiply operation */
+ shader_addline(buffer, "tmp0.z = dot(vec3(T%u), vec3(%s));\n", reg, src0_param.param_str);
+
+ /* Construct the eye-ray vector from w coordinates */
+ shader_addline(buffer, "tmp1.xyz = normalize(vec3(gl_TexCoord[%u].w, gl_TexCoord[%u].w, gl_TexCoord[%u].w));\n",
+ tex_mx->texcoord_w[0], tex_mx->texcoord_w[1], reg);
+ shader_addline(buffer, "tmp0.xyz = -reflect(tmp1.xyz, normalize(tmp0.xyz));\n");
+
+ /* Dependent read, not valid with conditional NP2 */
+ shader_glsl_get_sample_function(ins->ctx, reg, 0, &sample_function);
+ shader_glsl_write_mask_to_str(sample_function.coord_mask, coord_mask);
+
+ /* Sample the texture using the calculated coordinates */
+ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE,
+ NULL, NULL, NULL, "tmp0%s", coord_mask);
+
+ tex_mx->current_row = 0;
+}
+
+/** Process the WINED3DSIO_TEXBEM instruction in GLSL.
+ * Apply a fake bump map transform.
+ * texbem is pshader <= 1.3 only, this saves a few version checks
+ */
+static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins)
+{
+ const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
+ struct glsl_sample_function sample_function;
+ struct glsl_src_param coord_param;
+ DWORD sampler_idx;
+ DWORD mask;
+ DWORD flags;
+ char coord_mask[6];
+
+ sampler_idx = ins->dst[0].reg.idx[0].offset;
+ flags = (priv->cur_ps_args->tex_transform >> sampler_idx * WINED3D_PSARGS_TEXTRANSFORM_SHIFT)
+ & WINED3D_PSARGS_TEXTRANSFORM_MASK;
+
+ /* Dependent read, not valid with conditional NP2 */
+ shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function);
+ mask = sample_function.coord_mask;
+
+ shader_glsl_write_mask_to_str(mask, coord_mask);
+
+ /* With projected textures, texbem only divides the static texture coord,
+ * not the displacement, so we can't let GL handle this. */
+ if (flags & WINED3D_PSARGS_PROJECTED)
+ {
+ DWORD div_mask=0;
+ char coord_div_mask[3];
+ switch (flags & ~WINED3D_PSARGS_PROJECTED)
+ {
+ case WINED3D_TTFF_COUNT1:
+ FIXME("WINED3D_TTFF_PROJECTED with WINED3D_TTFF_COUNT1?\n");
+ break;
+ case WINED3D_TTFF_COUNT2:
+ div_mask = WINED3DSP_WRITEMASK_1;
+ break;
+ case WINED3D_TTFF_COUNT3:
+ div_mask = WINED3DSP_WRITEMASK_2;
+ break;
+ case WINED3D_TTFF_COUNT4:
+ case WINED3D_TTFF_DISABLE:
+ div_mask = WINED3DSP_WRITEMASK_3;
+ break;
+ }
+ shader_glsl_write_mask_to_str(div_mask, coord_div_mask);
+ shader_addline(ins->ctx->buffer, "T%u%s /= T%u%s;\n", sampler_idx, coord_mask, sampler_idx, coord_div_mask);
+ }
+
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &coord_param);
+
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
+ "T%u%s + vec4(bumpenv_mat%u * %s, 0.0, 0.0)%s", sampler_idx, coord_mask, sampler_idx,
+ coord_param.param_str, coord_mask);
+
+ if (ins->handler_idx == WINED3DSIH_TEXBEML)
+ {
+ struct glsl_src_param luminance_param;
+ struct glsl_dst_param dst_param;
+
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_2, &luminance_param);
+ shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param);
+
+ shader_addline(ins->ctx->buffer, "%s%s *= (%s * bumpenv_lum_scale%u + bumpenv_lum_offset%u);\n",
+ dst_param.reg_name, dst_param.mask_str,
+ luminance_param.param_str, sampler_idx, sampler_idx);
+ }
+}
+
+static void shader_glsl_bem(const struct wined3d_shader_instruction *ins)
+{
+ DWORD sampler_idx = ins->dst[0].reg.idx[0].offset;
+ struct glsl_src_param src0_param, src1_param;
+
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src1_param);
+
+ shader_glsl_append_dst(ins->ctx->buffer, ins);
+ shader_addline(ins->ctx->buffer, "%s + bumpenv_mat%u * %s);\n",
+ src0_param.param_str, sampler_idx, src1_param.param_str);
+}
+
+/** Process the WINED3DSIO_TEXREG2AR instruction in GLSL
+ * Sample 2D texture at dst using the alpha & red (wx) components of src as texture coordinates */
+static void shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
+{
+ DWORD sampler_idx = ins->dst[0].reg.idx[0].offset;
+ struct glsl_sample_function sample_function;
+ struct glsl_src_param src0_param;
+
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
+
+ shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function);
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
+ "%s.wx", src0_param.reg_name);
+}
+
+/** Process the WINED3DSIO_TEXREG2GB instruction in GLSL
+ * Sample 2D texture at dst using the green & blue (yz) components of src as texture coordinates */
+static void shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
+{
+ DWORD sampler_idx = ins->dst[0].reg.idx[0].offset;
+ struct glsl_sample_function sample_function;
+ struct glsl_src_param src0_param;
+
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
+
+ shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function);
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
+ "%s.yz", src0_param.reg_name);
+}
+
+/** Process the WINED3DSIO_TEXREG2RGB instruction in GLSL
+ * Sample texture at dst using the rgb (xyz) components of src as texture coordinates */
+static void shader_glsl_texreg2rgb(const struct wined3d_shader_instruction *ins)
+{
+ DWORD sampler_idx = ins->dst[0].reg.idx[0].offset;
+ struct glsl_sample_function sample_function;
+ struct glsl_src_param src0_param;
+
+ /* Dependent read, not valid with conditional NP2 */
+ shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function);
+ shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &src0_param);
+
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
+ "%s", src0_param.param_str);
+}
+
+/** Process the WINED3DSIO_TEXKILL instruction in GLSL.
+ * If any of the first 3 components are < 0, discard this pixel */
+static void shader_glsl_texkill(const struct wined3d_shader_instruction *ins)
+{
+ struct glsl_dst_param dst_param;
+
+ /* The argument is a destination parameter, and no writemasks are allowed */
+ shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param);
+ if (ins->ctx->reg_maps->shader_version.major >= 2)
+ {
+ /* 2.0 shaders compare all 4 components in texkill */
+ shader_addline(ins->ctx->buffer, "if (any(lessThan(%s.xyzw, vec4(0.0)))) discard;\n", dst_param.reg_name);
+ } else {
+ /* 1.X shaders only compare the first 3 components, probably due to the nature of the texkill
+ * instruction as a tex* instruction, and phase, which kills all a / w components. Even if all
+ * 4 components are defined, only the first 3 are used
+ */
+ shader_addline(ins->ctx->buffer, "if (any(lessThan(%s.xyz, vec3(0.0)))) discard;\n", dst_param.reg_name);
+ }
+}
+
+/** Process the WINED3DSIO_DP2ADD instruction in GLSL.
+ * dst = dot2(src0, src1) + src2 */
+static void shader_glsl_dp2add(const struct wined3d_shader_instruction *ins)
+{
+ struct glsl_src_param src0_param;
+ struct glsl_src_param src1_param;
+ struct glsl_src_param src2_param;
+ DWORD write_mask;
+ unsigned int mask_size;
+
+ write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
+ mask_size = shader_glsl_get_write_mask_size(write_mask);
+
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src0_param);
+ shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &src1_param);
+ shader_glsl_add_src_param(ins, &ins->src[2], WINED3DSP_WRITEMASK_0, &src2_param);
+
+ if (mask_size > 1) {
+ shader_addline(ins->ctx->buffer, "vec%d(dot(%s, %s) + %s));\n",
+ mask_size, src0_param.param_str, src1_param.param_str, src2_param.param_str);
+ } else {
+ shader_addline(ins->ctx->buffer, "dot(%s, %s) + %s);\n",
+ src0_param.param_str, src1_param.param_str, src2_param.param_str);
+ }
+}
+
+static void shader_glsl_input_pack(const struct wined3d_shader *shader, struct wined3d_shader_buffer *buffer,
+ const struct wined3d_shader_signature_element *input_signature,
+ const struct wined3d_shader_reg_maps *reg_maps,
+ enum vertexprocessing_mode vertexprocessing)
+{
+ WORD map = reg_maps->input_registers;
+ unsigned int i;
+
+ for (i = 0; map; map >>= 1, ++i)
+ {
+ const char *semantic_name;
+ UINT semantic_idx;
+ char reg_mask[6];
+
+ /* Unused */
+ if (!(map & 1)) continue;
+
+ semantic_name = input_signature[i].semantic_name;
+ semantic_idx = input_signature[i].semantic_idx;
+ shader_glsl_write_mask_to_str(input_signature[i].mask, reg_mask);
+
+ if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
+ {
+ if (semantic_idx < 8 && vertexprocessing == pretransformed)
+ shader_addline(buffer, "ps_in[%u]%s = gl_TexCoord[%u]%s;\n",
+ shader->u.ps.input_reg_map[i], reg_mask, semantic_idx, reg_mask);
+ else
+ shader_addline(buffer, "ps_in[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
+ shader->u.ps.input_reg_map[i], reg_mask, reg_mask);
+ }
+ else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR))
+ {
+ if (!semantic_idx)
+ shader_addline(buffer, "ps_in[%u]%s = vec4(gl_Color)%s;\n",
+ shader->u.ps.input_reg_map[i], reg_mask, reg_mask);
+ else if (semantic_idx == 1)
+ shader_addline(buffer, "ps_in[%u]%s = vec4(gl_SecondaryColor)%s;\n",
+ shader->u.ps.input_reg_map[i], reg_mask, reg_mask);
+ else
+ shader_addline(buffer, "ps_in[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
+ shader->u.ps.input_reg_map[i], reg_mask, reg_mask);
+ }
+ else
+ {
+ shader_addline(buffer, "ps_in[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
+ shader->u.ps.input_reg_map[i], reg_mask, reg_mask);
+ }
+ }
+}
+
+/*********************************************
+ * Vertex Shader Specific Code begins here
+ ********************************************/
+
+static void add_glsl_program_entry(struct shader_glsl_priv *priv, struct glsl_shader_prog_link *entry)
+{
+ struct glsl_program_key key;
+
+ key.vs_id = entry->vs.id;
+ key.gs_id = entry->gs.id;
+ key.ps_id = entry->ps.id;
+
+ if (wine_rb_put(&priv->program_lookup, &key, &entry->program_lookup_entry) == -1)
+ {
+ ERR("Failed to insert program entry.\n");
+ }
+}
+
+static struct glsl_shader_prog_link *get_glsl_program_entry(const struct shader_glsl_priv *priv,
+ GLhandleARB vs_id, GLhandleARB gs_id, GLhandleARB ps_id)
+{
+ struct wine_rb_entry *entry;
+ struct glsl_program_key key;
+
+ key.vs_id = vs_id;
+ key.gs_id = gs_id;
+ key.ps_id = ps_id;
+
+ entry = wine_rb_get(&priv->program_lookup, &key);
+ return entry ? WINE_RB_ENTRY_VALUE(entry, struct glsl_shader_prog_link, program_lookup_entry) : NULL;
+}
+
+#ifdef VBOX_WITH_WINE_FIX_SHADERCLEANUP
+static void shader_glsl_disable(void *shader_priv, const struct wined3d_context *context);
+#endif
+
+/* Context activation is done by the caller. */
+static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const struct wined3d_gl_info *gl_info,
+ struct glsl_shader_prog_link *entry
+#ifdef VBOX_WITH_WINE_FIX_SHADERCLEANUP
+ , struct wined3d_context *context
+#endif
+ )
+{
+ struct glsl_program_key key;
+
+ key.vs_id = entry->vs.id;
+ key.gs_id = entry->gs.id;
+ key.ps_id = entry->ps.id;
+ wine_rb_remove(&priv->program_lookup, &key);
+#ifdef VBOX_WITH_WINE_FIX_SHADERCLEANUP
+ if (priv->glsl_program == entry)
+ {
+ shader_glsl_disable(priv, context);
+ Assert(!priv->glsl_program);
+ }
+#endif
+
+ GL_EXTCALL(glDeleteObjectARB(entry->programId));
+ if (entry->vs.id)
+ list_remove(&entry->vs.shader_entry);
+ if (entry->gs.id)
+ list_remove(&entry->gs.shader_entry);
+ if (entry->ps.id)
+ list_remove(&entry->ps.shader_entry);
+ HeapFree(GetProcessHeap(), 0, entry->vs.uniform_f_locations);
+ HeapFree(GetProcessHeap(), 0, entry->ps.uniform_f_locations);
+ HeapFree(GetProcessHeap(), 0, entry);
+}
+
+static void handle_ps3_input(struct wined3d_shader_buffer *buffer,
+ const struct wined3d_gl_info *gl_info, const DWORD *map,
+ const struct wined3d_shader_signature_element *input_signature,
+ const struct wined3d_shader_reg_maps *reg_maps_in,
+ const struct wined3d_shader_signature_element *output_signature,
+ const struct wined3d_shader_reg_maps *reg_maps_out)
+{
+ unsigned int i, j;
+ const char *semantic_name_in;
+ UINT semantic_idx_in;
+ DWORD *set;
+ DWORD in_idx;
+ unsigned int in_count = vec4_varyings(3, gl_info);
+ char reg_mask[6];
+ char destination[50];
+ WORD input_map, output_map;
+
+ set = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*set) * (in_count + 2));
+
+ input_map = reg_maps_in->input_registers;
+ for (i = 0; input_map; input_map >>= 1, ++i)
+ {
+ if (!(input_map & 1)) continue;
+
+ in_idx = map[i];
+ /* Declared, but not read register */
+ if (in_idx == ~0U) continue;
+ if (in_idx >= (in_count + 2))
+ {
+ FIXME("More input varyings declared than supported, expect issues.\n");
+ continue;
+ }
+
+ if (in_idx == in_count)
+ sprintf(destination, "gl_FrontColor");
+ else if (in_idx == in_count + 1)
+ sprintf(destination, "gl_FrontSecondaryColor");
+ else
+ sprintf(destination, "ps_in[%u]", in_idx);
+
+ semantic_name_in = input_signature[i].semantic_name;
+ semantic_idx_in = input_signature[i].semantic_idx;
+ set[in_idx] = ~0U;
+
+ output_map = reg_maps_out->output_registers;
+ for (j = 0; output_map; output_map >>= 1, ++j)
+ {
+ DWORD mask;
+
+ if (!(output_map & 1)
+ || semantic_idx_in != output_signature[j].semantic_idx
+ || strcmp(semantic_name_in, output_signature[j].semantic_name)
+ || !(mask = input_signature[i].mask & output_signature[j].mask))
+ continue;
+
+ set[in_idx] = mask;
+ shader_glsl_write_mask_to_str(mask, reg_mask);
+
+ shader_addline(buffer, "%s%s = vs_out[%u]%s;\n",
+ destination, reg_mask, j, reg_mask);
+ }
+ }
+
+ for (i = 0; i < in_count + 2; ++i)
+ {
+ unsigned int size;
+
+ if (!set[i] || set[i] == WINED3DSP_WRITEMASK_ALL)
+ continue;
+
+ if (set[i] == ~0U) set[i] = 0;
+
+ size = 0;
+ if (!(set[i] & WINED3DSP_WRITEMASK_0)) reg_mask[size++] = 'x';
+ if (!(set[i] & WINED3DSP_WRITEMASK_1)) reg_mask[size++] = 'y';
+ if (!(set[i] & WINED3DSP_WRITEMASK_2)) reg_mask[size++] = 'z';
+ if (!(set[i] & WINED3DSP_WRITEMASK_3)) reg_mask[size++] = 'w';
+ reg_mask[size] = '\0';
+
+ if (i == in_count)
+ sprintf(destination, "gl_FrontColor");
+ else if (i == in_count + 1)
+ sprintf(destination, "gl_FrontSecondaryColor");
+ else
+ sprintf(destination, "ps_in[%u]", i);
+
+ if (size == 1) shader_addline(buffer, "%s.%s = 0.0;\n", destination, reg_mask);
+ else shader_addline(buffer, "%s.%s = vec%u(0.0);\n", destination, reg_mask, size);
+ }
+
+ HeapFree(GetProcessHeap(), 0, set);
+}
+
+/* Context activation is done by the caller. */
+static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer *buffer,
+ const struct wined3d_shader *vs, const struct wined3d_shader *ps,
+ const struct wined3d_gl_info *gl_info)
+{
+ GLhandleARB ret = 0;
+ DWORD ps_major = ps ? ps->reg_maps.shader_version.major : 0;
+ unsigned int i;
+ const char *semantic_name;
+ UINT semantic_idx;
+ char reg_mask[6];
+ const struct wined3d_shader_signature_element *output_signature = vs->output_signature;
+ WORD map = vs->reg_maps.output_registers;
+
+ shader_buffer_clear(buffer);
+
+ shader_addline(buffer, "#version 120\n");
+
+ if (ps_major < 3)
+ {
+ shader_addline(buffer, "void order_ps_input(in vec4 vs_out[%u])\n{\n", vs->limits.packed_output);
+
+ for (i = 0; map; map >>= 1, ++i)
+ {
+ DWORD write_mask;
+
+ if (!(map & 1)) continue;
+
+ semantic_name = output_signature[i].semantic_name;
+ semantic_idx = output_signature[i].semantic_idx;
+ write_mask = output_signature[i].mask;
+ shader_glsl_write_mask_to_str(write_mask, reg_mask);
+
+ if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_COLOR))
+ {
+ if (!semantic_idx)
+ shader_addline(buffer, "gl_FrontColor%s = vs_out[%u]%s;\n",
+ reg_mask, i, reg_mask);
+ else if (semantic_idx == 1)
+ shader_addline(buffer, "gl_FrontSecondaryColor%s = vs_out[%u]%s;\n",
+ reg_mask, i, reg_mask);
+ }
+ else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION))
+ {
+ shader_addline(buffer, "gl_Position%s = vs_out[%u]%s;\n",
+ reg_mask, i, reg_mask);
+ }
+ else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_TEXCOORD))
+ {
+ if (semantic_idx < 8)
+ {
+ if (!(gl_info->quirks & WINED3D_QUIRK_SET_TEXCOORD_W) || ps_major > 0)
+ write_mask |= WINED3DSP_WRITEMASK_3;
+
+ shader_addline(buffer, "gl_TexCoord[%u]%s = vs_out[%u]%s;\n",
+ semantic_idx, reg_mask, i, reg_mask);
+ if (!(write_mask & WINED3DSP_WRITEMASK_3))
+ shader_addline(buffer, "gl_TexCoord[%u].w = 1.0;\n", semantic_idx);
+ }
+ }
+ else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_PSIZE))
+ {
+ shader_addline(buffer, "gl_PointSize = vs_out[%u].%c;\n", i, reg_mask[1]);
+ }
+ else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG))
+ {
+ shader_addline(buffer, "gl_FogFragCoord = clamp(vs_out[%u].%c, 0.0, 1.0);\n", i, reg_mask[1]);
+ }
+ }
+ shader_addline(buffer, "}\n");
+ }
+ else
+ {
+ UINT in_count = min(vec4_varyings(ps_major, gl_info), ps->limits.packed_input);
+ /* This one is tricky: a 3.0 pixel shader reads from a 3.0 vertex shader */
+ shader_addline(buffer, "varying vec4 ps_in[%u];\n", in_count);
+ shader_addline(buffer, "void order_ps_input(in vec4 vs_out[%u])\n{\n", vs->limits.packed_output);
+
+ /* First, sort out position and point size. Those are not passed to the pixel shader */
+ for (i = 0; map; map >>= 1, ++i)
+ {
+ if (!(map & 1)) continue;
+
+ semantic_name = output_signature[i].semantic_name;
+ shader_glsl_write_mask_to_str(output_signature[i].mask, reg_mask);
+
+ if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_POSITION))
+ {
+ shader_addline(buffer, "gl_Position%s = vs_out[%u]%s;\n",
+ reg_mask, i, reg_mask);
+ }
+ else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_PSIZE))
+ {
+ shader_addline(buffer, "gl_PointSize = vs_out[%u].%c;\n", i, reg_mask[1]);
+ }
+ }
+
+ /* Then, fix the pixel shader input */
+ handle_ps3_input(buffer, gl_info, ps->u.ps.input_reg_map, ps->input_signature,
+ &ps->reg_maps, output_signature, &vs->reg_maps);
+
+ shader_addline(buffer, "}\n");
+ }
+
+ ret = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
+ checkGLcall("glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)");
+ shader_glsl_compile(gl_info, ret, buffer->buffer);
+
+ return ret;
+}
+
+static void shader_glsl_generate_srgb_write_correction(struct wined3d_shader_buffer *buffer)
+{
+ shader_addline(buffer, "tmp0.xyz = pow(gl_FragData[0].xyz, vec3(srgb_const0.x));\n");
+ shader_addline(buffer, "tmp0.xyz = tmp0.xyz * vec3(srgb_const0.y) - vec3(srgb_const0.z);\n");
+ shader_addline(buffer, "tmp1.xyz = gl_FragData[0].xyz * vec3(srgb_const0.w);\n");
+ shader_addline(buffer, "bvec3 srgb_compare = lessThan(gl_FragData[0].xyz, vec3(srgb_const1.x));\n");
+ shader_addline(buffer, "gl_FragData[0].xyz = mix(tmp0.xyz, tmp1.xyz, vec3(srgb_compare));\n");
+ shader_addline(buffer, "gl_FragData[0] = clamp(gl_FragData[0], 0.0, 1.0);\n");
+}
+
+static void shader_glsl_generate_fog_code(struct wined3d_shader_buffer *buffer, enum wined3d_ffp_ps_fog_mode mode)
+{
+ switch (mode)
+ {
+ case WINED3D_FFP_PS_FOG_OFF:
+ return;
+
+ case WINED3D_FFP_PS_FOG_LINEAR:
+ /* Fog = (gl_Fog.end - gl_FogFragCoord) / (gl_Fog.end - gl_Fog.start) */
+ shader_addline(buffer, "float Fog = (gl_Fog.end - gl_FogFragCoord) / (gl_Fog.end - gl_Fog.start);\n");
+ break;
+
+ case WINED3D_FFP_PS_FOG_EXP:
+ /* Fog = e^-(gl_Fog.density * gl_FogFragCoord) */
+ shader_addline(buffer, "float Fog = exp(-gl_Fog.density * gl_FogFragCoord);\n");
+ break;
+
+ case WINED3D_FFP_PS_FOG_EXP2:
+ /* Fog = e^-((gl_Fog.density * gl_FogFragCoord)^2) */
+ shader_addline(buffer, "float Fog = exp(-gl_Fog.density * gl_Fog.density * gl_FogFragCoord * gl_FogFragCoord);\n");
+ break;
+
+ default:
+ ERR("Invalid fog mode %#x.\n", mode);
+ return;
+ }
+
+ shader_addline(buffer, "gl_FragData[0].xyz = mix(gl_Fog.color.xyz, gl_FragData[0].xyz, clamp(Fog, 0.0, 1.0));\n");
+}
+
+/* Context activation is done by the caller. */
+static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context,
+ struct wined3d_shader_buffer *buffer, const struct wined3d_shader *shader,
+ const struct ps_compile_args *args, struct ps_np2fixup_info *np2fixup_info)
+{
+ const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const DWORD *function = shader->function;
+ struct shader_glsl_ctx_priv priv_ctx;
+
+ /* Create the hw GLSL shader object and assign it as the shader->prgId */
+ GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
+
+ memset(&priv_ctx, 0, sizeof(priv_ctx));
+ priv_ctx.cur_ps_args = args;
+ priv_ctx.cur_np2fixup_info = np2fixup_info;
+
+ shader_addline(buffer, "#version 120\n");
+
+ if (gl_info->supported[ARB_SHADER_BIT_ENCODING])
+ shader_addline(buffer, "#extension GL_ARB_shader_bit_encoding : enable\n");
+ if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+ shader_addline(buffer, "#extension GL_ARB_shader_texture_lod : enable\n");
+ /* The spec says that it doesn't have to be explicitly enabled, but the
+ * nvidia drivers write a warning if we don't do so. */
+ if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ shader_addline(buffer, "#extension GL_ARB_texture_rectangle : enable\n");
+ if (gl_info->supported[EXT_GPU_SHADER4])
+ shader_addline(buffer, "#extension GL_EXT_gpu_shader4 : enable\n");
+
+ /* Base Declarations */
+ shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx);
+
+ /* Pack 3.0 inputs */
+ if (reg_maps->shader_version.major >= 3 && args->vp_mode != vertexshader)
+ shader_glsl_input_pack(shader, buffer, shader->input_signature, reg_maps, args->vp_mode);
+
+ /* Base Shader Body */
+ shader_generate_main(shader, buffer, reg_maps, function, &priv_ctx);
+
+ /* Pixel shaders < 2.0 place the resulting color in R0 implicitly */
+ if (reg_maps->shader_version.major < 2)
+ {
+ /* Some older cards like GeforceFX ones don't support multiple buffers, so also not gl_FragData */
+ shader_addline(buffer, "gl_FragData[0] = R0;\n");
+ }
+
+ if (args->srgb_correction)
+ shader_glsl_generate_srgb_write_correction(buffer);
+
+ /* SM < 3 does not replace the fog stage. */
+ if (reg_maps->shader_version.major < 3)
+ shader_glsl_generate_fog_code(buffer, args->fog);
+
+ shader_addline(buffer, "}\n");
+
+ TRACE("Compiling shader object %u\n", shader_obj);
+ shader_glsl_compile(gl_info, shader_obj, buffer->buffer);
+
+ /* Store the shader object */
+ return shader_obj;
+}
+
+/* Context activation is done by the caller. */
+static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context,
+ struct wined3d_shader_buffer *buffer, const struct wined3d_shader *shader,
+ const struct vs_compile_args *args)
+{
+ const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const DWORD *function = shader->function;
+ struct shader_glsl_ctx_priv priv_ctx;
+
+ /* Create the hw GLSL shader program and assign it as the shader->prgId */
+ GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
+
+ shader_addline(buffer, "#version 120\n");
+
+ if (gl_info->supported[ARB_SHADER_BIT_ENCODING])
+ shader_addline(buffer, "#extension GL_ARB_shader_bit_encoding : enable\n");
+ if (gl_info->supported[EXT_GPU_SHADER4])
+ shader_addline(buffer, "#extension GL_EXT_gpu_shader4 : enable\n");
+
+ memset(&priv_ctx, 0, sizeof(priv_ctx));
+ priv_ctx.cur_vs_args = args;
+
+ /* Base Declarations */
+ shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx);
+
+ /* Base Shader Body */
+ shader_generate_main(shader, buffer, reg_maps, function, &priv_ctx);
+
+ /* Unpack outputs */
+ shader_addline(buffer, "order_ps_input(vs_out);\n");
+
+ /* The D3DRS_FOGTABLEMODE render state defines if the shader-generated fog coord is used
+ * or if the fragment depth is used. If the fragment depth is used(FOGTABLEMODE != NONE),
+ * the fog frag coord is thrown away. If the fog frag coord is used, but not written by
+ * the shader, it is set to 0.0(fully fogged, since start = 1.0, end = 0.0)
+ */
+ if (args->fog_src == VS_FOG_Z)
+ shader_addline(buffer, "gl_FogFragCoord = gl_Position.z;\n");
+ else if (!reg_maps->fog)
+ shader_addline(buffer, "gl_FogFragCoord = 0.0;\n");
+
+ /* We always store the clipplanes without y inversion */
+ if (args->clip_enabled)
+ shader_addline(buffer, "gl_ClipVertex = gl_Position;\n");
+
+ /* Write the final position.
+ *
+ * OpenGL coordinates specify the center of the pixel while d3d coords specify
+ * the corner. The offsets are stored in z and w in posFixup. posFixup.y contains
+ * 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x
+ * contains 1.0 to allow a mad.
+ */
+ shader_addline(buffer, "gl_Position.y = gl_Position.y * posFixup.y;\n");
+ shader_addline(buffer, "gl_Position.xy += posFixup.zw * gl_Position.ww;\n");
+
+ /* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c
+ *
+ * Basically we want (in homogeneous coordinates) z = z * 2 - 1. However, shaders are run
+ * before the homogeneous divide, so we have to take the w into account: z = ((z / w) * 2 - 1) * w,
+ * which is the same as z = z * 2 - w.
+ */
+ shader_addline(buffer, "gl_Position.z = gl_Position.z * 2.0 - gl_Position.w;\n");
+
+ shader_addline(buffer, "}\n");
+
+ TRACE("Compiling shader object %u\n", shader_obj);
+ shader_glsl_compile(gl_info, shader_obj, buffer->buffer);
+
+ return shader_obj;
+}
+
+/* Context activation is done by the caller. */
+static GLhandleARB shader_glsl_generate_geometry_shader(const struct wined3d_context *context,
+ struct wined3d_shader_buffer *buffer, const struct wined3d_shader *shader)
+{
+ const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const DWORD *function = shader->function;
+ struct shader_glsl_ctx_priv priv_ctx;
+ GLhandleARB shader_id;
+
+ shader_id = GL_EXTCALL(glCreateShaderObjectARB(GL_GEOMETRY_SHADER_ARB));
+
+ shader_addline(buffer, "#version 120\n");
+
+ if (gl_info->supported[ARB_GEOMETRY_SHADER4])
+ shader_addline(buffer, "#extension GL_ARB_geometry_shader4 : enable\n");
+ if (gl_info->supported[ARB_SHADER_BIT_ENCODING])
+ shader_addline(buffer, "#extension GL_ARB_shader_bit_encoding : enable\n");
+ if (gl_info->supported[EXT_GPU_SHADER4])
+ shader_addline(buffer, "#extension GL_EXT_gpu_shader4 : enable\n");
+
+ memset(&priv_ctx, 0, sizeof(priv_ctx));
+ shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx);
+ shader_generate_main(shader, buffer, reg_maps, function, &priv_ctx);
+ shader_addline(buffer, "}\n");
+
+ TRACE("Compiling shader object %u.\n", shader_id);
+ shader_glsl_compile(gl_info, shader_id, buffer->buffer);
+
+ return shader_id;
+}
+
+static GLhandleARB find_glsl_pshader(const struct wined3d_context *context,
+ struct wined3d_shader_buffer *buffer, struct wined3d_shader *shader,
+ const struct ps_compile_args *args, const struct ps_np2fixup_info **np2fixup_info)
+{
+ struct glsl_ps_compiled_shader *gl_shaders, *new_array;
+ struct glsl_shader_private *shader_data;
+ struct ps_np2fixup_info *np2fixup;
+ UINT i;
+ DWORD new_size;
+ GLhandleARB ret;
+
+ if (!shader->backend_data)
+ {
+ shader->backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
+ if (!shader->backend_data)
+ {
+ ERR("Failed to allocate backend data.\n");
+ return 0;
+ }
+ }
+ shader_data = shader->backend_data;
+ gl_shaders = shader_data->gl_shaders.ps;
+
+ /* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2),
+ * so a linear search is more performant than a hashmap or a binary search
+ * (cache coherency etc)
+ */
+ for (i = 0; i < shader_data->num_gl_shaders; ++i)
+ {
+ if (!memcmp(&gl_shaders[i].args, args, sizeof(*args)))
+ {
+ if (args->np2_fixup)
+ *np2fixup_info = &gl_shaders[i].np2fixup;
+ return gl_shaders[i].prgId;
+ }
+ }
+
+ TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader);
+ if(shader_data->shader_array_size == shader_data->num_gl_shaders) {
+ if (shader_data->num_gl_shaders)
+ {
+ new_size = shader_data->shader_array_size + max(1, shader_data->shader_array_size / 2);
+ new_array = HeapReAlloc(GetProcessHeap(), 0, shader_data->gl_shaders.ps,
+ new_size * sizeof(*gl_shaders));
+ }
+ else
+ {
+ new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*gl_shaders));
+ new_size = 1;
+ }
+
+ if(!new_array) {
+ ERR("Out of memory\n");
+ return 0;
+ }
+ shader_data->gl_shaders.ps = new_array;
+ shader_data->shader_array_size = new_size;
+ gl_shaders = new_array;
+ }
+
+ gl_shaders[shader_data->num_gl_shaders].args = *args;
+
+ np2fixup = &gl_shaders[shader_data->num_gl_shaders].np2fixup;
+ memset(np2fixup, 0, sizeof(*np2fixup));
+ *np2fixup_info = args->np2_fixup ? np2fixup : NULL;
+
+ pixelshader_update_samplers(shader, args->tex_types);
+
+ shader_buffer_clear(buffer);
+ ret = shader_glsl_generate_pshader(context, buffer, shader, args, np2fixup);
+ gl_shaders[shader_data->num_gl_shaders++].prgId = ret;
+
+ return ret;
+}
+
+static inline BOOL vs_args_equal(const struct vs_compile_args *stored, const struct vs_compile_args *new,
+ const DWORD use_map) {
+ if((stored->swizzle_map & use_map) != new->swizzle_map) return FALSE;
+ if((stored->clip_enabled) != new->clip_enabled) return FALSE;
+ return stored->fog_src == new->fog_src;
+}
+
+static GLhandleARB find_glsl_vshader(const struct wined3d_context *context,
+ struct wined3d_shader_buffer *buffer, struct wined3d_shader *shader,
+ const struct vs_compile_args *args)
+{
+ UINT i;
+ DWORD new_size;
+ DWORD use_map = shader->device->stream_info.use_map;
+ struct glsl_vs_compiled_shader *gl_shaders, *new_array;
+ struct glsl_shader_private *shader_data;
+ GLhandleARB ret;
+
+ if (!shader->backend_data)
+ {
+ shader->backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
+ if (!shader->backend_data)
+ {
+ ERR("Failed to allocate backend data.\n");
+ return 0;
+ }
+ }
+ shader_data = shader->backend_data;
+ gl_shaders = shader_data->gl_shaders.vs;
+
+ /* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2),
+ * so a linear search is more performant than a hashmap or a binary search
+ * (cache coherency etc)
+ */
+ for (i = 0; i < shader_data->num_gl_shaders; ++i)
+ {
+ if (vs_args_equal(&gl_shaders[i].args, args, use_map))
+ return gl_shaders[i].prgId;
+ }
+
+ TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader);
+
+ if(shader_data->shader_array_size == shader_data->num_gl_shaders) {
+ if (shader_data->num_gl_shaders)
+ {
+ new_size = shader_data->shader_array_size + max(1, shader_data->shader_array_size / 2);
+ new_array = HeapReAlloc(GetProcessHeap(), 0, shader_data->gl_shaders.vs,
+ new_size * sizeof(*gl_shaders));
+ }
+ else
+ {
+ new_array = HeapAlloc(GetProcessHeap(), 0, sizeof(*gl_shaders));
+ new_size = 1;
+ }
+
+ if(!new_array) {
+ ERR("Out of memory\n");
+ return 0;
+ }
+ shader_data->gl_shaders.vs = new_array;
+ shader_data->shader_array_size = new_size;
+ gl_shaders = new_array;
+ }
+
+ gl_shaders[shader_data->num_gl_shaders].args = *args;
+
+ shader_buffer_clear(buffer);
+ ret = shader_glsl_generate_vshader(context, buffer, shader, args);
+ gl_shaders[shader_data->num_gl_shaders++].prgId = ret;
+
+ return ret;
+}
+
+static GLhandleARB find_glsl_geometry_shader(const struct wined3d_context *context,
+ struct wined3d_shader_buffer *buffer, struct wined3d_shader *shader)
+{
+ struct glsl_gs_compiled_shader *gl_shaders;
+ struct glsl_shader_private *shader_data;
+ GLhandleARB ret;
+
+ if (!shader->backend_data)
+ {
+ if (!(shader->backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data))))
+ {
+ ERR("Failed to allocate backend data.\n");
+ return 0;
+ }
+ }
+ shader_data = shader->backend_data;
+ gl_shaders = shader_data->gl_shaders.gs;
+
+ if (shader_data->num_gl_shaders)
+ return gl_shaders[0].id;
+
+ TRACE("No matching GL shader found for shader %p, compiling a new shader.\n", shader);
+
+ if (!(shader_data->gl_shaders.gs = HeapAlloc(GetProcessHeap(), 0, sizeof(*gl_shaders))))
+ {
+ ERR("Failed to allocate GL shader array.\n");
+ return 0;
+ }
+ shader_data->shader_array_size = 1;
+ gl_shaders = shader_data->gl_shaders.gs;
+
+ shader_buffer_clear(buffer);
+ ret = shader_glsl_generate_geometry_shader(context, buffer, shader);
+ gl_shaders[shader_data->num_gl_shaders++].id = ret;
+
+ return ret;
+}
+
+static const char *shader_glsl_ffp_mcs(enum wined3d_material_color_source mcs, const char *material)
+{
+ switch (mcs)
+ {
+ case WINED3D_MCS_MATERIAL:
+ return material;
+ case WINED3D_MCS_COLOR1:
+ return "gl_Color";
+ case WINED3D_MCS_COLOR2:
+ return "gl_SecondaryColor";
+ default:
+ ERR("Invalid material color source %#x.\n", mcs);
+ return "<invalid>";
+ }
+}
+
+static void shader_glsl_ffp_vertex_lighting(struct wined3d_shader_buffer *buffer,
+ const struct wined3d_ffp_vs_settings *settings, const struct wined3d_gl_info *gl_info)
+{
+ const char *diffuse, *specular, *emission, *ambient;
+ enum wined3d_light_type light_type;
+ unsigned int i;
+
+ if (!settings->lighting)
+ {
+ shader_addline(buffer, "gl_FrontColor = gl_Color;\n");
+ shader_addline(buffer, "gl_FrontSecondaryColor = gl_SecondaryColor;\n");
+ return;
+ }
+
+ shader_addline(buffer, "vec3 ambient = gl_LightModel.ambient.xyz;\n");
+ shader_addline(buffer, "vec3 diffuse = vec3(0.0);\n");
+ shader_addline(buffer, "vec4 specular = vec4(0.0);\n");
+ shader_addline(buffer, "vec3 dir, dst;\n");
+ shader_addline(buffer, "float att, t;\n");
+
+ ambient = shader_glsl_ffp_mcs(settings->ambient_source, "gl_FrontMaterial.ambient");
+ diffuse = shader_glsl_ffp_mcs(settings->diffuse_source, "gl_FrontMaterial.diffuse");
+ specular = shader_glsl_ffp_mcs(settings->specular_source, "gl_FrontMaterial.specular");
+ emission = shader_glsl_ffp_mcs(settings->emission_source, "gl_FrontMaterial.emission");
+
+ for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i)
+ {
+ light_type = (settings->light_type >> WINED3D_FFP_LIGHT_TYPE_SHIFT(i)) & WINED3D_FFP_LIGHT_TYPE_MASK;
+ switch (light_type)
+ {
+ case WINED3D_LIGHT_POINT:
+ shader_addline(buffer, "dir = gl_LightSource[%u].position.xyz - ec_pos.xyz;\n", i);
+ shader_addline(buffer, "dst.z = dot(dir, dir);\n");
+ shader_addline(buffer, "dst.y = sqrt(dst.z);\n");
+ shader_addline(buffer, "dst.x = 1.0;\n");
+ shader_addline(buffer, "att = dot(dst.xyz, vec3(gl_LightSource[%u].constantAttenuation,"
+ " gl_LightSource[%u].linearAttenuation, gl_LightSource[%u].quadraticAttenuation));\n", i, i, i);
+ shader_addline(buffer, "ambient += gl_LightSource[%u].ambient.xyz / att;\n", i);
+ if (!settings->normal)
+ break;
+ shader_addline(buffer, "dir = normalize(dir);\n");
+ shader_addline(buffer, "diffuse += (max(0.0, dot(dir, normal))"
+ " * gl_LightSource[%u].diffuse.xyz) / att;\n", i);
+ if (settings->localviewer)
+ shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n");
+ else
+ shader_addline(buffer, "t = dot(normal, normalize(dir + vec3(0.0, 0.0, 1.0)));\n");
+ shader_addline(buffer, "if (t > 0.0) specular += (pow(t, gl_FrontMaterial.shininess)"
+ " * gl_LightSource[%u].specular) / att;\n", i);
+ break;
+
+ case WINED3D_LIGHT_SPOT:
+ shader_addline(buffer, "dir = gl_LightSource[%u].position.xyz - ec_pos.xyz;\n", i);
+ shader_addline(buffer, "dst.z = dot(dir, dir);\n");
+ shader_addline(buffer, "dst.y = sqrt(dst.z);\n");
+ shader_addline(buffer, "dst.x = 1.0;\n");
+ shader_addline(buffer, "dir = normalize(dir);\n");
+ shader_addline(buffer, "t = dot(-dir, normalize(gl_LightSource[%u].spotDirection));\n", i);
+ shader_addline(buffer, "if (t < gl_LightSource[%u].spotCosCutoff) att = 0.0;\n", i);
+ shader_addline(buffer, "else att = pow(t, gl_LightSource[%u].spotExponent)"
+ " / dot(dst.xyz, vec3(gl_LightSource[%u].constantAttenuation,"
+ " gl_LightSource[%u].linearAttenuation, gl_LightSource[%u].quadraticAttenuation));\n",
+ i, i, i, i);
+ shader_addline(buffer, "ambient += gl_LightSource[%u].ambient.xyz * att;\n", i);
+ if (!settings->normal)
+ break;
+ shader_addline(buffer, "diffuse += (max(0.0, dot(dir, normal))"
+ " * gl_LightSource[%u].diffuse.xyz) * att;\n", i);
+ if (settings->localviewer)
+ shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n");
+ else
+ shader_addline(buffer, "t = dot(normal, normalize(dir + vec3(0.0, 0.0, 1.0)));\n");
+ shader_addline(buffer, "if (t > 0.0) specular += (pow(t, gl_FrontMaterial.shininess)"
+ " * gl_LightSource[%u].specular) * att;\n", i);
+ break;
+
+ case WINED3D_LIGHT_DIRECTIONAL:
+ shader_addline(buffer, "ambient += gl_LightSource[%u].ambient.xyz;\n", i);
+ if (!settings->normal)
+ break;
+ shader_addline(buffer, "dir = normalize(gl_LightSource[%u].position.xyz);\n", i);
+ shader_addline(buffer, "diffuse += max(0.0, dot(dir, normal)) * gl_LightSource[%u].diffuse.xyz;\n", i);
+ shader_addline(buffer, "t = dot(normal, gl_LightSource[%u].halfVector.xyz);\n", i);
+ shader_addline(buffer, "if (t > 0.0) specular += pow(t, gl_FrontMaterial.shininess)"
+ " * gl_LightSource[%u].specular;\n", i);
+ break;
+
+ default:
+ if (light_type)
+ FIXME("Unhandled light type %#x.\n", light_type);
+ continue;
+ }
+ }
+
+ shader_addline(buffer, "gl_FrontColor.xyz = %s.xyz * ambient + %s.xyz * diffuse + %s.xyz;\n",
+ ambient, diffuse, emission);
+ shader_addline(buffer, "gl_FrontColor.w = %s.w;\n", diffuse);
+ shader_addline(buffer, "gl_FrontSecondaryColor = %s * specular;\n", specular);
+}
+
+/* Context activation is done by the caller. */
+static GLhandleARB shader_glsl_generate_ffp_vertex_shader(struct wined3d_shader_buffer *buffer,
+ const struct wined3d_ffp_vs_settings *settings, const struct wined3d_gl_info *gl_info)
+{
+ GLhandleARB shader_obj;
+ unsigned int i;
+
+ shader_buffer_clear(buffer);
+
+ shader_addline(buffer, "#version 120\n");
+ shader_addline(buffer, "\n");
+ shader_addline(buffer, "void main()\n{\n");
+ shader_addline(buffer, "float m;\n");
+ shader_addline(buffer, "vec3 r;\n");
+
+ if (settings->transformed)
+ {
+ shader_addline(buffer, "vec4 ec_pos = vec4(gl_Vertex.xyz, 1.0);\n");
+ shader_addline(buffer, "gl_Position = gl_ProjectionMatrix * ec_pos;\n");
+ shader_addline(buffer, "if (gl_Vertex.w != 0.0) gl_Position /= gl_Vertex.w;\n");
+ }
+ else
+ {
+ shader_addline(buffer, "vec4 ec_pos = gl_ModelViewMatrix * gl_Vertex;\n");
+ shader_addline(buffer, "gl_Position = gl_ProjectionMatrix * ec_pos;\n");
+ if (settings->clipping)
+ shader_addline(buffer, "gl_ClipVertex = ec_pos;\n");
+ shader_addline(buffer, "ec_pos /= ec_pos.w;\n");
+ }
+
+ if (!settings->normal)
+ shader_addline(buffer, "vec3 normal = vec3(0.0);\n");
+ else if (settings->normalize)
+ shader_addline(buffer, "vec3 normal = normalize(gl_NormalMatrix * gl_Normal);\n");
+ else
+ shader_addline(buffer, "vec3 normal = gl_NormalMatrix * gl_Normal;\n");
+
+ shader_glsl_ffp_vertex_lighting(buffer, settings, gl_info);
+
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ switch (settings->texgen[i] << WINED3D_FFP_TCI_SHIFT)
+ {
+ case WINED3DTSS_TCI_PASSTHRU:
+ if (settings->texcoords & (1 << i))
+ shader_addline(buffer, "gl_TexCoord[%u] = gl_TextureMatrix[%u] * gl_MultiTexCoord%d;\n",
+ i, i, i);
+ break;
+
+ case WINED3DTSS_TCI_CAMERASPACENORMAL:
+ shader_addline(buffer, "gl_TexCoord[%u] = gl_TextureMatrix[%u] * vec4(normal, 1.0);\n", i, i);
+ break;
+
+ case WINED3DTSS_TCI_CAMERASPACEPOSITION:
+ shader_addline(buffer, "gl_TexCoord[%u] = gl_TextureMatrix[%u] * ec_pos;\n", i, i);
+ break;
+
+ case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
+ shader_addline(buffer, "gl_TexCoord[%u] = gl_TextureMatrix[%u]"
+ " * vec4(reflect(normalize(ec_pos.xyz), normal), 1.0);\n", i, i);
+ break;
+
+ case WINED3DTSS_TCI_SPHEREMAP:
+ shader_addline(buffer, "r = reflect(normalize(ec_pos.xyz), normal);\n");
+ shader_addline(buffer, "m = 2.0 * length(vec3(r.x, r.y, r.z + 1.0));\n");
+ shader_addline(buffer, "gl_TexCoord[%u] = gl_TextureMatrix[%u]"
+ " * vec4(r.x / m + 0.5, r.y / m + 0.5, 0.0, 1.0);\n", i, i);
+ break;
+
+ default:
+ ERR("Unhandled texgen %#x.\n", settings->texgen[i]);
+ break;
+ }
+ }
+
+ switch (settings->fog_mode)
+ {
+ case WINED3D_FFP_VS_FOG_OFF:
+ break;
+
+ case WINED3D_FFP_VS_FOG_FOGCOORD:
+ shader_addline(buffer, "gl_FogFragCoord = gl_SecondaryColor.w * 255.0;\n");
+ break;
+
+ case WINED3D_FFP_VS_FOG_RANGE:
+ shader_addline(buffer, "gl_FogFragCoord = length(ec_pos.xyz);\n");
+ break;
+
+ case WINED3D_FFP_VS_FOG_DEPTH:
+ shader_addline(buffer, "gl_FogFragCoord = ec_pos.z;\n");
+ break;
+
+ default:
+ ERR("Unhandled fog mode %#x.\n", settings->fog_mode);
+ break;
+ }
+
+ if (settings->point_size)
+ {
+ shader_addline(buffer, "gl_PointSize = gl_Point.size / sqrt(gl_Point.distanceConstantAttenuation"
+ " + gl_Point.distanceLinearAttenuation * length(ec_pos.xyz)"
+ " + gl_Point.distanceQuadraticAttenuation * dot(ec_pos.xyz, ec_pos.xyz));\n");
+ shader_addline(buffer, "gl_PointSize = clamp(gl_PointSize, gl_Point.sizeMin, gl_Point.sizeMax);\n");
+ }
+
+ shader_addline(buffer, "}\n");
+
+ shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
+ shader_glsl_compile(gl_info, shader_obj, buffer->buffer);
+
+ return shader_obj;
+}
+
+static const char *shader_glsl_get_ffp_fragment_op_arg(struct wined3d_shader_buffer *buffer,
+ DWORD argnum, unsigned int stage, DWORD arg)
+{
+ const char *ret;
+
+ if (arg == ARG_UNUSED)
+ return "<unused arg>";
+
+ switch (arg & WINED3DTA_SELECTMASK)
+ {
+ case WINED3DTA_DIFFUSE:
+ ret = "gl_Color";
+ break;
+
+ case WINED3DTA_CURRENT:
+ if (!stage)
+ ret = "gl_Color";
+ else
+ ret = "ret";
+ break;
+
+ case WINED3DTA_TEXTURE:
+ switch (stage)
+ {
+ case 0: ret = "tex0"; break;
+ case 1: ret = "tex1"; break;
+ case 2: ret = "tex2"; break;
+ case 3: ret = "tex3"; break;
+ case 4: ret = "tex4"; break;
+ case 5: ret = "tex5"; break;
+ case 6: ret = "tex6"; break;
+ case 7: ret = "tex7"; break;
+ default:
+ ret = "<invalid texture>";
+ break;
+ }
+ break;
+
+ case WINED3DTA_TFACTOR:
+ ret = "tex_factor";
+ break;
+
+ case WINED3DTA_SPECULAR:
+ ret = "gl_SecondaryColor";
+ break;
+
+ case WINED3DTA_TEMP:
+ ret = "temp_reg";
+ break;
+
+ case WINED3DTA_CONSTANT:
+ FIXME("Per-stage constants not implemented.\n");
+ switch (stage)
+ {
+ case 0: ret = "const0"; break;
+ case 1: ret = "const1"; break;
+ case 2: ret = "const2"; break;
+ case 3: ret = "const3"; break;
+ case 4: ret = "const4"; break;
+ case 5: ret = "const5"; break;
+ case 6: ret = "const6"; break;
+ case 7: ret = "const7"; break;
+ default:
+ ret = "<invalid constant>";
+ break;
+ }
+ break;
+
+ default:
+ return "<unhandled arg>";
+ }
+
+ if (arg & WINED3DTA_COMPLEMENT)
+ {
+ shader_addline(buffer, "arg%u = vec4(1.0) - %s;\n", argnum, ret);
+ if (argnum == 0)
+ ret = "arg0";
+ else if (argnum == 1)
+ ret = "arg1";
+ else if (argnum == 2)
+ ret = "arg2";
+ }
+
+ if (arg & WINED3DTA_ALPHAREPLICATE)
+ {
+ shader_addline(buffer, "arg%u = vec4(%s.w);\n", argnum, ret);
+ if (argnum == 0)
+ ret = "arg0";
+ else if (argnum == 1)
+ ret = "arg1";
+ else if (argnum == 2)
+ ret = "arg2";
+ }
+
+ return ret;
+}
+
+static void shader_glsl_ffp_fragment_op(struct wined3d_shader_buffer *buffer, unsigned int stage, BOOL color,
+ BOOL alpha, DWORD dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2)
+{
+ const char *dstmask, *dstreg, *arg0, *arg1, *arg2;
+
+ if (color && alpha)
+ dstmask = "";
+ else if (color)
+ dstmask = ".xyz";
+ else
+ dstmask = ".w";
+
+ if (dst == tempreg)
+ dstreg = "temp_reg";
+ else
+ dstreg = "ret";
+
+ arg0 = shader_glsl_get_ffp_fragment_op_arg(buffer, 0, stage, dw_arg0);
+ arg1 = shader_glsl_get_ffp_fragment_op_arg(buffer, 1, stage, dw_arg1);
+ arg2 = shader_glsl_get_ffp_fragment_op_arg(buffer, 2, stage, dw_arg2);
+
+ switch (op)
+ {
+ case WINED3D_TOP_DISABLE:
+ if (!stage)
+ shader_addline(buffer, "%s%s = gl_Color%s;\n", dstreg, dstmask, dstmask);
+ break;
+
+ case WINED3D_TOP_SELECT_ARG1:
+ shader_addline(buffer, "%s%s = %s%s;\n", dstreg, dstmask, arg1, dstmask);
+ break;
+
+ case WINED3D_TOP_SELECT_ARG2:
+ shader_addline(buffer, "%s%s = %s%s;\n", dstreg, dstmask, arg2, dstmask);
+ break;
+
+ case WINED3D_TOP_MODULATE:
+ shader_addline(buffer, "%s%s = %s%s * %s%s;\n", dstreg, dstmask, arg1, dstmask, arg2, dstmask);
+ break;
+
+ case WINED3D_TOP_MODULATE_4X:
+ shader_addline(buffer, "%s%s = clamp(%s%s * %s%s * 4.0, 0.0, 1.0);\n",
+ dstreg, dstmask, arg1, dstmask, arg2, dstmask);
+ break;
+
+ case WINED3D_TOP_MODULATE_2X:
+ shader_addline(buffer, "%s%s = clamp(%s%s * %s%s * 2.0, 0.0, 1.0);\n",
+ dstreg, dstmask, arg1, dstmask, arg2, dstmask);
+ break;
+
+ case WINED3D_TOP_ADD:
+ shader_addline(buffer, "%s%s = clamp(%s%s + %s%s, 0.0, 1.0);\n",
+ dstreg, dstmask, arg1, dstmask, arg2, dstmask);
+ break;
+
+ case WINED3D_TOP_ADD_SIGNED:
+ shader_addline(buffer, "%s%s = clamp(%s%s + (%s - vec4(0.5))%s, 0.0, 1.0);\n",
+ dstreg, dstmask, arg1, dstmask, arg2, dstmask);
+ break;
+
+ case WINED3D_TOP_ADD_SIGNED_2X:
+ shader_addline(buffer, "%s%s = clamp((%s%s + (%s - vec4(0.5))%s) * 2.0, 0.0, 1.0);\n",
+ dstreg, dstmask, arg1, dstmask, arg2, dstmask);
+ break;
+
+ case WINED3D_TOP_SUBTRACT:
+ shader_addline(buffer, "%s%s = clamp(%s%s - %s%s, 0.0, 1.0);\n",
+ dstreg, dstmask, arg1, dstmask, arg2, dstmask);
+ break;
+
+ case WINED3D_TOP_ADD_SMOOTH:
+ shader_addline(buffer, "%s%s = clamp((vec4(1.0) - %s)%s * %s%s + %s%s, 0.0, 1.0);\n",
+ dstreg, dstmask, arg1, dstmask, arg2, dstmask, arg1, dstmask);
+ break;
+
+ case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
+ arg0 = shader_glsl_get_ffp_fragment_op_arg(buffer, 0, stage, WINED3DTA_DIFFUSE);
+ shader_addline(buffer, "%s%s = mix(%s%s, %s%s, %s.w);\n",
+ dstreg, dstmask, arg2, dstmask, arg1, dstmask, arg0);
+ break;
+
+ case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
+ arg0 = shader_glsl_get_ffp_fragment_op_arg(buffer, 0, stage, WINED3DTA_TEXTURE);
+ shader_addline(buffer, "%s%s = mix(%s%s, %s%s, %s.w);\n",
+ dstreg, dstmask, arg2, dstmask, arg1, dstmask, arg0);
+ break;
+
+ case WINED3D_TOP_BLEND_FACTOR_ALPHA:
+ arg0 = shader_glsl_get_ffp_fragment_op_arg(buffer, 0, stage, WINED3DTA_TFACTOR);
+ shader_addline(buffer, "%s%s = mix(%s%s, %s%s, %s.w);\n",
+ dstreg, dstmask, arg2, dstmask, arg1, dstmask, arg0);
+ break;
+
+ case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
+ arg0 = shader_glsl_get_ffp_fragment_op_arg(buffer, 0, stage, WINED3DTA_TEXTURE);
+ shader_addline(buffer, "%s%s = clamp(%s%s * (1.0 - %s.w) + %s%s, 0.0, 1.0);\n",
+ dstreg, dstmask, arg2, dstmask, arg0, arg1, dstmask);
+ break;
+
+ case WINED3D_TOP_BLEND_CURRENT_ALPHA:
+ arg0 = shader_glsl_get_ffp_fragment_op_arg(buffer, 0, stage, WINED3DTA_CURRENT);
+ shader_addline(buffer, "%s%s = mix(%s%s, %s%s, %s.w);\n",
+ dstreg, dstmask, arg2, dstmask, arg1, dstmask, arg0);
+ break;
+
+ case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
+ shader_addline(buffer, "%s%s = clamp(%s%s * %s.w + %s%s, 0.0, 1.0);\n",
+ dstreg, dstmask, arg2, dstmask, arg1, arg1, dstmask);
+ break;
+
+ case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
+ shader_addline(buffer, "%s%s = clamp(%s%s * %s%s + %s.w, 0.0, 1.0);\n",
+ dstreg, dstmask, arg1, dstmask, arg2, dstmask, arg1);
+ break;
+
+ case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
+ shader_addline(buffer, "%s%s = clamp(%s%s * (1.0 - %s.w) + %s%s, 0.0, 1.0);\n",
+ dstreg, dstmask, arg2, dstmask, arg1, arg1, dstmask);
+ break;
+ case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
+ shader_addline(buffer, "%s%s = clamp((vec4(1.0) - %s)%s * %s%s + %s.w, 0.0, 1.0);\n",
+ dstreg, dstmask, arg1, dstmask, arg2, dstmask, arg1);
+ break;
+
+ case WINED3D_TOP_BUMPENVMAP:
+ case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
+ /* These are handled in the first pass, nothing to do. */
+ break;
+
+ case WINED3D_TOP_DOTPRODUCT3:
+ shader_addline(buffer, "%s%s = vec4(clamp(dot(%s.xyz - 0.5, %s.xyz - 0.5) * 4.0, 0.0, 1.0))%s;\n",
+ dstreg, dstmask, arg1, arg2, dstmask);
+ break;
+
+ case WINED3D_TOP_MULTIPLY_ADD:
+ shader_addline(buffer, "%s%s = clamp(%s%s * %s%s + %s%s, 0.0, 1.0);\n",
+ dstreg, dstmask, arg1, dstmask, arg2, dstmask, arg0, dstmask);
+ break;
+
+ case WINED3D_TOP_LERP:
+ /* MSDN isn't quite right here. */
+ shader_addline(buffer, "%s%s = mix(%s%s, %s%s, %s%s);\n",
+ dstreg, dstmask, arg2, dstmask, arg1, dstmask, arg0, dstmask);
+ break;
+
+ default:
+ FIXME("Unhandled operation %#x.\n", op);
+ break;
+ }
+}
+
+/* Context activation is done by the caller. */
+static GLuint shader_glsl_generate_ffp_fragment_shader(struct wined3d_shader_buffer *buffer,
+ const struct ffp_frag_settings *settings, const struct wined3d_gl_info *gl_info)
+{
+ BOOL tempreg_used = FALSE, tfactor_used = FALSE;
+ BYTE lum_map = 0, bump_map = 0, tex_map = 0;
+ const char *final_combiner_src = "ret";
+ UINT lowest_disabled_stage;
+ GLhandleARB shader_obj;
+ DWORD arg0, arg1, arg2;
+ unsigned int stage;
+
+ shader_buffer_clear(buffer);
+
+ /* Find out which textures are read */
+ for (stage = 0; stage < MAX_TEXTURES; ++stage)
+ {
+ if (settings->op[stage].cop == WINED3D_TOP_DISABLE)
+ break;
+
+ arg0 = settings->op[stage].carg0 & WINED3DTA_SELECTMASK;
+ arg1 = settings->op[stage].carg1 & WINED3DTA_SELECTMASK;
+ arg2 = settings->op[stage].carg2 & WINED3DTA_SELECTMASK;
+
+ if (arg0 == WINED3DTA_TEXTURE || arg1 == WINED3DTA_TEXTURE || arg2 == WINED3DTA_TEXTURE)
+ tex_map |= 1 << stage;
+ if (arg0 == WINED3DTA_TFACTOR || arg1 == WINED3DTA_TFACTOR || arg2 == WINED3DTA_TFACTOR)
+ tfactor_used = TRUE;
+ if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP)
+ tempreg_used = TRUE;
+ if (settings->op[stage].dst == tempreg)
+ tempreg_used = TRUE;
+
+ switch (settings->op[stage].cop)
+ {
+ case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
+ lum_map |= 1 << stage;
+ /* fall through */
+ case WINED3D_TOP_BUMPENVMAP:
+ bump_map |= 1 << stage;
+ /* fall through */
+ case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
+ case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
+ tex_map |= 1 << stage;
+ break;
+
+ case WINED3D_TOP_BLEND_FACTOR_ALPHA:
+ tfactor_used = TRUE;
+ break;
+
+ default:
+ break;
+ }
+
+ if (settings->op[stage].aop == WINED3D_TOP_DISABLE)
+ continue;
+
+ arg0 = settings->op[stage].aarg0 & WINED3DTA_SELECTMASK;
+ arg1 = settings->op[stage].aarg1 & WINED3DTA_SELECTMASK;
+ arg2 = settings->op[stage].aarg2 & WINED3DTA_SELECTMASK;
+
+ if (arg0 == WINED3DTA_TEXTURE || arg1 == WINED3DTA_TEXTURE || arg2 == WINED3DTA_TEXTURE)
+ tex_map |= 1 << stage;
+ if (arg0 == WINED3DTA_TFACTOR || arg1 == WINED3DTA_TFACTOR || arg2 == WINED3DTA_TFACTOR)
+ tfactor_used = TRUE;
+ if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP)
+ tempreg_used = TRUE;
+ }
+ lowest_disabled_stage = stage;
+
+ shader_addline(buffer, "#version 120\n");
+
+ if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ shader_addline(buffer, "#extension GL_ARB_texture_rectangle : enable\n");
+
+ shader_addline(buffer, "vec4 tmp0, tmp1;\n");
+ shader_addline(buffer, "vec4 ret;\n");
+ if (tempreg_used || settings->sRGB_write)
+ shader_addline(buffer, "vec4 temp_reg;\n");
+ shader_addline(buffer, "vec4 arg0, arg1, arg2;\n");
+
+ for (stage = 0; stage < MAX_TEXTURES; ++stage)
+ {
+ if (!(tex_map & (1 << stage)))
+ continue;
+
+ switch (settings->op[stage].tex_type)
+ {
+ case tex_1d:
+ shader_addline(buffer, "uniform sampler1D ps_sampler%u;\n", stage);
+ break;
+ case tex_2d:
+ shader_addline(buffer, "uniform sampler2D ps_sampler%u;\n", stage);
+ break;
+ case tex_3d:
+ shader_addline(buffer, "uniform sampler3D ps_sampler%u;\n", stage);
+ break;
+ case tex_cube:
+ shader_addline(buffer, "uniform samplerCube ps_sampler%u;\n", stage);
+ break;
+ case tex_rect:
+ shader_addline(buffer, "uniform sampler2DRect ps_sampler%u;\n", stage);
+ break;
+ default:
+ FIXME("Unhandled sampler type %#x.\n", settings->op[stage].tex_type);
+ break;
+ }
+
+ shader_addline(buffer, "vec4 tex%u;\n", stage);
+
+ if (!(bump_map & (1 << stage)))
+ continue;
+ shader_addline(buffer, "uniform mat2 bumpenv_mat%u;\n", stage);
+
+ if (!(lum_map & (1 << stage)))
+ continue;
+ shader_addline(buffer, "uniform float bumpenv_lum_scale%u;\n", stage);
+ shader_addline(buffer, "uniform float bumpenv_lum_offset%u;\n", stage);
+ }
+ if (tfactor_used)
+ shader_addline(buffer, "uniform vec4 tex_factor;\n");
+ shader_addline(buffer, "uniform vec4 specular_enable;\n");
+
+ if (settings->sRGB_write)
+ {
+ shader_addline(buffer, "const vec4 srgb_const0 = ");
+ shader_glsl_append_imm_vec4(buffer, srgb_const0);
+ shader_addline(buffer, ";\n");
+ shader_addline(buffer, "const vec4 srgb_const1 = ");
+ shader_glsl_append_imm_vec4(buffer, srgb_const1);
+ shader_addline(buffer, ";\n");
+ }
+
+ shader_addline(buffer, "void main()\n{\n");
+
+ if (lowest_disabled_stage < 7 && settings->emul_clipplanes)
+ shader_addline(buffer, "if (any(lessThan(gl_TexCoord[7], vec4(0.0)))) discard;\n");
+
+ /* Generate texture sampling instructions) */
+ for (stage = 0; stage < MAX_TEXTURES && settings->op[stage].cop != WINED3D_TOP_DISABLE; ++stage)
+ {
+ const char *texture_function, *coord_mask;
+ char tex_reg_name[8];
+ BOOL proj, clamp;
+
+ if (!(tex_map & (1 << stage)))
+ continue;
+
+ if (settings->op[stage].projected == proj_none)
+ {
+ proj = FALSE;
+ }
+ else if (settings->op[stage].projected == proj_count4
+ || settings->op[stage].projected == proj_count3)
+ {
+ proj = TRUE;
+ }
+ else
+ {
+ FIXME("Unexpected projection mode %d\n", settings->op[stage].projected);
+ proj = TRUE;
+ }
+
+ if (settings->op[stage].cop == WINED3D_TOP_BUMPENVMAP
+ || settings->op[stage].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE)
+ clamp = FALSE;
+ else
+ clamp = TRUE;
+
+ switch (settings->op[stage].tex_type)
+ {
+ case tex_1d:
+ if (proj)
+ {
+ texture_function = "texture1DProj";
+ coord_mask = "xw";
+ }
+ else
+ {
+ texture_function = "texture1D";
+ coord_mask = "x";
+ }
+ break;
+ case tex_2d:
+ if (proj)
+ {
+ texture_function = "texture2DProj";
+ coord_mask = "xyw";
+ }
+ else
+ {
+ texture_function = "texture2D";
+ coord_mask = "xy";
+ }
+ break;
+ case tex_3d:
+ if (proj)
+ {
+ texture_function = "texture3DProj";
+ coord_mask = "xyzw";
+ }
+ else
+ {
+ texture_function = "texture3D";
+ coord_mask = "xyz";
+ }
+ break;
+ case tex_cube:
+ texture_function = "textureCube";
+ coord_mask = "xyz";
+ break;
+ case tex_rect:
+ if (proj)
+ {
+ texture_function = "texture2DRectProj";
+ coord_mask = "xyw";
+ }
+ else
+ {
+ texture_function = "texture2DRect";
+ coord_mask = "xy";
+ }
+ break;
+ default:
+ FIXME("Unhandled texture type %#x.\n", settings->op[stage].tex_type);
+ texture_function = "";
+ coord_mask = "xyzw";
+ break;
+ }
+
+ if (stage > 0
+ && (settings->op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP
+ || settings->op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE))
+ {
+ shader_addline(buffer, "ret.xy = bumpenv_mat%u * tex%u.xy;\n", stage - 1, stage - 1);
+
+ /* With projective textures, texbem only divides the static
+ * texture coord, not the displacement, so multiply the
+ * displacement with the dividing parameter before passing it to
+ * TXP. */
+ if (settings->op[stage].projected != proj_none)
+ {
+ if (settings->op[stage].projected == proj_count4)
+ {
+ shader_addline(buffer, "ret.xy = (ret.xy * gl_TexCoord[%u].w) + gl_TexCoord[%u].xy;\n",
+ stage, stage);
+ shader_addline(buffer, "ret.zw = gl_TexCoord[%u].ww;\n", stage);
+ }
+ else
+ {
+ shader_addline(buffer, "ret.xy = (ret.xy * gl_TexCoord[%u].z) + gl_TexCoord[%u].xy;\n",
+ stage, stage);
+ shader_addline(buffer, "ret.zw = gl_TexCoord[%u].zz;\n", stage);
+ }
+ }
+ else
+ {
+ shader_addline(buffer, "ret = gl_TexCoord[%u] + ret.xyxy;\n", stage);
+ }
+
+ if (clamp)
+ shader_addline(buffer, "tex%u = clamp(%s(ps_sampler%u, ret.%s), 0.0, 1.0);\n",
+ stage, texture_function, stage, coord_mask);
+ else
+ shader_addline(buffer, "tex%u = %s(ps_sampler%u, ret.%s);\n",
+ stage, texture_function, stage, coord_mask);
+
+ if (settings->op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE)
+ shader_addline(buffer, "tex%u *= clamp(tex%u.z * bumpenv_lum_scale%u + bumpenv_lum_offset%u, 0.0, 1.0);\n",
+ stage, stage - 1, stage - 1, stage - 1);
+ }
+ else if (settings->op[stage].projected == proj_count3)
+ {
+ if (clamp)
+ shader_addline(buffer, "tex%u = clamp(%s(ps_sampler%u, gl_TexCoord[%u].xyz), 0.0, 1.0);\n",
+ stage, texture_function, stage, stage);
+ else
+ shader_addline(buffer, "tex%u = %s(ps_sampler%u, gl_TexCoord[%u].xyz);\n",
+ stage, texture_function, stage, stage);
+ }
+ else
+ {
+ if (clamp)
+ shader_addline(buffer, "tex%u = clamp(%s(ps_sampler%u, gl_TexCoord[%u].%s), 0.0, 1.0);\n",
+ stage, texture_function, stage, stage, coord_mask);
+ else
+ shader_addline(buffer, "tex%u = %s(ps_sampler%u, gl_TexCoord[%u].%s);\n",
+ stage, texture_function, stage, stage, coord_mask);
+ }
+
+ sprintf(tex_reg_name, "tex%u", stage);
+ shader_glsl_color_correction_ext(buffer, tex_reg_name, WINED3DSP_WRITEMASK_ALL,
+ settings->op[stage].color_fixup);
+ }
+
+ /* Generate the main shader */
+ for (stage = 0; stage < MAX_TEXTURES; ++stage)
+ {
+ BOOL op_equal;
+
+ if (settings->op[stage].cop == WINED3D_TOP_DISABLE)
+ {
+ if (!stage)
+ final_combiner_src = "gl_Color";
+ break;
+ }
+
+ if (settings->op[stage].cop == WINED3D_TOP_SELECT_ARG1
+ && settings->op[stage].aop == WINED3D_TOP_SELECT_ARG1)
+ op_equal = settings->op[stage].carg1 == settings->op[stage].aarg1;
+ else if (settings->op[stage].cop == WINED3D_TOP_SELECT_ARG1
+ && settings->op[stage].aop == WINED3D_TOP_SELECT_ARG2)
+ op_equal = settings->op[stage].carg1 == settings->op[stage].aarg2;
+ else if (settings->op[stage].cop == WINED3D_TOP_SELECT_ARG2
+ && settings->op[stage].aop == WINED3D_TOP_SELECT_ARG1)
+ op_equal = settings->op[stage].carg2 == settings->op[stage].aarg1;
+ else if (settings->op[stage].cop == WINED3D_TOP_SELECT_ARG2
+ && settings->op[stage].aop == WINED3D_TOP_SELECT_ARG2)
+ op_equal = settings->op[stage].carg2 == settings->op[stage].aarg2;
+ else
+ op_equal = settings->op[stage].aop == settings->op[stage].cop
+ && settings->op[stage].carg0 == settings->op[stage].aarg0
+ && settings->op[stage].carg1 == settings->op[stage].aarg1
+ && settings->op[stage].carg2 == settings->op[stage].aarg2;
+
+ if (settings->op[stage].aop == WINED3D_TOP_DISABLE)
+ {
+ shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].dst,
+ settings->op[stage].cop, settings->op[stage].carg0,
+ settings->op[stage].carg1, settings->op[stage].carg2);
+ if (!stage)
+ shader_addline(buffer, "ret.w = gl_Color.w;\n");
+ }
+ else if (op_equal)
+ {
+ shader_glsl_ffp_fragment_op(buffer, stage, TRUE, TRUE, settings->op[stage].dst,
+ settings->op[stage].cop, settings->op[stage].carg0,
+ settings->op[stage].carg1, settings->op[stage].carg2);
+ }
+ else
+ {
+ shader_glsl_ffp_fragment_op(buffer, stage, TRUE, FALSE, settings->op[stage].dst,
+ settings->op[stage].cop, settings->op[stage].carg0,
+ settings->op[stage].carg1, settings->op[stage].carg2);
+ shader_glsl_ffp_fragment_op(buffer, stage, FALSE, TRUE, settings->op[stage].dst,
+ settings->op[stage].aop, settings->op[stage].aarg0,
+ settings->op[stage].aarg1, settings->op[stage].aarg2);
+ }
+ }
+
+ shader_addline(buffer, "gl_FragData[0] = gl_SecondaryColor * specular_enable + %s;\n", final_combiner_src);
+
+ if (settings->sRGB_write)
+ shader_glsl_generate_srgb_write_correction(buffer);
+
+ shader_glsl_generate_fog_code(buffer, settings->fog);
+
+ shader_addline(buffer, "}\n");
+
+ shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
+ shader_glsl_compile(gl_info, shader_obj, buffer->buffer);
+ return shader_obj;
+}
+
+static struct glsl_ffp_vertex_shader *shader_glsl_find_ffp_vertex_shader(struct shader_glsl_priv *priv,
+ const struct wined3d_gl_info *gl_info, const struct wined3d_ffp_vs_settings *settings)
+{
+ struct glsl_ffp_vertex_shader *shader;
+ const struct wine_rb_entry *entry;
+
+ if ((entry = wine_rb_get(&priv->ffp_vertex_shaders, settings)))
+ return WINE_RB_ENTRY_VALUE(entry, struct glsl_ffp_vertex_shader, desc.entry);
+
+ if (!(shader = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader))))
+ return NULL;
+
+ shader->desc.settings = *settings;
+ shader->id = shader_glsl_generate_ffp_vertex_shader(&priv->shader_buffer, settings, gl_info);
+ list_init(&shader->linked_programs);
+ if (wine_rb_put(&priv->ffp_vertex_shaders, &shader->desc.settings, &shader->desc.entry) == -1)
+ ERR("Failed to insert ffp vertex shader.\n");
+
+ return shader;
+}
+
+static struct glsl_ffp_fragment_shader *shader_glsl_find_ffp_fragment_shader(struct shader_glsl_priv *priv,
+ const struct wined3d_gl_info *gl_info, const struct ffp_frag_settings *args)
+{
+ struct glsl_ffp_fragment_shader *glsl_desc;
+ const struct ffp_frag_desc *desc;
+
+ if ((desc = find_ffp_frag_shader(&priv->ffp_fragment_shaders, args)))
+ return CONTAINING_RECORD(desc, struct glsl_ffp_fragment_shader, entry);
+
+ if (!(glsl_desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*glsl_desc))))
+ return NULL;
+
+ glsl_desc->entry.settings = *args;
+ glsl_desc->id = shader_glsl_generate_ffp_fragment_shader(&priv->shader_buffer, args, gl_info);
+ list_init(&glsl_desc->linked_programs);
+ add_ffp_frag_shader(&priv->ffp_fragment_shaders, &glsl_desc->entry);
+
+ return glsl_desc;
+}
+
+
+static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info *gl_info,
+ GLhandleARB program_id, struct glsl_vs_program *vs)
+{
+ unsigned int i;
+ char name[32];
+
+ vs->uniform_f_locations = HeapAlloc(GetProcessHeap(), 0,
+ sizeof(GLhandleARB) * gl_info->limits.glsl_vs_float_constants);
+ for (i = 0; i < gl_info->limits.glsl_vs_float_constants; ++i)
+ {
+ snprintf(name, sizeof(name), "vs_c[%u]", i);
+ vs->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name));
+ }
+
+ for (i = 0; i < MAX_CONST_I; ++i)
+ {
+ snprintf(name, sizeof(name), "vs_i[%u]", i);
+ vs->uniform_i_locations[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name));
+ }
+
+ vs->pos_fixup_location = GL_EXTCALL(glGetUniformLocationARB(program_id, "posFixup"));
+}
+
+static void shader_glsl_init_ps_uniform_locations(const struct wined3d_gl_info *gl_info,
+ GLhandleARB program_id, struct glsl_ps_program *ps)
+{
+ unsigned int i;
+ char name[32];
+
+ ps->uniform_f_locations = HeapAlloc(GetProcessHeap(), 0,
+ sizeof(GLhandleARB) * gl_info->limits.glsl_ps_float_constants);
+ for (i = 0; i < gl_info->limits.glsl_ps_float_constants; ++i)
+ {
+ snprintf(name, sizeof(name), "ps_c[%u]", i);
+ ps->uniform_f_locations[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name));
+ }
+
+ for (i = 0; i < MAX_CONST_I; ++i)
+ {
+ snprintf(name, sizeof(name), "ps_i[%u]", i);
+ ps->uniform_i_locations[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name));
+ }
+
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ snprintf(name, sizeof(name), "bumpenv_mat%u", i);
+ ps->bumpenv_mat_location[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name));
+ snprintf(name, sizeof(name), "bumpenv_lum_scale%u", i);
+ ps->bumpenv_lum_scale_location[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name));
+ snprintf(name, sizeof(name), "bumpenv_lum_offset%u", i);
+ ps->bumpenv_lum_offset_location[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name));
+ }
+
+ ps->tex_factor_location = GL_EXTCALL(glGetUniformLocationARB(program_id, "tex_factor"));
+ ps->specular_enable_location = GL_EXTCALL(glGetUniformLocationARB(program_id, "specular_enable"));
+ ps->np2_fixup_location = GL_EXTCALL(glGetUniformLocationARB(program_id, "ps_samplerNP2Fixup"));
+ ps->ycorrection_location = GL_EXTCALL(glGetUniformLocationARB(program_id, "ycorrection"));
+}
+
+/* Context activation is done by the caller. */
+static void set_glsl_shader_program(const struct wined3d_context *context, const struct wined3d_state *state,
+ struct shader_glsl_priv *priv)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const struct ps_np2fixup_info *np2fixup_info = NULL;
+ struct glsl_shader_prog_link *entry = NULL;
+ struct wined3d_shader *vshader = NULL;
+ struct wined3d_shader *gshader = NULL;
+ struct wined3d_shader *pshader = NULL;
+ GLhandleARB programId = 0;
+ GLhandleARB reorder_shader_id = 0;
+ unsigned int i;
+ struct ps_compile_args ps_compile_args;
+ struct vs_compile_args vs_compile_args;
+ GLhandleARB vs_id, gs_id, ps_id;
+ struct list *ps_list, *vs_list;
+ struct wined3d_device *device = context->swapchain->device;
+
+ if (use_vs(state))
+ {
+ vshader = state->vertex_shader;
+ find_vs_compile_args(state, vshader, &vs_compile_args);
+ vs_id = find_glsl_vshader(context, &priv->shader_buffer, vshader, &vs_compile_args);
+ vs_list = &vshader->linked_programs;
+
+ if ((gshader = state->geometry_shader))
+ gs_id = find_glsl_geometry_shader(context, &priv->shader_buffer, gshader);
+ else
+ gs_id = 0;
+ }
+ else if (priv->vertex_pipe == &glsl_vertex_pipe)
+ {
+ struct glsl_ffp_vertex_shader *ffp_shader;
+ struct wined3d_ffp_vs_settings settings;
+
+ wined3d_ffp_get_vs_settings(state, &device->stream_info, &settings);
+ ffp_shader = shader_glsl_find_ffp_vertex_shader(priv, gl_info, &settings);
+ vs_id = ffp_shader->id;
+ vs_list = &ffp_shader->linked_programs;
+
+ gs_id = 0;
+ }
+ else
+ {
+ vs_id = 0;
+ gs_id = 0;
+ }
+
+ if (use_ps(state))
+ {
+ pshader = state->pixel_shader;
+ find_ps_compile_args(state, pshader, &ps_compile_args);
+ ps_id = find_glsl_pshader(context, &priv->shader_buffer,
+ pshader, &ps_compile_args, &np2fixup_info);
+ ps_list = &pshader->linked_programs;
+ }
+ else if (priv->fragment_pipe == &glsl_fragment_pipe)
+ {
+ struct glsl_ffp_fragment_shader *ffp_shader;
+ struct ffp_frag_settings settings;
+
+ gen_ffp_frag_op(context, state, &settings, FALSE);
+ ffp_shader = shader_glsl_find_ffp_fragment_shader(priv, gl_info, &settings);
+ ps_id = ffp_shader->id;
+ ps_list = &ffp_shader->linked_programs;
+ }
+ else
+ {
+ ps_id = 0;
+ }
+
+ if ((!vs_id && !gs_id && !ps_id) || (entry = get_glsl_program_entry(priv, vs_id, gs_id, ps_id)))
+ {
+ priv->glsl_program = entry;
+ return;
+ }
+
+ /* If we get to this point, then no matching program exists, so we create one */
+ programId = GL_EXTCALL(glCreateProgramObjectARB());
+ TRACE("Created new GLSL shader program %u\n", programId);
+
+ /* Create the entry */
+ entry = HeapAlloc(GetProcessHeap(), 0, sizeof(struct glsl_shader_prog_link));
+ entry->programId = programId;
+ entry->vs.id = vs_id;
+ entry->gs.id = gs_id;
+ entry->ps.id = ps_id;
+ entry->constant_version = 0;
+ entry->ps.np2_fixup_info = np2fixup_info;
+ /* Add the hash table entry */
+ add_glsl_program_entry(priv, entry);
+
+ /* Set the current program */
+ priv->glsl_program = entry;
+
+ /* Attach GLSL vshader */
+ if (vs_id)
+ {
+ TRACE("Attaching GLSL shader object %u to program %u.\n", vs_id, programId);
+ GL_EXTCALL(glAttachObjectARB(programId, vs_id));
+ checkGLcall("glAttachObjectARB");
+
+ list_add_head(vs_list, &entry->vs.shader_entry);
+ }
+
+ if (vshader)
+ {
+ WORD map = vshader->reg_maps.input_registers;
+ char tmp_name[10];
+
+ reorder_shader_id = generate_param_reorder_function(&priv->shader_buffer, vshader, pshader, gl_info);
+ TRACE("Attaching GLSL shader object %u to program %u\n", reorder_shader_id, programId);
+ GL_EXTCALL(glAttachObjectARB(programId, reorder_shader_id));
+ checkGLcall("glAttachObjectARB");
+ /* Flag the reorder function for deletion, then it will be freed automatically when the program
+ * is destroyed
+ */
+ GL_EXTCALL(glDeleteObjectARB(reorder_shader_id));
+
+ /* Bind vertex attributes to a corresponding index number to match
+ * the same index numbers as ARB_vertex_programs (makes loading
+ * vertex attributes simpler). With this method, we can use the
+ * exact same code to load the attributes later for both ARB and
+ * GLSL shaders.
+ *
+ * We have to do this here because we need to know the Program ID
+ * in order to make the bindings work, and it has to be done prior
+ * to linking the GLSL program. */
+ for (i = 0; map; map >>= 1, ++i)
+ {
+ if (!(map & 1)) continue;
+
+ snprintf(tmp_name, sizeof(tmp_name), "vs_in%u", i);
+ GL_EXTCALL(glBindAttribLocationARB(programId, i, tmp_name));
+ }
+ checkGLcall("glBindAttribLocationARB");
+ }
+
+ if (gshader)
+ {
+ TRACE("Attaching GLSL geometry shader object %u to program %u.\n", gs_id, programId);
+ GL_EXTCALL(glAttachObjectARB(programId, gs_id));
+ checkGLcall("glAttachObjectARB");
+
+ TRACE("input type %s, output type %s, vertices out %u.\n",
+ debug_d3dprimitivetype(gshader->u.gs.input_type),
+ debug_d3dprimitivetype(gshader->u.gs.output_type),
+ gshader->u.gs.vertices_out);
+ GL_EXTCALL(glProgramParameteriARB(programId, GL_GEOMETRY_INPUT_TYPE_ARB,
+ gl_primitive_type_from_d3d(gshader->u.gs.input_type)));
+ GL_EXTCALL(glProgramParameteriARB(programId, GL_GEOMETRY_OUTPUT_TYPE_ARB,
+ gl_primitive_type_from_d3d(gshader->u.gs.output_type)));
+ GL_EXTCALL(glProgramParameteriARB(programId, GL_GEOMETRY_VERTICES_OUT_ARB,
+ gshader->u.gs.vertices_out));
+ checkGLcall("glProgramParameteriARB");
+
+ list_add_head(&gshader->linked_programs, &entry->gs.shader_entry);
+ }
+
+ /* Attach GLSL pshader */
+ if (ps_id)
+ {
+ TRACE("Attaching GLSL shader object %u to program %u.\n", ps_id, programId);
+ GL_EXTCALL(glAttachObjectARB(programId, ps_id));
+ checkGLcall("glAttachObjectARB");
+
+ list_add_head(ps_list, &entry->ps.shader_entry);
+ }
+
+ /* Link the program */
+ TRACE("Linking GLSL shader program %u\n", programId);
+ GL_EXTCALL(glLinkProgramARB(programId));
+ shader_glsl_validate_link(gl_info, programId);
+
+ shader_glsl_init_vs_uniform_locations(gl_info, programId, &entry->vs);
+ shader_glsl_init_ps_uniform_locations(gl_info, programId, &entry->ps);
+ checkGLcall("Find glsl program uniform locations");
+
+ if (pshader && pshader->reg_maps.shader_version.major >= 3
+ && pshader->u.ps.declared_in_count > vec4_varyings(3, gl_info))
+ {
+ TRACE("Shader %d needs vertex color clamping disabled\n", programId);
+ entry->vs.vertex_color_clamp = GL_FALSE;
+ }
+ else
+ {
+ entry->vs.vertex_color_clamp = GL_FIXED_ONLY_ARB;
+ }
+
+ /* Set the shader to allow uniform loading on it */
+ GL_EXTCALL(glUseProgramObjectARB(programId));
+ checkGLcall("glUseProgramObjectARB(programId)");
+
+ /* Load the vertex and pixel samplers now. The function that finds the mappings makes sure
+ * that it stays the same for each vertexshader-pixelshader pair(=linked glsl program). If
+ * a pshader with fixed function pipeline is used there are no vertex samplers, and if a
+ * vertex shader with fixed function pixel processing is used we make sure that the card
+ * supports enough samplers to allow the max number of vertex samplers with all possible
+ * fixed function fragment processing setups. So once the program is linked these samplers
+ * won't change.
+ */
+ shader_glsl_load_vsamplers(gl_info, device->texUnitMap, programId);
+ shader_glsl_load_psamplers(gl_info, device->texUnitMap, programId);
+}
+
+/* Context activation is done by the caller. */
+static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info, enum tex_types tex_type, BOOL masked)
+{
+ GLhandleARB program_id;
+ GLhandleARB vshader_id, pshader_id;
+ const char *blt_pshader;
+
+ static const char *blt_vshader =
+ "#version 120\n"
+ "void main(void)\n"
+ "{\n"
+ " gl_Position = gl_Vertex;\n"
+ " gl_FrontColor = vec4(1.0);\n"
+ " gl_TexCoord[0] = gl_MultiTexCoord0;\n"
+ "}\n";
+
+ static const char * const blt_pshaders_full[tex_type_count] =
+ {
+ /* tex_1d */
+ NULL,
+ /* tex_2d */
+ "#version 120\n"
+ "uniform sampler2D sampler;\n"
+ "void main(void)\n"
+ "{\n"
+ " gl_FragDepth = texture2D(sampler, gl_TexCoord[0].xy).x;\n"
+ "}\n",
+ /* tex_3d */
+ NULL,
+ /* tex_cube */
+ "#version 120\n"
+ "uniform samplerCube sampler;\n"
+ "void main(void)\n"
+ "{\n"
+ " gl_FragDepth = textureCube(sampler, gl_TexCoord[0].xyz).x;\n"
+ "}\n",
+ /* tex_rect */
+ "#version 120\n"
+ "#extension GL_ARB_texture_rectangle : enable\n"
+ "uniform sampler2DRect sampler;\n"
+ "void main(void)\n"
+ "{\n"
+ " gl_FragDepth = texture2DRect(sampler, gl_TexCoord[0].xy).x;\n"
+ "}\n",
+ };
+
+ static const char * const blt_pshaders_masked[tex_type_count] =
+ {
+ /* tex_1d */
+ NULL,
+ /* tex_2d */
+ "#version 120\n"
+ "uniform sampler2D sampler;\n"
+ "uniform vec4 mask;\n"
+ "void main(void)\n"
+ "{\n"
+ " if (all(lessThan(gl_FragCoord.xy, mask.zw))) discard;\n"
+ " gl_FragDepth = texture2D(sampler, gl_TexCoord[0].xy).x;\n"
+ "}\n",
+ /* tex_3d */
+ NULL,
+ /* tex_cube */
+ "#version 120\n"
+ "uniform samplerCube sampler;\n"
+ "uniform vec4 mask;\n"
+ "void main(void)\n"
+ "{\n"
+ " if (all(lessThan(gl_FragCoord.xy, mask.zw))) discard;\n"
+ " gl_FragDepth = textureCube(sampler, gl_TexCoord[0].xyz).x;\n"
+ "}\n",
+ /* tex_rect */
+ "#version 120\n"
+ "#extension GL_ARB_texture_rectangle : enable\n"
+ "uniform sampler2DRect sampler;\n"
+ "uniform vec4 mask;\n"
+ "void main(void)\n"
+ "{\n"
+ " if (all(lessThan(gl_FragCoord.xy, mask.zw))) discard;\n"
+ " gl_FragDepth = texture2DRect(sampler, gl_TexCoord[0].xy).x;\n"
+ "}\n",
+ };
+
+ blt_pshader = masked ? blt_pshaders_masked[tex_type] : blt_pshaders_full[tex_type];
+ if (!blt_pshader)
+ {
+ FIXME("tex_type %#x not supported\n", tex_type);
+ return 0;
+ }
+
+ vshader_id = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
+ shader_glsl_compile(gl_info, vshader_id, blt_vshader);
+
+ pshader_id = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
+ shader_glsl_compile(gl_info, pshader_id, blt_pshader);
+
+ program_id = GL_EXTCALL(glCreateProgramObjectARB());
+ GL_EXTCALL(glAttachObjectARB(program_id, vshader_id));
+ GL_EXTCALL(glAttachObjectARB(program_id, pshader_id));
+ GL_EXTCALL(glLinkProgramARB(program_id));
+
+ shader_glsl_validate_link(gl_info, program_id);
+
+ /* Once linked we can mark the shaders for deletion. They will be deleted once the program
+ * is destroyed
+ */
+ GL_EXTCALL(glDeleteObjectARB(vshader_id));
+ GL_EXTCALL(glDeleteObjectARB(pshader_id));
+ return program_id;
+}
+
+/* Context activation is done by the caller. */
+static void shader_glsl_select(void *shader_priv, const struct wined3d_context *context,
+ const struct wined3d_state *state)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct shader_glsl_priv *priv = shader_priv;
+ GLhandleARB program_id = 0;
+ GLenum old_vertex_color_clamp, current_vertex_color_clamp;
+
+ priv->vertex_pipe->vp_enable(gl_info, !use_vs(state));
+ priv->fragment_pipe->enable_extension(gl_info, !use_ps(state));
+
+ old_vertex_color_clamp = priv->glsl_program ? priv->glsl_program->vs.vertex_color_clamp : GL_FIXED_ONLY_ARB;
+ set_glsl_shader_program(context, state, priv);
+ current_vertex_color_clamp = priv->glsl_program ? priv->glsl_program->vs.vertex_color_clamp : GL_FIXED_ONLY_ARB;
+ if (old_vertex_color_clamp != current_vertex_color_clamp)
+ {
+ if (gl_info->supported[ARB_COLOR_BUFFER_FLOAT])
+ {
+ GL_EXTCALL(glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, current_vertex_color_clamp));
+ checkGLcall("glClampColorARB");
+ }
+ else
+ {
+ FIXME("vertex color clamp needs to be changed, but extension not supported.\n");
+ }
+ }
+
+ program_id = priv->glsl_program ? priv->glsl_program->programId : 0;
+ if (program_id) TRACE("Using GLSL program %u\n", program_id);
+ GL_EXTCALL(glUseProgramObjectARB(program_id));
+ checkGLcall("glUseProgramObjectARB");
+
+ /* In case that NP2 texcoord fixup data is found for the selected program, trigger a reload of the
+ * constants. This has to be done because it can't be guaranteed that sampler() (from state.c) is
+ * called between selecting the shader and using it, which results in wrong fixup for some frames. */
+ if (priv->glsl_program && priv->glsl_program->ps.np2_fixup_info)
+ {
+ shader_glsl_load_np2fixup_constants(priv, gl_info, state);
+ }
+}
+
+/* Context activation is done by the caller. */
+static void shader_glsl_disable(void *shader_priv, const struct wined3d_context *context)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct shader_glsl_priv *priv = shader_priv;
+
+ priv->glsl_program = NULL;
+ GL_EXTCALL(glUseProgramObjectARB(0));
+ checkGLcall("glUseProgramObjectARB");
+
+ priv->vertex_pipe->vp_enable(gl_info, FALSE);
+ priv->fragment_pipe->enable_extension(gl_info, FALSE);
+
+ if (gl_info->supported[ARB_COLOR_BUFFER_FLOAT])
+ {
+ GL_EXTCALL(glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, GL_FIXED_ONLY_ARB));
+ checkGLcall("glClampColorARB");
+ }
+}
+
+/* Context activation is done by the caller. */
+static void shader_glsl_select_depth_blt(void *shader_priv, const struct wined3d_gl_info *gl_info,
+ enum tex_types tex_type, const SIZE *ds_mask_size)
+{
+ BOOL masked = ds_mask_size->cx && ds_mask_size->cy;
+ struct shader_glsl_priv *priv = shader_priv;
+ GLhandleARB *blt_program;
+ GLint loc;
+
+ blt_program = masked ? &priv->depth_blt_program_masked[tex_type] : &priv->depth_blt_program_full[tex_type];
+ if (!*blt_program)
+ {
+ *blt_program = create_glsl_blt_shader(gl_info, tex_type, masked);
+ loc = GL_EXTCALL(glGetUniformLocationARB(*blt_program, "sampler"));
+ GL_EXTCALL(glUseProgramObjectARB(*blt_program));
+ GL_EXTCALL(glUniform1iARB(loc, 0));
+ }
+ else
+ {
+ GL_EXTCALL(glUseProgramObjectARB(*blt_program));
+ }
+
+ if (masked)
+ {
+ loc = GL_EXTCALL(glGetUniformLocationARB(*blt_program, "mask"));
+ GL_EXTCALL(glUniform4fARB(loc, 0.0f, 0.0f, (float)ds_mask_size->cx, (float)ds_mask_size->cy));
+ }
+}
+
+/* Context activation is done by the caller. */
+static void shader_glsl_deselect_depth_blt(void *shader_priv, const struct wined3d_gl_info *gl_info)
+{
+ struct shader_glsl_priv *priv = shader_priv;
+ GLhandleARB program_id;
+
+ program_id = priv->glsl_program ? priv->glsl_program->programId : 0;
+ if (program_id) TRACE("Using GLSL program %u\n", program_id);
+
+ GL_EXTCALL(glUseProgramObjectARB(program_id));
+ checkGLcall("glUseProgramObjectARB");
+}
+
+static void shader_glsl_destroy(struct wined3d_shader *shader)
+{
+ struct glsl_shader_private *shader_data = shader->backend_data;
+ struct wined3d_device *device = shader->device;
+ struct shader_glsl_priv *priv = device->shader_priv;
+ const struct wined3d_gl_info *gl_info;
+ const struct list *linked_programs;
+ struct wined3d_context *context;
+
+ if (!shader_data || !shader_data->num_gl_shaders)
+ {
+ HeapFree(GetProcessHeap(), 0, shader_data);
+ shader->backend_data = NULL;
+ return;
+ }
+
+ context = context_acquire(device, NULL);
+ gl_info = context->gl_info;
+
+ TRACE("Deleting linked programs.\n");
+ linked_programs = &shader->linked_programs;
+ if (linked_programs->next)
+ {
+ struct glsl_shader_prog_link *entry, *entry2;
+ UINT i;
+
+ switch (shader->reg_maps.shader_version.type)
+ {
+ case WINED3D_SHADER_TYPE_PIXEL:
+ {
+ struct glsl_ps_compiled_shader *gl_shaders = shader_data->gl_shaders.ps;
+
+ LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
+ struct glsl_shader_prog_link, ps.shader_entry)
+ {
+ delete_glsl_program_entry(priv, gl_info, entry
+#ifdef VBOX_WITH_WINE_FIX_SHADERCLEANUP
+ , context
+#endif
+ );
+ }
+
+ for (i = 0; i < shader_data->num_gl_shaders; ++i)
+ {
+ TRACE("Deleting pixel shader %u.\n", gl_shaders[i].prgId);
+ if (priv->glsl_program && priv->glsl_program->ps.id == gl_shaders[i].prgId)
+ shader_glsl_disable(priv, context);
+ GL_EXTCALL(glDeleteObjectARB(gl_shaders[i].prgId));
+ checkGLcall("glDeleteObjectARB");
+ }
+ HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.ps);
+
+ break;
+ }
+
+ case WINED3D_SHADER_TYPE_VERTEX:
+ {
+ struct glsl_vs_compiled_shader *gl_shaders = shader_data->gl_shaders.vs;
+
+ LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
+ struct glsl_shader_prog_link, vs.shader_entry)
+ {
+ delete_glsl_program_entry(priv, gl_info, entry
+#ifdef VBOX_WITH_WINE_FIX_SHADERCLEANUP
+ , context
+#endif
+ );
+ }
+
+ for (i = 0; i < shader_data->num_gl_shaders; ++i)
+ {
+ TRACE("Deleting vertex shader %u.\n", gl_shaders[i].prgId);
+ if (priv->glsl_program && priv->glsl_program->vs.id == gl_shaders[i].prgId)
+ shader_glsl_disable(priv, context);
+ GL_EXTCALL(glDeleteObjectARB(gl_shaders[i].prgId));
+ checkGLcall("glDeleteObjectARB");
+ }
+ HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.vs);
+
+ break;
+ }
+
+ case WINED3D_SHADER_TYPE_GEOMETRY:
+ {
+ struct glsl_gs_compiled_shader *gl_shaders = shader_data->gl_shaders.gs;
+
+ LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs,
+ struct glsl_shader_prog_link, gs.shader_entry)
+ {
+ delete_glsl_program_entry(priv, gl_info, entry
+#ifdef VBOX_WITH_WINE_FIX_SHADERCLEANUP
+ , context
+#endif
+ );
+ }
+
+ for (i = 0; i < shader_data->num_gl_shaders; ++i)
+ {
+ TRACE("Deleting geometry shader %u.\n", gl_shaders[i].id);
+ if (priv->glsl_program && priv->glsl_program->gs.id == gl_shaders[i].id)
+ shader_glsl_disable(priv, context);
+ GL_EXTCALL(glDeleteObjectARB(gl_shaders[i].id));
+ checkGLcall("glDeleteObjectARB");
+ }
+ HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders.gs);
+
+ break;
+ }
+
+ default:
+ ERR("Unhandled shader type %#x.\n", shader->reg_maps.shader_version.type);
+ break;
+ }
+ }
+
+ HeapFree(GetProcessHeap(), 0, shader->backend_data);
+ shader->backend_data = NULL;
+
+ context_release(context);
+}
+
+static int glsl_program_key_compare(const void *key, const struct wine_rb_entry *entry)
+{
+ const struct glsl_program_key *k = key;
+ const struct glsl_shader_prog_link *prog = WINE_RB_ENTRY_VALUE(entry,
+ const struct glsl_shader_prog_link, program_lookup_entry);
+
+ if (k->vs_id > prog->vs.id) return 1;
+ else if (k->vs_id < prog->vs.id) return -1;
+
+ if (k->gs_id > prog->gs.id) return 1;
+ else if (k->gs_id < prog->gs.id) return -1;
+
+ if (k->ps_id > prog->ps.id) return 1;
+ else if (k->ps_id < prog->ps.id) return -1;
+
+ return 0;
+}
+
+static BOOL constant_heap_init(struct constant_heap *heap, unsigned int constant_count)
+{
+ SIZE_T size = (constant_count + 1) * sizeof(*heap->entries) + constant_count * sizeof(*heap->positions);
+ void *mem = HeapAlloc(GetProcessHeap(), 0, size);
+
+ if (!mem)
+ {
+ ERR("Failed to allocate memory\n");
+ return FALSE;
+ }
+
+ heap->entries = mem;
+ heap->entries[1].version = 0;
+ heap->positions = (unsigned int *)(heap->entries + constant_count + 1);
+ heap->size = 1;
+
+ return TRUE;
+}
+
+static void constant_heap_free(struct constant_heap *heap)
+{
+ HeapFree(GetProcessHeap(), 0, heap->entries);
+}
+
+static const struct wine_rb_functions wined3d_glsl_program_rb_functions =
+{
+ wined3d_rb_alloc,
+ wined3d_rb_realloc,
+ wined3d_rb_free,
+ glsl_program_key_compare,
+};
+
+static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe,
+ const struct fragment_pipeline *fragment_pipe)
+{
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ struct shader_glsl_priv *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct shader_glsl_priv));
+ SIZE_T stack_size = wined3d_log2i(max(gl_info->limits.glsl_vs_float_constants,
+ gl_info->limits.glsl_ps_float_constants)) + 1;
+ struct fragment_caps fragment_caps;
+ void *vertex_priv, *fragment_priv;
+
+ if (!(vertex_priv = vertex_pipe->vp_alloc(&glsl_shader_backend, priv)))
+ {
+ ERR("Failed to initialize vertex pipe.\n");
+ HeapFree(GetProcessHeap(), 0, priv);
+ return E_FAIL;
+ }
+
+ if (!(fragment_priv = fragment_pipe->alloc_private(&glsl_shader_backend, priv)))
+ {
+ ERR("Failed to initialize fragment pipe.\n");
+ vertex_pipe->vp_free(device);
+ HeapFree(GetProcessHeap(), 0, priv);
+ return E_FAIL;
+ }
+
+ if (!shader_buffer_init(&priv->shader_buffer))
+ {
+ ERR("Failed to initialize shader buffer.\n");
+ goto fail;
+ }
+
+ priv->stack = HeapAlloc(GetProcessHeap(), 0, stack_size * sizeof(*priv->stack));
+ if (!priv->stack)
+ {
+ ERR("Failed to allocate memory.\n");
+ goto fail;
+ }
+
+ if (!constant_heap_init(&priv->vconst_heap, gl_info->limits.glsl_vs_float_constants))
+ {
+ ERR("Failed to initialize vertex shader constant heap\n");
+ goto fail;
+ }
+
+ if (!constant_heap_init(&priv->pconst_heap, gl_info->limits.glsl_ps_float_constants))
+ {
+ ERR("Failed to initialize pixel shader constant heap\n");
+ goto fail;
+ }
+
+ if (wine_rb_init(&priv->program_lookup, &wined3d_glsl_program_rb_functions) == -1)
+ {
+ ERR("Failed to initialize rbtree.\n");
+ goto fail;
+ }
+
+ priv->next_constant_version = 1;
+ priv->vertex_pipe = vertex_pipe;
+ priv->fragment_pipe = fragment_pipe;
+ fragment_pipe->get_caps(gl_info, &fragment_caps);
+ priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL;
+
+ device->vertex_priv = vertex_priv;
+ device->fragment_priv = fragment_priv;
+ device->shader_priv = priv;
+
+ return WINED3D_OK;
+
+fail:
+ constant_heap_free(&priv->pconst_heap);
+ constant_heap_free(&priv->vconst_heap);
+ HeapFree(GetProcessHeap(), 0, priv->stack);
+ shader_buffer_free(&priv->shader_buffer);
+ fragment_pipe->free_private(device);
+ vertex_pipe->vp_free(device);
+ HeapFree(GetProcessHeap(), 0, priv);
+ return E_OUTOFMEMORY;
+}
+
+/* Context activation is done by the caller. */
+static void shader_glsl_free(struct wined3d_device *device)
+{
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ struct shader_glsl_priv *priv = device->shader_priv;
+ int i;
+
+ for (i = 0; i < tex_type_count; ++i)
+ {
+ if (priv->depth_blt_program_full[i])
+ {
+ GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program_full[i]));
+ }
+ if (priv->depth_blt_program_masked[i])
+ {
+ GL_EXTCALL(glDeleteObjectARB(priv->depth_blt_program_masked[i]));
+ }
+ }
+
+ wine_rb_destroy(&priv->program_lookup, NULL, NULL);
+ constant_heap_free(&priv->pconst_heap);
+ constant_heap_free(&priv->vconst_heap);
+ HeapFree(GetProcessHeap(), 0, priv->stack);
+ shader_buffer_free(&priv->shader_buffer);
+ priv->fragment_pipe->free_private(device);
+ priv->vertex_pipe->vp_free(device);
+
+ HeapFree(GetProcessHeap(), 0, device->shader_priv);
+ device->shader_priv = NULL;
+}
+
+static void shader_glsl_context_destroyed(void *shader_priv, const struct wined3d_context *context) {}
+
+static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *caps)
+{
+ UINT shader_model;
+
+ if (gl_info->supported[EXT_GPU_SHADER4] && gl_info->supported[ARB_SHADER_BIT_ENCODING]
+ && gl_info->supported[ARB_GEOMETRY_SHADER4] && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 50)
+ && gl_info->supported[ARB_DRAW_ELEMENTS_BASE_VERTEX] && gl_info->supported[ARB_DRAW_INSTANCED])
+ shader_model = 4;
+ /* ARB_shader_texture_lod or EXT_gpu_shader4 is required for the SM3
+ * texldd and texldl instructions. */
+ else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD] || gl_info->supported[EXT_GPU_SHADER4])
+ shader_model = 3;
+ else
+ shader_model = 2;
+ TRACE("Shader model %u.\n", shader_model);
+
+ caps->vs_version = min(wined3d_settings.max_sm_vs, shader_model);
+ caps->gs_version = min(wined3d_settings.max_sm_gs, shader_model);
+ caps->ps_version = min(wined3d_settings.max_sm_ps, shader_model);
+
+ caps->vs_uniform_count = gl_info->limits.glsl_vs_float_constants;
+ caps->ps_uniform_count = gl_info->limits.glsl_ps_float_constants;
+
+ /* FIXME: The following line is card dependent. -8.0 to 8.0 is the
+ * Direct3D minimum requirement.
+ *
+ * Both GL_ARB_fragment_program and GLSL require a "maximum representable magnitude"
+ * of colors to be 2^10, and 2^32 for other floats. Should we use 1024 here?
+ *
+ * The problem is that the refrast clamps temporary results in the shader to
+ * [-MaxValue;+MaxValue]. If the card's max value is bigger than the one we advertize here,
+ * then applications may miss the clamping behavior. On the other hand, if it is smaller,
+ * the shader will generate incorrect results too. Unfortunately, GL deliberately doesn't
+ * offer a way to query this.
+ */
+ caps->ps_1x_max_value = 8.0;
+
+ /* Ideally we'd only set caps like sRGB writes here if supported by both
+ * the shader backend and the fragment pipe, but we can get called before
+ * shader_glsl_alloc(). */
+ caps->wined3d_caps = WINED3D_SHADER_CAP_VS_CLIPPING
+ | WINED3D_SHADER_CAP_SRGB_WRITE;
+}
+
+static BOOL shader_glsl_color_fixup_supported(struct color_fixup_desc fixup)
+{
+ if (TRACE_ON(d3d_shader) && TRACE_ON(d3d))
+ {
+ TRACE("Checking support for fixup:\n");
+ dump_color_fixup_desc(fixup);
+ }
+
+ /* We support everything except YUV conversions. */
+ if (!is_complex_fixup(fixup))
+ {
+ TRACE("[OK]\n");
+ return TRUE;
+ }
+
+ TRACE("[FAILED]\n");
+ return FALSE;
+}
+
+static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TABLE_SIZE] =
+{
+ /* WINED3DSIH_ABS */ shader_glsl_map2gl,
+ /* WINED3DSIH_ADD */ shader_glsl_binop,
+ /* WINED3DSIH_AND */ shader_glsl_binop,
+ /* WINED3DSIH_BEM */ shader_glsl_bem,
+ /* WINED3DSIH_BREAK */ shader_glsl_break,
+ /* WINED3DSIH_BREAKC */ shader_glsl_breakc,
+ /* WINED3DSIH_BREAKP */ shader_glsl_breakp,
+ /* WINED3DSIH_CALL */ shader_glsl_call,
+ /* WINED3DSIH_CALLNZ */ shader_glsl_callnz,
+ /* WINED3DSIH_CMP */ shader_glsl_conditional_move,
+ /* WINED3DSIH_CND */ shader_glsl_cnd,
+ /* WINED3DSIH_CRS */ shader_glsl_cross,
+ /* WINED3DSIH_CUT */ shader_glsl_cut,
+ /* WINED3DSIH_DCL */ shader_glsl_nop,
+ /* WINED3DSIH_DCL_CONSTANT_BUFFER */ shader_glsl_nop,
+ /* WINED3DSIH_DCL_INPUT_PRIMITIVE */ shader_glsl_nop,
+ /* WINED3DSIH_DCL_OUTPUT_TOPOLOGY */ shader_glsl_nop,
+ /* WINED3DSIH_DCL_VERTICES_OUT */ shader_glsl_nop,
+ /* WINED3DSIH_DEF */ shader_glsl_nop,
+ /* WINED3DSIH_DEFB */ shader_glsl_nop,
+ /* WINED3DSIH_DEFI */ shader_glsl_nop,
+ /* WINED3DSIH_DIV */ shader_glsl_binop,
+ /* WINED3DSIH_DP2ADD */ shader_glsl_dp2add,
+ /* WINED3DSIH_DP3 */ shader_glsl_dot,
+ /* WINED3DSIH_DP4 */ shader_glsl_dot,
+ /* WINED3DSIH_DST */ shader_glsl_dst,
+ /* WINED3DSIH_DSX */ shader_glsl_map2gl,
+ /* WINED3DSIH_DSY */ shader_glsl_map2gl,
+ /* WINED3DSIH_ELSE */ shader_glsl_else,
+ /* WINED3DSIH_EMIT */ shader_glsl_emit,
+ /* WINED3DSIH_ENDIF */ shader_glsl_end,
+ /* WINED3DSIH_ENDLOOP */ shader_glsl_end,
+ /* WINED3DSIH_ENDREP */ shader_glsl_end,
+ /* WINED3DSIH_EQ */ shader_glsl_relop,
+ /* WINED3DSIH_EXP */ shader_glsl_map2gl,
+ /* WINED3DSIH_EXPP */ shader_glsl_expp,
+ /* WINED3DSIH_FRC */ shader_glsl_map2gl,
+ /* WINED3DSIH_FTOI */ shader_glsl_to_int,
+ /* WINED3DSIH_GE */ shader_glsl_relop,
+ /* WINED3DSIH_IADD */ shader_glsl_binop,
+ /* WINED3DSIH_IEQ */ NULL,
+ /* WINED3DSIH_IF */ shader_glsl_if,
+ /* WINED3DSIH_IFC */ shader_glsl_ifc,
+ /* WINED3DSIH_IGE */ shader_glsl_relop,
+ /* WINED3DSIH_IMUL */ shader_glsl_imul,
+ /* WINED3DSIH_ITOF */ shader_glsl_to_float,
+ /* WINED3DSIH_LABEL */ shader_glsl_label,
+ /* WINED3DSIH_LD */ NULL,
+ /* WINED3DSIH_LIT */ shader_glsl_lit,
+ /* WINED3DSIH_LOG */ shader_glsl_log,
+ /* WINED3DSIH_LOGP */ shader_glsl_log,
+ /* WINED3DSIH_LOOP */ shader_glsl_loop,
+ /* WINED3DSIH_LRP */ shader_glsl_lrp,
+ /* WINED3DSIH_LT */ shader_glsl_relop,
+ /* WINED3DSIH_M3x2 */ shader_glsl_mnxn,
+ /* WINED3DSIH_M3x3 */ shader_glsl_mnxn,
+ /* WINED3DSIH_M3x4 */ shader_glsl_mnxn,
+ /* WINED3DSIH_M4x3 */ shader_glsl_mnxn,
+ /* WINED3DSIH_M4x4 */ shader_glsl_mnxn,
+ /* WINED3DSIH_MAD */ shader_glsl_mad,
+ /* WINED3DSIH_MAX */ shader_glsl_map2gl,
+ /* WINED3DSIH_MIN */ shader_glsl_map2gl,
+ /* WINED3DSIH_MOV */ shader_glsl_mov,
+ /* WINED3DSIH_MOVA */ shader_glsl_mov,
+ /* WINED3DSIH_MOVC */ shader_glsl_conditional_move,
+ /* WINED3DSIH_MUL */ shader_glsl_binop,
+ /* WINED3DSIH_NOP */ shader_glsl_nop,
+ /* WINED3DSIH_NRM */ shader_glsl_nrm,
+ /* WINED3DSIH_PHASE */ shader_glsl_nop,
+ /* WINED3DSIH_POW */ shader_glsl_pow,
+ /* WINED3DSIH_RCP */ shader_glsl_rcp,
+ /* WINED3DSIH_REP */ shader_glsl_rep,
+ /* WINED3DSIH_RET */ shader_glsl_ret,
+ /* WINED3DSIH_ROUND_NI */ shader_glsl_map2gl,
+ /* WINED3DSIH_RSQ */ shader_glsl_rsq,
+ /* WINED3DSIH_SAMPLE */ NULL,
+ /* WINED3DSIH_SAMPLE_GRAD */ NULL,
+ /* WINED3DSIH_SAMPLE_LOD */ NULL,
+ /* WINED3DSIH_SETP */ NULL,
+ /* WINED3DSIH_SGE */ shader_glsl_compare,
+ /* WINED3DSIH_SGN */ shader_glsl_sgn,
+ /* WINED3DSIH_SINCOS */ shader_glsl_sincos,
+ /* WINED3DSIH_SLT */ shader_glsl_compare,
+ /* WINED3DSIH_SQRT */ NULL,
+ /* WINED3DSIH_SUB */ shader_glsl_binop,
+ /* WINED3DSIH_TEX */ shader_glsl_tex,
+ /* WINED3DSIH_TEXBEM */ shader_glsl_texbem,
+ /* WINED3DSIH_TEXBEML */ shader_glsl_texbem,
+ /* WINED3DSIH_TEXCOORD */ shader_glsl_texcoord,
+ /* WINED3DSIH_TEXDEPTH */ shader_glsl_texdepth,
+ /* WINED3DSIH_TEXDP3 */ shader_glsl_texdp3,
+ /* WINED3DSIH_TEXDP3TEX */ shader_glsl_texdp3tex,
+ /* WINED3DSIH_TEXKILL */ shader_glsl_texkill,
+ /* WINED3DSIH_TEXLDD */ shader_glsl_texldd,
+ /* WINED3DSIH_TEXLDL */ shader_glsl_texldl,
+ /* WINED3DSIH_TEXM3x2DEPTH */ shader_glsl_texm3x2depth,
+ /* WINED3DSIH_TEXM3x2PAD */ shader_glsl_texm3x2pad,
+ /* WINED3DSIH_TEXM3x2TEX */ shader_glsl_texm3x2tex,
+ /* WINED3DSIH_TEXM3x3 */ shader_glsl_texm3x3,
+ /* WINED3DSIH_TEXM3x3DIFF */ NULL,
+ /* WINED3DSIH_TEXM3x3PAD */ shader_glsl_texm3x3pad,
+ /* WINED3DSIH_TEXM3x3SPEC */ shader_glsl_texm3x3spec,
+ /* WINED3DSIH_TEXM3x3TEX */ shader_glsl_texm3x3tex,
+ /* WINED3DSIH_TEXM3x3VSPEC */ shader_glsl_texm3x3vspec,
+ /* WINED3DSIH_TEXREG2AR */ shader_glsl_texreg2ar,
+ /* WINED3DSIH_TEXREG2GB */ shader_glsl_texreg2gb,
+ /* WINED3DSIH_TEXREG2RGB */ shader_glsl_texreg2rgb,
+ /* WINED3DSIH_UDIV */ shader_glsl_udiv,
+ /* WINED3DSIH_USHR */ shader_glsl_binop,
+ /* WINED3DSIH_UTOF */ shader_glsl_to_float,
+ /* WINED3DSIH_XOR */ shader_glsl_binop,
+};
+
+static void shader_glsl_handle_instruction(const struct wined3d_shader_instruction *ins) {
+ SHADER_HANDLER hw_fct;
+
+ /* Select handler */
+ hw_fct = shader_glsl_instruction_handler_table[ins->handler_idx];
+
+ /* Unhandled opcode */
+ if (!hw_fct)
+ {
+ FIXME("Backend can't handle opcode %#x\n", ins->handler_idx);
+ return;
+ }
+ hw_fct(ins);
+
+ shader_glsl_add_instruction_modifiers(ins);
+}
+
+static BOOL shader_glsl_has_ffp_proj_control(void *shader_priv)
+{
+ struct shader_glsl_priv *priv = shader_priv;
+
+ return priv->ffp_proj_control;
+}
+
+const struct wined3d_shader_backend_ops glsl_shader_backend =
+{
+ shader_glsl_handle_instruction,
+ shader_glsl_select,
+ shader_glsl_disable,
+ shader_glsl_select_depth_blt,
+ shader_glsl_deselect_depth_blt,
+ shader_glsl_update_float_vertex_constants,
+ shader_glsl_update_float_pixel_constants,
+ shader_glsl_load_constants,
+ shader_glsl_load_np2fixup_constants,
+ shader_glsl_destroy,
+ shader_glsl_alloc,
+ shader_glsl_free,
+ shader_glsl_context_destroyed,
+ shader_glsl_get_caps,
+ shader_glsl_color_fixup_supported,
+ shader_glsl_has_ffp_proj_control,
+};
+
+static void glsl_vertex_pipe_vp_enable(const struct wined3d_gl_info *gl_info, BOOL enable)
+{
+ if (enable)
+ gl_info->gl_ops.gl.p_glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
+ else
+ gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
+ checkGLcall("GL_VERTEX_PROGRAM_POINT_SIZE_ARB");
+}
+
+static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
+{
+ caps->xyzrhw = TRUE;
+ caps->max_active_lights = gl_info->limits.lights;
+ caps->max_vertex_blend_matrices = 0;
+ caps->max_vertex_blend_matrix_index = 0;
+ caps->vertex_processing_caps = WINED3DVTXPCAPS_TEXGEN
+ | WINED3DVTXPCAPS_MATERIALSOURCE7
+ | WINED3DVTXPCAPS_VERTEXFOG
+ | WINED3DVTXPCAPS_DIRECTIONALLIGHTS
+ | WINED3DVTXPCAPS_POSITIONALLIGHTS
+ | WINED3DVTXPCAPS_LOCALVIEWER
+ | WINED3DVTXPCAPS_TEXGEN_SPHEREMAP;
+ caps->fvf_caps = WINED3DFVFCAPS_PSIZE | 8; /* 8 texture coordinates. */
+ caps->max_user_clip_planes = gl_info->limits.clipplanes;
+ caps->raster_caps = WINED3DPRASTERCAPS_FOGRANGE;
+}
+
+static void *glsl_vertex_pipe_vp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
+{
+ struct shader_glsl_priv *priv;
+
+ if (shader_backend == &glsl_shader_backend)
+ {
+ priv = shader_priv;
+
+ if (wine_rb_init(&priv->ffp_vertex_shaders, &wined3d_ffp_vertex_program_rb_functions) == -1)
+ {
+ ERR("Failed to initialize rbtree.\n");
+ return NULL;
+ }
+
+ return priv;
+ }
+
+ FIXME("GLSL vertex pipe without GLSL shader backend not implemented.\n");
+
+ return NULL;
+}
+
+static void shader_glsl_free_ffp_vertex_shader(struct wine_rb_entry *entry, void *context)
+{
+ struct glsl_ffp_vertex_shader *shader = WINE_RB_ENTRY_VALUE(entry,
+ struct glsl_ffp_vertex_shader, desc.entry);
+ struct glsl_shader_prog_link *program, *program2;
+ struct glsl_ffp_destroy_ctx *ctx = context;
+
+ LIST_FOR_EACH_ENTRY_SAFE(program, program2, &shader->linked_programs,
+ struct glsl_shader_prog_link, vs.shader_entry)
+ {
+ delete_glsl_program_entry(ctx->priv, ctx->gl_info, program
+#ifdef VBOX_WITH_WINE_FIX_SHADERCLEANUP
+ , ctx->context
+#endif
+ );
+ }
+ ctx->gl_info->gl_ops.ext.p_glDeleteObjectARB(shader->id);
+ HeapFree(GetProcessHeap(), 0, shader);
+}
+
+/* Context activation is done by the caller. */
+static void glsl_vertex_pipe_vp_free(struct wined3d_device *device)
+{
+ struct shader_glsl_priv *priv = device->vertex_priv;
+ struct glsl_ffp_destroy_ctx ctx;
+
+ ctx.priv = priv;
+ ctx.gl_info = &device->adapter->gl_info;
+#ifdef VBOX_WITH_WINE_FIX_SHADERCLEANUP
+ ctx.context = device->contexts[0];
+#endif
+ wine_rb_destroy(&priv->ffp_vertex_shaders, shader_glsl_free_ffp_vertex_shader, &ctx);
+}
+
+static void glsl_vertex_pipe_shader(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id)
+{
+ context->select_shader = 1;
+}
+
+static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] =
+{
+ {STATE_VDECL, {STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE },
+ {STATE_VSHADER, {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_MATERIAL, {STATE_RENDER(WINED3D_RS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_SPECULARENABLE), {STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_specularenable }, WINED3D_GL_EXT_NONE },
+ /* Clip planes */
+ {STATE_CLIPPLANE(0), {STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(1), {STATE_CLIPPLANE(1), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(2), {STATE_CLIPPLANE(2), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(3), {STATE_CLIPPLANE(3), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(4), {STATE_CLIPPLANE(4), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(5), {STATE_CLIPPLANE(5), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(6), {STATE_CLIPPLANE(6), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(7), {STATE_CLIPPLANE(7), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(8), {STATE_CLIPPLANE(8), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(9), {STATE_CLIPPLANE(9), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(10), {STATE_CLIPPLANE(10), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(11), {STATE_CLIPPLANE(11), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(12), {STATE_CLIPPLANE(12), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(13), {STATE_CLIPPLANE(13), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(14), {STATE_CLIPPLANE(14), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(15), {STATE_CLIPPLANE(15), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(16), {STATE_CLIPPLANE(16), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(17), {STATE_CLIPPLANE(17), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(18), {STATE_CLIPPLANE(18), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(19), {STATE_CLIPPLANE(19), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(20), {STATE_CLIPPLANE(20), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(21), {STATE_CLIPPLANE(21), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(22), {STATE_CLIPPLANE(22), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(23), {STATE_CLIPPLANE(23), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(24), {STATE_CLIPPLANE(24), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(25), {STATE_CLIPPLANE(25), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(26), {STATE_CLIPPLANE(26), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(27), {STATE_CLIPPLANE(27), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(28), {STATE_CLIPPLANE(28), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(29), {STATE_CLIPPLANE(29), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(30), {STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(31), {STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE },
+ /* Lights */
+ {STATE_LIGHT_TYPE, {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(0), {STATE_ACTIVELIGHT(0), light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(1), {STATE_ACTIVELIGHT(1), light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(2), {STATE_ACTIVELIGHT(2), light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(3), {STATE_ACTIVELIGHT(3), light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(4), {STATE_ACTIVELIGHT(4), light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(5), {STATE_ACTIVELIGHT(5), light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(6), {STATE_ACTIVELIGHT(6), light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(7), {STATE_ACTIVELIGHT(7), light }, WINED3D_GL_EXT_NONE },
+ /* Viewport */
+ {STATE_VIEWPORT, {STATE_VIEWPORT, viewport_vertexpart }, WINED3D_GL_EXT_NONE },
+ /* Transform states */
+ {STATE_TRANSFORM(WINED3D_TS_VIEW), {STATE_TRANSFORM(WINED3D_TS_VIEW), transform_view }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_PROJECTION), {STATE_TRANSFORM(WINED3D_TS_PROJECTION), transform_projection }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE0), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE1), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE2), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE3), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE4), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE5), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE6), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE7), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)), transform_world }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ /* Fog */
+ {STATE_RENDER(WINED3D_RS_FOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), glsl_vertex_pipe_shader}, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_CLIPPING), {STATE_RENDER(WINED3D_RS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), {STATE_RENDER(WINED3D_RS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_LIGHTING), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_AMBIENT), {STATE_RENDER(WINED3D_RS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_COLORVERTEX), {STATE_RENDER(WINED3D_RS_COLORVERTEX), glsl_vertex_pipe_shader}, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_LOCALVIEWER), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_VERTEXBLEND), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE },
+ {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSCALE_A), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSCALE_B), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSCALE_C), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_TWEENFACTOR), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ /* Samplers for NP2 texture matrix adjustions. They are not needed if
+ * GL_ARB_texture_non_power_of_two is supported, so register a NULL state
+ * handler in that case to get the vertex part of sampler() skipped (VTF
+ * is handled in the misc states). Otherwise, register
+ * sampler_texmatrix(), which takes care of updating the texture matrix. */
+ {STATE_SAMPLER(0), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(0), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(0), {STATE_SAMPLER(0), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(1), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(1), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(1), {STATE_SAMPLER(1), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(2), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(2), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(2), {STATE_SAMPLER(2), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(3), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(3), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(3), {STATE_SAMPLER(3), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(4), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(4), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(4), {STATE_SAMPLER(4), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(5), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(5), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(5), {STATE_SAMPLER(5), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(6), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(6), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(6), {STATE_SAMPLER(6), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(7), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(7), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(7), {STATE_SAMPLER(7), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_POINT_SIZE_ENABLE, {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {0 /* Terminate */, {0, NULL }, WINED3D_GL_EXT_NONE },
+};
+
+/* TODO:
+ * - This currently depends on GL fixed function functions to set things
+ * like light parameters. Ideally we'd use regular uniforms for that.
+ * - In part because of the previous point, much of this is modelled after
+ * GL fixed function, and has much of the same limitations. For example,
+ * D3D spot lights are slightly different from GL spot lights.
+ * - We can now implement drawing transformed vertices using the GLSL pipe,
+ * instead of using the immediate mode fallback.
+ * - Similarly, we don't need the fallback for certain combinations of
+ * material sources anymore.
+ * - Implement vertex blending and vertex tweening.
+ * - Handle WINED3D_TSS_TEXCOORD_INDEX in the shader, instead of duplicating
+ * attribute arrays in load_tex_coords().
+ * - Per-vertex point sizes. */
+const struct wined3d_vertex_pipe_ops glsl_vertex_pipe =
+{
+ glsl_vertex_pipe_vp_enable,
+ glsl_vertex_pipe_vp_get_caps,
+ glsl_vertex_pipe_vp_alloc,
+ glsl_vertex_pipe_vp_free,
+ glsl_vertex_pipe_vp_states,
+};
+
+static void glsl_fragment_pipe_enable(const struct wined3d_gl_info *gl_info, BOOL enable)
+{
+ /* Nothing to do. */
+}
+
+static void glsl_fragment_pipe_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
+{
+ caps->wined3d_caps = WINED3D_FRAGMENT_CAP_PROJ_CONTROL
+ | WINED3D_FRAGMENT_CAP_SRGB_WRITE;
+ caps->PrimitiveMiscCaps = WINED3DPMISCCAPS_TSSARGTEMP;
+ caps->TextureOpCaps = WINED3DTEXOPCAPS_DISABLE
+ | WINED3DTEXOPCAPS_SELECTARG1
+ | WINED3DTEXOPCAPS_SELECTARG2
+ | WINED3DTEXOPCAPS_MODULATE4X
+ | WINED3DTEXOPCAPS_MODULATE2X
+ | WINED3DTEXOPCAPS_MODULATE
+ | WINED3DTEXOPCAPS_ADDSIGNED2X
+ | WINED3DTEXOPCAPS_ADDSIGNED
+ | WINED3DTEXOPCAPS_ADD
+ | WINED3DTEXOPCAPS_SUBTRACT
+ | WINED3DTEXOPCAPS_ADDSMOOTH
+ | WINED3DTEXOPCAPS_BLENDCURRENTALPHA
+ | WINED3DTEXOPCAPS_BLENDFACTORALPHA
+ | WINED3DTEXOPCAPS_BLENDTEXTUREALPHA
+ | WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA
+ | WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM
+ | WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
+ | WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
+ | WINED3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA
+ | WINED3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR
+ | WINED3DTEXOPCAPS_DOTPRODUCT3
+ | WINED3DTEXOPCAPS_MULTIPLYADD
+ | WINED3DTEXOPCAPS_LERP
+ | WINED3DTEXOPCAPS_BUMPENVMAP
+ | WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE;
+ caps->MaxTextureBlendStages = 8;
+ caps->MaxSimultaneousTextures = min(gl_info->limits.fragment_samplers, 8);
+}
+
+static void *glsl_fragment_pipe_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
+{
+ struct shader_glsl_priv *priv;
+
+ if (shader_backend == &glsl_shader_backend)
+ {
+ priv = shader_priv;
+
+ if (wine_rb_init(&priv->ffp_fragment_shaders, &wined3d_ffp_frag_program_rb_functions) == -1)
+ {
+ ERR("Failed to initialize rbtree.\n");
+ return NULL;
+ }
+
+ return priv;
+ }
+
+ FIXME("GLSL fragment pipe without GLSL shader backend not implemented.\n");
+
+ return NULL;
+}
+
+static void shader_glsl_free_ffp_fragment_shader(struct wine_rb_entry *entry, void *context)
+{
+ struct glsl_ffp_fragment_shader *shader = WINE_RB_ENTRY_VALUE(entry,
+ struct glsl_ffp_fragment_shader, entry.entry);
+ struct glsl_shader_prog_link *program, *program2;
+ struct glsl_ffp_destroy_ctx *ctx = context;
+
+ LIST_FOR_EACH_ENTRY_SAFE(program, program2, &shader->linked_programs,
+ struct glsl_shader_prog_link, ps.shader_entry)
+ {
+ delete_glsl_program_entry(ctx->priv, ctx->gl_info, program
+#ifdef VBOX_WITH_WINE_FIX_SHADERCLEANUP
+ , ctx->context
+#endif
+ );
+ }
+ ctx->gl_info->gl_ops.ext.p_glDeleteObjectARB(shader->id);
+ HeapFree(GetProcessHeap(), 0, shader);
+}
+
+/* Context activation is done by the caller. */
+static void glsl_fragment_pipe_free(struct wined3d_device *device)
+{
+ struct shader_glsl_priv *priv = device->fragment_priv;
+ struct glsl_ffp_destroy_ctx ctx;
+
+ ctx.priv = priv;
+ ctx.gl_info = &device->adapter->gl_info;
+#ifdef VBOX_WITH_WINE_FIX_SHADERCLEANUP
+ ctx.context = device->contexts[0];
+#endif
+ wine_rb_destroy(&priv->ffp_fragment_shaders, shader_glsl_free_ffp_fragment_shader, &ctx);
+}
+
+static void glsl_fragment_pipe_shader(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id)
+{
+ context->last_was_pshader = use_ps(state);
+
+ context->select_shader = 1;
+ context->load_constants = 1;
+}
+
+static void glsl_fragment_pipe_fog(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id)
+{
+ BOOL use_vshader = use_vs(state);
+ enum fogsource new_source;
+ DWORD fogstart = state->render_states[WINED3D_RS_FOGSTART];
+ DWORD fogend = state->render_states[WINED3D_RS_FOGEND];
+
+ context->select_shader = 1;
+ context->load_constants = 1;
+
+ if (!state->render_states[WINED3D_RS_FOGENABLE])
+ return;
+
+ if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
+ {
+ if (use_vshader)
+ new_source = FOGSOURCE_VS;
+ else if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE || context->last_was_rhw)
+ new_source = FOGSOURCE_COORD;
+ else
+ new_source = FOGSOURCE_FFP;
+ }
+ else
+ {
+ new_source = FOGSOURCE_FFP;
+ }
+
+ if (new_source != context->fog_source || fogstart == fogend)
+ {
+ context->fog_source = new_source;
+ state_fogstartend(context, state, STATE_RENDER(WINED3D_RS_FOGSTART));
+ }
+}
+
+static void glsl_fragment_pipe_tex_transform(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id)
+{
+ context->select_shader = 1;
+ context->load_constants = 1;
+}
+
+static void glsl_fragment_pipe_invalidate_constants(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id)
+{
+ context->load_constants = 1;
+}
+
+static const struct StateEntryTemplate glsl_fragment_pipe_state_template[] =
+{
+ {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_PIXELSHADER, {STATE_PIXELSHADER, glsl_fragment_pipe_shader }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), glsl_fragment_pipe_fog }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGSTART), {STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGEND), {STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), state_srgbwrite }, ARB_FRAMEBUFFER_SRGB},
+ {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), {STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGCOLOR), {STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGDENSITY), {STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_SPECULARENABLE), {STATE_RENDER(WINED3D_RS_SPECULARENABLE), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
+ {0 /* Terminate */, {0, 0 }, WINED3D_GL_EXT_NONE },
+};
+
+const struct fragment_pipeline glsl_fragment_pipe =
+{
+ glsl_fragment_pipe_enable,
+ glsl_fragment_pipe_get_caps,
+ glsl_fragment_pipe_alloc,
+ glsl_fragment_pipe_free,
+ shader_glsl_color_fixup_supported,
+ glsl_fragment_pipe_state_template,
+};
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/nvidia_texture_shader.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/nvidia_texture_shader.c
new file mode 100644
index 00000000..4083de9b
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/nvidia_texture_shader.c
@@ -0,0 +1,921 @@
+/*
+ * Fixed function pipeline replacement using GL_NV_register_combiners
+ * and GL_NV_texture_shader
+ *
+ * Copyright 2006 Henri Verbeet
+ * Copyright 2008 Stefan Dösinger(for CodeWeavers)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <math.h>
+#include <stdio.h>
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+
+/* Context activation for state handlers is done by the caller. */
+
+static void nvts_activate_dimensions(const struct wined3d_state *state, DWORD stage, struct wined3d_context *context)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ BOOL bumpmap = FALSE;
+
+ if (stage > 0
+ && (state->texture_states[stage - 1][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_BUMPENVMAP_LUMINANCE
+ || state->texture_states[stage - 1][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_BUMPENVMAP))
+ {
+ bumpmap = TRUE;
+ context->texShaderBumpMap |= (1 << stage);
+ } else {
+ context->texShaderBumpMap &= ~(1 << stage);
+ }
+
+ if (state->textures[stage])
+ {
+ switch (state->textures[stage]->target)
+ {
+ case GL_TEXTURE_2D:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV,
+ bumpmap ? GL_OFFSET_TEXTURE_2D_NV : GL_TEXTURE_2D);
+ checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, ...)");
+ break;
+ case GL_TEXTURE_RECTANGLE_ARB:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV,
+ bumpmap ? GL_OFFSET_TEXTURE_2D_NV : GL_TEXTURE_RECTANGLE_ARB);
+ checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, ...)");
+ break;
+ case GL_TEXTURE_3D:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D);
+ checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D)");
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB);
+ checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB)");
+ break;
+ }
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
+ checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE)");
+ }
+}
+
+struct tex_op_args
+{
+ GLenum input[3];
+ GLenum mapping[3];
+ GLenum component_usage[3];
+};
+
+static GLenum d3dta_to_combiner_input(DWORD d3dta, DWORD stage, INT texture_idx) {
+ switch (d3dta) {
+ case WINED3DTA_DIFFUSE:
+ return GL_PRIMARY_COLOR_NV;
+
+ case WINED3DTA_CURRENT:
+ if (stage) return GL_SPARE0_NV;
+ else return GL_PRIMARY_COLOR_NV;
+
+ case WINED3DTA_TEXTURE:
+ if (texture_idx > -1) return GL_TEXTURE0_ARB + texture_idx;
+ else return GL_PRIMARY_COLOR_NV;
+
+ case WINED3DTA_TFACTOR:
+ return GL_CONSTANT_COLOR0_NV;
+
+ case WINED3DTA_SPECULAR:
+ return GL_SECONDARY_COLOR_NV;
+
+ case WINED3DTA_TEMP:
+ return GL_SPARE1_NV;
+
+ case WINED3DTA_CONSTANT:
+ /* TODO: Support per stage constants (WINED3D_TSS_CONSTANT, NV_register_combiners2) */
+ FIXME("WINED3DTA_CONSTANT, not properly supported.\n");
+ return GL_CONSTANT_COLOR1_NV;
+
+ default:
+ FIXME("Unrecognized texture arg %#x\n", d3dta);
+ return GL_TEXTURE;
+ }
+}
+
+static GLenum invert_mapping(GLenum mapping) {
+ if (mapping == GL_UNSIGNED_INVERT_NV) return GL_UNSIGNED_IDENTITY_NV;
+ else if (mapping == GL_UNSIGNED_IDENTITY_NV) return GL_UNSIGNED_INVERT_NV;
+
+ FIXME("Unhandled mapping %#x\n", mapping);
+ return mapping;
+}
+
+static void get_src_and_opr_nvrc(DWORD stage, DWORD arg, BOOL is_alpha, GLenum* input, GLenum* mapping, GLenum *component_usage, INT texture_idx) {
+ /* The WINED3DTA_COMPLEMENT flag specifies the complement of the input should
+ * be used. */
+ if (arg & WINED3DTA_COMPLEMENT) *mapping = GL_UNSIGNED_INVERT_NV;
+ else *mapping = GL_UNSIGNED_IDENTITY_NV; /* Clamp all values to positive ranges */
+
+ /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the input
+ * should be used for all input components. */
+ if (is_alpha || arg & WINED3DTA_ALPHAREPLICATE) *component_usage = GL_ALPHA;
+ else *component_usage = GL_RGB;
+
+ *input = d3dta_to_combiner_input(arg & WINED3DTA_SELECTMASK, stage, texture_idx);
+}
+
+void set_tex_op_nvrc(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state, BOOL is_alpha,
+ int stage, enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx, DWORD dst)
+{
+ struct tex_op_args tex_op_args = {{0}, {0}, {0}};
+ GLenum portion = is_alpha ? GL_ALPHA : GL_RGB;
+ GLenum target = GL_COMBINER0_NV + stage;
+ GLenum output;
+
+ TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
+ stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx);
+
+ /* If a texture stage references an invalid texture unit the stage just
+ * passes through the result from the previous stage */
+ if (is_invalid_op(state, stage, op, arg1, arg2, arg3))
+ {
+ arg1 = WINED3DTA_CURRENT;
+ op = WINED3D_TOP_SELECT_ARG1;
+ }
+
+ get_src_and_opr_nvrc(stage, arg1, is_alpha, &tex_op_args.input[0],
+ &tex_op_args.mapping[0], &tex_op_args.component_usage[0], texture_idx);
+ get_src_and_opr_nvrc(stage, arg2, is_alpha, &tex_op_args.input[1],
+ &tex_op_args.mapping[1], &tex_op_args.component_usage[1], texture_idx);
+ get_src_and_opr_nvrc(stage, arg3, is_alpha, &tex_op_args.input[2],
+ &tex_op_args.mapping[2], &tex_op_args.component_usage[2], texture_idx);
+
+
+ if(dst == WINED3DTA_TEMP) {
+ output = GL_SPARE1_NV;
+ } else {
+ output = GL_SPARE0_NV;
+ }
+
+ /* This is called by a state handler which has the gl lock held and a context for the thread */
+ switch (op)
+ {
+ case WINED3D_TOP_DISABLE:
+ /* Only for alpha */
+ if (!is_alpha)
+ ERR("Shouldn't be called for WINED3D_TSS_COLOR_OP (WINED3DTOP_DISABLE).\n");
+ /* Input, prev_alpha*1 */
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+ GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+ GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
+
+ /* Output */
+ GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
+ GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+ break;
+
+ case WINED3D_TOP_SELECT_ARG1:
+ case WINED3D_TOP_SELECT_ARG2:
+ /* Input, arg*1 */
+ if (op == WINED3D_TOP_SELECT_ARG1)
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+ tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+ else
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+ tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+ GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+
+ /* Output */
+ GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
+ GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+ break;
+
+ case WINED3D_TOP_MODULATE:
+ case WINED3D_TOP_MODULATE_2X:
+ case WINED3D_TOP_MODULATE_4X:
+ /* Input, arg1*arg2 */
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+ tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+ tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+
+ /* Output */
+ if (op == WINED3D_TOP_MODULATE)
+ GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
+ GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+ else if (op == WINED3D_TOP_MODULATE_2X)
+ GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
+ GL_DISCARD_NV, GL_SCALE_BY_TWO_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+ else if (op == WINED3D_TOP_MODULATE_4X)
+ GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
+ GL_DISCARD_NV, GL_SCALE_BY_FOUR_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+ break;
+
+ case WINED3D_TOP_ADD:
+ case WINED3D_TOP_ADD_SIGNED:
+ case WINED3D_TOP_ADD_SIGNED_2X:
+ /* Input, arg1*1+arg2*1 */
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+ tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+ GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
+ tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
+ GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+
+ /* Output */
+ if (op == WINED3D_TOP_ADD)
+ GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+ output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+ else if (op == WINED3D_TOP_ADD_SIGNED)
+ GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+ output, GL_NONE, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
+ else if (op == WINED3D_TOP_ADD_SIGNED_2X)
+ GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+ output, GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
+ break;
+
+ case WINED3D_TOP_SUBTRACT:
+ /* Input, arg1*1+-arg2*1 */
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+ tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+ GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
+ tex_op_args.input[1], GL_SIGNED_NEGATE_NV, tex_op_args.component_usage[1]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
+ GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+
+ /* Output */
+ GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+ output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+ break;
+
+ case WINED3D_TOP_ADD_SMOOTH:
+ /* Input, arg1*1+(1-arg1)*arg2 */
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+ tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+ GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
+ tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
+ tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+
+ /* Output */
+ GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+ output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+ break;
+
+ case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
+ case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
+ case WINED3D_TOP_BLEND_FACTOR_ALPHA:
+ case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
+ case WINED3D_TOP_BLEND_CURRENT_ALPHA:
+ {
+ GLenum alpha_src = GL_PRIMARY_COLOR_NV;
+ if (op == WINED3D_TOP_BLEND_DIFFUSE_ALPHA)
+ alpha_src = d3dta_to_combiner_input(WINED3DTA_DIFFUSE, stage, texture_idx);
+ else if (op == WINED3D_TOP_BLEND_TEXTURE_ALPHA)
+ alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
+ else if (op == WINED3D_TOP_BLEND_FACTOR_ALPHA)
+ alpha_src = d3dta_to_combiner_input(WINED3DTA_TFACTOR, stage, texture_idx);
+ else if (op == WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM)
+ alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
+ else if (op == WINED3D_TOP_BLEND_CURRENT_ALPHA)
+ alpha_src = d3dta_to_combiner_input(WINED3DTA_CURRENT, stage, texture_idx);
+ else
+ FIXME("Unhandled texture op %s, shouldn't happen.\n", debug_d3dtop(op));
+
+ /* Input, arg1*alpha_src+arg2*(1-alpha_src) */
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+ tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+ if (op == WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM)
+ {
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+ GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+ } else {
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+ alpha_src, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
+ }
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
+ tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
+ alpha_src, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
+
+ /* Output */
+ GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+ output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+ break;
+ }
+
+ case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
+ /* Input, arg1_alpha*arg2_rgb+arg1_rgb*1 */
+ if (is_alpha)
+ ERR("Only supported for WINED3D_TSS_COLOR_OP (WINED3DTOP_MODULATEALPHA_ADDCOLOR).\n");
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+ tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+ tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
+ tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
+ GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+
+ /* Output */
+ GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+ output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+ break;
+
+ case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
+ /* Input, arg1_rgb*arg2_rgb+arg1_alpha*1 */
+ if (is_alpha)
+ ERR("Only supported for WINED3D_TSS_COLOR_OP (WINED3DTOP_MODULATECOLOR_ADDALPHA).\n");
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+ tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+ tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
+ tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
+ GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+
+ /* Output */
+ GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+ output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+ break;
+
+ case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
+ /* Input, (1-arg1_alpha)*arg2_rgb+arg1_rgb*1 */
+ if (is_alpha)
+ ERR("Only supported for WINED3D_TSS_COLOR_OP (WINED3DTOP_MODULATEINVALPHA_ADDCOLOR).\n");
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+ tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), GL_ALPHA));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+ tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
+ tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
+ GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+
+ /* Output */
+ GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+ output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+ break;
+
+ case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
+ /* Input, (1-arg1_rgb)*arg2_rgb+arg1_alpha*1 */
+ if (is_alpha)
+ ERR("Only supported for WINED3D_TSS_COLOR_OP (WINED3DTOP_MODULATEINVCOLOR_ADDALPHA).\n");
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+ tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+ tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
+ tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
+ GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+
+ /* Output */
+ GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+ output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+ break;
+
+ case WINED3D_TOP_DOTPRODUCT3:
+ /* Input, arg1 . arg2 */
+ /* FIXME: DX7 uses a different calculation? */
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+ tex_op_args.input[0], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[0]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+ tex_op_args.input[1], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[1]));
+
+ /* Output */
+ GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
+ GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE));
+ break;
+
+ case WINED3D_TOP_MULTIPLY_ADD:
+ /* Input, arg3*1+arg1*arg2 */
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+ tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+ GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
+ tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
+ tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+
+ /* Output */
+ GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+ output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+ break;
+
+ case WINED3D_TOP_LERP:
+ /* Input, arg3*arg1+(1-arg3)*arg2 */
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+ tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+ tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
+ tex_op_args.input[2], invert_mapping(tex_op_args.mapping[2]), tex_op_args.component_usage[2]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
+ tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+
+ /* Output */
+ GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+ output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+ break;
+
+ case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
+ case WINED3D_TOP_BUMPENVMAP:
+ if (!gl_info->supported[NV_TEXTURE_SHADER])
+ {
+ WARN("BUMPENVMAP requires GL_NV_texture_shader in this codepath\n");
+ break;
+ }
+
+ /* The bump map stage itself isn't exciting, just read the texture. But tell the next stage to
+ * perform bump mapping and source from the current stage. Pretty much a SELECTARG2.
+ * ARG2 is passed through unmodified(apps will most likely use D3DTA_CURRENT for arg2, arg1
+ * (which will most likely be D3DTA_TEXTURE) is available as a texture shader input for the
+ * next stage */
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+ tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+ GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+ GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+ /* Always pass through to CURRENT, ignore temp arg */
+ GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
+ GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+ break;
+
+ default:
+ FIXME("Unhandled texture op: stage %d, is_alpha %d, op %s (%#x), arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d.\n",
+ stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx);
+ }
+
+ checkGLcall("set_tex_op_nvrc()");
+}
+
+
+static void nvrc_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
+ const struct wined3d_device *device = context->swapchain->device;
+ BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
+ DWORD mapped_stage = device->texUnitMap[stage];
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ TRACE("Setting color op for stage %u.\n", stage);
+
+ /* Using a pixel shader? Don't care for anything here, the shader applying does it */
+ if (use_ps(state)) return;
+
+ if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
+
+ if (mapped_stage != WINED3D_UNMAPPED_STAGE)
+ {
+ if (tex_used && mapped_stage >= gl_info->limits.textures)
+ {
+ FIXME("Attempt to enable unsupported stage!\n");
+ return;
+ }
+ context_active_texture(context, gl_info, mapped_stage);
+ }
+
+ if (state->lowest_disabled_stage > 0)
+ {
+ gl_info->gl_ops.gl.p_glEnable(GL_REGISTER_COMBINERS_NV);
+ GL_EXTCALL(glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, state->lowest_disabled_stage));
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_REGISTER_COMBINERS_NV);
+ }
+ if (stage >= state->lowest_disabled_stage)
+ {
+ TRACE("Stage disabled\n");
+ if (mapped_stage != WINED3D_UNMAPPED_STAGE)
+ {
+ /* Disable everything here */
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
+ checkGLcall("glDisable(GL_TEXTURE_2D)");
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
+ checkGLcall("glDisable(GL_TEXTURE_3D)");
+ if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+ checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
+ }
+ if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
+ checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
+ }
+ if (gl_info->supported[NV_TEXTURE_SHADER2] && mapped_stage < gl_info->limits.textures)
+ {
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
+ }
+ }
+ /* All done */
+ return;
+ }
+
+ /* The sampler will also activate the correct texture dimensions, so no need to do it here
+ * if the sampler for this stage is dirty
+ */
+ if (!isStateDirty(context, STATE_SAMPLER(stage)))
+ {
+ if (tex_used)
+ {
+ if (gl_info->supported[NV_TEXTURE_SHADER2])
+ {
+ nvts_activate_dimensions(state, stage, context);
+ }
+ else
+ {
+ texture_activate_dimensions(state->textures[stage], gl_info);
+ }
+ }
+ }
+
+ /* Set the texture combiners */
+ set_tex_op_nvrc(gl_info, state, FALSE, stage,
+ state->texture_states[stage][WINED3D_TSS_COLOR_OP],
+ state->texture_states[stage][WINED3D_TSS_COLOR_ARG1],
+ state->texture_states[stage][WINED3D_TSS_COLOR_ARG2],
+ state->texture_states[stage][WINED3D_TSS_COLOR_ARG0],
+ mapped_stage,
+ state->texture_states[stage][WINED3D_TSS_RESULT_ARG]);
+
+ /* In register combiners bump mapping is done in the stage AFTER the one that has the bump map operation set,
+ * thus the texture shader may have to be updated
+ */
+ if (gl_info->supported[NV_TEXTURE_SHADER2])
+ {
+ BOOL usesBump = (state->texture_states[stage][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_BUMPENVMAP_LUMINANCE
+ || state->texture_states[stage][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_BUMPENVMAP);
+ BOOL usedBump = !!(context->texShaderBumpMap & 1 << (stage + 1));
+ if (usesBump != usedBump)
+ {
+ context_active_texture(context, gl_info, mapped_stage + 1);
+ nvts_activate_dimensions(state, stage + 1, context);
+ context_active_texture(context, gl_info, mapped_stage);
+ }
+ }
+}
+
+static void nvts_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ DWORD sampler = state_id - STATE_SAMPLER(0);
+ DWORD mapped_stage = context->swapchain->device->texUnitMap[sampler];
+
+ /* No need to enable / disable anything here for unused samplers. The tex_colorop
+ * handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
+ * will take care of this business. */
+ if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures)
+ return;
+ if (sampler >= state->lowest_disabled_stage)
+ return;
+ if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)))
+ return;
+
+ nvts_activate_dimensions(state, sampler, context);
+}
+
+static void nvts_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
+ DWORD mapped_stage = context->swapchain->device->texUnitMap[stage + 1];
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ float mat[2][2];
+
+ /* Direct3D sets the matrix in the stage reading the perturbation map. The result is used to
+ * offset the destination stage(always stage + 1 in d3d). In GL_NV_texture_shader, the bump
+ * map offsetting is done in the stage reading the bump mapped texture, and the perturbation
+ * map is read from a specified source stage(always stage - 1 for d3d). Thus set the matrix
+ * for stage + 1. Keep the nvrc tex unit mapping in mind too
+ */
+ if (mapped_stage < gl_info->limits.textures)
+ {
+ context_active_texture(context, gl_info, mapped_stage);
+
+ /* We can't just pass a pointer to the state to GL due to the
+ * different matrix format (column major vs row major). */
+ mat[0][0] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_MAT00]);
+ mat[1][0] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_MAT01]);
+ mat[0][1] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_MAT10]);
+ mat[1][1] = *((float *)&state->texture_states[stage][WINED3D_TSS_BUMPENV_MAT11]);
+ gl_info->gl_ops.gl.p_glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, (float *)mat);
+ checkGLcall("glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, mat)");
+ }
+}
+
+static void nvrc_texfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ float col[4];
+
+ D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col);
+ GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &col[0]));
+}
+
+/* Context activation is done by the caller. */
+static void nvrc_enable(const struct wined3d_gl_info *gl_info, BOOL enable)
+{
+ if (enable)
+ {
+ gl_info->gl_ops.gl.p_glEnable(GL_REGISTER_COMBINERS_NV);
+ checkGLcall("glEnable(GL_REGISTER_COMBINERS_NV)");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_REGISTER_COMBINERS_NV);
+ checkGLcall("glDisable(GL_REGISTER_COMBINERS_NV)");
+ }
+}
+
+/* Context activation is done by the caller. */
+static void nvts_enable(const struct wined3d_gl_info *gl_info, BOOL enable)
+{
+ nvrc_enable(gl_info, enable);
+ if (enable)
+ {
+ gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_SHADER_NV);
+ checkGLcall("glEnable(GL_TEXTURE_SHADER_NV)");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_SHADER_NV);
+ checkGLcall("glDisable(GL_TEXTURE_SHADER_NV)");
+ }
+}
+
+static void nvrc_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
+{
+ caps->wined3d_caps = 0;
+ caps->PrimitiveMiscCaps = WINED3DPMISCCAPS_TSSARGTEMP;
+
+ /* The caps below can be supported but aren't handled yet in utils.c
+ * 'd3dta_to_combiner_input', disable them until support is fixed */
+#if 0
+ if (gl_info->supported[NV_REGISTER_COMBINERS2])
+ caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_PERSTAGECONSTANT;
+#endif
+
+ caps->TextureOpCaps = WINED3DTEXOPCAPS_ADD
+ | WINED3DTEXOPCAPS_ADDSIGNED
+ | WINED3DTEXOPCAPS_ADDSIGNED2X
+ | WINED3DTEXOPCAPS_MODULATE
+ | WINED3DTEXOPCAPS_MODULATE2X
+ | WINED3DTEXOPCAPS_MODULATE4X
+ | WINED3DTEXOPCAPS_SELECTARG1
+ | WINED3DTEXOPCAPS_SELECTARG2
+ | WINED3DTEXOPCAPS_DISABLE
+ | WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA
+ | WINED3DTEXOPCAPS_BLENDTEXTUREALPHA
+ | WINED3DTEXOPCAPS_BLENDFACTORALPHA
+ | WINED3DTEXOPCAPS_BLENDCURRENTALPHA
+ | WINED3DTEXOPCAPS_LERP
+ | WINED3DTEXOPCAPS_SUBTRACT
+ | WINED3DTEXOPCAPS_ADDSMOOTH
+ | WINED3DTEXOPCAPS_MULTIPLYADD
+ | WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
+ | WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
+ | WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM
+ | WINED3DTEXOPCAPS_DOTPRODUCT3
+ | WINED3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR
+ | WINED3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA;
+
+ if (gl_info->supported[NV_TEXTURE_SHADER2])
+ {
+ /* Bump mapping is supported already in NV_TEXTURE_SHADER, but that extension does
+ * not support 3D textures. This asks for trouble if an app uses both bump mapping
+ * and 3D textures. It also allows us to keep the code simpler by having texture
+ * shaders constantly enabled. */
+ caps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
+ /* TODO: Luminance bump map? */
+ }
+
+#if 0
+ /* FIXME: Add
+ caps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE
+ WINED3DTEXOPCAPS_PREMODULATE */
+#endif
+
+ caps->MaxTextureBlendStages = min(MAX_TEXTURES, gl_info->limits.general_combiners);
+ caps->MaxSimultaneousTextures = gl_info->limits.textures;
+}
+
+static void *nvrc_fragment_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
+{
+ return shader_priv;
+}
+
+/* Context activation is done by the caller. */
+static void nvrc_fragment_free(struct wined3d_device *device) {}
+
+/* Two fixed function pipeline implementations using GL_NV_register_combiners and
+ * GL_NV_texture_shader. The nvts_fragment_pipeline assumes that both extensions
+ * are available(geforce 3 and newer), while nvrc_fragment_pipeline uses only the
+ * register combiners extension(Pre-GF3).
+ */
+
+static BOOL nvts_color_fixup_supported(struct color_fixup_desc fixup)
+{
+ if (TRACE_ON(d3d))
+ {
+ TRACE("Checking support for fixup:\n");
+ dump_color_fixup_desc(fixup);
+ }
+
+ /* We only support identity conversions. */
+ if (is_identity_fixup(fixup))
+ {
+ TRACE("[OK]\n");
+ return TRUE;
+ }
+
+ TRACE("[FAILED]\n");
+ return FALSE;
+}
+
+static const struct StateEntryTemplate nvrc_fragmentstate_template[] =
+{
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), nvrc_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), nvts_bumpenvmat }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, NV_TEXTURE_SHADER2 },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), nvrc_texfactor }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_FOGCOLOR), { STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_FOGDENSITY), { STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_FOGSTART), { STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_FOGEND), { STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(0), { STATE_SAMPLER(0), nvts_texdim }, NV_TEXTURE_SHADER2 },
+ { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(1), { STATE_SAMPLER(1), nvts_texdim }, NV_TEXTURE_SHADER2 },
+ { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(2), { STATE_SAMPLER(2), nvts_texdim }, NV_TEXTURE_SHADER2 },
+ { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(3), { STATE_SAMPLER(3), nvts_texdim }, NV_TEXTURE_SHADER2 },
+ { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(4), { STATE_SAMPLER(4), nvts_texdim }, NV_TEXTURE_SHADER2 },
+ { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(5), { STATE_SAMPLER(5), nvts_texdim }, NV_TEXTURE_SHADER2 },
+ { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(6), { STATE_SAMPLER(6), nvts_texdim }, NV_TEXTURE_SHADER2 },
+ { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(7), { STATE_SAMPLER(7), nvts_texdim }, NV_TEXTURE_SHADER2 },
+ { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
+};
+
+const struct fragment_pipeline nvts_fragment_pipeline = {
+ nvts_enable,
+ nvrc_fragment_get_caps,
+ nvrc_fragment_alloc,
+ nvrc_fragment_free,
+ nvts_color_fixup_supported,
+ nvrc_fragmentstate_template,
+};
+
+const struct fragment_pipeline nvrc_fragment_pipeline = {
+ nvrc_enable,
+ nvrc_fragment_get_caps,
+ nvrc_fragment_alloc,
+ nvrc_fragment_free,
+ nvts_color_fixup_supported,
+ nvrc_fragmentstate_template,
+};
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/palette.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/palette.c
new file mode 100644
index 00000000..97bdf5cc
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/palette.c
@@ -0,0 +1,226 @@
+/* DirectDraw - IDirectPalette base interface
+ *
+ * Copyright 1997-2000 Marcus Meissner
+ * Copyright 2000-2001 TransGaming Technologies Inc.
+ * Copyright 2006 Stefan Dösinger for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+#include "winerror.h"
+#include "wine/debug.h"
+
+#include <string.h>
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+
+#define SIZE_BITS (WINEDDPCAPS_1BIT | WINEDDPCAPS_2BIT | WINEDDPCAPS_4BIT | WINEDDPCAPS_8BIT)
+
+ULONG CDECL wined3d_palette_incref(struct wined3d_palette *palette)
+{
+ ULONG refcount = InterlockedIncrement(&palette->ref);
+
+ TRACE("%p increasing refcount to %u.\n", palette, refcount);
+
+ return refcount;
+}
+
+ULONG CDECL wined3d_palette_decref(struct wined3d_palette *palette)
+{
+ ULONG refcount = InterlockedDecrement(&palette->ref);
+
+ TRACE("%p decreasing refcount to %u.\n", palette, refcount);
+
+ if (!refcount)
+ {
+ DeleteObject(palette->hpal);
+ HeapFree(GetProcessHeap(), 0, palette);
+ }
+
+ return refcount;
+}
+
+static WORD wined3d_palette_size(DWORD flags)
+{
+ switch (flags & SIZE_BITS)
+ {
+ case WINEDDPCAPS_1BIT: return 2;
+ case WINEDDPCAPS_2BIT: return 4;
+ case WINEDDPCAPS_4BIT: return 16;
+ case WINEDDPCAPS_8BIT: return 256;
+ default:
+ FIXME("Unhandled size bits %#x.\n", flags & SIZE_BITS);
+ return 256;
+ }
+}
+
+HRESULT CDECL wined3d_palette_get_entries(const struct wined3d_palette *palette,
+ DWORD flags, DWORD start, DWORD count, PALETTEENTRY *entries)
+{
+ TRACE("palette %p, flags %#x, start %u, count %u, entries %p.\n",
+ palette, flags, start, count, entries);
+
+ if (flags) return WINED3DERR_INVALIDCALL; /* unchecked */
+ if (start + count > wined3d_palette_size(palette->flags))
+ return WINED3DERR_INVALIDCALL;
+
+ if (palette->flags & WINEDDPCAPS_8BITENTRIES)
+ {
+ BYTE *entry = (BYTE *)entries;
+ unsigned int i;
+
+ for (i = start; i < count + start; ++i)
+ *entry++ = palette->palents[i].peRed;
+ }
+ else
+ memcpy(entries, palette->palents + start, count * sizeof(*entries));
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_palette_set_entries(struct wined3d_palette *palette,
+ DWORD flags, DWORD start, DWORD count, const PALETTEENTRY *entries)
+{
+ struct wined3d_resource *resource;
+
+ TRACE("palette %p, flags %#x, start %u, count %u, entries %p.\n",
+ palette, flags, start, count, entries);
+ TRACE("Palette flags: %#x.\n", palette->flags);
+
+ if (palette->flags & WINEDDPCAPS_8BITENTRIES)
+ {
+ const BYTE *entry = (const BYTE *)entries;
+ unsigned int i;
+
+ for (i = start; i < count + start; ++i)
+ palette->palents[i].peRed = *entry++;
+ }
+ else
+ {
+ memcpy(palette->palents + start, entries, count * sizeof(*palette->palents));
+
+ /* When WINEDDCAPS_ALLOW256 isn't set we need to override entry 0 with black and 255 with white */
+ if (!(palette->flags & WINEDDPCAPS_ALLOW256))
+ {
+ TRACE("WINEDDPCAPS_ALLOW256 set, overriding palette entry 0 with black and 255 with white\n");
+ palette->palents[0].peRed = 0;
+ palette->palents[0].peGreen = 0;
+ palette->palents[0].peBlue = 0;
+
+ palette->palents[255].peRed = 255;
+ palette->palents[255].peGreen = 255;
+ palette->palents[255].peBlue = 255;
+ }
+
+ if (palette->hpal)
+ SetPaletteEntries(palette->hpal, start, count, palette->palents + start);
+ }
+
+ /* If the palette is attached to the render target, update all render targets */
+ LIST_FOR_EACH_ENTRY(resource, &palette->device->resources, struct wined3d_resource, resource_list_entry)
+ {
+ if (resource->type == WINED3D_RTYPE_SURFACE)
+ {
+ struct wined3d_surface *surface = surface_from_resource(resource);
+ if (surface->palette == palette)
+ surface->surface_ops->surface_realize_palette(surface);
+ }
+ }
+
+ return WINED3D_OK;
+}
+
+DWORD CDECL wined3d_palette_get_flags(const struct wined3d_palette *palette)
+{
+ TRACE("palette %p.\n", palette);
+
+ return palette->flags;
+}
+
+void * CDECL wined3d_palette_get_parent(const struct wined3d_palette *palette)
+{
+ TRACE("palette %p.\n", palette);
+
+ return palette->parent;
+}
+
+static HRESULT wined3d_palette_init(struct wined3d_palette *palette, struct wined3d_device *device,
+ DWORD flags, const PALETTEENTRY *entries, void *parent)
+{
+ HRESULT hr;
+
+ palette->ref = 1;
+ palette->parent = parent;
+ palette->device = device;
+ palette->flags = flags;
+
+ palette->palNumEntries = wined3d_palette_size(flags);
+ palette->hpal = CreatePalette((const LOGPALETTE *)&palette->palVersion);
+ if (!palette->hpal)
+ {
+ WARN("Failed to create palette.\n");
+ return E_FAIL;
+ }
+
+ hr = wined3d_palette_set_entries(palette, 0, 0, wined3d_palette_size(flags), entries);
+ if (FAILED(hr))
+ {
+ WARN("Failed to set palette entries, hr %#x.\n", hr);
+ DeleteObject(palette->hpal);
+ return hr;
+ }
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_palette_create(struct wined3d_device *device, DWORD flags,
+ const PALETTEENTRY *entries, void *parent, struct wined3d_palette **palette)
+{
+ struct wined3d_palette *object;
+ HRESULT hr;
+
+ TRACE("device %p, flags %#x, entries %p, palette %p, parent %p.\n",
+ device, flags, entries, palette, parent);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ hr = wined3d_palette_init(object, device, flags, entries, parent);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize palette, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created palette %p.\n", object);
+ *palette = object;
+
+ return WINED3D_OK;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/query.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/query.c
new file mode 100644
index 00000000..43041f67
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/query.c
@@ -0,0 +1,653 @@
+/*
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2009-2010 Henri Verbeet for CodeWeavers.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+
+BOOL wined3d_event_query_supported(const struct wined3d_gl_info *gl_info)
+{
+ return gl_info->supported[ARB_SYNC] || gl_info->supported[NV_FENCE] || gl_info->supported[APPLE_FENCE];
+}
+
+void wined3d_event_query_destroy(struct wined3d_event_query *query)
+{
+ if (query->context) context_free_event_query(query);
+ HeapFree(GetProcessHeap(), 0, query);
+}
+
+static enum wined3d_event_query_result wined3d_event_query_test(const struct wined3d_event_query *query,
+ const struct wined3d_device *device)
+{
+ struct wined3d_context *context;
+ const struct wined3d_gl_info *gl_info;
+ enum wined3d_event_query_result ret;
+ BOOL fence_result;
+
+ TRACE("(%p) : device %p\n", query, device);
+
+ if (!query->context)
+ {
+ TRACE("Query not started\n");
+ return WINED3D_EVENT_QUERY_NOT_STARTED;
+ }
+
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ if (!query->context->gl_info->supported[ARB_SYNC] && query->context->tid != GetCurrentThreadId())
+ {
+ WARN("Event query tested from wrong thread\n");
+ return WINED3D_EVENT_QUERY_WRONG_THREAD;
+ }
+#endif
+
+ context = context_acquire(device, query->context->current_rt);
+ gl_info = context->gl_info;
+
+ if (gl_info->supported[ARB_SYNC])
+ {
+ GLenum gl_ret = GL_EXTCALL(glClientWaitSync(query->object.sync, 0, 0));
+ checkGLcall("glClientWaitSync");
+
+ switch (gl_ret)
+ {
+ case GL_ALREADY_SIGNALED:
+ case GL_CONDITION_SATISFIED:
+ ret = WINED3D_EVENT_QUERY_OK;
+ break;
+
+ case GL_TIMEOUT_EXPIRED:
+ ret = WINED3D_EVENT_QUERY_WAITING;
+ break;
+
+ case GL_WAIT_FAILED:
+ default:
+ ERR("glClientWaitSync returned %#x.\n", gl_ret);
+ ret = WINED3D_EVENT_QUERY_ERROR;
+ }
+ }
+ else if (gl_info->supported[APPLE_FENCE])
+ {
+ fence_result = GL_EXTCALL(glTestFenceAPPLE(query->object.id));
+ checkGLcall("glTestFenceAPPLE");
+ if (fence_result) ret = WINED3D_EVENT_QUERY_OK;
+ else ret = WINED3D_EVENT_QUERY_WAITING;
+ }
+ else if (gl_info->supported[NV_FENCE])
+ {
+ fence_result = GL_EXTCALL(glTestFenceNV(query->object.id));
+ checkGLcall("glTestFenceNV");
+ if (fence_result) ret = WINED3D_EVENT_QUERY_OK;
+ else ret = WINED3D_EVENT_QUERY_WAITING;
+ }
+ else
+ {
+#ifdef VBOX_WITH_WDDM
+ /* doing Flush (rather than Finish) should be enough since we're serialized on the host in any way */
+ gl_info->gl_ops.gl.p_glFlush();
+ ret = WINED3D_EVENT_QUERY_OK;
+#else
+ ERR("Event query created despite lack of GL support\n");
+ ret = WINED3D_EVENT_QUERY_ERROR;
+#endif
+ }
+
+ context_release(context);
+ return ret;
+}
+
+enum wined3d_event_query_result wined3d_event_query_finish(const struct wined3d_event_query *query,
+ const struct wined3d_device *device)
+{
+ struct wined3d_context *context;
+ const struct wined3d_gl_info *gl_info;
+ enum wined3d_event_query_result ret;
+
+ TRACE("(%p)\n", query);
+
+ if (!query->context)
+ {
+ TRACE("Query not started\n");
+ return WINED3D_EVENT_QUERY_NOT_STARTED;
+ }
+ gl_info = query->context->gl_info;
+
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ if (query->context->tid != GetCurrentThreadId() && !gl_info->supported[ARB_SYNC])
+ {
+ /* A glFinish does not reliably wait for draws in other contexts. The caller has
+ * to find its own way to cope with the thread switch
+ */
+ WARN("Event query finished from wrong thread\n");
+ return WINED3D_EVENT_QUERY_WRONG_THREAD;
+ }
+#endif
+
+ context = context_acquire(device, query->context->current_rt);
+
+ if (gl_info->supported[ARB_SYNC])
+ {
+ /* Apple seems to be into arbitrary limits, and timeouts larger than
+ * 0xfffffffffffffbff immediately return GL_TIMEOUT_EXPIRED. We don't
+ * really care and can live with waiting a few μs less. (OS X 10.7.4). */
+ GLenum gl_ret = GL_EXTCALL(glClientWaitSync(query->object.sync, GL_SYNC_FLUSH_COMMANDS_BIT, ~(GLuint64)0xffff));
+ checkGLcall("glClientWaitSync");
+
+ switch (gl_ret)
+ {
+ case GL_ALREADY_SIGNALED:
+ case GL_CONDITION_SATISFIED:
+ ret = WINED3D_EVENT_QUERY_OK;
+ break;
+
+ /* We don't expect a timeout for a ~584 year wait */
+ default:
+ ERR("glClientWaitSync returned %#x.\n", gl_ret);
+ ret = WINED3D_EVENT_QUERY_ERROR;
+ }
+ }
+ else if (context->gl_info->supported[APPLE_FENCE])
+ {
+ GL_EXTCALL(glFinishFenceAPPLE(query->object.id));
+ checkGLcall("glFinishFenceAPPLE");
+ ret = WINED3D_EVENT_QUERY_OK;
+ }
+ else if (context->gl_info->supported[NV_FENCE])
+ {
+ GL_EXTCALL(glFinishFenceNV(query->object.id));
+ checkGLcall("glFinishFenceNV");
+ ret = WINED3D_EVENT_QUERY_OK;
+ }
+ else
+ {
+ ERR("Event query created without GL support\n");
+ ret = WINED3D_EVENT_QUERY_ERROR;
+ }
+
+ context_release(context);
+ return ret;
+}
+
+void wined3d_event_query_issue(struct wined3d_event_query *query, const struct wined3d_device *device)
+{
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+
+ if (query->context)
+ {
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ if (!query->context->gl_info->supported[ARB_SYNC] && query->context->tid != GetCurrentThreadId())
+ {
+ context_free_event_query(query);
+ context = context_acquire(device, NULL);
+ context_alloc_event_query(context, query);
+ }
+ else
+#endif
+ {
+ context = context_acquire(device, query->context->current_rt);
+ }
+ }
+ else
+ {
+ context = context_acquire(device, NULL);
+ context_alloc_event_query(context, query);
+ }
+
+ gl_info = context->gl_info;
+
+ if (gl_info->supported[ARB_SYNC])
+ {
+ if (query->object.sync) GL_EXTCALL(glDeleteSync(query->object.sync));
+ checkGLcall("glDeleteSync");
+ query->object.sync = GL_EXTCALL(glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
+ checkGLcall("glFenceSync");
+ }
+ else if (gl_info->supported[APPLE_FENCE])
+ {
+ GL_EXTCALL(glSetFenceAPPLE(query->object.id));
+ checkGLcall("glSetFenceAPPLE");
+ }
+ else if (gl_info->supported[NV_FENCE])
+ {
+ GL_EXTCALL(glSetFenceNV(query->object.id, GL_ALL_COMPLETED_NV));
+ checkGLcall("glSetFenceNV");
+ }
+
+ context_release(context);
+}
+
+ULONG CDECL wined3d_query_incref(struct wined3d_query *query)
+{
+ ULONG refcount = InterlockedIncrement(&query->ref);
+
+ TRACE("%p increasing refcount to %u.\n", query, refcount);
+
+ return refcount;
+}
+
+ULONG CDECL wined3d_query_decref(struct wined3d_query *query)
+{
+ ULONG refcount = InterlockedDecrement(&query->ref);
+
+ TRACE("%p decreasing refcount to %u.\n", query, refcount);
+
+ if (!refcount)
+ {
+ /* Queries are specific to the GL context that created them. Not
+ * deleting the query will obviously leak it, but that's still better
+ * than potentially deleting a different query with the same id in this
+ * context, and (still) leaking the actual query. */
+ if (query->type == WINED3D_QUERY_TYPE_EVENT)
+ {
+ struct wined3d_event_query *event_query = query->extendedData;
+ if (event_query) wined3d_event_query_destroy(event_query);
+ }
+ else if (query->type == WINED3D_QUERY_TYPE_OCCLUSION)
+ {
+ struct wined3d_occlusion_query *oq = query->extendedData;
+
+ if (oq->context) context_free_occlusion_query(oq);
+ HeapFree(GetProcessHeap(), 0, query->extendedData);
+ }
+
+ HeapFree(GetProcessHeap(), 0, query);
+ }
+
+ return refcount;
+}
+
+HRESULT CDECL wined3d_query_get_data(struct wined3d_query *query,
+ void *data, UINT data_size, DWORD flags)
+{
+ TRACE("query %p, data %p, data_size %u, flags %#x.\n",
+ query, data, data_size, flags);
+
+ return query->query_ops->query_get_data(query, data, data_size, flags);
+}
+
+UINT CDECL wined3d_query_get_data_size(const struct wined3d_query *query)
+{
+ TRACE("query %p.\n", query);
+
+ return query->data_size;
+}
+
+HRESULT CDECL wined3d_query_issue(struct wined3d_query *query, DWORD flags)
+{
+ TRACE("query %p, flags %#x.\n", query, flags);
+
+ return query->query_ops->query_issue(query, flags);
+}
+
+static HRESULT wined3d_occlusion_query_ops_get_data(struct wined3d_query *query,
+ void *pData, DWORD dwSize, DWORD flags)
+{
+ struct wined3d_occlusion_query *oq = query->extendedData;
+ struct wined3d_device *device = query->device;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ struct wined3d_context *context;
+ DWORD* data = pData;
+ GLuint available;
+ GLuint samples;
+ HRESULT res;
+
+ TRACE("(%p) : type D3DQUERY_OCCLUSION, pData %p, dwSize %#x, flags %#x.\n", query, pData, dwSize, flags);
+
+ if (!oq->context)
+ query->state = QUERY_CREATED;
+
+ if (query->state == QUERY_CREATED)
+ {
+ /* D3D allows GetData on a new query, OpenGL doesn't. So just invent the data ourselves */
+ TRACE("Query wasn't yet started, returning S_OK\n");
+ if(data) *data = 0;
+ return S_OK;
+ }
+
+ if (query->state == QUERY_BUILDING)
+ {
+ /* Msdn says this returns an error, but our tests show that S_FALSE is returned */
+ TRACE("Query is building, returning S_FALSE\n");
+ return S_FALSE;
+ }
+
+ if (!gl_info->supported[ARB_OCCLUSION_QUERY])
+ {
+ WARN("%p Occlusion queries not supported. Returning 1.\n", query);
+ *data = 1;
+ return S_OK;
+ }
+
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ if (oq->context->tid != GetCurrentThreadId())
+ {
+ FIXME("%p Wrong thread, returning 1.\n", query);
+ *data = 1;
+ return S_OK;
+ }
+#endif
+
+ context = context_acquire(query->device, oq->context->current_rt);
+
+ GL_EXTCALL(glGetQueryObjectuivARB(oq->id, GL_QUERY_RESULT_AVAILABLE_ARB, &available));
+ checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)");
+ TRACE("available %#x.\n", available);
+
+ if (available)
+ {
+ if (data)
+ {
+ GL_EXTCALL(glGetQueryObjectuivARB(oq->id, GL_QUERY_RESULT_ARB, &samples));
+ checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)");
+ TRACE("Returning %d samples.\n", samples);
+ *data = samples;
+ }
+ res = S_OK;
+ }
+ else
+ {
+ res = S_FALSE;
+ }
+
+ context_release(context);
+
+ return res;
+}
+
+static HRESULT wined3d_event_query_ops_get_data(struct wined3d_query *query,
+ void *pData, DWORD dwSize, DWORD flags)
+{
+ struct wined3d_event_query *event_query = query->extendedData;
+ BOOL *data = pData;
+ enum wined3d_event_query_result ret;
+
+ TRACE("query %p, pData %p, dwSize %#x, flags %#x.\n", query, pData, dwSize, flags);
+
+ if (!pData || !dwSize) return S_OK;
+ if (!event_query)
+ {
+ WARN("Event query not supported by GL, reporting GPU idle.\n");
+ *data = TRUE;
+ return S_OK;
+ }
+
+ ret = wined3d_event_query_test(event_query, query->device);
+ switch(ret)
+ {
+ case WINED3D_EVENT_QUERY_OK:
+ case WINED3D_EVENT_QUERY_NOT_STARTED:
+ *data = TRUE;
+ break;
+
+ case WINED3D_EVENT_QUERY_WAITING:
+ *data = FALSE;
+ break;
+
+ case WINED3D_EVENT_QUERY_WRONG_THREAD:
+ FIXME("(%p) Wrong thread, reporting GPU idle.\n", query);
+ *data = TRUE;
+ break;
+
+ case WINED3D_EVENT_QUERY_ERROR:
+ ERR("The GL event query failed, returning D3DERR_INVALIDCALL\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ return S_OK;
+}
+
+enum wined3d_query_type CDECL wined3d_query_get_type(const struct wined3d_query *query)
+{
+ TRACE("query %p.\n", query);
+
+ return query->type;
+}
+
+static HRESULT wined3d_event_query_ops_issue(struct wined3d_query *query, DWORD flags)
+{
+ TRACE("query %p, flags %#x.\n", query, flags);
+
+ TRACE("(%p) : flags %#x, type D3DQUERY_EVENT\n", query, flags);
+ if (flags & WINED3DISSUE_END)
+ {
+ struct wined3d_event_query *event_query = query->extendedData;
+
+ /* Faked event query support */
+ if (!event_query) return WINED3D_OK;
+
+ wined3d_event_query_issue(event_query, query->device);
+ }
+ else if (flags & WINED3DISSUE_BEGIN)
+ {
+ /* Started implicitly at device creation */
+ ERR("Event query issued with START flag - what to do?\n");
+ }
+
+ if (flags & WINED3DISSUE_BEGIN)
+ query->state = QUERY_BUILDING;
+ else
+ query->state = QUERY_SIGNALLED;
+
+ return WINED3D_OK;
+}
+
+static HRESULT wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD flags)
+{
+ struct wined3d_device *device = query->device;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+
+ TRACE("query %p, flags %#x.\n", query, flags);
+
+ if (gl_info->supported[ARB_OCCLUSION_QUERY])
+ {
+ struct wined3d_occlusion_query *oq = query->extendedData;
+ struct wined3d_context *context;
+
+ /* This is allowed according to msdn and our tests. Reset the query and restart */
+ if (flags & WINED3DISSUE_BEGIN)
+ {
+ if (query->state == QUERY_BUILDING)
+ {
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ if (oq->context->tid != GetCurrentThreadId())
+ {
+ FIXME("Wrong thread, can't restart query.\n");
+
+ context_free_occlusion_query(oq);
+ context = context_acquire(query->device, NULL);
+ context_alloc_occlusion_query(context, oq);
+ }
+ else
+#endif
+ {
+ context = context_acquire(query->device, oq->context->current_rt);
+
+ GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
+ checkGLcall("glEndQuery()");
+ }
+ }
+ else
+ {
+ if (oq->context) context_free_occlusion_query(oq);
+ context = context_acquire(query->device, NULL);
+ context_alloc_occlusion_query(context, oq);
+ }
+
+ GL_EXTCALL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, oq->id));
+ checkGLcall("glBeginQuery()");
+
+ context_release(context);
+ }
+ if (flags & WINED3DISSUE_END)
+ {
+ /* Msdn says _END on a non-building occlusion query returns an error, but
+ * our tests show that it returns OK. But OpenGL doesn't like it, so avoid
+ * generating an error
+ */
+ if (query->state == QUERY_BUILDING)
+ {
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ if (oq->context->tid != GetCurrentThreadId())
+ {
+ FIXME("Wrong thread, can't end query.\n");
+ }
+ else
+#endif
+ {
+ context = context_acquire(query->device, oq->context->current_rt);
+
+ GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
+ checkGLcall("glEndQuery()");
+
+ context_release(context);
+ }
+ }
+ }
+ }
+ else
+ {
+ FIXME("%p Occlusion queries not supported.\n", query);
+ }
+
+ if (flags & WINED3DISSUE_BEGIN)
+ query->state = QUERY_BUILDING;
+ else
+ query->state = QUERY_SIGNALLED;
+
+ return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */
+}
+
+static const struct wined3d_query_ops event_query_ops =
+{
+ wined3d_event_query_ops_get_data,
+ wined3d_event_query_ops_issue,
+};
+
+static const struct wined3d_query_ops occlusion_query_ops =
+{
+ wined3d_occlusion_query_ops_get_data,
+ wined3d_occlusion_query_ops_issue,
+};
+
+static HRESULT query_init(struct wined3d_query *query, struct wined3d_device *device, enum wined3d_query_type type)
+{
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+
+ switch (type)
+ {
+ case WINED3D_QUERY_TYPE_OCCLUSION:
+ TRACE("Occlusion query.\n");
+ if (!gl_info->supported[ARB_OCCLUSION_QUERY])
+ {
+ WARN("Unsupported in local OpenGL implementation: ARB_OCCLUSION_QUERY.\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
+ query->query_ops = &occlusion_query_ops;
+ query->data_size = sizeof(DWORD);
+ query->extendedData = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_occlusion_query));
+ if (!query->extendedData)
+ {
+ ERR("Failed to allocate occlusion query extended data.\n");
+ return E_OUTOFMEMORY;
+ }
+ ((struct wined3d_occlusion_query *)query->extendedData)->context = NULL;
+ break;
+
+ case WINED3D_QUERY_TYPE_EVENT:
+ TRACE("Event query.\n");
+ if (!wined3d_event_query_supported(gl_info))
+ {
+ /* Half-Life 2 needs this query. It does not render the main
+ * menu correctly otherwise. Pretend to support it, faking
+ * this query does not do much harm except potentially
+ * lowering performance. */
+ FIXME("Event query: Unimplemented, but pretending to be supported.\n");
+ }
+ query->query_ops = &event_query_ops;
+ query->data_size = sizeof(BOOL);
+ query->extendedData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct wined3d_event_query));
+ if (!query->extendedData)
+ {
+ ERR("Failed to allocate event query memory.\n");
+ return E_OUTOFMEMORY;
+ }
+ break;
+
+ case WINED3D_QUERY_TYPE_VCACHE:
+ case WINED3D_QUERY_TYPE_RESOURCE_MANAGER:
+ case WINED3D_QUERY_TYPE_VERTEX_STATS:
+ case WINED3D_QUERY_TYPE_TIMESTAMP:
+ case WINED3D_QUERY_TYPE_TIMESTAMP_DISJOINT:
+ case WINED3D_QUERY_TYPE_TIMESTAMP_FREQ:
+ case WINED3D_QUERY_TYPE_PIPELINE_TIMINGS:
+ case WINED3D_QUERY_TYPE_INTERFACE_TIMINGS:
+ case WINED3D_QUERY_TYPE_VERTEX_TIMINGS:
+ case WINED3D_QUERY_TYPE_PIXEL_TIMINGS:
+ case WINED3D_QUERY_TYPE_BANDWIDTH_TIMINGS:
+ case WINED3D_QUERY_TYPE_CACHE_UTILIZATION:
+ default:
+ FIXME("Unhandled query type %#x.\n", type);
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ query->type = type;
+ query->state = QUERY_CREATED;
+ query->device = device;
+ query->ref = 1;
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_query_create(struct wined3d_device *device,
+ enum wined3d_query_type type, struct wined3d_query **query)
+{
+ struct wined3d_query *object;
+ HRESULT hr;
+
+ TRACE("device %p, type %#x, query %p.\n", device, type, query);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ hr = query_init(object, device, type);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize query, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created query %p.\n", object);
+ *query = object;
+
+ return WINED3D_OK;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/resource.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/resource.c
new file mode 100644
index 00000000..c46731de
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/resource.c
@@ -0,0 +1,377 @@
+/*
+ * Copyright 2002-2004 Jason Edmeades
+ * Copyright 2003-2004 Raphael Junqueira
+ * Copyright 2004 Christian Costa
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2009-2010 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+
+struct private_data
+{
+ struct list entry;
+
+ GUID tag;
+ DWORD flags; /* DDSPD_* */
+
+ union
+ {
+ void *data;
+ IUnknown *object;
+ } ptr;
+
+ DWORD size;
+};
+
+static DWORD resource_access_from_pool(enum wined3d_pool pool)
+{
+ switch (pool)
+ {
+ case WINED3D_POOL_DEFAULT:
+ return WINED3D_RESOURCE_ACCESS_GPU;
+
+ case WINED3D_POOL_MANAGED:
+ return WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_CPU;
+
+ case WINED3D_POOL_SYSTEM_MEM:
+ return WINED3D_RESOURCE_ACCESS_CPU;
+
+ case WINED3D_POOL_SCRATCH:
+ return WINED3D_RESOURCE_ACCESS_SCRATCH;
+
+ default:
+ FIXME("Unhandled pool %#x.\n", pool);
+ return 0;
+ }
+}
+
+static void resource_check_usage(DWORD usage)
+{
+ static const DWORD handled = WINED3DUSAGE_RENDERTARGET
+ | WINED3DUSAGE_DEPTHSTENCIL
+ | WINED3DUSAGE_DYNAMIC
+ | WINED3DUSAGE_AUTOGENMIPMAP
+ | WINED3DUSAGE_STATICDECL
+ | WINED3DUSAGE_OVERLAY;
+
+ if (usage & ~handled)
+ FIXME("Unhandled usage flags %#x.\n", usage & ~handled);
+}
+
+HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *device,
+ enum wined3d_resource_type type, const struct wined3d_format *format,
+ enum wined3d_multisample_type multisample_type, UINT multisample_quality,
+ DWORD usage, enum wined3d_pool pool, UINT width, UINT height, UINT depth, UINT size,
+ void *parent, const struct wined3d_parent_ops *parent_ops,
+ const struct wined3d_resource_ops *resource_ops
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void *pvClientMem
+#endif
+ )
+{
+ const struct wined3d *d3d = device->wined3d;
+
+ resource->ref = 1;
+ resource->device = device;
+ resource->type = type;
+ resource->format = format;
+ resource->multisample_type = multisample_type;
+ resource->multisample_quality = multisample_quality;
+ resource->usage = usage;
+ resource->pool = pool;
+ resource->access_flags = resource_access_from_pool(pool);
+ if (usage & WINED3DUSAGE_DYNAMIC)
+ resource->access_flags |= WINED3D_RESOURCE_ACCESS_CPU;
+ resource->width = width;
+ resource->height = height;
+ resource->depth = depth;
+ resource->size = size;
+ resource->priority = 0;
+ resource->parent = parent;
+ resource->parent_ops = parent_ops;
+ resource->resource_ops = resource_ops;
+ list_init(&resource->privateData);
+
+ resource_check_usage(usage);
+
+#ifdef VBOX_WITH_WDDM
+ resource->sharerc_handle = 0;
+ resource->sharerc_flags = 0;
+ resource->sharerc_locks = 0;
+ if (pool == WINED3D_POOL_SYSTEM_MEM && pvClientMem)
+ {
+ resource->allocatedMemory = pvClientMem;
+ resource->heapMemory = NULL;
+ }
+ else
+#endif
+ {
+#ifdef VBOX_WITH_WDDM
+ if (pool == WINED3D_POOL_DEFAULT && shared_handle)
+ {
+ resource->sharerc_handle = (DWORD)*shared_handle;
+ resource->sharerc_flags = VBOXSHRC_F_SHARED;
+ if (*shared_handle)
+ resource->sharerc_flags |= VBOXSHRC_F_SHARED_OPENED;
+ }
+#endif
+
+ if (size)
+ {
+ resource->heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + RESOURCE_ALIGNMENT);
+ if (!resource->heapMemory)
+ {
+ ERR("Out of memory!\n");
+ return WINED3DERR_OUTOFVIDEOMEMORY;
+ }
+ }
+ else
+ {
+ resource->heapMemory = NULL;
+ }
+ resource->allocatedMemory = (BYTE *)(((ULONG_PTR)resource->heapMemory
+ + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
+ }
+
+#ifndef VBOX_WITH_WDDM
+ /* Check that we have enough video ram left */
+ if (pool == WINED3D_POOL_DEFAULT && d3d->flags & WINED3D_VIDMEM_ACCOUNTING)
+ {
+ if (size > wined3d_device_get_available_texture_mem(device))
+ {
+ ERR("Out of adapter memory\n");
+ HeapFree(GetProcessHeap(), 0, resource->heapMemory);
+ return WINED3DERR_OUTOFVIDEOMEMORY;
+ }
+ adapter_adjust_memory(device->adapter, size);
+ }
+#endif
+
+ device_resource_add(device, resource);
+
+ return WINED3D_OK;
+}
+
+void resource_cleanup(struct wined3d_resource *resource)
+{
+ const struct wined3d *d3d = resource->device->wined3d;
+ struct private_data *data;
+ struct list *e1, *e2;
+ HRESULT hr;
+
+ TRACE("Cleaning up resource %p.\n", resource);
+#ifndef VBOX_WITH_WDDM
+ if (resource->pool == WINED3D_POOL_DEFAULT && d3d->flags & WINED3D_VIDMEM_ACCOUNTING)
+ {
+ TRACE("Decrementing device memory pool by %u.\n", resource->size);
+ adapter_adjust_memory(resource->device->adapter, 0 - resource->size);
+ }
+#endif
+
+ LIST_FOR_EACH_SAFE(e1, e2, &resource->privateData)
+ {
+ data = LIST_ENTRY(e1, struct private_data, entry);
+ hr = wined3d_resource_free_private_data(resource, &data->tag);
+ if (FAILED(hr))
+ ERR("Failed to free private data when destroying resource %p, hr = %#x.\n", resource, hr);
+ }
+
+ HeapFree(GetProcessHeap(), 0, resource->heapMemory);
+ resource->allocatedMemory = 0;
+ resource->heapMemory = 0;
+
+ device_resource_released(resource->device, resource);
+}
+
+void resource_unload(struct wined3d_resource *resource)
+{
+ if (resource->map_count)
+ ERR("Resource %p is being unloaded while mapped.\n", resource);
+
+ context_resource_unloaded(resource->device,
+ resource, resource->type);
+}
+
+static struct private_data *resource_find_private_data(const struct wined3d_resource *resource, REFGUID tag)
+{
+ struct private_data *data;
+ struct list *entry;
+
+ TRACE("Searching for private data %s\n", debugstr_guid(tag));
+ LIST_FOR_EACH(entry, &resource->privateData)
+ {
+ data = LIST_ENTRY(entry, struct private_data, entry);
+ if (IsEqualGUID(&data->tag, tag)) {
+ TRACE("Found %p\n", data);
+ return data;
+ }
+ }
+ TRACE("Not found\n");
+ return NULL;
+}
+
+HRESULT CDECL wined3d_resource_set_private_data(struct wined3d_resource *resource, REFGUID guid,
+ const void *data, DWORD data_size, DWORD flags)
+{
+ struct private_data *d;
+
+ TRACE("resource %p, riid %s, data %p, data_size %u, flags %#x.\n",
+ resource, debugstr_guid(guid), data, data_size, flags);
+
+ wined3d_resource_free_private_data(resource, guid);
+
+ d = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d));
+ if (!d) return E_OUTOFMEMORY;
+
+ d->tag = *guid;
+ d->flags = flags;
+
+ if (flags & WINED3DSPD_IUNKNOWN)
+ {
+ if (data_size != sizeof(IUnknown *))
+ {
+ WARN("IUnknown data with size %u, returning WINED3DERR_INVALIDCALL.\n", data_size);
+ HeapFree(GetProcessHeap(), 0, d);
+ return WINED3DERR_INVALIDCALL;
+ }
+ d->ptr.object = (IUnknown *)data;
+ d->size = sizeof(IUnknown *);
+ IUnknown_AddRef(d->ptr.object);
+ }
+ else
+ {
+ d->ptr.data = HeapAlloc(GetProcessHeap(), 0, data_size);
+ if (!d->ptr.data)
+ {
+ HeapFree(GetProcessHeap(), 0, d);
+ return E_OUTOFMEMORY;
+ }
+ d->size = data_size;
+ memcpy(d->ptr.data, data, data_size);
+ }
+ list_add_tail(&resource->privateData, &d->entry);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_resource_get_private_data(const struct wined3d_resource *resource, REFGUID guid,
+ void *data, DWORD *data_size)
+{
+ const struct private_data *d;
+
+ TRACE("resource %p, guid %s, data %p, data_size %p.\n",
+ resource, debugstr_guid(guid), data, data_size);
+
+ d = resource_find_private_data(resource, guid);
+ if (!d) return WINED3DERR_NOTFOUND;
+
+ if (*data_size < d->size)
+ {
+ *data_size = d->size;
+ return WINED3DERR_MOREDATA;
+ }
+
+ if (d->flags & WINED3DSPD_IUNKNOWN)
+ {
+ *(IUnknown **)data = d->ptr.object;
+ if (resource->device->wined3d->dxVersion != 7)
+ {
+ /* D3D8 and D3D9 addref the private data, DDraw does not. This
+ * can't be handled in ddraw because it doesn't know if the
+ * pointer returned is an IUnknown * or just a blob. */
+ IUnknown_AddRef(d->ptr.object);
+ }
+ }
+ else
+ {
+ memcpy(data, d->ptr.data, d->size);
+ }
+
+ return WINED3D_OK;
+}
+HRESULT CDECL wined3d_resource_free_private_data(struct wined3d_resource *resource, REFGUID guid)
+{
+ struct private_data *data;
+
+ TRACE("resource %p, guid %s.\n", resource, debugstr_guid(guid));
+
+ data = resource_find_private_data(resource, guid);
+ if (!data) return WINED3DERR_NOTFOUND;
+
+ if (data->flags & WINED3DSPD_IUNKNOWN)
+ {
+ if (data->ptr.object)
+ IUnknown_Release(data->ptr.object);
+ }
+ else
+ {
+ HeapFree(GetProcessHeap(), 0, data->ptr.data);
+ }
+ list_remove(&data->entry);
+
+ HeapFree(GetProcessHeap(), 0, data);
+
+ return WINED3D_OK;
+}
+
+DWORD resource_set_priority(struct wined3d_resource *resource, DWORD priority)
+{
+ DWORD prev = resource->priority;
+ resource->priority = priority;
+ TRACE("resource %p, new priority %u, returning old priority %u.\n", resource, priority, prev);
+ return prev;
+}
+
+DWORD resource_get_priority(const struct wined3d_resource *resource)
+{
+ TRACE("resource %p, returning %u.\n", resource, resource->priority);
+ return resource->priority;
+}
+
+void * CDECL wined3d_resource_get_parent(const struct wined3d_resource *resource)
+{
+ return resource->parent;
+}
+
+void CDECL wined3d_resource_get_desc(const struct wined3d_resource *resource, struct wined3d_resource_desc *desc)
+{
+ desc->resource_type = resource->type;
+ desc->format = resource->format->id;
+ desc->multisample_type = resource->multisample_type;
+ desc->multisample_quality = resource->multisample_quality;
+ desc->usage = resource->usage;
+ desc->pool = resource->pool;
+ desc->width = resource->width;
+ desc->height = resource->height;
+ desc->depth = resource->depth;
+ desc->size = resource->size;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/sampler.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/sampler.c
new file mode 100644
index 00000000..1775d7b6
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/sampler.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2012 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+
+ULONG CDECL wined3d_sampler_incref(struct wined3d_sampler *sampler)
+{
+ ULONG refcount = InterlockedIncrement(&sampler->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", sampler, refcount);
+
+ return refcount;
+}
+
+ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler)
+{
+ ULONG refcount = InterlockedDecrement(&sampler->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", sampler, refcount);
+
+ if (!refcount)
+ HeapFree(GetProcessHeap(), 0, sampler);
+
+ return refcount;
+}
+
+void * CDECL wined3d_sampler_get_parent(const struct wined3d_sampler *sampler)
+{
+ TRACE("sampler %p.\n", sampler);
+
+ return sampler->parent;
+}
+
+static void wined3d_sampler_init(struct wined3d_sampler *sampler, void *parent)
+{
+ sampler->refcount = 1;
+ sampler->parent = parent;
+}
+
+HRESULT CDECL wined3d_sampler_create(void *parent, struct wined3d_sampler **sampler)
+{
+ struct wined3d_sampler *object;
+
+ TRACE("parent %p, sampler %p.\n", parent, sampler);
+
+ if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+ return E_OUTOFMEMORY;
+
+ wined3d_sampler_init(object, parent);
+
+ TRACE("Created sampler %p.\n", object);
+ *sampler = object;
+
+ return WINED3D_OK;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/shader.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/shader.c
new file mode 100644
index 00000000..b76ccb17
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/shader.c
@@ -0,0 +1,2615 @@
+/*
+ * Copyright 2002-2003 Jason Edmeades
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2004 Christian Costa
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2006 Ivan Gyurdiev
+ * Copyright 2007-2008, 2013 Stefan Dösinger for CodeWeavers
+ * Copyright 2009-2011 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
+
+#ifdef VBOX_WINE_WITH_SHADER_CACHE
+static void shader_chache_put(PVBOXEXT_HASHCACHE pCache, struct wined3d_shader *shader);
+#endif
+
+static const char * const shader_opcode_names[] =
+{
+ /* WINED3DSIH_ABS */ "abs",
+ /* WINED3DSIH_ADD */ "add",
+ /* WINED3DSIH_AND */ "and",
+ /* WINED3DSIH_BEM */ "bem",
+ /* WINED3DSIH_BREAK */ "break",
+ /* WINED3DSIH_BREAKC */ "breakc",
+ /* WINED3DSIH_BREAKP */ "breakp",
+ /* WINED3DSIH_CALL */ "call",
+ /* WINED3DSIH_CALLNZ */ "callnz",
+ /* WINED3DSIH_CMP */ "cmp",
+ /* WINED3DSIH_CND */ "cnd",
+ /* WINED3DSIH_CRS */ "crs",
+ /* WINED3DSIH_CUT */ "cut",
+ /* WINED3DSIH_DCL */ "dcl",
+ /* WINED3DSIH_DCL_CONSTANT_BUFFER */ "dcl_constantBuffer",
+ /* WINED3DSIH_DCL_INPUT_PRIMITIVE */ "dcl_inputPrimitive",
+ /* WINED3DSIH_DCL_OUTPUT_TOPOLOGY */ "dcl_outputTopology",
+ /* WINED3DSIH_DCL_VERTICES_OUT */ "dcl_maxOutputVertexCount",
+ /* WINED3DSIH_DEF */ "def",
+ /* WINED3DSIH_DEFB */ "defb",
+ /* WINED3DSIH_DEFI */ "defi",
+ /* WINED3DSIH_DIV */ "div",
+ /* WINED3DSIH_DP2ADD */ "dp2add",
+ /* WINED3DSIH_DP3 */ "dp3",
+ /* WINED3DSIH_DP4 */ "dp4",
+ /* WINED3DSIH_DST */ "dst",
+ /* WINED3DSIH_DSX */ "dsx",
+ /* WINED3DSIH_DSY */ "dsy",
+ /* WINED3DSIH_ELSE */ "else",
+ /* WINED3DSIH_EMIT */ "emit",
+ /* WINED3DSIH_ENDIF */ "endif",
+ /* WINED3DSIH_ENDLOOP */ "endloop",
+ /* WINED3DSIH_ENDREP */ "endrep",
+ /* WINED3DSIH_EQ */ "eq",
+ /* WINED3DSIH_EXP */ "exp",
+ /* WINED3DSIH_EXPP */ "expp",
+ /* WINED3DSIH_FRC */ "frc",
+ /* WINED3DSIH_FTOI */ "ftoi",
+ /* WINED3DSIH_GE */ "ge",
+ /* WINED3DSIH_IADD */ "iadd",
+ /* WINED3DSIH_IEQ */ "ieq",
+ /* WINED3DSIH_IF */ "if",
+ /* WINED3DSIH_IFC */ "ifc",
+ /* WINED3DSIH_IGE */ "ige",
+ /* WINED3DSIH_IMUL */ "imul",
+ /* WINED3DSIH_ITOF */ "itof",
+ /* WINED3DSIH_LABEL */ "label",
+ /* WINED3DSIH_LD */ "ld",
+ /* WINED3DSIH_LIT */ "lit",
+ /* WINED3DSIH_LOG */ "log",
+ /* WINED3DSIH_LOGP */ "logp",
+ /* WINED3DSIH_LOOP */ "loop",
+ /* WINED3DSIH_LRP */ "lrp",
+ /* WINED3DSIH_LT */ "lt",
+ /* WINED3DSIH_M3x2 */ "m3x2",
+ /* WINED3DSIH_M3x3 */ "m3x3",
+ /* WINED3DSIH_M3x4 */ "m3x4",
+ /* WINED3DSIH_M4x3 */ "m4x3",
+ /* WINED3DSIH_M4x4 */ "m4x4",
+ /* WINED3DSIH_MAD */ "mad",
+ /* WINED3DSIH_MAX */ "max",
+ /* WINED3DSIH_MIN */ "min",
+ /* WINED3DSIH_MOV */ "mov",
+ /* WINED3DSIH_MOVA */ "mova",
+ /* WINED3DSIH_MOVC */ "movc",
+ /* WINED3DSIH_MUL */ "mul",
+ /* WINED3DSIH_NOP */ "nop",
+ /* WINED3DSIH_NRM */ "nrm",
+ /* WINED3DSIH_PHASE */ "phase",
+ /* WINED3DSIH_POW */ "pow",
+ /* WINED3DSIH_RCP */ "rcp",
+ /* WINED3DSIH_REP */ "rep",
+ /* WINED3DSIH_RET */ "ret",
+ /* WINED3DSIH_ROUND_NI */ "round_ni",
+ /* WINED3DSIH_RSQ */ "rsq",
+ /* WINED3DSIH_SAMPLE */ "sample",
+ /* WINED3DSIH_SAMPLE_GRAD */ "sample_d",
+ /* WINED3DSIH_SAMPLE_LOD */ "sample_l",
+ /* WINED3DSIH_SETP */ "setp",
+ /* WINED3DSIH_SGE */ "sge",
+ /* WINED3DSIH_SGN */ "sgn",
+ /* WINED3DSIH_SINCOS */ "sincos",
+ /* WINED3DSIH_SLT */ "slt",
+ /* WINED3DSIH_SQRT */ "sqrt",
+ /* WINED3DSIH_SUB */ "sub",
+ /* WINED3DSIH_TEX */ "texld",
+ /* WINED3DSIH_TEXBEM */ "texbem",
+ /* WINED3DSIH_TEXBEML */ "texbeml",
+ /* WINED3DSIH_TEXCOORD */ "texcrd",
+ /* WINED3DSIH_TEXDEPTH */ "texdepth",
+ /* WINED3DSIH_TEXDP3 */ "texdp3",
+ /* WINED3DSIH_TEXDP3TEX */ "texdp3tex",
+ /* WINED3DSIH_TEXKILL */ "texkill",
+ /* WINED3DSIH_TEXLDD */ "texldd",
+ /* WINED3DSIH_TEXLDL */ "texldl",
+ /* WINED3DSIH_TEXM3x2DEPTH */ "texm3x2depth",
+ /* WINED3DSIH_TEXM3x2PAD */ "texm3x2pad",
+ /* WINED3DSIH_TEXM3x2TEX */ "texm3x2tex",
+ /* WINED3DSIH_TEXM3x3 */ "texm3x3",
+ /* WINED3DSIH_TEXM3x3DIFF */ "texm3x3diff",
+ /* WINED3DSIH_TEXM3x3PAD */ "texm3x3pad",
+ /* WINED3DSIH_TEXM3x3SPEC */ "texm3x3spec",
+ /* WINED3DSIH_TEXM3x3TEX */ "texm3x3tex",
+ /* WINED3DSIH_TEXM3x3VSPEC */ "texm3x3vspec",
+ /* WINED3DSIH_TEXREG2AR */ "texreg2ar",
+ /* WINED3DSIH_TEXREG2GB */ "texreg2gb",
+ /* WINED3DSIH_TEXREG2RGB */ "texreg2rgb",
+ /* WINED3DSIH_UDIV */ "udiv",
+ /* WINED3DSIH_USHR */ "ushr",
+ /* WINED3DSIH_UTOF */ "utof",
+ /* WINED3DSIH_XOR */ "xor",
+};
+
+static const char * const semantic_names[] =
+{
+ /* WINED3D_DECL_USAGE_POSITION */ "SV_POSITION",
+ /* WINED3D_DECL_USAGE_BLEND_WEIGHT */ "BLENDWEIGHT",
+ /* WINED3D_DECL_USAGE_BLEND_INDICES */ "BLENDINDICES",
+ /* WINED3D_DECL_USAGE_NORMAL */ "NORMAL",
+ /* WINED3D_DECL_USAGE_PSIZE */ "PSIZE",
+ /* WINED3D_DECL_USAGE_TEXCOORD */ "TEXCOORD",
+ /* WINED3D_DECL_USAGE_TANGENT */ "TANGENT",
+ /* WINED3D_DECL_USAGE_BINORMAL */ "BINORMAL",
+ /* WINED3D_DECL_USAGE_TESS_FACTOR */ "TESSFACTOR",
+ /* WINED3D_DECL_USAGE_POSITIONT */ "POSITIONT",
+ /* WINED3D_DECL_USAGE_COLOR */ "COLOR",
+ /* WINED3D_DECL_USAGE_FOG */ "FOG",
+ /* WINED3D_DECL_USAGE_DEPTH */ "DEPTH",
+ /* WINED3D_DECL_USAGE_SAMPLE */ "SAMPLE",
+};
+
+static const char *shader_semantic_name_from_usage(enum wined3d_decl_usage usage)
+{
+ if (usage >= sizeof(semantic_names) / sizeof(*semantic_names))
+ {
+ FIXME("Unrecognized usage %#x.\n", usage);
+ return "UNRECOGNIZED";
+ }
+
+ return semantic_names[usage];
+}
+
+static enum wined3d_decl_usage shader_usage_from_semantic_name(const char *name)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof(semantic_names) / sizeof(*semantic_names); ++i)
+ {
+ if (!strcmp(name, semantic_names[i])) return i;
+ }
+
+ return ~0U;
+}
+
+BOOL shader_match_semantic(const char *semantic_name, enum wined3d_decl_usage usage)
+{
+ return !strcmp(semantic_name, shader_semantic_name_from_usage(usage));
+}
+
+static void shader_signature_from_semantic(struct wined3d_shader_signature_element *e,
+ const struct wined3d_shader_semantic *s)
+{
+ e->semantic_name = shader_semantic_name_from_usage(s->usage);
+ e->semantic_idx = s->usage_idx;
+ e->sysval_semantic = 0;
+ e->component_type = 0;
+ e->register_idx = s->reg.reg.idx[0].offset;
+ e->mask = s->reg.write_mask;
+}
+
+static void shader_signature_from_usage(struct wined3d_shader_signature_element *e,
+ enum wined3d_decl_usage usage, UINT usage_idx, UINT reg_idx, DWORD write_mask)
+{
+ e->semantic_name = shader_semantic_name_from_usage(usage);
+ e->semantic_idx = usage_idx;
+ e->sysval_semantic = 0;
+ e->component_type = 0;
+ e->register_idx = reg_idx;
+ e->mask = write_mask;
+}
+
+static const struct wined3d_shader_frontend *shader_select_frontend(DWORD version_token)
+{
+ switch (version_token >> 16)
+ {
+ case WINED3D_SM1_VS:
+ case WINED3D_SM1_PS:
+ return &sm1_shader_frontend;
+
+ case WINED3D_SM4_PS:
+ case WINED3D_SM4_VS:
+ case WINED3D_SM4_GS:
+ return &sm4_shader_frontend;
+
+ default:
+ FIXME("Unrecognised version token %#x\n", version_token);
+ return NULL;
+ }
+}
+
+void shader_buffer_clear(struct wined3d_shader_buffer *buffer)
+{
+ buffer->buffer[0] = '\0';
+ buffer->content_size = 0;
+ buffer->lineNo = 0;
+ buffer->newline = TRUE;
+}
+
+BOOL shader_buffer_init(struct wined3d_shader_buffer *buffer)
+{
+ buffer->buffer = HeapAlloc(GetProcessHeap(), 0, SHADER_PGMSIZE);
+ if (!buffer->buffer)
+ {
+ ERR("Failed to allocate shader buffer memory.\n");
+ return FALSE;
+ }
+ buffer->buffer_size = SHADER_PGMSIZE;
+
+ shader_buffer_clear(buffer);
+ return TRUE;
+}
+
+void shader_buffer_free(struct wined3d_shader_buffer *buffer)
+{
+ HeapFree(GetProcessHeap(), 0, buffer->buffer);
+}
+
+int shader_vaddline(struct wined3d_shader_buffer *buffer, const char *format, va_list args)
+{
+ char *base = buffer->buffer + buffer->content_size;
+ int rc;
+ char *new_buffer;
+
+ while(1)
+ {
+ rc = vsnprintf(base, buffer->buffer_size - buffer->content_size, format, args);
+ if (rc < 0 /* C89 */ || (unsigned int)rc >= buffer->buffer_size - buffer->content_size /* C99 */)
+ {
+ new_buffer = HeapReAlloc(GetProcessHeap(), 0, buffer->buffer, buffer->buffer_size * 2);
+ if (!new_buffer)
+ {
+ ERR("The buffer allocated for the shader program string is too small at %d bytes.\n", buffer->buffer_size);
+ buffer->content_size = buffer->buffer_size - 1;
+ return -1;
+ }
+ buffer->buffer = new_buffer;
+ buffer->buffer_size = buffer->buffer_size * 2;
+ base = buffer->buffer + buffer->content_size;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (buffer->newline)
+ {
+ TRACE("GL HW (%u, %u) : %s", buffer->lineNo + 1, buffer->content_size, base);
+ buffer->newline = FALSE;
+ }
+ else
+ {
+ TRACE("%s", base);
+ }
+
+ buffer->content_size += rc;
+ if (buffer->buffer[buffer->content_size-1] == '\n')
+ {
+ ++buffer->lineNo;
+ buffer->newline = TRUE;
+ }
+
+ return 0;
+}
+
+int shader_addline(struct wined3d_shader_buffer *buffer, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start(args, format);
+ ret = shader_vaddline(buffer, format, args);
+ va_end(args);
+
+ return ret;
+}
+
+static void shader_init(struct wined3d_shader *shader, struct wined3d_device *device,
+ void *parent, const struct wined3d_parent_ops *parent_ops)
+{
+ shader->ref = 1;
+ shader->device = device;
+ shader->parent = parent;
+ shader->parent_ops = parent_ops;
+ list_init(&shader->linked_programs);
+ list_add_head(&device->shaders, &shader->shader_list_entry);
+}
+
+/* Convert floating point offset relative to a register file to an absolute
+ * offset for float constants. */
+static unsigned int shader_get_float_offset(enum wined3d_shader_register_type register_type, UINT register_idx)
+{
+ switch (register_type)
+ {
+ case WINED3DSPR_CONST: return register_idx;
+ case WINED3DSPR_CONST2: return 2048 + register_idx;
+ case WINED3DSPR_CONST3: return 4096 + register_idx;
+ case WINED3DSPR_CONST4: return 6144 + register_idx;
+ default:
+ FIXME("Unsupported register type: %u.\n", register_type);
+ return register_idx;
+ }
+}
+
+static void shader_delete_constant_list(struct list *clist)
+{
+ struct wined3d_shader_lconst *constant;
+ struct list *ptr;
+
+ ptr = list_head(clist);
+ while (ptr)
+ {
+ constant = LIST_ENTRY(ptr, struct wined3d_shader_lconst, entry);
+ ptr = list_next(clist, ptr);
+ HeapFree(GetProcessHeap(), 0, constant);
+ }
+ list_init(clist);
+}
+
+static inline void set_bitmap_bit(DWORD *bitmap, DWORD bit)
+{
+ DWORD idx, shift;
+ idx = bit >> 5;
+ shift = bit & 0x1f;
+ bitmap[idx] |= (1 << shift);
+}
+
+static void shader_record_register_usage(struct wined3d_shader *shader, struct wined3d_shader_reg_maps *reg_maps,
+ const struct wined3d_shader_register *reg, enum wined3d_shader_type shader_type)
+{
+ switch (reg->type)
+ {
+ case WINED3DSPR_TEXTURE: /* WINED3DSPR_ADDR */
+ if (shader_type == WINED3D_SHADER_TYPE_PIXEL)
+ reg_maps->texcoord |= 1 << reg->idx[0].offset;
+ else
+ reg_maps->address |= 1 << reg->idx[0].offset;
+ break;
+
+ case WINED3DSPR_TEMP:
+ reg_maps->temporary |= 1 << reg->idx[0].offset;
+ break;
+
+ case WINED3DSPR_INPUT:
+ if (shader_type == WINED3D_SHADER_TYPE_PIXEL)
+ {
+ if (reg->idx[0].rel_addr)
+ {
+ /* If relative addressing is used, we must assume that all registers
+ * are used. Even if it is a construct like v3[aL], we can't assume
+ * that v0, v1 and v2 aren't read because aL can be negative */
+ unsigned int i;
+ for (i = 0; i < MAX_REG_INPUT; ++i)
+ {
+ shader->u.ps.input_reg_used[i] = TRUE;
+ }
+ }
+ else
+ {
+ shader->u.ps.input_reg_used[reg->idx[0].offset] = TRUE;
+ }
+ }
+ else
+ reg_maps->input_registers |= 1 << reg->idx[0].offset;
+ break;
+
+ case WINED3DSPR_RASTOUT:
+ if (reg->idx[0].offset == 1)
+ reg_maps->fog = 1;
+ break;
+
+ case WINED3DSPR_MISCTYPE:
+ if (shader_type == WINED3D_SHADER_TYPE_PIXEL)
+ {
+ if (!reg->idx[0].offset)
+ reg_maps->vpos = 1;
+ else if (reg->idx[0].offset == 1)
+ reg_maps->usesfacing = 1;
+ }
+ break;
+
+ case WINED3DSPR_CONST:
+ if (reg->idx[0].rel_addr)
+ {
+ if (reg->idx[0].offset < reg_maps->min_rel_offset)
+ reg_maps->min_rel_offset = reg->idx[0].offset;
+ if (reg->idx[0].offset > reg_maps->max_rel_offset)
+ reg_maps->max_rel_offset = reg->idx[0].offset;
+ reg_maps->usesrelconstF = TRUE;
+ }
+ else
+ {
+ set_bitmap_bit(reg_maps->constf, reg->idx[0].offset);
+ }
+ break;
+
+ case WINED3DSPR_CONSTINT:
+ reg_maps->integer_constants |= (1 << reg->idx[0].offset);
+ break;
+
+ case WINED3DSPR_CONSTBOOL:
+ reg_maps->boolean_constants |= (1 << reg->idx[0].offset);
+ break;
+
+ case WINED3DSPR_COLOROUT:
+ reg_maps->rt_mask |= (1 << reg->idx[0].offset);
+ break;
+
+ default:
+ TRACE("Not recording register of type %#x and [%#x][%#x].\n",
+ reg->type, reg->idx[0].offset, reg->idx[1].offset);
+ break;
+ }
+}
+
+static unsigned int get_instr_extra_regcount(enum WINED3D_SHADER_INSTRUCTION_HANDLER instr, unsigned int param)
+{
+ switch (instr)
+ {
+ case WINED3DSIH_M4x4:
+ case WINED3DSIH_M3x4:
+ return param == 1 ? 3 : 0;
+
+ case WINED3DSIH_M4x3:
+ case WINED3DSIH_M3x3:
+ return param == 1 ? 2 : 0;
+
+ case WINED3DSIH_M3x2:
+ return param == 1 ? 1 : 0;
+
+ default:
+ return 0;
+ }
+}
+
+/* Note that this does not count the loop register as an address register. */
+static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const struct wined3d_shader_frontend *fe,
+ struct wined3d_shader_reg_maps *reg_maps, struct wined3d_shader_signature_element *input_signature,
+ struct wined3d_shader_signature_element *output_signature, const DWORD *byte_code, DWORD constf_size)
+{
+ unsigned int cur_loop_depth = 0, max_loop_depth = 0;
+ void *fe_data = shader->frontend_data;
+ struct wined3d_shader_version shader_version;
+ const DWORD *ptr = byte_code;
+
+ memset(reg_maps, 0, sizeof(*reg_maps));
+ reg_maps->min_rel_offset = ~0U;
+
+ fe->shader_read_header(fe_data, &ptr, &shader_version);
+ reg_maps->shader_version = shader_version;
+
+ reg_maps->constf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof(*reg_maps->constf) * ((constf_size + 31) / 32));
+ if (!reg_maps->constf)
+ {
+ ERR("Failed to allocate constant map memory.\n");
+ return E_OUTOFMEMORY;
+ }
+
+ while (!fe->shader_is_end(fe_data, &ptr))
+ {
+ struct wined3d_shader_instruction ins;
+
+ /* Fetch opcode. */
+ fe->shader_read_instruction(fe_data, &ptr, &ins);
+
+ /* Unhandled opcode, and its parameters. */
+ if (ins.handler_idx == WINED3DSIH_TABLE_SIZE)
+ {
+ TRACE("Skipping unrecognized instruction.\n");
+ continue;
+ }
+
+ /* Handle declarations. */
+ if (ins.handler_idx == WINED3DSIH_DCL)
+ {
+ struct wined3d_shader_semantic *semantic = &ins.declaration.semantic;
+
+ switch (semantic->reg.reg.type)
+ {
+ /* Mark input registers used. */
+ case WINED3DSPR_INPUT:
+ reg_maps->input_registers |= 1 << semantic->reg.reg.idx[0].offset;
+ shader_signature_from_semantic(&input_signature[semantic->reg.reg.idx[0].offset], semantic);
+ break;
+
+ /* Vertex shader: mark 3.0 output registers used, save token. */
+ case WINED3DSPR_OUTPUT:
+ reg_maps->output_registers |= 1 << semantic->reg.reg.idx[0].offset;
+ shader_signature_from_semantic(&output_signature[semantic->reg.reg.idx[0].offset], semantic);
+ if (semantic->usage == WINED3D_DECL_USAGE_FOG)
+ reg_maps->fog = 1;
+ break;
+
+ /* Save sampler usage token. */
+ case WINED3DSPR_SAMPLER:
+ reg_maps->sampler_type[semantic->reg.reg.idx[0].offset] = semantic->sampler_type;
+ break;
+
+ default:
+ TRACE("Not recording DCL register type %#x.\n", semantic->reg.reg.type);
+ break;
+ }
+ }
+ else if (ins.handler_idx == WINED3DSIH_DCL_CONSTANT_BUFFER)
+ {
+ struct wined3d_shader_register *reg = &ins.declaration.src.reg;
+ if (reg->idx[0].offset >= WINED3D_MAX_CBS)
+ ERR("Invalid CB index %u.\n", reg->idx[0].offset);
+ else
+ reg_maps->cb_sizes[reg->idx[0].offset] = reg->idx[1].offset;
+ }
+ else if (ins.handler_idx == WINED3DSIH_DCL_INPUT_PRIMITIVE)
+ {
+ if (shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY)
+ shader->u.gs.input_type = ins.declaration.primitive_type;
+ else
+ FIXME("Invalid instruction %#x for shader type %#x.\n",
+ ins.handler_idx, shader_version.type);
+ }
+ else if (ins.handler_idx == WINED3DSIH_DCL_OUTPUT_TOPOLOGY)
+ {
+ if (shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY)
+ shader->u.gs.output_type = ins.declaration.primitive_type;
+ else
+ FIXME("Invalid instruction %#x for shader type %#x.\n",
+ ins.handler_idx, shader_version.type);
+ }
+ else if (ins.handler_idx == WINED3DSIH_DCL_VERTICES_OUT)
+ {
+ if (shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY)
+ shader->u.gs.vertices_out = ins.declaration.count;
+ else
+ FIXME("Invalid instruction %#x for shader type %#x.\n",
+ ins.handler_idx, shader_version.type);
+ }
+ else if (ins.handler_idx == WINED3DSIH_DEF)
+ {
+ struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst));
+ float *value;
+ if (!lconst) return E_OUTOFMEMORY;
+
+ lconst->idx = ins.dst[0].reg.idx[0].offset;
+ memcpy(lconst->value, ins.src[0].reg.immconst_data, 4 * sizeof(DWORD));
+ value = (float *)lconst->value;
+
+ /* In pixel shader 1.X shaders, the constants are clamped between [-1;1] */
+ if (shader_version.major == 1 && shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
+ {
+ if (value[0] < -1.0f) value[0] = -1.0f;
+ else if (value[0] > 1.0f) value[0] = 1.0f;
+ if (value[1] < -1.0f) value[1] = -1.0f;
+ else if (value[1] > 1.0f) value[1] = 1.0f;
+ if (value[2] < -1.0f) value[2] = -1.0f;
+ else if (value[2] > 1.0f) value[2] = 1.0f;
+ if (value[3] < -1.0f) value[3] = -1.0f;
+ else if (value[3] > 1.0f) value[3] = 1.0f;
+ }
+
+ list_add_head(&shader->constantsF, &lconst->entry);
+
+ if (isinf(value[0]) || isnan(value[0]) || isinf(value[1]) || isnan(value[1])
+ || isinf(value[2]) || isnan(value[2]) || isinf(value[3]) || isnan(value[3]))
+ {
+ shader->lconst_inf_or_nan = TRUE;
+ }
+ }
+ else if (ins.handler_idx == WINED3DSIH_DEFI)
+ {
+ struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst));
+ if (!lconst) return E_OUTOFMEMORY;
+
+ lconst->idx = ins.dst[0].reg.idx[0].offset;
+ memcpy(lconst->value, ins.src[0].reg.immconst_data, 4 * sizeof(DWORD));
+
+ list_add_head(&shader->constantsI, &lconst->entry);
+ reg_maps->local_int_consts |= (1 << lconst->idx);
+ }
+ else if (ins.handler_idx == WINED3DSIH_DEFB)
+ {
+ struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst));
+ if (!lconst) return E_OUTOFMEMORY;
+
+ lconst->idx = ins.dst[0].reg.idx[0].offset;
+ memcpy(lconst->value, ins.src[0].reg.immconst_data, sizeof(DWORD));
+
+ list_add_head(&shader->constantsB, &lconst->entry);
+ reg_maps->local_bool_consts |= (1 << lconst->idx);
+ }
+ /* For subroutine prototypes. */
+ else if (ins.handler_idx == WINED3DSIH_LABEL)
+ {
+ reg_maps->labels |= 1 << ins.src[0].reg.idx[0].offset;
+ }
+ /* Set texture, address, temporary registers. */
+ else
+ {
+ BOOL color0_mov = FALSE;
+ unsigned int i;
+
+ /* This will loop over all the registers and try to
+ * make a bitmask of the ones we're interested in.
+ *
+ * Relative addressing tokens are ignored, but that's
+ * okay, since we'll catch any address registers when
+ * they are initialized (required by spec). */
+ for (i = 0; i < ins.dst_count; ++i)
+ {
+ shader_record_register_usage(shader, reg_maps, &ins.dst[i].reg, shader_version.type);
+
+ /* WINED3DSPR_TEXCRDOUT is the same as WINED3DSPR_OUTPUT. _OUTPUT can be > MAX_REG_TEXCRD and
+ * is used in >= 3.0 shaders. Filter 3.0 shaders to prevent overflows, and also filter pixel
+ * shaders because TECRDOUT isn't used in them, but future register types might cause issues */
+ if (shader_version.type == WINED3D_SHADER_TYPE_VERTEX && shader_version.major < 3)
+ {
+ UINT idx = ins.dst[i].reg.idx[0].offset;
+
+ switch (ins.dst[i].reg.type)
+ {
+ case WINED3DSPR_RASTOUT:
+ switch (idx)
+ {
+ case 0: /* oPos */
+ reg_maps->output_registers |= 1 << 10;
+ shader_signature_from_usage(&output_signature[10],
+ WINED3D_DECL_USAGE_POSITION, 0, 10, WINED3DSP_WRITEMASK_ALL);
+ break;
+
+ case 1: /* oFog */
+ reg_maps->output_registers |= 1 << 11;
+ shader_signature_from_usage(&output_signature[11],
+ WINED3D_DECL_USAGE_FOG, 0, 11, WINED3DSP_WRITEMASK_0);
+ break;
+
+ case 2: /* oPts */
+ reg_maps->output_registers |= 1 << 11;
+ shader_signature_from_usage(&output_signature[11],
+ WINED3D_DECL_USAGE_PSIZE, 0, 11, WINED3DSP_WRITEMASK_1);
+ break;
+ }
+ break;
+
+ case WINED3DSPR_ATTROUT:
+ if (idx < 2)
+ {
+ idx += 8;
+ if (reg_maps->output_registers & (1 << idx))
+ {
+ output_signature[idx].mask |= ins.dst[i].write_mask;
+ }
+ else
+ {
+ reg_maps->output_registers |= 1 << idx;
+ shader_signature_from_usage(&output_signature[idx],
+ WINED3D_DECL_USAGE_COLOR, idx - 8, idx, ins.dst[i].write_mask);
+ }
+ }
+ break;
+
+ case WINED3DSPR_TEXCRDOUT:
+
+ reg_maps->texcoord_mask[idx] |= ins.dst[i].write_mask;
+ if (reg_maps->output_registers & (1 << idx))
+ {
+ output_signature[idx].mask |= ins.dst[i].write_mask;
+ }
+ else
+ {
+ reg_maps->output_registers |= 1 << idx;
+ shader_signature_from_usage(&output_signature[idx],
+ WINED3D_DECL_USAGE_TEXCOORD, idx, idx, ins.dst[i].write_mask);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
+ {
+ if (ins.dst[i].reg.type == WINED3DSPR_COLOROUT && !ins.dst[i].reg.idx[0].offset)
+ {
+ /* Many 2.0 and 3.0 pixel shaders end with a MOV from a temp register to
+ * COLOROUT 0. If we know this in advance, the ARB shader backend can skip
+ * the mov and perform the sRGB write correction from the source register.
+ *
+ * However, if the mov is only partial, we can't do this, and if the write
+ * comes from an instruction other than MOV it is hard to do as well. If
+ * COLOROUT 0 is overwritten partially later, the marker is dropped again. */
+ shader->u.ps.color0_mov = FALSE;
+ if (ins.handler_idx == WINED3DSIH_MOV
+ && ins.dst[i].write_mask == WINED3DSP_WRITEMASK_ALL)
+ {
+ /* Used later when the source register is read. */
+ color0_mov = TRUE;
+ }
+ }
+ /* Also drop the MOV marker if the source register is overwritten prior to the shader
+ * end
+ */
+ else if (ins.dst[i].reg.type == WINED3DSPR_TEMP
+ && ins.dst[i].reg.idx[0].offset == shader->u.ps.color0_reg)
+ {
+ shader->u.ps.color0_mov = FALSE;
+ }
+ }
+
+ /* Declare 1.x samplers implicitly, based on the destination reg. number. */
+ if (shader_version.major == 1
+ && (ins.handler_idx == WINED3DSIH_TEX
+ || ins.handler_idx == WINED3DSIH_TEXBEM
+ || ins.handler_idx == WINED3DSIH_TEXBEML
+ || ins.handler_idx == WINED3DSIH_TEXDP3TEX
+ || ins.handler_idx == WINED3DSIH_TEXM3x2TEX
+ || ins.handler_idx == WINED3DSIH_TEXM3x3SPEC
+ || ins.handler_idx == WINED3DSIH_TEXM3x3TEX
+ || ins.handler_idx == WINED3DSIH_TEXM3x3VSPEC
+ || ins.handler_idx == WINED3DSIH_TEXREG2AR
+ || ins.handler_idx == WINED3DSIH_TEXREG2GB
+ || ins.handler_idx == WINED3DSIH_TEXREG2RGB))
+ {
+ /* Fake sampler usage, only set reserved bit and type. */
+ DWORD sampler_code = ins.dst[i].reg.idx[0].offset;
+
+ TRACE("Setting fake 2D sampler for 1.x pixelshader.\n");
+ reg_maps->sampler_type[sampler_code] = WINED3DSTT_2D;
+
+ /* texbem is only valid with < 1.4 pixel shaders */
+ if (ins.handler_idx == WINED3DSIH_TEXBEM
+ || ins.handler_idx == WINED3DSIH_TEXBEML)
+ {
+ reg_maps->bumpmat |= 1 << ins.dst[i].reg.idx[0].offset;
+ if (ins.handler_idx == WINED3DSIH_TEXBEML)
+ {
+ reg_maps->luminanceparams |= 1 << ins.dst[i].reg.idx[0].offset;
+ }
+ }
+ }
+ else if (ins.handler_idx == WINED3DSIH_BEM)
+ {
+ reg_maps->bumpmat |= 1 << ins.dst[i].reg.idx[0].offset;
+ }
+ }
+
+ if (ins.handler_idx == WINED3DSIH_NRM) reg_maps->usesnrm = 1;
+ else if (ins.handler_idx == WINED3DSIH_DSY) reg_maps->usesdsy = 1;
+ else if (ins.handler_idx == WINED3DSIH_DSX) reg_maps->usesdsx = 1;
+ else if (ins.handler_idx == WINED3DSIH_TEXLDD) reg_maps->usestexldd = 1;
+ else if (ins.handler_idx == WINED3DSIH_TEXLDL) reg_maps->usestexldl = 1;
+ else if (ins.handler_idx == WINED3DSIH_MOVA) reg_maps->usesmova = 1;
+ else if (ins.handler_idx == WINED3DSIH_IFC) reg_maps->usesifc = 1;
+ else if (ins.handler_idx == WINED3DSIH_CALL) reg_maps->usescall = 1;
+ else if (ins.handler_idx == WINED3DSIH_POW) reg_maps->usespow = 1;
+ else if (ins.handler_idx == WINED3DSIH_LOOP
+ || ins.handler_idx == WINED3DSIH_REP)
+ {
+ ++cur_loop_depth;
+ if (cur_loop_depth > max_loop_depth)
+ max_loop_depth = cur_loop_depth;
+ }
+ else if (ins.handler_idx == WINED3DSIH_ENDLOOP
+ || ins.handler_idx == WINED3DSIH_ENDREP)
+ --cur_loop_depth;
+
+ if (ins.predicate)
+ shader_record_register_usage(shader, reg_maps, &ins.predicate->reg, shader_version.type);
+
+ for (i = 0; i < ins.src_count; ++i)
+ {
+ unsigned int count = get_instr_extra_regcount(ins.handler_idx, i);
+ struct wined3d_shader_register reg = ins.src[i].reg;
+
+ shader_record_register_usage(shader, reg_maps, &ins.src[i].reg, shader_version.type);
+ while (count)
+ {
+ ++reg.idx[0].offset;
+ shader_record_register_usage(shader, reg_maps, &reg, shader_version.type);
+ --count;
+ }
+
+ if (color0_mov)
+ {
+ if (ins.src[i].reg.type == WINED3DSPR_TEMP
+ && ins.src[i].swizzle == WINED3DSP_NOSWIZZLE)
+ {
+ shader->u.ps.color0_mov = TRUE;
+ shader->u.ps.color0_reg = ins.src[i].reg.idx[0].offset;
+ }
+ }
+ }
+ }
+ }
+ reg_maps->loop_depth = max_loop_depth;
+
+ /* PS before 2.0 don't have explicit color outputs. Instead the value of
+ * R0 is written to the render target. */
+ if (shader_version.major < 2 && shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
+ reg_maps->rt_mask |= (1 << 0);
+
+ shader->functionLength = ((const char *)ptr - (const char *)byte_code);
+
+ return WINED3D_OK;
+}
+
+unsigned int shader_find_free_input_register(const struct wined3d_shader_reg_maps *reg_maps, unsigned int max)
+{
+ DWORD map = 1 << max;
+ map |= map - 1;
+ map &= reg_maps->shader_version.major < 3 ? ~reg_maps->texcoord : ~reg_maps->input_registers;
+
+ return wined3d_log2i(map);
+}
+
+static void shader_dump_decl_usage(const struct wined3d_shader_semantic *semantic,
+ const struct wined3d_shader_version *shader_version)
+{
+ TRACE("dcl");
+
+ if (semantic->reg.reg.type == WINED3DSPR_SAMPLER)
+ {
+ switch (semantic->sampler_type)
+ {
+ case WINED3DSTT_2D: TRACE("_2d"); break;
+ case WINED3DSTT_CUBE: TRACE("_cube"); break;
+ case WINED3DSTT_VOLUME: TRACE("_volume"); break;
+ default: TRACE("_unknown_ttype(0x%08x)", semantic->sampler_type);
+ }
+ }
+ else
+ {
+ /* Pixel shaders 3.0 don't have usage semantics. */
+ if (shader_version->major < 3 && shader_version->type == WINED3D_SHADER_TYPE_PIXEL) return;
+ else TRACE("_");
+
+ switch (semantic->usage)
+ {
+ case WINED3D_DECL_USAGE_POSITION:
+ TRACE("position%u", semantic->usage_idx);
+ break;
+
+ case WINED3D_DECL_USAGE_BLEND_INDICES:
+ TRACE("blend");
+ break;
+
+ case WINED3D_DECL_USAGE_BLEND_WEIGHT:
+ TRACE("weight");
+ break;
+
+ case WINED3D_DECL_USAGE_NORMAL:
+ TRACE("normal%u", semantic->usage_idx);
+ break;
+
+ case WINED3D_DECL_USAGE_PSIZE:
+ TRACE("psize");
+ break;
+
+ case WINED3D_DECL_USAGE_COLOR:
+ if (!semantic->usage_idx) TRACE("color");
+ else TRACE("specular%u", (semantic->usage_idx - 1));
+ break;
+
+ case WINED3D_DECL_USAGE_TEXCOORD:
+ TRACE("texture%u", semantic->usage_idx);
+ break;
+
+ case WINED3D_DECL_USAGE_TANGENT:
+ TRACE("tangent");
+ break;
+
+ case WINED3D_DECL_USAGE_BINORMAL:
+ TRACE("binormal");
+ break;
+
+ case WINED3D_DECL_USAGE_TESS_FACTOR:
+ TRACE("tessfactor");
+ break;
+
+ case WINED3D_DECL_USAGE_POSITIONT:
+ TRACE("positionT%u", semantic->usage_idx);
+ break;
+
+ case WINED3D_DECL_USAGE_FOG:
+ TRACE("fog");
+ break;
+
+ case WINED3D_DECL_USAGE_DEPTH:
+ TRACE("depth");
+ break;
+
+ case WINED3D_DECL_USAGE_SAMPLE:
+ TRACE("sample");
+ break;
+
+ default:
+ FIXME("unknown_semantics(0x%08x)", semantic->usage);
+ }
+ }
+}
+
+static void shader_dump_register(const struct wined3d_shader_register *reg,
+ const struct wined3d_shader_version *shader_version)
+{
+ static const char * const rastout_reg_names[] = {"oPos", "oFog", "oPts"};
+ static const char * const misctype_reg_names[] = {"vPos", "vFace"};
+ UINT offset = reg->idx[0].offset;
+
+ switch (reg->type)
+ {
+ case WINED3DSPR_TEMP:
+ TRACE("r");
+ break;
+
+ case WINED3DSPR_INPUT:
+ TRACE("v");
+ break;
+
+ case WINED3DSPR_CONST:
+ case WINED3DSPR_CONST2:
+ case WINED3DSPR_CONST3:
+ case WINED3DSPR_CONST4:
+ TRACE("c");
+ offset = shader_get_float_offset(reg->type, offset);
+ break;
+
+ case WINED3DSPR_TEXTURE: /* vs: case WINED3DSPR_ADDR */
+ TRACE("%c", shader_version->type == WINED3D_SHADER_TYPE_PIXEL ? 't' : 'a');
+ break;
+
+ case WINED3DSPR_RASTOUT:
+ TRACE("%s", rastout_reg_names[offset]);
+ break;
+
+ case WINED3DSPR_COLOROUT:
+ TRACE("oC");
+ break;
+
+ case WINED3DSPR_DEPTHOUT:
+ TRACE("oDepth");
+ break;
+
+ case WINED3DSPR_ATTROUT:
+ TRACE("oD");
+ break;
+
+ case WINED3DSPR_TEXCRDOUT:
+ /* Vertex shaders >= 3.0 use general purpose output registers
+ * (WINED3DSPR_OUTPUT), which can include an address token. */
+ if (shader_version->major >= 3) TRACE("o");
+ else TRACE("oT");
+ break;
+
+ case WINED3DSPR_CONSTINT:
+ TRACE("i");
+ break;
+
+ case WINED3DSPR_CONSTBOOL:
+ TRACE("b");
+ break;
+
+ case WINED3DSPR_LABEL:
+ TRACE("l");
+ break;
+
+ case WINED3DSPR_LOOP:
+ TRACE("aL");
+ break;
+
+ case WINED3DSPR_SAMPLER:
+ TRACE("s");
+ break;
+
+ case WINED3DSPR_MISCTYPE:
+ if (offset > 1)
+ FIXME("Unhandled misctype register %u.\n", offset);
+ else
+ TRACE("%s", misctype_reg_names[offset]);
+ break;
+
+ case WINED3DSPR_PREDICATE:
+ TRACE("p");
+ break;
+
+ case WINED3DSPR_IMMCONST:
+ TRACE("l");
+ break;
+
+ case WINED3DSPR_CONSTBUFFER:
+ TRACE("cb");
+ break;
+
+ case WINED3DSPR_PRIMID:
+ TRACE("primID");
+ break;
+
+ case WINED3DSPR_NULL:
+ TRACE("null");
+ break;
+
+ case WINED3DSPR_RESOURCE:
+ TRACE("t");
+ break;
+
+ default:
+ TRACE("unhandled_rtype(%#x)", reg->type);
+ break;
+ }
+
+ if (reg->type == WINED3DSPR_IMMCONST)
+ {
+ TRACE("(");
+ switch (reg->immconst_type)
+ {
+ case WINED3D_IMMCONST_SCALAR:
+ switch (reg->data_type)
+ {
+ case WINED3D_DATA_FLOAT:
+ TRACE("%.8e", *(const float *)reg->immconst_data);
+ break;
+ case WINED3D_DATA_INT:
+ TRACE("%d", reg->immconst_data[0]);
+ break;
+ case WINED3D_DATA_RESOURCE:
+ case WINED3D_DATA_SAMPLER:
+ case WINED3D_DATA_UINT:
+ TRACE("%u", reg->immconst_data[0]);
+ break;
+ default:
+ TRACE("<unhandled data type %#x>", reg->data_type);
+ break;
+ }
+ break;
+
+ case WINED3D_IMMCONST_VEC4:
+ switch (reg->data_type)
+ {
+ case WINED3D_DATA_FLOAT:
+ TRACE("%.8e, %.8e, %.8e, %.8e",
+ *(const float *)&reg->immconst_data[0], *(const float *)&reg->immconst_data[1],
+ *(const float *)&reg->immconst_data[2], *(const float *)&reg->immconst_data[3]);
+ break;
+ case WINED3D_DATA_INT:
+ TRACE("%d, %d, %d, %d",
+ reg->immconst_data[0], reg->immconst_data[1],
+ reg->immconst_data[2], reg->immconst_data[3]);
+ break;
+ case WINED3D_DATA_RESOURCE:
+ case WINED3D_DATA_SAMPLER:
+ case WINED3D_DATA_UINT:
+ TRACE("%u, %u, %u, %u",
+ reg->immconst_data[0], reg->immconst_data[1],
+ reg->immconst_data[2], reg->immconst_data[3]);
+ break;
+ default:
+ TRACE("<unhandled data type %#x>", reg->data_type);
+ break;
+ }
+ break;
+
+ default:
+ TRACE("<unhandled immconst_type %#x>", reg->immconst_type);
+ break;
+ }
+ TRACE(")");
+ }
+ else if (reg->type != WINED3DSPR_RASTOUT
+ && reg->type != WINED3DSPR_MISCTYPE
+ && reg->type != WINED3DSPR_NULL)
+ {
+ if (offset != ~0U)
+ {
+ TRACE("[");
+ if (reg->idx[0].rel_addr)
+ {
+ shader_dump_src_param(reg->idx[0].rel_addr, shader_version);
+ TRACE(" + ");
+ }
+ TRACE("%u]", offset);
+
+ if (reg->idx[1].offset != ~0U)
+ {
+ TRACE("[");
+ if (reg->idx[1].rel_addr)
+ {
+ shader_dump_src_param(reg->idx[1].rel_addr, shader_version);
+ TRACE(" + ");
+ }
+ TRACE("%u]", reg->idx[1].offset);
+ }
+ }
+ }
+}
+
+void shader_dump_dst_param(const struct wined3d_shader_dst_param *param,
+ const struct wined3d_shader_version *shader_version)
+{
+ DWORD write_mask = param->write_mask;
+
+ shader_dump_register(&param->reg, shader_version);
+
+ if (write_mask && write_mask != WINED3DSP_WRITEMASK_ALL)
+ {
+ static const char *write_mask_chars = "xyzw";
+
+ TRACE(".");
+ if (write_mask & WINED3DSP_WRITEMASK_0) TRACE("%c", write_mask_chars[0]);
+ if (write_mask & WINED3DSP_WRITEMASK_1) TRACE("%c", write_mask_chars[1]);
+ if (write_mask & WINED3DSP_WRITEMASK_2) TRACE("%c", write_mask_chars[2]);
+ if (write_mask & WINED3DSP_WRITEMASK_3) TRACE("%c", write_mask_chars[3]);
+ }
+}
+
+void shader_dump_src_param(const struct wined3d_shader_src_param *param,
+ const struct wined3d_shader_version *shader_version)
+{
+ enum wined3d_shader_src_modifier src_modifier = param->modifiers;
+ DWORD swizzle = param->swizzle;
+
+ if (src_modifier == WINED3DSPSM_NEG
+ || src_modifier == WINED3DSPSM_BIASNEG
+ || src_modifier == WINED3DSPSM_SIGNNEG
+ || src_modifier == WINED3DSPSM_X2NEG
+ || src_modifier == WINED3DSPSM_ABSNEG)
+ TRACE("-");
+ else if (src_modifier == WINED3DSPSM_COMP)
+ TRACE("1-");
+ else if (src_modifier == WINED3DSPSM_NOT)
+ TRACE("!");
+
+ if (src_modifier == WINED3DSPSM_ABS || src_modifier == WINED3DSPSM_ABSNEG)
+ TRACE("abs(");
+
+ shader_dump_register(&param->reg, shader_version);
+
+ if (src_modifier)
+ {
+ switch (src_modifier)
+ {
+ case WINED3DSPSM_NONE: break;
+ case WINED3DSPSM_NEG: break;
+ case WINED3DSPSM_NOT: break;
+ case WINED3DSPSM_BIAS: TRACE("_bias"); break;
+ case WINED3DSPSM_BIASNEG: TRACE("_bias"); break;
+ case WINED3DSPSM_SIGN: TRACE("_bx2"); break;
+ case WINED3DSPSM_SIGNNEG: TRACE("_bx2"); break;
+ case WINED3DSPSM_COMP: break;
+ case WINED3DSPSM_X2: TRACE("_x2"); break;
+ case WINED3DSPSM_X2NEG: TRACE("_x2"); break;
+ case WINED3DSPSM_DZ: TRACE("_dz"); break;
+ case WINED3DSPSM_DW: TRACE("_dw"); break;
+ case WINED3DSPSM_ABSNEG: TRACE(")"); break;
+ case WINED3DSPSM_ABS: TRACE(")"); break;
+ default: TRACE("_unknown_modifier(%#x)", src_modifier);
+ }
+ }
+
+ if (swizzle != WINED3DSP_NOSWIZZLE)
+ {
+ static const char *swizzle_chars = "xyzw";
+ DWORD swizzle_x = swizzle & 0x03;
+ DWORD swizzle_y = (swizzle >> 2) & 0x03;
+ DWORD swizzle_z = (swizzle >> 4) & 0x03;
+ DWORD swizzle_w = (swizzle >> 6) & 0x03;
+
+ if (swizzle_x == swizzle_y
+ && swizzle_x == swizzle_z
+ && swizzle_x == swizzle_w)
+ {
+ TRACE(".%c", swizzle_chars[swizzle_x]);
+ }
+ else
+ {
+ TRACE(".%c%c%c%c", swizzle_chars[swizzle_x], swizzle_chars[swizzle_y],
+ swizzle_chars[swizzle_z], swizzle_chars[swizzle_w]);
+ }
+ }
+}
+
+/* Shared code in order to generate the bulk of the shader string.
+ * NOTE: A description of how to parse tokens can be found on MSDN. */
+void shader_generate_main(const struct wined3d_shader *shader, struct wined3d_shader_buffer *buffer,
+ const struct wined3d_shader_reg_maps *reg_maps, const DWORD *byte_code, void *backend_ctx)
+{
+ struct wined3d_device *device = shader->device;
+ const struct wined3d_shader_frontend *fe = shader->frontend;
+ void *fe_data = shader->frontend_data;
+ struct wined3d_shader_version shader_version;
+ struct wined3d_shader_loop_state loop_state;
+ struct wined3d_shader_instruction ins;
+ struct wined3d_shader_tex_mx tex_mx;
+ struct wined3d_shader_context ctx;
+ const DWORD *ptr = byte_code;
+
+ /* Initialize current parsing state. */
+ tex_mx.current_row = 0;
+ loop_state.current_depth = 0;
+ loop_state.current_reg = 0;
+
+ ctx.shader = shader;
+ ctx.gl_info = &device->adapter->gl_info;
+ ctx.reg_maps = reg_maps;
+ ctx.buffer = buffer;
+ ctx.tex_mx = &tex_mx;
+ ctx.loop_state = &loop_state;
+ ctx.backend_data = backend_ctx;
+ ins.ctx = &ctx;
+
+ fe->shader_read_header(fe_data, &ptr, &shader_version);
+
+ while (!fe->shader_is_end(fe_data, &ptr))
+ {
+ /* Read opcode. */
+ fe->shader_read_instruction(fe_data, &ptr, &ins);
+
+ /* Unknown opcode and its parameters. */
+ if (ins.handler_idx == WINED3DSIH_TABLE_SIZE)
+ {
+ TRACE("Skipping unrecognized instruction.\n");
+ continue;
+ }
+
+ if (ins.predicate)
+ FIXME("Predicates not implemented.\n");
+
+ /* Call appropriate function for output target */
+ device->shader_backend->shader_handle_instruction(&ins);
+ }
+}
+
+static void shader_dump_ins_modifiers(const struct wined3d_shader_dst_param *dst)
+{
+ DWORD mmask = dst->modifiers;
+
+ switch (dst->shift)
+ {
+ case 0: break;
+ case 13: TRACE("_d8"); break;
+ case 14: TRACE("_d4"); break;
+ case 15: TRACE("_d2"); break;
+ case 1: TRACE("_x2"); break;
+ case 2: TRACE("_x4"); break;
+ case 3: TRACE("_x8"); break;
+ default: TRACE("_unhandled_shift(%d)", dst->shift); break;
+ }
+
+ if (mmask & WINED3DSPDM_SATURATE) TRACE("_sat");
+ if (mmask & WINED3DSPDM_PARTIALPRECISION) TRACE("_pp");
+ if (mmask & WINED3DSPDM_MSAMPCENTROID) TRACE("_centroid");
+
+ mmask &= ~(WINED3DSPDM_SATURATE | WINED3DSPDM_PARTIALPRECISION | WINED3DSPDM_MSAMPCENTROID);
+ if (mmask) FIXME("_unrecognized_modifier(%#x)", mmask);
+}
+
+static void shader_dump_primitive_type(enum wined3d_primitive_type primitive_type)
+{
+ switch (primitive_type)
+ {
+ case WINED3D_PT_UNDEFINED:
+ TRACE("undefined");
+ break;
+ case WINED3D_PT_POINTLIST:
+ TRACE("pointlist");
+ break;
+ case WINED3D_PT_LINELIST:
+ TRACE("linelist");
+ break;
+ case WINED3D_PT_LINESTRIP:
+ TRACE("linestrip");
+ break;
+ case WINED3D_PT_TRIANGLELIST:
+ TRACE("trianglelist");
+ break;
+ case WINED3D_PT_TRIANGLESTRIP:
+ TRACE("trianglestrip");
+ break;
+ case WINED3D_PT_TRIANGLEFAN:
+ TRACE("trianglefan");
+ break;
+ case WINED3D_PT_LINELIST_ADJ:
+ TRACE("linelist_adj");
+ break;
+ case WINED3D_PT_LINESTRIP_ADJ:
+ TRACE("linestrip_adj");
+ break;
+ case WINED3D_PT_TRIANGLELIST_ADJ:
+ TRACE("trianglelist_adj");
+ break;
+ case WINED3D_PT_TRIANGLESTRIP_ADJ:
+ TRACE("trianglestrip_adj");
+ break;
+ default:
+ TRACE("<unrecognized_primitive_type %#x>", primitive_type);
+ break;
+ }
+}
+
+static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe_data, const DWORD *byte_code)
+{
+ struct wined3d_shader_version shader_version;
+ const DWORD *ptr = byte_code;
+ const char *type_prefix;
+ DWORD i;
+
+ TRACE("Parsing %p.\n", byte_code);
+
+ fe->shader_read_header(fe_data, &ptr, &shader_version);
+
+ switch (shader_version.type)
+ {
+ case WINED3D_SHADER_TYPE_VERTEX:
+ type_prefix = "vs";
+ break;
+
+ case WINED3D_SHADER_TYPE_GEOMETRY:
+ type_prefix = "gs";
+ break;
+
+ case WINED3D_SHADER_TYPE_PIXEL:
+ type_prefix = "ps";
+ break;
+
+ default:
+ FIXME("Unhandled shader type %#x.\n", shader_version.type);
+ type_prefix = "unknown";
+ break;
+ }
+
+ TRACE("%s_%u_%u\n", type_prefix, shader_version.major, shader_version.minor);
+
+ while (!fe->shader_is_end(fe_data, &ptr))
+ {
+ struct wined3d_shader_instruction ins;
+
+ fe->shader_read_instruction(fe_data, &ptr, &ins);
+ if (ins.handler_idx == WINED3DSIH_TABLE_SIZE)
+ {
+ TRACE("Skipping unrecognized instruction.\n");
+ continue;
+ }
+
+ if (ins.handler_idx == WINED3DSIH_DCL)
+ {
+ shader_dump_decl_usage(&ins.declaration.semantic, &shader_version);
+ shader_dump_ins_modifiers(&ins.declaration.semantic.reg);
+ TRACE(" ");
+ shader_dump_dst_param(&ins.declaration.semantic.reg, &shader_version);
+ }
+ else if (ins.handler_idx == WINED3DSIH_DCL_CONSTANT_BUFFER)
+ {
+ TRACE("%s ", shader_opcode_names[ins.handler_idx]);
+ shader_dump_src_param(&ins.declaration.src, &shader_version);
+ TRACE(", %s", ins.flags & WINED3DSI_INDEXED_DYNAMIC ? "dynamicIndexed" : "immediateIndexed");
+ }
+ else if (ins.handler_idx == WINED3DSIH_DCL_INPUT_PRIMITIVE
+ || ins.handler_idx == WINED3DSIH_DCL_OUTPUT_TOPOLOGY)
+ {
+ TRACE("%s ", shader_opcode_names[ins.handler_idx]);
+ shader_dump_primitive_type(ins.declaration.primitive_type);
+ }
+ else if (ins.handler_idx == WINED3DSIH_DCL_VERTICES_OUT)
+ {
+ TRACE("%s %u", shader_opcode_names[ins.handler_idx], ins.declaration.count);
+ }
+ else if (ins.handler_idx == WINED3DSIH_DEF)
+ {
+ TRACE("def c%u = %f, %f, %f, %f", shader_get_float_offset(ins.dst[0].reg.type,
+ ins.dst[0].reg.idx[0].offset),
+ *(const float *)&ins.src[0].reg.immconst_data[0],
+ *(const float *)&ins.src[0].reg.immconst_data[1],
+ *(const float *)&ins.src[0].reg.immconst_data[2],
+ *(const float *)&ins.src[0].reg.immconst_data[3]);
+ }
+ else if (ins.handler_idx == WINED3DSIH_DEFI)
+ {
+ TRACE("defi i%u = %d, %d, %d, %d", ins.dst[0].reg.idx[0].offset,
+ ins.src[0].reg.immconst_data[0],
+ ins.src[0].reg.immconst_data[1],
+ ins.src[0].reg.immconst_data[2],
+ ins.src[0].reg.immconst_data[3]);
+ }
+ else if (ins.handler_idx == WINED3DSIH_DEFB)
+ {
+ TRACE("defb b%u = %s", ins.dst[0].reg.idx[0].offset, ins.src[0].reg.immconst_data[0] ? "true" : "false");
+ }
+ else
+ {
+ if (ins.predicate)
+ {
+ TRACE("(");
+ shader_dump_src_param(ins.predicate, &shader_version);
+ TRACE(") ");
+ }
+
+ /* PixWin marks instructions with the coissue flag with a '+' */
+ if (ins.coissue) TRACE("+");
+
+ TRACE("%s", shader_opcode_names[ins.handler_idx]);
+
+ if (ins.handler_idx == WINED3DSIH_IFC
+ || ins.handler_idx == WINED3DSIH_BREAKC)
+ {
+ switch (ins.flags)
+ {
+ case WINED3D_SHADER_REL_OP_GT: TRACE("_gt"); break;
+ case WINED3D_SHADER_REL_OP_EQ: TRACE("_eq"); break;
+ case WINED3D_SHADER_REL_OP_GE: TRACE("_ge"); break;
+ case WINED3D_SHADER_REL_OP_LT: TRACE("_lt"); break;
+ case WINED3D_SHADER_REL_OP_NE: TRACE("_ne"); break;
+ case WINED3D_SHADER_REL_OP_LE: TRACE("_le"); break;
+ default: TRACE("_(%u)", ins.flags);
+ }
+ }
+ else if (ins.handler_idx == WINED3DSIH_TEX
+ && shader_version.major >= 2
+ && (ins.flags & WINED3DSI_TEXLD_PROJECT))
+ {
+ TRACE("p");
+ }
+
+ for (i = 0; i < ins.dst_count; ++i)
+ {
+ shader_dump_ins_modifiers(&ins.dst[i]);
+ TRACE(!i ? " " : ", ");
+ shader_dump_dst_param(&ins.dst[i], &shader_version);
+ }
+
+ /* Other source tokens */
+ for (i = ins.dst_count; i < (ins.dst_count + ins.src_count); ++i)
+ {
+ TRACE(!i ? " " : ", ");
+ shader_dump_src_param(&ins.src[i - ins.dst_count], &shader_version);
+ }
+ }
+ TRACE("\n");
+ }
+}
+
+static void shader_cleanup(struct wined3d_shader *shader)
+{
+ shader->device->shader_backend->shader_destroy(shader);
+ HeapFree(GetProcessHeap(), 0, shader->reg_maps.constf);
+ HeapFree(GetProcessHeap(), 0, shader->function);
+ shader_delete_constant_list(&shader->constantsF);
+ shader_delete_constant_list(&shader->constantsB);
+ shader_delete_constant_list(&shader->constantsI);
+ list_remove(&shader->shader_list_entry);
+
+ if (shader->frontend && shader->frontend_data)
+ shader->frontend->shader_free(shader->frontend_data);
+}
+
+struct shader_none_priv
+{
+ const struct wined3d_vertex_pipe_ops *vertex_pipe;
+ const struct fragment_pipeline *fragment_pipe;
+ BOOL ffp_proj_control;
+};
+
+static void shader_none_handle_instruction(const struct wined3d_shader_instruction *ins) {}
+static void shader_none_select_depth_blt(void *shader_priv, const struct wined3d_gl_info *gl_info,
+ enum tex_types tex_type, const SIZE *ds_mask_size) {}
+static void shader_none_deselect_depth_blt(void *shader_priv, const struct wined3d_gl_info *gl_info) {}
+static void shader_none_update_float_vertex_constants(struct wined3d_device *device, UINT start, UINT count) {}
+static void shader_none_update_float_pixel_constants(struct wined3d_device *device, UINT start, UINT count) {}
+static void shader_none_load_constants(void *shader_priv, const struct wined3d_context *context,
+ const struct wined3d_state *state) {}
+static void shader_none_load_np2fixup_constants(void *shader_priv,
+ const struct wined3d_gl_info *gl_info, const struct wined3d_state *state) {}
+static void shader_none_destroy(struct wined3d_shader *shader) {}
+static void shader_none_context_destroyed(void *shader_priv, const struct wined3d_context *context) {}
+
+/* Context activation is done by the caller. */
+static void shader_none_select(void *shader_priv, const struct wined3d_context *context,
+ const struct wined3d_state *state)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct shader_none_priv *priv = shader_priv;
+
+ priv->vertex_pipe->vp_enable(gl_info, !use_vs(state));
+ priv->fragment_pipe->enable_extension(gl_info, !use_ps(state));
+}
+
+/* Context activation is done by the caller. */
+static void shader_none_disable(void *shader_priv, const struct wined3d_context *context)
+{
+ struct shader_none_priv *priv = shader_priv;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ priv->vertex_pipe->vp_enable(gl_info, FALSE);
+ priv->fragment_pipe->enable_extension(gl_info, FALSE);
+}
+
+static HRESULT shader_none_alloc(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe,
+ const struct fragment_pipeline *fragment_pipe)
+{
+ struct fragment_caps fragment_caps;
+ void *vertex_priv, *fragment_priv;
+ struct shader_none_priv *priv;
+
+ if (!(priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv))))
+ return E_OUTOFMEMORY;
+
+ if (!(vertex_priv = vertex_pipe->vp_alloc(&none_shader_backend, priv)))
+ {
+ ERR("Failed to initialize vertex pipe.\n");
+ HeapFree(GetProcessHeap(), 0, priv);
+ return E_FAIL;
+ }
+
+ if (!(fragment_priv = fragment_pipe->alloc_private(&none_shader_backend, priv)))
+ {
+ ERR("Failed to initialize fragment pipe.\n");
+ vertex_pipe->vp_free(device);
+ HeapFree(GetProcessHeap(), 0, priv);
+ return E_FAIL;
+ }
+
+ priv->vertex_pipe = vertex_pipe;
+ priv->fragment_pipe = fragment_pipe;
+ fragment_pipe->get_caps(&device->adapter->gl_info, &fragment_caps);
+ priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL;
+
+ device->vertex_priv = vertex_priv;
+ device->fragment_priv = fragment_priv;
+ device->shader_priv = priv;
+
+ return WINED3D_OK;
+}
+
+static void shader_none_free(struct wined3d_device *device)
+{
+ struct shader_none_priv *priv = device->shader_priv;
+
+ priv->fragment_pipe->free_private(device);
+ priv->vertex_pipe->vp_free(device);
+ HeapFree(GetProcessHeap(), 0, priv);
+}
+
+static void shader_none_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *caps)
+{
+ /* Set the shader caps to 0 for the none shader backend */
+ caps->vs_version = 0;
+ caps->gs_version = 0;
+ caps->ps_version = 0;
+ caps->vs_uniform_count = 0;
+ caps->ps_uniform_count = 0;
+ caps->ps_1x_max_value = 0.0f;
+ caps->wined3d_caps = 0;
+}
+
+static BOOL shader_none_color_fixup_supported(struct color_fixup_desc fixup)
+{
+ /* We "support" every possible fixup, since we don't support any shader
+ * model, and will never have to actually sample a texture. */
+ return TRUE;
+}
+
+static BOOL shader_none_has_ffp_proj_control(void *shader_priv)
+{
+ struct shader_none_priv *priv = shader_priv;
+
+ return priv->ffp_proj_control;
+}
+
+const struct wined3d_shader_backend_ops none_shader_backend =
+{
+ shader_none_handle_instruction,
+ shader_none_select,
+ shader_none_disable,
+ shader_none_select_depth_blt,
+ shader_none_deselect_depth_blt,
+ shader_none_update_float_vertex_constants,
+ shader_none_update_float_pixel_constants,
+ shader_none_load_constants,
+ shader_none_load_np2fixup_constants,
+ shader_none_destroy,
+ shader_none_alloc,
+ shader_none_free,
+ shader_none_context_destroyed,
+ shader_none_get_caps,
+ shader_none_color_fixup_supported,
+ shader_none_has_ffp_proj_control,
+};
+
+static HRESULT shader_set_function(struct wined3d_shader *shader, const DWORD *byte_code,
+ const struct wined3d_shader_signature *output_signature, DWORD float_const_count,
+ enum wined3d_shader_type type, unsigned int max_version)
+{
+ struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
+ const struct wined3d_shader_frontend *fe;
+ HRESULT hr;
+ unsigned int backend_version;
+ const struct wined3d_d3d_info *d3d_info = &shader->device->adapter->d3d_info;
+
+ TRACE("shader %p, byte_code %p, output_signature %p, float_const_count %u.\n",
+ shader, byte_code, output_signature, float_const_count);
+
+ fe = shader_select_frontend(*byte_code);
+ if (!fe)
+ {
+ FIXME("Unable to find frontend for shader.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+ shader->frontend = fe;
+ shader->frontend_data = fe->shader_init(byte_code, output_signature);
+ if (!shader->frontend_data)
+ {
+ FIXME("Failed to initialize frontend.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ /* First pass: trace shader. */
+ if (TRACE_ON(d3d_shader))
+ shader_trace_init(fe, shader->frontend_data, byte_code);
+
+ /* Initialize immediate constant lists. */
+ list_init(&shader->constantsF);
+ list_init(&shader->constantsB);
+ list_init(&shader->constantsI);
+ shader->lconst_inf_or_nan = FALSE;
+
+ /* Second pass: figure out which registers are used, what the semantics are, etc. */
+ hr = shader_get_registers_used(shader, fe,
+ reg_maps, shader->input_signature, shader->output_signature,
+ byte_code, float_const_count);
+ if (FAILED(hr)) return hr;
+
+ if (reg_maps->shader_version.type != type)
+ {
+ WARN("Wrong shader type %d.\n", reg_maps->shader_version.type);
+ return WINED3DERR_INVALIDCALL;
+ }
+ if (reg_maps->shader_version.major > max_version)
+ {
+ WARN("Shader version %d not supported by this D3D API version.\n", reg_maps->shader_version.major);
+ return WINED3DERR_INVALIDCALL;
+ }
+ switch (type)
+ {
+ case WINED3D_SHADER_TYPE_VERTEX:
+ backend_version = d3d_info->limits.vs_version;
+ break;
+ case WINED3D_SHADER_TYPE_GEOMETRY:
+ backend_version = d3d_info->limits.gs_version;
+ break;
+ case WINED3D_SHADER_TYPE_PIXEL:
+ backend_version = d3d_info->limits.ps_version;
+ break;
+ default:
+ FIXME("No backend version-checking for this shader type\n");
+ backend_version = 0;
+ }
+ if (reg_maps->shader_version.major > backend_version)
+ {
+ WARN("Shader version %d.%d not supported by your GPU with the current shader backend.\n",
+ reg_maps->shader_version.major, reg_maps->shader_version.minor);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ shader->function = HeapAlloc(GetProcessHeap(), 0, shader->functionLength);
+ if (!shader->function)
+ return E_OUTOFMEMORY;
+ memcpy(shader->function, byte_code, shader->functionLength);
+
+ return WINED3D_OK;
+}
+
+ULONG CDECL wined3d_shader_incref(struct wined3d_shader *shader)
+{
+ ULONG refcount = InterlockedIncrement(&shader->ref);
+
+ TRACE("%p increasing refcount to %u.\n", shader, refcount);
+
+ return refcount;
+}
+
+/* Do not call while under the GL lock. */
+ULONG CDECL wined3d_shader_decref(struct wined3d_shader *shader)
+{
+ ULONG refcount = InterlockedDecrement(&shader->ref);
+
+ TRACE("%p decreasing refcount to %u.\n", shader, refcount);
+
+ if (!refcount)
+ {
+#ifdef VBOX_WINE_WITH_SHADER_CACHE
+ shader_chache_put(shader->shaderCache, shader);
+#else
+ shader_cleanup(shader);
+ shader->parent_ops->wined3d_object_destroyed(shader->parent);
+ HeapFree(GetProcessHeap(), 0, shader);
+#endif
+ }
+
+ return refcount;
+}
+
+void * CDECL wined3d_shader_get_parent(const struct wined3d_shader *shader)
+{
+ TRACE("shader %p.\n", shader);
+
+ return shader->parent;
+}
+
+HRESULT CDECL wined3d_shader_get_byte_code(const struct wined3d_shader *shader,
+ void *byte_code, UINT *byte_code_size)
+{
+ TRACE("shader %p, byte_code %p, byte_code_size %p.\n", shader, byte_code, byte_code_size);
+
+ if (!byte_code)
+ {
+ *byte_code_size = shader->functionLength;
+ return WINED3D_OK;
+ }
+
+ if (*byte_code_size < shader->functionLength)
+ {
+ /* MSDN claims (for d3d8 at least) that if *byte_code_size is smaller
+ * than the required size we should write the required size and
+ * return D3DERR_MOREDATA. That's not actually true. */
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ memcpy(byte_code, shader->function, shader->functionLength);
+
+ return WINED3D_OK;
+}
+
+/* Set local constants for d3d8 shaders. */
+HRESULT CDECL wined3d_shader_set_local_constants_float(struct wined3d_shader *shader,
+ UINT start_idx, const float *src_data, UINT count)
+{
+ UINT end_idx = start_idx + count;
+ UINT i;
+
+ TRACE("shader %p, start_idx %u, src_data %p, count %u.\n", shader, start_idx, src_data, count);
+
+ if (end_idx > shader->limits.constant_float)
+ {
+ WARN("end_idx %u > float constants limit %u.\n",
+ end_idx, shader->limits.constant_float);
+ end_idx = shader->limits.constant_float;
+ }
+
+ for (i = start_idx; i < end_idx; ++i)
+ {
+ struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst));
+ float *value;
+ if (!lconst)
+ return E_OUTOFMEMORY;
+
+ lconst->idx = i;
+ value = (float *)lconst->value;
+ memcpy(value, src_data + (i - start_idx) * 4 /* 4 components */, 4 * sizeof(float));
+ list_add_head(&shader->constantsF, &lconst->entry);
+
+ if (isinf(value[0]) || isnan(value[0]) || isinf(value[1]) || isnan(value[1])
+ || isinf(value[2]) || isnan(value[2]) || isinf(value[3]) || isnan(value[3]))
+ {
+ shader->lconst_inf_or_nan = TRUE;
+ }
+ }
+
+ return WINED3D_OK;
+}
+
+void find_vs_compile_args(const struct wined3d_state *state,
+ const struct wined3d_shader *shader, struct vs_compile_args *args)
+{
+ args->fog_src = state->render_states[WINED3D_RS_FOGTABLEMODE]
+ == WINED3D_FOG_NONE ? VS_FOG_COORD : VS_FOG_Z;
+ args->clip_enabled = state->render_states[WINED3D_RS_CLIPPING]
+ && state->render_states[WINED3D_RS_CLIPPLANEENABLE];
+ args->swizzle_map = shader->device->stream_info.swizzle_map;
+}
+
+static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2)
+{
+ if (usage_idx1 != usage_idx2)
+ return FALSE;
+ if (usage1 == usage2)
+ return TRUE;
+ if (usage1 == WINED3D_DECL_USAGE_POSITION && usage2 == WINED3D_DECL_USAGE_POSITIONT)
+ return TRUE;
+ if (usage2 == WINED3D_DECL_USAGE_POSITION && usage1 == WINED3D_DECL_USAGE_POSITIONT)
+ return TRUE;
+
+ return FALSE;
+}
+
+BOOL vshader_get_input(const struct wined3d_shader *shader,
+ BYTE usage_req, BYTE usage_idx_req, unsigned int *regnum)
+{
+ WORD map = shader->reg_maps.input_registers;
+ unsigned int i;
+
+ for (i = 0; map; map >>= 1, ++i)
+ {
+ if (!(map & 1)) continue;
+
+ if (match_usage(shader->u.vs.attributes[i].usage,
+ shader->u.vs.attributes[i].usage_idx, usage_req, usage_idx_req))
+ {
+ *regnum = i;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static void vertexshader_set_limits(struct wined3d_shader *shader)
+{
+ DWORD shader_version = WINED3D_SHADER_VERSION(shader->reg_maps.shader_version.major,
+ shader->reg_maps.shader_version.minor);
+ struct wined3d_device *device = shader->device;
+ const DWORD vs_uniform_count = device->adapter->d3d_info.limits.vs_uniform_count;
+
+ shader->limits.packed_input = 0;
+
+ switch (shader_version)
+ {
+ case WINED3D_SHADER_VERSION(1, 0):
+ case WINED3D_SHADER_VERSION(1, 1):
+ shader->limits.constant_bool = 0;
+ shader->limits.constant_int = 0;
+ shader->limits.packed_output = 12;
+ shader->limits.sampler = 0;
+ /* TODO: vs_1_1 has a minimum of 96 constants. What happens when
+ * a vs_1_1 shader is used on a vs_3_0 capable card that has 256
+ * constants? */
+ shader->limits.constant_float = min(256, vs_uniform_count);
+ break;
+
+ case WINED3D_SHADER_VERSION(2, 0):
+ case WINED3D_SHADER_VERSION(2, 1):
+ shader->limits.constant_bool = 16;
+ shader->limits.constant_int = 16;
+ shader->limits.packed_output = 12;
+ shader->limits.sampler = 0;
+ shader->limits.constant_float = min(256, vs_uniform_count);
+ break;
+
+ case WINED3D_SHADER_VERSION(3, 0):
+ shader->limits.constant_bool = 16;
+ shader->limits.constant_int = 16;
+ shader->limits.packed_output = 12;
+ shader->limits.sampler = 4;
+ /* DX10 cards on Windows advertise a d3d9 constant limit of 256
+ * even though they are capable of supporting much more (GL
+ * drivers advertise 1024). d3d9.dll and d3d8.dll clamp the
+ * wined3d-advertised maximum. Clamp the constant limit for <= 3.0
+ * shaders to 256. */
+ shader->limits.constant_float = min(256, vs_uniform_count);
+ break;
+
+ case WINED3D_SHADER_VERSION(4, 0):
+ shader->limits.sampler = 16; /* FIXME: 128 resources, 16 sampler states */
+ shader->limits.constant_int = 0;
+ shader->limits.constant_float = 0;
+ shader->limits.constant_bool = 0;
+ shader->limits.packed_output = 16;
+ shader->limits.packed_input = 0;
+ break;
+
+ default:
+ shader->limits.constant_bool = 16;
+ shader->limits.constant_int = 16;
+ shader->limits.packed_output = 12;
+ shader->limits.sampler = 0;
+ shader->limits.constant_float = min(256, vs_uniform_count);
+ FIXME("Unrecognized vertex shader version \"%u.%u\".\n",
+ shader->reg_maps.shader_version.major,
+ shader->reg_maps.shader_version.minor);
+ }
+}
+
+static HRESULT vertexshader_init(struct wined3d_shader *shader, struct wined3d_device *device,
+ const DWORD *byte_code, const struct wined3d_shader_signature *output_signature,
+ void *parent, const struct wined3d_parent_ops *parent_ops, unsigned int max_version)
+{
+ struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
+ unsigned int i;
+ HRESULT hr;
+ WORD map;
+ const DWORD vs_uniform_count = device->adapter->d3d_info.limits.vs_uniform_count;
+
+ if (!byte_code) return WINED3DERR_INVALIDCALL;
+
+ shader_init(shader, device, parent, parent_ops);
+ hr = shader_set_function(shader, byte_code, output_signature, vs_uniform_count,
+ WINED3D_SHADER_TYPE_VERTEX, max_version);
+ if (FAILED(hr))
+ {
+ WARN("Failed to set function, hr %#x.\n", hr);
+ shader_cleanup(shader);
+ return hr;
+ }
+
+ map = reg_maps->input_registers;
+ for (i = 0; map; map >>= 1, ++i)
+ {
+ if (!(map & 1) || !shader->input_signature[i].semantic_name)
+ continue;
+
+ shader->u.vs.attributes[i].usage =
+ shader_usage_from_semantic_name(shader->input_signature[i].semantic_name);
+ shader->u.vs.attributes[i].usage_idx = shader->input_signature[i].semantic_idx;
+ }
+
+ if (output_signature)
+ {
+ for (i = 0; i < output_signature->element_count; ++i)
+ {
+ struct wined3d_shader_signature_element *e = &output_signature->elements[i];
+ reg_maps->output_registers |= 1 << e->register_idx;
+ shader->output_signature[e->register_idx] = *e;
+ }
+ }
+
+ vertexshader_set_limits(shader);
+
+ shader->load_local_constsF = (reg_maps->usesrelconstF && !list_empty(&shader->constantsF)) ||
+ shader->lconst_inf_or_nan;
+
+ return WINED3D_OK;
+}
+
+static void geometryshader_set_limits(struct wined3d_shader *shader)
+{
+ DWORD shader_version = WINED3D_SHADER_VERSION(shader->reg_maps.shader_version.major,
+ shader->reg_maps.shader_version.minor);
+
+ switch (shader_version)
+ {
+ case WINED3D_SHADER_VERSION(4, 0):
+ shader->limits.sampler = 16; /* FIXME: 128 resources, 16 sampler states */
+ shader->limits.constant_int = 0;
+ shader->limits.constant_float = 0;
+ shader->limits.constant_bool = 0;
+ shader->limits.packed_output = 32;
+ shader->limits.packed_input = 16;
+ break;
+
+ default:
+ memset(&shader->limits, 0, sizeof(shader->limits));
+ FIXME("Unhandled geometry shader version \"%u.%u\".\n",
+ shader->reg_maps.shader_version.major,
+ shader->reg_maps.shader_version.minor);
+ }
+}
+
+static HRESULT geometryshader_init(struct wined3d_shader *shader, struct wined3d_device *device,
+ const DWORD *byte_code, const struct wined3d_shader_signature *output_signature,
+ void *parent, const struct wined3d_parent_ops *parent_ops, unsigned int max_version)
+{
+ HRESULT hr;
+
+ shader_init(shader, device, parent, parent_ops);
+ hr = shader_set_function(shader, byte_code, output_signature, 0,
+ WINED3D_SHADER_TYPE_GEOMETRY, max_version);
+ if (FAILED(hr))
+ {
+ WARN("Failed to set function, hr %#x.\n", hr);
+ shader_cleanup(shader);
+ return hr;
+ }
+
+ geometryshader_set_limits(shader);
+
+ shader->load_local_constsF = shader->lconst_inf_or_nan;
+
+ return WINED3D_OK;
+}
+
+void find_ps_compile_args(const struct wined3d_state *state,
+ const struct wined3d_shader *shader, struct ps_compile_args *args)
+{
+ struct wined3d_device *device = shader->device;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ const struct wined3d_texture *texture;
+ UINT i;
+
+ memset(args, 0, sizeof(*args)); /* FIXME: Make sure all bits are set. */
+ if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB] && state->render_states[WINED3D_RS_SRGBWRITEENABLE])
+ {
+ const struct wined3d_surface *rt = state->fb->render_targets[0];
+ if (rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
+ {
+ static unsigned int warned = 0;
+
+ args->srgb_correction = 1;
+ if (state->render_states[WINED3D_RS_ALPHABLENDENABLE] && !warned++)
+ WARN("Blending into a sRGB render target with no GL_ARB_framebuffer_sRGB "
+ "support, expect rendering artifacts.\n");
+ }
+ }
+
+ if (shader->reg_maps.shader_version.major == 1
+ && shader->reg_maps.shader_version.minor <= 3)
+ {
+ for (i = 0; i < shader->limits.sampler; ++i)
+ {
+ DWORD flags = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS];
+
+ if (flags & WINED3D_TTFF_PROJECTED)
+ {
+ DWORD tex_transform = flags & ~WINED3D_TTFF_PROJECTED;
+
+ if (!state->vertex_shader)
+ {
+ unsigned int j;
+ unsigned int index = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
+ DWORD max_valid = WINED3D_TTFF_COUNT4;
+ enum wined3d_sampler_texture_type sampler_type = shader->reg_maps.sampler_type[i];
+
+ for (j = 0; j < state->vertex_declaration->element_count; ++j)
+ {
+ struct wined3d_vertex_declaration_element *element =
+ &state->vertex_declaration->elements[j];
+
+ if (element->usage == WINED3D_DECL_USAGE_TEXCOORD
+ && element->usage_idx == index)
+ {
+ max_valid = element->format->component_count;
+ break;
+ }
+ }
+ if (!tex_transform || tex_transform > max_valid)
+ {
+ WARN("Fixing up projected texture transform flags from %#x to %#x.\n",
+ tex_transform, max_valid);
+ tex_transform = max_valid;
+ }
+ if ((sampler_type == WINED3DSTT_1D && tex_transform > WINED3D_TTFF_COUNT1)
+ || (sampler_type == WINED3DSTT_2D && tex_transform > WINED3D_TTFF_COUNT2)
+ || (sampler_type == WINED3DSTT_VOLUME && tex_transform > WINED3D_TTFF_COUNT3))
+ tex_transform |= WINED3D_PSARGS_PROJECTED;
+ else
+ {
+ WARN("Application requested projected texture with unsuitable texture coordinates.\n");
+ WARN("(texture unit %u, transform flags %#x, sampler type %u).\n",
+ i, tex_transform, sampler_type);
+ }
+ }
+ else
+ tex_transform = WINED3D_TTFF_COUNT4 | WINED3D_PSARGS_PROJECTED;
+
+ args->tex_transform |= tex_transform << i * WINED3D_PSARGS_TEXTRANSFORM_SHIFT;
+ }
+ }
+ }
+ if (shader->reg_maps.shader_version.major == 1
+ && shader->reg_maps.shader_version.minor <= 4)
+ {
+ for (i = 0; i < shader->limits.sampler; ++i)
+ {
+ const struct wined3d_texture *texture = state->textures[i];
+
+ if (!shader->reg_maps.sampler_type[i])
+ continue;
+
+ /* Treat unbound textures as 2D. The dummy texture will provide
+ * the proper sample value. The tex_types bitmap defaults to
+ * 2D because of the memset. */
+ if (!texture)
+ continue;
+
+ switch (texture->target)
+ {
+ /* RECT textures are distinguished from 2D textures via np2_fixup */
+ case GL_TEXTURE_RECTANGLE_ARB:
+ case GL_TEXTURE_2D:
+ break;
+
+ case GL_TEXTURE_3D:
+ args->tex_types |= WINED3D_SHADER_TEX_3D << i * WINED3D_PSARGS_TEXTYPE_SHIFT;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ args->tex_types |= WINED3D_SHADER_TEX_CUBE << i * WINED3D_PSARGS_TEXTYPE_SHIFT;
+ break;
+ }
+ }
+ }
+
+ for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
+ {
+ if (!shader->reg_maps.sampler_type[i])
+ continue;
+
+ texture = state->textures[i];
+ if (!texture)
+ {
+ args->color_fixup[i] = COLOR_FIXUP_IDENTITY;
+ continue;
+ }
+ args->color_fixup[i] = texture->resource.format->color_fixup;
+
+ if (texture->resource.format->flags & WINED3DFMT_FLAG_SHADOW)
+ args->shadow |= 1 << i;
+
+ /* Flag samplers that need NP2 texcoord fixup. */
+ if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
+ args->np2_fixup |= (1 << i);
+ }
+ if (shader->reg_maps.shader_version.major >= 3)
+ {
+ if (device->stream_info.position_transformed)
+ args->vp_mode = pretransformed;
+ else if (use_vs(state))
+ args->vp_mode = vertexshader;
+ else
+ args->vp_mode = fixedfunction;
+ args->fog = WINED3D_FFP_PS_FOG_OFF;
+ }
+ else
+ {
+ args->vp_mode = vertexshader;
+ if (state->render_states[WINED3D_RS_FOGENABLE])
+ {
+ switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
+ {
+ case WINED3D_FOG_NONE:
+ if (device->stream_info.position_transformed || use_vs(state))
+ {
+ args->fog = WINED3D_FFP_PS_FOG_LINEAR;
+ break;
+ }
+
+ switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
+ {
+ case WINED3D_FOG_NONE: /* Fall through. */
+ case WINED3D_FOG_LINEAR: args->fog = WINED3D_FFP_PS_FOG_LINEAR; break;
+ case WINED3D_FOG_EXP: args->fog = WINED3D_FFP_PS_FOG_EXP; break;
+ case WINED3D_FOG_EXP2: args->fog = WINED3D_FFP_PS_FOG_EXP2; break;
+ }
+ break;
+
+ case WINED3D_FOG_LINEAR: args->fog = WINED3D_FFP_PS_FOG_LINEAR; break;
+ case WINED3D_FOG_EXP: args->fog = WINED3D_FFP_PS_FOG_EXP; break;
+ case WINED3D_FOG_EXP2: args->fog = WINED3D_FFP_PS_FOG_EXP2; break;
+ }
+ }
+ else
+ {
+ args->fog = WINED3D_FFP_PS_FOG_OFF;
+ }
+ }
+}
+
+static void pixelshader_set_limits(struct wined3d_shader *shader)
+{
+ DWORD shader_version = WINED3D_SHADER_VERSION(shader->reg_maps.shader_version.major,
+ shader->reg_maps.shader_version.minor);
+
+ shader->limits.packed_output = 0;
+
+ switch (shader_version)
+ {
+ case WINED3D_SHADER_VERSION(1, 0):
+ case WINED3D_SHADER_VERSION(1, 1):
+ case WINED3D_SHADER_VERSION(1, 2):
+ case WINED3D_SHADER_VERSION(1, 3):
+ shader->limits.constant_float = 8;
+ shader->limits.constant_int = 0;
+ shader->limits.constant_bool = 0;
+ shader->limits.sampler = 4;
+ shader->limits.packed_input = 0;
+ break;
+
+ case WINED3D_SHADER_VERSION(1, 4):
+ shader->limits.constant_float = 8;
+ shader->limits.constant_int = 0;
+ shader->limits.constant_bool = 0;
+ shader->limits.sampler = 6;
+ shader->limits.packed_input = 0;
+ break;
+
+ /* FIXME: Temporaries must match D3DPSHADERCAPS2_0.NumTemps. */
+ case WINED3D_SHADER_VERSION(2, 0):
+ shader->limits.constant_float = 32;
+ shader->limits.constant_int = 16;
+ shader->limits.constant_bool = 16;
+ shader->limits.sampler = 16;
+ shader->limits.packed_input = 0;
+ break;
+
+ case WINED3D_SHADER_VERSION(2, 1):
+ shader->limits.constant_float = 32;
+ shader->limits.constant_int = 16;
+ shader->limits.constant_bool = 16;
+ shader->limits.sampler = 16;
+ shader->limits.packed_input = 0;
+ break;
+
+ case WINED3D_SHADER_VERSION(3, 0):
+ shader->limits.constant_float = 224;
+ shader->limits.constant_int = 16;
+ shader->limits.constant_bool = 16;
+ shader->limits.sampler = 16;
+ shader->limits.packed_input = 12;
+ break;
+
+ case WINED3D_SHADER_VERSION(4, 0):
+ shader->limits.sampler = 16; /* FIXME: 128 resources, 16 sampler states */
+ shader->limits.constant_int = 0;
+ shader->limits.constant_float = 0;
+ shader->limits.constant_bool = 0;
+ shader->limits.packed_input = 32;
+ break;
+
+ default:
+ shader->limits.constant_float = 32;
+ shader->limits.constant_int = 16;
+ shader->limits.constant_bool = 16;
+ shader->limits.sampler = 16;
+ shader->limits.packed_input = 0;
+ FIXME("Unrecognized pixel shader version %u.%u\n",
+ shader->reg_maps.shader_version.major,
+ shader->reg_maps.shader_version.minor);
+ }
+}
+
+static HRESULT pixelshader_init(struct wined3d_shader *shader, struct wined3d_device *device,
+ const DWORD *byte_code, const struct wined3d_shader_signature *output_signature,
+ void *parent, const struct wined3d_parent_ops *parent_ops, unsigned int max_version)
+{
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ unsigned int i, highest_reg_used = 0, num_regs_used = 0;
+ HRESULT hr;
+ const DWORD ps_uniform_count = device->adapter->d3d_info.limits.ps_uniform_count;
+
+ if (!byte_code) return WINED3DERR_INVALIDCALL;
+
+ shader_init(shader, device, parent, parent_ops);
+ hr = shader_set_function(shader, byte_code, output_signature, ps_uniform_count,
+ WINED3D_SHADER_TYPE_PIXEL, max_version);
+ if (FAILED(hr))
+ {
+ WARN("Failed to set function, hr %#x.\n", hr);
+ shader_cleanup(shader);
+ return hr;
+ }
+
+ pixelshader_set_limits(shader);
+
+ for (i = 0; i < MAX_REG_INPUT; ++i)
+ {
+ if (shader->u.ps.input_reg_used[i])
+ {
+ ++num_regs_used;
+ highest_reg_used = i;
+ }
+ }
+
+ /* Don't do any register mapping magic if it is not needed, or if we can't
+ * achieve anything anyway */
+ if (highest_reg_used < (gl_info->limits.glsl_varyings / 4)
+ || num_regs_used > (gl_info->limits.glsl_varyings / 4))
+ {
+ if (num_regs_used > (gl_info->limits.glsl_varyings / 4))
+ {
+ /* This happens with relative addressing. The input mapper function
+ * warns about this if the higher registers are declared too, so
+ * don't write a FIXME here */
+ WARN("More varying registers used than supported\n");
+ }
+
+ for (i = 0; i < MAX_REG_INPUT; ++i)
+ {
+ shader->u.ps.input_reg_map[i] = i;
+ }
+
+ shader->u.ps.declared_in_count = highest_reg_used + 1;
+ }
+ else
+ {
+ shader->u.ps.declared_in_count = 0;
+ for (i = 0; i < MAX_REG_INPUT; ++i)
+ {
+ if (shader->u.ps.input_reg_used[i])
+ shader->u.ps.input_reg_map[i] = shader->u.ps.declared_in_count++;
+ else shader->u.ps.input_reg_map[i] = ~0U;
+ }
+ }
+
+ shader->load_local_constsF = shader->lconst_inf_or_nan;
+
+ return WINED3D_OK;
+}
+
+void pixelshader_update_samplers(struct wined3d_shader *shader, WORD tex_types)
+{
+ struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
+ enum wined3d_sampler_texture_type *sampler_type = reg_maps->sampler_type;
+ unsigned int i;
+
+ if (reg_maps->shader_version.major != 1) return;
+
+ for (i = 0; i < shader->limits.sampler; ++i)
+ {
+ /* We don't sample from this sampler. */
+ if (!sampler_type[i]) continue;
+
+ switch ((tex_types >> i * WINED3D_PSARGS_TEXTYPE_SHIFT) & WINED3D_PSARGS_TEXTYPE_MASK)
+ {
+ case WINED3D_SHADER_TEX_2D:
+ sampler_type[i] = WINED3DSTT_2D;
+ break;
+
+ case WINED3D_SHADER_TEX_3D:
+ sampler_type[i] = WINED3DSTT_VOLUME;
+ break;
+
+ case WINED3D_SHADER_TEX_CUBE:
+ sampler_type[i] = WINED3DSTT_CUBE;
+ break;
+ }
+ }
+}
+
+HRESULT CDECL wined3d_shader_create_gs(struct wined3d_device *device, const DWORD *byte_code,
+ const struct wined3d_shader_signature *output_signature, void *parent,
+ const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version)
+{
+ struct wined3d_shader *object;
+ HRESULT hr;
+
+ TRACE("device %p, byte_code %p, output_signature %p, parent %p, parent_ops %p, shader %p.\n",
+ device, byte_code, output_signature, parent, parent_ops, shader);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ hr = geometryshader_init(object, device, byte_code, output_signature, parent, parent_ops, max_version);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize geometry shader, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created geometry shader %p.\n", object);
+ *shader = object;
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_shader_create_ps(struct wined3d_device *device, const DWORD *byte_code,
+ const struct wined3d_shader_signature *output_signature, void *parent,
+ const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version)
+{
+ struct wined3d_shader *object;
+ HRESULT hr;
+
+ TRACE("device %p, byte_code %p, output_signature %p, parent %p, parent_ops %p, shader %p.\n",
+ device, byte_code, output_signature, parent, parent_ops, shader);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ hr = pixelshader_init(object, device, byte_code, output_signature, parent, parent_ops, max_version);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+#ifdef VBOX_WINE_WITH_SHADER_CACHE
+ object = pixelshader_check_cached(device, object);
+#endif
+
+ TRACE("Created pixel shader %p.\n", object);
+ *shader = object;
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_shader_create_vs(struct wined3d_device *device, const DWORD *byte_code,
+ const struct wined3d_shader_signature *output_signature, void *parent,
+ const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version)
+{
+ struct wined3d_shader *object;
+ HRESULT hr;
+
+ TRACE("device %p, byte_code %p, output_signature %p, parent %p, parent_ops %p, shader %p.\n",
+ device, byte_code, output_signature, parent, parent_ops, shader);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ hr = vertexshader_init(object, device, byte_code, output_signature, parent, parent_ops, max_version);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+#ifdef VBOX_WINE_WITH_SHADER_CACHE
+ object = vertexshader_check_cached(device, object);
+#endif
+
+ TRACE("Created vertex shader %p.\n", object);
+ *shader = object;
+
+ return WINED3D_OK;
+}
+
+#ifdef VBOX_WINE_WITH_SHADER_CACHE
+
+static void shader_reinit(struct wined3d_shader *shader, struct wined3d_device *device,
+ void *parent, const struct wined3d_parent_ops *parent_ops)
+{
+ shader->ref = 1;
+ shader->device = device;
+ shader->parent = parent;
+ shader->parent_ops = parent_ops;
+#ifdef DEBUG
+ {
+ struct wined3d_shader *tst_shader;
+ LIST_FOR_EACH_ENTRY(tst_shader, &device->shaders, struct wined3d_shader, shader_list_entry) {
+ if (tst_shader == shader)
+ return;
+ }
+ ERR("shader not in list!");
+ }
+#endif
+}
+
+static DECLCALLBACK(uint32_t) shader_cache_hash(void *pvKey)
+{
+ uint32_t u32Hash, i;
+ DWORD *function;
+ struct wined3d_shader * shader = (struct wined3d_shader *)pvKey;
+ if (shader->u32CacheDataInited)
+ return shader->u32Hash;
+
+ u32Hash = shader->functionLength;
+ function = shader->function;
+ for (i = 0; i < shader->functionLength / 4; ++i)
+ {
+ u32Hash += *function++;
+ }
+
+ for (i = 0; i < shader->functionLength % 4; ++i)
+ {
+ u32Hash += *((uint8_t*)function)++;
+ }
+
+ shader->u32Hash = u32Hash;
+ shader->u32CacheDataInited = TRUE;
+ return shader->u32Hash;
+}
+
+static DECLCALLBACK(bool) shader_cache_equal(void *pvKey1, void *pvKey2)
+{
+ struct wined3d_shader *shader1 = (struct wined3d_shader *)pvKey1;
+ struct wined3d_shader *shader2 = (struct wined3d_shader *)pvKey2;
+
+ if (shader1 == shader2)
+ return TRUE;
+
+ if (shader1->functionLength != shader2->functionLength)
+ return FALSE;
+
+ if (shader_cache_hash(pvKey1) != shader_cache_hash(pvKey2))
+ {
+#ifdef DEBUG_misha
+ Assert(memcmp(shader1->function, shader2->function, shader1->functionLength));
+#endif
+ return FALSE;
+ }
+
+ return !memcmp(shader1->function, shader2->function, shader1->functionLength);
+}
+
+#define VBOX_SHADER_FROM_CACHE_ENTRY(_pEntry) RT_FROM_MEMBER((_pEntry), struct wined3d_shader, CacheEntry)
+
+static DECLCALLBACK(void) shader_cache_cleanup_entry(void *pvKey, struct VBOXEXT_HASHCACHE_ENTRY *pEntry)
+{
+ struct wined3d_shader *shader = VBOX_SHADER_FROM_CACHE_ENTRY(pEntry);
+ shader_cleanup(shader);
+ if (shader->parent)
+ shader->parent_ops->wined3d_object_destroyed(shader->parent);
+ HeapFree(GetProcessHeap(), 0, shader);
+}
+
+static void shader_chache_init(PVBOXEXT_HASHCACHE pCache)
+{
+ VBoxExtCacheInit(pCache, 1024, shader_cache_hash, shader_cache_equal, shader_cache_cleanup_entry);
+}
+
+static void shader_chache_term(PVBOXEXT_HASHCACHE pCache)
+{
+ VBoxExtCacheTerm(pCache);
+}
+
+static void shader_chache_put(PVBOXEXT_HASHCACHE pCache, struct wined3d_shader *shader)
+{
+ if (shader->parent)
+ {
+ shader->parent_ops->wined3d_object_destroyed(shader->parent);
+ shader->parent = NULL;
+ }
+
+ VBoxExtCachePut(pCache, shader, &shader->CacheEntry);
+}
+
+static struct wined3d_shader* shader_chache_get(PVBOXEXT_HASHCACHE pCache, struct wined3d_shader *shader)
+{
+ PVBOXEXT_HASHCACHE_ENTRY pEntry = VBoxExtCacheGet(pCache, shader);
+ struct wined3d_shader *cached_shader;
+
+ if (!pEntry)
+ return shader;
+
+ cached_shader = VBOX_SHADER_FROM_CACHE_ENTRY(pEntry);
+ shader_reinit(cached_shader, shader->device,
+ shader->parent, shader->parent_ops);
+ shader->parent = NULL;
+ /* we can not do a IWineD3DBaseShader_Release here since this would result in putting a shader to the cache */
+ shader_cleanup(shader);
+ HeapFree(GetProcessHeap(), 0, shader);
+ return cached_shader;
+}
+
+struct wined3d_shader * vertexshader_check_cached(struct wined3d_device *device, struct wined3d_shader *object)
+{
+ object->shaderCache = &device->vshaderCache;
+ return shader_chache_get(&device->vshaderCache, (struct wined3d_shader *)object);
+}
+
+struct wined3d_shader * pixelshader_check_cached(struct wined3d_device *device, struct wined3d_shader *object)
+{
+ object->shaderCache = &device->pshaderCache;
+ return shader_chache_get(&device->pshaderCache, (struct wined3d_shader *)object);
+}
+
+void shader_chaches_init(struct wined3d_device *device)
+{
+ shader_chache_init(&device->vshaderCache);
+ shader_chache_init(&device->pshaderCache);
+}
+
+void shader_chaches_term(struct wined3d_device *device)
+{
+ shader_chache_term(&device->vshaderCache);
+ shader_chache_term(&device->pshaderCache);
+}
+#endif
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/shader_sm1.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/shader_sm1.c
new file mode 100644
index 00000000..31c77c77
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/shader_sm1.c
@@ -0,0 +1,781 @@
+/*
+ * Copyright 2002-2003 Jason Edmeades
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2004 Christian Costa
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2006 Ivan Gyurdiev
+ * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2009 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
+
+/* DCL usage masks */
+#define WINED3DSP_DCL_USAGE_SHIFT 0
+#define WINED3DSP_DCL_USAGE_MASK (0xf << WINED3DSP_DCL_USAGE_SHIFT)
+#define WINED3DSP_DCL_USAGEINDEX_SHIFT 16
+#define WINED3DSP_DCL_USAGEINDEX_MASK (0xf << WINED3DSP_DCL_USAGEINDEX_SHIFT)
+
+/* DCL sampler type */
+#define WINED3DSP_TEXTURETYPE_SHIFT 27
+#define WINED3DSP_TEXTURETYPE_MASK (0xf << WINED3DSP_TEXTURETYPE_SHIFT)
+
+/* Opcode-related masks */
+#define WINED3DSI_OPCODE_MASK 0x0000ffff
+
+#define WINED3D_OPCODESPECIFICCONTROL_SHIFT 16
+#define WINED3D_OPCODESPECIFICCONTROL_MASK (0xff << WINED3D_OPCODESPECIFICCONTROL_SHIFT)
+
+#define WINED3DSI_INSTLENGTH_SHIFT 24
+#define WINED3DSI_INSTLENGTH_MASK (0xf << WINED3DSI_INSTLENGTH_SHIFT)
+
+#define WINED3DSI_COISSUE (1 << 30)
+
+#define WINED3DSI_COMMENTSIZE_SHIFT 16
+#define WINED3DSI_COMMENTSIZE_MASK (0x7fff << WINED3DSI_COMMENTSIZE_SHIFT)
+
+#define WINED3DSHADER_INSTRUCTION_PREDICATED (1 << 28)
+
+/* Register number mask */
+#define WINED3DSP_REGNUM_MASK 0x000007ff
+
+/* Register type masks */
+#define WINED3DSP_REGTYPE_SHIFT 28
+#define WINED3DSP_REGTYPE_MASK (0x7 << WINED3DSP_REGTYPE_SHIFT)
+#define WINED3DSP_REGTYPE_SHIFT2 8
+#define WINED3DSP_REGTYPE_MASK2 (0x18 << WINED3DSP_REGTYPE_SHIFT2)
+
+/* Relative addressing mask */
+#define WINED3DSHADER_ADDRESSMODE_SHIFT 13
+#define WINED3DSHADER_ADDRESSMODE_MASK (1 << WINED3DSHADER_ADDRESSMODE_SHIFT)
+
+/* Destination modifier mask */
+#define WINED3DSP_DSTMOD_SHIFT 20
+#define WINED3DSP_DSTMOD_MASK (0xf << WINED3DSP_DSTMOD_SHIFT)
+
+/* Destination shift mask */
+#define WINED3DSP_DSTSHIFT_SHIFT 24
+#define WINED3DSP_DSTSHIFT_MASK (0xf << WINED3DSP_DSTSHIFT_SHIFT)
+
+/* Write mask */
+#define WINED3D_SM1_WRITEMASK_SHIFT 16
+#define WINED3D_SM1_WRITEMASK_MASK (0xf << WINED3D_SM1_WRITEMASK_SHIFT)
+
+/* Swizzle mask */
+#define WINED3DSP_SWIZZLE_SHIFT 16
+#define WINED3DSP_SWIZZLE_MASK (0xff << WINED3DSP_SWIZZLE_SHIFT)
+
+/* Source modifier mask */
+#define WINED3DSP_SRCMOD_SHIFT 24
+#define WINED3DSP_SRCMOD_MASK (0xf << WINED3DSP_SRCMOD_SHIFT)
+
+#define WINED3DSP_END 0x0000ffff
+
+#define WINED3D_SM1_VERSION_MAJOR(version) (((version) >> 8) & 0xff)
+#define WINED3D_SM1_VERSION_MINOR(version) (((version) >> 0) & 0xff)
+
+enum WINED3DSHADER_ADDRESSMODE_TYPE
+{
+ WINED3DSHADER_ADDRMODE_ABSOLUTE = 0 << WINED3DSHADER_ADDRESSMODE_SHIFT,
+ WINED3DSHADER_ADDRMODE_RELATIVE = 1 << WINED3DSHADER_ADDRESSMODE_SHIFT,
+};
+
+enum wined3d_sm1_opcode
+{
+ WINED3D_SM1_OP_NOP = 0x00,
+ WINED3D_SM1_OP_MOV = 0x01,
+ WINED3D_SM1_OP_ADD = 0x02,
+ WINED3D_SM1_OP_SUB = 0x03,
+ WINED3D_SM1_OP_MAD = 0x04,
+ WINED3D_SM1_OP_MUL = 0x05,
+ WINED3D_SM1_OP_RCP = 0x06,
+ WINED3D_SM1_OP_RSQ = 0x07,
+ WINED3D_SM1_OP_DP3 = 0x08,
+ WINED3D_SM1_OP_DP4 = 0x09,
+ WINED3D_SM1_OP_MIN = 0x0a,
+ WINED3D_SM1_OP_MAX = 0x0b,
+ WINED3D_SM1_OP_SLT = 0x0c,
+ WINED3D_SM1_OP_SGE = 0x0d,
+ WINED3D_SM1_OP_EXP = 0x0e,
+ WINED3D_SM1_OP_LOG = 0x0f,
+ WINED3D_SM1_OP_LIT = 0x10,
+ WINED3D_SM1_OP_DST = 0x11,
+ WINED3D_SM1_OP_LRP = 0x12,
+ WINED3D_SM1_OP_FRC = 0x13,
+ WINED3D_SM1_OP_M4x4 = 0x14,
+ WINED3D_SM1_OP_M4x3 = 0x15,
+ WINED3D_SM1_OP_M3x4 = 0x16,
+ WINED3D_SM1_OP_M3x3 = 0x17,
+ WINED3D_SM1_OP_M3x2 = 0x18,
+ WINED3D_SM1_OP_CALL = 0x19,
+ WINED3D_SM1_OP_CALLNZ = 0x1a,
+ WINED3D_SM1_OP_LOOP = 0x1b,
+ WINED3D_SM1_OP_RET = 0x1c,
+ WINED3D_SM1_OP_ENDLOOP = 0x1d,
+ WINED3D_SM1_OP_LABEL = 0x1e,
+ WINED3D_SM1_OP_DCL = 0x1f,
+ WINED3D_SM1_OP_POW = 0x20,
+ WINED3D_SM1_OP_CRS = 0x21,
+ WINED3D_SM1_OP_SGN = 0x22,
+ WINED3D_SM1_OP_ABS = 0x23,
+ WINED3D_SM1_OP_NRM = 0x24,
+ WINED3D_SM1_OP_SINCOS = 0x25,
+ WINED3D_SM1_OP_REP = 0x26,
+ WINED3D_SM1_OP_ENDREP = 0x27,
+ WINED3D_SM1_OP_IF = 0x28,
+ WINED3D_SM1_OP_IFC = 0x29,
+ WINED3D_SM1_OP_ELSE = 0x2a,
+ WINED3D_SM1_OP_ENDIF = 0x2b,
+ WINED3D_SM1_OP_BREAK = 0x2c,
+ WINED3D_SM1_OP_BREAKC = 0x2d,
+ WINED3D_SM1_OP_MOVA = 0x2e,
+ WINED3D_SM1_OP_DEFB = 0x2f,
+ WINED3D_SM1_OP_DEFI = 0x30,
+
+ WINED3D_SM1_OP_TEXCOORD = 0x40,
+ WINED3D_SM1_OP_TEXKILL = 0x41,
+ WINED3D_SM1_OP_TEX = 0x42,
+ WINED3D_SM1_OP_TEXBEM = 0x43,
+ WINED3D_SM1_OP_TEXBEML = 0x44,
+ WINED3D_SM1_OP_TEXREG2AR = 0x45,
+ WINED3D_SM1_OP_TEXREG2GB = 0x46,
+ WINED3D_SM1_OP_TEXM3x2PAD = 0x47,
+ WINED3D_SM1_OP_TEXM3x2TEX = 0x48,
+ WINED3D_SM1_OP_TEXM3x3PAD = 0x49,
+ WINED3D_SM1_OP_TEXM3x3TEX = 0x4a,
+ WINED3D_SM1_OP_TEXM3x3DIFF = 0x4b,
+ WINED3D_SM1_OP_TEXM3x3SPEC = 0x4c,
+ WINED3D_SM1_OP_TEXM3x3VSPEC = 0x4d,
+ WINED3D_SM1_OP_EXPP = 0x4e,
+ WINED3D_SM1_OP_LOGP = 0x4f,
+ WINED3D_SM1_OP_CND = 0x50,
+ WINED3D_SM1_OP_DEF = 0x51,
+ WINED3D_SM1_OP_TEXREG2RGB = 0x52,
+ WINED3D_SM1_OP_TEXDP3TEX = 0x53,
+ WINED3D_SM1_OP_TEXM3x2DEPTH = 0x54,
+ WINED3D_SM1_OP_TEXDP3 = 0x55,
+ WINED3D_SM1_OP_TEXM3x3 = 0x56,
+ WINED3D_SM1_OP_TEXDEPTH = 0x57,
+ WINED3D_SM1_OP_CMP = 0x58,
+ WINED3D_SM1_OP_BEM = 0x59,
+ WINED3D_SM1_OP_DP2ADD = 0x5a,
+ WINED3D_SM1_OP_DSX = 0x5b,
+ WINED3D_SM1_OP_DSY = 0x5c,
+ WINED3D_SM1_OP_TEXLDD = 0x5d,
+ WINED3D_SM1_OP_SETP = 0x5e,
+ WINED3D_SM1_OP_TEXLDL = 0x5f,
+ WINED3D_SM1_OP_BREAKP = 0x60,
+
+ WINED3D_SM1_OP_PHASE = 0xfffd,
+ WINED3D_SM1_OP_COMMENT = 0xfffe,
+ WINED3D_SM1_OP_END = 0Xffff,
+};
+
+struct wined3d_sm1_opcode_info
+{
+ enum wined3d_sm1_opcode opcode;
+ UINT dst_count;
+ UINT param_count;
+ enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx;
+ DWORD min_version;
+ DWORD max_version;
+};
+
+struct wined3d_sm1_data
+{
+ struct wined3d_shader_version shader_version;
+ const struct wined3d_sm1_opcode_info *opcode_table;
+
+ struct wined3d_shader_src_param src_rel_addr[4];
+ struct wined3d_shader_src_param pred_rel_addr;
+ struct wined3d_shader_src_param dst_rel_addr;
+ struct wined3d_shader_src_param src_param[4];
+ struct wined3d_shader_src_param pred_param;
+ struct wined3d_shader_dst_param dst_param;
+};
+
+/* This table is not order or position dependent. */
+static const struct wined3d_sm1_opcode_info vs_opcode_table[] =
+{
+ /* Arithmetic */
+ {WINED3D_SM1_OP_NOP, 0, 0, WINED3DSIH_NOP, 0, 0 },
+ {WINED3D_SM1_OP_MOV, 1, 2, WINED3DSIH_MOV, 0, 0 },
+ {WINED3D_SM1_OP_MOVA, 1, 2, WINED3DSIH_MOVA, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3D_SM1_OP_ADD, 1, 3, WINED3DSIH_ADD, 0, 0 },
+ {WINED3D_SM1_OP_SUB, 1, 3, WINED3DSIH_SUB, 0, 0 },
+ {WINED3D_SM1_OP_MAD, 1, 4, WINED3DSIH_MAD, 0, 0 },
+ {WINED3D_SM1_OP_MUL, 1, 3, WINED3DSIH_MUL, 0, 0 },
+ {WINED3D_SM1_OP_RCP, 1, 2, WINED3DSIH_RCP, 0, 0 },
+ {WINED3D_SM1_OP_RSQ, 1, 2, WINED3DSIH_RSQ, 0, 0 },
+ {WINED3D_SM1_OP_DP3, 1, 3, WINED3DSIH_DP3, 0, 0 },
+ {WINED3D_SM1_OP_DP4, 1, 3, WINED3DSIH_DP4, 0, 0 },
+ {WINED3D_SM1_OP_MIN, 1, 3, WINED3DSIH_MIN, 0, 0 },
+ {WINED3D_SM1_OP_MAX, 1, 3, WINED3DSIH_MAX, 0, 0 },
+ {WINED3D_SM1_OP_SLT, 1, 3, WINED3DSIH_SLT, 0, 0 },
+ {WINED3D_SM1_OP_SGE, 1, 3, WINED3DSIH_SGE, 0, 0 },
+ {WINED3D_SM1_OP_ABS, 1, 2, WINED3DSIH_ABS, 0, 0 },
+ {WINED3D_SM1_OP_EXP, 1, 2, WINED3DSIH_EXP, 0, 0 },
+ {WINED3D_SM1_OP_LOG, 1, 2, WINED3DSIH_LOG, 0, 0 },
+ {WINED3D_SM1_OP_EXPP, 1, 2, WINED3DSIH_EXPP, 0, 0 },
+ {WINED3D_SM1_OP_LOGP, 1, 2, WINED3DSIH_LOGP, 0, 0 },
+ {WINED3D_SM1_OP_LIT, 1, 2, WINED3DSIH_LIT, 0, 0 },
+ {WINED3D_SM1_OP_DST, 1, 3, WINED3DSIH_DST, 0, 0 },
+ {WINED3D_SM1_OP_LRP, 1, 4, WINED3DSIH_LRP, 0, 0 },
+ {WINED3D_SM1_OP_FRC, 1, 2, WINED3DSIH_FRC, 0, 0 },
+ {WINED3D_SM1_OP_POW, 1, 3, WINED3DSIH_POW, 0, 0 },
+ {WINED3D_SM1_OP_CRS, 1, 3, WINED3DSIH_CRS, 0, 0 },
+ {WINED3D_SM1_OP_SGN, 1, 4, WINED3DSIH_SGN, WINED3D_SHADER_VERSION(2,0), WINED3D_SHADER_VERSION(2,1)},
+ {WINED3D_SM1_OP_SGN, 1, 2, WINED3DSIH_SGN, WINED3D_SHADER_VERSION(3,0), -1 },
+ {WINED3D_SM1_OP_NRM, 1, 2, WINED3DSIH_NRM, 0, 0 },
+ {WINED3D_SM1_OP_SINCOS, 1, 4, WINED3DSIH_SINCOS, WINED3D_SHADER_VERSION(2,0), WINED3D_SHADER_VERSION(2,1)},
+ {WINED3D_SM1_OP_SINCOS, 1, 2, WINED3DSIH_SINCOS, WINED3D_SHADER_VERSION(3,0), -1 },
+ /* Matrix */
+ {WINED3D_SM1_OP_M4x4, 1, 3, WINED3DSIH_M4x4, 0, 0 },
+ {WINED3D_SM1_OP_M4x3, 1, 3, WINED3DSIH_M4x3, 0, 0 },
+ {WINED3D_SM1_OP_M3x4, 1, 3, WINED3DSIH_M3x4, 0, 0 },
+ {WINED3D_SM1_OP_M3x3, 1, 3, WINED3DSIH_M3x3, 0, 0 },
+ {WINED3D_SM1_OP_M3x2, 1, 3, WINED3DSIH_M3x2, 0, 0 },
+ /* Declare registers */
+ {WINED3D_SM1_OP_DCL, 0, 2, WINED3DSIH_DCL, 0, 0 },
+ /* Constant definitions */
+ {WINED3D_SM1_OP_DEF, 1, 5, WINED3DSIH_DEF, 0, 0 },
+ {WINED3D_SM1_OP_DEFB, 1, 2, WINED3DSIH_DEFB, 0, 0 },
+ {WINED3D_SM1_OP_DEFI, 1, 5, WINED3DSIH_DEFI, 0, 0 },
+ /* Flow control */
+ {WINED3D_SM1_OP_REP, 0, 1, WINED3DSIH_REP, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3D_SM1_OP_ENDREP, 0, 0, WINED3DSIH_ENDREP, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3D_SM1_OP_IF, 0, 1, WINED3DSIH_IF, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3D_SM1_OP_IFC, 0, 2, WINED3DSIH_IFC, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3D_SM1_OP_ELSE, 0, 0, WINED3DSIH_ELSE, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3D_SM1_OP_ENDIF, 0, 0, WINED3DSIH_ENDIF, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3D_SM1_OP_BREAK, 0, 0, WINED3DSIH_BREAK, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3D_SM1_OP_BREAKC, 0, 2, WINED3DSIH_BREAKC, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3D_SM1_OP_BREAKP, 0, 1, WINED3DSIH_BREAKP, 0, 0 },
+ {WINED3D_SM1_OP_CALL, 0, 1, WINED3DSIH_CALL, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3D_SM1_OP_CALLNZ, 0, 2, WINED3DSIH_CALLNZ, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3D_SM1_OP_LOOP, 0, 2, WINED3DSIH_LOOP, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3D_SM1_OP_RET, 0, 0, WINED3DSIH_RET, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3D_SM1_OP_ENDLOOP, 0, 0, WINED3DSIH_ENDLOOP, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3D_SM1_OP_LABEL, 0, 1, WINED3DSIH_LABEL, WINED3D_SHADER_VERSION(2,0), -1 },
+
+ {WINED3D_SM1_OP_SETP, 1, 3, WINED3DSIH_SETP, 0, 0 },
+ {WINED3D_SM1_OP_TEXLDL, 1, 3, WINED3DSIH_TEXLDL, WINED3D_SHADER_VERSION(3,0), -1 },
+ {0, 0, 0, WINED3DSIH_TABLE_SIZE, 0, 0 },
+};
+
+static const struct wined3d_sm1_opcode_info ps_opcode_table[] =
+{
+ /* Arithmetic */
+ {WINED3D_SM1_OP_NOP, 0, 0, WINED3DSIH_NOP, 0, 0 },
+ {WINED3D_SM1_OP_MOV, 1, 2, WINED3DSIH_MOV, 0, 0 },
+ {WINED3D_SM1_OP_ADD, 1, 3, WINED3DSIH_ADD, 0, 0 },
+ {WINED3D_SM1_OP_SUB, 1, 3, WINED3DSIH_SUB, 0, 0 },
+ {WINED3D_SM1_OP_MAD, 1, 4, WINED3DSIH_MAD, 0, 0 },
+ {WINED3D_SM1_OP_MUL, 1, 3, WINED3DSIH_MUL, 0, 0 },
+ {WINED3D_SM1_OP_RCP, 1, 2, WINED3DSIH_RCP, 0, 0 },
+ {WINED3D_SM1_OP_RSQ, 1, 2, WINED3DSIH_RSQ, 0, 0 },
+ {WINED3D_SM1_OP_DP3, 1, 3, WINED3DSIH_DP3, 0, 0 },
+ {WINED3D_SM1_OP_DP4, 1, 3, WINED3DSIH_DP4, 0, 0 },
+ {WINED3D_SM1_OP_MIN, 1, 3, WINED3DSIH_MIN, 0, 0 },
+ {WINED3D_SM1_OP_MAX, 1, 3, WINED3DSIH_MAX, 0, 0 },
+ {WINED3D_SM1_OP_SLT, 1, 3, WINED3DSIH_SLT, 0, 0 },
+ {WINED3D_SM1_OP_SGE, 1, 3, WINED3DSIH_SGE, 0, 0 },
+ {WINED3D_SM1_OP_ABS, 1, 2, WINED3DSIH_ABS, 0, 0 },
+ {WINED3D_SM1_OP_EXP, 1, 2, WINED3DSIH_EXP, 0, 0 },
+ {WINED3D_SM1_OP_LOG, 1, 2, WINED3DSIH_LOG, 0, 0 },
+ {WINED3D_SM1_OP_EXPP, 1, 2, WINED3DSIH_EXPP, 0, 0 },
+ {WINED3D_SM1_OP_LOGP, 1, 2, WINED3DSIH_LOGP, 0, 0 },
+ {WINED3D_SM1_OP_DST, 1, 3, WINED3DSIH_DST, 0, 0 },
+ {WINED3D_SM1_OP_LRP, 1, 4, WINED3DSIH_LRP, 0, 0 },
+ {WINED3D_SM1_OP_FRC, 1, 2, WINED3DSIH_FRC, 0, 0 },
+ {WINED3D_SM1_OP_CND, 1, 4, WINED3DSIH_CND, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,4)},
+ {WINED3D_SM1_OP_CMP, 1, 4, WINED3DSIH_CMP, WINED3D_SHADER_VERSION(1,2), WINED3D_SHADER_VERSION(3,0)},
+ {WINED3D_SM1_OP_POW, 1, 3, WINED3DSIH_POW, 0, 0 },
+ {WINED3D_SM1_OP_CRS, 1, 3, WINED3DSIH_CRS, 0, 0 },
+ {WINED3D_SM1_OP_NRM, 1, 2, WINED3DSIH_NRM, 0, 0 },
+ {WINED3D_SM1_OP_SINCOS, 1, 4, WINED3DSIH_SINCOS, WINED3D_SHADER_VERSION(2,0), WINED3D_SHADER_VERSION(2,1)},
+ {WINED3D_SM1_OP_SINCOS, 1, 2, WINED3DSIH_SINCOS, WINED3D_SHADER_VERSION(3,0), -1 },
+ {WINED3D_SM1_OP_DP2ADD, 1, 4, WINED3DSIH_DP2ADD, WINED3D_SHADER_VERSION(2,0), -1 },
+ /* Matrix */
+ {WINED3D_SM1_OP_M4x4, 1, 3, WINED3DSIH_M4x4, 0, 0 },
+ {WINED3D_SM1_OP_M4x3, 1, 3, WINED3DSIH_M4x3, 0, 0 },
+ {WINED3D_SM1_OP_M3x4, 1, 3, WINED3DSIH_M3x4, 0, 0 },
+ {WINED3D_SM1_OP_M3x3, 1, 3, WINED3DSIH_M3x3, 0, 0 },
+ {WINED3D_SM1_OP_M3x2, 1, 3, WINED3DSIH_M3x2, 0, 0 },
+ /* Register declarations */
+ {WINED3D_SM1_OP_DCL, 0, 2, WINED3DSIH_DCL, 0, 0 },
+ /* Flow control */
+ {WINED3D_SM1_OP_REP, 0, 1, WINED3DSIH_REP, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3D_SM1_OP_ENDREP, 0, 0, WINED3DSIH_ENDREP, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3D_SM1_OP_IF, 0, 1, WINED3DSIH_IF, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3D_SM1_OP_IFC, 0, 2, WINED3DSIH_IFC, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3D_SM1_OP_ELSE, 0, 0, WINED3DSIH_ELSE, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3D_SM1_OP_ENDIF, 0, 0, WINED3DSIH_ENDIF, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3D_SM1_OP_BREAK, 0, 0, WINED3DSIH_BREAK, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3D_SM1_OP_BREAKC, 0, 2, WINED3DSIH_BREAKC, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3D_SM1_OP_BREAKP, 0, 1, WINED3DSIH_BREAKP, 0, 0 },
+ {WINED3D_SM1_OP_CALL, 0, 1, WINED3DSIH_CALL, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3D_SM1_OP_CALLNZ, 0, 2, WINED3DSIH_CALLNZ, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3D_SM1_OP_LOOP, 0, 2, WINED3DSIH_LOOP, WINED3D_SHADER_VERSION(3,0), -1 },
+ {WINED3D_SM1_OP_RET, 0, 0, WINED3DSIH_RET, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3D_SM1_OP_ENDLOOP, 0, 0, WINED3DSIH_ENDLOOP, WINED3D_SHADER_VERSION(3,0), -1 },
+ {WINED3D_SM1_OP_LABEL, 0, 1, WINED3DSIH_LABEL, WINED3D_SHADER_VERSION(2,1), -1 },
+ /* Constant definitions */
+ {WINED3D_SM1_OP_DEF, 1, 5, WINED3DSIH_DEF, 0, 0 },
+ {WINED3D_SM1_OP_DEFB, 1, 2, WINED3DSIH_DEFB, 0, 0 },
+ {WINED3D_SM1_OP_DEFI, 1, 5, WINED3DSIH_DEFI, 0, 0 },
+ /* Texture */
+ {WINED3D_SM1_OP_TEXCOORD, 1, 1, WINED3DSIH_TEXCOORD, 0, WINED3D_SHADER_VERSION(1,3)},
+ {WINED3D_SM1_OP_TEXCOORD, 1, 2, WINED3DSIH_TEXCOORD, WINED3D_SHADER_VERSION(1,4), WINED3D_SHADER_VERSION(1,4)},
+ {WINED3D_SM1_OP_TEXKILL, 1, 1, WINED3DSIH_TEXKILL, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(3,0)},
+ {WINED3D_SM1_OP_TEX, 1, 1, WINED3DSIH_TEX, 0, WINED3D_SHADER_VERSION(1,3)},
+ {WINED3D_SM1_OP_TEX, 1, 2, WINED3DSIH_TEX, WINED3D_SHADER_VERSION(1,4), WINED3D_SHADER_VERSION(1,4)},
+ {WINED3D_SM1_OP_TEX, 1, 3, WINED3DSIH_TEX, WINED3D_SHADER_VERSION(2,0), -1 },
+ {WINED3D_SM1_OP_TEXBEM, 1, 2, WINED3DSIH_TEXBEM, 0, WINED3D_SHADER_VERSION(1,3)},
+ {WINED3D_SM1_OP_TEXBEML, 1, 2, WINED3DSIH_TEXBEML, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3D_SM1_OP_TEXREG2AR, 1, 2, WINED3DSIH_TEXREG2AR, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3D_SM1_OP_TEXREG2GB, 1, 2, WINED3DSIH_TEXREG2GB, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3D_SM1_OP_TEXREG2RGB, 1, 2, WINED3DSIH_TEXREG2RGB, WINED3D_SHADER_VERSION(1,2), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3D_SM1_OP_TEXM3x2PAD, 1, 2, WINED3DSIH_TEXM3x2PAD, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3D_SM1_OP_TEXM3x2TEX, 1, 2, WINED3DSIH_TEXM3x2TEX, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3D_SM1_OP_TEXM3x3PAD, 1, 2, WINED3DSIH_TEXM3x3PAD, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3D_SM1_OP_TEXM3x3DIFF, 1, 2, WINED3DSIH_TEXM3x3DIFF, WINED3D_SHADER_VERSION(0,0), WINED3D_SHADER_VERSION(0,0)},
+ {WINED3D_SM1_OP_TEXM3x3SPEC, 1, 3, WINED3DSIH_TEXM3x3SPEC, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3D_SM1_OP_TEXM3x3VSPEC, 1, 2, WINED3DSIH_TEXM3x3VSPEC, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3D_SM1_OP_TEXM3x3TEX, 1, 2, WINED3DSIH_TEXM3x3TEX, WINED3D_SHADER_VERSION(1,0), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3D_SM1_OP_TEXDP3TEX, 1, 2, WINED3DSIH_TEXDP3TEX, WINED3D_SHADER_VERSION(1,2), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3D_SM1_OP_TEXM3x2DEPTH, 1, 2, WINED3DSIH_TEXM3x2DEPTH, WINED3D_SHADER_VERSION(1,3), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3D_SM1_OP_TEXDP3, 1, 2, WINED3DSIH_TEXDP3, WINED3D_SHADER_VERSION(1,2), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3D_SM1_OP_TEXM3x3, 1, 2, WINED3DSIH_TEXM3x3, WINED3D_SHADER_VERSION(1,2), WINED3D_SHADER_VERSION(1,3)},
+ {WINED3D_SM1_OP_TEXDEPTH, 1, 1, WINED3DSIH_TEXDEPTH, WINED3D_SHADER_VERSION(1,4), WINED3D_SHADER_VERSION(1,4)},
+ {WINED3D_SM1_OP_BEM, 1, 3, WINED3DSIH_BEM, WINED3D_SHADER_VERSION(1,4), WINED3D_SHADER_VERSION(1,4)},
+ {WINED3D_SM1_OP_DSX, 1, 2, WINED3DSIH_DSX, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3D_SM1_OP_DSY, 1, 2, WINED3DSIH_DSY, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3D_SM1_OP_TEXLDD, 1, 5, WINED3DSIH_TEXLDD, WINED3D_SHADER_VERSION(2,1), -1 },
+ {WINED3D_SM1_OP_SETP, 1, 3, WINED3DSIH_SETP, 0, 0 },
+ {WINED3D_SM1_OP_TEXLDL, 1, 3, WINED3DSIH_TEXLDL, WINED3D_SHADER_VERSION(3,0), -1 },
+ {WINED3D_SM1_OP_PHASE, 0, 0, WINED3DSIH_PHASE, 0, 0 },
+ {0, 0, 0, WINED3DSIH_TABLE_SIZE, 0, 0 },
+};
+
+/* Read a parameter opcode from the input stream,
+ * and possibly a relative addressing token.
+ * Return the number of tokens read */
+static int shader_get_param(const struct wined3d_sm1_data *priv, const DWORD *ptr, DWORD *token, DWORD *addr_token)
+{
+ UINT count = 1;
+
+ *token = *ptr;
+
+ /* PS >= 3.0 have relative addressing (with token)
+ * VS >= 2.0 have relative addressing (with token)
+ * VS >= 1.0 < 2.0 have relative addressing (without token)
+ * The version check below should work in general */
+ if (*ptr & WINED3DSHADER_ADDRMODE_RELATIVE)
+ {
+ if (priv->shader_version.major < 2)
+ {
+ *addr_token = (1 << 31)
+ | ((WINED3DSPR_ADDR << WINED3DSP_REGTYPE_SHIFT2) & WINED3DSP_REGTYPE_MASK2)
+ | ((WINED3DSPR_ADDR << WINED3DSP_REGTYPE_SHIFT) & WINED3DSP_REGTYPE_MASK)
+ | (WINED3DSP_NOSWIZZLE << WINED3DSP_SWIZZLE_SHIFT);
+ }
+ else
+ {
+ *addr_token = *(ptr + 1);
+ ++count;
+ }
+ }
+
+ return count;
+}
+
+static const struct wined3d_sm1_opcode_info *shader_get_opcode(const struct wined3d_sm1_data *priv, DWORD code)
+{
+ DWORD shader_version = WINED3D_SHADER_VERSION(priv->shader_version.major, priv->shader_version.minor);
+ const struct wined3d_sm1_opcode_info *opcode_table = priv->opcode_table;
+ DWORD i = 0;
+
+ while (opcode_table[i].handler_idx != WINED3DSIH_TABLE_SIZE)
+ {
+ if ((code & WINED3DSI_OPCODE_MASK) == opcode_table[i].opcode
+ && shader_version >= opcode_table[i].min_version
+ && (!opcode_table[i].max_version || shader_version <= opcode_table[i].max_version))
+ {
+ return &opcode_table[i];
+ }
+ ++i;
+ }
+
+ FIXME("Unsupported opcode %#x(%d) masked %#x, shader version %#x\n",
+ code, code, code & WINED3DSI_OPCODE_MASK, shader_version);
+
+ return NULL;
+}
+
+/* Return the number of parameters to skip for an opcode */
+static int shader_skip_opcode(const struct wined3d_sm1_data *priv,
+ const struct wined3d_sm1_opcode_info *opcode_info, DWORD opcode_token)
+{
+ /* Shaders >= 2.0 may contain address tokens, but fortunately they
+ * have a useful length mask - use it here. Shaders 1.0 contain no such tokens */
+ return (priv->shader_version.major >= 2)
+ ? ((opcode_token & WINED3DSI_INSTLENGTH_MASK) >> WINED3DSI_INSTLENGTH_SHIFT) : opcode_info->param_count;
+}
+
+static void shader_parse_src_param(DWORD param, const struct wined3d_shader_src_param *rel_addr,
+ struct wined3d_shader_src_param *src)
+{
+ src->reg.type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT)
+ | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2);
+ src->reg.data_type = WINED3D_DATA_FLOAT;
+ src->reg.idx[0].offset = param & WINED3DSP_REGNUM_MASK;
+ src->reg.idx[0].rel_addr = rel_addr;
+ src->reg.idx[1].offset = ~0U;
+ src->reg.idx[1].rel_addr = NULL;
+ src->swizzle = (param & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT;
+ src->modifiers = (param & WINED3DSP_SRCMOD_MASK) >> WINED3DSP_SRCMOD_SHIFT;
+}
+
+static void shader_parse_dst_param(DWORD param, const struct wined3d_shader_src_param *rel_addr,
+ struct wined3d_shader_dst_param *dst)
+{
+ dst->reg.type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT)
+ | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2);
+ dst->reg.data_type = WINED3D_DATA_FLOAT;
+ dst->reg.idx[0].offset = param & WINED3DSP_REGNUM_MASK;
+ dst->reg.idx[0].rel_addr = rel_addr;
+ dst->reg.idx[1].offset = ~0U;
+ dst->reg.idx[1].rel_addr = NULL;
+ dst->write_mask = (param & WINED3D_SM1_WRITEMASK_MASK) >> WINED3D_SM1_WRITEMASK_SHIFT;
+ dst->modifiers = (param & WINED3DSP_DSTMOD_MASK) >> WINED3DSP_DSTMOD_SHIFT;
+ dst->shift = (param & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT;
+}
+
+/* Read the parameters of an unrecognized opcode from the input stream
+ * Return the number of tokens read.
+ *
+ * Note: This function assumes source or destination token format.
+ * It will not work with specially-formatted tokens like DEF or DCL,
+ * but hopefully those would be recognized */
+static int shader_skip_unrecognized(const struct wined3d_sm1_data *priv, const DWORD *ptr)
+{
+ int tokens_read = 0;
+ int i = 0;
+
+ /* TODO: Think of a good name for 0x80000000 and replace it with a constant */
+ while (*ptr & 0x80000000)
+ {
+ DWORD token, addr_token = 0;
+ struct wined3d_shader_src_param rel_addr;
+
+ tokens_read += shader_get_param(priv, ptr, &token, &addr_token);
+ ptr += tokens_read;
+
+ FIXME("Unrecognized opcode param: token=0x%08x addr_token=0x%08x name=", token, addr_token);
+
+ if (token & WINED3DSHADER_ADDRMODE_RELATIVE) shader_parse_src_param(addr_token, NULL, &rel_addr);
+
+ if (!i)
+ {
+ struct wined3d_shader_dst_param dst;
+
+ shader_parse_dst_param(token, token & WINED3DSHADER_ADDRMODE_RELATIVE ? &rel_addr : NULL, &dst);
+ shader_dump_dst_param(&dst, &priv->shader_version);
+ }
+ else
+ {
+ struct wined3d_shader_src_param src;
+
+ shader_parse_src_param(token, token & WINED3DSHADER_ADDRMODE_RELATIVE ? &rel_addr : NULL, &src);
+ shader_dump_src_param(&src, &priv->shader_version);
+ }
+ FIXME("\n");
+ ++i;
+ }
+ return tokens_read;
+}
+
+static void *shader_sm1_init(const DWORD *byte_code, const struct wined3d_shader_signature *output_signature)
+{
+ struct wined3d_sm1_data *priv;
+ BYTE major, minor;
+
+ major = WINED3D_SM1_VERSION_MAJOR(*byte_code);
+ minor = WINED3D_SM1_VERSION_MINOR(*byte_code);
+ if (WINED3D_SHADER_VERSION(major, minor) > WINED3D_SHADER_VERSION(3, 0))
+ {
+ WARN("Invalid shader version %u.%u (%#x).\n", major, minor, *byte_code);
+ return NULL;
+ }
+
+ priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv));
+ if (!priv)
+ return NULL;
+
+ if (output_signature)
+ {
+ FIXME("SM 1-3 shader shouldn't have output signatures.\n");
+ }
+
+ switch (*byte_code >> 16)
+ {
+ case WINED3D_SM1_VS:
+ priv->shader_version.type = WINED3D_SHADER_TYPE_VERTEX;
+ priv->opcode_table = vs_opcode_table;
+ break;
+
+ case WINED3D_SM1_PS:
+ priv->shader_version.type = WINED3D_SHADER_TYPE_PIXEL;
+ priv->opcode_table = ps_opcode_table;
+ break;
+
+ default:
+ FIXME("Unrecognized shader type %#x\n", *byte_code >> 16);
+ HeapFree(GetProcessHeap(), 0, priv);
+ return NULL;
+ }
+
+ return priv;
+}
+
+static void shader_sm1_free(void *data)
+{
+ HeapFree(GetProcessHeap(), 0, data);
+}
+
+static void shader_sm1_read_header(void *data, const DWORD **ptr, struct wined3d_shader_version *shader_version)
+{
+ struct wined3d_sm1_data *priv = data;
+ DWORD version_token;
+
+ version_token = *(*ptr)++;
+ TRACE("version: 0x%08x\n", version_token);
+
+ priv->shader_version.major = WINED3D_SM1_VERSION_MAJOR(version_token);
+ priv->shader_version.minor = WINED3D_SM1_VERSION_MINOR(version_token);
+ *shader_version = priv->shader_version;
+}
+
+static void shader_sm1_read_src_param(struct wined3d_sm1_data *priv, const DWORD **ptr,
+ struct wined3d_shader_src_param *src_param, struct wined3d_shader_src_param *src_rel_addr)
+{
+ DWORD token, addr_token;
+
+ *ptr += shader_get_param(priv, *ptr, &token, &addr_token);
+ if (token & WINED3DSHADER_ADDRMODE_RELATIVE)
+ {
+ shader_parse_src_param(addr_token, NULL, src_rel_addr);
+ shader_parse_src_param(token, src_rel_addr, src_param);
+ }
+ else
+ {
+ shader_parse_src_param(token, NULL, src_param);
+ }
+}
+
+static void shader_sm1_read_dst_param(struct wined3d_sm1_data *priv, const DWORD **ptr,
+ struct wined3d_shader_dst_param *dst_param, struct wined3d_shader_src_param *dst_rel_addr)
+{
+ DWORD token, addr_token;
+
+ *ptr += shader_get_param(priv, *ptr, &token, &addr_token);
+ if (token & WINED3DSHADER_ADDRMODE_RELATIVE)
+ {
+ shader_parse_src_param(addr_token, NULL, dst_rel_addr);
+ shader_parse_dst_param(token, dst_rel_addr, dst_param);
+ }
+ else
+ {
+ shader_parse_dst_param(token, NULL, dst_param);
+ }
+}
+
+static void shader_sm1_read_semantic(const DWORD **ptr, struct wined3d_shader_semantic *semantic)
+{
+ DWORD usage_token = *(*ptr)++;
+ DWORD dst_token = *(*ptr)++;
+
+ semantic->usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
+ semantic->usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
+ semantic->sampler_type = (usage_token & WINED3DSP_TEXTURETYPE_MASK) >> WINED3DSP_TEXTURETYPE_SHIFT;
+ shader_parse_dst_param(dst_token, NULL, &semantic->reg);
+}
+
+static void shader_sm1_read_immconst(const DWORD **ptr, struct wined3d_shader_src_param *src_param,
+ enum wined3d_immconst_type type, enum wined3d_data_type data_type)
+{
+ UINT count = type == WINED3D_IMMCONST_VEC4 ? 4 : 1;
+ src_param->reg.type = WINED3DSPR_IMMCONST;
+ src_param->reg.data_type = data_type;
+ src_param->reg.idx[0].offset = ~0U;
+ src_param->reg.idx[0].rel_addr = NULL;
+ src_param->reg.idx[1].offset = ~0U;
+ src_param->reg.idx[1].rel_addr = NULL;
+ src_param->reg.immconst_type = type;
+ memcpy(src_param->reg.immconst_data, *ptr, count * sizeof(DWORD));
+ src_param->swizzle = WINED3DSP_NOSWIZZLE;
+ src_param->modifiers = 0;
+
+ *ptr += count;
+}
+
+static void shader_sm1_read_comment(const DWORD **ptr)
+{
+ DWORD token = **ptr;
+ const char *comment;
+ UINT size;
+
+ while ((token & WINED3DSI_OPCODE_MASK) == WINED3D_SM1_OP_COMMENT)
+ {
+ size = (token & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT;
+ comment = (const char *)++(*ptr);
+ *ptr += size;
+
+ if (size > 1 && *(const DWORD *)comment == WINEMAKEFOURCC('T', 'E', 'X', 'T'))
+ {
+ const char *end = comment + size * sizeof(token);
+ const char *p = comment + sizeof(token);
+ const char *line = p;
+
+ TRACE("// TEXT\n");
+ while (p != end)
+ {
+ if (*p == '\n')
+ {
+ UINT len = p - line;
+ if (len && *(p - 1) == '\r') --len;
+ TRACE("// %s\n", debugstr_an(line, len));
+ line = ++p;
+ }
+ else ++p;
+ }
+ if (line != p)
+ TRACE("// %s\n", debugstr_an(line, p - line));
+ }
+ else if (size)
+ TRACE("// %s\n", debugstr_an(comment, size * sizeof(token)));
+ else
+ break;
+
+ token = **ptr;
+ }
+}
+
+static void shader_sm1_read_instruction(void *data, const DWORD **ptr, struct wined3d_shader_instruction *ins)
+{
+ const struct wined3d_sm1_opcode_info *opcode_info;
+ struct wined3d_sm1_data *priv = data;
+ DWORD opcode_token;
+ unsigned int i;
+ const DWORD *p;
+
+ shader_sm1_read_comment(ptr);
+
+ opcode_token = *(*ptr)++;
+ if (!(opcode_info = shader_get_opcode(priv, opcode_token)))
+ {
+ FIXME("Unrecognized opcode: token=0x%08x.\n", opcode_token);
+ ins->handler_idx = WINED3DSIH_TABLE_SIZE;
+ *ptr += shader_skip_unrecognized(priv, *ptr);
+ return;
+ }
+
+ ins->handler_idx = opcode_info->handler_idx;
+ ins->flags = (opcode_token & WINED3D_OPCODESPECIFICCONTROL_MASK) >> WINED3D_OPCODESPECIFICCONTROL_SHIFT;
+ ins->coissue = opcode_token & WINED3DSI_COISSUE;
+ ins->predicate = opcode_token & WINED3DSHADER_INSTRUCTION_PREDICATED ? &priv->pred_param : NULL;
+ ins->dst_count = opcode_info->dst_count ? 1 : 0;
+ ins->dst = &priv->dst_param;
+ ins->src_count = opcode_info->param_count - opcode_info->dst_count;
+ ins->src = priv->src_param;
+
+ p = *ptr;
+ *ptr += shader_skip_opcode(priv, opcode_info, opcode_token);
+
+ if (ins->handler_idx == WINED3DSIH_DCL)
+ {
+ shader_sm1_read_semantic(&p, &ins->declaration.semantic);
+ }
+ else if (ins->handler_idx == WINED3DSIH_DEF)
+ {
+ shader_sm1_read_dst_param(priv, &p, &priv->dst_param, &priv->dst_rel_addr);
+ shader_sm1_read_immconst(&p, &priv->src_param[0], WINED3D_IMMCONST_VEC4, WINED3D_DATA_FLOAT);
+ }
+ else if (ins->handler_idx == WINED3DSIH_DEFI)
+ {
+ shader_sm1_read_dst_param(priv, &p, &priv->dst_param, &priv->dst_rel_addr);
+ shader_sm1_read_immconst(&p, &priv->src_param[0], WINED3D_IMMCONST_VEC4, WINED3D_DATA_INT);
+ }
+ else if (ins->handler_idx == WINED3DSIH_DEFB)
+ {
+ shader_sm1_read_dst_param(priv, &p, &priv->dst_param, &priv->dst_rel_addr);
+ shader_sm1_read_immconst(&p, &priv->src_param[0], WINED3D_IMMCONST_SCALAR, WINED3D_DATA_UINT);
+ }
+ else
+ {
+ /* Destination token */
+ if (ins->dst_count)
+ shader_sm1_read_dst_param(priv, &p, &priv->dst_param, &priv->dst_rel_addr);
+
+ /* Predication token */
+ if (ins->predicate)
+ shader_sm1_read_src_param(priv, &p, &priv->pred_param, &priv->pred_rel_addr);
+
+ /* Other source tokens */
+ for (i = 0; i < ins->src_count; ++i)
+ {
+ shader_sm1_read_src_param(priv, &p, &priv->src_param[i], &priv->src_rel_addr[i]);
+ }
+ }
+}
+
+static BOOL shader_sm1_is_end(void *data, const DWORD **ptr)
+{
+ shader_sm1_read_comment(ptr);
+
+ if (**ptr == WINED3DSP_END)
+ {
+ ++(*ptr);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+const struct wined3d_shader_frontend sm1_shader_frontend =
+{
+ shader_sm1_init,
+ shader_sm1_free,
+ shader_sm1_read_header,
+ shader_sm1_read_instruction,
+ shader_sm1_is_end,
+};
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/shader_sm4.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/shader_sm4.c
new file mode 100644
index 00000000..9cb5e0ce
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/shader_sm4.c
@@ -0,0 +1,815 @@
+/*
+ * Copyright 2009 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_bytecode);
+
+#define WINED3D_SM4_INSTRUCTION_MODIFIER (1 << 31)
+
+#define WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT 24
+#define WINED3D_SM4_INSTRUCTION_LENGTH_MASK (0xf << WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT)
+
+#define WINED3D_SM4_PRIMITIVE_TYPE_SHIFT 11
+#define WINED3D_SM4_PRIMITIVE_TYPE_MASK (0x7 << WINED3D_SM4_PRIMITIVE_TYPE_SHIFT)
+
+#define WINED3D_SM4_INDEX_TYPE_SHIFT 11
+#define WINED3D_SM4_INDEX_TYPE_MASK (0x1 << WINED3D_SM4_INDEX_TYPE_SHIFT)
+
+#define WINED3D_SM4_OPCODE_MASK 0xff
+
+#define WINED3D_SM4_REGISTER_MODIFIER (1 << 31)
+
+#define WINED3D_SM4_ADDRESSING_SHIFT1 25
+#define WINED3D_SM4_ADDRESSING_MASK1 (0x3 << WINED3D_SM4_ADDRESSING_SHIFT1)
+
+#define WINED3D_SM4_ADDRESSING_SHIFT0 22
+#define WINED3D_SM4_ADDRESSING_MASK0 (0x3 << WINED3D_SM4_ADDRESSING_SHIFT0)
+
+#define WINED3D_SM4_REGISTER_ORDER_SHIFT 20
+#define WINED3D_SM4_REGISTER_ORDER_MASK (0x3 << WINED3D_SM4_REGISTER_ORDER_SHIFT)
+
+#define WINED3D_SM4_REGISTER_TYPE_SHIFT 12
+#define WINED3D_SM4_REGISTER_TYPE_MASK (0xf << WINED3D_SM4_REGISTER_TYPE_SHIFT)
+
+#define WINED3D_SM4_SWIZZLE_TYPE_SHIFT 2
+#define WINED3D_SM4_SWIZZLE_TYPE_MASK (0x3 << WINED3D_SM4_SWIZZLE_TYPE_SHIFT)
+
+#define WINED3D_SM4_IMMCONST_TYPE_SHIFT 0
+#define WINED3D_SM4_IMMCONST_TYPE_MASK (0x3 << WINED3D_SM4_IMMCONST_TYPE_SHIFT)
+
+#define WINED3D_SM4_WRITEMASK_SHIFT 4
+#define WINED3D_SM4_WRITEMASK_MASK (0xf << WINED3D_SM4_WRITEMASK_SHIFT)
+
+#define WINED3D_SM4_SWIZZLE_SHIFT 4
+#define WINED3D_SM4_SWIZZLE_MASK (0xff << WINED3D_SM4_SWIZZLE_SHIFT)
+
+#define WINED3D_SM4_VERSION_MAJOR(version) (((version) >> 4) & 0xf)
+#define WINED3D_SM4_VERSION_MINOR(version) (((version) >> 0) & 0xf)
+
+#define WINED3D_SM4_ADDRESSING_RELATIVE 0x2
+#define WINED3D_SM4_ADDRESSING_OFFSET 0x1
+
+enum wined3d_sm4_opcode
+{
+ WINED3D_SM4_OP_ADD = 0x00,
+ WINED3D_SM4_OP_AND = 0x01,
+ WINED3D_SM4_OP_BREAK = 0x02,
+ WINED3D_SM4_OP_BREAKC = 0x03,
+ WINED3D_SM4_OP_CUT = 0x09,
+ WINED3D_SM4_OP_DERIV_RTX = 0x0b,
+ WINED3D_SM4_OP_DERIV_RTY = 0x0c,
+ WINED3D_SM4_OP_DIV = 0x0e,
+ WINED3D_SM4_OP_DP3 = 0x10,
+ WINED3D_SM4_OP_DP4 = 0x11,
+ WINED3D_SM4_OP_EMIT = 0x13,
+ WINED3D_SM4_OP_ENDIF = 0x15,
+ WINED3D_SM4_OP_ENDLOOP = 0x16,
+ WINED3D_SM4_OP_EQ = 0x18,
+ WINED3D_SM4_OP_EXP = 0x19,
+ WINED3D_SM4_OP_FRC = 0x1a,
+ WINED3D_SM4_OP_FTOI = 0x1b,
+ WINED3D_SM4_OP_GE = 0x1d,
+ WINED3D_SM4_OP_IADD = 0x1e,
+ WINED3D_SM4_OP_IF = 0x1f,
+ WINED3D_SM4_OP_IEQ = 0x20,
+ WINED3D_SM4_OP_IGE = 0x21,
+ WINED3D_SM4_OP_IMUL = 0x26,
+ WINED3D_SM4_OP_ITOF = 0x2b,
+ WINED3D_SM4_OP_LD = 0x2d,
+ WINED3D_SM4_OP_LOG = 0x2f,
+ WINED3D_SM4_OP_LOOP = 0x30,
+ WINED3D_SM4_OP_LT = 0x31,
+ WINED3D_SM4_OP_MAD = 0x32,
+ WINED3D_SM4_OP_MIN = 0x33,
+ WINED3D_SM4_OP_MAX = 0x34,
+ WINED3D_SM4_OP_MOV = 0x36,
+ WINED3D_SM4_OP_MOVC = 0x37,
+ WINED3D_SM4_OP_MUL = 0x38,
+ WINED3D_SM4_OP_RET = 0x3e,
+ WINED3D_SM4_OP_ROUND_NI = 0x41,
+ WINED3D_SM4_OP_RSQ = 0x44,
+ WINED3D_SM4_OP_SAMPLE = 0x45,
+ WINED3D_SM4_OP_SAMPLE_LOD = 0x48,
+ WINED3D_SM4_OP_SAMPLE_GRAD = 0x49,
+ WINED3D_SM4_OP_SQRT = 0x4b,
+ WINED3D_SM4_OP_SINCOS = 0x4d,
+ WINED3D_SM4_OP_UDIV = 0x4e,
+ WINED3D_SM4_OP_USHR = 0x55,
+ WINED3D_SM4_OP_UTOF = 0x56,
+ WINED3D_SM4_OP_XOR = 0x57,
+ WINED3D_SM4_OP_DCL_CONSTANT_BUFFER = 0x59,
+ WINED3D_SM4_OP_DCL_OUTPUT_TOPOLOGY = 0x5c,
+ WINED3D_SM4_OP_DCL_INPUT_PRIMITIVE = 0x5d,
+ WINED3D_SM4_OP_DCL_VERTICES_OUT = 0x5e,
+};
+
+enum wined3d_sm4_register_type
+{
+ WINED3D_SM4_RT_TEMP = 0x0,
+ WINED3D_SM4_RT_INPUT = 0x1,
+ WINED3D_SM4_RT_OUTPUT = 0x2,
+ WINED3D_SM4_RT_IMMCONST = 0x4,
+ WINED3D_SM4_RT_SAMPLER = 0x6,
+ WINED3D_SM4_RT_CONSTBUFFER = 0x8,
+ WINED3D_SM4_RT_PRIMID = 0xb,
+ WINED3D_SM4_RT_NULL = 0xd,
+};
+
+enum wined3d_sm4_output_primitive_type
+{
+ WINED3D_SM4_OUTPUT_PT_POINTLIST = 0x1,
+ WINED3D_SM4_OUTPUT_PT_LINELIST = 0x3,
+ WINED3D_SM4_OUTPUT_PT_TRIANGLESTRIP = 0x5,
+};
+
+enum wined3d_sm4_input_primitive_type
+{
+ WINED3D_SM4_INPUT_PT_POINT = 0x1,
+ WINED3D_SM4_INPUT_PT_LINE = 0x2,
+ WINED3D_SM4_INPUT_PT_TRIANGLE = 0x3,
+ WINED3D_SM4_INPUT_PT_LINEADJ = 0x6,
+ WINED3D_SM4_INPUT_PT_TRIANGLEADJ = 0x7,
+};
+
+enum wined3d_sm4_swizzle_type
+{
+ WINED3D_SM4_SWIZZLE_VEC4 = 0x1,
+ WINED3D_SM4_SWIZZLE_SCALAR = 0x2,
+};
+
+enum wined3d_sm4_immconst_type
+{
+ WINED3D_SM4_IMMCONST_SCALAR = 0x1,
+ WINED3D_SM4_IMMCONST_VEC4 = 0x2,
+};
+
+struct wined3d_shader_src_param_entry
+{
+ struct list entry;
+ struct wined3d_shader_src_param param;
+};
+
+struct wined3d_sm4_data
+{
+ struct wined3d_shader_version shader_version;
+ const DWORD *end;
+ const struct wined3d_shader_signature *output_signature;
+
+ struct wined3d_shader_src_param src_param[5];
+ struct wined3d_shader_dst_param dst_param[2];
+ struct list src_free;
+ struct list src;
+};
+
+struct wined3d_sm4_opcode_info
+{
+ enum wined3d_sm4_opcode opcode;
+ enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx;
+ const char *dst_info;
+ const char *src_info;
+};
+
+struct sysval_map
+{
+ enum wined3d_sysval_semantic sysval;
+ enum wined3d_shader_register_type register_type;
+ UINT register_idx;
+};
+
+/*
+ * F -> WINED3D_DATA_FLOAT
+ * I -> WINED3D_DATA_INT
+ * R -> WINED3D_DATA_RESOURCE
+ * S -> WINED3D_DATA_SAMPLER
+ * U -> WINED3D_DATA_UINT
+ */
+static const struct wined3d_sm4_opcode_info opcode_table[] =
+{
+ {WINED3D_SM4_OP_ADD, WINED3DSIH_ADD, "F", "FF"},
+ {WINED3D_SM4_OP_AND, WINED3DSIH_AND, "U", "UU"},
+ {WINED3D_SM4_OP_BREAK, WINED3DSIH_BREAK, "", ""},
+ {WINED3D_SM4_OP_BREAKC, WINED3DSIH_BREAKP, "", "U"},
+ {WINED3D_SM4_OP_CUT, WINED3DSIH_CUT, "", ""},
+ {WINED3D_SM4_OP_DERIV_RTX, WINED3DSIH_DSX, "F", "F"},
+ {WINED3D_SM4_OP_DERIV_RTY, WINED3DSIH_DSY, "F", "F"},
+ {WINED3D_SM4_OP_DIV, WINED3DSIH_DIV, "F", "FF"},
+ {WINED3D_SM4_OP_DP3, WINED3DSIH_DP3, "F", "FF"},
+ {WINED3D_SM4_OP_DP4, WINED3DSIH_DP4, "F", "FF"},
+ {WINED3D_SM4_OP_EMIT, WINED3DSIH_EMIT, "", ""},
+ {WINED3D_SM4_OP_ENDIF, WINED3DSIH_ENDIF, "", ""},
+ {WINED3D_SM4_OP_ENDLOOP, WINED3DSIH_ENDLOOP, "", ""},
+ {WINED3D_SM4_OP_EQ, WINED3DSIH_EQ, "U", "FF"},
+ {WINED3D_SM4_OP_EXP, WINED3DSIH_EXP, "F", "F"},
+ {WINED3D_SM4_OP_FRC, WINED3DSIH_FRC, "F", "F"},
+ {WINED3D_SM4_OP_FTOI, WINED3DSIH_FTOI, "I", "F"},
+ {WINED3D_SM4_OP_GE, WINED3DSIH_GE, "U", "FF"},
+ {WINED3D_SM4_OP_IADD, WINED3DSIH_IADD, "I", "II"},
+ {WINED3D_SM4_OP_IF, WINED3DSIH_IF, "", "U"},
+ {WINED3D_SM4_OP_IEQ, WINED3DSIH_IEQ, "U", "II"},
+ {WINED3D_SM4_OP_IGE, WINED3DSIH_IGE, "U", "II"},
+ {WINED3D_SM4_OP_IMUL, WINED3DSIH_IMUL, "II", "II"},
+ {WINED3D_SM4_OP_ITOF, WINED3DSIH_ITOF, "F", "I"},
+ {WINED3D_SM4_OP_LD, WINED3DSIH_LD, "U", "FR"},
+ {WINED3D_SM4_OP_LOG, WINED3DSIH_LOG, "F", "F"},
+ {WINED3D_SM4_OP_LOOP, WINED3DSIH_LOOP, "", ""},
+ {WINED3D_SM4_OP_LT, WINED3DSIH_LT, "U", "FF"},
+ {WINED3D_SM4_OP_MAD, WINED3DSIH_MAD, "F", "FFF"},
+ {WINED3D_SM4_OP_MIN, WINED3DSIH_MIN, "F", "FF"},
+ {WINED3D_SM4_OP_MAX, WINED3DSIH_MAX, "F", "FF"},
+ {WINED3D_SM4_OP_MOV, WINED3DSIH_MOV, "F", "F"},
+ {WINED3D_SM4_OP_MOVC, WINED3DSIH_MOVC, "F", "UFF"},
+ {WINED3D_SM4_OP_MUL, WINED3DSIH_MUL, "F", "FF"},
+ {WINED3D_SM4_OP_RET, WINED3DSIH_RET, "", ""},
+ {WINED3D_SM4_OP_ROUND_NI, WINED3DSIH_ROUND_NI, "F", "F"},
+ {WINED3D_SM4_OP_RSQ, WINED3DSIH_RSQ, "F", "F"},
+ {WINED3D_SM4_OP_SAMPLE, WINED3DSIH_SAMPLE, "U", "FRS"},
+ {WINED3D_SM4_OP_SAMPLE_LOD, WINED3DSIH_SAMPLE_LOD, "U", "FRSF"},
+ {WINED3D_SM4_OP_SAMPLE_GRAD, WINED3DSIH_SAMPLE_GRAD, "U", "FRSFF"},
+ {WINED3D_SM4_OP_SQRT, WINED3DSIH_SQRT, "F", "F"},
+ {WINED3D_SM4_OP_SINCOS, WINED3DSIH_SINCOS, "FF", "F"},
+ {WINED3D_SM4_OP_UDIV, WINED3DSIH_UDIV, "UU", "UU"},
+ {WINED3D_SM4_OP_USHR, WINED3DSIH_USHR, "U", "UU"},
+ {WINED3D_SM4_OP_UTOF, WINED3DSIH_UTOF, "F", "U"},
+ {WINED3D_SM4_OP_XOR, WINED3DSIH_XOR, "U", "UU"},
+ {WINED3D_SM4_OP_DCL_CONSTANT_BUFFER, WINED3DSIH_DCL_CONSTANT_BUFFER, "", ""},
+ {WINED3D_SM4_OP_DCL_OUTPUT_TOPOLOGY, WINED3DSIH_DCL_OUTPUT_TOPOLOGY, "", ""},
+ {WINED3D_SM4_OP_DCL_INPUT_PRIMITIVE, WINED3DSIH_DCL_INPUT_PRIMITIVE, "", ""},
+ {WINED3D_SM4_OP_DCL_VERTICES_OUT, WINED3DSIH_DCL_VERTICES_OUT, "", ""},
+};
+
+static const enum wined3d_shader_register_type register_type_table[] =
+{
+ /* WINED3D_SM4_RT_TEMP */ WINED3DSPR_TEMP,
+ /* WINED3D_SM4_RT_INPUT */ WINED3DSPR_INPUT,
+ /* WINED3D_SM4_RT_OUTPUT */ WINED3DSPR_OUTPUT,
+ /* UNKNOWN */ 0,
+ /* WINED3D_SM4_RT_IMMCONST */ WINED3DSPR_IMMCONST,
+ /* UNKNOWN */ 0,
+ /* WINED3D_SM4_RT_SAMPLER */ WINED3DSPR_SAMPLER,
+ /* WINED3D_SM4_RT_RESOURCE */ WINED3DSPR_RESOURCE,
+ /* WINED3D_SM4_RT_CONSTBUFFER */ WINED3DSPR_CONSTBUFFER,
+ /* UNKNOWN */ 0,
+ /* UNKNOWN */ 0,
+ /* WINED3D_SM4_RT_PRIMID */ WINED3DSPR_PRIMID,
+ /* UNKNOWN */ 0,
+ /* WINED3D_SM4_RT_NULL */ WINED3DSPR_NULL,
+};
+
+static const enum wined3d_primitive_type output_primitive_type_table[] =
+{
+ /* UNKNOWN */ WINED3D_PT_UNDEFINED,
+ /* WINED3D_SM4_OUTPUT_PT_POINTLIST */ WINED3D_PT_POINTLIST,
+ /* UNKNOWN */ WINED3D_PT_UNDEFINED,
+ /* WINED3D_SM4_OUTPUT_PT_LINELIST */ WINED3D_PT_LINELIST,
+ /* UNKNOWN */ WINED3D_PT_UNDEFINED,
+ /* WINED3D_SM4_OUTPUT_PT_TRIANGLESTRIP */ WINED3D_PT_TRIANGLESTRIP,
+};
+
+static const enum wined3d_primitive_type input_primitive_type_table[] =
+{
+ /* UNKNOWN */ WINED3D_PT_UNDEFINED,
+ /* WINED3D_SM4_INPUT_PT_POINT */ WINED3D_PT_POINTLIST,
+ /* WINED3D_SM4_INPUT_PT_LINE */ WINED3D_PT_LINELIST,
+ /* WINED3D_SM4_INPUT_PT_TRIANGLE */ WINED3D_PT_TRIANGLELIST,
+ /* UNKNOWN */ WINED3D_PT_UNDEFINED,
+ /* UNKNOWN */ WINED3D_PT_UNDEFINED,
+ /* WINED3D_SM4_INPUT_PT_LINEADJ */ WINED3D_PT_LINELIST_ADJ,
+ /* WINED3D_SM4_INPUT_PT_TRIANGLEADJ */ WINED3D_PT_TRIANGLELIST_ADJ,
+};
+
+static const struct sysval_map sysval_map[] =
+{
+ {WINED3D_SV_DEPTH, WINED3DSPR_DEPTHOUT, 0},
+ {WINED3D_SV_TARGET0, WINED3DSPR_COLOROUT, 0},
+ {WINED3D_SV_TARGET1, WINED3DSPR_COLOROUT, 1},
+ {WINED3D_SV_TARGET2, WINED3DSPR_COLOROUT, 2},
+ {WINED3D_SV_TARGET3, WINED3DSPR_COLOROUT, 3},
+ {WINED3D_SV_TARGET4, WINED3DSPR_COLOROUT, 4},
+ {WINED3D_SV_TARGET5, WINED3DSPR_COLOROUT, 5},
+ {WINED3D_SV_TARGET6, WINED3DSPR_COLOROUT, 6},
+ {WINED3D_SV_TARGET7, WINED3DSPR_COLOROUT, 7},
+};
+
+static BOOL shader_sm4_read_src_param(struct wined3d_sm4_data *priv, const DWORD **ptr,
+ enum wined3d_data_type data_type, struct wined3d_shader_src_param *src_param);
+
+static const struct wined3d_sm4_opcode_info *get_opcode_info(enum wined3d_sm4_opcode opcode)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof(opcode_table) / sizeof(*opcode_table); ++i)
+ {
+ if (opcode == opcode_table[i].opcode) return &opcode_table[i];
+ }
+
+ return NULL;
+}
+
+static void map_sysval(enum wined3d_sysval_semantic sysval, struct wined3d_shader_register *reg)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof(sysval_map) / sizeof(*sysval_map); ++i)
+ {
+ if (sysval == sysval_map[i].sysval)
+ {
+ reg->type = sysval_map[i].register_type;
+ reg->idx[0].offset = sysval_map[i].register_idx;
+ }
+ }
+}
+
+static void map_register(const struct wined3d_sm4_data *priv, struct wined3d_shader_register *reg)
+{
+ switch (priv->shader_version.type)
+ {
+ case WINED3D_SHADER_TYPE_PIXEL:
+ if (reg->type == WINED3DSPR_OUTPUT)
+ {
+ unsigned int i;
+ const struct wined3d_shader_signature *s = priv->output_signature;
+
+ if (!s)
+ {
+ ERR("Shader has no output signature, unable to map register.\n");
+ break;
+ }
+
+ for (i = 0; i < s->element_count; ++i)
+ {
+ if (s->elements[i].register_idx == reg->idx[0].offset)
+ {
+ map_sysval(s->elements[i].sysval_semantic, reg);
+ break;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+static enum wined3d_data_type map_data_type(char t)
+{
+ switch (t)
+ {
+ case 'F':
+ return WINED3D_DATA_FLOAT;
+ case 'I':
+ return WINED3D_DATA_INT;
+ case 'R':
+ return WINED3D_DATA_RESOURCE;
+ case 'S':
+ return WINED3D_DATA_SAMPLER;
+ case 'U':
+ return WINED3D_DATA_UINT;
+ default:
+ ERR("Invalid data type '%c'.\n", t);
+ return WINED3D_DATA_FLOAT;
+ }
+}
+
+static void *shader_sm4_init(const DWORD *byte_code, const struct wined3d_shader_signature *output_signature)
+{
+ struct wined3d_sm4_data *priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv));
+ if (!priv)
+ {
+ ERR("Failed to allocate private data\n");
+ return NULL;
+ }
+
+ priv->output_signature = output_signature;
+ list_init(&priv->src_free);
+ list_init(&priv->src);
+
+ return priv;
+}
+
+static void shader_sm4_free(void *data)
+{
+ struct wined3d_shader_src_param_entry *e1, *e2;
+ struct wined3d_sm4_data *priv = data;
+
+ list_move_head(&priv->src_free, &priv->src);
+ LIST_FOR_EACH_ENTRY_SAFE(e1, e2, &priv->src_free, struct wined3d_shader_src_param_entry, entry)
+ {
+ HeapFree(GetProcessHeap(), 0, e1);
+ }
+ HeapFree(GetProcessHeap(), 0, priv);
+}
+
+static struct wined3d_shader_src_param *get_src_param(struct wined3d_sm4_data *priv)
+{
+ struct wined3d_shader_src_param_entry *e;
+ struct list *elem;
+
+ if (!list_empty(&priv->src_free))
+ {
+ elem = list_head(&priv->src_free);
+ list_remove(elem);
+ }
+ else
+ {
+ if (!(e = HeapAlloc(GetProcessHeap(), 0, sizeof(*e))))
+ return NULL;
+ elem = &e->entry;
+ }
+
+ list_add_tail(&priv->src, elem);
+ e = LIST_ENTRY(elem, struct wined3d_shader_src_param_entry, entry);
+ return &e->param;
+}
+
+static void shader_sm4_read_header(void *data, const DWORD **ptr, struct wined3d_shader_version *shader_version)
+{
+ struct wined3d_sm4_data *priv = data;
+ DWORD version_token;
+
+ priv->end = *ptr;
+
+ version_token = *(*ptr)++;
+ TRACE("version: 0x%08x\n", version_token);
+
+ TRACE("token count: %u\n", **ptr);
+ priv->end += *(*ptr)++;
+
+ switch (version_token >> 16)
+ {
+ case WINED3D_SM4_PS:
+ priv->shader_version.type = WINED3D_SHADER_TYPE_PIXEL;
+ break;
+
+ case WINED3D_SM4_VS:
+ priv->shader_version.type = WINED3D_SHADER_TYPE_VERTEX;
+ break;
+
+ case WINED3D_SM4_GS:
+ priv->shader_version.type = WINED3D_SHADER_TYPE_GEOMETRY;
+ break;
+
+ default:
+ FIXME("Unrecognized shader type %#x\n", version_token >> 16);
+ }
+ priv->shader_version.major = WINED3D_SM4_VERSION_MAJOR(version_token);
+ priv->shader_version.minor = WINED3D_SM4_VERSION_MINOR(version_token);
+
+ *shader_version = priv->shader_version;
+}
+
+static BOOL shader_sm4_read_reg_idx(struct wined3d_sm4_data *priv, const DWORD **ptr,
+ DWORD addressing, struct wined3d_shader_register_index *reg_idx)
+{
+ if (addressing & WINED3D_SM4_ADDRESSING_RELATIVE)
+ {
+ struct wined3d_shader_src_param *rel_addr = get_src_param(priv);
+
+ if (!(reg_idx->rel_addr = rel_addr))
+ {
+ ERR("Failed to get src param for relative addressing.\n");
+ return FALSE;
+ }
+
+ if (addressing & WINED3D_SM4_ADDRESSING_OFFSET)
+ reg_idx->offset = *(*ptr)++;
+ else
+ reg_idx->offset = 0;
+ shader_sm4_read_src_param(priv, ptr, WINED3D_DATA_INT, rel_addr);
+ }
+ else
+ {
+ reg_idx->rel_addr = NULL;
+ reg_idx->offset = *(*ptr)++;
+ }
+
+ return TRUE;
+}
+
+static BOOL shader_sm4_read_param(struct wined3d_sm4_data *priv, const DWORD **ptr,
+ enum wined3d_data_type data_type, struct wined3d_shader_register *param,
+ enum wined3d_shader_src_modifier *modifier)
+{
+ enum wined3d_sm4_register_type register_type;
+ DWORD token = *(*ptr)++;
+ DWORD order;
+
+ register_type = (token & WINED3D_SM4_REGISTER_TYPE_MASK) >> WINED3D_SM4_REGISTER_TYPE_SHIFT;
+ if (register_type >= sizeof(register_type_table) / sizeof(*register_type_table))
+ {
+ FIXME("Unhandled register type %#x.\n", register_type);
+ param->type = WINED3DSPR_TEMP;
+ }
+ else
+ {
+ param->type = register_type_table[register_type];
+ }
+ param->data_type = data_type;
+
+ if (token & WINED3D_SM4_REGISTER_MODIFIER)
+ {
+ DWORD m = *(*ptr)++;
+
+ /* FIXME: This will probably break down at some point. The SM4
+ * modifiers look like flags, while wined3d currently has an enum
+ * with possible combinations, e.g. WINED3DSPSM_ABSNEG. */
+ switch (m)
+ {
+ case 0x41:
+ *modifier = WINED3DSPSM_NEG;
+ break;
+
+ case 0x81:
+ *modifier = WINED3DSPSM_ABS;
+ break;
+
+ default:
+ FIXME("Skipping modifier 0x%08x.\n", m);
+ *modifier = WINED3DSPSM_NONE;
+ break;
+ }
+ }
+ else
+ {
+ *modifier = WINED3DSPSM_NONE;
+ }
+
+ order = (token & WINED3D_SM4_REGISTER_ORDER_MASK) >> WINED3D_SM4_REGISTER_ORDER_SHIFT;
+
+ if (order < 1)
+ param->idx[0].offset = ~0U;
+ else
+ {
+ DWORD addressing = (token & WINED3D_SM4_ADDRESSING_MASK0) >> WINED3D_SM4_ADDRESSING_SHIFT0;
+ if (!(shader_sm4_read_reg_idx(priv, ptr, addressing, &param->idx[0])))
+ {
+ ERR("Failed to read register index.\n");
+ return FALSE;
+ }
+ }
+
+ if (order < 2)
+ param->idx[1].offset = ~0U;
+ else
+ {
+ DWORD addressing = (token & WINED3D_SM4_ADDRESSING_MASK1) >> WINED3D_SM4_ADDRESSING_SHIFT1;
+ if (!(shader_sm4_read_reg_idx(priv, ptr, addressing, &param->idx[1])))
+ {
+ ERR("Failed to read register index.\n");
+ return FALSE;
+ }
+ }
+
+ if (order > 2)
+ FIXME("Unhandled order %u.\n", order);
+
+ if (register_type == WINED3D_SM4_RT_IMMCONST)
+ {
+ enum wined3d_sm4_immconst_type immconst_type =
+ (token & WINED3D_SM4_IMMCONST_TYPE_MASK) >> WINED3D_SM4_IMMCONST_TYPE_SHIFT;
+
+ switch (immconst_type)
+ {
+ case WINED3D_SM4_IMMCONST_SCALAR:
+ param->immconst_type = WINED3D_IMMCONST_SCALAR;
+ memcpy(param->immconst_data, *ptr, 1 * sizeof(DWORD));
+ *ptr += 1;
+ break;
+
+ case WINED3D_SM4_IMMCONST_VEC4:
+ param->immconst_type = WINED3D_IMMCONST_VEC4;
+ memcpy(param->immconst_data, *ptr, 4 * sizeof(DWORD));
+ *ptr += 4;
+ break;
+
+ default:
+ FIXME("Unhandled immediate constant type %#x.\n", immconst_type);
+ break;
+ }
+ }
+
+ map_register(priv, param);
+
+ return TRUE;
+}
+
+static BOOL shader_sm4_read_src_param(struct wined3d_sm4_data *priv, const DWORD **ptr,
+ enum wined3d_data_type data_type, struct wined3d_shader_src_param *src_param)
+{
+ DWORD token = **ptr;
+
+ if (!shader_sm4_read_param(priv, ptr, data_type, &src_param->reg, &src_param->modifiers))
+ {
+ ERR("Failed to read parameter.\n");
+ return FALSE;
+ }
+
+ if (src_param->reg.type == WINED3DSPR_IMMCONST)
+ {
+ src_param->swizzle = WINED3DSP_NOSWIZZLE;
+ }
+ else
+ {
+ enum wined3d_sm4_swizzle_type swizzle_type =
+ (token & WINED3D_SM4_SWIZZLE_TYPE_MASK) >> WINED3D_SM4_SWIZZLE_TYPE_SHIFT;
+
+ switch (swizzle_type)
+ {
+ case WINED3D_SM4_SWIZZLE_SCALAR:
+ src_param->swizzle = (token & WINED3D_SM4_SWIZZLE_MASK) >> WINED3D_SM4_SWIZZLE_SHIFT;
+ src_param->swizzle = (src_param->swizzle & 0x3) * 0x55;
+ break;
+
+ case WINED3D_SM4_SWIZZLE_VEC4:
+ src_param->swizzle = (token & WINED3D_SM4_SWIZZLE_MASK) >> WINED3D_SM4_SWIZZLE_SHIFT;
+ break;
+
+ default:
+ FIXME("Unhandled swizzle type %#x.\n", swizzle_type);
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+static BOOL shader_sm4_read_dst_param(struct wined3d_sm4_data *priv, const DWORD **ptr,
+ enum wined3d_data_type data_type, struct wined3d_shader_dst_param *dst_param)
+{
+ enum wined3d_shader_src_modifier modifier;
+ DWORD token = **ptr;
+
+ if (!shader_sm4_read_param(priv, ptr, data_type, &dst_param->reg, &modifier))
+ {
+ ERR("Failed to read parameter.\n");
+ return FALSE;
+ }
+
+ if (modifier != WINED3DSPSM_NONE)
+ {
+ ERR("Invalid source modifier %#x on destination register.\n", modifier);
+ return FALSE;
+ }
+
+ dst_param->write_mask = (token & WINED3D_SM4_WRITEMASK_MASK) >> WINED3D_SM4_WRITEMASK_SHIFT;
+ dst_param->modifiers = 0;
+ dst_param->shift = 0;
+
+ return TRUE;
+}
+
+static void shader_sm4_read_instruction(void *data, const DWORD **ptr, struct wined3d_shader_instruction *ins)
+{
+ const struct wined3d_sm4_opcode_info *opcode_info;
+ struct wined3d_sm4_data *priv = data;
+ DWORD opcode_token, opcode;
+ const DWORD *p;
+ UINT i, len;
+
+ list_move_head(&priv->src_free, &priv->src);
+
+ opcode_token = *(*ptr)++;
+ opcode = opcode_token & WINED3D_SM4_OPCODE_MASK;
+ len = ((opcode_token & WINED3D_SM4_INSTRUCTION_LENGTH_MASK) >> WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT) - 1;
+
+ if (TRACE_ON(d3d_bytecode))
+ {
+ TRACE_(d3d_bytecode)("[ %08x ", opcode_token);
+ for (i = 0; i < len; ++i)
+ {
+ TRACE_(d3d_bytecode)("%08x ", (*ptr)[i]);
+ }
+ TRACE_(d3d_bytecode)("]\n");
+ }
+
+ if (!(opcode_info = get_opcode_info(opcode)))
+ {
+ FIXME("Unrecognized opcode %#x, opcode_token 0x%08x.\n", opcode, opcode_token);
+ ins->handler_idx = WINED3DSIH_TABLE_SIZE;
+ *ptr += len;
+ return;
+ }
+
+ ins->handler_idx = opcode_info->handler_idx;
+ ins->flags = 0;
+ ins->coissue = 0;
+ ins->predicate = NULL;
+ ins->dst_count = strlen(opcode_info->dst_info);
+ ins->dst = priv->dst_param;
+ ins->src_count = strlen(opcode_info->src_info);
+ ins->src = priv->src_param;
+
+ p = *ptr;
+ *ptr += len;
+
+ if (opcode_token & WINED3D_SM4_INSTRUCTION_MODIFIER)
+ {
+ DWORD modifier = *p++;
+ FIXME("Skipping modifier 0x%08x.\n", modifier);
+ }
+
+ if (opcode == WINED3D_SM4_OP_DCL_CONSTANT_BUFFER)
+ {
+ shader_sm4_read_src_param(priv, &p, WINED3D_DATA_FLOAT, &ins->declaration.src);
+ if (opcode_token & WINED3D_SM4_INDEX_TYPE_MASK)
+ ins->flags |= WINED3DSI_INDEXED_DYNAMIC;
+ }
+ else if (opcode == WINED3D_SM4_OP_DCL_OUTPUT_TOPOLOGY)
+ {
+ enum wined3d_sm4_output_primitive_type primitive_type;
+
+ primitive_type = (opcode_token & WINED3D_SM4_PRIMITIVE_TYPE_MASK) >> WINED3D_SM4_PRIMITIVE_TYPE_SHIFT;
+ if (primitive_type >= sizeof(output_primitive_type_table) / sizeof(*output_primitive_type_table))
+ {
+ FIXME("Unhandled output primitive type %#x.\n", primitive_type);
+ ins->declaration.primitive_type = WINED3D_PT_UNDEFINED;
+ }
+ else
+ {
+ ins->declaration.primitive_type = output_primitive_type_table[primitive_type];
+ }
+ }
+ else if (opcode == WINED3D_SM4_OP_DCL_INPUT_PRIMITIVE)
+ {
+ enum wined3d_sm4_input_primitive_type primitive_type;
+
+ primitive_type = (opcode_token & WINED3D_SM4_PRIMITIVE_TYPE_MASK) >> WINED3D_SM4_PRIMITIVE_TYPE_SHIFT;
+ if (primitive_type >= sizeof(input_primitive_type_table) / sizeof(*input_primitive_type_table))
+ {
+ FIXME("Unhandled input primitive type %#x.\n", primitive_type);
+ ins->declaration.primitive_type = WINED3D_PT_UNDEFINED;
+ }
+ else
+ {
+ ins->declaration.primitive_type = input_primitive_type_table[primitive_type];
+ }
+ }
+ else if (opcode == WINED3D_SM4_OP_DCL_VERTICES_OUT)
+ {
+ ins->declaration.count = *p++;
+ }
+ else
+ {
+ for (i = 0; i < ins->dst_count; ++i)
+ {
+ if (!(shader_sm4_read_dst_param(priv, &p, map_data_type(opcode_info->dst_info[i]), &priv->dst_param[i])))
+ {
+ ins->handler_idx = WINED3DSIH_TABLE_SIZE;
+ return;
+ }
+ }
+
+ for (i = 0; i < ins->src_count; ++i)
+ {
+ if (!(shader_sm4_read_src_param(priv, &p, map_data_type(opcode_info->src_info[i]), &priv->src_param[i])))
+ {
+ ins->handler_idx = WINED3DSIH_TABLE_SIZE;
+ return;
+ }
+ }
+ }
+}
+
+static BOOL shader_sm4_is_end(void *data, const DWORD **ptr)
+{
+ struct wined3d_sm4_data *priv = data;
+ return *ptr == priv->end;
+}
+
+const struct wined3d_shader_frontend sm4_shader_frontend =
+{
+ shader_sm4_init,
+ shader_sm4_free,
+ shader_sm4_read_header,
+ shader_sm4_read_instruction,
+ shader_sm4_is_end,
+};
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/state.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/state.c
new file mode 100644
index 00000000..91b708fc
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/state.c
@@ -0,0 +1,6097 @@
+/*
+ * Direct3D state management
+ *
+ * Copyright 2002 Lionel Ulmer
+ * Copyright 2002-2005 Jason Edmeades
+ * Copyright 2003-2004 Raphael Junqueira
+ * Copyright 2004 Christian Costa
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2006 Henri Verbeet
+ * Copyright 2006-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2009-2011 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
+#ifdef HAVE_FLOAT_H
+# include <float.h>
+#endif
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
+
+/* Context activation for state handler is done by the caller. */
+
+static void state_undefined(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+#ifndef VBOX
+ ERR("Undefined state.\n");
+#else
+ WARN("Undefined state.\n");
+#endif
+}
+
+static void state_nop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ TRACE("%s: nop in current pipe config.\n", debug_d3dstate(state_id));
+}
+
+static void state_fillmode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ enum wined3d_fill_mode mode = state->render_states[WINED3D_RS_FILLMODE];
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ switch (mode)
+ {
+ case WINED3D_FILL_POINT:
+ gl_info->gl_ops.gl.p_glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
+ checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)");
+ break;
+ case WINED3D_FILL_WIREFRAME:
+ gl_info->gl_ops.gl.p_glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)");
+ break;
+ case WINED3D_FILL_SOLID:
+ gl_info->gl_ops.gl.p_glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
+ break;
+ default:
+ FIXME("Unrecognized fill mode %#x.\n", mode);
+ }
+}
+
+static void state_lighting(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ /* Lighting is not enabled if transformed vertices are drawn, but lighting
+ * does not affect the stream sources, so it is not grouped for
+ * performance reasons. This state reads the decoded vertex declaration,
+ * so if it is dirty don't do anything. The vertex declaration applying
+ * function calls this function for updating. */
+ if (isStateDirty(context, STATE_VDECL))
+ return;
+
+ if (state->render_states[WINED3D_RS_LIGHTING]
+ && !context->swapchain->device->stream_info.position_transformed)
+ {
+ gl_info->gl_ops.gl.p_glEnable(GL_LIGHTING);
+ checkGLcall("glEnable GL_LIGHTING");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
+ checkGLcall("glDisable GL_LIGHTING");
+ }
+}
+
+static void state_zenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ enum wined3d_depth_buffer_type zenable = state->render_states[WINED3D_RS_ZENABLE];
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ static UINT once;
+
+ /* No z test without depth stencil buffers */
+ if (!state->fb->depth_stencil)
+ {
+ TRACE("No Z buffer - disabling depth test\n");
+ zenable = WINED3D_ZB_FALSE;
+ }
+
+ switch (zenable)
+ {
+ case WINED3D_ZB_FALSE:
+ gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST);
+ checkGLcall("glDisable GL_DEPTH_TEST");
+ break;
+ case WINED3D_ZB_TRUE:
+ gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_TEST);
+ checkGLcall("glEnable GL_DEPTH_TEST");
+ break;
+ case WINED3D_ZB_USEW:
+ gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_TEST);
+ checkGLcall("glEnable GL_DEPTH_TEST");
+ FIXME("W buffer is not well handled\n");
+ break;
+ default:
+ FIXME("Unrecognized depth buffer type %#x.\n", zenable);
+ break;
+ }
+
+ if (context->gl_info->supported[ARB_DEPTH_CLAMP])
+ {
+ if (!zenable && context->swapchain->device->stream_info.position_transformed)
+ {
+ gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_CLAMP);
+ checkGLcall("glEnable(GL_DEPTH_CLAMP)");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_CLAMP);
+ checkGLcall("glDisable(GL_DEPTH_CLAMP)");
+ }
+ }
+ else if (!zenable && !once++)
+ FIXME("Z buffer disabled, but ARB_depth_clamp isn't supported.\n");
+}
+
+static void state_cullmode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ /* glFrontFace() is set in context.c at context init and on an
+ * offscreen / onscreen rendering switch. */
+ switch (state->render_states[WINED3D_RS_CULLMODE])
+ {
+ case WINED3D_CULL_NONE:
+ gl_info->gl_ops.gl.p_glDisable(GL_CULL_FACE);
+ checkGLcall("glDisable GL_CULL_FACE");
+ break;
+ case WINED3D_CULL_CW:
+ gl_info->gl_ops.gl.p_glEnable(GL_CULL_FACE);
+ checkGLcall("glEnable GL_CULL_FACE");
+ gl_info->gl_ops.gl.p_glCullFace(GL_FRONT);
+ checkGLcall("glCullFace(GL_FRONT)");
+ break;
+ case WINED3D_CULL_CCW:
+ gl_info->gl_ops.gl.p_glEnable(GL_CULL_FACE);
+ checkGLcall("glEnable GL_CULL_FACE");
+ gl_info->gl_ops.gl.p_glCullFace(GL_BACK);
+ checkGLcall("glCullFace(GL_BACK)");
+ break;
+ default:
+ FIXME("Unrecognized cull mode %#x.\n",
+ state->render_states[WINED3D_RS_CULLMODE]);
+ }
+}
+
+static void state_shademode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ switch (state->render_states[WINED3D_RS_SHADEMODE])
+ {
+ case WINED3D_SHADE_FLAT:
+ gl_info->gl_ops.gl.p_glShadeModel(GL_FLAT);
+ checkGLcall("glShadeModel(GL_FLAT)");
+ break;
+ case WINED3D_SHADE_GOURAUD:
+ gl_info->gl_ops.gl.p_glShadeModel(GL_SMOOTH);
+ checkGLcall("glShadeModel(GL_SMOOTH)");
+ break;
+ case WINED3D_SHADE_PHONG:
+ FIXME("WINED3D_SHADE_PHONG isn't supported.\n");
+ break;
+ default:
+ FIXME("Unrecognized shade mode %#x.\n",
+ state->render_states[WINED3D_RS_SHADEMODE]);
+ }
+}
+
+static void state_ditherenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (state->render_states[WINED3D_RS_DITHERENABLE])
+ {
+ gl_info->gl_ops.gl.p_glEnable(GL_DITHER);
+ checkGLcall("glEnable GL_DITHER");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_DITHER);
+ checkGLcall("glDisable GL_DITHER");
+ }
+}
+
+static void state_zwritenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (state->render_states[WINED3D_RS_ZWRITEENABLE])
+ {
+ gl_info->gl_ops.gl.p_glDepthMask(1);
+ checkGLcall("glDepthMask(1)");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDepthMask(0);
+ checkGLcall("glDepthMask(0)");
+ }
+}
+
+static GLenum gl_compare_func(enum wined3d_cmp_func f)
+{
+ switch (f)
+ {
+ case WINED3D_CMP_NEVER:
+ return GL_NEVER;
+ case WINED3D_CMP_LESS:
+ return GL_LESS;
+ case WINED3D_CMP_EQUAL:
+ return GL_EQUAL;
+ case WINED3D_CMP_LESSEQUAL:
+ return GL_LEQUAL;
+ case WINED3D_CMP_GREATER:
+ return GL_GREATER;
+ case WINED3D_CMP_NOTEQUAL:
+ return GL_NOTEQUAL;
+ case WINED3D_CMP_GREATEREQUAL:
+ return GL_GEQUAL;
+ case WINED3D_CMP_ALWAYS:
+ return GL_ALWAYS;
+ default:
+ FIXME("Unrecognized compare function %#x.\n", f);
+ return GL_NONE;
+ }
+}
+
+static void state_zfunc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ GLenum depth_func = gl_compare_func(state->render_states[WINED3D_RS_ZFUNC]);
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (!depth_func) return;
+
+ gl_info->gl_ops.gl.p_glDepthFunc(depth_func);
+ checkGLcall("glDepthFunc");
+}
+
+void state_ambient(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ float col[4];
+
+ D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_AMBIENT], col);
+ TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
+ gl_info->gl_ops.gl.p_glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
+ checkGLcall("glLightModel for MODEL_AMBIENT");
+}
+
+static void state_blendop_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
+}
+
+static GLenum gl_blend_op(enum wined3d_blend_op op)
+{
+ switch (op)
+ {
+ case WINED3D_BLEND_OP_ADD:
+ return GL_FUNC_ADD_EXT;
+ case WINED3D_BLEND_OP_SUBTRACT:
+ return GL_FUNC_SUBTRACT_EXT;
+ case WINED3D_BLEND_OP_REVSUBTRACT:
+ return GL_FUNC_REVERSE_SUBTRACT_EXT;
+ case WINED3D_BLEND_OP_MIN:
+ return GL_MIN_EXT;
+ case WINED3D_BLEND_OP_MAX:
+ return GL_MAX_EXT;
+ default:
+ FIXME("Unhandled blend op %#x.\n", op);
+ return GL_NONE;
+ }
+}
+
+static void state_blendop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ GLenum blend_equation_alpha = GL_FUNC_ADD_EXT;
+ GLenum blend_equation = GL_FUNC_ADD_EXT;
+
+ /* BLENDOPALPHA requires GL_EXT_blend_equation_separate, so make sure it is around */
+ if (state->render_states[WINED3D_RS_BLENDOPALPHA]
+ && !gl_info->supported[EXT_BLEND_EQUATION_SEPARATE])
+ {
+ WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparateEXT\n");
+ return;
+ }
+
+ blend_equation = gl_blend_op(state->render_states[WINED3D_RS_BLENDOP]);
+ blend_equation_alpha = gl_blend_op(state->render_states[WINED3D_RS_BLENDOPALPHA]);
+ TRACE("blend_equation %#x, blend_equation_alpha %#x.\n", blend_equation, blend_equation_alpha);
+
+ if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE])
+ {
+ GL_EXTCALL(glBlendEquationSeparateEXT(blend_equation, blend_equation_alpha));
+ checkGLcall("glBlendEquationSeparateEXT");
+ }
+ else
+ {
+ GL_EXTCALL(glBlendEquationEXT(blend_equation));
+ checkGLcall("glBlendEquation");
+ }
+}
+
+static GLenum gl_blend_factor(enum wined3d_blend factor, const struct wined3d_format *dst_format)
+{
+ switch (factor)
+ {
+ case WINED3D_BLEND_ZERO:
+ return GL_ZERO;
+ case WINED3D_BLEND_ONE:
+ return GL_ONE;
+ case WINED3D_BLEND_SRCCOLOR:
+ return GL_SRC_COLOR;
+ case WINED3D_BLEND_INVSRCCOLOR:
+ return GL_ONE_MINUS_SRC_COLOR;
+ case WINED3D_BLEND_SRCALPHA:
+ return GL_SRC_ALPHA;
+ case WINED3D_BLEND_INVSRCALPHA:
+ return GL_ONE_MINUS_SRC_ALPHA;
+ case WINED3D_BLEND_DESTCOLOR:
+ return GL_DST_COLOR;
+ case WINED3D_BLEND_INVDESTCOLOR:
+ return GL_ONE_MINUS_DST_COLOR;
+ /* To compensate for the lack of format switching with backbuffer
+ * offscreen rendering, and with onscreen rendering, we modify the
+ * alpha test parameters for (INV)DESTALPHA if the render target
+ * doesn't support alpha blending. A nonexistent alpha channel
+ * returns 1.0, so WINED3D_BLEND_DESTALPHA becomes GL_ONE, and
+ * WINED3D_BLEND_INVDESTALPHA becomes GL_ZERO. */
+ case WINED3D_BLEND_DESTALPHA:
+ return dst_format->alpha_size ? GL_DST_ALPHA : GL_ONE;
+ case WINED3D_BLEND_INVDESTALPHA:
+ return dst_format->alpha_size ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO;
+ case WINED3D_BLEND_SRCALPHASAT:
+ return GL_SRC_ALPHA_SATURATE;
+ case WINED3D_BLEND_BLENDFACTOR:
+ return GL_CONSTANT_COLOR_EXT;
+ case WINED3D_BLEND_INVBLENDFACTOR:
+ return GL_ONE_MINUS_CONSTANT_COLOR_EXT;
+ default:
+ FIXME("Unhandled blend factor %#x.\n", factor);
+ return GL_NONE;
+ }
+}
+
+static void state_blend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_surface *target = state->fb->render_targets[0];
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ GLenum srcBlend, dstBlend;
+ enum wined3d_blend d3d_blend;
+
+ /* According to the red book, GL_LINE_SMOOTH needs GL_BLEND with specific
+ * blending parameters to work. */
+ if (state->render_states[WINED3D_RS_ALPHABLENDENABLE]
+ || state->render_states[WINED3D_RS_EDGEANTIALIAS]
+ || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE])
+ {
+ /* Disable blending in all cases even without pixelshaders.
+ * With blending on we could face a big performance penalty.
+ * The d3d9 visual test confirms the behavior. */
+ if (context->render_offscreen
+ && !(target->resource.format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
+ checkGLcall("glDisable GL_BLEND");
+ return;
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
+ checkGLcall("glEnable GL_BLEND");
+ }
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
+ checkGLcall("glDisable GL_BLEND");
+ /* Nothing more to do - get out */
+ return;
+ };
+
+ /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy
+ * source blending values which are still valid up to d3d9. They should
+ * not occur as dest blend values. */
+ d3d_blend = state->render_states[WINED3D_RS_SRCBLEND];
+ if (d3d_blend == WINED3D_BLEND_BOTHSRCALPHA)
+ {
+ srcBlend = GL_SRC_ALPHA;
+ dstBlend = GL_ONE_MINUS_SRC_ALPHA;
+ }
+ else if (d3d_blend == WINED3D_BLEND_BOTHINVSRCALPHA)
+ {
+ srcBlend = GL_ONE_MINUS_SRC_ALPHA;
+ dstBlend = GL_SRC_ALPHA;
+ }
+ else
+ {
+ srcBlend = gl_blend_factor(d3d_blend, target->resource.format);
+ dstBlend = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLEND],
+ target->resource.format);
+ }
+
+ if (state->render_states[WINED3D_RS_EDGEANTIALIAS]
+ || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE])
+ {
+ gl_info->gl_ops.gl.p_glEnable(GL_LINE_SMOOTH);
+ checkGLcall("glEnable(GL_LINE_SMOOTH)");
+ if (srcBlend != GL_SRC_ALPHA)
+ WARN("WINED3D_RS_EDGEANTIALIAS enabled, but unexpected src blending param.\n");
+ if (dstBlend != GL_ONE_MINUS_SRC_ALPHA && dstBlend != GL_ONE)
+ WARN("WINED3D_RS_EDGEANTIALIAS enabled, but unexpected dst blending param.\n");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_LINE_SMOOTH);
+ checkGLcall("glDisable(GL_LINE_SMOOTH)");
+ }
+
+ /* Re-apply BLENDOP(ALPHA) because of a possible SEPARATEALPHABLENDENABLE change */
+ if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_BLENDOP)))
+ state_blendop(context, state, STATE_RENDER(WINED3D_RS_BLENDOPALPHA));
+
+ if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE])
+ {
+ GLenum srcBlendAlpha, dstBlendAlpha;
+
+ /* Separate alpha blending requires GL_EXT_blend_function_separate, so make sure it is around */
+ if (!context->gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
+ {
+ WARN("Unsupported in local OpenGL implementation: glBlendFuncSeparateEXT\n");
+ return;
+ }
+
+ /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy
+ * source blending values which are still valid up to d3d9. They should
+ * not occur as dest blend values. */
+ d3d_blend = state->render_states[WINED3D_RS_SRCBLENDALPHA];
+ if (d3d_blend == WINED3D_BLEND_BOTHSRCALPHA)
+ {
+ srcBlendAlpha = GL_SRC_ALPHA;
+ dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
+ }
+ else if (d3d_blend == WINED3D_BLEND_BOTHINVSRCALPHA)
+ {
+ srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
+ dstBlendAlpha = GL_SRC_ALPHA;
+ }
+ else
+ {
+ srcBlendAlpha = gl_blend_factor(d3d_blend, target->resource.format);
+ dstBlendAlpha = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLENDALPHA],
+ target->resource.format);
+ }
+
+ GL_EXTCALL(glBlendFuncSeparateEXT(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha));
+ checkGLcall("glBlendFuncSeparateEXT");
+ }
+ else
+ {
+ TRACE("glBlendFunc src=%x, dst=%x\n", srcBlend, dstBlend);
+ gl_info->gl_ops.gl.p_glBlendFunc(srcBlend, dstBlend);
+ checkGLcall("glBlendFunc");
+ }
+
+ /* Colorkey fixup for stage 0 alphaop depends on
+ * WINED3D_RS_ALPHABLENDENABLE state, so it may need updating. */
+ if (state->render_states[WINED3D_RS_COLORKEYENABLE])
+ context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP));
+}
+
+static void state_blendfactor_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ WARN("Unsupported in local OpenGL implementation: glBlendColorEXT\n");
+}
+
+static void state_blendfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ float col[4];
+
+ TRACE("Setting blend factor to %#x.\n", state->render_states[WINED3D_RS_BLENDFACTOR]);
+
+ D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_BLENDFACTOR], col);
+ GL_EXTCALL(glBlendColorEXT (col[0],col[1],col[2],col[3]));
+ checkGLcall("glBlendColor");
+}
+
+static void state_alpha(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ int glParm = 0;
+ float ref;
+ BOOL enable_ckey = FALSE;
+
+ TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
+
+ /* Find out if the texture on the first stage has a ckey set
+ * The alpha state func reads the texture settings, even though alpha and texture are not grouped
+ * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly
+ * used WINED3D_RS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha
+ * in case it finds some texture+colorkeyenable combination which needs extra care.
+ */
+ if (state->textures[0])
+ {
+ struct wined3d_surface *surface = surface_from_resource(state->textures[0]->sub_resources[0]);
+
+ if (surface->CKeyFlags & WINEDDSD_CKSRCBLT)
+ enable_ckey = TRUE;
+ }
+
+ if (enable_ckey || context->last_was_ckey)
+ context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP));
+ context->last_was_ckey = enable_ckey;
+
+ if (state->render_states[WINED3D_RS_ALPHATESTENABLE]
+ || (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey))
+ {
+ gl_info->gl_ops.gl.p_glEnable(GL_ALPHA_TEST);
+ checkGLcall("glEnable GL_ALPHA_TEST");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST);
+ checkGLcall("glDisable GL_ALPHA_TEST");
+ /* Alpha test is disabled, don't bother setting the params - it will happen on the next
+ * enable call
+ */
+ return;
+ }
+
+ if (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey)
+ {
+ glParm = GL_NOTEQUAL;
+ ref = 0.0f;
+ }
+ else
+ {
+ ref = ((float)state->render_states[WINED3D_RS_ALPHAREF]) / 255.0f;
+ glParm = gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]);
+ }
+ if (glParm)
+ {
+ gl_info->gl_ops.gl.p_glAlphaFunc(glParm, ref);
+ checkGLcall("glAlphaFunc");
+ }
+}
+
+static void shaderconstant(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ context->load_constants = 1;
+}
+
+void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ DWORD enable = 0xffffffff;
+ DWORD disable = 0x00000000;
+
+ if (use_vs(state) && !context->d3d_info->vs_clipping)
+ {
+ static BOOL warned;
+
+ /* The OpenGL spec says that clipping planes are disabled when using
+ * shaders. Direct3D planes aren't, so that is an issue. The MacOS ATI
+ * driver keeps clipping planes activated with shaders in some
+ * conditions I got sick of tracking down. The shader state handler
+ * disables all clip planes because of that - don't do anything here
+ * and keep them disabled. */
+ if (state->render_states[WINED3D_RS_CLIPPLANEENABLE] && !warned++)
+ FIXME("Clipping not supported with vertex shaders\n");
+ return;
+ }
+
+ /* glEnable(GL_CLIP_PLANEx) doesn't apply to (ARB backend) vertex shaders.
+ * The enabled / disabled planes are hardcoded into the shader. Update the
+ * shader to update the enabled clipplanes. In case of fixed function, we
+ * need to update the clipping field from ffp_vertex_settings. */
+ context->select_shader = 1;
+ context->load_constants = 1;
+
+ /* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
+ * of already set values
+ */
+
+ /* If enabling / disabling all
+ * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
+ */
+ if (state->render_states[WINED3D_RS_CLIPPING])
+ {
+ enable = state->render_states[WINED3D_RS_CLIPPLANEENABLE];
+ disable = ~state->render_states[WINED3D_RS_CLIPPLANEENABLE];
+ }
+ else
+ {
+ disable = 0xffffffff;
+ enable = 0x00;
+ }
+
+ if (enable & WINED3DCLIPPLANE0) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE0);
+ if (enable & WINED3DCLIPPLANE1) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE1);
+ if (enable & WINED3DCLIPPLANE2) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE2);
+ if (enable & WINED3DCLIPPLANE3) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE3);
+ if (enable & WINED3DCLIPPLANE4) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE4);
+ if (enable & WINED3DCLIPPLANE5) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE5);
+ checkGLcall("clip plane enable");
+
+ if (disable & WINED3DCLIPPLANE0) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0);
+ if (disable & WINED3DCLIPPLANE1) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE1);
+ if (disable & WINED3DCLIPPLANE2) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE2);
+ if (disable & WINED3DCLIPPLANE3) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE3);
+ if (disable & WINED3DCLIPPLANE4) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE4);
+ if (disable & WINED3DCLIPPLANE5) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE5);
+ checkGLcall("clip plane disable");
+}
+
+void state_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
+ * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
+ * specular color. This is wrong:
+ * Separate specular color means the specular colour is maintained separately, whereas
+ * single color means it is merged in. However in both cases they are being used to
+ * some extent.
+ * To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
+ * NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
+ * running 1.4 yet!
+ *
+ *
+ * If register combiners are enabled, enabling / disabling GL_COLOR_SUM has no effect.
+ * Instead, we need to setup the FinalCombiner properly.
+ *
+ * The default setup for the FinalCombiner is:
+ *
+ * <variable> <input> <mapping> <usage>
+ * GL_VARIABLE_A_NV GL_FOG, GL_UNSIGNED_IDENTITY_NV GL_ALPHA
+ * GL_VARIABLE_B_NV GL_SPARE0_PLUS_SECONDARY_COLOR_NV GL_UNSIGNED_IDENTITY_NV GL_RGB
+ * GL_VARIABLE_C_NV GL_FOG GL_UNSIGNED_IDENTITY_NV GL_RGB
+ * GL_VARIABLE_D_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
+ * GL_VARIABLE_E_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
+ * GL_VARIABLE_F_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
+ * GL_VARIABLE_G_NV GL_SPARE0_NV GL_UNSIGNED_IDENTITY_NV GL_ALPHA
+ *
+ * That's pretty much fine as it is, except for variable B, which needs to take
+ * either GL_SPARE0_PLUS_SECONDARY_COLOR_NV or GL_SPARE0_NV, depending on
+ * whether WINED3D_RS_SPECULARENABLE is enabled or not.
+ */
+
+ TRACE("Setting specular enable state and materials\n");
+ if (state->render_states[WINED3D_RS_SPECULARENABLE])
+ {
+ gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
+ checkGLcall("glMaterialfv");
+
+ if (state->material.power > gl_info->limits.shininess)
+ {
+ /* glMaterialf man page says that the material says that GL_SHININESS must be between 0.0
+ * and 128.0, although in d3d neither -1 nor 129 produce an error. GL_NV_max_light_exponent
+ * allows bigger values. If the extension is supported, gl_info->limits.shininess contains the
+ * value reported by the extension, otherwise 128. For values > gl_info->limits.shininess clamp
+ * them, it should be safe to do so without major visual distortions.
+ */
+ WARN("Material power = %.8e, limit %.8e\n", state->material.power, gl_info->limits.shininess);
+ gl_info->gl_ops.gl.p_glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, gl_info->limits.shininess);
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, state->material.power);
+ }
+ checkGLcall("glMaterialf(GL_SHININESS)");
+
+ if (gl_info->supported[EXT_SECONDARY_COLOR])
+ gl_info->gl_ops.gl.p_glEnable(GL_COLOR_SUM_EXT);
+ else
+ TRACE("Specular colors cannot be enabled in this version of opengl\n");
+ checkGLcall("glEnable(GL_COLOR_SUM)");
+
+ if (gl_info->supported[NV_REGISTER_COMBINERS])
+ {
+ GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_PLUS_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
+ checkGLcall("glFinalCombinerInputNV()");
+ }
+ } else {
+ static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ /* for the case of enabled lighting: */
+ gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
+ checkGLcall("glMaterialfv");
+
+ /* for the case of disabled lighting: */
+ if (gl_info->supported[EXT_SECONDARY_COLOR])
+ gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT);
+ else
+ TRACE("Specular colors cannot be disabled in this version of opengl\n");
+ checkGLcall("glDisable(GL_COLOR_SUM)");
+
+ if (gl_info->supported[NV_REGISTER_COMBINERS])
+ {
+ GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
+ checkGLcall("glFinalCombinerInputNV()");
+ }
+ }
+
+ TRACE("diffuse {%.8e, %.8e, %.8e, %.8e}\n",
+ state->material.diffuse.r, state->material.diffuse.g,
+ state->material.diffuse.b, state->material.diffuse.a);
+ TRACE("ambient {%.8e, %.8e, %.8e, %.8e}\n",
+ state->material.ambient.r, state->material.ambient.g,
+ state->material.ambient.b, state->material.ambient.a);
+ TRACE("specular {%.8e, %.8e, %.8e, %.8e}\n",
+ state->material.specular.r, state->material.specular.g,
+ state->material.specular.b, state->material.specular.a);
+ TRACE("emissive {%.8e, %.8e, %.8e, %.8e}\n",
+ state->material.emissive.r, state->material.emissive.g,
+ state->material.emissive.b, state->material.emissive.a);
+
+ gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
+ checkGLcall("glMaterialfv(GL_AMBIENT)");
+ gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
+ checkGLcall("glMaterialfv(GL_DIFFUSE)");
+ gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
+ checkGLcall("glMaterialfv(GL_EMISSION)");
+}
+
+static void state_texfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ unsigned int i;
+
+ /* Note the texture color applies to all textures whereas
+ * GL_TEXTURE_ENV_COLOR applies to active only. */
+ float col[4];
+ D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col);
+
+ /* And now the default texture color as well */
+ for (i = 0; i < context->d3d_info->limits.ffp_blend_stages; ++i)
+ {
+ /* Note the WINED3D_RS value applies to all textures, but GL has one
+ * per texture, so apply it now ready to be used! */
+ context_active_texture(context, gl_info, i);
+
+ gl_info->gl_ops.gl.p_glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
+ checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
+ }
+}
+
+static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face,
+ GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
+ checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
+ GL_EXTCALL(glActiveStencilFaceEXT(face));
+ checkGLcall("glActiveStencilFaceEXT(...)");
+ gl_info->gl_ops.gl.p_glStencilFunc(func, ref, mask);
+ checkGLcall("glStencilFunc(...)");
+ gl_info->gl_ops.gl.p_glStencilOp(stencilFail, depthFail, stencilPass);
+ checkGLcall("glStencilOp(...)");
+}
+
+static GLenum gl_stencil_op(enum wined3d_stencil_op op)
+{
+ switch (op)
+ {
+ case WINED3D_STENCIL_OP_KEEP:
+ return GL_KEEP;
+ case WINED3D_STENCIL_OP_ZERO:
+ return GL_ZERO;
+ case WINED3D_STENCIL_OP_REPLACE:
+ return GL_REPLACE;
+ case WINED3D_STENCIL_OP_INCR_SAT:
+ return GL_INCR;
+ case WINED3D_STENCIL_OP_DECR_SAT:
+ return GL_DECR;
+ case WINED3D_STENCIL_OP_INVERT:
+ return GL_INVERT;
+ case WINED3D_STENCIL_OP_INCR:
+ return GL_INCR_WRAP_EXT;
+ case WINED3D_STENCIL_OP_DECR:
+ return GL_DECR_WRAP_EXT;
+ default:
+ FIXME("Unrecognized stencil op %#x.\n", op);
+ return GL_KEEP;
+ }
+}
+
+static void state_stencil(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ DWORD onesided_enable = FALSE;
+ DWORD twosided_enable = FALSE;
+ GLint func = GL_ALWAYS;
+ GLint func_ccw = GL_ALWAYS;
+ GLint ref = 0;
+ GLuint mask = 0;
+ GLint stencilFail = GL_KEEP;
+ GLint depthFail = GL_KEEP;
+ GLint stencilPass = GL_KEEP;
+ GLint stencilFail_ccw = GL_KEEP;
+ GLint depthFail_ccw = GL_KEEP;
+ GLint stencilPass_ccw = GL_KEEP;
+
+ /* No stencil test without a stencil buffer. */
+ if (!state->fb->depth_stencil)
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
+ checkGLcall("glDisable GL_STENCIL_TEST");
+ return;
+ }
+
+ onesided_enable = state->render_states[WINED3D_RS_STENCILENABLE];
+ twosided_enable = state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE];
+ if (!(func = gl_compare_func(state->render_states[WINED3D_RS_STENCILFUNC])))
+ func = GL_ALWAYS;
+ if (!(func_ccw = gl_compare_func(state->render_states[WINED3D_RS_CCW_STENCILFUNC])))
+ func_ccw = GL_ALWAYS;
+ ref = state->render_states[WINED3D_RS_STENCILREF];
+ mask = state->render_states[WINED3D_RS_STENCILMASK];
+ stencilFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILFAIL]);
+ depthFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILZFAIL]);
+ stencilPass = gl_stencil_op(state->render_states[WINED3D_RS_STENCILPASS]);
+ stencilFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILFAIL]);
+ depthFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILZFAIL]);
+ stencilPass_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILPASS]);
+
+ TRACE("(onesided %d, twosided %d, ref %x, mask %x, "
+ "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x "
+ "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n",
+ onesided_enable, twosided_enable, ref, mask,
+ func, stencilFail, depthFail, stencilPass,
+ func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
+
+ if (twosided_enable && onesided_enable)
+ {
+ gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST);
+ checkGLcall("glEnable GL_STENCIL_TEST");
+
+ if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
+ {
+ /* Apply back first, then front. This function calls glActiveStencilFaceEXT,
+ * which has an effect on the code below too. If we apply the front face
+ * afterwards, we are sure that the active stencil face is set to front,
+ * and other stencil functions which do not use two sided stencil do not have
+ * to set it back
+ */
+ renderstate_stencil_twosided(context, GL_BACK,
+ func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
+ renderstate_stencil_twosided(context, GL_FRONT,
+ func, ref, mask, stencilFail, depthFail, stencilPass);
+ }
+ else if (gl_info->supported[ATI_SEPARATE_STENCIL])
+ {
+ GL_EXTCALL(glStencilFuncSeparateATI(func, func_ccw, ref, mask));
+ checkGLcall("glStencilFuncSeparateATI(...)");
+ GL_EXTCALL(glStencilOpSeparateATI(GL_FRONT, stencilFail, depthFail, stencilPass));
+ checkGLcall("glStencilOpSeparateATI(GL_FRONT, ...)");
+ GL_EXTCALL(glStencilOpSeparateATI(GL_BACK, stencilFail_ccw, depthFail_ccw, stencilPass_ccw));
+ checkGLcall("glStencilOpSeparateATI(GL_BACK, ...)");
+ } else {
+ ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
+ }
+ }
+ else if(onesided_enable)
+ {
+ if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
+ checkGLcall("glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
+ }
+
+ /* This code disables the ATI extension as well, since the standard stencil functions are equal
+ * to calling the ATI functions with GL_FRONT_AND_BACK as face parameter
+ */
+ gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST);
+ checkGLcall("glEnable GL_STENCIL_TEST");
+ gl_info->gl_ops.gl.p_glStencilFunc(func, ref, mask);
+ checkGLcall("glStencilFunc(...)");
+ gl_info->gl_ops.gl.p_glStencilOp(stencilFail, depthFail, stencilPass);
+ checkGLcall("glStencilOp(...)");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
+ checkGLcall("glDisable GL_STENCIL_TEST");
+ }
+}
+
+static void state_stencilwrite2s(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK));
+ checkGLcall("glActiveStencilFaceEXT(GL_BACK)");
+ gl_info->gl_ops.gl.p_glStencilMask(mask);
+ checkGLcall("glStencilMask");
+ GL_EXTCALL(glActiveStencilFaceEXT(GL_FRONT));
+ checkGLcall("glActiveStencilFaceEXT(GL_FRONT)");
+ gl_info->gl_ops.gl.p_glStencilMask(mask);
+}
+
+static void state_stencilwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ gl_info->gl_ops.gl.p_glStencilMask(mask);
+ checkGLcall("glStencilMask");
+}
+
+static void state_fog_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
+
+ if (!state->render_states[WINED3D_RS_FOGENABLE])
+ return;
+
+ /* Table fog on: Never use fog coords, and use per-fragment fog */
+ if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
+ {
+ gl_info->gl_ops.gl.p_glHint(GL_FOG_HINT, GL_NICEST);
+ if (context->fog_coord)
+ {
+ gl_info->gl_ops.gl.p_glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
+ checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
+ context->fog_coord = FALSE;
+ }
+
+ /* Range fog is only used with per-vertex fog in d3d */
+ if (gl_info->supported[NV_FOG_DISTANCE])
+ {
+ gl_info->gl_ops.gl.p_glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
+ checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
+ }
+ return;
+ }
+
+ /* Otherwise use per-vertex fog in any case */
+ gl_info->gl_ops.gl.p_glHint(GL_FOG_HINT, GL_FASTEST);
+
+ if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE || context->last_was_rhw)
+ {
+ /* No fog at all, or transformed vertices: Use fog coord */
+ if (!context->fog_coord)
+ {
+ gl_info->gl_ops.gl.p_glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
+ checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)");
+ context->fog_coord = TRUE;
+ }
+ }
+ else
+ {
+ /* Otherwise, use the fragment depth */
+ if (context->fog_coord)
+ {
+ gl_info->gl_ops.gl.p_glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
+ checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
+ context->fog_coord = FALSE;
+ }
+
+ if (state->render_states[WINED3D_RS_RANGEFOGENABLE])
+ {
+ if (gl_info->supported[NV_FOG_DISTANCE])
+ {
+ gl_info->gl_ops.gl.p_glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
+ checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)");
+ }
+ else
+ {
+ WARN("Range fog enabled, but not supported by this GL implementation.\n");
+ }
+ }
+ else if (gl_info->supported[NV_FOG_DISTANCE])
+ {
+ gl_info->gl_ops.gl.p_glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
+ checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
+ }
+ }
+}
+
+void state_fogstartend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ float fogstart, fogend;
+ union {
+ DWORD d;
+ float f;
+ } tmpvalue;
+
+ switch(context->fog_source) {
+ case FOGSOURCE_VS:
+ fogstart = 1.0f;
+ fogend = 0.0f;
+ break;
+
+ case FOGSOURCE_COORD:
+ fogstart = 255.0f;
+ fogend = 0.0f;
+ break;
+
+ case FOGSOURCE_FFP:
+ tmpvalue.d = state->render_states[WINED3D_RS_FOGSTART];
+ fogstart = tmpvalue.f;
+ tmpvalue.d = state->render_states[WINED3D_RS_FOGEND];
+ fogend = tmpvalue.f;
+ /* Special handling for fogstart == fogend. In d3d with vertex
+ * fog, everything is fogged. With table fog, everything with
+ * fog_coord < fog_start is unfogged, and fog_coord > fog_start
+ * is fogged. Windows drivers disagree when fog_coord == fog_start. */
+ if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE
+ && fogstart == fogend)
+ {
+ fogstart = -INFINITY;
+ fogend = 0.0f;
+ }
+ break;
+
+ default:
+ /* This should not happen.context->fog_source is set in wined3d, not the app.
+ * Still this is needed to make the compiler happy
+ */
+ ERR("Unexpected fog coordinate source\n");
+ fogstart = 0.0f;
+ fogend = 0.0f;
+ }
+
+ gl_info->gl_ops.gl.p_glFogf(GL_FOG_START, fogstart);
+ checkGLcall("glFogf(GL_FOG_START, fogstart)");
+ TRACE("Fog Start == %f\n", fogstart);
+
+ gl_info->gl_ops.gl.p_glFogf(GL_FOG_END, fogend);
+ checkGLcall("glFogf(GL_FOG_END, fogend)");
+ TRACE("Fog End == %f\n", fogend);
+}
+
+void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ enum fogsource new_source;
+ DWORD fogstart = state->render_states[WINED3D_RS_FOGSTART];
+ DWORD fogend = state->render_states[WINED3D_RS_FOGEND];
+
+ TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
+
+ if (!state->render_states[WINED3D_RS_FOGENABLE])
+ {
+ /* No fog? Disable it, and we're done :-) */
+ glDisableWINE(GL_FOG);
+ checkGLcall("glDisable GL_FOG");
+ return;
+ }
+
+ /* Fog Rules:
+ *
+ * With fixed function vertex processing, Direct3D knows 2 different fog input sources.
+ * It can use the Z value of the vertex, or the alpha component of the specular color.
+ * This depends on the fog vertex, fog table and the vertex declaration. If the Z value
+ * is used, fogstart, fogend and the equation type are used, otherwise linear fog with
+ * start = 255, end = 0 is used. Obviously the msdn is not very clear on that.
+ *
+ * FOGTABLEMODE != NONE:
+ * The Z value is used, with the equation specified, no matter what vertex type.
+ *
+ * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, untransformed:
+ * Per vertex fog is calculated using the specified fog equation and the parameters
+ *
+ * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, transformed, OR
+ * FOGTABLEMODE == NONE, FOGVERTEXMODE == NONE, untransformed:
+ * Linear fog with start = 255.0, end = 0.0, input comes from the specular color
+ *
+ *
+ * Rules for vertex fog with shaders:
+ *
+ * When mixing fixed function functionality with the programmable pipeline, D3D expects
+ * the fog computation to happen during transformation while openGL expects it to happen
+ * during rasterization. Also, prior to pixel shader 3.0 D3D handles fog blending after
+ * the pixel shader while openGL always expects the pixel shader to handle the blending.
+ * To solve this problem, WineD3D does:
+ * 1) implement a linear fog equation and fog blending at the end of every pre 3.0 pixel
+ * shader,
+ * and 2) disables the fog computation (in either the fixed function or programmable
+ * rasterizer) if using a vertex program.
+ *
+ * D3D shaders can provide an explicit fog coordinate. This fog coordinate is used with
+ * D3DRS_FOGTABLEMODE==D3DFOG_NONE. The FOGVERTEXMODE is ignored, d3d always uses linear
+ * fog with start=1.0 and end=0.0 in this case. This is similar to fog coordinates in
+ * the specular color, a vertex shader counts as pretransformed geometry in this case.
+ * There are some GL differences between specular fog coords and vertex shaders though.
+ *
+ * With table fog the vertex shader fog coordinate is ignored.
+ *
+ * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
+ * without shaders).
+ */
+
+ /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
+ * the system will apply only pixel(=table) fog effects."
+ */
+ if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
+ {
+ if (use_vs(state))
+ {
+ gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
+ checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
+ new_source = FOGSOURCE_VS;
+ }
+ else
+ {
+ switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
+ {
+ /* If processed vertices are used, fall through to the NONE case */
+ case WINED3D_FOG_EXP:
+ if (!context->last_was_rhw)
+ {
+ gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP);
+ checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
+ new_source = FOGSOURCE_FFP;
+ break;
+ }
+ /* drop through */
+
+ case WINED3D_FOG_EXP2:
+ if (!context->last_was_rhw)
+ {
+ gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP2);
+ checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
+ new_source = FOGSOURCE_FFP;
+ break;
+ }
+ /* drop through */
+
+ case WINED3D_FOG_LINEAR:
+ if (!context->last_was_rhw)
+ {
+ gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
+ checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
+ new_source = FOGSOURCE_FFP;
+ break;
+ }
+ /* drop through */
+
+ case WINED3D_FOG_NONE:
+ /* Both are none? According to msdn the alpha channel of the specular
+ * color contains a fog factor. Set it in drawStridedSlow.
+ * Same happens with Vertexfog on transformed vertices
+ */
+ new_source = FOGSOURCE_COORD;
+ gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
+ checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
+ break;
+
+ default:
+ FIXME("Unexpected WINED3D_RS_FOGVERTEXMODE %#x.\n",
+ state->render_states[WINED3D_RS_FOGVERTEXMODE]);
+ new_source = FOGSOURCE_FFP; /* Make the compiler happy */
+ }
+ }
+ } else {
+ new_source = FOGSOURCE_FFP;
+
+ switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
+ {
+ case WINED3D_FOG_EXP:
+ gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP);
+ checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
+ break;
+
+ case WINED3D_FOG_EXP2:
+ gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP2);
+ checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
+ break;
+
+ case WINED3D_FOG_LINEAR:
+ gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
+ checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
+ break;
+
+ case WINED3D_FOG_NONE: /* Won't happen */
+ default:
+ FIXME("Unexpected WINED3D_RS_FOGTABLEMODE %#x.\n",
+ state->render_states[WINED3D_RS_FOGTABLEMODE]);
+ }
+ }
+
+ glEnableWINE(GL_FOG);
+ checkGLcall("glEnable GL_FOG");
+ if (new_source != context->fog_source || fogstart == fogend)
+ {
+ context->fog_source = new_source;
+ state_fogstartend(context, state, STATE_RENDER(WINED3D_RS_FOGSTART));
+ }
+}
+
+void state_fogcolor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ float col[4];
+
+ D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_FOGCOLOR], col);
+ gl_info->gl_ops.gl.p_glFogfv(GL_FOG_COLOR, &col[0]);
+ checkGLcall("glFog GL_FOG_COLOR");
+}
+
+void state_fogdensity(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ union {
+ DWORD d;
+ float f;
+ } tmpvalue;
+
+ tmpvalue.d = state->render_states[WINED3D_RS_FOGDENSITY];
+ gl_info->gl_ops.gl.p_glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
+ checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
+}
+
+static void state_colormat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_device *device = context->swapchain->device;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ GLenum Parm = 0;
+
+ /* Depends on the decoded vertex declaration to read the existence of diffuse data.
+ * The vertex declaration will call this function if the fixed function pipeline is used.
+ */
+
+ if(isStateDirty(context, STATE_VDECL)) {
+ return;
+ }
+
+ context->num_untracked_materials = 0;
+ if ((device->stream_info.use_map & (1 << WINED3D_FFP_DIFFUSE))
+ && state->render_states[WINED3D_RS_COLORVERTEX])
+ {
+ TRACE("diff %d, amb %d, emis %d, spec %d\n",
+ state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE],
+ state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE],
+ state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE],
+ state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]);
+
+ if (state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
+ {
+ if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
+ Parm = GL_AMBIENT_AND_DIFFUSE;
+ else
+ Parm = GL_DIFFUSE;
+ if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
+ {
+ context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
+ context->num_untracked_materials++;
+ }
+ if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
+ {
+ context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
+ context->num_untracked_materials++;
+ }
+ }
+ else if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
+ {
+ Parm = GL_AMBIENT;
+ if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
+ {
+ context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
+ context->num_untracked_materials++;
+ }
+ if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
+ {
+ context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
+ context->num_untracked_materials++;
+ }
+ }
+ else if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
+ {
+ Parm = GL_EMISSION;
+ if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
+ {
+ context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
+ context->num_untracked_materials++;
+ }
+ }
+ else if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
+ {
+ Parm = GL_SPECULAR;
+ }
+ }
+
+ /* Nothing changed, return. */
+ if (Parm == context->tracking_parm) return;
+
+ if (!Parm)
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_COLOR_MATERIAL);
+ checkGLcall("glDisable GL_COLOR_MATERIAL");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glColorMaterial(GL_FRONT_AND_BACK, Parm);
+ checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
+ gl_info->gl_ops.gl.p_glEnable(GL_COLOR_MATERIAL);
+ checkGLcall("glEnable(GL_COLOR_MATERIAL)");
+ }
+
+ /* Apparently calls to glMaterialfv are ignored for properties we're
+ * tracking with glColorMaterial, so apply those here. */
+ switch (context->tracking_parm)
+ {
+ case GL_AMBIENT_AND_DIFFUSE:
+ gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
+ gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
+ checkGLcall("glMaterialfv");
+ break;
+
+ case GL_DIFFUSE:
+ gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
+ checkGLcall("glMaterialfv");
+ break;
+
+ case GL_AMBIENT:
+ gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
+ checkGLcall("glMaterialfv");
+ break;
+
+ case GL_EMISSION:
+ gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
+ checkGLcall("glMaterialfv");
+ break;
+
+ case GL_SPECULAR:
+ /* Only change material color if specular is enabled, otherwise it is set to black */
+ if (state->render_states[WINED3D_RS_SPECULARENABLE])
+ {
+ gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
+ checkGLcall("glMaterialfv");
+ }
+ else
+ {
+ static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
+ gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
+ checkGLcall("glMaterialfv");
+ }
+ break;
+ }
+
+ context->tracking_parm = Parm;
+}
+
+static void state_linepattern(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ union
+ {
+ DWORD d;
+ struct wined3d_line_pattern lp;
+ } tmppattern;
+ tmppattern.d = state->render_states[WINED3D_RS_LINEPATTERN];
+
+ TRACE("Line pattern: repeat %d bits %x.\n", tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
+
+ if (tmppattern.lp.repeat_factor)
+ {
+ gl_info->gl_ops.gl.p_glLineStipple(tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
+ checkGLcall("glLineStipple(repeat, linepattern)");
+ gl_info->gl_ops.gl.p_glEnable(GL_LINE_STIPPLE);
+ checkGLcall("glEnable(GL_LINE_STIPPLE);");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_LINE_STIPPLE);
+ checkGLcall("glDisable(GL_LINE_STIPPLE);");
+ }
+}
+
+static void state_normalize(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (isStateDirty(context, STATE_VDECL))
+ return;
+
+ /* Without vertex normals, we set the current normal to 0/0/0 to remove the diffuse factor
+ * from the opengl lighting equation, as d3d does. Normalization of 0/0/0 can lead to a division
+ * by zero and is not properly defined in opengl, so avoid it
+ */
+ if (state->render_states[WINED3D_RS_NORMALIZENORMALS]
+ && (context->swapchain->device->stream_info.use_map & (1 << WINED3D_FFP_NORMAL)))
+ {
+ gl_info->gl_ops.gl.p_glEnable(GL_NORMALIZE);
+ checkGLcall("glEnable(GL_NORMALIZE);");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_NORMALIZE);
+ checkGLcall("glDisable(GL_NORMALIZE);");
+ }
+}
+
+void state_psizemin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ union {
+ DWORD d;
+ float f;
+ } tmpvalue;
+
+ tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
+ if (tmpvalue.f != 1.0f)
+ {
+ FIXME("WINED3D_RS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
+ }
+ tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
+ if (tmpvalue.f != 64.0f)
+ {
+ FIXME("WINED3D_RS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
+ }
+
+}
+
+void state_psizemin_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ union
+ {
+ DWORD d;
+ float f;
+ } min, max;
+
+ min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
+ max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
+
+ /* Max point size trumps min point size */
+ if(min.f > max.f) {
+ min.f = max.f;
+ }
+
+ GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, min.f);
+ checkGLcall("glPointParameterfEXT(...)");
+ GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, max.f);
+ checkGLcall("glPointParameterfEXT(...)");
+}
+
+void state_psizemin_arb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ union
+ {
+ DWORD d;
+ float f;
+ } min, max;
+
+ min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
+ max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
+
+ /* Max point size trumps min point size */
+ if(min.f > max.f) {
+ min.f = max.f;
+ }
+
+ GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, min.f);
+ checkGLcall("glPointParameterfARB(...)");
+ GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, max.f);
+ checkGLcall("glPointParameterfARB(...)");
+}
+
+void state_pscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ /* TODO: Group this with the viewport */
+ /*
+ * POINTSCALEENABLE controls how point size value is treated. If set to
+ * true, the point size is scaled with respect to height of viewport.
+ * When set to false point size is in pixels.
+ */
+
+ /* Default values */
+ GLfloat att[3] = {1.0f, 0.0f, 0.0f};
+ union {
+ DWORD d;
+ float f;
+ } pointSize, A, B, C;
+
+ pointSize.d = state->render_states[WINED3D_RS_POINTSIZE];
+ A.d = state->render_states[WINED3D_RS_POINTSCALE_A];
+ B.d = state->render_states[WINED3D_RS_POINTSCALE_B];
+ C.d = state->render_states[WINED3D_RS_POINTSCALE_C];
+
+ if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
+ {
+ DWORD h = state->viewport.height;
+ GLfloat scaleFactor;
+
+ if (pointSize.f < gl_info->limits.pointsize_min)
+ {
+ /* Minimum valid point size for OpenGL is driver specific. For Direct3D it is
+ * 0.0f. This means that OpenGL will clamp really small point sizes to the
+ * driver minimum. To correct for this we need to multiply by the scale factor when sizes
+ * are less than 1.0f. scale_factor = 1.0f / point_size.
+ */
+ scaleFactor = pointSize.f / gl_info->limits.pointsize_min;
+ /* Clamp the point size, don't rely on the driver to do it. MacOS says min point size
+ * is 1.0, but then accepts points below that and draws too small points
+ */
+ pointSize.f = gl_info->limits.pointsize_min;
+ }
+ else if(pointSize.f > gl_info->limits.pointsize_max)
+ {
+ /* gl already scales the input to glPointSize,
+ * d3d scales the result after the point size scale.
+ * If the point size is bigger than the max size, use the
+ * scaling to scale it bigger, and set the gl point size to max
+ */
+ scaleFactor = pointSize.f / gl_info->limits.pointsize_max;
+ TRACE("scale: %f\n", scaleFactor);
+ pointSize.f = gl_info->limits.pointsize_max;
+ } else {
+ scaleFactor = 1.0f;
+ }
+ scaleFactor = powf(h * scaleFactor, 2);
+
+ att[0] = A.f / scaleFactor;
+ att[1] = B.f / scaleFactor;
+ att[2] = C.f / scaleFactor;
+ }
+
+ if (gl_info->supported[ARB_POINT_PARAMETERS])
+ {
+ GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
+ checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...)");
+ }
+ else if (gl_info->supported[EXT_POINT_PARAMETERS])
+ {
+ GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
+ checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...)");
+ }
+ else if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
+ {
+ WARN("POINT_PARAMETERS not supported in this version of opengl\n");
+ }
+
+ gl_info->gl_ops.gl.p_glPointSize(pointSize.f);
+ checkGLcall("glPointSize(...);");
+}
+
+static void state_debug_monitor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ WARN("token: %#x.\n", state->render_states[WINED3D_RS_DEBUGMONITORTOKEN]);
+}
+
+static void state_colorwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ DWORD mask0 = state->render_states[WINED3D_RS_COLORWRITEENABLE];
+ DWORD mask1 = state->render_states[WINED3D_RS_COLORWRITEENABLE1];
+ DWORD mask2 = state->render_states[WINED3D_RS_COLORWRITEENABLE2];
+ DWORD mask3 = state->render_states[WINED3D_RS_COLORWRITEENABLE3];
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
+ mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0,
+ mask0 & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
+ mask0 & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0,
+ mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
+ gl_info->gl_ops.gl.p_glColorMask(mask0 & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
+ mask0 & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
+ mask0 & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
+ mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
+ checkGLcall("glColorMask(...)");
+
+ if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0)
+ || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf)))
+ {
+ FIXME("WINED3D_RS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n",
+ mask0, mask1, mask2, mask3);
+ FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n");
+ }
+}
+
+static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask)
+{
+ GL_EXTCALL(glColorMaskIndexedEXT(index,
+ mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
+ mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
+ mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
+ mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE));
+}
+
+static void state_colorwrite0(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ set_color_mask(context->gl_info, 0, state->render_states[WINED3D_RS_COLORWRITEENABLE]);
+}
+
+static void state_colorwrite1(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ set_color_mask(context->gl_info, 1, state->render_states[WINED3D_RS_COLORWRITEENABLE1]);
+}
+
+static void state_colorwrite2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ set_color_mask(context->gl_info, 2, state->render_states[WINED3D_RS_COLORWRITEENABLE2]);
+}
+
+static void state_colorwrite3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ set_color_mask(context->gl_info, 3, state->render_states[WINED3D_RS_COLORWRITEENABLE3]);
+}
+
+static void state_localviewer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (state->render_states[WINED3D_RS_LOCALVIEWER])
+ {
+ gl_info->gl_ops.gl.p_glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
+ checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
+ checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
+ }
+}
+
+static void state_lastpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_LASTPIXEL])
+ {
+ TRACE("Last Pixel Drawing Enabled\n");
+ }
+ else
+ {
+ static BOOL warned;
+ if (!warned) {
+ FIXME("Last Pixel Drawing Disabled, not handled yet\n");
+ warned = TRUE;
+ } else {
+ TRACE("Last Pixel Drawing Disabled, not handled yet\n");
+ }
+ }
+}
+
+void state_pointsprite_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ static BOOL warned;
+
+ /* TODO: NV_POINT_SPRITE */
+ if (!warned && state->render_states[WINED3D_RS_POINTSPRITEENABLE])
+ {
+ /* A FIXME, not a WARN because point sprites should be software emulated if not supported by HW */
+ FIXME("Point sprites not supported\n");
+ warned = TRUE;
+ }
+}
+
+void state_pointsprite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (state->render_states[WINED3D_RS_POINTSPRITEENABLE])
+ {
+ gl_info->gl_ops.gl.p_glEnable(GL_POINT_SPRITE_ARB);
+ checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_POINT_SPRITE_ARB);
+ checkGLcall("glDisable(GL_POINT_SPRITE_ARB)");
+ }
+}
+
+static void state_wrap(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_WRAP0]
+ || state->render_states[WINED3D_RS_WRAP1]
+ || state->render_states[WINED3D_RS_WRAP2]
+ || state->render_states[WINED3D_RS_WRAP3]
+ || state->render_states[WINED3D_RS_WRAP4]
+ || state->render_states[WINED3D_RS_WRAP5]
+ || state->render_states[WINED3D_RS_WRAP6]
+ || state->render_states[WINED3D_RS_WRAP7]
+ || state->render_states[WINED3D_RS_WRAP8]
+ || state->render_states[WINED3D_RS_WRAP9]
+ || state->render_states[WINED3D_RS_WRAP10]
+ || state->render_states[WINED3D_RS_WRAP11]
+ || state->render_states[WINED3D_RS_WRAP12]
+ || state->render_states[WINED3D_RS_WRAP13]
+ || state->render_states[WINED3D_RS_WRAP14]
+ || state->render_states[WINED3D_RS_WRAP15])
+ FIXME("(WINED3D_RS_WRAP0) Texture wrapping not yet supported.\n");
+}
+
+static void state_msaa_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
+ WARN("Multisample antialiasing not supported by GL.\n");
+}
+
+static void state_msaa(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
+ {
+ gl_info->gl_ops.gl.p_glEnable(GL_MULTISAMPLE_ARB);
+ checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_MULTISAMPLE_ARB);
+ checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
+ }
+}
+
+static void state_scissor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
+ {
+ gl_info->gl_ops.gl.p_glEnable(GL_SCISSOR_TEST);
+ checkGLcall("glEnable(GL_SCISSOR_TEST)");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
+ checkGLcall("glDisable(GL_SCISSOR_TEST)");
+ }
+}
+
+/* The Direct3D depth bias is specified in normalized depth coordinates. In
+ * OpenGL the bias is specified in units of "the smallest value that is
+ * guaranteed to produce a resolvable offset for a given implementation". To
+ * convert from D3D to GL we need to divide the D3D depth bias by that value.
+ * There's no practical way to retrieve that value from a given GL
+ * implementation, but the D3D application has essentially the same problem,
+ * which makes a guess of the depth buffer format's highest possible value a
+ * reasonable guess. Note that SLOPESCALEDEPTHBIAS is a scaling factor for the
+ * depth slope, and doesn't need to be scaled. */
+static void state_depthbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS]
+ || state->render_states[WINED3D_RS_DEPTHBIAS])
+ {
+ const struct wined3d_surface *depth = state->fb->depth_stencil;
+ float scale;
+
+ union
+ {
+ DWORD d;
+ float f;
+ } scale_bias, const_bias;
+
+ scale_bias.d = state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS];
+ const_bias.d = state->render_states[WINED3D_RS_DEPTHBIAS];
+
+ gl_info->gl_ops.gl.p_glEnable(GL_POLYGON_OFFSET_FILL);
+ checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
+
+ if (context->swapchain->device->wined3d->flags & WINED3D_LEGACY_DEPTH_BIAS)
+ {
+ float bias = -(float)const_bias.d;
+ gl_info->gl_ops.gl.p_glPolygonOffset(bias, bias);
+ checkGLcall("glPolygonOffset");
+ }
+ else
+ {
+ if (depth)
+ {
+ const struct wined3d_format *fmt = depth->resource.format;
+ scale = powf(2, fmt->depth_size) - 1;
+ TRACE("Depth format %s, using depthbias scale of %.8e.\n",
+ debug_d3dformat(fmt->id), scale);
+ }
+ else
+ {
+ /* The context manager will reapply this state on a depth stencil change */
+ TRACE("No depth stencil, using depthbias scale of 0.0.\n");
+ scale = 0.0f;
+ }
+
+ gl_info->gl_ops.gl.p_glPolygonOffset(scale_bias.f, const_bias.f * scale);
+ checkGLcall("glPolygonOffset(...)");
+ }
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_POLYGON_OFFSET_FILL);
+ checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
+ }
+}
+
+static void state_zvisible(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_ZVISIBLE])
+ FIXME("WINED3D_RS_ZVISIBLE not implemented.\n");
+}
+
+static void state_perspective(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (state->render_states[WINED3D_RS_TEXTUREPERSPECTIVE])
+ {
+ gl_info->gl_ops.gl.p_glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+ checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+ checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
+ }
+}
+
+static void state_stippledalpha(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_STIPPLEDALPHA])
+ FIXME("Stippled Alpha not supported yet.\n");
+}
+
+static void state_antialias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_ANTIALIAS])
+ FIXME("Antialias not supported yet.\n");
+}
+
+static void state_multisampmask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_MULTISAMPLEMASK] != 0xffffffff)
+ FIXME("WINED3D_RS_MULTISAMPLEMASK %#x not yet implemented.\n",
+ state->render_states[WINED3D_RS_MULTISAMPLEMASK]);
+}
+
+static void state_patchedgestyle(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_PATCHEDGESTYLE] != WINED3D_PATCH_EDGE_DISCRETE)
+ FIXME("WINED3D_RS_PATCHEDGESTYLE %#x not yet implemented.\n",
+ state->render_states[WINED3D_RS_PATCHEDGESTYLE]);
+}
+
+static void state_patchsegments(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ union {
+ DWORD d;
+ float f;
+ } tmpvalue;
+ tmpvalue.f = 1.0f;
+
+ if (state->render_states[WINED3D_RS_PATCHSEGMENTS] != tmpvalue.d)
+ {
+ static BOOL displayed = FALSE;
+
+ tmpvalue.d = state->render_states[WINED3D_RS_PATCHSEGMENTS];
+ if(!displayed)
+ FIXME("(WINED3D_RS_PATCHSEGMENTS,%f) not yet implemented\n", tmpvalue.f);
+
+ displayed = TRUE;
+ }
+}
+
+static void state_positiondegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_POSITIONDEGREE] != WINED3D_DEGREE_CUBIC)
+ FIXME("WINED3D_RS_POSITIONDEGREE %#x not yet implemented.\n",
+ state->render_states[WINED3D_RS_POSITIONDEGREE]);
+}
+
+static void state_normaldegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_NORMALDEGREE] != WINED3D_DEGREE_LINEAR)
+ FIXME("WINED3D_RS_NORMALDEGREE %#x not yet implemented.\n",
+ state->render_states[WINED3D_RS_NORMALDEGREE]);
+}
+
+static void state_tessellation(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION])
+ FIXME("WINED3D_RS_ENABLEADAPTIVETESSELLATION %#x not yet implemented.\n",
+ state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION]);
+}
+
+static void state_nvdb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ union {
+ DWORD d;
+ float f;
+ } zmin, zmax;
+
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (state->render_states[WINED3D_RS_ADAPTIVETESS_X] == WINED3DFMT_NVDB)
+ {
+ zmin.d = state->render_states[WINED3D_RS_ADAPTIVETESS_Z];
+ zmax.d = state->render_states[WINED3D_RS_ADAPTIVETESS_W];
+
+ /* If zmin is larger than zmax INVALID_VALUE error is generated.
+ * In d3d9 test is not performed in this case*/
+ if (zmin.f <= zmax.f)
+ {
+ gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_BOUNDS_TEST_EXT);
+ checkGLcall("glEnable(GL_DEPTH_BOUNDS_TEST_EXT)");
+ GL_EXTCALL(glDepthBoundsEXT(zmin.f, zmax.f));
+ checkGLcall("glDepthBoundsEXT(...)");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
+ checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
+ }
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
+ checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
+ }
+
+ state_tessellation(context, state, STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION));
+}
+
+static void state_wrapu(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_WRAPU])
+ FIXME("Render state WINED3D_RS_WRAPU not implemented yet.\n");
+}
+
+static void state_wrapv(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_WRAPV])
+ FIXME("Render state WINED3D_RS_WRAPV not implemented yet.\n");
+}
+
+static void state_monoenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_MONOENABLE])
+ FIXME("Render state WINED3D_RS_MONOENABLE not implemented yet.\n");
+}
+
+static void state_rop2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_ROP2])
+ FIXME("Render state WINED3D_RS_ROP2 not implemented yet.\n");
+}
+
+static void state_planemask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_PLANEMASK])
+ FIXME("Render state WINED3D_RS_PLANEMASK not implemented yet.\n");
+}
+
+static void state_subpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_SUBPIXEL])
+ FIXME("Render state WINED3D_RS_SUBPIXEL not implemented yet.\n");
+}
+
+static void state_subpixelx(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_SUBPIXELX])
+ FIXME("Render state WINED3D_RS_SUBPIXELX not implemented yet.\n");
+}
+
+static void state_stippleenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_STIPPLEENABLE])
+ FIXME("Render state WINED3D_RS_STIPPLEENABLE not implemented yet.\n");
+}
+
+static void state_mipmaplodbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_MIPMAPLODBIAS])
+ FIXME("Render state WINED3D_RS_MIPMAPLODBIAS not implemented yet.\n");
+}
+
+static void state_anisotropy(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_ANISOTROPY])
+ FIXME("Render state WINED3D_RS_ANISOTROPY not implemented yet.\n");
+}
+
+static void state_flushbatch(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_FLUSHBATCH])
+ FIXME("Render state WINED3D_RS_FLUSHBATCH not implemented yet.\n");
+}
+
+static void state_translucentsi(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_TRANSLUCENTSORTINDEPENDENT])
+ FIXME("Render state WINED3D_RS_TRANSLUCENTSORTINDEPENDENT not implemented yet.\n");
+}
+
+static void state_extents(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_EXTENTS])
+ FIXME("Render state WINED3D_RS_EXTENTS not implemented yet.\n");
+}
+
+static void state_ckeyblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_COLORKEYBLENDENABLE])
+ FIXME("Render state WINED3D_RS_COLORKEYBLENDENABLE not implemented yet.\n");
+}
+
+static void state_swvp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (state->render_states[WINED3D_RS_SOFTWAREVERTEXPROCESSING])
+ FIXME("Software vertex processing not implemented.\n");
+}
+
+static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
+ /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
+ * input should be used for all input components. The WINED3DTA_COMPLEMENT
+ * flag specifies the complement of the input should be used. */
+ BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
+ BOOL complement = arg & WINED3DTA_COMPLEMENT;
+
+ /* Calculate the operand */
+ if (complement) {
+ if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
+ else *operand = GL_ONE_MINUS_SRC_COLOR;
+ } else {
+ if (from_alpha) *operand = GL_SRC_ALPHA;
+ else *operand = GL_SRC_COLOR;
+ }
+
+ /* Calculate the source */
+ switch (arg & WINED3DTA_SELECTMASK) {
+ case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
+ case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
+ case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
+ case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
+ case WINED3DTA_SPECULAR:
+ /*
+ * According to the GL_ARB_texture_env_combine specs, SPECULAR is
+ * 'Secondary color' and isn't supported until base GL supports it
+ * There is no concept of temp registers as far as I can tell
+ */
+ FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
+ *source = GL_TEXTURE;
+ break;
+ default:
+ FIXME("Unrecognized texture arg %#x\n", arg);
+ *source = GL_TEXTURE;
+ break;
+ }
+}
+
+/* Setup the texture operations texture stage states */
+static void set_tex_op(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state,
+ BOOL isAlpha, int Stage, enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
+{
+ GLenum src1, src2, src3;
+ GLenum opr1, opr2, opr3;
+ GLenum comb_target;
+ GLenum src0_target, src1_target, src2_target;
+ GLenum opr0_target, opr1_target, opr2_target;
+ GLenum scal_target;
+ GLenum opr=0, invopr, src3_target, opr3_target;
+ BOOL Handled = FALSE;
+
+ TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
+
+ /* This is called by a state handler which has the gl lock held and a context for the thread */
+
+ /* Note: Operations usually involve two ars, src0 and src1 and are operations of
+ the form (a1 <operation> a2). However, some of the more complex operations
+ take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
+ in a third parameter called a0. Therefore these are operations of the form
+ a0 <operation> a1 <operation> a2, i.e., the new parameter goes to the front.
+
+ However, below we treat the new (a0) parameter as src2/opr2, so in the actual
+ functions below, expect their syntax to differ slightly to those listed in the
+ manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
+ This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
+
+ if (isAlpha)
+ {
+ comb_target = GL_COMBINE_ALPHA;
+ src0_target = GL_SOURCE0_ALPHA;
+ src1_target = GL_SOURCE1_ALPHA;
+ src2_target = GL_SOURCE2_ALPHA;
+ opr0_target = GL_OPERAND0_ALPHA;
+ opr1_target = GL_OPERAND1_ALPHA;
+ opr2_target = GL_OPERAND2_ALPHA;
+ scal_target = GL_ALPHA_SCALE;
+ }
+ else
+ {
+ comb_target = GL_COMBINE_RGB;
+ src0_target = GL_SOURCE0_RGB;
+ src1_target = GL_SOURCE1_RGB;
+ src2_target = GL_SOURCE2_RGB;
+ opr0_target = GL_OPERAND0_RGB;
+ opr1_target = GL_OPERAND1_RGB;
+ opr2_target = GL_OPERAND2_RGB;
+ scal_target = GL_RGB_SCALE;
+ }
+
+ /* If a texture stage references an invalid texture unit the stage just
+ * passes through the result from the previous stage */
+ if (is_invalid_op(state, Stage, op, arg1, arg2, arg3))
+ {
+ arg1 = WINED3DTA_CURRENT;
+ op = WINED3D_TOP_SELECT_ARG1;
+ }
+
+ if (isAlpha && !state->textures[Stage] && arg1 == WINED3DTA_TEXTURE)
+ {
+ get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
+ } else {
+ get_src_and_opr(arg1, isAlpha, &src1, &opr1);
+ }
+ get_src_and_opr(arg2, isAlpha, &src2, &opr2);
+ get_src_and_opr(arg3, isAlpha, &src3, &opr3);
+
+ TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
+
+ Handled = TRUE; /* Assume will be handled */
+
+ /* Other texture operations require special extensions: */
+ if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
+ {
+ if (isAlpha) {
+ opr = GL_SRC_ALPHA;
+ invopr = GL_ONE_MINUS_SRC_ALPHA;
+ src3_target = GL_SOURCE3_ALPHA_NV;
+ opr3_target = GL_OPERAND3_ALPHA_NV;
+ } else {
+ opr = GL_SRC_COLOR;
+ invopr = GL_ONE_MINUS_SRC_COLOR;
+ src3_target = GL_SOURCE3_RGB_NV;
+ opr3_target = GL_OPERAND3_RGB_NV;
+ }
+ switch (op)
+ {
+ case WINED3D_TOP_DISABLE: /* Only for alpha */
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
+ break;
+
+ case WINED3D_TOP_SELECT_ARG1: /* = a1 * 1 + 0 * 0 */
+ case WINED3D_TOP_SELECT_ARG2: /* = a2 * 1 + 0 * 0 */
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ if (op == WINED3D_TOP_SELECT_ARG1)
+ {
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
+ }
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
+ break;
+
+ case WINED3D_TOP_MODULATE:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_MODULATE_2X:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
+ break;
+ case WINED3D_TOP_MODULATE_4X:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
+ break;
+
+ case WINED3D_TOP_ADD:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+
+ case WINED3D_TOP_ADD_SIGNED:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+
+ case WINED3D_TOP_ADD_SIGNED_2X:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
+ break;
+
+ case WINED3D_TOP_ADD_SMOOTH:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
+ case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+ }
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+
+ case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_BLEND_FACTOR_ALPHA:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_CONSTANT);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_CONSTANT");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_CONSTANT);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_CONSTANT");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
+ switch (opr) {
+ case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ }
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ }
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
+ case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+ }
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
+ case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+ }
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ }
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_MULTIPLY_ADD:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+
+ case WINED3D_TOP_BUMPENVMAP:
+ case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
+ FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
+ Handled = FALSE;
+ break;
+
+ default:
+ Handled = FALSE;
+ }
+ if (Handled)
+ {
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
+ checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
+
+ return;
+ }
+ } /* GL_NV_texture_env_combine4 */
+
+ Handled = TRUE; /* Again, assume handled */
+ switch (op) {
+ case WINED3D_TOP_DISABLE: /* Only for alpha */
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_SELECT_ARG1:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_SELECT_ARG2:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_MODULATE:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_MODULATE_2X:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
+ break;
+ case WINED3D_TOP_MODULATE_4X:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
+ break;
+ case WINED3D_TOP_ADD:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_ADD_SIGNED:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_ADD_SIGNED_2X:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
+ break;
+ case WINED3D_TOP_SUBTRACT:
+ if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE])
+ {
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_SUBTRACT");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ } else {
+ FIXME("This version of opengl does not support GL_SUBTRACT\n");
+ }
+ break;
+
+ case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_BLEND_FACTOR_ALPHA:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_CONSTANT);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_BLEND_CURRENT_ALPHA:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PREVIOUS);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_DOTPRODUCT3:
+ if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
+ {
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
+ }
+ else if (gl_info->supported[EXT_TEXTURE_ENV_DOT3])
+ {
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
+ } else {
+ FIXME("This version of opengl does not support GL_DOT3\n");
+ }
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_LERP:
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case WINED3D_TOP_ADD_SMOOTH:
+ if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
+ {
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
+ case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+ }
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ } else
+ Handled = FALSE;
+ break;
+ case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
+ if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
+ {
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ } else
+ Handled = FALSE;
+ break;
+ case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
+ if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
+ {
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ }
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ } else
+ Handled = FALSE;
+ break;
+ case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
+ if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
+ {
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ }
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ } else
+ Handled = FALSE;
+ break;
+ case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
+ if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
+ {
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
+ case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+ }
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ } else
+ Handled = FALSE;
+ break;
+ case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
+ if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
+ {
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
+ case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+ }
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ }
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ } else
+ Handled = FALSE;
+ break;
+ case WINED3D_TOP_MULTIPLY_ADD:
+ if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
+ {
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ } else
+ Handled = FALSE;
+ break;
+ case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
+ case WINED3D_TOP_BUMPENVMAP:
+ if (gl_info->supported[NV_TEXTURE_SHADER2])
+ {
+ /* Technically texture shader support without register combiners is possible, but not expected to occur
+ * on real world cards, so for now a fixme should be enough
+ */
+ FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
+ }
+ Handled = FALSE;
+ break;
+
+ default:
+ Handled = FALSE;
+ }
+
+ if (Handled) {
+ BOOL combineOK = TRUE;
+ if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
+ {
+ DWORD op2;
+
+ if (isAlpha)
+ op2 = state->texture_states[Stage][WINED3D_TSS_COLOR_OP];
+ else
+ op2 = state->texture_states[Stage][WINED3D_TSS_ALPHA_OP];
+
+ /* Note: If COMBINE4 in effect can't go back to combine! */
+ switch (op2)
+ {
+ case WINED3D_TOP_ADD_SMOOTH:
+ case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
+ case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
+ case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
+ case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
+ case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
+ case WINED3D_TOP_MULTIPLY_ADD:
+ /* Ignore those implemented in both cases */
+ switch (op)
+ {
+ case WINED3D_TOP_SELECT_ARG1:
+ case WINED3D_TOP_SELECT_ARG2:
+ combineOK = FALSE;
+ Handled = FALSE;
+ break;
+ default:
+ FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
+ return;
+ }
+ }
+ }
+
+ if (combineOK)
+ {
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE");
+
+ return;
+ }
+ }
+
+ /* After all the extensions, if still unhandled, report fixme */
+ FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
+}
+
+
+static void tex_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
+ const struct wined3d_device *device = context->swapchain->device;
+ BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
+ DWORD mapped_stage = device->texUnitMap[stage];
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ TRACE("Setting color op for stage %d\n", stage);
+
+ /* Using a pixel shader? Don't care for anything here, the shader applying does it */
+ if (use_ps(state)) return;
+
+ if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
+
+ if (mapped_stage != WINED3D_UNMAPPED_STAGE)
+ {
+ if (tex_used && mapped_stage >= gl_info->limits.textures)
+ {
+ FIXME("Attempt to enable unsupported stage!\n");
+ return;
+ }
+ context_active_texture(context, gl_info, mapped_stage);
+ }
+
+ if (stage >= state->lowest_disabled_stage)
+ {
+ TRACE("Stage disabled\n");
+ if (mapped_stage != WINED3D_UNMAPPED_STAGE)
+ {
+ /* Disable everything here */
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
+ checkGLcall("glDisable(GL_TEXTURE_2D)");
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
+ checkGLcall("glDisable(GL_TEXTURE_3D)");
+ if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+ checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
+ }
+ if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
+ checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
+ }
+ }
+ /* All done */
+ return;
+ }
+
+ /* The sampler will also activate the correct texture dimensions, so no
+ * need to do it here if the sampler for this stage is dirty. */
+ if (!isStateDirty(context, STATE_SAMPLER(stage)) && tex_used)
+ texture_activate_dimensions(state->textures[stage], gl_info);
+
+ set_tex_op(gl_info, state, FALSE, stage,
+ state->texture_states[stage][WINED3D_TSS_COLOR_OP],
+ state->texture_states[stage][WINED3D_TSS_COLOR_ARG1],
+ state->texture_states[stage][WINED3D_TSS_COLOR_ARG2],
+ state->texture_states[stage][WINED3D_TSS_COLOR_ARG0]);
+}
+
+void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
+ const struct wined3d_device *device = context->swapchain->device;
+ BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
+ DWORD mapped_stage = device->texUnitMap[stage];
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ DWORD op, arg1, arg2, arg0;
+
+ TRACE("Setting alpha op for stage %d\n", stage);
+ /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */
+ if (mapped_stage != WINED3D_UNMAPPED_STAGE)
+ {
+ if (tex_used && mapped_stage >= gl_info->limits.textures)
+ {
+ FIXME("Attempt to enable unsupported stage!\n");
+ return;
+ }
+ context_active_texture(context, gl_info, mapped_stage);
+ }
+
+ op = state->texture_states[stage][WINED3D_TSS_ALPHA_OP];
+ arg1 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG1];
+ arg2 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG2];
+ arg0 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG0];
+
+ if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !stage && state->textures[0])
+ {
+ struct wined3d_texture *texture = state->textures[0];
+ GLenum texture_dimensions = texture->target;
+
+ if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
+ {
+ struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
+
+ if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_size)
+ {
+ /* Color keying needs to pass alpha values from the texture through to have the alpha test work
+ * properly. On the other hand applications can still use texture combiners apparently. This code
+ * takes care that apps cannot remove the texture's alpha channel entirely.
+ *
+ * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires
+ * D3DTOP_MODULATE to work on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures
+ * and alpha component of diffuse color to draw things like translucent text and perform other
+ * blending effects.
+ *
+ * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To
+ * provide the behavior expected by the game, while emulating the colorkey, diffuse alpha must be
+ * modulated with texture alpha. OTOH, Moto racer 2 at some points sets alphaop/alphaarg to
+ * SELECTARG/CURRENT, yet puts garbage in diffuse alpha (zeroes). This works on native, because the
+ * game disables alpha test and alpha blending. Alpha test is overwritten by wine's for purposes of
+ * color-keying though, so this will lead to missing geometry if texture alpha is modulated (pixels
+ * fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha
+ * blending, it can be expected to provide meaningful values in diffuse alpha, so it should be
+ * modulated with texture alpha; otherwise, selecting diffuse alpha is ignored in favour of texture
+ * alpha.
+ *
+ * What to do with multitexturing? So far no app has been found that uses color keying with
+ * multitexturing */
+ if (op == WINED3D_TOP_DISABLE)
+ {
+ arg1 = WINED3DTA_TEXTURE;
+ op = WINED3D_TOP_SELECT_ARG1;
+ }
+ else if (op == WINED3D_TOP_SELECT_ARG1 && arg1 != WINED3DTA_TEXTURE)
+ {
+ if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
+ {
+ arg2 = WINED3DTA_TEXTURE;
+ op = WINED3D_TOP_MODULATE;
+ }
+ else arg1 = WINED3DTA_TEXTURE;
+ }
+ else if (op == WINED3D_TOP_SELECT_ARG2 && arg2 != WINED3DTA_TEXTURE)
+ {
+ if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
+ {
+ arg1 = WINED3DTA_TEXTURE;
+ op = WINED3D_TOP_MODULATE;
+ }
+ else arg2 = WINED3DTA_TEXTURE;
+ }
+ }
+ }
+ }
+
+ /* tex_alphaop is shared between the ffp and nvrc because the difference only comes down to
+ * this if block here, and the other code(color keying, texture unit selection) are the same
+ */
+ TRACE("Setting alpha op for stage %d\n", stage);
+ if (gl_info->supported[NV_REGISTER_COMBINERS])
+ {
+ set_tex_op_nvrc(gl_info, state, TRUE, stage, op, arg1, arg2, arg0,
+ mapped_stage, state->texture_states[stage][WINED3D_TSS_RESULT_ARG]);
+ }
+ else
+ {
+ set_tex_op(gl_info, state, TRUE, stage, op, arg1, arg2, arg0);
+ }
+}
+
+void transform_texture(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ DWORD texUnit = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
+ const struct wined3d_device *device = context->swapchain->device;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ DWORD mapped_stage = device->texUnitMap[texUnit];
+ BOOL generated;
+ int coordIdx;
+
+ /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
+ if (use_vs(state) || isStateDirty(context, STATE_VDECL))
+ {
+ TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
+ return;
+ }
+
+ if (mapped_stage == WINED3D_UNMAPPED_STAGE) return;
+ if (mapped_stage >= gl_info->limits.textures) return;
+
+ context_active_texture(context, gl_info, mapped_stage);
+ generated = (state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU;
+ coordIdx = min(state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX & 0x0000ffff], MAX_TEXTURES - 1);
+
+ set_texture_matrix(gl_info, &state->transforms[WINED3D_TS_TEXTURE0 + texUnit].u.m[0][0],
+ state->texture_states[texUnit][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS],
+ generated, context->last_was_rhw,
+ device->stream_info.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))
+ ? device->stream_info.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format->id
+ : WINED3DFMT_UNKNOWN,
+ device->shader_backend->shader_has_ffp_proj_control(device->shader_priv));
+
+ /* The sampler applying function calls us if this changes */
+ if ((context->lastWasPow2Texture & (1 << texUnit)) && state->textures[texUnit])
+ {
+ if(generated) {
+ FIXME("Non-power2 texture being used with generated texture coords\n");
+ }
+ /* NP2 texcoord fixup is implemented for pixelshaders so only enable the
+ fixed-function-pipeline fixup via pow2Matrix when no PS is used. */
+ if (!use_ps(state))
+ {
+ TRACE("Non power two matrix multiply fixup\n");
+ gl_info->gl_ops.gl.p_glMultMatrixf(state->textures[texUnit]->pow2_matrix);
+ }
+ }
+}
+
+static void unload_tex_coords(const struct wined3d_gl_info *gl_info)
+{
+ unsigned int texture_idx;
+
+ for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx)
+ {
+ GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
+ gl_info->gl_ops.gl.p_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+}
+
+static void load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si,
+ GLuint *curVBO, const struct wined3d_state *state)
+{
+ const struct wined3d_device *device = context->swapchain->device;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ unsigned int mapped_stage = 0;
+ unsigned int textureNo = 0;
+
+ for (textureNo = 0; textureNo < context->d3d_info->limits.ffp_blend_stages; ++textureNo)
+ {
+ int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX];
+
+ mapped_stage = device->texUnitMap[textureNo];
+ if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue;
+
+ if (mapped_stage >= gl_info->limits.texture_coords)
+ {
+ FIXME("Attempted to load unsupported texture coordinate %u\n", mapped_stage);
+ continue;
+ }
+
+ if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
+ {
+ const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
+
+ TRACE("Setting up texture %u, idx %d, coordindx %u, data {%#x:%p}.\n",
+ textureNo, mapped_stage, coordIdx, e->data.buffer_object, e->data.addr);
+
+ if (*curVBO != e->data.buffer_object)
+ {
+ GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
+ checkGLcall("glBindBufferARB");
+ *curVBO = e->data.buffer_object;
+ }
+
+ GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
+ checkGLcall("glClientActiveTextureARB");
+
+ /* The coords to supply depend completely on the fvf / vertex shader */
+ gl_info->gl_ops.gl.p_glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
+ e->data.addr + state->load_base_vertex_index * e->stride);
+ gl_info->gl_ops.gl.p_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+ else
+ {
+ GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
+ }
+ }
+ if (gl_info->supported[NV_REGISTER_COMBINERS])
+ {
+ /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */
+ for (textureNo = mapped_stage + 1; textureNo < gl_info->limits.textures; ++textureNo)
+ {
+ GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
+ }
+ }
+
+ checkGLcall("loadTexCoords");
+}
+
+static void tex_coordindex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
+ const struct wined3d_device *device = context->swapchain->device;
+ static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f };
+ static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f };
+ static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f };
+ static const GLfloat q_plane[] = { 0.0f, 0.0f, 0.0f, 1.0f };
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ DWORD mapped_stage = device->texUnitMap[stage];
+
+ if (mapped_stage == WINED3D_UNMAPPED_STAGE)
+ {
+ TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
+ return;
+ }
+
+ if (mapped_stage >= gl_info->limits.fragment_samplers)
+ {
+ WARN("stage %u not mapped to a valid texture unit (%u)\n", stage, mapped_stage);
+ return;
+ }
+ context_active_texture(context, gl_info, mapped_stage);
+
+ /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
+ *
+ * FIXME: When using generated texture coordinates, the index value is used to specify the wrapping mode.
+ * eg. SetTextureStageState( 0, WINED3D_TSS_TEXCOORDINDEX, WINED3D_TSS_TCI_CAMERASPACEPOSITION | 1 );
+ * means use the vertex position (camera-space) as the input texture coordinates
+ * for this texture stage, and the wrap mode set in the WINED3D_RS_WRAP1 render
+ * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
+ * to the TEXCOORDINDEX value
+ */
+ switch (state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000)
+ {
+ case WINED3DTSS_TCI_PASSTHRU:
+ /* Use the specified texture coordinates contained within the
+ * vertex format. This value resolves to zero. */
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_S);
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_T);
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_Q);
+ checkGLcall("WINED3DTSS_TCI_PASSTHRU - Disable texgen.");
+ break;
+
+ case WINED3DTSS_TCI_CAMERASPACEPOSITION:
+ /* CameraSpacePosition means use the vertex position, transformed to camera space,
+ * as the input texture coordinates for this stage's texture transformation. This
+ * equates roughly to EYE_LINEAR */
+
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
+ gl_info->gl_ops.gl.p_glPushMatrix();
+ gl_info->gl_ops.gl.p_glLoadIdentity();
+ gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
+ gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
+ gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
+ gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
+ gl_info->gl_ops.gl.p_glPopMatrix();
+ checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane.");
+
+ gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+ gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+ gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+ checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set texgen mode.");
+
+ gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
+ gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
+ gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
+ checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Enable texgen.");
+
+ break;
+
+ case WINED3DTSS_TCI_CAMERASPACENORMAL:
+ /* Note that NV_TEXGEN_REFLECTION support is implied when
+ * ARB_TEXTURE_CUBE_MAP is supported */
+ if (!gl_info->supported[NV_TEXGEN_REFLECTION])
+ {
+ FIXME("WINED3DTSS_TCI_CAMERASPACENORMAL not supported.\n");
+ break;
+ }
+
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
+ gl_info->gl_ops.gl.p_glPushMatrix();
+ gl_info->gl_ops.gl.p_glLoadIdentity();
+ gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
+ gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
+ gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
+ gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
+ gl_info->gl_ops.gl.p_glPopMatrix();
+ checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane.");
+
+ gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
+ gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
+ gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
+ checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set texgen mode.");
+
+ gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
+ gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
+ gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
+ checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Enable texgen.");
+
+ break;
+
+ case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
+ /* Note that NV_TEXGEN_REFLECTION support is implied when
+ * ARB_TEXTURE_CUBE_MAP is supported */
+ if (!gl_info->supported[NV_TEXGEN_REFLECTION])
+ {
+ FIXME("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR not supported.\n");
+ break;
+ }
+
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
+ gl_info->gl_ops.gl.p_glPushMatrix();
+ gl_info->gl_ops.gl.p_glLoadIdentity();
+ gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
+ gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
+ gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
+ gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
+ gl_info->gl_ops.gl.p_glPopMatrix();
+ checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane.");
+
+ gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
+ gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
+ gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
+ checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set texgen mode.");
+
+ gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
+ gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
+ gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
+ checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Enable texgen.");
+
+ break;
+
+ case WINED3DTSS_TCI_SPHEREMAP:
+ gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+ gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+ checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Set texgen mode.");
+
+ gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
+ gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
+ checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Enable texgen.");
+
+ break;
+
+ default:
+ FIXME("Unhandled WINED3D_TSS_TEXCOORD_INDEX %#x.\n",
+ state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX]);
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_S);
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_T);
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_Q);
+ checkGLcall("Disable texgen.");
+
+ break;
+ }
+
+ /* Update the texture matrix. */
+ if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + stage)))
+ transform_texture(context, state, STATE_TEXTURESTAGE(stage, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
+
+ if (!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded)
+ {
+ /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
+ * source. Call loadTexCoords directly because there is no need to reparse the vertex declaration
+ * and do all the things linked to it
+ * TODO: Tidy that up to reload only the arrays of the changed unit
+ */
+ GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
+
+ unload_tex_coords(gl_info);
+ load_tex_coords(context, &device->stream_info, &curVBO, state);
+ }
+}
+
+static void tex_bumpenvlscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
+ const struct wined3d_shader *ps = state->pixel_shader;
+
+ /* The pixel shader has to know the luminance scale. Do a constants update. */
+ if (ps && stage && (ps->reg_maps.luminanceparams & (1 << stage)))
+ context->load_constants = 1;
+}
+
+void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const DWORD sampler = state_id - STATE_SAMPLER(0);
+ const struct wined3d_texture *texture = state->textures[sampler];
+
+ TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
+
+ if(!texture) return;
+ /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
+ * wined3d_texture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the
+ * scaling is reapplied or removed, the texture matrix has to be reapplied
+ *
+ * The mapped stage is already active because the sampler() function below, which is part of the
+ * misc pipeline
+ */
+ if (sampler < MAX_TEXTURES)
+ {
+ const BOOL texIsPow2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT);
+
+ if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler)))
+ {
+ const struct wined3d_device *device = context->swapchain->device;
+
+ if (texIsPow2)
+ context->lastWasPow2Texture |= 1 << sampler;
+ else
+ context->lastWasPow2Texture &= ~(1 << sampler);
+
+ transform_texture(context, state,
+ STATE_TEXTURESTAGE(device->texUnitMap[sampler], WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
+ }
+ }
+}
+
+static void sampler(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_device *device = context->swapchain->device;
+ DWORD sampler = state_id - STATE_SAMPLER(0);
+ DWORD mapped_stage = device->texUnitMap[sampler];
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ union {
+ float f;
+ DWORD d;
+ } tmpvalue;
+
+ TRACE("Sampler: %d\n", sampler);
+ /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
+ * only has to bind textures and set the per texture states
+ */
+
+ if (mapped_stage == WINED3D_UNMAPPED_STAGE)
+ {
+ TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
+ return;
+ }
+
+ if (mapped_stage >= gl_info->limits.combined_samplers)
+ {
+ return;
+ }
+ context_active_texture(context, gl_info, mapped_stage);
+
+ if (state->textures[sampler])
+ {
+ struct wined3d_texture *texture = state->textures[sampler];
+ BOOL srgb = state->sampler_states[sampler][WINED3D_SAMP_SRGB_TEXTURE];
+
+ texture->texture_ops->texture_bind(texture, context, srgb);
+ wined3d_texture_apply_state_changes(texture, state->sampler_states[sampler], gl_info);
+
+ if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
+ {
+ tmpvalue.d = state->sampler_states[sampler][WINED3D_SAMP_MIPMAP_LOD_BIAS];
+ gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
+ GL_TEXTURE_LOD_BIAS_EXT, tmpvalue.f);
+ checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)");
+ }
+
+ if (!use_ps(state) && sampler < state->lowest_disabled_stage)
+ {
+ if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
+ {
+ /* If color keying is enabled update the alpha test, it
+ * depends on the existence of a color key in stage 0. */
+ state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
+ }
+ }
+
+ /* Trigger shader constant reloading (for NP2 texcoord fixup) */
+ if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
+ device->shader_backend->shader_load_np2fixup_constants(device->shader_priv, gl_info, state);
+ }
+ else
+ {
+ if (sampler < state->lowest_disabled_stage)
+ {
+ /* TODO: What should I do with pixel shaders here ??? */
+ if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
+ {
+ /* If color keying is enabled update the alpha test, it
+ * depends on the existence of a color key in stage 0. */
+ state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
+ }
+ } /* Otherwise tex_colorop disables the stage */
+ context_bind_texture(context, GL_NONE, 0);
+ }
+}
+
+void apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ unsigned int i;
+
+ if (use_ps(state))
+ {
+ if (!context->last_was_pshader)
+ {
+ /* Former draw without a pixel shader, some samplers may be
+ * disabled because of WINED3D_TSS_COLOR_OP = WINED3DTOP_DISABLE
+ * make sure to enable them. */
+ for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
+ {
+ if (!isStateDirty(context, STATE_SAMPLER(i)))
+ sampler(context, state, STATE_SAMPLER(i));
+ }
+ context->last_was_pshader = TRUE;
+ }
+ else
+ {
+ /* Otherwise all samplers were activated by the code above in
+ * earlier draws, or by sampler() if a different texture was
+ * bound. I don't have to do anything. */
+ }
+ }
+ else
+ {
+ /* Disabled the pixel shader - color ops weren't applied while it was
+ * enabled, so re-apply them. */
+ for (i = 0; i < context->d3d_info->limits.ffp_blend_stages; ++i)
+ {
+ if (!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP)))
+ context_apply_state(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP));
+ }
+ context->last_was_pshader = FALSE;
+ }
+
+ context->select_shader = 1;
+ context->load_constants = 1;
+}
+
+static void state_geometry_shader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ context->select_shader = 1;
+}
+
+static void shader_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
+ const struct wined3d_shader *ps = state->pixel_shader;
+
+ /* The pixel shader has to know the bump env matrix. Do a constants update. */
+ if (ps && stage && (ps->reg_maps.bumpmat & (1 << stage)))
+ context->load_constants = 1;
+}
+
+void transform_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ /* This function is called by transform_view below if the view matrix was changed too
+ *
+ * Deliberately no check if the vertex declaration is dirty because the vdecl state
+ * does not always update the world matrix, only on a switch between transformed
+ * and untransformed draws. It *may* happen that the world matrix is set 2 times during one
+ * draw, but that should be rather rare and cheaper in total.
+ */
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
+ checkGLcall("glMatrixMode");
+
+ if (context->last_was_rhw)
+ {
+ gl_info->gl_ops.gl.p_glLoadIdentity();
+ checkGLcall("glLoadIdentity()");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
+ checkGLcall("glLoadMatrixf");
+ gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
+ checkGLcall("glMultMatrixf");
+ }
+}
+
+void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ UINT index = state_id - STATE_CLIPPLANE(0);
+ GLdouble plane[4];
+
+ if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)) || index >= gl_info->limits.clipplanes)
+ return;
+
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
+ gl_info->gl_ops.gl.p_glPushMatrix();
+
+ /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
+ if (!use_vs(state))
+ gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
+ else
+ /* With vertex shaders, clip planes are not transformed in Direct3D,
+ * while in OpenGL they are still transformed by the model view matix. */
+ gl_info->gl_ops.gl.p_glLoadIdentity();
+
+ plane[0] = state->clip_planes[index].x;
+ plane[1] = state->clip_planes[index].y;
+ plane[2] = state->clip_planes[index].z;
+ plane[3] = state->clip_planes[index].w;
+
+ TRACE("Clipplane [%.8e, %.8e, %.8e, %.8e]\n",
+ plane[0], plane[1], plane[2], plane[3]);
+ gl_info->gl_ops.gl.p_glClipPlane(GL_CLIP_PLANE0 + index, plane);
+ checkGLcall("glClipPlane");
+
+ gl_info->gl_ops.gl.p_glPopMatrix();
+}
+
+static void transform_worldex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ UINT matrix = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0));
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ GLenum glMat;
+
+ TRACE("Setting world matrix %d\n", matrix);
+
+ if (matrix >= gl_info->limits.blends)
+ {
+ WARN("Unsupported blend matrix set\n");
+ return;
+ }
+
+ if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
+ return;
+
+ /* GL_MODELVIEW0_ARB: 0x1700
+ * GL_MODELVIEW1_ARB: 0x850a
+ * GL_MODELVIEW2_ARB: 0x8722
+ * GL_MODELVIEW3_ARB: 0x8723
+ * etc
+ * GL_MODELVIEW31_ARB: 0x873f
+ */
+ if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
+ else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
+
+ gl_info->gl_ops.gl.p_glMatrixMode(glMat);
+ checkGLcall("glMatrixMode(glMat)");
+
+ /* World matrix 0 is multiplied with the view matrix because d3d uses 3
+ * matrices while gl uses only 2. To avoid weighting the view matrix
+ * incorrectly it has to be multiplied into every GL modelview matrix. */
+ gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
+ checkGLcall("glLoadMatrixf");
+ gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
+ checkGLcall("glMultMatrixf");
+}
+
+static void state_vertexblend_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ enum wined3d_vertex_blend_flags f = state->render_states[WINED3D_RS_VERTEXBLEND];
+ static unsigned int once;
+
+ if (f == WINED3D_VBF_DISABLE)
+ return;
+
+ if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f);
+ else WARN("Vertex blend flags %#x not supported.\n", f);
+}
+
+static void state_vertexblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ enum wined3d_vertex_blend_flags val = state->render_states[WINED3D_RS_VERTEXBLEND];
+ struct wined3d_device *device = context->swapchain->device;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ static unsigned int once;
+
+ switch (val)
+ {
+ case WINED3D_VBF_1WEIGHTS:
+ case WINED3D_VBF_2WEIGHTS:
+ case WINED3D_VBF_3WEIGHTS:
+ gl_info->gl_ops.gl.p_glEnable(GL_VERTEX_BLEND_ARB);
+ checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
+
+ /* D3D adds one more matrix which has weight (1 - sum(weights)).
+ * This is enabled at context creation with enabling
+ * GL_WEIGHT_SUM_UNITY_ARB. */
+ GL_EXTCALL(glVertexBlendARB(state->render_states[WINED3D_RS_VERTEXBLEND] + 1));
+
+ if (!device->vertexBlendUsed)
+ {
+ unsigned int i;
+ for (i = 1; i < gl_info->limits.blends; ++i)
+ {
+ if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i))))
+ transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i)));
+ }
+ device->vertexBlendUsed = TRUE;
+ }
+ break;
+
+ case WINED3D_VBF_TWEENING:
+ case WINED3D_VBF_0WEIGHTS: /* Indexed vertex blending, not supported. */
+ if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val);
+ else WARN("Vertex blend flags %#x not supported.\n", val);
+ /* Fall through. */
+ case WINED3D_VBF_DISABLE:
+ gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_BLEND_ARB);
+ checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
+ break;
+ }
+}
+
+void transform_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const struct wined3d_light_info *light = NULL;
+ unsigned int k;
+
+ /* If we are changing the View matrix, reset the light and clipping planes to the new view
+ * NOTE: We have to reset the positions even if the light/plane is not currently
+ * enabled, since the call to enable it will not reset the position.
+ * NOTE2: Apparently texture transforms do NOT need reapplying
+ */
+
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
+ checkGLcall("glMatrixMode(GL_MODELVIEW)");
+ gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
+ checkGLcall("glLoadMatrixf(...)");
+
+ /* Reset lights. TODO: Call light apply func */
+ for (k = 0; k < gl_info->limits.lights; ++k)
+ {
+ if (!(light = state->lights[k]))
+ continue;
+ gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
+ checkGLcall("glLightfv posn");
+ gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
+ checkGLcall("glLightfv dirn");
+ }
+
+ /* Reset Clipping Planes */
+ for (k = 0; k < gl_info->limits.clipplanes; ++k)
+ {
+ if (!isStateDirty(context, STATE_CLIPPLANE(k)))
+ clipplane(context, state, STATE_CLIPPLANE(k));
+ }
+
+ if (context->last_was_rhw)
+ {
+ gl_info->gl_ops.gl.p_glLoadIdentity();
+ checkGLcall("glLoadIdentity()");
+ /* No need to update the world matrix, the identity is fine */
+ return;
+ }
+
+ /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
+ * No need to do it here if the state is scheduled for update. */
+ if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
+ transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
+
+ /* Avoid looping over a number of matrices if the app never used the functionality */
+ if (context->swapchain->device->vertexBlendUsed)
+ {
+ for (k = 1; k < gl_info->limits.blends; ++k)
+ {
+ if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k))))
+ transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k)));
+ }
+ }
+}
+
+void transform_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
+ checkGLcall("glMatrixMode(GL_PROJECTION)");
+
+ /* There are a couple of additional things we have to take into account
+ * here besides the projection transformation itself:
+ * - We need to flip along the y-axis in case of offscreen rendering.
+ * - OpenGL Z range is {-Wc,...,Wc} while D3D Z range is {0,...,Wc}.
+ * - D3D coordinates refer to pixel centers while GL coordinates refer
+ * to pixel corners.
+ * - D3D has a top-left filling convention. We need to maintain this
+ * even after the y-flip mentioned above.
+ * In order to handle the last two points, we translate by
+ * (63.0 / 128.0) / VPw and (63.0 / 128.0) / VPh. This is equivalent to
+ * translating slightly less than half a pixel. We want the difference to
+ * be large enough that it doesn't get lost due to rounding inside the
+ * driver, but small enough to prevent it from interfering with any
+ * anti-aliasing. */
+
+ if (context->last_was_rhw)
+ {
+ /* Transform D3D RHW coordinates to OpenGL clip coordinates. */
+ double x = state->viewport.x;
+ double y = state->viewport.y;
+ double w = state->viewport.width;
+ double h = state->viewport.height;
+ double x_scale = 2.0 / w;
+ double x_offset = ((63.0 / 64.0) - (2.0 * x) - w) / w;
+ double y_scale = context->render_offscreen ? 2.0 / h : 2.0 / -h;
+ double y_offset = context->render_offscreen
+ ? ((63.0 / 64.0) - (2.0 * y) - h) / h
+ : ((63.0 / 64.0) - (2.0 * y) - h) / -h;
+ const GLdouble projection[] =
+ {
+ x_scale, 0.0, 0.0, 0.0,
+ 0.0, y_scale, 0.0, 0.0,
+ 0.0, 0.0, 2.0, 0.0,
+ x_offset, y_offset, -1.0, 1.0,
+ };
+
+ gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
+ checkGLcall("glLoadMatrixd");
+ }
+ else
+ {
+ double y_scale = context->render_offscreen ? -1.0 : 1.0;
+ double x_offset = (63.0 / 64.0) / state->viewport.width;
+ double y_offset = context->render_offscreen
+ ? (63.0 / 64.0) / state->viewport.height
+ : -(63.0 / 64.0) / state->viewport.height;
+ const GLdouble projection[] =
+ {
+ 1.0, 0.0, 0.0, 0.0,
+ 0.0, y_scale, 0.0, 0.0,
+ 0.0, 0.0, 2.0, 0.0,
+ x_offset, y_offset, -1.0, 1.0,
+ };
+
+ gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
+ checkGLcall("glLoadMatrixd");
+
+ gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_PROJECTION].u.m[0][0]);
+ checkGLcall("glLoadMatrixf");
+ }
+}
+
+/* This should match any arrays loaded in load_vertex_data.
+ * TODO: Only load / unload arrays if we have to. */
+static void unload_vertex_data(const struct wined3d_gl_info *gl_info)
+{
+ gl_info->gl_ops.gl.p_glDisableClientState(GL_VERTEX_ARRAY);
+ gl_info->gl_ops.gl.p_glDisableClientState(GL_NORMAL_ARRAY);
+ gl_info->gl_ops.gl.p_glDisableClientState(GL_COLOR_ARRAY);
+ if (gl_info->supported[EXT_SECONDARY_COLOR])
+ gl_info->gl_ops.gl.p_glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
+ if (gl_info->supported[ARB_VERTEX_BLEND])
+ gl_info->gl_ops.gl.p_glDisableClientState(GL_WEIGHT_ARRAY_ARB);
+ unload_tex_coords(gl_info);
+}
+
+static inline void unload_numbered_array(struct wined3d_context *context, int i)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ GL_EXTCALL(glDisableVertexAttribArrayARB(i));
+ checkGLcall("glDisableVertexAttribArrayARB(reg)");
+ if (gl_info->supported[ARB_INSTANCED_ARRAYS])
+ GL_EXTCALL(glVertexAttribDivisorARB(i, 0));
+
+ context->numbered_array_mask &= ~(1 << i);
+}
+
+/* This should match any arrays loaded in loadNumberedArrays
+ * TODO: Only load / unload arrays if we have to. */
+static void unload_numbered_arrays(struct wined3d_context *context)
+{
+ /* disable any attribs (this is the same for both GLSL and ARB modes) */
+ int i;
+
+ for (i = 0; i < context->gl_info->limits.vertex_attribs; ++i) {
+ unload_numbered_array(context, i);
+ }
+}
+
+static void load_numbered_arrays(struct wined3d_context *context,
+ const struct wined3d_stream_info *stream_info, const struct wined3d_state *state)
+{
+ struct wined3d_device *device = context->swapchain->device;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
+ int i;
+
+ /* Default to no instancing */
+ device->instance_count = 0;
+
+ for (i = 0; i < MAX_ATTRIBS; i++)
+ {
+ const struct wined3d_stream_state *stream;
+
+ if (!(stream_info->use_map & (1 << i)))
+ {
+#ifdef VBOX_WITH_WINE_FIX_ZEROVERTATTR
+ if (i == 0)
+ {
+ GLfloat af[4] = {0., 0., 0., 0.,};
+# ifdef DEBUG_misha
+ ERR("Test it!\n");
+# endif
+ Assert(device->czvDrawVertices);
+ zv_bind(context, GL_FLOAT, device->czvDrawVertices, 4, GL_FALSE, af);
+# ifdef VBOX_WITH_WINE_FIX_CURVBO
+ /* we need to invalidate the curVBO state, since buffer_get_sysmem maay change the current buffer */
+ curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
+# endif
+ }
+ else
+#endif
+ {
+
+ if (context->numbered_array_mask & (1 << i))
+ unload_numbered_array(context, i);
+ if (state->vertex_shader->reg_maps.input_registers & (1 << i))
+ GL_EXTCALL(glVertexAttrib4fARB(i, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ }
+
+ continue;
+ }
+
+ stream = &state->streams[stream_info->elements[i].stream_idx];
+
+ if (stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
+ {
+ if (!device->instance_count)
+ device->instance_count = state->streams[0].frequency ? state->streams[0].frequency : 1;
+
+ if (!gl_info->supported[ARB_INSTANCED_ARRAYS])
+ {
+ /* Unload instanced arrays, they will be loaded using
+ * immediate mode instead. */
+ if (context->numbered_array_mask & (1 << i))
+ unload_numbered_array(context, i);
+ continue;
+ }
+
+ GL_EXTCALL(glVertexAttribDivisorARB(i, 1));
+ }
+ else if (gl_info->supported[ARB_INSTANCED_ARRAYS])
+ {
+ GL_EXTCALL(glVertexAttribDivisorARB(i, 0));
+ }
+
+ TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].data.buffer_object);
+
+ if (stream_info->elements[i].stride)
+ {
+ if (curVBO != stream_info->elements[i].data.buffer_object)
+ {
+ GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, stream_info->elements[i].data.buffer_object));
+ checkGLcall("glBindBufferARB");
+ curVBO = stream_info->elements[i].data.buffer_object;
+ }
+ /* Use the VBO to find out if a vertex buffer exists, not the vb
+ * pointer. vb can point to a user pointer data blob. In that case
+ * curVBO will be 0. If there is a vertex buffer but no vbo we
+ * won't be load converted attributes anyway. */
+ GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
+ stream_info->elements[i].format->gl_vtx_type,
+ stream_info->elements[i].format->gl_normalized,
+ stream_info->elements[i].stride, stream_info->elements[i].data.addr
+ + state->load_base_vertex_index * stream_info->elements[i].stride));
+
+ if (!(context->numbered_array_mask & (1 << i)))
+ {
+ GL_EXTCALL(glEnableVertexAttribArrayARB(i));
+ context->numbered_array_mask |= (1 << i);
+ }
+ }
+ else
+ {
+ /* Stride = 0 means always the same values.
+ * glVertexAttribPointerARB doesn't do that. Instead disable the
+ * pointer and set up the attribute statically. But we have to
+ * figure out the system memory address. */
+ const BYTE *ptr = stream_info->elements[i].data.addr;
+ if (stream_info->elements[i].data.buffer_object)
+ {
+ ptr += (ULONG_PTR)buffer_get_sysmem(stream->buffer, gl_info);
+#ifdef VBOX_WITH_WINE_FIX_CURVBO
+ /* we need to invalidate the curVBO state, since buffer_get_sysmem maay change the current buffer */
+ curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
+#endif
+ }
+
+#ifdef VBOX_WITH_WINE_FIX_ZEROVERTATTR
+ if (i == 0)
+ {
+ Assert(device->czvDrawVertices);
+ zv_bind_by_element(context, &stream_info->elements[i], device->czvDrawVertices, ptr);
+# ifdef VBOX_WITH_WINE_FIX_CURVBO
+ /* we need to invalidate the curVBO state, since buffer_get_sysmem maay change the current buffer */
+ curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
+# endif
+ }
+ else
+#endif
+ {
+
+ if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
+
+ switch (stream_info->elements[i].format->id)
+ {
+ case WINED3DFMT_R32_FLOAT:
+ GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr));
+ break;
+ case WINED3DFMT_R32G32_FLOAT:
+ GL_EXTCALL(glVertexAttrib2fvARB(i, (const GLfloat *)ptr));
+ break;
+ case WINED3DFMT_R32G32B32_FLOAT:
+ GL_EXTCALL(glVertexAttrib3fvARB(i, (const GLfloat *)ptr));
+ break;
+ case WINED3DFMT_R32G32B32A32_FLOAT:
+ GL_EXTCALL(glVertexAttrib4fvARB(i, (const GLfloat *)ptr));
+ break;
+
+ case WINED3DFMT_R8G8B8A8_UINT:
+ GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
+ break;
+ case WINED3DFMT_B8G8R8A8_UNORM:
+ if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
+ {
+ const DWORD *src = (const DWORD *)ptr;
+ DWORD c = *src & 0xff00ff00;
+ c |= (*src & 0xff0000) >> 16;
+ c |= (*src & 0xff) << 16;
+ GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c));
+ break;
+ }
+ /* else fallthrough */
+ case WINED3DFMT_R8G8B8A8_UNORM:
+ GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
+ break;
+
+ case WINED3DFMT_R16G16_SINT:
+ GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
+ break;
+ case WINED3DFMT_R16G16B16A16_SINT:
+ GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
+ break;
+
+ case WINED3DFMT_R16G16_SNORM:
+ {
+ const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
+ GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
+ break;
+ }
+ case WINED3DFMT_R16G16_UNORM:
+ {
+ const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
+ GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
+ break;
+ }
+ case WINED3DFMT_R16G16B16A16_SNORM:
+ GL_EXTCALL(glVertexAttrib4NsvARB(i, (const GLshort *)ptr));
+ break;
+ case WINED3DFMT_R16G16B16A16_UNORM:
+ GL_EXTCALL(glVertexAttrib4NusvARB(i, (const GLushort *)ptr));
+ break;
+
+ case WINED3DFMT_R10G10B10A2_UINT:
+ FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
+ /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
+ break;
+ case WINED3DFMT_R10G10B10A2_SNORM:
+ FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
+ /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
+ break;
+
+ case WINED3DFMT_R16G16_FLOAT:
+ /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
+ * byte float according to the IEEE standard
+ */
+ FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
+ break;
+ case WINED3DFMT_R16G16B16A16_FLOAT:
+ FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
+ break;
+
+ default:
+ ERR("Unexpected declaration in stride 0 attributes\n");
+ break;
+
+ }
+
+ }
+ }
+ }
+ checkGLcall("Loading numbered arrays");
+}
+
+static void load_vertex_data(const struct wined3d_context *context,
+ const struct wined3d_stream_info *si, const struct wined3d_state *state)
+{
+ struct wined3d_device *device = context->swapchain->device;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
+ const struct wined3d_stream_info_element *e;
+
+ TRACE("Using fast vertex array code\n");
+
+ /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
+ device->instance_count = 0;
+
+ /* Blend Data ---------------------------------------------- */
+ if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT))
+ || si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
+ {
+ e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
+
+ if (gl_info->supported[ARB_VERTEX_BLEND])
+ {
+ TRACE("Blend %u %p %u\n", e->format->component_count,
+ e->data.addr + state->load_base_vertex_index * e->stride, e->stride);
+
+ gl_info->gl_ops.gl.p_glEnableClientState(GL_WEIGHT_ARRAY_ARB);
+ checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
+
+ GL_EXTCALL(glVertexBlendARB(e->format->component_count + 1));
+
+ if (curVBO != e->data.buffer_object)
+ {
+ GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
+ checkGLcall("glBindBufferARB");
+ curVBO = e->data.buffer_object;
+ }
+
+ TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n",
+ e->format->gl_vtx_format,
+ e->format->gl_vtx_type,
+ e->stride,
+ e->data.addr + state->load_base_vertex_index * e->stride);
+ GL_EXTCALL(glWeightPointerARB(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
+ e->data.addr + state->load_base_vertex_index * e->stride));
+
+ checkGLcall("glWeightPointerARB");
+
+ if (si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
+ {
+ static BOOL warned;
+ if (!warned)
+ {
+ FIXME("blendMatrixIndices support\n");
+ warned = TRUE;
+ }
+ }
+ } else {
+ /* TODO: support blends in drawStridedSlow
+ * No need to write a FIXME here, this is done after the general vertex decl decoding
+ */
+ WARN("unsupported blending in openGl\n");
+ }
+ }
+ else
+ {
+ if (gl_info->supported[ARB_VERTEX_BLEND])
+ {
+ static const GLbyte one = 1;
+ GL_EXTCALL(glWeightbvARB(1, &one));
+ checkGLcall("glWeightbvARB(gl_info->max_blends, weights)");
+ }
+ }
+
+ /* Point Size ----------------------------------------------*/
+ if (si->use_map & (1 << WINED3D_FFP_PSIZE))
+ {
+ /* no such functionality in the fixed function GL pipeline */
+ TRACE("Cannot change ptSize here in openGl\n");
+ /* TODO: Implement this function in using shaders if they are available */
+ }
+
+ /* Vertex Pointers -----------------------------------------*/
+ if (si->use_map & (1 << WINED3D_FFP_POSITION))
+ {
+ e = &si->elements[WINED3D_FFP_POSITION];
+
+ if (curVBO != e->data.buffer_object)
+ {
+ GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
+ checkGLcall("glBindBufferARB");
+ curVBO = e->data.buffer_object;
+ }
+
+ TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n",
+ e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
+ e->data.addr + state->load_base_vertex_index * e->stride);
+ gl_info->gl_ops.gl.p_glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
+ e->data.addr + state->load_base_vertex_index * e->stride);
+ checkGLcall("glVertexPointer(...)");
+ gl_info->gl_ops.gl.p_glEnableClientState(GL_VERTEX_ARRAY);
+ checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
+ }
+
+ /* Normals -------------------------------------------------*/
+ if (si->use_map & (1 << WINED3D_FFP_NORMAL))
+ {
+ e = &si->elements[WINED3D_FFP_NORMAL];
+
+ if (curVBO != e->data.buffer_object)
+ {
+ GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
+ checkGLcall("glBindBufferARB");
+ curVBO = e->data.buffer_object;
+ }
+
+ TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
+ e->data.addr + state->load_base_vertex_index * e->stride);
+ gl_info->gl_ops.gl.p_glNormalPointer(e->format->gl_vtx_type, e->stride,
+ e->data.addr + state->load_base_vertex_index * e->stride);
+ checkGLcall("glNormalPointer(...)");
+ gl_info->gl_ops.gl.p_glEnableClientState(GL_NORMAL_ARRAY);
+ checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
+
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glNormal3f(0, 0, 0);
+ checkGLcall("glNormal3f(0, 0, 0)");
+ }
+
+ /* Diffuse Colour --------------------------------------------*/
+ if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
+ {
+ e = &si->elements[WINED3D_FFP_DIFFUSE];
+
+ if (curVBO != e->data.buffer_object)
+ {
+ GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
+ checkGLcall("glBindBufferARB");
+ curVBO = e->data.buffer_object;
+ }
+
+ TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
+ e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
+ e->data.addr + state->load_base_vertex_index * e->stride);
+ gl_info->gl_ops.gl.p_glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
+ e->data.addr + state->load_base_vertex_index * e->stride);
+ checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
+ gl_info->gl_ops.gl.p_glEnableClientState(GL_COLOR_ARRAY);
+ checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
+
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+ checkGLcall("glColor4f(1, 1, 1, 1)");
+ }
+
+ /* Specular Colour ------------------------------------------*/
+ if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
+ {
+ TRACE("setting specular colour\n");
+
+ e = &si->elements[WINED3D_FFP_SPECULAR];
+
+ if (gl_info->supported[EXT_SECONDARY_COLOR])
+ {
+ GLenum type = e->format->gl_vtx_type;
+ GLint format = e->format->gl_vtx_format;
+
+ if (curVBO != e->data.buffer_object)
+ {
+ GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
+ checkGLcall("glBindBufferARB");
+ curVBO = e->data.buffer_object;
+ }
+
+ if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
+ {
+ /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
+ * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
+ * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
+ * 4 component secondary colors use it
+ */
+ TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
+ e->data.addr + state->load_base_vertex_index * e->stride);
+ GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
+ e->data.addr + state->load_base_vertex_index * e->stride));
+ checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
+ }
+ else
+ {
+ switch(type)
+ {
+ case GL_UNSIGNED_BYTE:
+ TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
+ e->data.addr + state->load_base_vertex_index * e->stride);
+ GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
+ e->data.addr + state->load_base_vertex_index * e->stride));
+ checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
+ break;
+
+ default:
+ FIXME("Add 4 component specular color pointers for type %x\n", type);
+ /* Make sure that the right color component is dropped */
+ TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
+ e->data.addr + state->load_base_vertex_index * e->stride);
+ GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
+ e->data.addr + state->load_base_vertex_index * e->stride));
+ checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
+ }
+ }
+ gl_info->gl_ops.gl.p_glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
+ checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
+ }
+ else
+ {
+ WARN("Specular colour is not supported in this GL implementation.\n");
+ }
+ }
+ else
+ {
+ if (gl_info->supported[EXT_SECONDARY_COLOR])
+ {
+ GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
+ checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
+ }
+ else
+ {
+ WARN("Specular colour is not supported in this GL implementation.\n");
+ }
+ }
+
+ /* Texture coords -------------------------------------------*/
+ load_tex_coords(context, si, &curVBO, state);
+}
+
+static void streamsrc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_device *device = context->swapchain->device;
+ BOOL load_numbered = use_vs(state) && !device->useDrawStridedSlow;
+ BOOL load_named = !use_vs(state) && !device->useDrawStridedSlow;
+
+ if (isStateDirty(context, STATE_VDECL)) return;
+ if (context->numberedArraysLoaded && !load_numbered)
+ {
+ unload_numbered_arrays(context);
+ context->numberedArraysLoaded = FALSE;
+ context->numbered_array_mask = 0;
+ }
+ else if (context->namedArraysLoaded)
+ {
+ unload_vertex_data(context->gl_info);
+ context->namedArraysLoaded = FALSE;
+ }
+
+ if (load_numbered)
+ {
+ TRACE("Loading numbered arrays\n");
+ load_numbered_arrays(context, &device->stream_info, state);
+ context->numberedArraysLoaded = TRUE;
+ }
+ else if (load_named)
+ {
+ TRACE("Loading vertex data\n");
+ load_vertex_data(context, &device->stream_info, state);
+ context->namedArraysLoaded = TRUE;
+ }
+}
+
+static void vdecl_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (isStateDirty(context, STATE_STREAMSRC))
+ return;
+ streamsrc(context, state, STATE_STREAMSRC);
+}
+
+void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_device *device = context->swapchain->device;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ BOOL useVertexShaderFunction = use_vs(state);
+ BOOL updateFog = FALSE;
+ BOOL transformed;
+ BOOL wasrhw = context->last_was_rhw;
+ unsigned int i;
+
+ transformed = device->stream_info.position_transformed;
+ if (transformed != context->last_was_rhw && !useVertexShaderFunction)
+ updateFog = TRUE;
+
+ context->last_was_rhw = transformed;
+
+ /* Don't have to apply the matrices when vertex shaders are used. When
+ * vshaders are turned off this function will be called again anyway to
+ * make sure they're properly set. */
+ if (!useVertexShaderFunction)
+ {
+ /* TODO: Move this mainly to the viewport state and only apply when
+ * the vp has changed or transformed / untransformed was switched. */
+ if (wasrhw != context->last_was_rhw
+ && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION))
+ && !isStateDirty(context, STATE_VIEWPORT))
+ transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
+ /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
+ * mode.
+ *
+ * If a vertex shader is used, the world matrix changed and then vertex shader unbound
+ * this check will fail and the matrix not applied again. This is OK because a simple
+ * world matrix change reapplies the matrix - These checks here are only to satisfy the
+ * needs of the vertex declaration.
+ *
+ * World and view matrix go into the same gl matrix, so only apply them when neither is
+ * dirty
+ */
+ if (transformed != wasrhw && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)))
+ && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
+ transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
+ if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_COLORVERTEX)))
+ context_apply_state(context, state, STATE_RENDER(WINED3D_RS_COLORVERTEX));
+ if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_LIGHTING)))
+ state_lighting(context, state, STATE_RENDER(WINED3D_RS_LIGHTING));
+
+ if (context->last_was_vshader)
+ {
+ updateFog = TRUE;
+
+ if (!context->d3d_info->vs_clipping
+ && !isStateDirty(context, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE)))
+ {
+ state_clipping(context, state, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE));
+ }
+
+ for (i = 0; i < gl_info->limits.clipplanes; ++i)
+ {
+ clipplane(context, state, STATE_CLIPPLANE(i));
+ }
+ }
+ if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS)))
+ state_normalize(context, state, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS));
+ }
+ else
+ {
+ if(!context->last_was_vshader) {
+ static BOOL warned = FALSE;
+ if (!context->d3d_info->vs_clipping)
+ {
+ /* Disable all clip planes to get defined results on all drivers. See comment in the
+ * state_clipping state handler
+ */
+ for (i = 0; i < gl_info->limits.clipplanes; ++i)
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0 + i);
+ checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
+ }
+
+ if (!warned && state->render_states[WINED3D_RS_CLIPPLANEENABLE])
+ {
+ FIXME("Clipping not supported with vertex shaders\n");
+ warned = TRUE;
+ }
+ }
+ if (wasrhw)
+ {
+ /* Apply the transform matrices when switching from rhw
+ * drawing to vertex shaders. Vertex shaders themselves do
+ * not need it, but the matrices are not reapplied
+ * automatically when switching back from vertex shaders to
+ * fixed function processing. So make sure we leave the fixed
+ * function vertex processing states back in a sane state
+ * before switching to shaders. */
+ if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
+ transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
+ if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
+ transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
+ }
+ updateFog = TRUE;
+
+ /* Vertex shader clipping ignores the view matrix. Update all clipplanes
+ * (Note: ARB shaders can read the clip planes for clipping emulation even if
+ * device->vs_clipping is false.
+ */
+ for (i = 0; i < gl_info->limits.clipplanes; ++i)
+ {
+ clipplane(context, state, STATE_CLIPPLANE(i));
+ }
+ }
+ }
+
+ context->last_was_vshader = useVertexShaderFunction;
+ context->select_shader = 1;
+ context->load_constants = 1;
+
+ if (updateFog)
+ context_apply_state(context, state, STATE_RENDER(WINED3D_RS_FOGVERTEXMODE));
+
+ if (!useVertexShaderFunction)
+ {
+ unsigned int i;
+
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + i)))
+ transform_texture(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
+ }
+ }
+
+ if (transformed != wasrhw && !isStateDirty(context, STATE_RENDER(WINED3D_RS_ZENABLE)))
+ state_zenable(context, state, STATE_RENDER(WINED3D_RS_ZENABLE));
+}
+
+static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_surface *target = state->fb->render_targets[0];
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct wined3d_viewport vp = state->viewport;
+
+ if (vp.width > target->resource.width)
+ vp.width = target->resource.width;
+ if (vp.height > target->resource.height)
+ vp.height = target->resource.height;
+
+ gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z);
+ checkGLcall("glDepthRange");
+ /* Note: GL requires lower left, DirectX supplies upper left. This is
+ * reversed when using offscreen rendering. */
+ if (context->render_offscreen)
+ {
+ gl_info->gl_ops.gl.p_glViewport(vp.x, vp.y, vp.width, vp.height);
+ }
+ else
+ {
+ UINT width, height;
+
+ target->get_drawable_size(context, &width, &height);
+ gl_info->gl_ops.gl.p_glViewport(vp.x, (height - (vp.y + vp.height)),
+ vp.width, vp.height);
+ }
+
+ if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)))
+ state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE));
+
+ checkGLcall("glViewport");
+}
+
+void viewport_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
+ transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
+ if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)))
+ state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE));
+ /* Update the position fixup. */
+ context->load_constants = 1;
+}
+
+void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ UINT Index = state_id - STATE_ACTIVELIGHT(0);
+ const struct wined3d_light_info *lightInfo = state->lights[Index];
+
+ if (!lightInfo)
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_LIGHT0 + Index);
+ checkGLcall("glDisable(GL_LIGHT0 + Index)");
+ }
+ else
+ {
+ float quad_att;
+ float colRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
+ gl_info->gl_ops.gl.p_glPushMatrix();
+ gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
+
+ /* Diffuse: */
+ colRGBA[0] = lightInfo->OriginalParms.diffuse.r;
+ colRGBA[1] = lightInfo->OriginalParms.diffuse.g;
+ colRGBA[2] = lightInfo->OriginalParms.diffuse.b;
+ colRGBA[3] = lightInfo->OriginalParms.diffuse.a;
+ gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
+ checkGLcall("glLightfv");
+
+ /* Specular */
+ colRGBA[0] = lightInfo->OriginalParms.specular.r;
+ colRGBA[1] = lightInfo->OriginalParms.specular.g;
+ colRGBA[2] = lightInfo->OriginalParms.specular.b;
+ colRGBA[3] = lightInfo->OriginalParms.specular.a;
+ gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
+ checkGLcall("glLightfv");
+
+ /* Ambient */
+ colRGBA[0] = lightInfo->OriginalParms.ambient.r;
+ colRGBA[1] = lightInfo->OriginalParms.ambient.g;
+ colRGBA[2] = lightInfo->OriginalParms.ambient.b;
+ colRGBA[3] = lightInfo->OriginalParms.ambient.a;
+ gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
+ checkGLcall("glLightfv");
+
+ if ((lightInfo->OriginalParms.range * lightInfo->OriginalParms.range) >= FLT_MIN)
+ quad_att = 1.4f / (lightInfo->OriginalParms.range * lightInfo->OriginalParms.range);
+ else
+ quad_att = 0.0f; /* 0 or MAX? (0 seems to be ok) */
+
+ /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
+ * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
+ * Attenuation0 to NaN and crashes in the gl lib
+ */
+
+ switch (lightInfo->OriginalParms.type)
+ {
+ case WINED3D_LIGHT_POINT:
+ /* Position */
+ gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
+ checkGLcall("glLightfv");
+ gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
+ checkGLcall("glLightf");
+ /* Attenuation - Are these right? guessing... */
+ gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION,
+ lightInfo->OriginalParms.attenuation0);
+ checkGLcall("glLightf");
+ gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION,
+ lightInfo->OriginalParms.attenuation1);
+ checkGLcall("glLightf");
+ if (quad_att < lightInfo->OriginalParms.attenuation2)
+ quad_att = lightInfo->OriginalParms.attenuation2;
+ gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
+ checkGLcall("glLightf");
+ /* FIXME: Range */
+ break;
+
+ case WINED3D_LIGHT_SPOT:
+ /* Position */
+ gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
+ checkGLcall("glLightfv");
+ /* Direction */
+ gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
+ checkGLcall("glLightfv");
+ gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
+ checkGLcall("glLightf");
+ gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
+ checkGLcall("glLightf");
+ /* Attenuation - Are these right? guessing... */
+ gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION,
+ lightInfo->OriginalParms.attenuation0);
+ checkGLcall("glLightf");
+ gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION,
+ lightInfo->OriginalParms.attenuation1);
+ checkGLcall("glLightf");
+ if (quad_att < lightInfo->OriginalParms.attenuation2)
+ quad_att = lightInfo->OriginalParms.attenuation2;
+ gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
+ checkGLcall("glLightf");
+ /* FIXME: Range */
+ break;
+
+ case WINED3D_LIGHT_DIRECTIONAL:
+ /* Direction */
+ /* Note GL uses w position of 0 for direction! */
+ gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
+ checkGLcall("glLightfv");
+ gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
+ checkGLcall("glLightf");
+ gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
+ checkGLcall("glLightf");
+ break;
+
+ default:
+ FIXME("Unrecognized light type %#x.\n", lightInfo->OriginalParms.type);
+ }
+
+ /* Restore the modelview matrix */
+ gl_info->gl_ops.gl.p_glPopMatrix();
+
+ gl_info->gl_ops.gl.p_glEnable(GL_LIGHT0 + Index);
+ checkGLcall("glEnable(GL_LIGHT0 + Index)");
+ }
+}
+
+static void scissorrect(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const RECT *r = &state->scissor_rect;
+
+ /* Warning: glScissor uses window coordinates, not viewport coordinates,
+ * so our viewport correction does not apply. Warning2: Even in windowed
+ * mode the coords are relative to the window, not the screen. */
+ TRACE("Setting new scissor rect to %s.\n", wine_dbgstr_rect(r));
+
+ if (context->render_offscreen)
+ {
+ gl_info->gl_ops.gl.p_glScissor(r->left, r->top, r->right - r->left, r->bottom - r->top);
+ }
+ else
+ {
+ const struct wined3d_surface *target = state->fb->render_targets[0];
+ UINT height;
+ UINT width;
+
+ target->get_drawable_size(context, &width, &height);
+ gl_info->gl_ops.gl.p_glScissor(r->left, height - r->bottom, r->right - r->left, r->bottom - r->top);
+ }
+ checkGLcall("glScissor");
+}
+
+static void indexbuffer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_stream_info *stream_info = &context->swapchain->device->stream_info;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (!state->index_buffer || !stream_info->all_vbo)
+ {
+ GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
+ }
+ else
+ {
+ struct wined3d_buffer *ib = state->index_buffer;
+ GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
+ }
+}
+
+static void frontface(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (context->render_offscreen)
+ {
+ gl_info->gl_ops.gl.p_glFrontFace(GL_CCW);
+ checkGLcall("glFrontFace(GL_CCW)");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glFrontFace(GL_CW);
+ checkGLcall("glFrontFace(GL_CW)");
+ }
+}
+
+static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ static BOOL warned;
+
+ if (!warned)
+ {
+ WARN("Point sprite coordinate origin switching not supported.\n");
+ warned = TRUE;
+ }
+}
+
+static void psorigin(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ GLint origin = context->render_offscreen ? GL_LOWER_LEFT : GL_UPPER_LEFT;
+
+ if (gl_info->supported[NV_POINT_SPRITE])
+ {
+ GL_EXTCALL(glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, origin));
+ checkGLcall("glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
+ }
+}
+
+void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const struct wined3d_surface *rt = state->fb->render_targets[0];
+
+ TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
+
+ if (state->render_states[WINED3D_RS_SRGBWRITEENABLE]
+ && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
+ gl_info->gl_ops.gl.p_glEnable(GL_FRAMEBUFFER_SRGB);
+ else
+ gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB);
+}
+
+const struct StateEntryTemplate misc_state_template[] = {
+ { STATE_RENDER(WINED3D_RS_SRCBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_DESTBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_EDGEANTIALIAS), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_SRCBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_BLENDOPALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_STREAMSRC, { STATE_STREAMSRC, streamsrc }, WINED3D_GL_EXT_NONE },
+ { STATE_VDECL, { STATE_VDECL, vdecl_miscpart }, WINED3D_GL_EXT_NONE },
+ { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE },
+ { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE },
+ { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin }, WINED3D_GL_VERSION_2_0 },
+ { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin_w }, WINED3D_GL_EXT_NONE },
+
+ /* TODO: Move shader constant loading to vertex and fragment pipeline respectively, as soon as the pshader and
+ * vshader loadings are untied from each other
+ */
+ { STATE_VERTEXSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE },
+ { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
+
+ { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE },
+ { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT },
+ { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_ANTIALIAS), { STATE_RENDER(WINED3D_RS_ANTIALIAS), state_antialias }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), state_perspective }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_ZENABLE), { STATE_RENDER(WINED3D_RS_ZENABLE), state_zenable }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_WRAPU), { STATE_RENDER(WINED3D_RS_WRAPU), state_wrapu }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_WRAPV), { STATE_RENDER(WINED3D_RS_WRAPV), state_wrapv }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_FILLMODE), { STATE_RENDER(WINED3D_RS_FILLMODE), state_fillmode }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_LINEPATTERN), { STATE_RENDER(WINED3D_RS_LINEPATTERN), state_linepattern }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_MONOENABLE), { STATE_RENDER(WINED3D_RS_MONOENABLE), state_monoenable }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_ROP2), { STATE_RENDER(WINED3D_RS_ROP2), state_rop2 }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_PLANEMASK), { STATE_RENDER(WINED3D_RS_PLANEMASK), state_planemask }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), state_zwritenable }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_ALPHAREF), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_ALPHAFUNC), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_COLORKEYENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_LASTPIXEL), { STATE_RENDER(WINED3D_RS_LASTPIXEL), state_lastpixel }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_CULLMODE), { STATE_RENDER(WINED3D_RS_CULLMODE), state_cullmode }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_ZFUNC), { STATE_RENDER(WINED3D_RS_ZFUNC), state_zfunc }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_DITHERENABLE), { STATE_RENDER(WINED3D_RS_DITHERENABLE), state_ditherenable }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_SUBPIXEL), { STATE_RENDER(WINED3D_RS_SUBPIXEL), state_subpixel }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_SUBPIXELX), { STATE_RENDER(WINED3D_RS_SUBPIXELX), state_subpixelx }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), state_stippledalpha }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_STIPPLEENABLE), { STATE_RENDER(WINED3D_RS_STIPPLEENABLE), state_stippleenable }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), state_mipmaplodbias }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_ANISOTROPY), { STATE_RENDER(WINED3D_RS_ANISOTROPY), state_anisotropy }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_FLUSHBATCH), { STATE_RENDER(WINED3D_RS_FLUSHBATCH), state_flushbatch }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),{ STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),state_translucentsi }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_STENCILENABLE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_STENCILREF), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_STENCILMASK), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE },
+ { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_CCW_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_CCW_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_CCW_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_WRAP0), { STATE_RENDER(WINED3D_RS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_WRAP1), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_WRAP2), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_WRAP3), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_WRAP4), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_WRAP5), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_WRAP6), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_WRAP7), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_WRAP8), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_WRAP9), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_WRAP10), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_WRAP11), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_WRAP12), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_WRAP13), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_WRAP14), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_WRAP15), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_EXTENTS), { STATE_RENDER(WINED3D_RS_EXTENTS), state_extents }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), state_ckeyblend }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), state_swvp }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), state_patchedgestyle}, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), state_patchsegments }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_POSITIONDEGREE), { STATE_RENDER(WINED3D_RS_POSITIONDEGREE), state_positiondegree}, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_NORMALDEGREE), { STATE_RENDER(WINED3D_RS_NORMALDEGREE), state_normaldegree }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_X), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_W), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_nvdb }, EXT_DEPTH_BOUNDS_TEST },
+ { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_tessellation }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa }, ARB_MULTISAMPLE },
+ { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 },
+ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop }, EXT_BLEND_MINMAX },
+ { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 },
+ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 },
+ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 },
+ { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR },
+ { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_DEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE },
+ /* Samplers */
+ { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(8), { STATE_SAMPLER(8), sampler }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(9), { STATE_SAMPLER(9), sampler }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(10), { STATE_SAMPLER(10), sampler }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(11), { STATE_SAMPLER(11), sampler }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(12), { STATE_SAMPLER(12), sampler }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(13), { STATE_SAMPLER(13), sampler }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(14), { STATE_SAMPLER(14), sampler }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(15), { STATE_SAMPLER(15), sampler }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(16), /* Vertex sampler 0 */ { STATE_SAMPLER(16), sampler }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(17), /* Vertex sampler 1 */ { STATE_SAMPLER(17), sampler }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(18), /* Vertex sampler 2 */ { STATE_SAMPLER(18), sampler }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(19), /* Vertex sampler 3 */ { STATE_SAMPLER(19), sampler }, WINED3D_GL_EXT_NONE },
+ { STATE_BASEVERTEXINDEX, { STATE_BASEVERTEXINDEX, state_nop, }, ARB_DRAW_ELEMENTS_BASE_VERTEX },
+ { STATE_BASEVERTEXINDEX, { STATE_STREAMSRC, NULL, }, WINED3D_GL_EXT_NONE },
+ { STATE_FRAMEBUFFER, { STATE_FRAMEBUFFER, context_state_fb }, WINED3D_GL_EXT_NONE },
+ { STATE_PIXELSHADER, { STATE_PIXELSHADER, context_state_drawbuf},WINED3D_GL_EXT_NONE },
+ { STATE_GEOMETRY_SHADER, { STATE_GEOMETRY_SHADER, state_geometry_shader}, WINED3D_GL_EXT_NONE },
+ {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
+};
+
+const struct StateEntryTemplate vp_ffp_states[] =
+{
+ { STATE_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE },
+ { STATE_VSHADER, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_MATERIAL, { STATE_RENDER(WINED3D_RS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_SPECULARENABLE), { STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE },
+ /* Clip planes */
+ { STATE_CLIPPLANE(0), { STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(1), { STATE_CLIPPLANE(1), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(2), { STATE_CLIPPLANE(2), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(3), { STATE_CLIPPLANE(3), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(4), { STATE_CLIPPLANE(4), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(5), { STATE_CLIPPLANE(5), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(6), { STATE_CLIPPLANE(6), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(7), { STATE_CLIPPLANE(7), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(8), { STATE_CLIPPLANE(8), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(9), { STATE_CLIPPLANE(9), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(10), { STATE_CLIPPLANE(10), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(11), { STATE_CLIPPLANE(11), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(12), { STATE_CLIPPLANE(12), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(13), { STATE_CLIPPLANE(13), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(14), { STATE_CLIPPLANE(14), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(15), { STATE_CLIPPLANE(15), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(16), { STATE_CLIPPLANE(16), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(17), { STATE_CLIPPLANE(17), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(18), { STATE_CLIPPLANE(18), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(19), { STATE_CLIPPLANE(19), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(20), { STATE_CLIPPLANE(20), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(21), { STATE_CLIPPLANE(21), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(22), { STATE_CLIPPLANE(22), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(23), { STATE_CLIPPLANE(23), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(24), { STATE_CLIPPLANE(24), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(25), { STATE_CLIPPLANE(25), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(26), { STATE_CLIPPLANE(26), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(27), { STATE_CLIPPLANE(27), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(28), { STATE_CLIPPLANE(28), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(29), { STATE_CLIPPLANE(29), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(30), { STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE },
+ { STATE_CLIPPLANE(31), { STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE },
+ /* Lights */
+ { STATE_LIGHT_TYPE, { STATE_LIGHT_TYPE, state_nop }, WINED3D_GL_EXT_NONE },
+ { STATE_ACTIVELIGHT(0), { STATE_ACTIVELIGHT(0), light }, WINED3D_GL_EXT_NONE },
+ { STATE_ACTIVELIGHT(1), { STATE_ACTIVELIGHT(1), light }, WINED3D_GL_EXT_NONE },
+ { STATE_ACTIVELIGHT(2), { STATE_ACTIVELIGHT(2), light }, WINED3D_GL_EXT_NONE },
+ { STATE_ACTIVELIGHT(3), { STATE_ACTIVELIGHT(3), light }, WINED3D_GL_EXT_NONE },
+ { STATE_ACTIVELIGHT(4), { STATE_ACTIVELIGHT(4), light }, WINED3D_GL_EXT_NONE },
+ { STATE_ACTIVELIGHT(5), { STATE_ACTIVELIGHT(5), light }, WINED3D_GL_EXT_NONE },
+ { STATE_ACTIVELIGHT(6), { STATE_ACTIVELIGHT(6), light }, WINED3D_GL_EXT_NONE },
+ { STATE_ACTIVELIGHT(7), { STATE_ACTIVELIGHT(7), light }, WINED3D_GL_EXT_NONE },
+ /* Viewport */
+ { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_vertexpart }, WINED3D_GL_EXT_NONE },
+ /* Transform states follow */
+ { STATE_TRANSFORM(WINED3D_TS_VIEW), { STATE_TRANSFORM(WINED3D_TS_VIEW), transform_view }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_PROJECTION), { STATE_TRANSFORM(WINED3D_TS_PROJECTION), transform_projection}, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_TEXTURE0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_TEXTURE1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_TEXTURE2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_TEXTURE3), { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_TEXTURE4), { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_TEXTURE5), { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_TEXTURE6), { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_TEXTURE7), { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 0)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 0)), transform_world }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 1)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 1)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 2)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 2)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 3)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 3)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 4)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 4)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 5)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 5)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 6)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 6)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 7)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 7)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 8)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 8)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 9)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 9)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), transform_worldex }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
+ /* Fog */
+ { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_CLIPPING), { STATE_RENDER(WINED3D_RS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), { STATE_RENDER(WINED3D_RS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_LIGHTING), { STATE_RENDER(WINED3D_RS_LIGHTING), state_lighting }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_AMBIENT), { STATE_RENDER(WINED3D_RS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_COLORVERTEX), { STATE_RENDER(WINED3D_RS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_LOCALVIEWER), { STATE_RENDER(WINED3D_RS_LOCALVIEWER), state_localviewer }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), state_normalize }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND },
+ { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_POINTSIZE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
+ { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS },
+ { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE },
+ { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_POINTSCALE_A), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_POINTSCALE_B), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_POINTSCALE_C), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS },
+ { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS },
+ { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_TWEENFACTOR), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
+
+ /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
+ * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
+ * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
+ */
+ { STATE_SAMPLER(0), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ { STATE_SAMPLER(0), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
+ { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(1), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ { STATE_SAMPLER(1), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
+ { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(2), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ { STATE_SAMPLER(2), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
+ { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(3), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ { STATE_SAMPLER(3), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
+ { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(4), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ { STATE_SAMPLER(4), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
+ { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(5), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ { STATE_SAMPLER(5), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
+ { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(6), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ { STATE_SAMPLER(6), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
+ { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(7), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ { STATE_SAMPLER(7), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
+ { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ { STATE_POINT_SIZE_ENABLE, { STATE_POINT_SIZE_ENABLE, state_nop }, WINED3D_GL_EXT_NONE },
+ {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
+};
+
+static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), state_texfactor }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_FOGCOLOR), { STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_FOGDENSITY), { STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_FOGSTART), { STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
+ { STATE_RENDER(WINED3D_RS_FOGEND), { STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE },
+ {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
+};
+
+/* Context activation is done by the caller. */
+static void ffp_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {}
+
+static void *ffp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
+{
+ return shader_priv;
+}
+
+static void ffp_free(struct wined3d_device *device) {}
+
+static void vp_ffp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
+{
+ caps->xyzrhw = FALSE;
+ caps->max_active_lights = gl_info->limits.lights;
+ caps->max_vertex_blend_matrices = gl_info->limits.blends;
+ caps->max_vertex_blend_matrix_index = 0;
+ caps->vertex_processing_caps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS
+ | WINED3DVTXPCAPS_MATERIALSOURCE7
+ | WINED3DVTXPCAPS_POSITIONALLIGHTS
+ | WINED3DVTXPCAPS_LOCALVIEWER
+ | WINED3DVTXPCAPS_VERTEXFOG
+ | WINED3DVTXPCAPS_TEXGEN
+ | WINED3DVTXPCAPS_TEXGEN_SPHEREMAP;
+ caps->fvf_caps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
+ caps->max_user_clip_planes = gl_info->limits.clipplanes;
+ caps->raster_caps = 0;
+ if (gl_info->supported[NV_FOG_DISTANCE])
+ caps->raster_caps |= WINED3DPRASTERCAPS_FOGRANGE;
+}
+
+const struct wined3d_vertex_pipe_ops ffp_vertex_pipe =
+{
+ ffp_enable,
+ vp_ffp_get_caps,
+ ffp_alloc,
+ ffp_free,
+ vp_ffp_states,
+};
+
+static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
+{
+ caps->wined3d_caps = 0;
+ caps->PrimitiveMiscCaps = 0;
+ caps->TextureOpCaps = WINED3DTEXOPCAPS_ADD
+ | WINED3DTEXOPCAPS_ADDSIGNED
+ | WINED3DTEXOPCAPS_ADDSIGNED2X
+ | WINED3DTEXOPCAPS_MODULATE
+ | WINED3DTEXOPCAPS_MODULATE2X
+ | WINED3DTEXOPCAPS_MODULATE4X
+ | WINED3DTEXOPCAPS_SELECTARG1
+ | WINED3DTEXOPCAPS_SELECTARG2
+ | WINED3DTEXOPCAPS_DISABLE;
+
+ if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE]
+ || gl_info->supported[EXT_TEXTURE_ENV_COMBINE]
+ || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
+ {
+ caps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA
+ | WINED3DTEXOPCAPS_BLENDTEXTUREALPHA
+ | WINED3DTEXOPCAPS_BLENDFACTORALPHA
+ | WINED3DTEXOPCAPS_BLENDCURRENTALPHA
+ | WINED3DTEXOPCAPS_LERP
+ | WINED3DTEXOPCAPS_SUBTRACT;
+ }
+ if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]
+ || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
+ {
+ caps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH
+ | WINED3DTEXOPCAPS_MULTIPLYADD
+ | WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
+ | WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
+ | WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
+ }
+ if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
+ caps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
+
+ caps->MaxTextureBlendStages = gl_info->limits.textures;
+ caps->MaxSimultaneousTextures = gl_info->limits.textures;
+}
+
+static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
+{
+ if (TRACE_ON(d3d))
+ {
+ TRACE("Checking support for fixup:\n");
+ dump_color_fixup_desc(fixup);
+ }
+
+ /* We only support identity conversions. */
+ if (is_identity_fixup(fixup))
+ {
+ TRACE("[OK]\n");
+ return TRUE;
+ }
+
+ TRACE("[FAILED]\n");
+ return FALSE;
+}
+
+const struct fragment_pipeline ffp_fragment_pipeline = {
+ ffp_enable,
+ ffp_fragment_get_caps,
+ ffp_alloc,
+ ffp_free,
+ ffp_color_fixup_supported,
+ ffp_fragmentstate_template,
+};
+
+static void none_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {}
+
+static void *none_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
+{
+ return shader_priv;
+}
+
+static void none_free(struct wined3d_device *device) {}
+
+static void vp_none_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
+{
+ memset(caps, 0, sizeof(*caps));
+}
+
+const struct wined3d_vertex_pipe_ops none_vertex_pipe =
+{
+ none_enable,
+ vp_none_get_caps,
+ none_alloc,
+ none_free,
+ NULL,
+};
+
+static void fp_none_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
+{
+ memset(caps, 0, sizeof(*caps));
+}
+
+static BOOL fp_none_color_fixup_supported(struct color_fixup_desc fixup)
+{
+ return is_identity_fixup(fixup);
+}
+
+const struct fragment_pipeline none_fragment_pipe =
+{
+ none_enable,
+ fp_none_get_caps,
+ none_alloc,
+ none_free,
+ fp_none_color_fixup_supported,
+ NULL,
+};
+
+static unsigned int num_handlers(const APPLYSTATEFUNC *funcs)
+{
+ unsigned int i;
+ for(i = 0; funcs[i]; i++);
+ return i;
+}
+
+static void multistate_apply_2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
+ context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
+}
+
+static void multistate_apply_3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
+ context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
+ context->swapchain->device->multistate_funcs[state_id][2](context, state, state_id);
+}
+
+static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info,
+ const struct wined3d_d3d_info *d3d_info)
+{
+ unsigned int start, last, i;
+
+ start = STATE_TEXTURESTAGE(d3d_info->limits.ffp_blend_stages, 0);
+ last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE);
+ for (i = start; i <= last; ++i)
+ {
+ state_table[i].representative = 0;
+ state_table[i].apply = state_undefined;
+ }
+
+ start = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + d3d_info->limits.ffp_blend_stages);
+ last = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + MAX_TEXTURES - 1);
+ for (i = start; i <= last; ++i)
+ {
+ state_table[i].representative = 0;
+ state_table[i].apply = state_undefined;
+ }
+
+ start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(gl_info->limits.blends));
+ last = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255));
+ for (i = start; i <= last; ++i)
+ {
+ state_table[i].representative = 0;
+ state_table[i].apply = state_undefined;
+ }
+}
+
+static void validate_state_table(struct StateEntry *state_table)
+{
+ static const struct
+ {
+ DWORD first;
+ DWORD last;
+ }
+ rs_holes[] =
+ {
+ { 1, 1},
+ { 3, 3},
+ { 17, 18},
+ { 21, 21},
+ { 42, 45},
+ { 47, 47},
+ { 61, 127},
+ {149, 150},
+ {169, 169},
+ {177, 177},
+ {196, 197},
+ { 0, 0},
+ };
+ static const DWORD simple_states[] =
+ {
+ STATE_MATERIAL,
+ STATE_VDECL,
+ STATE_STREAMSRC,
+ STATE_INDEXBUFFER,
+ STATE_VERTEXSHADERCONSTANT,
+ STATE_PIXELSHADERCONSTANT,
+ STATE_VSHADER,
+ STATE_GEOMETRY_SHADER,
+ STATE_PIXELSHADER,
+ STATE_VIEWPORT,
+ STATE_LIGHT_TYPE,
+ STATE_SCISSORRECT,
+ STATE_FRONTFACE,
+ STATE_POINTSPRITECOORDORIGIN,
+ STATE_BASEVERTEXINDEX,
+ STATE_FRAMEBUFFER,
+ STATE_POINT_SIZE_ENABLE,
+ };
+ unsigned int i, current;
+
+ for (i = STATE_RENDER(1), current = 0; i <= STATE_RENDER(WINEHIGHEST_RENDER_STATE); ++i)
+ {
+ if (!rs_holes[current].first || i < STATE_RENDER(rs_holes[current].first))
+ {
+ if (!state_table[i].representative)
+ ERR("State %s (%#x) should have a representative.\n", debug_d3dstate(i), i);
+ }
+ else if (state_table[i].representative)
+ ERR("State %s (%#x) shouldn't have a representative.\n", debug_d3dstate(i), i);
+
+ if (i == STATE_RENDER(rs_holes[current].last)) ++current;
+ }
+
+ for (i = 0; i < sizeof(simple_states) / sizeof(*simple_states); ++i)
+ {
+ if (!state_table[simple_states[i]].representative)
+ ERR("State %s (%#x) should have a representative.\n",
+ debug_d3dstate(simple_states[i]), simple_states[i]);
+ }
+
+ for (i = 0; i < STATE_HIGHEST + 1; ++i)
+ {
+ DWORD rep = state_table[i].representative;
+ if (rep)
+ {
+ if (state_table[rep].representative != rep)
+ {
+ ERR("State %s (%#x) has invalid representative %s (%#x).\n",
+ debug_d3dstate(i), i, debug_d3dstate(rep), rep);
+ state_table[i].representative = 0;
+ }
+
+ if (rep != i)
+ {
+ if (state_table[i].apply)
+ ERR("State %s (%#x) has both a handler and representative.\n", debug_d3dstate(i), i);
+ }
+ else if (!state_table[i].apply)
+ {
+ ERR("Self representing state %s (%#x) has no handler.\n", debug_d3dstate(i), i);
+ }
+ }
+ }
+}
+
+HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
+ const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info,
+ const struct wined3d_vertex_pipe_ops *vertex, const struct fragment_pipeline *fragment,
+ const struct StateEntryTemplate *misc)
+{
+ unsigned int i, type, handlers;
+ APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];
+ const struct StateEntryTemplate *cur;
+ BOOL set[STATE_HIGHEST + 1];
+
+ memset(multistate_funcs, 0, sizeof(multistate_funcs));
+
+ for(i = 0; i < STATE_HIGHEST + 1; i++) {
+ StateTable[i].representative = 0;
+ StateTable[i].apply = state_undefined;
+ }
+
+ for(type = 0; type < 3; type++) {
+ /* This switch decides the order in which the states are applied */
+ switch(type) {
+ case 0: cur = misc; break;
+ case 1: cur = fragment->states; break;
+ case 2: cur = vertex->vp_states; break;
+ default: cur = NULL; /* Stupid compiler */
+ }
+ if(!cur) continue;
+
+ /* GL extension filtering should not prevent multiple handlers being applied from different
+ * pipeline parts
+ */
+ memset(set, 0, sizeof(set));
+
+ for(i = 0; cur[i].state; i++) {
+ APPLYSTATEFUNC *funcs_array;
+
+ /* Only use the first matching state with the available extension from one template.
+ * e.g.
+ * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func1}, XYZ_FANCY},
+ * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func2}, 0 }
+ *
+ * if GL_XYZ_fancy is supported, ignore the 2nd line
+ */
+ if(set[cur[i].state]) continue;
+ /* Skip state lines depending on unsupported extensions */
+ if (!gl_info->supported[cur[i].extension]) continue;
+ set[cur[i].state] = TRUE;
+ /* In some cases having an extension means that nothing has to be
+ * done for a state, e.g. if GL_ARB_texture_non_power_of_two is
+ * supported, the texture coordinate fixup can be ignored. If the
+ * apply function is used, mark the state set(done above) to prevent
+ * applying later lines, but do not record anything in the state
+ * table
+ */
+ if (!cur[i].content.representative) continue;
+
+ handlers = num_handlers(multistate_funcs[cur[i].state]);
+ multistate_funcs[cur[i].state][handlers] = cur[i].content.apply;
+ switch(handlers) {
+ case 0:
+ StateTable[cur[i].state].apply = cur[i].content.apply;
+ break;
+ case 1:
+ StateTable[cur[i].state].apply = multistate_apply_2;
+ dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
+ 0,
+ sizeof(**dev_multistate_funcs) * 2);
+ if (!dev_multistate_funcs[cur[i].state]) {
+ goto out_of_mem;
+ }
+
+ dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
+ dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
+ break;
+ case 2:
+ StateTable[cur[i].state].apply = multistate_apply_3;
+ funcs_array = HeapReAlloc(GetProcessHeap(),
+ 0,
+ dev_multistate_funcs[cur[i].state],
+ sizeof(**dev_multistate_funcs) * 3);
+ if (!funcs_array) {
+ goto out_of_mem;
+ }
+
+ dev_multistate_funcs[cur[i].state] = funcs_array;
+ dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
+ break;
+ default:
+ ERR("Unexpected amount of state handlers for state %u: %u\n",
+ cur[i].state, handlers + 1);
+ }
+
+ if (StateTable[cur[i].state].representative
+ && StateTable[cur[i].state].representative != cur[i].content.representative)
+ {
+ FIXME("State %s (%#x) has different representatives in different pipeline parts.\n",
+ debug_d3dstate(cur[i].state), cur[i].state);
+ }
+ StateTable[cur[i].state].representative = cur[i].content.representative;
+ }
+ }
+
+ prune_invalid_states(StateTable, gl_info, d3d_info);
+ validate_state_table(StateTable);
+
+ return WINED3D_OK;
+
+out_of_mem:
+ for (i = 0; i <= STATE_HIGHEST; ++i) {
+ HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
+ }
+
+ memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
+
+ return E_OUTOFMEMORY;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/stateblock.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/stateblock.c
new file mode 100644
index 00000000..624a0754
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/stateblock.c
@@ -0,0 +1,1494 @@
+/*
+ * state block implementation
+ *
+ * Copyright 2002 Raphael Junqueira
+ * Copyright 2004 Jason Edmeades
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2007 Stefan Dösinger for CodeWeavers
+ * Copyright 2009 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+
+static const DWORD pixel_states_render[] =
+{
+ WINED3D_RS_ALPHABLENDENABLE,
+ WINED3D_RS_ALPHAFUNC,
+ WINED3D_RS_ALPHAREF,
+ WINED3D_RS_ALPHATESTENABLE,
+ WINED3D_RS_ANTIALIASEDLINEENABLE,
+ WINED3D_RS_BLENDFACTOR,
+ WINED3D_RS_BLENDOP,
+ WINED3D_RS_BLENDOPALPHA,
+ WINED3D_RS_CCW_STENCILFAIL,
+ WINED3D_RS_CCW_STENCILPASS,
+ WINED3D_RS_CCW_STENCILZFAIL,
+ WINED3D_RS_COLORWRITEENABLE,
+ WINED3D_RS_COLORWRITEENABLE1,
+ WINED3D_RS_COLORWRITEENABLE2,
+ WINED3D_RS_COLORWRITEENABLE3,
+ WINED3D_RS_DEPTHBIAS,
+ WINED3D_RS_DESTBLEND,
+ WINED3D_RS_DESTBLENDALPHA,
+ WINED3D_RS_DITHERENABLE,
+ WINED3D_RS_FILLMODE,
+ WINED3D_RS_FOGDENSITY,
+ WINED3D_RS_FOGEND,
+ WINED3D_RS_FOGSTART,
+ WINED3D_RS_LASTPIXEL,
+ WINED3D_RS_SCISSORTESTENABLE,
+ WINED3D_RS_SEPARATEALPHABLENDENABLE,
+ WINED3D_RS_SHADEMODE,
+ WINED3D_RS_SLOPESCALEDEPTHBIAS,
+ WINED3D_RS_SRCBLEND,
+ WINED3D_RS_SRCBLENDALPHA,
+ WINED3D_RS_SRGBWRITEENABLE,
+ WINED3D_RS_STENCILENABLE,
+ WINED3D_RS_STENCILFAIL,
+ WINED3D_RS_STENCILFUNC,
+ WINED3D_RS_STENCILMASK,
+ WINED3D_RS_STENCILPASS,
+ WINED3D_RS_STENCILREF,
+ WINED3D_RS_STENCILWRITEMASK,
+ WINED3D_RS_STENCILZFAIL,
+ WINED3D_RS_TEXTUREFACTOR,
+ WINED3D_RS_TWOSIDEDSTENCILMODE,
+ WINED3D_RS_WRAP0,
+ WINED3D_RS_WRAP1,
+ WINED3D_RS_WRAP10,
+ WINED3D_RS_WRAP11,
+ WINED3D_RS_WRAP12,
+ WINED3D_RS_WRAP13,
+ WINED3D_RS_WRAP14,
+ WINED3D_RS_WRAP15,
+ WINED3D_RS_WRAP2,
+ WINED3D_RS_WRAP3,
+ WINED3D_RS_WRAP4,
+ WINED3D_RS_WRAP5,
+ WINED3D_RS_WRAP6,
+ WINED3D_RS_WRAP7,
+ WINED3D_RS_WRAP8,
+ WINED3D_RS_WRAP9,
+ WINED3D_RS_ZENABLE,
+ WINED3D_RS_ZFUNC,
+ WINED3D_RS_ZWRITEENABLE,
+};
+
+static const DWORD pixel_states_texture[] =
+{
+ WINED3D_TSS_ALPHA_ARG0,
+ WINED3D_TSS_ALPHA_ARG1,
+ WINED3D_TSS_ALPHA_ARG2,
+ WINED3D_TSS_ALPHA_OP,
+ WINED3D_TSS_BUMPENV_LOFFSET,
+ WINED3D_TSS_BUMPENV_LSCALE,
+ WINED3D_TSS_BUMPENV_MAT00,
+ WINED3D_TSS_BUMPENV_MAT01,
+ WINED3D_TSS_BUMPENV_MAT10,
+ WINED3D_TSS_BUMPENV_MAT11,
+ WINED3D_TSS_COLOR_ARG0,
+ WINED3D_TSS_COLOR_ARG1,
+ WINED3D_TSS_COLOR_ARG2,
+ WINED3D_TSS_COLOR_OP,
+ WINED3D_TSS_RESULT_ARG,
+ WINED3D_TSS_TEXCOORD_INDEX,
+ WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS,
+};
+
+static const DWORD pixel_states_sampler[] =
+{
+ WINED3D_SAMP_ADDRESS_U,
+ WINED3D_SAMP_ADDRESS_V,
+ WINED3D_SAMP_ADDRESS_W,
+ WINED3D_SAMP_BORDER_COLOR,
+ WINED3D_SAMP_MAG_FILTER,
+ WINED3D_SAMP_MIN_FILTER,
+ WINED3D_SAMP_MIP_FILTER,
+ WINED3D_SAMP_MIPMAP_LOD_BIAS,
+ WINED3D_SAMP_MAX_MIP_LEVEL,
+ WINED3D_SAMP_MAX_ANISOTROPY,
+ WINED3D_SAMP_SRGB_TEXTURE,
+ WINED3D_SAMP_ELEMENT_INDEX,
+};
+
+static const DWORD vertex_states_render[] =
+{
+ WINED3D_RS_ADAPTIVETESS_W,
+ WINED3D_RS_ADAPTIVETESS_X,
+ WINED3D_RS_ADAPTIVETESS_Y,
+ WINED3D_RS_ADAPTIVETESS_Z,
+ WINED3D_RS_AMBIENT,
+ WINED3D_RS_AMBIENTMATERIALSOURCE,
+ WINED3D_RS_CLIPPING,
+ WINED3D_RS_CLIPPLANEENABLE,
+ WINED3D_RS_COLORVERTEX,
+ WINED3D_RS_CULLMODE,
+ WINED3D_RS_DIFFUSEMATERIALSOURCE,
+ WINED3D_RS_EMISSIVEMATERIALSOURCE,
+ WINED3D_RS_ENABLEADAPTIVETESSELLATION,
+ WINED3D_RS_FOGCOLOR,
+ WINED3D_RS_FOGDENSITY,
+ WINED3D_RS_FOGENABLE,
+ WINED3D_RS_FOGEND,
+ WINED3D_RS_FOGSTART,
+ WINED3D_RS_FOGTABLEMODE,
+ WINED3D_RS_FOGVERTEXMODE,
+ WINED3D_RS_INDEXEDVERTEXBLENDENABLE,
+ WINED3D_RS_LIGHTING,
+ WINED3D_RS_LOCALVIEWER,
+ WINED3D_RS_MAXTESSELLATIONLEVEL,
+ WINED3D_RS_MINTESSELLATIONLEVEL,
+ WINED3D_RS_MULTISAMPLEANTIALIAS,
+ WINED3D_RS_MULTISAMPLEMASK,
+ WINED3D_RS_NORMALDEGREE,
+ WINED3D_RS_NORMALIZENORMALS,
+ WINED3D_RS_PATCHEDGESTYLE,
+ WINED3D_RS_POINTSCALE_A,
+ WINED3D_RS_POINTSCALE_B,
+ WINED3D_RS_POINTSCALE_C,
+ WINED3D_RS_POINTSCALEENABLE,
+ WINED3D_RS_POINTSIZE,
+ WINED3D_RS_POINTSIZE_MAX,
+ WINED3D_RS_POINTSIZE_MIN,
+ WINED3D_RS_POINTSPRITEENABLE,
+ WINED3D_RS_POSITIONDEGREE,
+ WINED3D_RS_RANGEFOGENABLE,
+ WINED3D_RS_SHADEMODE,
+ WINED3D_RS_SPECULARENABLE,
+ WINED3D_RS_SPECULARMATERIALSOURCE,
+ WINED3D_RS_TWEENFACTOR,
+ WINED3D_RS_VERTEXBLEND,
+};
+
+static const DWORD vertex_states_texture[] =
+{
+ WINED3D_TSS_TEXCOORD_INDEX,
+ WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS,
+};
+
+static const DWORD vertex_states_sampler[] =
+{
+ WINED3D_SAMP_DMAP_OFFSET,
+};
+
+/* Allocates the correct amount of space for pixel and vertex shader constants,
+ * along with their set/changed flags on the given stateblock object
+ */
+static HRESULT stateblock_allocate_shader_constants(struct wined3d_stateblock *object)
+{
+ const struct wined3d_d3d_info *d3d_info = &object->device->adapter->d3d_info;
+
+ /* Allocate space for floating point constants */
+ object->state.ps_consts_f = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof(float) * d3d_info->limits.ps_uniform_count * 4);
+ if (!object->state.ps_consts_f) goto fail;
+
+ object->changed.pixelShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof(BOOL) * d3d_info->limits.ps_uniform_count);
+ if (!object->changed.pixelShaderConstantsF) goto fail;
+
+ object->state.vs_consts_f = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof(float) * d3d_info->limits.vs_uniform_count * 4);
+ if (!object->state.vs_consts_f) goto fail;
+
+ object->changed.vertexShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof(BOOL) * d3d_info->limits.vs_uniform_count);
+ if (!object->changed.vertexShaderConstantsF) goto fail;
+
+ object->contained_vs_consts_f = HeapAlloc(GetProcessHeap(), 0,
+ sizeof(DWORD) * d3d_info->limits.vs_uniform_count);
+ if (!object->contained_vs_consts_f) goto fail;
+
+ object->contained_ps_consts_f = HeapAlloc(GetProcessHeap(), 0,
+ sizeof(DWORD) * d3d_info->limits.ps_uniform_count);
+ if (!object->contained_ps_consts_f) goto fail;
+
+ return WINED3D_OK;
+
+fail:
+ ERR("Failed to allocate memory\n");
+ HeapFree(GetProcessHeap(), 0, object->state.ps_consts_f);
+ HeapFree(GetProcessHeap(), 0, object->changed.pixelShaderConstantsF);
+ HeapFree(GetProcessHeap(), 0, object->state.vs_consts_f);
+ HeapFree(GetProcessHeap(), 0, object->changed.vertexShaderConstantsF);
+ HeapFree(GetProcessHeap(), 0, object->contained_vs_consts_f);
+ HeapFree(GetProcessHeap(), 0, object->contained_ps_consts_f);
+ return E_OUTOFMEMORY;
+}
+
+static inline void stateblock_set_bits(DWORD *map, UINT map_size)
+{
+ DWORD mask = (1 << (map_size & 0x1f)) - 1;
+ memset(map, 0xff, (map_size >> 5) * sizeof(*map));
+ if (mask) map[map_size >> 5] = mask;
+}
+
+/* Set all members of a stateblock savedstate to the given value */
+static void stateblock_savedstates_set_all(struct wined3d_saved_states *states, DWORD vs_consts, DWORD ps_consts)
+{
+ unsigned int i;
+
+ /* Single values */
+ states->primitive_type = 1;
+ states->indices = 1;
+ states->material = 1;
+ states->viewport = 1;
+ states->vertexDecl = 1;
+ states->pixelShader = 1;
+ states->vertexShader = 1;
+ states->scissorRect = 1;
+
+ /* Fixed size arrays */
+ states->streamSource = 0xffff;
+ states->streamFreq = 0xffff;
+ states->textures = 0xfffff;
+ stateblock_set_bits(states->transform, HIGHEST_TRANSFORMSTATE + 1);
+ stateblock_set_bits(states->renderState, WINEHIGHEST_RENDER_STATE + 1);
+ for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = 0x3ffff;
+ for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = 0x3ffe;
+ states->clipplane = 0xffffffff;
+ states->pixelShaderConstantsB = 0xffff;
+ states->pixelShaderConstantsI = 0xffff;
+ states->vertexShaderConstantsB = 0xffff;
+ states->vertexShaderConstantsI = 0xffff;
+
+ /* Dynamically sized arrays */
+ memset(states->pixelShaderConstantsF, TRUE, sizeof(BOOL) * ps_consts);
+ memset(states->vertexShaderConstantsF, TRUE, sizeof(BOOL) * vs_consts);
+}
+
+static void stateblock_savedstates_set_pixel(struct wined3d_saved_states *states, const DWORD num_constants)
+{
+ DWORD texture_mask = 0;
+ WORD sampler_mask = 0;
+ unsigned int i;
+
+ states->pixelShader = 1;
+
+ for (i = 0; i < sizeof(pixel_states_render) / sizeof(*pixel_states_render); ++i)
+ {
+ DWORD rs = pixel_states_render[i];
+ states->renderState[rs >> 5] |= 1 << (rs & 0x1f);
+ }
+
+ for (i = 0; i < sizeof(pixel_states_texture) / sizeof(*pixel_states_texture); ++i)
+ texture_mask |= 1 << pixel_states_texture[i];
+ for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = texture_mask;
+ for (i = 0; i < sizeof(pixel_states_sampler) / sizeof(*pixel_states_sampler); ++i)
+ sampler_mask |= 1 << pixel_states_sampler[i];
+ for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = sampler_mask;
+ states->pixelShaderConstantsB = 0xffff;
+ states->pixelShaderConstantsI = 0xffff;
+
+ memset(states->pixelShaderConstantsF, TRUE, sizeof(BOOL) * num_constants);
+}
+
+static void stateblock_savedstates_set_vertex(struct wined3d_saved_states *states, const DWORD num_constants)
+{
+ DWORD texture_mask = 0;
+ WORD sampler_mask = 0;
+ unsigned int i;
+
+ states->vertexDecl = 1;
+ states->vertexShader = 1;
+
+ for (i = 0; i < sizeof(vertex_states_render) / sizeof(*vertex_states_render); ++i)
+ {
+ DWORD rs = vertex_states_render[i];
+ states->renderState[rs >> 5] |= 1 << (rs & 0x1f);
+ }
+
+ for (i = 0; i < sizeof(vertex_states_texture) / sizeof(*vertex_states_texture); ++i)
+ texture_mask |= 1 << vertex_states_texture[i];
+ for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = texture_mask;
+ for (i = 0; i < sizeof(vertex_states_sampler) / sizeof(*vertex_states_sampler); ++i)
+ sampler_mask |= 1 << vertex_states_sampler[i];
+ for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = sampler_mask;
+ states->vertexShaderConstantsB = 0xffff;
+ states->vertexShaderConstantsI = 0xffff;
+
+ memset(states->vertexShaderConstantsF, TRUE, sizeof(BOOL) * num_constants);
+}
+
+void stateblock_init_contained_states(struct wined3d_stateblock *stateblock)
+{
+ const struct wined3d_d3d_info *d3d_info = &stateblock->device->adapter->d3d_info;
+ unsigned int i, j;
+
+ for (i = 0; i <= WINEHIGHEST_RENDER_STATE >> 5; ++i)
+ {
+ DWORD map = stateblock->changed.renderState[i];
+ for (j = 0; map; map >>= 1, ++j)
+ {
+ if (!(map & 1)) continue;
+
+ stateblock->contained_render_states[stateblock->num_contained_render_states] = (i << 5) | j;
+ ++stateblock->num_contained_render_states;
+ }
+ }
+
+ for (i = 0; i <= HIGHEST_TRANSFORMSTATE >> 5; ++i)
+ {
+ DWORD map = stateblock->changed.transform[i];
+ for (j = 0; map; map >>= 1, ++j)
+ {
+ if (!(map & 1)) continue;
+
+ stateblock->contained_transform_states[stateblock->num_contained_transform_states] = (i << 5) | j;
+ ++stateblock->num_contained_transform_states;
+ }
+ }
+
+ for (i = 0; i < d3d_info->limits.vs_uniform_count; ++i)
+ {
+ if (stateblock->changed.vertexShaderConstantsF[i])
+ {
+ stateblock->contained_vs_consts_f[stateblock->num_contained_vs_consts_f] = i;
+ ++stateblock->num_contained_vs_consts_f;
+ }
+ }
+
+ for (i = 0; i < MAX_CONST_I; ++i)
+ {
+ if (stateblock->changed.vertexShaderConstantsI & (1 << i))
+ {
+ stateblock->contained_vs_consts_i[stateblock->num_contained_vs_consts_i] = i;
+ ++stateblock->num_contained_vs_consts_i;
+ }
+ }
+
+ for (i = 0; i < MAX_CONST_B; ++i)
+ {
+ if (stateblock->changed.vertexShaderConstantsB & (1 << i))
+ {
+ stateblock->contained_vs_consts_b[stateblock->num_contained_vs_consts_b] = i;
+ ++stateblock->num_contained_vs_consts_b;
+ }
+ }
+
+ for (i = 0; i < d3d_info->limits.ps_uniform_count; ++i)
+ {
+ if (stateblock->changed.pixelShaderConstantsF[i])
+ {
+ stateblock->contained_ps_consts_f[stateblock->num_contained_ps_consts_f] = i;
+ ++stateblock->num_contained_ps_consts_f;
+ }
+ }
+
+ for (i = 0; i < MAX_CONST_I; ++i)
+ {
+ if (stateblock->changed.pixelShaderConstantsI & (1 << i))
+ {
+ stateblock->contained_ps_consts_i[stateblock->num_contained_ps_consts_i] = i;
+ ++stateblock->num_contained_ps_consts_i;
+ }
+ }
+
+ for (i = 0; i < MAX_CONST_B; ++i)
+ {
+ if (stateblock->changed.pixelShaderConstantsB & (1 << i))
+ {
+ stateblock->contained_ps_consts_b[stateblock->num_contained_ps_consts_b] = i;
+ ++stateblock->num_contained_ps_consts_b;
+ }
+ }
+
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ DWORD map = stateblock->changed.textureState[i];
+
+ for(j = 0; map; map >>= 1, ++j)
+ {
+ if (!(map & 1)) continue;
+
+ stateblock->contained_tss_states[stateblock->num_contained_tss_states].stage = i;
+ stateblock->contained_tss_states[stateblock->num_contained_tss_states].state = j;
+ ++stateblock->num_contained_tss_states;
+ }
+ }
+
+ for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
+ {
+ DWORD map = stateblock->changed.samplerState[i];
+
+ for (j = 0; map; map >>= 1, ++j)
+ {
+ if (!(map & 1)) continue;
+
+ stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].stage = i;
+ stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].state = j;
+ ++stateblock->num_contained_sampler_states;
+ }
+ }
+}
+
+static void stateblock_init_lights(struct wined3d_stateblock *stateblock, struct list *light_map)
+{
+ unsigned int i;
+
+ for (i = 0; i < LIGHTMAP_SIZE; ++i)
+ {
+ const struct wined3d_light_info *src_light;
+
+ LIST_FOR_EACH_ENTRY(src_light, &light_map[i], struct wined3d_light_info, entry)
+ {
+ struct wined3d_light_info *dst_light = HeapAlloc(GetProcessHeap(), 0, sizeof(*dst_light));
+
+ *dst_light = *src_light;
+ list_add_tail(&stateblock->state.light_map[i], &dst_light->entry);
+ }
+ }
+}
+
+ULONG CDECL wined3d_stateblock_incref(struct wined3d_stateblock *stateblock)
+{
+ ULONG refcount = InterlockedIncrement(&stateblock->ref);
+
+ TRACE("%p increasing refcount to %u.\n", stateblock, refcount);
+
+ return refcount;
+}
+
+void stateblock_unbind_resources(struct wined3d_stateblock *stateblock)
+{
+ struct wined3d_state *state = &stateblock->state;
+ struct wined3d_vertex_declaration *decl;
+ struct wined3d_sampler *sampler;
+ struct wined3d_texture *texture;
+ struct wined3d_buffer *buffer;
+ struct wined3d_shader *shader;
+ unsigned int i;
+
+ if ((decl = state->vertex_declaration))
+ {
+ state->vertex_declaration = NULL;
+ wined3d_vertex_declaration_decref(decl);
+ }
+
+ for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
+ {
+ if ((texture = state->textures[i]))
+ {
+ state->textures[i] = NULL;
+ wined3d_texture_decref(texture);
+ }
+ }
+
+ for (i = 0; i < MAX_STREAM_OUT; ++i)
+ {
+ if ((buffer = state->stream_output[i].buffer))
+ {
+ state->stream_output[i].buffer = NULL;
+ wined3d_buffer_decref(buffer);
+ }
+ }
+
+ for (i = 0; i < MAX_STREAMS; ++i)
+ {
+ if ((buffer = state->streams[i].buffer))
+ {
+ state->streams[i].buffer = NULL;
+ wined3d_buffer_decref(buffer);
+ }
+ }
+
+ if ((buffer = state->index_buffer))
+ {
+ state->index_buffer = NULL;
+ wined3d_buffer_decref(buffer);
+ }
+
+ if ((shader = state->vertex_shader))
+ {
+ state->vertex_shader = NULL;
+ wined3d_shader_decref(shader);
+ }
+
+ for (i = 0; i < MAX_CONSTANT_BUFFERS; ++i)
+ {
+ if ((buffer = state->vs_cb[i]))
+ {
+ state->vs_cb[i] = NULL;
+ wined3d_buffer_decref(buffer);
+ }
+ }
+
+ for (i = 0; i < MAX_SAMPLER_OBJECTS; ++i)
+ {
+ if ((sampler = state->vs_sampler[i]))
+ {
+ state->vs_sampler[i] = NULL;
+ wined3d_sampler_decref(sampler);
+ }
+ }
+
+ if ((shader = state->geometry_shader))
+ {
+ state->geometry_shader = NULL;
+ wined3d_shader_decref(shader);
+ }
+
+ for (i = 0; i < MAX_CONSTANT_BUFFERS; ++i)
+ {
+ if ((buffer = state->gs_cb[i]))
+ {
+ state->gs_cb[i] = NULL;
+ wined3d_buffer_decref(buffer);
+ }
+ }
+
+ for (i = 0; i < MAX_SAMPLER_OBJECTS; ++i)
+ {
+ if ((sampler = state->gs_sampler[i]))
+ {
+ state->gs_sampler[i] = NULL;
+ wined3d_sampler_decref(sampler);
+ }
+ }
+
+ if ((shader = state->pixel_shader))
+ {
+ state->pixel_shader = NULL;
+ wined3d_shader_decref(shader);
+ }
+
+ for (i = 0; i < MAX_SAMPLER_OBJECTS; ++i)
+ {
+ if ((sampler = state->ps_sampler[i]))
+ {
+ state->ps_sampler[i] = NULL;
+ wined3d_sampler_decref(sampler);
+ }
+ }
+
+ for (i = 0; i < MAX_CONSTANT_BUFFERS; ++i)
+ {
+ if ((buffer = state->ps_cb[i]))
+ {
+ state->ps_cb[i] = NULL;
+ wined3d_buffer_decref(buffer);
+ }
+ }
+}
+
+ULONG CDECL wined3d_stateblock_decref(struct wined3d_stateblock *stateblock)
+{
+ ULONG refcount = InterlockedDecrement(&stateblock->ref);
+
+ TRACE("%p decreasing refcount to %u\n", stateblock, refcount);
+
+ if (!refcount)
+ {
+ int counter;
+
+ stateblock_unbind_resources(stateblock);
+
+ for (counter = 0; counter < LIGHTMAP_SIZE; ++counter)
+ {
+ struct list *e1, *e2;
+ LIST_FOR_EACH_SAFE(e1, e2, &stateblock->state.light_map[counter])
+ {
+ struct wined3d_light_info *light = LIST_ENTRY(e1, struct wined3d_light_info, entry);
+ list_remove(&light->entry);
+ HeapFree(GetProcessHeap(), 0, light);
+ }
+ }
+
+ HeapFree(GetProcessHeap(), 0, stateblock->state.vs_consts_f);
+ HeapFree(GetProcessHeap(), 0, stateblock->changed.vertexShaderConstantsF);
+ HeapFree(GetProcessHeap(), 0, stateblock->state.ps_consts_f);
+ HeapFree(GetProcessHeap(), 0, stateblock->changed.pixelShaderConstantsF);
+ HeapFree(GetProcessHeap(), 0, stateblock->contained_vs_consts_f);
+ HeapFree(GetProcessHeap(), 0, stateblock->contained_ps_consts_f);
+ HeapFree(GetProcessHeap(), 0, stateblock);
+ }
+
+ return refcount;
+}
+
+static void wined3d_state_record_lights(struct wined3d_state *dst_state, const struct wined3d_state *src_state)
+{
+ UINT i;
+
+ /* Lights... For a recorded state block, we just had a chain of actions
+ * to perform, so we need to walk that chain and update any actions which
+ * differ. */
+ for (i = 0; i < LIGHTMAP_SIZE; ++i)
+ {
+ struct list *e, *f;
+ LIST_FOR_EACH(e, &dst_state->light_map[i])
+ {
+ BOOL updated = FALSE;
+ struct wined3d_light_info *src = LIST_ENTRY(e, struct wined3d_light_info, entry), *realLight;
+
+ /* Look up the light in the destination */
+ LIST_FOR_EACH(f, &src_state->light_map[i])
+ {
+ realLight = LIST_ENTRY(f, struct wined3d_light_info, entry);
+ if (realLight->OriginalIndex == src->OriginalIndex)
+ {
+ src->OriginalParms = realLight->OriginalParms;
+
+ if (realLight->glIndex == -1 && src->glIndex != -1)
+ {
+ /* Light disabled */
+ dst_state->lights[src->glIndex] = NULL;
+ }
+ else if (realLight->glIndex != -1 && src->glIndex == -1)
+ {
+ /* Light enabled */
+ dst_state->lights[realLight->glIndex] = src;
+ }
+ src->glIndex = realLight->glIndex;
+ updated = TRUE;
+ break;
+ }
+ }
+
+ if (!updated)
+ {
+ /* This can happen if the light was originally created as a
+ * default light for SetLightEnable() while recording. */
+ WARN("Light %u in dst_state %p does not exist in src_state %p.\n",
+ src->OriginalIndex, dst_state, src_state);
+
+ src->OriginalParms = WINED3D_default_light;
+ if (src->glIndex != -1)
+ {
+ dst_state->lights[src->glIndex] = NULL;
+ src->glIndex = -1;
+ }
+ }
+ }
+ }
+}
+
+void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock)
+{
+ const struct wined3d_state *src_state = &stateblock->device->stateBlock->state;
+ unsigned int i;
+ DWORD map;
+
+ TRACE("stateblock %p.\n", stateblock);
+
+ TRACE("Capturing state %p.\n", src_state);
+
+ if (stateblock->changed.vertexShader && stateblock->state.vertex_shader != src_state->vertex_shader)
+ {
+ TRACE("Updating vertex shader from %p to %p\n",
+ stateblock->state.vertex_shader, src_state->vertex_shader);
+
+ if (src_state->vertex_shader)
+ wined3d_shader_incref(src_state->vertex_shader);
+ if (stateblock->state.vertex_shader)
+ wined3d_shader_decref(stateblock->state.vertex_shader);
+ stateblock->state.vertex_shader = src_state->vertex_shader;
+ }
+
+ /* Vertex shader float constants. */
+ for (i = 0; i < stateblock->num_contained_vs_consts_f; ++i)
+ {
+ unsigned int idx = stateblock->contained_vs_consts_f[i];
+
+ TRACE("Setting vs_consts_f[%u] to {%.8e, %.8e, %.8e, %.8e}.\n", idx,
+ src_state->vs_consts_f[idx * 4 + 0],
+ src_state->vs_consts_f[idx * 4 + 1],
+ src_state->vs_consts_f[idx * 4 + 2],
+ src_state->vs_consts_f[idx * 4 + 3]);
+
+ stateblock->state.vs_consts_f[idx * 4 + 0] = src_state->vs_consts_f[idx * 4 + 0];
+ stateblock->state.vs_consts_f[idx * 4 + 1] = src_state->vs_consts_f[idx * 4 + 1];
+ stateblock->state.vs_consts_f[idx * 4 + 2] = src_state->vs_consts_f[idx * 4 + 2];
+ stateblock->state.vs_consts_f[idx * 4 + 3] = src_state->vs_consts_f[idx * 4 + 3];
+ }
+
+ /* Vertex shader integer constants. */
+ for (i = 0; i < stateblock->num_contained_vs_consts_i; ++i)
+ {
+ unsigned int idx = stateblock->contained_vs_consts_i[i];
+
+ TRACE("Setting vs_consts[%u] to {%d, %d, %d, %d}.\n", idx,
+ src_state->vs_consts_i[idx * 4 + 0],
+ src_state->vs_consts_i[idx * 4 + 1],
+ src_state->vs_consts_i[idx * 4 + 2],
+ src_state->vs_consts_i[idx * 4 + 3]);
+
+ stateblock->state.vs_consts_i[idx * 4 + 0] = src_state->vs_consts_i[idx * 4 + 0];
+ stateblock->state.vs_consts_i[idx * 4 + 1] = src_state->vs_consts_i[idx * 4 + 1];
+ stateblock->state.vs_consts_i[idx * 4 + 2] = src_state->vs_consts_i[idx * 4 + 2];
+ stateblock->state.vs_consts_i[idx * 4 + 3] = src_state->vs_consts_i[idx * 4 + 3];
+ }
+
+ /* Vertex shader boolean constants. */
+ for (i = 0; i < stateblock->num_contained_vs_consts_b; ++i)
+ {
+ unsigned int idx = stateblock->contained_vs_consts_b[i];
+
+ TRACE("Setting vs_consts_b[%u] to %s.\n",
+ idx, src_state->vs_consts_b[idx] ? "TRUE" : "FALSE");
+
+ stateblock->state.vs_consts_b[idx] = src_state->vs_consts_b[idx];
+ }
+
+ /* Pixel shader float constants. */
+ for (i = 0; i < stateblock->num_contained_ps_consts_f; ++i)
+ {
+ unsigned int idx = stateblock->contained_ps_consts_f[i];
+
+ TRACE("Setting ps_consts_f[%u] to {%.8e, %.8e, %.8e, %.8e}.\n", idx,
+ src_state->ps_consts_f[idx * 4 + 0],
+ src_state->ps_consts_f[idx * 4 + 1],
+ src_state->ps_consts_f[idx * 4 + 2],
+ src_state->ps_consts_f[idx * 4 + 3]);
+
+ stateblock->state.ps_consts_f[idx * 4 + 0] = src_state->ps_consts_f[idx * 4 + 0];
+ stateblock->state.ps_consts_f[idx * 4 + 1] = src_state->ps_consts_f[idx * 4 + 1];
+ stateblock->state.ps_consts_f[idx * 4 + 2] = src_state->ps_consts_f[idx * 4 + 2];
+ stateblock->state.ps_consts_f[idx * 4 + 3] = src_state->ps_consts_f[idx * 4 + 3];
+ }
+
+ /* Pixel shader integer constants. */
+ for (i = 0; i < stateblock->num_contained_ps_consts_i; ++i)
+ {
+ unsigned int idx = stateblock->contained_ps_consts_i[i];
+ TRACE("Setting ps_consts_i[%u] to {%d, %d, %d, %d}.\n", idx,
+ src_state->ps_consts_i[idx * 4 + 0],
+ src_state->ps_consts_i[idx * 4 + 1],
+ src_state->ps_consts_i[idx * 4 + 2],
+ src_state->ps_consts_i[idx * 4 + 3]);
+
+ stateblock->state.ps_consts_i[idx * 4 + 0] = src_state->ps_consts_i[idx * 4 + 0];
+ stateblock->state.ps_consts_i[idx * 4 + 1] = src_state->ps_consts_i[idx * 4 + 1];
+ stateblock->state.ps_consts_i[idx * 4 + 2] = src_state->ps_consts_i[idx * 4 + 2];
+ stateblock->state.ps_consts_i[idx * 4 + 3] = src_state->ps_consts_i[idx * 4 + 3];
+ }
+
+ /* Pixel shader boolean constants. */
+ for (i = 0; i < stateblock->num_contained_ps_consts_b; ++i)
+ {
+ unsigned int idx = stateblock->contained_ps_consts_b[i];
+ TRACE("Setting ps_consts_b[%u] to %s.\n",
+ idx, src_state->ps_consts_b[idx] ? "TRUE" : "FALSE");
+
+ stateblock->state.ps_consts_b[idx] = src_state->ps_consts_b[idx];
+ }
+
+ /* Others + Render & Texture */
+ for (i = 0; i < stateblock->num_contained_transform_states; ++i)
+ {
+ enum wined3d_transform_state transform = stateblock->contained_transform_states[i];
+
+ TRACE("Updating transform %#x.\n", transform);
+
+ stateblock->state.transforms[transform] = src_state->transforms[transform];
+ }
+
+ if (stateblock->changed.primitive_type)
+ stateblock->state.gl_primitive_type = src_state->gl_primitive_type;
+
+ if (stateblock->changed.indices
+ && ((stateblock->state.index_buffer != src_state->index_buffer)
+ || (stateblock->state.base_vertex_index != src_state->base_vertex_index)
+ || (stateblock->state.index_format != src_state->index_format)))
+ {
+ TRACE("Updating index buffer to %p, base vertex index to %d.\n",
+ src_state->index_buffer, src_state->base_vertex_index);
+
+ if (src_state->index_buffer)
+ wined3d_buffer_incref(src_state->index_buffer);
+ if (stateblock->state.index_buffer)
+ wined3d_buffer_decref(stateblock->state.index_buffer);
+ stateblock->state.index_buffer = src_state->index_buffer;
+ stateblock->state.base_vertex_index = src_state->base_vertex_index;
+ stateblock->state.index_format = src_state->index_format;
+ }
+
+ if (stateblock->changed.vertexDecl && stateblock->state.vertex_declaration != src_state->vertex_declaration)
+ {
+ TRACE("Updating vertex declaration from %p to %p.\n",
+ stateblock->state.vertex_declaration, src_state->vertex_declaration);
+
+ if (src_state->vertex_declaration)
+ wined3d_vertex_declaration_incref(src_state->vertex_declaration);
+ if (stateblock->state.vertex_declaration)
+ wined3d_vertex_declaration_decref(stateblock->state.vertex_declaration);
+ stateblock->state.vertex_declaration = src_state->vertex_declaration;
+ }
+
+ if (stateblock->changed.material
+ && memcmp(&src_state->material, &stateblock->state.material, sizeof(stateblock->state.material)))
+ {
+ TRACE("Updating material.\n");
+
+ stateblock->state.material = src_state->material;
+ }
+
+ if (stateblock->changed.viewport
+ && memcmp(&src_state->viewport, &stateblock->state.viewport, sizeof(stateblock->state.viewport)))
+ {
+ TRACE("Updating viewport.\n");
+
+ stateblock->state.viewport = src_state->viewport;
+ }
+
+ if (stateblock->changed.scissorRect && memcmp(&src_state->scissor_rect,
+ &stateblock->state.scissor_rect, sizeof(stateblock->state.scissor_rect)))
+ {
+ TRACE("Updating scissor rect.\n");
+
+ stateblock->state.scissor_rect = src_state->scissor_rect;
+ }
+
+ map = stateblock->changed.streamSource;
+ for (i = 0; map; map >>= 1, ++i)
+ {
+ if (!(map & 1)) continue;
+
+ if (stateblock->state.streams[i].stride != src_state->streams[i].stride
+ || stateblock->state.streams[i].buffer != src_state->streams[i].buffer)
+ {
+ TRACE("Updating stream source %u to %p, stride to %u.\n",
+ i, src_state->streams[i].buffer,
+ src_state->streams[i].stride);
+
+ stateblock->state.streams[i].stride = src_state->streams[i].stride;
+ if (src_state->streams[i].buffer)
+ wined3d_buffer_incref(src_state->streams[i].buffer);
+ if (stateblock->state.streams[i].buffer)
+ wined3d_buffer_decref(stateblock->state.streams[i].buffer);
+ stateblock->state.streams[i].buffer = src_state->streams[i].buffer;
+ }
+ }
+
+ map = stateblock->changed.streamFreq;
+ for (i = 0; map; map >>= 1, ++i)
+ {
+ if (!(map & 1)) continue;
+
+ if (stateblock->state.streams[i].frequency != src_state->streams[i].frequency
+ || stateblock->state.streams[i].flags != src_state->streams[i].flags)
+ {
+ TRACE("Updating stream frequency %u to %u flags to %#x.\n",
+ i, src_state->streams[i].frequency, src_state->streams[i].flags);
+
+ stateblock->state.streams[i].frequency = src_state->streams[i].frequency;
+ stateblock->state.streams[i].flags = src_state->streams[i].flags;
+ }
+ }
+
+ map = stateblock->changed.clipplane;
+ for (i = 0; map; map >>= 1, ++i)
+ {
+ if (!(map & 1)) continue;
+
+ if (memcmp(&stateblock->state.clip_planes[i], &src_state->clip_planes[i], sizeof(src_state->clip_planes[i])))
+ {
+ TRACE("Updating clipplane %u.\n", i);
+ stateblock->state.clip_planes[i] = src_state->clip_planes[i];
+ }
+ }
+
+ /* Render */
+ for (i = 0; i < stateblock->num_contained_render_states; ++i)
+ {
+ enum wined3d_render_state rs = stateblock->contained_render_states[i];
+
+ TRACE("Updating render state %#x to %u.\n", rs, src_state->render_states[rs]);
+
+ stateblock->state.render_states[rs] = src_state->render_states[rs];
+ }
+
+ /* Texture states */
+ for (i = 0; i < stateblock->num_contained_tss_states; ++i)
+ {
+ DWORD stage = stateblock->contained_tss_states[i].stage;
+ DWORD state = stateblock->contained_tss_states[i].state;
+
+ TRACE("Updating texturestage state %u, %u to %#x (was %#x).\n", stage, state,
+ src_state->texture_states[stage][state], stateblock->state.texture_states[stage][state]);
+
+ stateblock->state.texture_states[stage][state] = src_state->texture_states[stage][state];
+ }
+
+ /* Samplers */
+ map = stateblock->changed.textures;
+ for (i = 0; map; map >>= 1, ++i)
+ {
+ if (!(map & 1)) continue;
+
+ TRACE("Updating texture %u to %p (was %p).\n",
+ i, src_state->textures[i], stateblock->state.textures[i]);
+
+ if (src_state->textures[i])
+ wined3d_texture_incref(src_state->textures[i]);
+ if (stateblock->state.textures[i])
+ wined3d_texture_decref(stateblock->state.textures[i]);
+ stateblock->state.textures[i] = src_state->textures[i];
+ }
+
+ for (i = 0; i < stateblock->num_contained_sampler_states; ++i)
+ {
+ DWORD stage = stateblock->contained_sampler_states[i].stage;
+ DWORD state = stateblock->contained_sampler_states[i].state;
+
+ TRACE("Updating sampler state %u, %u to %#x (was %#x).\n", stage, state,
+ src_state->sampler_states[stage][state], stateblock->state.sampler_states[stage][state]);
+
+ stateblock->state.sampler_states[stage][state] = src_state->sampler_states[stage][state];
+ }
+
+ if (stateblock->changed.pixelShader && stateblock->state.pixel_shader != src_state->pixel_shader)
+ {
+ if (src_state->pixel_shader)
+ wined3d_shader_incref(src_state->pixel_shader);
+ if (stateblock->state.pixel_shader)
+ wined3d_shader_decref(stateblock->state.pixel_shader);
+ stateblock->state.pixel_shader = src_state->pixel_shader;
+ }
+
+ wined3d_state_record_lights(&stateblock->state, src_state);
+
+ TRACE("Capture done.\n");
+}
+
+static void apply_lights(struct wined3d_device *device, const struct wined3d_state *state)
+{
+ UINT i;
+
+ for (i = 0; i < LIGHTMAP_SIZE; ++i)
+ {
+ struct list *e;
+
+ LIST_FOR_EACH(e, &state->light_map[i])
+ {
+ const struct wined3d_light_info *light = LIST_ENTRY(e, struct wined3d_light_info, entry);
+
+ wined3d_device_set_light(device, light->OriginalIndex, &light->OriginalParms);
+ wined3d_device_set_light_enable(device, light->OriginalIndex, light->glIndex != -1);
+ }
+ }
+}
+
+void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock)
+{
+ struct wined3d_device *device = stateblock->device;
+ unsigned int i;
+ DWORD map;
+
+ TRACE("Applying stateblock %p to device %p.\n", stateblock, device);
+
+ if (stateblock->changed.vertexShader)
+ wined3d_device_set_vertex_shader(device, stateblock->state.vertex_shader);
+
+ /* Vertex Shader Constants. */
+ for (i = 0; i < stateblock->num_contained_vs_consts_f; ++i)
+ {
+ wined3d_device_set_vs_consts_f(device, stateblock->contained_vs_consts_f[i],
+ stateblock->state.vs_consts_f + stateblock->contained_vs_consts_f[i] * 4, 1);
+ }
+ for (i = 0; i < stateblock->num_contained_vs_consts_i; ++i)
+ {
+ wined3d_device_set_vs_consts_i(device, stateblock->contained_vs_consts_i[i],
+ stateblock->state.vs_consts_i + stateblock->contained_vs_consts_i[i] * 4, 1);
+ }
+ for (i = 0; i < stateblock->num_contained_vs_consts_b; ++i)
+ {
+ wined3d_device_set_vs_consts_b(device, stateblock->contained_vs_consts_b[i],
+ stateblock->state.vs_consts_b + stateblock->contained_vs_consts_b[i], 1);
+ }
+
+ apply_lights(device, &stateblock->state);
+
+ if (stateblock->changed.pixelShader)
+ wined3d_device_set_pixel_shader(device, stateblock->state.pixel_shader);
+
+ /* Pixel Shader Constants. */
+ for (i = 0; i < stateblock->num_contained_ps_consts_f; ++i)
+ {
+ wined3d_device_set_ps_consts_f(device, stateblock->contained_ps_consts_f[i],
+ stateblock->state.ps_consts_f + stateblock->contained_ps_consts_f[i] * 4, 1);
+ }
+ for (i = 0; i < stateblock->num_contained_ps_consts_i; ++i)
+ {
+ wined3d_device_set_ps_consts_i(device, stateblock->contained_ps_consts_i[i],
+ stateblock->state.ps_consts_i + stateblock->contained_ps_consts_i[i] * 4, 1);
+ }
+ for (i = 0; i < stateblock->num_contained_ps_consts_b; ++i)
+ {
+ wined3d_device_set_ps_consts_b(device, stateblock->contained_ps_consts_b[i],
+ stateblock->state.ps_consts_b + stateblock->contained_ps_consts_b[i], 1);
+ }
+
+ /* Render states. */
+ for (i = 0; i < stateblock->num_contained_render_states; ++i)
+ {
+ wined3d_device_set_render_state(device, stateblock->contained_render_states[i],
+ stateblock->state.render_states[stateblock->contained_render_states[i]]);
+ }
+
+ /* Texture states. */
+ for (i = 0; i < stateblock->num_contained_tss_states; ++i)
+ {
+ DWORD stage = stateblock->contained_tss_states[i].stage;
+ DWORD state = stateblock->contained_tss_states[i].state;
+
+ wined3d_device_set_texture_stage_state(device, stage, state, stateblock->state.texture_states[stage][state]);
+ }
+
+ /* Sampler states. */
+ for (i = 0; i < stateblock->num_contained_sampler_states; ++i)
+ {
+ DWORD stage = stateblock->contained_sampler_states[i].stage;
+ DWORD state = stateblock->contained_sampler_states[i].state;
+ DWORD value = stateblock->state.sampler_states[stage][state];
+
+ if (stage >= MAX_FRAGMENT_SAMPLERS) stage += WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS;
+ wined3d_device_set_sampler_state(device, stage, state, value);
+ }
+
+ /* Transform states. */
+ for (i = 0; i < stateblock->num_contained_transform_states; ++i)
+ {
+ wined3d_device_set_transform(device, stateblock->contained_transform_states[i],
+ &stateblock->state.transforms[stateblock->contained_transform_states[i]]);
+ }
+
+ if (stateblock->changed.primitive_type)
+ {
+ GLenum gl_primitive_type, prev;
+
+ device->updateStateBlock->changed.primitive_type = TRUE;
+ gl_primitive_type = stateblock->state.gl_primitive_type;
+ prev = device->updateStateBlock->state.gl_primitive_type;
+ device->updateStateBlock->state.gl_primitive_type = gl_primitive_type;
+ if (gl_primitive_type != prev && (gl_primitive_type == GL_POINTS || prev == GL_POINTS))
+ device_invalidate_state(device, STATE_POINT_SIZE_ENABLE);
+ }
+
+ if (stateblock->changed.indices)
+ {
+ wined3d_device_set_index_buffer(device, stateblock->state.index_buffer, stateblock->state.index_format);
+ wined3d_device_set_base_vertex_index(device, stateblock->state.base_vertex_index);
+ }
+
+ if (stateblock->changed.vertexDecl && stateblock->state.vertex_declaration)
+ wined3d_device_set_vertex_declaration(device, stateblock->state.vertex_declaration);
+
+ if (stateblock->changed.material)
+ wined3d_device_set_material(device, &stateblock->state.material);
+
+ if (stateblock->changed.viewport)
+ wined3d_device_set_viewport(device, &stateblock->state.viewport);
+
+ if (stateblock->changed.scissorRect)
+ wined3d_device_set_scissor_rect(device, &stateblock->state.scissor_rect);
+
+ map = stateblock->changed.streamSource;
+ for (i = 0; map; map >>= 1, ++i)
+ {
+ if (map & 1)
+ wined3d_device_set_stream_source(device, i,
+ stateblock->state.streams[i].buffer,
+ 0, stateblock->state.streams[i].stride);
+ }
+
+ map = stateblock->changed.streamFreq;
+ for (i = 0; map; map >>= 1, ++i)
+ {
+ if (map & 1)
+ wined3d_device_set_stream_source_freq(device, i,
+ stateblock->state.streams[i].frequency | stateblock->state.streams[i].flags);
+ }
+
+ map = stateblock->changed.textures;
+ for (i = 0; map; map >>= 1, ++i)
+ {
+ DWORD stage;
+
+ if (!(map & 1)) continue;
+
+ stage = i < MAX_FRAGMENT_SAMPLERS ? i : WINED3DVERTEXTEXTURESAMPLER0 + i - MAX_FRAGMENT_SAMPLERS;
+ wined3d_device_set_texture(device, stage, stateblock->state.textures[i]);
+ }
+
+ map = stateblock->changed.clipplane;
+ for (i = 0; map; map >>= 1, ++i)
+ {
+ if (!(map & 1)) continue;
+
+ wined3d_device_set_clip_plane(device, i, &stateblock->state.clip_planes[i]);
+ }
+
+ stateblock->device->stateBlock->state.lowest_disabled_stage = MAX_TEXTURES - 1;
+ for (i = 0; i < MAX_TEXTURES - 1; ++i)
+ {
+ if (stateblock->device->stateBlock->state.texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE)
+ {
+ stateblock->device->stateBlock->state.lowest_disabled_stage = i;
+ break;
+ }
+ }
+
+ TRACE("Applied stateblock %p.\n", stateblock);
+}
+
+void stateblock_init_default_state(struct wined3d_stateblock *stateblock)
+{
+ struct wined3d_device *device = stateblock->device;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+ struct wined3d_state *state = &stateblock->state;
+ union
+ {
+ struct wined3d_line_pattern lp;
+ DWORD d;
+ } lp;
+ union {
+ float f;
+ DWORD d;
+ } tmpfloat;
+ unsigned int i;
+ struct wined3d_swapchain *swapchain;
+ struct wined3d_surface *backbuffer;
+ static const struct wined3d_matrix identity =
+ {{{
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f,
+ }}};
+
+ TRACE("stateblock %p.\n", stateblock);
+
+ memset(stateblock->changed.pixelShaderConstantsF, 0, d3d_info->limits.ps_uniform_count * sizeof(BOOL));
+ memset(stateblock->changed.vertexShaderConstantsF, 0, d3d_info->limits.vs_uniform_count * sizeof(BOOL));
+
+ /* Set some of the defaults for lights, transforms etc */
+ state->transforms[WINED3D_TS_PROJECTION] = identity;
+ state->transforms[WINED3D_TS_VIEW] = identity;
+ for (i = 0; i < 256; ++i)
+ {
+ state->transforms[WINED3D_TS_WORLD_MATRIX(i)] = identity;
+ }
+
+ state->fb = &device->fb;
+
+ TRACE("Render states\n");
+ /* Render states: */
+ if (device->auto_depth_stencil)
+ state->render_states[WINED3D_RS_ZENABLE] = WINED3D_ZB_TRUE;
+ else
+ state->render_states[WINED3D_RS_ZENABLE] = WINED3D_ZB_FALSE;
+ state->render_states[WINED3D_RS_FILLMODE] = WINED3D_FILL_SOLID;
+ state->render_states[WINED3D_RS_SHADEMODE] = WINED3D_SHADE_GOURAUD;
+ lp.lp.repeat_factor = 0;
+ lp.lp.line_pattern = 0;
+ state->render_states[WINED3D_RS_LINEPATTERN] = lp.d;
+ state->render_states[WINED3D_RS_ZWRITEENABLE] = TRUE;
+ state->render_states[WINED3D_RS_ALPHATESTENABLE] = FALSE;
+ state->render_states[WINED3D_RS_LASTPIXEL] = TRUE;
+ state->render_states[WINED3D_RS_SRCBLEND] = WINED3D_BLEND_ONE;
+ state->render_states[WINED3D_RS_DESTBLEND] = WINED3D_BLEND_ZERO;
+ state->render_states[WINED3D_RS_CULLMODE] = WINED3D_CULL_CCW;
+ state->render_states[WINED3D_RS_ZFUNC] = WINED3D_CMP_LESSEQUAL;
+ state->render_states[WINED3D_RS_ALPHAFUNC] = WINED3D_CMP_ALWAYS;
+ state->render_states[WINED3D_RS_ALPHAREF] = 0;
+ state->render_states[WINED3D_RS_DITHERENABLE] = FALSE;
+ state->render_states[WINED3D_RS_ALPHABLENDENABLE] = FALSE;
+ state->render_states[WINED3D_RS_FOGENABLE] = FALSE;
+ state->render_states[WINED3D_RS_SPECULARENABLE] = FALSE;
+ state->render_states[WINED3D_RS_ZVISIBLE] = 0;
+ state->render_states[WINED3D_RS_FOGCOLOR] = 0;
+ state->render_states[WINED3D_RS_FOGTABLEMODE] = WINED3D_FOG_NONE;
+ tmpfloat.f = 0.0f;
+ state->render_states[WINED3D_RS_FOGSTART] = tmpfloat.d;
+ tmpfloat.f = 1.0f;
+ state->render_states[WINED3D_RS_FOGEND] = tmpfloat.d;
+ tmpfloat.f = 1.0f;
+ state->render_states[WINED3D_RS_FOGDENSITY] = tmpfloat.d;
+ state->render_states[WINED3D_RS_EDGEANTIALIAS] = FALSE;
+ state->render_states[WINED3D_RS_RANGEFOGENABLE] = FALSE;
+ state->render_states[WINED3D_RS_STENCILENABLE] = FALSE;
+ state->render_states[WINED3D_RS_STENCILFAIL] = WINED3D_STENCIL_OP_KEEP;
+ state->render_states[WINED3D_RS_STENCILZFAIL] = WINED3D_STENCIL_OP_KEEP;
+ state->render_states[WINED3D_RS_STENCILPASS] = WINED3D_STENCIL_OP_KEEP;
+ state->render_states[WINED3D_RS_STENCILREF] = 0;
+ state->render_states[WINED3D_RS_STENCILMASK] = 0xffffffff;
+ state->render_states[WINED3D_RS_STENCILFUNC] = WINED3D_CMP_ALWAYS;
+ state->render_states[WINED3D_RS_STENCILWRITEMASK] = 0xffffffff;
+ state->render_states[WINED3D_RS_TEXTUREFACTOR] = 0xffffffff;
+ state->render_states[WINED3D_RS_WRAP0] = 0;
+ state->render_states[WINED3D_RS_WRAP1] = 0;
+ state->render_states[WINED3D_RS_WRAP2] = 0;
+ state->render_states[WINED3D_RS_WRAP3] = 0;
+ state->render_states[WINED3D_RS_WRAP4] = 0;
+ state->render_states[WINED3D_RS_WRAP5] = 0;
+ state->render_states[WINED3D_RS_WRAP6] = 0;
+ state->render_states[WINED3D_RS_WRAP7] = 0;
+ state->render_states[WINED3D_RS_CLIPPING] = TRUE;
+ state->render_states[WINED3D_RS_LIGHTING] = TRUE;
+ state->render_states[WINED3D_RS_AMBIENT] = 0;
+ state->render_states[WINED3D_RS_FOGVERTEXMODE] = WINED3D_FOG_NONE;
+ state->render_states[WINED3D_RS_COLORVERTEX] = TRUE;
+ state->render_states[WINED3D_RS_LOCALVIEWER] = TRUE;
+ state->render_states[WINED3D_RS_NORMALIZENORMALS] = FALSE;
+ state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE] = WINED3D_MCS_COLOR1;
+ state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] = WINED3D_MCS_COLOR2;
+ state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] = WINED3D_MCS_MATERIAL;
+ state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] = WINED3D_MCS_MATERIAL;
+ state->render_states[WINED3D_RS_VERTEXBLEND] = WINED3D_VBF_DISABLE;
+ state->render_states[WINED3D_RS_CLIPPLANEENABLE] = 0;
+ state->render_states[WINED3D_RS_SOFTWAREVERTEXPROCESSING] = FALSE;
+ tmpfloat.f = 1.0f;
+ state->render_states[WINED3D_RS_POINTSIZE] = tmpfloat.d;
+ tmpfloat.f = 1.0f;
+ state->render_states[WINED3D_RS_POINTSIZE_MIN] = tmpfloat.d;
+ state->render_states[WINED3D_RS_POINTSPRITEENABLE] = FALSE;
+ state->render_states[WINED3D_RS_POINTSCALEENABLE] = FALSE;
+ tmpfloat.f = 1.0f;
+ state->render_states[WINED3D_RS_POINTSCALE_A] = tmpfloat.d;
+ tmpfloat.f = 0.0f;
+ state->render_states[WINED3D_RS_POINTSCALE_B] = tmpfloat.d;
+ tmpfloat.f = 0.0f;
+ state->render_states[WINED3D_RS_POINTSCALE_C] = tmpfloat.d;
+ state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS] = TRUE;
+ state->render_states[WINED3D_RS_MULTISAMPLEMASK] = 0xffffffff;
+ state->render_states[WINED3D_RS_PATCHEDGESTYLE] = WINED3D_PATCH_EDGE_DISCRETE;
+ tmpfloat.f = 1.0f;
+ state->render_states[WINED3D_RS_PATCHSEGMENTS] = tmpfloat.d;
+ state->render_states[WINED3D_RS_DEBUGMONITORTOKEN] = 0xbaadcafe;
+ tmpfloat.f = gl_info->limits.pointsize_max;
+ state->render_states[WINED3D_RS_POINTSIZE_MAX] = tmpfloat.d;
+ state->render_states[WINED3D_RS_INDEXEDVERTEXBLENDENABLE] = FALSE;
+ state->render_states[WINED3D_RS_COLORWRITEENABLE] = 0x0000000f;
+ tmpfloat.f = 0.0f;
+ state->render_states[WINED3D_RS_TWEENFACTOR] = tmpfloat.d;
+ state->render_states[WINED3D_RS_BLENDOP] = WINED3D_BLEND_OP_ADD;
+ state->render_states[WINED3D_RS_POSITIONDEGREE] = WINED3D_DEGREE_CUBIC;
+ state->render_states[WINED3D_RS_NORMALDEGREE] = WINED3D_DEGREE_LINEAR;
+ /* states new in d3d9 */
+ state->render_states[WINED3D_RS_SCISSORTESTENABLE] = FALSE;
+ state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS] = 0;
+ tmpfloat.f = 1.0f;
+ state->render_states[WINED3D_RS_MINTESSELLATIONLEVEL] = tmpfloat.d;
+ state->render_states[WINED3D_RS_MAXTESSELLATIONLEVEL] = tmpfloat.d;
+ state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE] = FALSE;
+ tmpfloat.f = 0.0f;
+ state->render_states[WINED3D_RS_ADAPTIVETESS_X] = tmpfloat.d;
+ state->render_states[WINED3D_RS_ADAPTIVETESS_Y] = tmpfloat.d;
+ tmpfloat.f = 1.0f;
+ state->render_states[WINED3D_RS_ADAPTIVETESS_Z] = tmpfloat.d;
+ tmpfloat.f = 0.0f;
+ state->render_states[WINED3D_RS_ADAPTIVETESS_W] = tmpfloat.d;
+ state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION] = FALSE;
+ state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE] = FALSE;
+ state->render_states[WINED3D_RS_CCW_STENCILFAIL] = WINED3D_STENCIL_OP_KEEP;
+ state->render_states[WINED3D_RS_CCW_STENCILZFAIL] = WINED3D_STENCIL_OP_KEEP;
+ state->render_states[WINED3D_RS_CCW_STENCILPASS] = WINED3D_STENCIL_OP_KEEP;
+ state->render_states[WINED3D_RS_CCW_STENCILFUNC] = WINED3D_CMP_ALWAYS;
+ state->render_states[WINED3D_RS_COLORWRITEENABLE1] = 0x0000000f;
+ state->render_states[WINED3D_RS_COLORWRITEENABLE2] = 0x0000000f;
+ state->render_states[WINED3D_RS_COLORWRITEENABLE3] = 0x0000000f;
+ state->render_states[WINED3D_RS_BLENDFACTOR] = 0xffffffff;
+ state->render_states[WINED3D_RS_SRGBWRITEENABLE] = 0;
+ state->render_states[WINED3D_RS_DEPTHBIAS] = 0;
+ state->render_states[WINED3D_RS_WRAP8] = 0;
+ state->render_states[WINED3D_RS_WRAP9] = 0;
+ state->render_states[WINED3D_RS_WRAP10] = 0;
+ state->render_states[WINED3D_RS_WRAP11] = 0;
+ state->render_states[WINED3D_RS_WRAP12] = 0;
+ state->render_states[WINED3D_RS_WRAP13] = 0;
+ state->render_states[WINED3D_RS_WRAP14] = 0;
+ state->render_states[WINED3D_RS_WRAP15] = 0;
+ state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE] = FALSE;
+ state->render_states[WINED3D_RS_SRCBLENDALPHA] = WINED3D_BLEND_ONE;
+ state->render_states[WINED3D_RS_DESTBLENDALPHA] = WINED3D_BLEND_ZERO;
+ state->render_states[WINED3D_RS_BLENDOPALPHA] = WINED3D_BLEND_OP_ADD;
+
+ /* Texture Stage States - Put directly into state block, we will call function below */
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ TRACE("Setting up default texture states for texture Stage %u.\n", i);
+ state->transforms[WINED3D_TS_TEXTURE0 + i] = identity;
+ state->texture_states[i][WINED3D_TSS_COLOR_OP] = i ? WINED3D_TOP_DISABLE : WINED3D_TOP_MODULATE;
+ state->texture_states[i][WINED3D_TSS_COLOR_ARG1] = WINED3DTA_TEXTURE;
+ state->texture_states[i][WINED3D_TSS_COLOR_ARG2] = WINED3DTA_CURRENT;
+ state->texture_states[i][WINED3D_TSS_ALPHA_OP] = i ? WINED3D_TOP_DISABLE : WINED3D_TOP_SELECT_ARG1;
+ state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] = WINED3DTA_TEXTURE;
+ state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] = WINED3DTA_CURRENT;
+ state->texture_states[i][WINED3D_TSS_BUMPENV_MAT00] = 0;
+ state->texture_states[i][WINED3D_TSS_BUMPENV_MAT01] = 0;
+ state->texture_states[i][WINED3D_TSS_BUMPENV_MAT10] = 0;
+ state->texture_states[i][WINED3D_TSS_BUMPENV_MAT11] = 0;
+ state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] = i;
+ state->texture_states[i][WINED3D_TSS_BUMPENV_LSCALE] = 0;
+ state->texture_states[i][WINED3D_TSS_BUMPENV_LOFFSET] = 0;
+ state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS] = WINED3D_TTFF_DISABLE;
+ state->texture_states[i][WINED3D_TSS_COLOR_ARG0] = WINED3DTA_CURRENT;
+ state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] = WINED3DTA_CURRENT;
+ state->texture_states[i][WINED3D_TSS_RESULT_ARG] = WINED3DTA_CURRENT;
+ }
+ state->lowest_disabled_stage = 1;
+
+ /* Sampler states*/
+ for (i = 0 ; i < MAX_COMBINED_SAMPLERS; ++i)
+ {
+ TRACE("Setting up default samplers states for sampler %u.\n", i);
+ state->sampler_states[i][WINED3D_SAMP_ADDRESS_U] = WINED3D_TADDRESS_WRAP;
+ state->sampler_states[i][WINED3D_SAMP_ADDRESS_V] = WINED3D_TADDRESS_WRAP;
+ state->sampler_states[i][WINED3D_SAMP_ADDRESS_W] = WINED3D_TADDRESS_WRAP;
+ state->sampler_states[i][WINED3D_SAMP_BORDER_COLOR] = 0;
+ state->sampler_states[i][WINED3D_SAMP_MAG_FILTER] = WINED3D_TEXF_POINT;
+ state->sampler_states[i][WINED3D_SAMP_MIN_FILTER] = WINED3D_TEXF_POINT;
+ state->sampler_states[i][WINED3D_SAMP_MIP_FILTER] = WINED3D_TEXF_NONE;
+ state->sampler_states[i][WINED3D_SAMP_MIPMAP_LOD_BIAS] = 0;
+ state->sampler_states[i][WINED3D_SAMP_MAX_MIP_LEVEL] = 0;
+ state->sampler_states[i][WINED3D_SAMP_MAX_ANISOTROPY] = 1;
+ state->sampler_states[i][WINED3D_SAMP_SRGB_TEXTURE] = 0;
+ /* TODO: Indicates which element of a multielement texture to use. */
+ state->sampler_states[i][WINED3D_SAMP_ELEMENT_INDEX] = 0;
+ /* TODO: Vertex offset in the presampled displacement map. */
+ state->sampler_states[i][WINED3D_SAMP_DMAP_OFFSET] = 0;
+ }
+
+ for (i = 0; i < gl_info->limits.textures; ++i)
+ {
+ state->textures[i] = NULL;
+ }
+
+ /* check the return values, because the GetBackBuffer call isn't valid for ddraw */
+ if ((swapchain = wined3d_device_get_swapchain(device, 0)))
+ {
+ if ((backbuffer = wined3d_swapchain_get_back_buffer(swapchain, 0, WINED3D_BACKBUFFER_TYPE_MONO)))
+ {
+ struct wined3d_resource_desc desc;
+
+ wined3d_resource_get_desc(&backbuffer->resource, &desc);
+
+ /* Set the default scissor rect values */
+ state->scissor_rect.left = 0;
+ state->scissor_rect.right = desc.width;
+ state->scissor_rect.top = 0;
+ state->scissor_rect.bottom = desc.height;
+ }
+
+ /* Set the default viewport */
+ state->viewport.x = 0;
+ state->viewport.y = 0;
+ state->viewport.width = swapchain->desc.backbuffer_width;
+ state->viewport.height = swapchain->desc.backbuffer_height;
+ state->viewport.min_z = 0.0f;
+ state->viewport.max_z = 1.0f;
+ }
+
+ TRACE("Done.\n");
+}
+
+static HRESULT stateblock_init(struct wined3d_stateblock *stateblock,
+ struct wined3d_device *device, enum wined3d_stateblock_type type)
+{
+ unsigned int i;
+ HRESULT hr;
+ const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
+
+ stateblock->ref = 1;
+ stateblock->device = device;
+
+ for (i = 0; i < LIGHTMAP_SIZE; i++)
+ {
+ list_init(&stateblock->state.light_map[i]);
+ }
+
+ hr = stateblock_allocate_shader_constants(stateblock);
+ if (FAILED(hr)) return hr;
+
+ /* The WINED3D_SBT_INIT stateblock type is used during initialization to
+ * produce a placeholder stateblock so other functions called can update a
+ * state block. */
+ if (type == WINED3D_SBT_INIT || type == WINED3D_SBT_RECORDED) return WINED3D_OK;
+
+ TRACE("Updating changed flags appropriate for type %#x.\n", type);
+
+ switch (type)
+ {
+ case WINED3D_SBT_ALL:
+ stateblock_init_lights(stateblock, device->stateBlock->state.light_map);
+ stateblock_savedstates_set_all(&stateblock->changed,
+ d3d_info->limits.vs_uniform_count, d3d_info->limits.ps_uniform_count);
+ break;
+
+ case WINED3D_SBT_PIXEL_STATE:
+ stateblock_savedstates_set_pixel(&stateblock->changed,
+ d3d_info->limits.ps_uniform_count);
+ break;
+
+ case WINED3D_SBT_VERTEX_STATE:
+ stateblock_init_lights(stateblock, device->stateBlock->state.light_map);
+ stateblock_savedstates_set_vertex(&stateblock->changed,
+ d3d_info->limits.vs_uniform_count);
+ break;
+
+ default:
+ FIXME("Unrecognized state block type %#x.\n", type);
+ break;
+ }
+
+ stateblock_init_contained_states(stateblock);
+ wined3d_stateblock_capture(stateblock);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_stateblock_create(struct wined3d_device *device,
+ enum wined3d_stateblock_type type, struct wined3d_stateblock **stateblock)
+{
+ struct wined3d_stateblock *object;
+ HRESULT hr;
+
+ TRACE("device %p, type %#x, stateblock %p.\n",
+ device, type, stateblock);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ hr = stateblock_init(object, device, type);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize stateblock, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created stateblock %p.\n", object);
+ *stateblock = object;
+
+ return WINED3D_OK;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/surface.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/surface.c
new file mode 100644
index 00000000..fe04990f
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/surface.c
@@ -0,0 +1,7832 @@
+/*
+ * Copyright 1997-2000 Marcus Meissner
+ * Copyright 1998-2000 Lionel Ulmer
+ * Copyright 2000-2001 TransGaming Technologies Inc.
+ * Copyright 2002-2005 Jason Edmeades
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2004 Christian Costa
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2006-2011 Stefan Dösinger for CodeWeavers
+ * Copyright 2007-2008 Henri Verbeet
+ * Copyright 2006-2008 Roderick Colenbrander
+ * Copyright 2009-2011 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+#include "wined3d_private.h"
+#ifdef VBOX_WITH_WINE_FIXES
+# include <float.h>
+#endif
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
+WINE_DECLARE_DEBUG_CHANNEL(d3d);
+
+#ifdef VBOX_WITH_WDDM
+void surface_shrc_lock_surf(struct wined3d_surface *surf)
+{
+ VBOXSHRC_LOCK(surf);
+}
+
+void surface_shrc_unlock_surf(struct wined3d_surface *surf)
+{
+ VBOXSHRC_UNLOCK(surf);
+ if (VBOXSHRC_IS_LOCKED(surf))
+ return;
+
+ /* perform data->texture synchronization */
+ surface_load_location(surf, SFLAG_INTEXTURE, NULL);
+}
+
+void surface_shrc_lock(struct wined3d_surface *surf)
+{
+ if (!VBOXSHRC_IS_SHARED(surf))
+ return;
+
+ surface_shrc_lock_surf(surf);
+}
+
+void surface_shrc_unlock(struct wined3d_surface *surf)
+{
+ if (!VBOXSHRC_IS_SHARED(surf))
+ return;
+ surface_shrc_unlock_surf(surf);
+}
+#endif
+
+static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect,
+ struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags,
+ const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter);
+static HRESULT IWineD3DSurfaceImpl_BltOverride(struct wined3d_surface *dst_surface, const RECT *dst_rect,
+ struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, const WINEDDBLTFX *fx,
+ enum wined3d_texture_filter_type filter);
+
+static void surface_cleanup(struct wined3d_surface *surface)
+{
+ struct wined3d_surface *overlay, *cur;
+
+ TRACE("surface %p.\n", surface);
+
+ if (surface->texture_name || (surface->flags & SFLAG_PBO)
+ || surface->rb_multisample || surface->rb_resolved
+ || !list_empty(&surface->renderbuffers))
+ {
+ struct wined3d_renderbuffer_entry *entry, *entry2;
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+
+ context = context_acquire(surface->resource.device, NULL);
+ gl_info = context->gl_info;
+
+ if (surface->texture_name)
+ {
+ TRACE("Deleting texture %u.\n", surface->texture_name);
+#ifdef VBOX_WITH_WDDM
+ texture_gl_delete(surface->texture_name);
+#else
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &surface->texture_name);
+#endif
+ }
+
+ if (surface->flags & SFLAG_PBO)
+ {
+ TRACE("Deleting PBO %u.\n", surface->pbo);
+ GL_EXTCALL(glDeleteBuffersARB(1, &surface->pbo));
+ }
+
+ if (surface->rb_multisample)
+ {
+ TRACE("Deleting multisample renderbuffer %u.\n", surface->rb_multisample);
+ gl_info->fbo_ops.glDeleteRenderbuffers(1, &surface->rb_multisample);
+ }
+
+ if (surface->rb_resolved)
+ {
+ TRACE("Deleting resolved renderbuffer %u.\n", surface->rb_resolved);
+ gl_info->fbo_ops.glDeleteRenderbuffers(1, &surface->rb_resolved);
+ }
+
+ LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry)
+ {
+ TRACE("Deleting renderbuffer %u.\n", entry->id);
+ gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
+ HeapFree(GetProcessHeap(), 0, entry);
+ }
+
+ context_release(context);
+ }
+
+ if (surface->flags & SFLAG_DIBSECTION)
+ {
+ DeleteDC(surface->hDC);
+ DeleteObject(surface->dib.DIBsection);
+ surface->dib.bitmap_data = NULL;
+ surface->resource.allocatedMemory = NULL;
+ }
+
+ if (surface->flags & SFLAG_USERPTR)
+ wined3d_surface_set_mem(surface, NULL, 0);
+ if (surface->overlay_dest)
+ list_remove(&surface->overlay_entry);
+
+ LIST_FOR_EACH_ENTRY_SAFE(overlay, cur, &surface->overlays, struct wined3d_surface, overlay_entry)
+ {
+ list_remove(&overlay->overlay_entry);
+ overlay->overlay_dest = NULL;
+ }
+
+ resource_cleanup(&surface->resource);
+
+#ifdef VBOX_WITH_WDDM
+ /* @rodo: CHECK AND REMOVE : this should not be necessary anymore */
+ {
+ struct wined3d_device *device = surface->resource.device;
+ struct wined3d_context *context;
+ UINT i;
+ for (i = 0; i < device->context_count; ++i)
+ {
+ context = device->contexts[i];
+ /* pretty hacky, @todo: check if the context is acquired and re-acquire it with the new swapchain */
+ if (context->current_rt == surface)
+ {
+ Assert(0);
+ }
+ }
+ }
+#endif
+
+}
+
+void surface_update_draw_binding(struct wined3d_surface *surface)
+{
+ if (!surface_is_offscreen(surface) || wined3d_settings.offscreen_rendering_mode != ORM_FBO)
+ surface->draw_binding = SFLAG_INDRAWABLE;
+ else if (surface->resource.multisample_type)
+ surface->draw_binding = SFLAG_INRB_MULTISAMPLE;
+ else
+ surface->draw_binding = SFLAG_INTEXTURE;
+}
+
+void surface_set_swapchain(struct wined3d_surface *surface, struct wined3d_swapchain *swapchain)
+{
+ TRACE("surface %p, swapchain %p.\n", surface, swapchain);
+
+ if (swapchain)
+ {
+ surface->get_drawable_size = get_drawable_size_swapchain;
+ }
+ else
+ {
+ switch (wined3d_settings.offscreen_rendering_mode)
+ {
+ case ORM_FBO:
+ surface->get_drawable_size = get_drawable_size_fbo;
+ break;
+
+ case ORM_BACKBUFFER:
+ surface->get_drawable_size = get_drawable_size_backbuffer;
+ break;
+
+ default:
+ ERR("Unhandled offscreen rendering mode %#x.\n", wined3d_settings.offscreen_rendering_mode);
+ return;
+ }
+ }
+
+ surface->swapchain = swapchain;
+ surface_update_draw_binding(surface);
+}
+
+void surface_set_container(struct wined3d_surface *surface, struct wined3d_texture *container)
+{
+ TRACE("surface %p, container %p.\n", surface, container);
+
+ if (!surface->swapchain)
+ {
+ switch (wined3d_settings.offscreen_rendering_mode)
+ {
+ case ORM_FBO:
+ surface->get_drawable_size = get_drawable_size_fbo;
+ break;
+
+ case ORM_BACKBUFFER:
+ surface->get_drawable_size = get_drawable_size_backbuffer;
+ break;
+
+ default:
+ ERR("Unhandled offscreen rendering mode %#x.\n", wined3d_settings.offscreen_rendering_mode);
+ return;
+ }
+ }
+
+ surface->container = container;
+ surface_update_draw_binding(surface);
+}
+
+struct blt_info
+{
+ GLenum binding;
+ GLenum bind_target;
+ enum tex_types tex_type;
+ GLfloat coords[4][3];
+};
+
+struct float_rect
+{
+ float l;
+ float t;
+ float r;
+ float b;
+};
+
+static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct float_rect *f)
+{
+ f->l = ((r->left * 2.0f) / w) - 1.0f;
+ f->t = ((r->top * 2.0f) / h) - 1.0f;
+ f->r = ((r->right * 2.0f) / w) - 1.0f;
+ f->b = ((r->bottom * 2.0f) / h) - 1.0f;
+}
+
+static void surface_get_blt_info(GLenum target, const RECT *rect, GLsizei w, GLsizei h, struct blt_info *info)
+{
+ GLfloat (*coords)[3] = info->coords;
+ struct float_rect f;
+
+ switch (target)
+ {
+ default:
+ FIXME("Unsupported texture target %#x\n", target);
+ /* Fall back to GL_TEXTURE_2D */
+ case GL_TEXTURE_2D:
+ info->binding = GL_TEXTURE_BINDING_2D;
+ info->bind_target = GL_TEXTURE_2D;
+ info->tex_type = tex_2d;
+ coords[0][0] = (float)rect->left / w;
+ coords[0][1] = (float)rect->top / h;
+ coords[0][2] = 0.0f;
+
+ coords[1][0] = (float)rect->right / w;
+ coords[1][1] = (float)rect->top / h;
+ coords[1][2] = 0.0f;
+
+ coords[2][0] = (float)rect->left / w;
+ coords[2][1] = (float)rect->bottom / h;
+ coords[2][2] = 0.0f;
+
+ coords[3][0] = (float)rect->right / w;
+ coords[3][1] = (float)rect->bottom / h;
+ coords[3][2] = 0.0f;
+ break;
+
+ case GL_TEXTURE_RECTANGLE_ARB:
+ info->binding = GL_TEXTURE_BINDING_RECTANGLE_ARB;
+ info->bind_target = GL_TEXTURE_RECTANGLE_ARB;
+ info->tex_type = tex_rect;
+ coords[0][0] = rect->left; coords[0][1] = rect->top; coords[0][2] = 0.0f;
+ coords[1][0] = rect->right; coords[1][1] = rect->top; coords[1][2] = 0.0f;
+ coords[2][0] = rect->left; coords[2][1] = rect->bottom; coords[2][2] = 0.0f;
+ coords[3][0] = rect->right; coords[3][1] = rect->bottom; coords[3][2] = 0.0f;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
+ info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
+ info->tex_type = tex_cube;
+ cube_coords_float(rect, w, h, &f);
+
+ coords[0][0] = 1.0f; coords[0][1] = -f.t; coords[0][2] = -f.l;
+ coords[1][0] = 1.0f; coords[1][1] = -f.t; coords[1][2] = -f.r;
+ coords[2][0] = 1.0f; coords[2][1] = -f.b; coords[2][2] = -f.l;
+ coords[3][0] = 1.0f; coords[3][1] = -f.b; coords[3][2] = -f.r;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
+ info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
+ info->tex_type = tex_cube;
+ cube_coords_float(rect, w, h, &f);
+
+ coords[0][0] = -1.0f; coords[0][1] = -f.t; coords[0][2] = f.l;
+ coords[1][0] = -1.0f; coords[1][1] = -f.t; coords[1][2] = f.r;
+ coords[2][0] = -1.0f; coords[2][1] = -f.b; coords[2][2] = f.l;
+ coords[3][0] = -1.0f; coords[3][1] = -f.b; coords[3][2] = f.r;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
+ info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
+ info->tex_type = tex_cube;
+ cube_coords_float(rect, w, h, &f);
+
+ coords[0][0] = f.l; coords[0][1] = 1.0f; coords[0][2] = f.t;
+ coords[1][0] = f.r; coords[1][1] = 1.0f; coords[1][2] = f.t;
+ coords[2][0] = f.l; coords[2][1] = 1.0f; coords[2][2] = f.b;
+ coords[3][0] = f.r; coords[3][1] = 1.0f; coords[3][2] = f.b;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
+ info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
+ info->tex_type = tex_cube;
+ cube_coords_float(rect, w, h, &f);
+
+ coords[0][0] = f.l; coords[0][1] = -1.0f; coords[0][2] = -f.t;
+ coords[1][0] = f.r; coords[1][1] = -1.0f; coords[1][2] = -f.t;
+ coords[2][0] = f.l; coords[2][1] = -1.0f; coords[2][2] = -f.b;
+ coords[3][0] = f.r; coords[3][1] = -1.0f; coords[3][2] = -f.b;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
+ info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
+ info->tex_type = tex_cube;
+ cube_coords_float(rect, w, h, &f);
+
+ coords[0][0] = f.l; coords[0][1] = -f.t; coords[0][2] = 1.0f;
+ coords[1][0] = f.r; coords[1][1] = -f.t; coords[1][2] = 1.0f;
+ coords[2][0] = f.l; coords[2][1] = -f.b; coords[2][2] = 1.0f;
+ coords[3][0] = f.r; coords[3][1] = -f.b; coords[3][2] = 1.0f;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ info->binding = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
+ info->bind_target = GL_TEXTURE_CUBE_MAP_ARB;
+ info->tex_type = tex_cube;
+ cube_coords_float(rect, w, h, &f);
+
+ coords[0][0] = -f.l; coords[0][1] = -f.t; coords[0][2] = -1.0f;
+ coords[1][0] = -f.r; coords[1][1] = -f.t; coords[1][2] = -1.0f;
+ coords[2][0] = -f.l; coords[2][1] = -f.b; coords[2][2] = -1.0f;
+ coords[3][0] = -f.r; coords[3][1] = -f.b; coords[3][2] = -1.0f;
+ break;
+ }
+}
+
+static void surface_get_rect(const struct wined3d_surface *surface, const RECT *rect_in, RECT *rect_out)
+{
+ if (rect_in)
+ *rect_out = *rect_in;
+ else
+ {
+ rect_out->left = 0;
+ rect_out->top = 0;
+ rect_out->right = surface->resource.width;
+ rect_out->bottom = surface->resource.height;
+ }
+}
+
+/* Context activation is done by the caller. */
+void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3d_context *context,
+ const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct blt_info info;
+
+ surface_get_blt_info(src_surface->texture_target, src_rect, src_surface->pow2Width, src_surface->pow2Height, &info);
+
+ gl_info->gl_ops.gl.p_glEnable(info.bind_target);
+ checkGLcall("glEnable(bind_target)");
+
+ context_bind_texture(context, info.bind_target, src_surface->texture_name);
+
+ /* Filtering for StretchRect */
+ gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MAG_FILTER,
+ wined3d_gl_mag_filter(magLookup, filter));
+ checkGLcall("glTexParameteri");
+ gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_MIN_FILTER,
+ wined3d_gl_min_mip_filter(minMipLookup, filter, WINED3D_TEXF_NONE));
+ checkGLcall("glTexParameteri");
+ gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ if (context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
+ gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
+ gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ checkGLcall("glTexEnvi");
+
+ /* Draw a quad */
+ gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
+ gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[0]);
+ gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->top);
+
+ gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[1]);
+ gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->top);
+
+ gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[2]);
+ gl_info->gl_ops.gl.p_glVertex2i(dst_rect->left, dst_rect->bottom);
+
+ gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[3]);
+ gl_info->gl_ops.gl.p_glVertex2i(dst_rect->right, dst_rect->bottom);
+ gl_info->gl_ops.gl.p_glEnd();
+
+ /* Unbind the texture */
+ context_bind_texture(context, info.bind_target, 0);
+
+ /* We changed the filtering settings on the texture. Inform the
+ * container about this to get the filters reset properly next draw. */
+ if (src_surface->container)
+ {
+ struct wined3d_texture *texture = src_surface->container;
+ texture->texture_rgb.states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_POINT;
+ texture->texture_rgb.states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT;
+ texture->texture_rgb.states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_NONE;
+ texture->texture_rgb.states[WINED3DTEXSTA_SRGBTEXTURE] = FALSE;
+ }
+}
+
+/* Works correctly only for <= 4 bpp formats. */
+static void get_color_masks(const struct wined3d_format *format, DWORD *masks)
+{
+ masks[0] = ((1 << format->red_size) - 1) << format->red_offset;
+ masks[1] = ((1 << format->green_size) - 1) << format->green_offset;
+ masks[2] = ((1 << format->blue_size) - 1) << format->blue_offset;
+}
+
+static HRESULT surface_create_dib_section(struct wined3d_surface *surface)
+{
+ const struct wined3d_format *format = surface->resource.format;
+ SYSTEM_INFO sysInfo;
+ BITMAPINFO *b_info;
+ int extraline = 0;
+ DWORD *masks;
+
+ TRACE("surface %p.\n", surface);
+
+ if (!(format->flags & WINED3DFMT_FLAG_GETDC))
+ {
+ WARN("Cannot use GetDC on a %s surface.\n", debug_d3dformat(format->id));
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ switch (format->byte_count)
+ {
+ case 2:
+ case 4:
+ /* Allocate extra space to store the RGB bit masks. */
+ b_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
+ break;
+
+ case 3:
+ b_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
+ break;
+
+ default:
+ /* Allocate extra space for a palette. */
+ b_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1 << (format->byte_count * 8)));
+ break;
+ }
+
+ if (!b_info)
+ return E_OUTOFMEMORY;
+
+ /* Some applications access the surface in via DWORDs, and do not take
+ * the necessary care at the end of the surface. So we need at least
+ * 4 extra bytes at the end of the surface. Check against the page size,
+ * if the last page used for the surface has at least 4 spare bytes we're
+ * safe, otherwise add an extra line to the DIB section. */
+ GetSystemInfo(&sysInfo);
+ if( ((surface->resource.size + 3) % sysInfo.dwPageSize) < 4)
+ {
+ extraline = 1;
+ TRACE("Adding an extra line to the DIB section.\n");
+ }
+
+ b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ /* TODO: Is there a nicer way to force a specific alignment? (8 byte for ddraw) */
+ b_info->bmiHeader.biWidth = wined3d_surface_get_pitch(surface) / format->byte_count;
+ b_info->bmiHeader.biHeight = 0 - surface->resource.height - extraline;
+ b_info->bmiHeader.biSizeImage = (surface->resource.height + extraline)
+ * wined3d_surface_get_pitch(surface);
+ b_info->bmiHeader.biPlanes = 1;
+ b_info->bmiHeader.biBitCount = format->byte_count * 8;
+
+ b_info->bmiHeader.biXPelsPerMeter = 0;
+ b_info->bmiHeader.biYPelsPerMeter = 0;
+ b_info->bmiHeader.biClrUsed = 0;
+ b_info->bmiHeader.biClrImportant = 0;
+
+ /* Get the bit masks */
+ masks = (DWORD *)b_info->bmiColors;
+ switch (surface->resource.format->id)
+ {
+ case WINED3DFMT_B8G8R8_UNORM:
+ b_info->bmiHeader.biCompression = BI_RGB;
+ break;
+
+ case WINED3DFMT_B5G5R5X1_UNORM:
+ case WINED3DFMT_B5G5R5A1_UNORM:
+ case WINED3DFMT_B4G4R4A4_UNORM:
+ case WINED3DFMT_B4G4R4X4_UNORM:
+ case WINED3DFMT_B2G3R3_UNORM:
+ case WINED3DFMT_B2G3R3A8_UNORM:
+ case WINED3DFMT_R10G10B10A2_UNORM:
+ case WINED3DFMT_R8G8B8A8_UNORM:
+ case WINED3DFMT_R8G8B8X8_UNORM:
+ case WINED3DFMT_B10G10R10A2_UNORM:
+ case WINED3DFMT_B5G6R5_UNORM:
+ case WINED3DFMT_R16G16B16A16_UNORM:
+ b_info->bmiHeader.biCompression = BI_BITFIELDS;
+ get_color_masks(format, masks);
+ break;
+
+ default:
+ /* Don't know palette */
+ b_info->bmiHeader.biCompression = BI_RGB;
+ break;
+ }
+
+ TRACE("Creating a DIB section with size %dx%dx%d, size=%d.\n",
+ b_info->bmiHeader.biWidth, b_info->bmiHeader.biHeight,
+ b_info->bmiHeader.biBitCount, b_info->bmiHeader.biSizeImage);
+ surface->dib.DIBsection = CreateDIBSection(0, b_info, DIB_RGB_COLORS, &surface->dib.bitmap_data, 0, 0);
+
+ if (!surface->dib.DIBsection)
+ {
+ ERR("Failed to create DIB section.\n");
+ HeapFree(GetProcessHeap(), 0, b_info);
+ return HRESULT_FROM_WIN32(GetLastError());
+ }
+
+ TRACE("DIBSection at %p.\n", surface->dib.bitmap_data);
+ /* Copy the existing surface to the dib section. */
+ if (surface->resource.allocatedMemory)
+ {
+ memcpy(surface->dib.bitmap_data, surface->resource.allocatedMemory,
+ surface->resource.height * wined3d_surface_get_pitch(surface));
+ }
+ else
+ {
+ /* This is to make maps read the GL texture although memory is allocated. */
+ surface->flags &= ~SFLAG_INSYSMEM;
+ }
+ surface->dib.bitmap_size = b_info->bmiHeader.biSizeImage;
+
+ HeapFree(GetProcessHeap(), 0, b_info);
+
+ /* Now allocate a DC. */
+ surface->hDC = CreateCompatibleDC(0);
+ SelectObject(surface->hDC, surface->dib.DIBsection);
+ TRACE("Using wined3d palette %p.\n", surface->palette);
+ SelectPalette(surface->hDC, surface->palette ? surface->palette->hpal : 0, FALSE);
+
+ surface->flags |= SFLAG_DIBSECTION;
+
+ return WINED3D_OK;
+}
+
+static BOOL surface_need_pbo(const struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info)
+{
+ if (surface->resource.pool == WINED3D_POOL_SYSTEM_MEM)
+ return FALSE;
+ if (!(surface->flags & SFLAG_DYNLOCK))
+ return FALSE;
+ if (surface->flags & (SFLAG_CONVERTED | SFLAG_NONPOW2 | SFLAG_PIN_SYSMEM))
+ return FALSE;
+ if (!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT])
+ return FALSE;
+
+ return TRUE;
+}
+
+static void surface_load_pbo(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info)
+{
+ struct wined3d_context *context;
+ GLenum error;
+
+ context = context_acquire(surface->resource.device, NULL);
+
+ GL_EXTCALL(glGenBuffersARB(1, &surface->pbo));
+ error = gl_info->gl_ops.gl.p_glGetError();
+ if (!surface->pbo || error != GL_NO_ERROR)
+ ERR("Failed to create a PBO with error %s (%#x).\n", debug_glerror(error), error);
+
+ TRACE("Binding PBO %u.\n", surface->pbo);
+
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo));
+ checkGLcall("glBindBufferARB");
+
+ GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->resource.size + 4,
+ surface->resource.allocatedMemory, GL_STREAM_DRAW_ARB));
+ checkGLcall("glBufferDataARB");
+
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+ checkGLcall("glBindBufferARB");
+
+ /* We don't need the system memory anymore and we can't even use it for PBOs. */
+ if (!(surface->flags & SFLAG_CLIENT))
+ {
+ HeapFree(GetProcessHeap(), 0, surface->resource.heapMemory);
+ surface->resource.heapMemory = NULL;
+ }
+ surface->resource.allocatedMemory = NULL;
+ surface->flags |= SFLAG_PBO;
+ context_release(context);
+}
+
+#ifdef VBOX_WITH_WDDM
+static HRESULT d3dfmt_get_conv(const struct wined3d_surface *surface, BOOL need_alpha_ck, BOOL use_texturing,
+ struct wined3d_format *format, enum wined3d_conversion_type *conversion_type);
+
+void surface_setup_location_onopen(struct wined3d_surface *surface)
+{
+ struct wined3d_device *device = surface->resource.device;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ DWORD alloc_flag = SFLAG_ALLOCATED;
+// DWORD alloc_flag = srgb ? SFLAG_SRGBALLOCATED : SFLAG_ALLOCATED;
+ enum wined3d_conversion_type convert;
+ struct wined3d_format format;
+
+
+ d3dfmt_get_conv(surface, TRUE, TRUE, &format, &convert);
+ if (convert != WINED3D_CT_NONE || format.convert)
+ surface->flags |= SFLAG_CONVERTED;
+ else surface->flags &= ~SFLAG_CONVERTED;
+
+ if(surface->container)
+ {
+ struct wined3d_context *context = context_acquire(device, NULL);
+ pglChromiumParameteriCR(GL_RCUSAGE_TEXTURE_SET_CR, (GLuint)VBOXSHRC_GET_SHAREHANDLE(surface));
+ context_release(context);
+
+ }
+ /* else -> all should be already set in texture init,
+ * which actually calls the current routine for each of texture's surfaces
+ * for setting up their state */
+
+ surface->flags |= alloc_flag;
+ surface->texture_name = (GLuint)VBOXSHRC_GET_SHAREHANDLE(surface);
+
+ surface_modify_location(surface, SFLAG_INTEXTURE, TRUE);
+}
+#endif
+
+static void surface_prepare_system_memory(struct wined3d_surface *surface)
+{
+ const struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info;
+
+ TRACE("surface %p.\n", surface);
+
+ if (!(surface->flags & SFLAG_PBO) && surface_need_pbo(surface, gl_info))
+ surface_load_pbo(surface, gl_info);
+ else if (!(surface->resource.allocatedMemory || surface->flags & SFLAG_PBO))
+ {
+ /* Whatever surface we have, make sure that there is memory allocated
+ * for the downloaded copy, or a PBO to map. */
+ if (!surface->resource.heapMemory)
+ surface->resource.heapMemory = HeapAlloc(GetProcessHeap(), 0, surface->resource.size + RESOURCE_ALIGNMENT);
+
+ surface->resource.allocatedMemory = (BYTE *)(((ULONG_PTR)surface->resource.heapMemory
+ + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
+
+ if (surface->flags & SFLAG_INSYSMEM)
+ ERR("Surface without memory or PBO has SFLAG_INSYSMEM set.\n");
+ }
+}
+
+static void surface_evict_sysmem(struct wined3d_surface *surface)
+{
+ if (surface->resource.map_count || (surface->flags & SFLAG_DONOTFREE))
+ return;
+
+ HeapFree(GetProcessHeap(), 0, surface->resource.heapMemory);
+ surface->resource.allocatedMemory = NULL;
+ surface->resource.heapMemory = NULL;
+ surface_modify_location(surface, SFLAG_INSYSMEM, FALSE);
+}
+
+/* Context activation is done by the caller. */
+static void surface_bind(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb)
+{
+ TRACE("surface %p, context %p, srgb %#x.\n", surface, context, srgb);
+
+ if (surface->container)
+ {
+ struct wined3d_texture *texture = surface->container;
+
+ TRACE("Passing to container (%p).\n", texture);
+ texture->texture_ops->texture_bind(texture, context, srgb);
+ }
+ else
+ {
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (surface->texture_level)
+ {
+ ERR("Standalone surface %p is non-zero texture level %u.\n",
+ surface, surface->texture_level);
+ }
+
+ if (srgb)
+ ERR("Trying to bind standalone surface %p as sRGB.\n", surface);
+
+ if (!surface->texture_name)
+ {
+#ifdef VBOX_WITH_WDDM
+ if (VBOXSHRC_IS_SHARED_OPENED(surface))
+ {
+ struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info;
+ ERR("should not be here!");
+ surface->texture_name = (GLuint)VBOXSHRC_GET_SHAREHANDLE(surface);
+ Assert(surface->texture_name);
+ pglChromiumParameteriCR(GL_RCUSAGE_TEXTURE_SET_CR, surface->texture_name);
+ }
+ else
+#endif
+ {
+ gl_info->gl_ops.gl.p_glGenTextures(1, &surface->texture_name);
+ checkGLcall("glGenTextures");
+
+ TRACE("Surface %p given name %u.\n", surface, surface->texture_name);
+
+ context_bind_texture(context, surface->texture_target, surface->texture_name);
+ gl_info->gl_ops.gl.p_glTexParameteri(surface->texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl_info->gl_ops.gl.p_glTexParameteri(surface->texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ gl_info->gl_ops.gl.p_glTexParameteri(surface->texture_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+ gl_info->gl_ops.gl.p_glTexParameteri(surface->texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl_info->gl_ops.gl.p_glTexParameteri(surface->texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ checkGLcall("glTexParameteri");
+
+#ifdef VBOX_WITH_WDDM
+ if (VBOXSHRC_IS_SHARED(surface))
+ {
+ VBOXSHRC_SET_SHAREHANDLE(surface, surface->texture_name);
+ }
+#endif
+ }
+ }
+ else
+ {
+ context_bind_texture(context, surface->texture_target, surface->texture_name);
+ }
+
+ }
+}
+
+/* Context activation is done by the caller. */
+static void surface_bind_and_dirtify(struct wined3d_surface *surface,
+ struct wined3d_context *context, BOOL srgb)
+{
+ struct wined3d_device *device = surface->resource.device;
+ DWORD active_sampler;
+
+ /* We don't need a specific texture unit, but after binding the texture
+ * the current unit is dirty. Read the unit back instead of switching to
+ * 0, this avoids messing around with the state manager's GL states. The
+ * current texture unit should always be a valid one.
+ *
+ * To be more specific, this is tricky because we can implicitly be
+ * called from sampler() in state.c. This means we can't touch anything
+ * other than whatever happens to be the currently active texture, or we
+ * would risk marking already applied sampler states dirty again. */
+ active_sampler = device->rev_tex_unit_map[context->active_texture];
+
+#if 0 //def DEBUG_misha
+ {
+ GLint active_texture=GL_TEXTURE0_ARB;
+ glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
+ Assert(active_texture - GL_TEXTURE0_ARB == context->active_texture);
+ }
+#endif
+
+ if (active_sampler != WINED3D_UNMAPPED_STAGE)
+ device_invalidate_state(device, STATE_SAMPLER(active_sampler));
+ surface_bind(surface, context, srgb);
+}
+
+static void surface_force_reload(struct wined3d_surface *surface)
+{
+ surface->flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
+}
+
+static void surface_release_client_storage(struct wined3d_surface *surface)
+{
+ struct wined3d_context *context = context_acquire(surface->resource.device, NULL);
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
+ if (surface->texture_name)
+ {
+ surface_bind_and_dirtify(surface, context, FALSE);
+ gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level,
+ GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ }
+ if (surface->texture_name_srgb)
+ {
+ surface_bind_and_dirtify(surface, context, TRUE);
+ gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level,
+ GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ }
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
+
+ context_release(context);
+
+ surface_modify_location(surface, SFLAG_INSRGBTEX, FALSE);
+ surface_modify_location(surface, SFLAG_INTEXTURE, FALSE);
+ surface_force_reload(surface);
+}
+
+static HRESULT surface_private_setup(struct wined3d_surface *surface)
+{
+ /* TODO: Check against the maximum texture sizes supported by the video card. */
+ const struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info;
+ unsigned int pow2Width, pow2Height;
+
+ TRACE("surface %p.\n", surface);
+
+ surface->texture_name = 0;
+ surface->texture_target = GL_TEXTURE_2D;
+
+ /* Non-power2 support */
+ if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] || gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT])
+ {
+ pow2Width = surface->resource.width;
+ pow2Height = surface->resource.height;
+ }
+ else
+ {
+ /* Find the nearest pow2 match */
+ pow2Width = pow2Height = 1;
+ while (pow2Width < surface->resource.width)
+ pow2Width <<= 1;
+ while (pow2Height < surface->resource.height)
+ pow2Height <<= 1;
+ }
+ surface->pow2Width = pow2Width;
+ surface->pow2Height = pow2Height;
+
+ if (pow2Width > surface->resource.width || pow2Height > surface->resource.height)
+ {
+ /* TODO: Add support for non power two compressed textures. */
+ if (surface->resource.format->flags & WINED3DFMT_FLAG_COMPRESSED)
+ {
+ FIXME("(%p) Compressed non-power-two textures are not supported w(%d) h(%d)\n",
+ surface, surface->resource.width, surface->resource.height);
+ return WINED3DERR_NOTAVAILABLE;
+ }
+ }
+
+ if (pow2Width != surface->resource.width
+ || pow2Height != surface->resource.height)
+ {
+ surface->flags |= SFLAG_NONPOW2;
+ }
+
+ if ((surface->pow2Width > gl_info->limits.texture_size || surface->pow2Height > gl_info->limits.texture_size)
+ && !(surface->resource.usage & (WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL)))
+ {
+ /* One of three options:
+ * 1: Do the same as we do with NPOT and scale the texture, (any
+ * texture ops would require the texture to be scaled which is
+ * potentially slow)
+ * 2: Set the texture to the maximum size (bad idea).
+ * 3: WARN and return WINED3DERR_NOTAVAILABLE;
+ * 4: Create the surface, but allow it to be used only for DirectDraw
+ * Blts. Some apps (e.g. Swat 3) create textures with a Height of
+ * 16 and a Width > 3000 and blt 16x16 letter areas from them to
+ * the render target. */
+ if (surface->resource.pool == WINED3D_POOL_DEFAULT || surface->resource.pool == WINED3D_POOL_MANAGED)
+ {
+ WARN("Unable to allocate a surface which exceeds the maximum OpenGL texture size.\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+ /* We should never use this surface in combination with OpenGL! */
+ TRACE("Creating an oversized surface: %ux%u.\n",
+ surface->pow2Width, surface->pow2Height);
+ }
+ else
+ {
+ /* Don't use ARB_TEXTURE_RECTANGLE in case the surface format is P8
+ * and EXT_PALETTED_TEXTURE is used in combination with texture
+ * uploads (RTL_READTEX/RTL_TEXTEX). The reason is that
+ * EXT_PALETTED_TEXTURE doesn't work in combination with
+ * ARB_TEXTURE_RECTANGLE. */
+ if (surface->flags & SFLAG_NONPOW2 && gl_info->supported[ARB_TEXTURE_RECTANGLE]
+ && !(surface->resource.format->id == WINED3DFMT_P8_UINT
+ && gl_info->supported[EXT_PALETTED_TEXTURE]
+ && wined3d_settings.rendertargetlock_mode == RTL_READTEX))
+ {
+ surface->texture_target = GL_TEXTURE_RECTANGLE_ARB;
+ surface->pow2Width = surface->resource.width;
+ surface->pow2Height = surface->resource.height;
+ surface->flags &= ~(SFLAG_NONPOW2 | SFLAG_NORMCOORD);
+ }
+ }
+
+ switch (wined3d_settings.offscreen_rendering_mode)
+ {
+ case ORM_FBO:
+ surface->get_drawable_size = get_drawable_size_fbo;
+ break;
+
+ case ORM_BACKBUFFER:
+ surface->get_drawable_size = get_drawable_size_backbuffer;
+ break;
+
+ default:
+ ERR("Unhandled offscreen rendering mode %#x.\n", wined3d_settings.offscreen_rendering_mode);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
+ surface->flags |= SFLAG_DISCARDED;
+
+ return WINED3D_OK;
+}
+
+static void surface_realize_palette(struct wined3d_surface *surface)
+{
+ struct wined3d_palette *palette = surface->palette;
+
+ TRACE("surface %p.\n", surface);
+
+ if (!palette) return;
+
+ if (surface->resource.format->id == WINED3DFMT_P8_UINT
+ || surface->resource.format->id == WINED3DFMT_P8_UINT_A8_UNORM)
+ {
+ if (surface->resource.usage & WINED3DUSAGE_RENDERTARGET)
+ {
+ /* Make sure the texture is up to date. This call doesn't do
+ * anything if the texture is already up to date. */
+ surface_load_location(surface, SFLAG_INTEXTURE, NULL);
+
+ /* We want to force a palette refresh, so mark the drawable as not being up to date */
+ if (!surface_is_offscreen(surface))
+ surface_modify_location(surface, SFLAG_INDRAWABLE, FALSE);
+ }
+ else
+ {
+ if (!(surface->flags & SFLAG_INSYSMEM))
+ {
+ TRACE("Palette changed with surface that does not have an up to date system memory copy.\n");
+ surface_load_location(surface, SFLAG_INSYSMEM, NULL);
+ }
+ surface_modify_location(surface, SFLAG_INSYSMEM, TRUE);
+ }
+ }
+
+ if (surface->flags & SFLAG_DIBSECTION)
+ {
+ RGBQUAD col[256];
+ unsigned int i;
+
+ TRACE("Updating the DC's palette.\n");
+
+ for (i = 0; i < 256; ++i)
+ {
+ col[i].rgbRed = palette->palents[i].peRed;
+ col[i].rgbGreen = palette->palents[i].peGreen;
+ col[i].rgbBlue = palette->palents[i].peBlue;
+ col[i].rgbReserved = 0;
+ }
+ SetDIBColorTable(surface->hDC, 0, 256, col);
+ }
+
+ /* Propagate the changes to the drawable when we have a palette. */
+ if (surface->resource.usage & WINED3DUSAGE_RENDERTARGET)
+ surface_load_location(surface, surface->draw_binding, NULL);
+}
+
+static HRESULT surface_draw_overlay(struct wined3d_surface *surface)
+{
+ HRESULT hr;
+
+ /* If there's no destination surface there is nothing to do. */
+ if (!surface->overlay_dest)
+ return WINED3D_OK;
+
+ /* Blt calls ModifyLocation on the dest surface, which in turn calls
+ * DrawOverlay to update the overlay. Prevent an endless recursion. */
+ if (surface->overlay_dest->flags & SFLAG_INOVERLAYDRAW)
+ return WINED3D_OK;
+
+ surface->overlay_dest->flags |= SFLAG_INOVERLAYDRAW;
+ hr = wined3d_surface_blt(surface->overlay_dest, &surface->overlay_destrect, surface,
+ &surface->overlay_srcrect, WINEDDBLT_WAIT, NULL, WINED3D_TEXF_LINEAR);
+ surface->overlay_dest->flags &= ~SFLAG_INOVERLAYDRAW;
+
+ return hr;
+}
+
+static void surface_map(struct wined3d_surface *surface, const RECT *rect, DWORD flags)
+{
+ struct wined3d_device *device = surface->resource.device;
+ const RECT *pass_rect = rect;
+
+ TRACE("surface %p, rect %s, flags %#x.\n",
+ surface, wine_dbgstr_rect(rect), flags);
+
+ if (flags & WINED3D_MAP_DISCARD)
+ {
+ TRACE("WINED3D_MAP_DISCARD flag passed, marking SYSMEM as up to date.\n");
+ surface_prepare_system_memory(surface);
+ surface_modify_location(surface, SFLAG_INSYSMEM, TRUE);
+ }
+ else
+ {
+ if (surface->resource.usage & WINED3DUSAGE_DYNAMIC)
+ WARN_(d3d_perf)("Mapping a dynamic surface without WINED3D_MAP_DISCARD.\n");
+
+ /* surface_load_location() does not check if the rectangle specifies
+ * the full surface. Most callers don't need that, so do it here. */
+ if (rect && !rect->top && !rect->left
+ && rect->right == surface->resource.width
+ && rect->bottom == surface->resource.height)
+ pass_rect = NULL;
+ surface_load_location(surface, SFLAG_INSYSMEM, pass_rect);
+ }
+
+ if (surface->flags & SFLAG_PBO)
+ {
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+
+ context = context_acquire(device, NULL);
+ gl_info = context->gl_info;
+
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo));
+ checkGLcall("glBindBufferARB");
+
+ /* This shouldn't happen but could occur if some other function
+ * didn't handle the PBO properly. */
+ if (surface->resource.allocatedMemory)
+ ERR("The surface already has PBO memory allocated.\n");
+
+ surface->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_READ_WRITE_ARB));
+ checkGLcall("glMapBufferARB");
+
+ /* Make sure the PBO isn't set anymore in order not to break non-PBO
+ * calls. */
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+ checkGLcall("glBindBufferARB");
+
+ context_release(context);
+ }
+
+ if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY)))
+ {
+ if (!rect)
+ surface_add_dirty_rect(surface, NULL);
+ else
+ {
+ struct wined3d_box b;
+
+ b.left = rect->left;
+ b.top = rect->top;
+ b.right = rect->right;
+ b.bottom = rect->bottom;
+ b.front = 0;
+ b.back = 1;
+ surface_add_dirty_rect(surface, &b);
+ }
+ }
+}
+
+static void surface_unmap(struct wined3d_surface *surface)
+{
+ struct wined3d_device *device = surface->resource.device;
+ BOOL fullsurface;
+
+ TRACE("surface %p.\n", surface);
+
+ memset(&surface->lockedRect, 0, sizeof(surface->lockedRect));
+
+ if (surface->flags & SFLAG_PBO)
+ {
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+
+ TRACE("Freeing PBO memory.\n");
+
+ context = context_acquire(device, NULL);
+ gl_info = context->gl_info;
+
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo));
+ GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB));
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+ checkGLcall("glUnmapBufferARB");
+ context_release(context);
+
+ surface->resource.allocatedMemory = NULL;
+ }
+
+ TRACE("dirtyfied %u.\n", surface->flags & (SFLAG_INDRAWABLE | SFLAG_INTEXTURE) ? 0 : 1);
+
+ if (surface->flags & (SFLAG_INDRAWABLE | SFLAG_INTEXTURE))
+ {
+ TRACE("Not dirtified, nothing to do.\n");
+ goto done;
+ }
+
+ if (surface->swapchain && surface->swapchain->front_buffer == surface)
+ {
+ if (!surface->dirtyRect.left && !surface->dirtyRect.top
+ && surface->dirtyRect.right == surface->resource.width
+ && surface->dirtyRect.bottom == surface->resource.height)
+ {
+ fullsurface = TRUE;
+ }
+ else
+ {
+ /* TODO: Proper partial rectangle tracking. */
+ fullsurface = FALSE;
+ surface->flags |= SFLAG_INSYSMEM;
+ }
+
+ surface_load_location(surface, surface->draw_binding, fullsurface ? NULL : &surface->dirtyRect);
+
+ /* Partial rectangle tracking is not commonly implemented, it is only
+ * done for render targets. INSYSMEM was set before to tell
+ * surface_load_location() where to read the rectangle from.
+ * Indrawable is set because all modifications from the partial
+ * sysmem copy are written back to the drawable, thus the surface is
+ * merged again in the drawable. The sysmem copy is not fully up to
+ * date because only a subrectangle was read in Map(). */
+ if (!fullsurface)
+ {
+ surface_modify_location(surface, surface->draw_binding, TRUE);
+ surface_evict_sysmem(surface);
+ }
+
+ surface->dirtyRect.left = surface->resource.width;
+ surface->dirtyRect.top = surface->resource.height;
+ surface->dirtyRect.right = 0;
+ surface->dirtyRect.bottom = 0;
+ }
+ else if (surface->resource.format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
+ {
+ FIXME("Depth / stencil buffer locking is not implemented.\n");
+ }
+
+done:
+ /* Overlays have to be redrawn manually after changes with the GL implementation */
+ if (surface->overlay_dest)
+ surface_draw_overlay(surface);
+}
+
+static BOOL surface_is_full_rect(const struct wined3d_surface *surface, const RECT *r)
+{
+ if ((r->left && r->right) || abs(r->right - r->left) != surface->resource.width)
+ return FALSE;
+ if ((r->top && r->bottom) || abs(r->bottom - r->top) != surface->resource.height)
+ return FALSE;
+ return TRUE;
+}
+
+static void surface_depth_blt_fbo(const struct wined3d_device *device,
+ struct wined3d_surface *src_surface, DWORD src_location, const RECT *src_rect,
+ struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect)
+{
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+ DWORD src_mask, dst_mask;
+ GLbitfield gl_mask;
+
+ TRACE("device %p\n", device);
+ TRACE("src_surface %p, src_location %s, src_rect %s,\n",
+ src_surface, debug_surflocation(src_location), wine_dbgstr_rect(src_rect));
+ TRACE("dst_surface %p, dst_location %s, dst_rect %s.\n",
+ dst_surface, debug_surflocation(dst_location), wine_dbgstr_rect(dst_rect));
+
+ src_mask = src_surface->resource.format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL);
+ dst_mask = dst_surface->resource.format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL);
+
+ if (src_mask != dst_mask)
+ {
+ ERR("Incompatible formats %s and %s.\n",
+ debug_d3dformat(src_surface->resource.format->id),
+ debug_d3dformat(dst_surface->resource.format->id));
+ return;
+ }
+
+ if (!src_mask)
+ {
+ ERR("Not a depth / stencil format: %s.\n",
+ debug_d3dformat(src_surface->resource.format->id));
+ return;
+ }
+
+ gl_mask = 0;
+ if (src_mask & WINED3DFMT_FLAG_DEPTH)
+ gl_mask |= GL_DEPTH_BUFFER_BIT;
+ if (src_mask & WINED3DFMT_FLAG_STENCIL)
+ gl_mask |= GL_STENCIL_BUFFER_BIT;
+
+ /* Make sure the locations are up-to-date. Loading the destination
+ * surface isn't required if the entire surface is overwritten. */
+ surface_load_location(src_surface, src_location, NULL);
+ if (!surface_is_full_rect(dst_surface, dst_rect))
+ surface_load_location(dst_surface, dst_location, NULL);
+
+ context = context_acquire(device, NULL);
+ if (!context->valid)
+ {
+ context_release(context);
+ WARN("Invalid context, skipping blit.\n");
+ return;
+ }
+
+ gl_info = context->gl_info;
+
+ context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, NULL, src_surface, src_location);
+ context_check_fbo_status(context, GL_READ_FRAMEBUFFER);
+
+ context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, NULL, dst_surface, dst_location);
+ context_set_draw_buffer(context, GL_NONE);
+ context_check_fbo_status(context, GL_DRAW_FRAMEBUFFER);
+ context_invalidate_state(context, STATE_FRAMEBUFFER);
+
+ if (gl_mask & GL_DEPTH_BUFFER_BIT)
+ {
+ gl_info->gl_ops.gl.p_glDepthMask(GL_TRUE);
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZWRITEENABLE));
+ }
+ if (gl_mask & GL_STENCIL_BUFFER_BIT)
+ {
+ if (context->gl_info->supported[EXT_STENCIL_TWO_SIDE])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE));
+ }
+ gl_info->gl_ops.gl.p_glStencilMask(~0U);
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_STENCILWRITEMASK));
+ }
+
+ gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE));
+
+ gl_info->fbo_ops.glBlitFramebuffer(src_rect->left, src_rect->top, src_rect->right, src_rect->bottom,
+ dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, gl_mask, GL_NEAREST);
+ checkGLcall("glBlitFramebuffer()");
+
+ if (wined3d_settings.strict_draw_ordering)
+ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
+
+ context_release(context);
+}
+
+/* Blit between surface locations. Onscreen on different swapchains is not supported.
+ * Depth / stencil is not supported. */
+static void surface_blt_fbo(const struct wined3d_device *device, enum wined3d_texture_filter_type filter,
+ struct wined3d_surface *src_surface, DWORD src_location, const RECT *src_rect_in,
+ struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect_in)
+{
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+ RECT src_rect, dst_rect;
+ GLenum gl_filter;
+ GLenum buffer;
+
+ TRACE("device %p, filter %s,\n", device, debug_d3dtexturefiltertype(filter));
+ TRACE("src_surface %p, src_location %s, src_rect %s,\n",
+ src_surface, debug_surflocation(src_location), wine_dbgstr_rect(src_rect_in));
+ TRACE("dst_surface %p, dst_location %s, dst_rect %s.\n",
+ dst_surface, debug_surflocation(dst_location), wine_dbgstr_rect(dst_rect_in));
+
+ src_rect = *src_rect_in;
+ dst_rect = *dst_rect_in;
+
+ switch (filter)
+ {
+ case WINED3D_TEXF_LINEAR:
+ gl_filter = GL_LINEAR;
+ break;
+
+ default:
+ FIXME("Unsupported filter mode %s (%#x).\n", debug_d3dtexturefiltertype(filter), filter);
+ case WINED3D_TEXF_NONE:
+ case WINED3D_TEXF_POINT:
+ gl_filter = GL_NEAREST;
+ break;
+ }
+
+ /* Resolve the source surface first if needed. */
+ if (src_location == SFLAG_INRB_MULTISAMPLE
+ && (src_surface->resource.format->id != dst_surface->resource.format->id
+ || abs(src_rect.bottom - src_rect.top) != abs(dst_rect.bottom - dst_rect.top)
+ || abs(src_rect.right - src_rect.left) != abs(dst_rect.right - dst_rect.left)))
+ src_location = SFLAG_INRB_RESOLVED;
+
+ /* Make sure the locations are up-to-date. Loading the destination
+ * surface isn't required if the entire surface is overwritten. (And is
+ * in fact harmful if we're being called by surface_load_location() with
+ * the purpose of loading the destination surface.) */
+ surface_load_location(src_surface, src_location, NULL);
+ if (!surface_is_full_rect(dst_surface, &dst_rect))
+ surface_load_location(dst_surface, dst_location, NULL);
+
+ if (src_location == SFLAG_INDRAWABLE) context = context_acquire(device, src_surface);
+ else if (dst_location == SFLAG_INDRAWABLE) context = context_acquire(device, dst_surface);
+ else context = context_acquire(device, NULL);
+
+ if (!context->valid)
+ {
+ context_release(context);
+ WARN("Invalid context, skipping blit.\n");
+ return;
+ }
+
+ gl_info = context->gl_info;
+
+ if (src_location == SFLAG_INDRAWABLE)
+ {
+ TRACE("Source surface %p is onscreen.\n", src_surface);
+ buffer = surface_get_gl_buffer(src_surface);
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ surface_translate_drawable_coords(src_surface, context->win_handle, &src_rect);
+#else
+ surface_translate_drawable_coords(src_surface, context->swapchain->win_handle, &src_rect);
+#endif
+ }
+ else
+ {
+ TRACE("Source surface %p is offscreen.\n", src_surface);
+ buffer = GL_COLOR_ATTACHMENT0;
+ }
+
+ context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, src_surface, NULL, src_location);
+ gl_info->gl_ops.gl.p_glReadBuffer(buffer);
+ checkGLcall("glReadBuffer()");
+ context_check_fbo_status(context, GL_READ_FRAMEBUFFER);
+
+ if (dst_location == SFLAG_INDRAWABLE)
+ {
+ TRACE("Destination surface %p is onscreen.\n", dst_surface);
+ buffer = surface_get_gl_buffer(dst_surface);
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ surface_translate_drawable_coords(dst_surface, context->win_handle, &dst_rect);
+#else
+ surface_translate_drawable_coords(dst_surface, context->swapchain->win_handle, &dst_rect);
+#endif
+ }
+ else
+ {
+ TRACE("Destination surface %p is offscreen.\n", dst_surface);
+ buffer = GL_COLOR_ATTACHMENT0;
+ }
+
+ context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, dst_surface, NULL, dst_location);
+ context_set_draw_buffer(context, buffer);
+ context_check_fbo_status(context, GL_DRAW_FRAMEBUFFER);
+ context_invalidate_state(context, STATE_FRAMEBUFFER);
+
+ gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE));
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1));
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2));
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3));
+
+ gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE));
+
+ gl_info->fbo_ops.glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom,
+ dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, GL_COLOR_BUFFER_BIT, gl_filter);
+ checkGLcall("glBlitFramebuffer()");
+
+ if (wined3d_settings.strict_draw_ordering
+ || (dst_location == SFLAG_INDRAWABLE
+ && dst_surface->swapchain->front_buffer == dst_surface))
+ gl_info->gl_ops.gl.p_glFlush();
+
+ context_release(context);
+}
+
+static BOOL fbo_blit_supported(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
+ const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
+ const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
+{
+ if ((wined3d_settings.offscreen_rendering_mode != ORM_FBO) || !gl_info->fbo_ops.glBlitFramebuffer)
+ return FALSE;
+
+ /* Source and/or destination need to be on the GL side */
+ if (src_pool == WINED3D_POOL_SYSTEM_MEM || dst_pool == WINED3D_POOL_SYSTEM_MEM)
+ return FALSE;
+
+ switch (blit_op)
+ {
+ case WINED3D_BLIT_OP_COLOR_BLIT:
+ if (!((src_format->flags & WINED3DFMT_FLAG_FBO_ATTACHABLE) || (src_usage & WINED3DUSAGE_RENDERTARGET)))
+ return FALSE;
+ if (!((dst_format->flags & WINED3DFMT_FLAG_FBO_ATTACHABLE) || (dst_usage & WINED3DUSAGE_RENDERTARGET)))
+ return FALSE;
+ break;
+
+ case WINED3D_BLIT_OP_DEPTH_BLIT:
+ if (!(src_format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)))
+ return FALSE;
+ if (!(dst_format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)))
+ return FALSE;
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ if (!(src_format->id == dst_format->id
+ || (is_identity_fixup(src_format->color_fixup)
+ && is_identity_fixup(dst_format->color_fixup))))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* This function checks if the primary render target uses the 8bit paletted format. */
+static BOOL primary_render_target_is_p8(const struct wined3d_device *device)
+{
+ if (device->fb.render_targets && device->fb.render_targets[0])
+ {
+ const struct wined3d_surface *render_target = device->fb.render_targets[0];
+ if ((render_target->resource.usage & WINED3DUSAGE_RENDERTARGET)
+ && (render_target->resource.format->id == WINED3DFMT_P8_UINT))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static BOOL surface_convert_color_to_float(const struct wined3d_surface *surface,
+ DWORD color, struct wined3d_color *float_color)
+{
+ const struct wined3d_format *format = surface->resource.format;
+ const struct wined3d_device *device = surface->resource.device;
+
+ switch (format->id)
+ {
+ case WINED3DFMT_P8_UINT:
+ if (surface->palette)
+ {
+ float_color->r = surface->palette->palents[color].peRed / 255.0f;
+ float_color->g = surface->palette->palents[color].peGreen / 255.0f;
+ float_color->b = surface->palette->palents[color].peBlue / 255.0f;
+ }
+ else
+ {
+ float_color->r = 0.0f;
+ float_color->g = 0.0f;
+ float_color->b = 0.0f;
+ }
+ float_color->a = primary_render_target_is_p8(device) ? color / 255.0f : 1.0f;
+ break;
+
+ case WINED3DFMT_B5G6R5_UNORM:
+ float_color->r = ((color >> 11) & 0x1f) / 31.0f;
+ float_color->g = ((color >> 5) & 0x3f) / 63.0f;
+ float_color->b = (color & 0x1f) / 31.0f;
+ float_color->a = 1.0f;
+ break;
+
+ case WINED3DFMT_B8G8R8_UNORM:
+ case WINED3DFMT_B8G8R8X8_UNORM:
+ float_color->r = D3DCOLOR_R(color);
+ float_color->g = D3DCOLOR_G(color);
+ float_color->b = D3DCOLOR_B(color);
+ float_color->a = 1.0f;
+ break;
+
+ case WINED3DFMT_B8G8R8A8_UNORM:
+ float_color->r = D3DCOLOR_R(color);
+ float_color->g = D3DCOLOR_G(color);
+ float_color->b = D3DCOLOR_B(color);
+ float_color->a = D3DCOLOR_A(color);
+ break;
+
+ default:
+ ERR("Unhandled conversion from %s to floating point.\n", debug_d3dformat(format->id));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static BOOL surface_convert_depth_to_float(const struct wined3d_surface *surface, DWORD depth, float *float_depth)
+{
+ const struct wined3d_format *format = surface->resource.format;
+
+ switch (format->id)
+ {
+ case WINED3DFMT_S1_UINT_D15_UNORM:
+ *float_depth = depth / (float)0x00007fff;
+ break;
+
+ case WINED3DFMT_D16_UNORM:
+ *float_depth = depth / (float)0x0000ffff;
+ break;
+
+ case WINED3DFMT_D24_UNORM_S8_UINT:
+ case WINED3DFMT_X8D24_UNORM:
+ *float_depth = depth / (float)0x00ffffff;
+ break;
+
+ case WINED3DFMT_D32_UNORM:
+ *float_depth = depth / (float)0xffffffff;
+ break;
+
+ default:
+ ERR("Unhandled conversion from %s to floating point.\n", debug_d3dformat(format->id));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Do not call while under the GL lock. */
+static HRESULT wined3d_surface_depth_fill(struct wined3d_surface *surface, const RECT *rect, float depth)
+{
+ const struct wined3d_resource *resource = &surface->resource;
+ struct wined3d_device *device = resource->device;
+ const struct blit_shader *blitter;
+
+ blitter = wined3d_select_blitter(&device->adapter->gl_info, WINED3D_BLIT_OP_DEPTH_FILL,
+ NULL, 0, 0, NULL, rect, resource->usage, resource->pool, resource->format);
+ if (!blitter)
+ {
+ FIXME("No blitter is capable of performing the requested depth fill operation.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ return blitter->depth_fill(device, surface, rect, depth);
+}
+
+static HRESULT wined3d_surface_depth_blt(struct wined3d_surface *src_surface, DWORD src_location, const RECT *src_rect,
+ struct wined3d_surface *dst_surface, DWORD dst_location, const RECT *dst_rect)
+{
+ struct wined3d_device *device = src_surface->resource.device;
+
+ if (!fbo_blit_supported(&device->adapter->gl_info, WINED3D_BLIT_OP_DEPTH_BLIT,
+ src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format,
+ dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format))
+ return WINED3DERR_INVALIDCALL;
+
+ surface_depth_blt_fbo(device, src_surface, src_location, src_rect, dst_surface, dst_location, dst_rect);
+
+ surface_modify_ds_location(dst_surface, dst_location,
+ dst_surface->ds_current_size.cx, dst_surface->ds_current_size.cy);
+
+ return WINED3D_OK;
+}
+
+/* Do not call while under the GL lock. */
+HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect_in,
+ struct wined3d_surface *src_surface, const RECT *src_rect_in, DWORD flags,
+ const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter)
+{
+ struct wined3d_swapchain *src_swapchain, *dst_swapchain;
+ struct wined3d_device *device = dst_surface->resource.device;
+ DWORD src_ds_flags, dst_ds_flags;
+ RECT src_rect, dst_rect;
+ BOOL scale, convert;
+#ifdef VBOX_WITH_WDDM
+ HRESULT hr = WINED3D_OK;
+#endif
+
+ static const DWORD simple_blit = WINEDDBLT_ASYNC
+ | WINEDDBLT_COLORFILL
+ | WINEDDBLT_WAIT
+ | WINEDDBLT_DEPTHFILL
+ | WINEDDBLT_DONOTWAIT;
+
+ TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n",
+ dst_surface, wine_dbgstr_rect(dst_rect_in), src_surface, wine_dbgstr_rect(src_rect_in),
+ flags, fx, debug_d3dtexturefiltertype(filter));
+ TRACE("Usage is %s.\n", debug_d3dusage(dst_surface->resource.usage));
+
+ if (fx)
+ {
+ TRACE("dwSize %#x.\n", fx->dwSize);
+ TRACE("dwDDFX %#x.\n", fx->dwDDFX);
+ TRACE("dwROP %#x.\n", fx->dwROP);
+ TRACE("dwDDROP %#x.\n", fx->dwDDROP);
+ TRACE("dwRotationAngle %#x.\n", fx->dwRotationAngle);
+ TRACE("dwZBufferOpCode %#x.\n", fx->dwZBufferOpCode);
+ TRACE("dwZBufferLow %#x.\n", fx->dwZBufferLow);
+ TRACE("dwZBufferHigh %#x.\n", fx->dwZBufferHigh);
+ TRACE("dwZBufferBaseDest %#x.\n", fx->dwZBufferBaseDest);
+ TRACE("dwZDestConstBitDepth %#x.\n", fx->dwZDestConstBitDepth);
+ TRACE("lpDDSZBufferDest %p.\n", fx->u1.lpDDSZBufferDest);
+ TRACE("dwZSrcConstBitDepth %#x.\n", fx->dwZSrcConstBitDepth);
+ TRACE("lpDDSZBufferSrc %p.\n", fx->u2.lpDDSZBufferSrc);
+ TRACE("dwAlphaEdgeBlendBitDepth %#x.\n", fx->dwAlphaEdgeBlendBitDepth);
+ TRACE("dwAlphaEdgeBlend %#x.\n", fx->dwAlphaEdgeBlend);
+ TRACE("dwReserved %#x.\n", fx->dwReserved);
+ TRACE("dwAlphaDestConstBitDepth %#x.\n", fx->dwAlphaDestConstBitDepth);
+ TRACE("lpDDSAlphaDest %p.\n", fx->u3.lpDDSAlphaDest);
+ TRACE("dwAlphaSrcConstBitDepth %#x.\n", fx->dwAlphaSrcConstBitDepth);
+ TRACE("lpDDSAlphaSrc %p.\n", fx->u4.lpDDSAlphaSrc);
+ TRACE("lpDDSPattern %p.\n", fx->u5.lpDDSPattern);
+ TRACE("ddckDestColorkey {%#x, %#x}.\n",
+ fx->ddckDestColorkey.color_space_low_value,
+ fx->ddckDestColorkey.color_space_high_value);
+ TRACE("ddckSrcColorkey {%#x, %#x}.\n",
+ fx->ddckSrcColorkey.color_space_low_value,
+ fx->ddckSrcColorkey.color_space_high_value);
+ }
+
+ if (dst_surface->resource.map_count || (src_surface && src_surface->resource.map_count))
+ {
+ WARN("Surface is busy, returning WINEDDERR_SURFACEBUSY.\n");
+ return WINEDDERR_SURFACEBUSY;
+ }
+
+ surface_get_rect(dst_surface, dst_rect_in, &dst_rect);
+
+ if (dst_rect.left >= dst_rect.right || dst_rect.top >= dst_rect.bottom
+ || dst_rect.left > dst_surface->resource.width || dst_rect.left < 0
+ || dst_rect.top > dst_surface->resource.height || dst_rect.top < 0
+ || dst_rect.right > dst_surface->resource.width || dst_rect.right < 0
+ || dst_rect.bottom > dst_surface->resource.height || dst_rect.bottom < 0)
+ {
+ WARN("The application gave us a bad destination rectangle.\n");
+ return WINEDDERR_INVALIDRECT;
+ }
+
+ if (src_surface)
+ {
+ surface_get_rect(src_surface, src_rect_in, &src_rect);
+
+ if (src_rect.left >= src_rect.right || src_rect.top >= src_rect.bottom
+ || src_rect.left > src_surface->resource.width || src_rect.left < 0
+ || src_rect.top > src_surface->resource.height || src_rect.top < 0
+ || src_rect.right > src_surface->resource.width || src_rect.right < 0
+ || src_rect.bottom > src_surface->resource.height || src_rect.bottom < 0)
+ {
+ WARN("Application gave us bad source rectangle for Blt.\n");
+ return WINEDDERR_INVALIDRECT;
+ }
+ }
+ else
+ {
+ memset(&src_rect, 0, sizeof(src_rect));
+ }
+
+#ifdef VBOX_WITH_WDDM
+ surface_shrc_lock(dst_surface);
+ if (src_surface) surface_shrc_lock(src_surface);
+
+ /* once we've done locking, we should do unlock on exit,
+ * do goto post_process instead of return below! */
+#endif
+
+ if (!fx || !(fx->dwDDFX))
+ flags &= ~WINEDDBLT_DDFX;
+
+ if (flags & WINEDDBLT_WAIT)
+ flags &= ~WINEDDBLT_WAIT;
+
+ if (flags & WINEDDBLT_ASYNC)
+ {
+ static unsigned int once;
+
+ if (!once++)
+ FIXME("Can't handle WINEDDBLT_ASYNC flag.\n");
+ flags &= ~WINEDDBLT_ASYNC;
+ }
+
+ /* WINEDDBLT_DONOTWAIT appeared in DX7. */
+ if (flags & WINEDDBLT_DONOTWAIT)
+ {
+ static unsigned int once;
+
+ if (!once++)
+ FIXME("Can't handle WINEDDBLT_DONOTWAIT flag.\n");
+ flags &= ~WINEDDBLT_DONOTWAIT;
+ }
+
+ if (!device->d3d_initialized)
+ {
+ WARN("D3D not initialized, using fallback.\n");
+ goto cpu;
+ }
+
+ /* We want to avoid invalidating the sysmem location for converted
+ * surfaces, since otherwise we'd have to convert the data back when
+ * locking them. */
+ if (dst_surface->flags & SFLAG_CONVERTED)
+ {
+ WARN_(d3d_perf)("Converted surface, using CPU blit.\n");
+#ifndef VBOX_WITH_WDDM
+ return surface_cpu_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fx, filter);
+#else
+ hr = surface_cpu_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fx, filter);
+ goto post_process;
+#endif
+
+ }
+
+ if (flags & ~simple_blit)
+ {
+ WARN_(d3d_perf)("Using fallback for complex blit (%#x).\n", flags);
+ goto fallback;
+ }
+
+ if (src_surface)
+ src_swapchain = src_surface->swapchain;
+ else
+ src_swapchain = NULL;
+
+ dst_swapchain = dst_surface->swapchain;
+
+ /* This isn't strictly needed. FBO blits for example could deal with
+ * cross-swapchain blits by first downloading the source to a texture
+ * before switching to the destination context. We just have this here to
+ * not have to deal with the issue, since cross-swapchain blits should be
+ * rare. */
+ if (src_swapchain && dst_swapchain && src_swapchain != dst_swapchain)
+ {
+ FIXME("Using fallback for cross-swapchain blit.\n");
+ goto fallback;
+ }
+
+ scale = src_surface
+ && (src_rect.right - src_rect.left != dst_rect.right - dst_rect.left
+ || src_rect.bottom - src_rect.top != dst_rect.bottom - dst_rect.top);
+ convert = src_surface && src_surface->resource.format->id != dst_surface->resource.format->id;
+
+ dst_ds_flags = dst_surface->resource.format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL);
+ if (src_surface)
+ src_ds_flags = src_surface->resource.format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL);
+ else
+ src_ds_flags = 0;
+
+ if (src_ds_flags || dst_ds_flags)
+ {
+ if (flags & WINEDDBLT_DEPTHFILL)
+ {
+ float depth;
+
+ TRACE("Depth fill.\n");
+
+ if (!surface_convert_depth_to_float(dst_surface, fx->u5.dwFillDepth, &depth))
+#ifndef VBOX_WITH_WDDM
+ return WINED3DERR_INVALIDCALL;
+#else
+ {
+ hr = WINED3DERR_INVALIDCALL;
+ goto post_process;
+ }
+#endif
+
+ if (SUCCEEDED(wined3d_surface_depth_fill(dst_surface, &dst_rect, depth)))
+#ifndef VBOX_WITH_WDDM
+ return WINED3D_OK;
+#else
+ {
+ hr = WINED3D_OK;
+ goto post_process;
+ }
+#endif
+ }
+ else
+ {
+ if (src_ds_flags != dst_ds_flags)
+ {
+ WARN("Rejecting depth / stencil blit between incompatible formats.\n");
+#ifndef VBOX_WITH_WDDM
+ return WINED3DERR_INVALIDCALL;
+#else
+ hr = WINED3D_OK;
+ goto post_process;
+#endif
+ }
+
+ if (SUCCEEDED(wined3d_surface_depth_blt(src_surface, src_surface->draw_binding, &src_rect,
+ dst_surface, dst_surface->draw_binding, &dst_rect)))
+#ifndef VBOX_WITH_WDDM
+ return WINED3D_OK;
+#else
+ {
+ hr = WINED3D_OK;
+ goto post_process;
+ }
+#endif
+ }
+ }
+ else
+ {
+ /* In principle this would apply to depth blits as well, but we don't
+ * implement those in the CPU blitter at the moment. */
+ if ((dst_surface->flags & SFLAG_INSYSMEM)
+ && (!src_surface || (src_surface->flags & SFLAG_INSYSMEM)))
+ {
+#ifdef DEBUG_misha
+ /* if below condition is not specified, i.e. both surfaces are in tecxture locations,
+ * we would perhaps need to fallback to tex->tex hw blitting */
+ Assert(!(dst_surface->flags & SFLAG_INTEXTURE) ||
+ !src_surface || !(src_surface->flags & SFLAG_INTEXTURE));
+#endif
+ if (scale)
+ TRACE("Not doing sysmem blit because of scaling.\n");
+ else if (convert)
+ TRACE("Not doing sysmem blit because of format conversion.\n");
+ else
+#ifndef VBOX_WITH_WDDM
+ return surface_cpu_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fx, filter);
+#else
+ {
+ hr = surface_cpu_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fx, filter);
+ goto post_process;
+ }
+#endif
+
+ }
+
+ if (flags & WINEDDBLT_COLORFILL)
+ {
+ struct wined3d_color color;
+
+ TRACE("Color fill.\n");
+
+ if (!surface_convert_color_to_float(dst_surface, fx->u5.dwFillColor, &color))
+ goto fallback;
+
+ if (SUCCEEDED(surface_color_fill(dst_surface, &dst_rect, &color)))
+#ifndef VBOX_WITH_WDDM
+ return WINED3D_OK;
+#else
+ {
+ hr = WINED3D_OK;
+ goto post_process;
+ }
+#endif
+ }
+ else
+ {
+ TRACE("Color blit.\n");
+
+ /* Upload */
+ if ((src_surface->flags & SFLAG_INSYSMEM) && !(dst_surface->flags & SFLAG_INSYSMEM))
+ {
+ if (scale)
+ TRACE("Not doing upload because of scaling.\n");
+ else if (convert)
+ TRACE("Not doing upload because of format conversion.\n");
+ else
+ {
+ POINT dst_point = {dst_rect.left, dst_rect.top};
+
+ if (SUCCEEDED(surface_upload_from_surface(dst_surface, &dst_point, src_surface, &src_rect)))
+ {
+ if (!surface_is_offscreen(dst_surface))
+ surface_load_location(dst_surface, dst_surface->draw_binding, NULL);
+#ifndef VBOX_WITH_WDDM
+ return WINED3D_OK;
+#else
+ hr = WINED3D_OK;
+ goto post_process;
+#endif
+ }
+ }
+ }
+
+ /* Use present for back -> front blits. The idea behind this is
+ * that present is potentially faster than a blit, in particular
+ * when FBO blits aren't available. Some ddraw applications like
+ * Half-Life and Prince of Persia 3D use Blt() from the backbuffer
+ * to the frontbuffer instead of doing a Flip(). D3D8 and D3D9
+ * applications can't blit directly to the frontbuffer. */
+ if (dst_swapchain && dst_swapchain->back_buffers
+ && dst_surface == dst_swapchain->front_buffer
+ && src_surface == dst_swapchain->back_buffers[0])
+ {
+ enum wined3d_swap_effect swap_effect = dst_swapchain->desc.swap_effect;
+
+ TRACE("Using present for backbuffer -> frontbuffer blit.\n");
+
+ /* Set the swap effect to COPY, we don't want the backbuffer
+ * to become undefined. */
+ dst_swapchain->desc.swap_effect = WINED3D_SWAP_EFFECT_COPY;
+ wined3d_swapchain_present(dst_swapchain, NULL, NULL, dst_swapchain->win_handle, NULL, 0);
+ dst_swapchain->desc.swap_effect = swap_effect;
+
+#ifndef VBOX_WITH_WDDM
+ return WINED3D_OK;
+#else
+ hr = WINED3D_OK;
+ goto post_process;
+#endif
+ }
+
+ if (fbo_blit_supported(&device->adapter->gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
+ &src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format,
+ &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format))
+ {
+ TRACE("Using FBO blit.\n");
+
+ surface_blt_fbo(device, filter,
+ src_surface, src_surface->draw_binding, &src_rect,
+ dst_surface, dst_surface->draw_binding, &dst_rect);
+ surface_modify_location(dst_surface, dst_surface->draw_binding, TRUE);
+#ifndef VBOX_WITH_WDDM
+ return WINED3D_OK;
+#else
+ hr = WINED3D_OK;
+ goto post_process;
+#endif
+ }
+
+ if (arbfp_blit.blit_supported(&device->adapter->gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
+ &src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format,
+ &dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format))
+ {
+ TRACE("Using arbfp blit.\n");
+
+ if (SUCCEEDED(arbfp_blit_surface(device, filter, src_surface, &src_rect, dst_surface, &dst_rect)))
+#ifndef VBOX_WITH_WDDM
+ return WINED3D_OK;
+#else
+ {
+ hr = WINED3D_OK;
+ goto post_process;
+ }
+#endif
+ }
+ }
+ }
+
+fallback:
+
+#ifdef DEBUG_misha
+ /* test ! */
+ Assert(0);
+#endif
+ /* Special cases for render targets. */
+ if ((dst_surface->resource.usage & WINED3DUSAGE_RENDERTARGET)
+ || (src_surface && (src_surface->resource.usage & WINED3DUSAGE_RENDERTARGET)))
+ {
+ if (SUCCEEDED(IWineD3DSurfaceImpl_BltOverride(dst_surface, &dst_rect,
+ src_surface, &src_rect, flags, fx, filter)))
+#ifndef VBOX_WITH_WDDM
+ return WINED3D_OK;
+#else
+ {
+ hr = WINED3D_OK;
+ goto post_process;
+ }
+#endif
+ }
+
+cpu:
+
+#ifdef DEBUG_misha
+ /* test ! */
+ Assert(0);
+#endif
+
+
+ /* For the rest call the X11 surface implementation. For render targets
+ * this should be implemented OpenGL accelerated in BltOverride, other
+ * blits are rather rare. */
+#ifndef VBOX_WITH_WDDM
+ return surface_cpu_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fx, filter);
+#else
+ hr = surface_cpu_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fx, filter);
+ goto post_process;
+#endif
+
+#ifdef VBOX_WITH_WDDM
+post_process:
+ surface_shrc_unlock(dst_surface);
+ if (src_surface) surface_shrc_unlock(src_surface);
+ return hr;
+#endif
+}
+
+HRESULT CDECL wined3d_surface_get_render_target_data(struct wined3d_surface *surface,
+ struct wined3d_surface *render_target)
+{
+ TRACE("surface %p, render_target %p.\n", surface, render_target);
+
+ /* TODO: Check surface sizes, pools, etc. */
+
+ if (render_target->resource.multisample_type)
+ return WINED3DERR_INVALIDCALL;
+
+ return wined3d_surface_blt(surface, NULL, render_target, NULL, 0, NULL, WINED3D_TEXF_POINT);
+}
+
+/* Context activation is done by the caller. */
+static void surface_remove_pbo(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info)
+{
+ if (surface->flags & SFLAG_DIBSECTION)
+ {
+ surface->resource.allocatedMemory = surface->dib.bitmap_data;
+ }
+ else
+ {
+ if (!surface->resource.heapMemory)
+ surface->resource.heapMemory = HeapAlloc(GetProcessHeap(), 0, surface->resource.size + RESOURCE_ALIGNMENT);
+ else if (!(surface->flags & SFLAG_CLIENT))
+ ERR("Surface %p has heapMemory %p and flags %#x.\n",
+ surface, surface->resource.heapMemory, surface->flags);
+
+ surface->resource.allocatedMemory = (BYTE *)(((ULONG_PTR)surface->resource.heapMemory
+ + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
+ }
+
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo));
+ checkGLcall("glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, surface->pbo)");
+ GL_EXTCALL(glGetBufferSubDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0,
+ surface->resource.size, surface->resource.allocatedMemory));
+ checkGLcall("glGetBufferSubDataARB");
+ GL_EXTCALL(glDeleteBuffersARB(1, &surface->pbo));
+ checkGLcall("glDeleteBuffersARB");
+
+ surface->pbo = 0;
+ surface->flags &= ~SFLAG_PBO;
+}
+
+static BOOL surface_init_sysmem(struct wined3d_surface *surface)
+{
+ if (!surface->resource.allocatedMemory)
+ {
+ if (!surface->resource.heapMemory)
+ {
+ if (!(surface->resource.heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ surface->resource.size + RESOURCE_ALIGNMENT)))
+ {
+ ERR("Failed to allocate memory.\n");
+ return FALSE;
+ }
+ }
+ else if (!(surface->flags & SFLAG_CLIENT))
+ {
+ ERR("Surface %p has heapMemory %p and flags %#x.\n",
+ surface, surface->resource.heapMemory, surface->flags);
+ }
+
+ surface->resource.allocatedMemory =
+ (BYTE *)(((ULONG_PTR)surface->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
+ }
+ else
+ {
+ memset(surface->resource.allocatedMemory, 0, surface->resource.size);
+ }
+
+ surface_modify_location(surface, SFLAG_INSYSMEM, TRUE);
+
+ return TRUE;
+}
+
+/* Do not call while under the GL lock. */
+static void surface_unload(struct wined3d_resource *resource)
+{
+ struct wined3d_surface *surface = surface_from_resource(resource);
+ struct wined3d_renderbuffer_entry *entry, *entry2;
+ struct wined3d_device *device = resource->device;
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+
+ TRACE("surface %p.\n", surface);
+
+ if (resource->pool == WINED3D_POOL_DEFAULT)
+ {
+ /* Default pool resources are supposed to be destroyed before Reset is called.
+ * Implicit resources stay however. So this means we have an implicit render target
+ * or depth stencil. The content may be destroyed, but we still have to tear down
+ * opengl resources, so we cannot leave early.
+ *
+ * Put the surfaces into sysmem, and reset the content. The D3D content is undefined,
+ * but we can't set the sysmem INDRAWABLE because when we're rendering the swapchain
+ * or the depth stencil into an FBO the texture or render buffer will be removed
+ * and all flags get lost
+ */
+ if (!(surface->flags & SFLAG_PBO))
+ surface_init_sysmem(surface);
+ /* We also get here when the ddraw swapchain is destroyed, for example
+ * for a mode switch. In this case this surface won't necessarily be
+ * an implicit surface. We have to mark it lost so that the
+ * application can restore it after the mode switch. */
+ surface->flags |= SFLAG_LOST;
+ }
+ else
+ {
+ /* Load the surface into system memory */
+ surface_load_location(surface, SFLAG_INSYSMEM, NULL);
+ surface_modify_location(surface, surface->draw_binding, FALSE);
+ }
+ surface_modify_location(surface, SFLAG_INTEXTURE, FALSE);
+ surface_modify_location(surface, SFLAG_INSRGBTEX, FALSE);
+ surface->flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
+
+ context = context_acquire(device, NULL);
+ gl_info = context->gl_info;
+
+ /* Destroy PBOs, but load them into real sysmem before */
+ if (surface->flags & SFLAG_PBO)
+ surface_remove_pbo(surface, gl_info);
+
+ /* Destroy fbo render buffers. This is needed for implicit render targets, for
+ * all application-created targets the application has to release the surface
+ * before calling _Reset
+ */
+ LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry)
+ {
+ gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
+ list_remove(&entry->entry);
+ HeapFree(GetProcessHeap(), 0, entry);
+ }
+ list_init(&surface->renderbuffers);
+ surface->current_renderbuffer = NULL;
+
+ /* If we're in a texture, the texture name belongs to the texture.
+ * Otherwise, destroy it. */
+ if (!surface->container)
+ {
+#ifdef VBOX_WITH_WINE_FIX_TEXCLEAR
+ if (surface->texture_name)
+#endif
+ {
+#ifdef VBOX_WITH_WDDM
+ texture_gl_delete(surface->texture_name);
+#else
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &surface->texture_name);
+#endif
+ surface->texture_name = 0;
+ }
+#ifdef VBOX_WITH_WINE_FIX_TEXCLEAR
+ if (surface->texture_name_srgb)
+#endif
+ {
+#ifdef VBOX_WITH_WDDM
+ texture_gl_delete(surface->texture_name_srgb);
+#else
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &surface->texture_name_srgb);
+#endif
+ surface->texture_name_srgb = 0;
+ }
+ }
+ if (surface->rb_multisample)
+ {
+ gl_info->fbo_ops.glDeleteRenderbuffers(1, &surface->rb_multisample);
+ surface->rb_multisample = 0;
+ }
+ if (surface->rb_resolved)
+ {
+ gl_info->fbo_ops.glDeleteRenderbuffers(1, &surface->rb_resolved);
+ surface->rb_resolved = 0;
+ }
+
+ context_release(context);
+
+ resource_unload(resource);
+}
+
+static const struct wined3d_resource_ops surface_resource_ops =
+{
+ surface_unload,
+};
+
+static const struct wined3d_surface_ops surface_ops =
+{
+ surface_private_setup,
+ surface_realize_palette,
+ surface_map,
+ surface_unmap,
+};
+
+/*****************************************************************************
+ * Initializes the GDI surface, aka creates the DIB section we render to
+ * The DIB section creation is done by calling GetDC, which will create the
+ * section and releasing the dc to allow the app to use it. The dib section
+ * will stay until the surface is released
+ *
+ * GDI surfaces do not need to be a power of 2 in size, so the pow2 sizes
+ * are set to the real sizes to save memory. The NONPOW2 flag is unset to
+ * avoid confusion in the shared surface code.
+ *
+ * Returns:
+ * WINED3D_OK on success
+ * The return values of called methods on failure
+ *
+ *****************************************************************************/
+static HRESULT gdi_surface_private_setup(struct wined3d_surface *surface)
+{
+ HRESULT hr;
+
+ TRACE("surface %p.\n", surface);
+
+ if (surface->resource.usage & WINED3DUSAGE_OVERLAY)
+ {
+ ERR("Overlays not yet supported by GDI surfaces.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ /* Sysmem textures have memory already allocated - release it,
+ * this avoids an unnecessary memcpy. */
+ hr = surface_create_dib_section(surface);
+ if (SUCCEEDED(hr))
+ {
+ HeapFree(GetProcessHeap(), 0, surface->resource.heapMemory);
+ surface->resource.heapMemory = NULL;
+ surface->resource.allocatedMemory = surface->dib.bitmap_data;
+ }
+
+ /* We don't mind the nonpow2 stuff in GDI. */
+ surface->pow2Width = surface->resource.width;
+ surface->pow2Height = surface->resource.height;
+
+ return WINED3D_OK;
+}
+
+static void gdi_surface_realize_palette(struct wined3d_surface *surface)
+{
+ struct wined3d_palette *palette = surface->palette;
+
+ TRACE("surface %p.\n", surface);
+
+ if (!palette) return;
+
+ if (surface->flags & SFLAG_DIBSECTION)
+ {
+ RGBQUAD col[256];
+ unsigned int i;
+
+ TRACE("Updating the DC's palette.\n");
+
+ for (i = 0; i < 256; ++i)
+ {
+ col[i].rgbRed = palette->palents[i].peRed;
+ col[i].rgbGreen = palette->palents[i].peGreen;
+ col[i].rgbBlue = palette->palents[i].peBlue;
+ col[i].rgbReserved = 0;
+ }
+ SetDIBColorTable(surface->hDC, 0, 256, col);
+ }
+
+ /* Update the image because of the palette change. Some games like e.g.
+ * Red Alert call SetEntries a lot to implement fading. */
+ /* Tell the swapchain to update the screen. */
+ if (surface->swapchain && surface == surface->swapchain->front_buffer)
+ x11_copy_to_screen(surface->swapchain, NULL);
+}
+
+static void gdi_surface_map(struct wined3d_surface *surface, const RECT *rect, DWORD flags)
+{
+ TRACE("surface %p, rect %s, flags %#x.\n",
+ surface, wine_dbgstr_rect(rect), flags);
+
+ if (!(surface->flags & SFLAG_DIBSECTION))
+ {
+ HRESULT hr;
+
+ /* This happens on gdi surfaces if the application set a user pointer
+ * and resets it. Recreate the DIB section. */
+ if (FAILED(hr = surface_create_dib_section(surface)))
+ {
+ ERR("Failed to create dib section, hr %#x.\n", hr);
+ return;
+ }
+ HeapFree(GetProcessHeap(), 0, surface->resource.heapMemory);
+ surface->resource.heapMemory = NULL;
+ surface->resource.allocatedMemory = surface->dib.bitmap_data;
+ }
+}
+
+static void gdi_surface_unmap(struct wined3d_surface *surface)
+{
+ TRACE("surface %p.\n", surface);
+
+ /* Tell the swapchain to update the screen. */
+ if (surface->swapchain && surface == surface->swapchain->front_buffer)
+ x11_copy_to_screen(surface->swapchain, &surface->lockedRect);
+
+ memset(&surface->lockedRect, 0, sizeof(RECT));
+}
+
+static const struct wined3d_surface_ops gdi_surface_ops =
+{
+ gdi_surface_private_setup,
+ gdi_surface_realize_palette,
+ gdi_surface_map,
+ gdi_surface_unmap,
+};
+
+void surface_set_texture_name(struct wined3d_surface *surface, GLuint new_name, BOOL srgb)
+{
+ GLuint *name;
+ DWORD flag;
+
+ TRACE("surface %p, new_name %u, srgb %#x.\n", surface, new_name, srgb);
+
+ if(srgb)
+ {
+ name = &surface->texture_name_srgb;
+ flag = SFLAG_INSRGBTEX;
+ }
+ else
+ {
+ name = &surface->texture_name;
+ flag = SFLAG_INTEXTURE;
+ }
+
+ if (!*name && new_name)
+ {
+ /* FIXME: We shouldn't need to remove SFLAG_INTEXTURE if the
+ * surface has no texture name yet. See if we can get rid of this. */
+ if (surface->flags & flag)
+ {
+ ERR("Surface has %s set, but no texture name.\n", debug_surflocation(flag));
+#ifndef VBOX_WITH_WDDM
+ surface_modify_location(surface, flag, FALSE);
+#endif
+ }
+ }
+
+#ifdef VBOX_WITH_WDDM
+ if (VBOXSHRC_IS_SHARED(surface))
+ {
+ Assert(VBOXSHRC_GET_SHAREHANDLE(surface) == NULL
+ || (GLuint)VBOXSHRC_GET_SHAREHANDLE(surface) == new_name
+ || new_name == 0 /* on cleanup */);
+ VBOXSHRC_SET_SHAREHANDLE(surface, new_name);
+ }
+#endif
+ *name = new_name;
+ surface_force_reload(surface);
+}
+
+void surface_set_texture_target(struct wined3d_surface *surface, GLenum target, GLint level)
+{
+ TRACE("surface %p, target %#x.\n", surface, target);
+
+ if (surface->texture_target != target)
+ {
+ if (target == GL_TEXTURE_RECTANGLE_ARB)
+ {
+ surface->flags &= ~SFLAG_NORMCOORD;
+ }
+ else if (surface->texture_target == GL_TEXTURE_RECTANGLE_ARB)
+ {
+ surface->flags |= SFLAG_NORMCOORD;
+ }
+ }
+ surface->texture_target = target;
+ surface->texture_level = level;
+ surface_force_reload(surface);
+}
+
+/* This call just downloads data, the caller is responsible for binding the
+ * correct texture. */
+/* Context activation is done by the caller. */
+static void surface_download_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info)
+{
+ const struct wined3d_format *format = surface->resource.format;
+
+ /* Only support read back of converted P8 surfaces. */
+ if (surface->flags & SFLAG_CONVERTED && format->id != WINED3DFMT_P8_UINT)
+ {
+ ERR("Trying to read back converted surface %p with format %s.\n", surface, debug_d3dformat(format->id));
+ return;
+ }
+
+ if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
+ {
+ TRACE("(%p) : Calling glGetCompressedTexImageARB level %d, format %#x, type %#x, data %p.\n",
+ surface, surface->texture_level, format->glFormat, format->glType,
+ surface->resource.allocatedMemory);
+
+ if (surface->flags & SFLAG_PBO)
+ {
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, surface->pbo));
+ checkGLcall("glBindBufferARB");
+ GL_EXTCALL(glGetCompressedTexImageARB(surface->texture_target, surface->texture_level, NULL));
+ checkGLcall("glGetCompressedTexImageARB");
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
+ checkGLcall("glBindBufferARB");
+ }
+ else
+ {
+ GL_EXTCALL(glGetCompressedTexImageARB(surface->texture_target,
+ surface->texture_level, surface->resource.allocatedMemory));
+ checkGLcall("glGetCompressedTexImageARB");
+ }
+
+ }
+ else
+ {
+ void *mem;
+ GLenum gl_format = format->glFormat;
+ GLenum gl_type = format->glType;
+ int src_pitch = 0;
+ int dst_pitch = 0;
+
+ /* In case of P8 the index is stored in the alpha component if the primary render target uses P8. */
+ if (format->id == WINED3DFMT_P8_UINT && primary_render_target_is_p8(surface->resource.device))
+ {
+ gl_format = GL_ALPHA;
+ gl_type = GL_UNSIGNED_BYTE;
+ }
+
+ if (surface->flags & SFLAG_NONPOW2)
+ {
+ unsigned char alignment = surface->resource.device->surface_alignment;
+ src_pitch = format->byte_count * surface->pow2Width;
+ dst_pitch = wined3d_surface_get_pitch(surface);
+ src_pitch = (src_pitch + alignment - 1) & ~(alignment - 1);
+ mem = HeapAlloc(GetProcessHeap(), 0, src_pitch * surface->pow2Height);
+ }
+ else
+ {
+ mem = surface->resource.allocatedMemory;
+ }
+
+ TRACE("(%p) : Calling glGetTexImage level %d, format %#x, type %#x, data %p\n",
+ surface, surface->texture_level, gl_format, gl_type, mem);
+
+ if (surface->flags & SFLAG_PBO)
+ {
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, surface->pbo));
+ checkGLcall("glBindBufferARB");
+
+ gl_info->gl_ops.gl.p_glGetTexImage(surface->texture_target, surface->texture_level,
+ gl_format, gl_type, NULL);
+ checkGLcall("glGetTexImage");
+
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
+ checkGLcall("glBindBufferARB");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glGetTexImage(surface->texture_target, surface->texture_level,
+ gl_format, gl_type, mem);
+ checkGLcall("glGetTexImage");
+ }
+
+ if (surface->flags & SFLAG_NONPOW2)
+ {
+ const BYTE *src_data;
+ BYTE *dst_data;
+ UINT y;
+ /*
+ * Some games (e.g. warhammer 40k) don't work properly with the odd pitches, preventing
+ * the surface pitch from being used to box non-power2 textures. Instead we have to use a hack to
+ * repack the texture so that the bpp * width pitch can be used instead of bpp * pow2width.
+ *
+ * We're doing this...
+ *
+ * instead of boxing the texture :
+ * |<-texture width ->| -->pow2width| /\
+ * |111111111111111111| | |
+ * |222 Texture 222222| boxed empty | texture height
+ * |3333 Data 33333333| | |
+ * |444444444444444444| | \/
+ * ----------------------------------- |
+ * | boxed empty | boxed empty | pow2height
+ * | | | \/
+ * -----------------------------------
+ *
+ *
+ * we're repacking the data to the expected texture width
+ *
+ * |<-texture width ->| -->pow2width| /\
+ * |111111111111111111222222222222222| |
+ * |222333333333333333333444444444444| texture height
+ * |444444 | |
+ * | | \/
+ * | | |
+ * | empty | pow2height
+ * | | \/
+ * -----------------------------------
+ *
+ * == is the same as
+ *
+ * |<-texture width ->| /\
+ * |111111111111111111|
+ * |222222222222222222|texture height
+ * |333333333333333333|
+ * |444444444444444444| \/
+ * --------------------
+ *
+ * this also means that any references to allocatedMemory should work with the data as if were a
+ * standard texture with a non-power2 width instead of texture boxed up to be a power2 texture.
+ *
+ * internally the texture is still stored in a boxed format so any references to textureName will
+ * get a boxed texture with width pow2width and not a texture of width resource.width.
+ *
+ * Performance should not be an issue, because applications normally do not lock the surfaces when
+ * rendering. If an app does, the SFLAG_DYNLOCK flag will kick in and the memory copy won't be released,
+ * and doesn't have to be re-read. */
+ src_data = mem;
+ dst_data = surface->resource.allocatedMemory;
+ TRACE("(%p) : Repacking the surface data from pitch %d to pitch %d\n", surface, src_pitch, dst_pitch);
+ for (y = 0; y < surface->resource.height; ++y)
+ {
+ memcpy(dst_data, src_data, dst_pitch);
+ src_data += src_pitch;
+ dst_data += dst_pitch;
+ }
+
+ HeapFree(GetProcessHeap(), 0, mem);
+ }
+ }
+
+ /* Surface has now been downloaded */
+ surface->flags |= SFLAG_INSYSMEM;
+}
+
+/* This call just uploads data, the caller is responsible for binding the
+ * correct texture. */
+/* Context activation is done by the caller. */
+static void surface_upload_data(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info,
+ const struct wined3d_format *format, const RECT *src_rect, UINT src_pitch, const POINT *dst_point,
+ BOOL srgb, const struct wined3d_bo_address *data)
+{
+ UINT update_w = src_rect->right - src_rect->left;
+ UINT update_h = src_rect->bottom - src_rect->top;
+
+ TRACE("surface %p, gl_info %p, format %s, src_rect %s, src_pitch %u, dst_point %s, srgb %#x, data {%#x:%p}.\n",
+ surface, gl_info, debug_d3dformat(format->id), wine_dbgstr_rect(src_rect), src_pitch,
+ wine_dbgstr_point(dst_point), srgb, data->buffer_object, data->addr);
+
+ if (surface->resource.map_count)
+ {
+ WARN("Uploading a surface that is currently mapped, setting SFLAG_PIN_SYSMEM.\n");
+ surface->flags |= SFLAG_PIN_SYSMEM;
+ }
+
+ if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
+ {
+ update_h *= format->height_scale.numerator;
+ update_h /= format->height_scale.denominator;
+ }
+
+ if (data->buffer_object)
+ {
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, data->buffer_object));
+ checkGLcall("glBindBufferARB");
+ }
+
+ if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
+ {
+ UINT row_length = wined3d_format_calculate_size(format, 1, update_w, 1);
+ UINT row_count = (update_h + format->block_height - 1) / format->block_height;
+ const BYTE *addr = data->addr;
+ GLenum internal;
+
+ addr += (src_rect->top / format->block_height) * src_pitch;
+ addr += (src_rect->left / format->block_width) * format->block_byte_count;
+
+ if (srgb)
+ internal = format->glGammaInternal;
+ else if (surface->resource.usage & WINED3DUSAGE_RENDERTARGET && surface_is_offscreen(surface))
+ internal = format->rtInternal;
+ else
+ internal = format->glInternal;
+
+ TRACE("glCompressedTexSubImage2DARB, target %#x, level %d, x %d, y %d, w %d, h %d, "
+ "format %#x, image_size %#x, addr %p.\n", surface->texture_target, surface->texture_level,
+ dst_point->x, dst_point->y, update_w, update_h, internal, row_count * row_length, addr);
+
+ if (row_length == src_pitch)
+ {
+ GL_EXTCALL(glCompressedTexSubImage2DARB(surface->texture_target, surface->texture_level,
+ dst_point->x, dst_point->y, update_w, update_h, internal, row_count * row_length, addr));
+ }
+ else
+ {
+ UINT row, y;
+
+ /* glCompressedTexSubImage2DARB() ignores pixel store state, so we
+ * can't use the unpack row length like below. */
+ for (row = 0, y = dst_point->y; row < row_count; ++row)
+ {
+ GL_EXTCALL(glCompressedTexSubImage2DARB(surface->texture_target, surface->texture_level,
+ dst_point->x, y, update_w, format->block_height, internal, row_length, addr));
+ y += format->block_height;
+ addr += src_pitch;
+ }
+ }
+ checkGLcall("glCompressedTexSubImage2DARB");
+ }
+ else
+ {
+ const BYTE *addr = data->addr;
+
+ addr += src_rect->top * src_pitch;
+ addr += src_rect->left * format->byte_count;
+
+ TRACE("glTexSubImage2D, target %#x, level %d, x %d, y %d, w %d, h %d, format %#x, type %#x, addr %p.\n",
+ surface->texture_target, surface->texture_level, dst_point->x, dst_point->y,
+ update_w, update_h, format->glFormat, format->glType, addr);
+
+#ifdef VBOX_WITH_WINE_FIX_SURFUPDATA
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+#endif
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, src_pitch / format->byte_count);
+ gl_info->gl_ops.gl.p_glTexSubImage2D(surface->texture_target, surface->texture_level,
+ dst_point->x, dst_point->y, update_w, update_h, format->glFormat, format->glType, addr);
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+#ifdef VBOX_WITH_WINE_FIX_SURFUPDATA
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ALIGNMENT, surface->resource.device->surface_alignment);
+#endif
+ checkGLcall("glTexSubImage2D");
+ }
+
+ if (data->buffer_object)
+ {
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+ checkGLcall("glBindBufferARB");
+ }
+
+ if (wined3d_settings.strict_draw_ordering)
+ gl_info->gl_ops.gl.p_glFlush();
+
+ if (gl_info->quirks & WINED3D_QUIRK_FBO_TEX_UPDATE)
+ {
+ struct wined3d_device *device = surface->resource.device;
+ unsigned int i;
+
+ for (i = 0; i < device->context_count; ++i)
+ {
+ context_surface_update(device->contexts[i], surface);
+ }
+ }
+}
+
+static HRESULT d3dfmt_get_conv(const struct wined3d_surface *surface, BOOL need_alpha_ck, BOOL use_texturing,
+ struct wined3d_format *format, enum wined3d_conversion_type *conversion_type)
+{
+ BOOL colorkey_active = need_alpha_ck && (surface->CKeyFlags & WINEDDSD_CKSRCBLT);
+ const struct wined3d_device *device = surface->resource.device;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ BOOL blit_supported = FALSE;
+
+ /* Copy the default values from the surface. Below we might perform fixups */
+ /* TODO: get rid of color keying desc fixups by using e.g. a table. */
+ *format = *surface->resource.format;
+ *conversion_type = WINED3D_CT_NONE;
+
+ /* Ok, now look if we have to do any conversion */
+ switch (surface->resource.format->id)
+ {
+ case WINED3DFMT_P8_UINT:
+ /* Below the call to blit_supported is disabled for Wine 1.2
+ * because the function isn't operating correctly yet. At the
+ * moment 8-bit blits are handled in software and if certain GL
+ * extensions are around, surface conversion is performed at
+ * upload time. The blit_supported call recognizes it as a
+ * destination fixup. This type of upload 'fixup' and 8-bit to
+ * 8-bit blits need to be handled by the blit_shader.
+ * TODO: get rid of this #if 0. */
+#if 0
+ blit_supported = device->blitter->blit_supported(&device->adapter->gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
+ &rect, surface->resource.usage, surface->resource.pool, surface->resource.format,
+ &rect, surface->resource.usage, surface->resource.pool, surface->resource.format);
+#endif
+ blit_supported = gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM];
+
+ /* Use conversion when the blit_shader backend supports it. It only supports this in case of
+ * texturing. Further also use conversion in case of color keying.
+ * Paletted textures can be emulated using shaders but only do that for 2D purposes e.g. situations
+ * in which the main render target uses p8. Some games like GTA Vice City use P8 for texturing which
+ * conflicts with this.
+ */
+ if (!((blit_supported && device->fb.render_targets && surface == device->fb.render_targets[0]))
+ || colorkey_active || !use_texturing)
+ {
+ format->glFormat = GL_RGBA;
+ format->glInternal = GL_RGBA;
+ format->glType = GL_UNSIGNED_BYTE;
+ format->conv_byte_count = 4;
+ if (colorkey_active)
+ *conversion_type = WINED3D_CT_PALETTED_CK;
+ else
+ *conversion_type = WINED3D_CT_PALETTED;
+ }
+ break;
+
+ case WINED3DFMT_B2G3R3_UNORM:
+ /* **********************
+ GL_UNSIGNED_BYTE_3_3_2
+ ********************** */
+ if (colorkey_active) {
+ /* This texture format will never be used.. So do not care about color keying
+ up until the point in time it will be needed :-) */
+ FIXME(" ColorKeying not supported in the RGB 332 format !\n");
+ }
+ break;
+
+ case WINED3DFMT_B5G6R5_UNORM:
+ if (colorkey_active)
+ {
+ *conversion_type = WINED3D_CT_CK_565;
+ format->glFormat = GL_RGBA;
+ format->glInternal = GL_RGB5_A1;
+ format->glType = GL_UNSIGNED_SHORT_5_5_5_1;
+ format->conv_byte_count = 2;
+ }
+ break;
+
+ case WINED3DFMT_B5G5R5X1_UNORM:
+ if (colorkey_active)
+ {
+ *conversion_type = WINED3D_CT_CK_5551;
+ format->glFormat = GL_BGRA;
+ format->glInternal = GL_RGB5_A1;
+ format->glType = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+ format->conv_byte_count = 2;
+ }
+ break;
+
+ case WINED3DFMT_B8G8R8_UNORM:
+ if (colorkey_active)
+ {
+ *conversion_type = WINED3D_CT_CK_RGB24;
+ format->glFormat = GL_RGBA;
+ format->glInternal = GL_RGBA8;
+ format->glType = GL_UNSIGNED_INT_8_8_8_8;
+ format->conv_byte_count = 4;
+ }
+ break;
+
+ case WINED3DFMT_B8G8R8X8_UNORM:
+ if (colorkey_active)
+ {
+ *conversion_type = WINED3D_CT_RGB32_888;
+ format->glFormat = GL_RGBA;
+ format->glInternal = GL_RGBA8;
+ format->glType = GL_UNSIGNED_INT_8_8_8_8;
+ format->conv_byte_count = 4;
+ }
+ break;
+
+ case WINED3DFMT_B8G8R8A8_UNORM:
+ if (colorkey_active)
+ {
+ *conversion_type = WINED3D_CT_CK_ARGB32;
+ format->conv_byte_count = 4;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (*conversion_type != WINED3D_CT_NONE)
+ {
+ format->rtInternal = format->glInternal;
+ format->glGammaInternal = format->glInternal;
+ }
+
+ return WINED3D_OK;
+}
+
+static BOOL surface_check_block_align(struct wined3d_surface *surface, const RECT *rect)
+{
+ UINT width_mask, height_mask;
+
+ if (!rect->left && !rect->top
+ && rect->right == surface->resource.width
+ && rect->bottom == surface->resource.height)
+ return TRUE;
+
+ /* This assumes power of two block sizes, but NPOT block sizes would be
+ * silly anyway. */
+ width_mask = surface->resource.format->block_width - 1;
+ height_mask = surface->resource.format->block_height - 1;
+
+ if (!(rect->left & width_mask) && !(rect->top & height_mask)
+ && !(rect->right & width_mask) && !(rect->bottom & height_mask))
+ return TRUE;
+
+ return FALSE;
+}
+
+HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point,
+ struct wined3d_surface *src_surface, const RECT *src_rect)
+{
+ const struct wined3d_format *src_format;
+ const struct wined3d_format *dst_format;
+ const struct wined3d_gl_info *gl_info;
+ enum wined3d_conversion_type convert;
+ struct wined3d_context *context;
+ struct wined3d_bo_address data;
+ struct wined3d_format format;
+ UINT update_w, update_h;
+ UINT dst_w, dst_h;
+ RECT r, dst_rect;
+ UINT src_pitch;
+ POINT p;
+
+ TRACE("dst_surface %p, dst_point %s, src_surface %p, src_rect %s.\n",
+ dst_surface, wine_dbgstr_point(dst_point),
+ src_surface, wine_dbgstr_rect(src_rect));
+
+ src_format = src_surface->resource.format;
+ dst_format = dst_surface->resource.format;
+
+ if (src_format->id != dst_format->id)
+ {
+ WARN("Source and destination surfaces should have the same format.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (!dst_point)
+ {
+ p.x = 0;
+ p.y = 0;
+ dst_point = &p;
+ }
+ else if (dst_point->x < 0 || dst_point->y < 0)
+ {
+ WARN("Invalid destination point.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (!src_rect)
+ {
+ r.left = 0;
+ r.top = 0;
+ r.right = src_surface->resource.width;
+ r.bottom = src_surface->resource.height;
+ src_rect = &r;
+ }
+ else if (src_rect->left < 0 || src_rect->left >= src_rect->right
+ || src_rect->top < 0 || src_rect->top >= src_rect->bottom)
+ {
+ WARN("Invalid source rectangle.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ dst_w = dst_surface->resource.width;
+ dst_h = dst_surface->resource.height;
+
+ update_w = src_rect->right - src_rect->left;
+ update_h = src_rect->bottom - src_rect->top;
+
+ if (update_w > dst_w || dst_point->x > dst_w - update_w
+ || update_h > dst_h || dst_point->y > dst_h - update_h)
+ {
+ WARN("Destination out of bounds.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if ((src_format->flags & WINED3DFMT_FLAG_BLOCKS) && !surface_check_block_align(src_surface, src_rect))
+ {
+ WARN("Source rectangle not block-aligned.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ SetRect(&dst_rect, dst_point->x, dst_point->y, dst_point->x + update_w, dst_point->y + update_h);
+ if ((dst_format->flags & WINED3DFMT_FLAG_BLOCKS) && !surface_check_block_align(dst_surface, &dst_rect))
+ {
+ WARN("Destination rectangle not block-aligned.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ /* Use wined3d_surface_blt() instead of uploading directly if we need conversion. */
+ d3dfmt_get_conv(dst_surface, FALSE, TRUE, &format, &convert);
+ if (convert != WINED3D_CT_NONE || format.convert)
+ return wined3d_surface_blt(dst_surface, &dst_rect, src_surface, src_rect, 0, NULL, WINED3D_TEXF_POINT);
+
+ context = context_acquire(dst_surface->resource.device, NULL);
+ gl_info = context->gl_info;
+
+ /* Only load the surface for partial updates. For newly allocated texture
+ * the texture wouldn't be the current location, and we'd upload zeroes
+ * just to overwrite them again. */
+ if (update_w == dst_w && update_h == dst_h)
+ surface_prepare_texture(dst_surface, context, FALSE);
+ else
+ surface_load_location(dst_surface, SFLAG_INTEXTURE, NULL);
+ surface_bind(dst_surface, context, FALSE);
+
+ data.buffer_object = src_surface->pbo;
+ data.addr = src_surface->resource.allocatedMemory;
+ src_pitch = wined3d_surface_get_pitch(src_surface);
+
+ surface_upload_data(dst_surface, gl_info, src_format, src_rect, src_pitch, dst_point, FALSE, &data);
+
+ invalidate_active_texture(dst_surface->resource.device, context);
+
+ context_release(context);
+
+ surface_modify_location(dst_surface, SFLAG_INTEXTURE, TRUE);
+ return WINED3D_OK;
+}
+
+/* This call just allocates the texture, the caller is responsible for binding
+ * the correct texture. */
+/* Context activation is done by the caller. */
+static void surface_allocate_surface(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info,
+ const struct wined3d_format *format, BOOL srgb)
+{
+ BOOL enable_client_storage = FALSE;
+ GLsizei width = surface->pow2Width;
+ GLsizei height = surface->pow2Height;
+ const BYTE *mem = NULL;
+ GLenum internal;
+
+#ifdef VBOX_WITH_WDDM
+ if (VBOXSHRC_IS_SHARED_OPENED(surface))
+ {
+ ERR("trying to allocate shared openned resource!!, ignoring..\n");
+ return;
+ }
+#endif
+
+ if (srgb)
+ {
+ internal = format->glGammaInternal;
+ }
+ else if (surface->resource.usage & WINED3DUSAGE_RENDERTARGET && surface_is_offscreen(surface))
+ {
+ internal = format->rtInternal;
+ }
+ else
+ {
+ internal = format->glInternal;
+ }
+
+ if (!internal)
+ FIXME("No GL internal format for format %s.\n", debug_d3dformat(format->id));
+
+ if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
+ {
+ height *= format->height_scale.numerator;
+ height /= format->height_scale.denominator;
+ }
+
+ TRACE("(%p) : Creating surface (target %#x) level %d, d3d format %s, internal format %#x, width %d, height %d, gl format %#x, gl type=%#x\n",
+ surface, surface->texture_target, surface->texture_level, debug_d3dformat(format->id),
+ internal, width, height, format->glFormat, format->glType);
+
+ if (gl_info->supported[APPLE_CLIENT_STORAGE])
+ {
+ if (surface->flags & (SFLAG_NONPOW2 | SFLAG_DIBSECTION | SFLAG_CONVERTED)
+ || !surface->resource.allocatedMemory)
+ {
+ /* In some cases we want to disable client storage.
+ * SFLAG_NONPOW2 has a bigger opengl texture than the client memory, and different pitches
+ * SFLAG_DIBSECTION: Dibsections may have read / write protections on the memory. Avoid issues...
+ * SFLAG_CONVERTED: The conversion destination memory is freed after loading the surface
+ * allocatedMemory == NULL: Not defined in the extension. Seems to disable client storage effectively
+ */
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
+ checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE)");
+ surface->flags &= ~SFLAG_CLIENT;
+ enable_client_storage = TRUE;
+ }
+ else
+ {
+ surface->flags |= SFLAG_CLIENT;
+
+ /* Point OpenGL to our allocated texture memory. Do not use
+ * resource.allocatedMemory here because it might point into a
+ * PBO. Instead use heapMemory, but get the alignment right. */
+ mem = (BYTE *)(((ULONG_PTR)surface->resource.heapMemory
+ + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
+ }
+ }
+
+ if (format->flags & WINED3DFMT_FLAG_COMPRESSED && mem)
+ {
+ GL_EXTCALL(glCompressedTexImage2DARB(surface->texture_target, surface->texture_level,
+ internal, width, height, 0, surface->resource.size, mem));
+ checkGLcall("glCompressedTexImage2DARB");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level,
+ internal, width, height, 0, format->glFormat, format->glType, mem);
+ checkGLcall("glTexImage2D");
+ }
+
+ if (enable_client_storage)
+ {
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
+ checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
+ }
+}
+
+/* In D3D the depth stencil dimensions have to be greater than or equal to the
+ * render target dimensions. With FBOs, the dimensions have to be an exact match. */
+/* TODO: We should synchronize the renderbuffer's content with the texture's content. */
+/* Context activation is done by the caller. */
+void surface_set_compatible_renderbuffer(struct wined3d_surface *surface, const struct wined3d_surface *rt)
+{
+ const struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info;
+ struct wined3d_renderbuffer_entry *entry;
+ GLuint renderbuffer = 0;
+ unsigned int src_width, src_height;
+ unsigned int width, height;
+
+ if (rt && rt->resource.format->id != WINED3DFMT_NULL)
+ {
+ width = rt->pow2Width;
+ height = rt->pow2Height;
+ }
+ else
+ {
+ width = surface->pow2Width;
+ height = surface->pow2Height;
+ }
+
+ src_width = surface->pow2Width;
+ src_height = surface->pow2Height;
+
+ /* A depth stencil smaller than the render target is not valid */
+ if (width > src_width || height > src_height) return;
+
+ /* Remove any renderbuffer set if the sizes match */
+ if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
+ || (width == src_width && height == src_height))
+ {
+ surface->current_renderbuffer = NULL;
+ return;
+ }
+
+ /* Look if we've already got a renderbuffer of the correct dimensions */
+ LIST_FOR_EACH_ENTRY(entry, &surface->renderbuffers, struct wined3d_renderbuffer_entry, entry)
+ {
+ if (entry->width == width && entry->height == height)
+ {
+ renderbuffer = entry->id;
+ surface->current_renderbuffer = entry;
+ break;
+ }
+ }
+
+ if (!renderbuffer)
+ {
+ gl_info->fbo_ops.glGenRenderbuffers(1, &renderbuffer);
+ gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
+ gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER,
+ surface->resource.format->glInternal, width, height);
+
+ entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry));
+ entry->width = width;
+ entry->height = height;
+ entry->id = renderbuffer;
+ list_add_head(&surface->renderbuffers, &entry->entry);
+
+ surface->current_renderbuffer = entry;
+ }
+
+ checkGLcall("set_compatible_renderbuffer");
+}
+
+GLenum surface_get_gl_buffer(const struct wined3d_surface *surface)
+{
+ const struct wined3d_swapchain *swapchain = surface->swapchain;
+
+ TRACE("surface %p.\n", surface);
+
+ if (!swapchain)
+ {
+ ERR("Surface %p is not on a swapchain.\n", surface);
+ return GL_NONE;
+ }
+
+ if (swapchain->back_buffers && swapchain->back_buffers[0] == surface)
+ {
+ if (swapchain->render_to_fbo)
+ {
+ TRACE("Returning GL_COLOR_ATTACHMENT0\n");
+ return GL_COLOR_ATTACHMENT0;
+ }
+ TRACE("Returning GL_BACK\n");
+ return GL_BACK;
+ }
+ else if (surface == swapchain->front_buffer)
+ {
+ TRACE("Returning GL_FRONT\n");
+ return GL_FRONT;
+ }
+
+ FIXME("Higher back buffer, returning GL_BACK\n");
+ return GL_BACK;
+}
+
+/* Slightly inefficient way to handle multiple dirty rects but it works :) */
+void surface_add_dirty_rect(struct wined3d_surface *surface, const struct wined3d_box *dirty_rect)
+{
+ TRACE("surface %p, dirty_rect %p.\n", surface, dirty_rect);
+
+ if (!(surface->flags & SFLAG_INSYSMEM) && (surface->flags & SFLAG_INTEXTURE))
+ /* No partial locking for textures yet. */
+ surface_load_location(surface, SFLAG_INSYSMEM, NULL);
+
+ surface_modify_location(surface, SFLAG_INSYSMEM, TRUE);
+ if (dirty_rect)
+ {
+ surface->dirtyRect.left = min(surface->dirtyRect.left, dirty_rect->left);
+ surface->dirtyRect.top = min(surface->dirtyRect.top, dirty_rect->top);
+ surface->dirtyRect.right = max(surface->dirtyRect.right, dirty_rect->right);
+ surface->dirtyRect.bottom = max(surface->dirtyRect.bottom, dirty_rect->bottom);
+ }
+ else
+ {
+ surface->dirtyRect.left = 0;
+ surface->dirtyRect.top = 0;
+ surface->dirtyRect.right = surface->resource.width;
+ surface->dirtyRect.bottom = surface->resource.height;
+ }
+
+ /* if the container is a texture then mark it dirty. */
+ if (surface->container)
+ {
+ TRACE("Passing to container.\n");
+ wined3d_texture_set_dirty(surface->container, TRUE);
+ }
+}
+
+HRESULT surface_load(struct wined3d_surface *surface, BOOL srgb)
+{
+ DWORD flag = srgb ? SFLAG_INSRGBTEX : SFLAG_INTEXTURE;
+ BOOL ck_changed;
+
+ TRACE("surface %p, srgb %#x.\n", surface, srgb);
+
+ if (surface->resource.pool == WINED3D_POOL_SCRATCH)
+ {
+ ERR("Not supported on scratch surfaces.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ ck_changed = !(surface->flags & SFLAG_GLCKEY) != !(surface->CKeyFlags & WINEDDSD_CKSRCBLT);
+
+ /* Reload if either the texture and sysmem have different ideas about the
+ * color key, or the actual key values changed. */
+ if (ck_changed || ((surface->CKeyFlags & WINEDDSD_CKSRCBLT)
+ && (surface->gl_color_key.color_space_low_value != surface->src_blt_color_key.color_space_low_value
+ || surface->gl_color_key.color_space_high_value != surface->src_blt_color_key.color_space_high_value)))
+ {
+ TRACE("Reloading because of color keying\n");
+ /* To perform the color key conversion we need a sysmem copy of
+ * the surface. Make sure we have it. */
+
+ surface_load_location(surface, SFLAG_INSYSMEM, NULL);
+ /* Make sure the texture is reloaded because of the color key change,
+ * this kills performance though :( */
+ /* TODO: This is not necessarily needed with hw palettized texture support. */
+ surface_modify_location(surface, SFLAG_INSYSMEM, TRUE);
+ /* Switching color keying on / off may change the internal format. */
+ if (ck_changed)
+ surface_force_reload(surface);
+ }
+ else if (!(surface->flags & flag))
+ {
+ TRACE("Reloading because surface is dirty.\n");
+ }
+ else
+ {
+ TRACE("surface is already in texture\n");
+ return WINED3D_OK;
+ }
+
+ /* No partial locking for textures yet. */
+ surface_load_location(surface, flag, NULL);
+ surface_evict_sysmem(surface);
+
+ return WINED3D_OK;
+}
+
+/* See also float_16_to_32() in wined3d_private.h */
+static inline unsigned short float_32_to_16(const float *in)
+{
+ int exp = 0;
+ float tmp = fabsf(*in);
+ unsigned int mantissa;
+ unsigned short ret;
+
+ /* Deal with special numbers */
+ if (*in == 0.0f)
+ return 0x0000;
+ if (isnan(*in))
+ return 0x7c01;
+ if (isinf(*in))
+ return (*in < 0.0f ? 0xfc00 : 0x7c00);
+
+ if (tmp < powf(2, 10))
+ {
+ do
+ {
+ tmp = tmp * 2.0f;
+ exp--;
+ } while (tmp < powf(2, 10));
+ }
+ else if (tmp >= powf(2, 11))
+ {
+ do
+ {
+ tmp /= 2.0f;
+ exp++;
+ } while (tmp >= powf(2, 11));
+ }
+
+ mantissa = (unsigned int)tmp;
+ if (tmp - mantissa >= 0.5f)
+ ++mantissa; /* Round to nearest, away from zero. */
+
+ exp += 10; /* Normalize the mantissa. */
+ exp += 15; /* Exponent is encoded with excess 15. */
+
+ if (exp > 30) /* too big */
+ {
+ ret = 0x7c00; /* INF */
+ }
+ else if (exp <= 0)
+ {
+ /* exp == 0: Non-normalized mantissa. Returns 0x0000 (=0.0) for too small numbers. */
+ while (exp <= 0)
+ {
+ mantissa = mantissa >> 1;
+ ++exp;
+ }
+ ret = mantissa & 0x3ff;
+ }
+ else
+ {
+ ret = (exp << 10) | (mantissa & 0x3ff);
+ }
+
+ ret |= ((*in < 0.0f ? 1 : 0) << 15); /* Add the sign */
+ return ret;
+}
+
+ULONG CDECL wined3d_surface_incref(struct wined3d_surface *surface)
+{
+ ULONG refcount;
+
+ TRACE("surface %p, swapchain %p, container %p.\n",
+ surface, surface->swapchain, surface->container);
+
+ if (surface->swapchain)
+ return wined3d_swapchain_incref(surface->swapchain);
+
+ if (surface->container)
+ return wined3d_texture_incref(surface->container);
+
+ refcount = InterlockedIncrement(&surface->resource.ref);
+ TRACE("%p increasing refcount to %u.\n", surface, refcount);
+
+ return refcount;
+}
+
+/* Do not call while under the GL lock. */
+ULONG CDECL wined3d_surface_decref(struct wined3d_surface *surface)
+{
+ ULONG refcount;
+
+ TRACE("surface %p, swapchain %p, container %p.\n",
+ surface, surface->swapchain, surface->container);
+
+ if (surface->swapchain)
+ return wined3d_swapchain_decref(surface->swapchain);
+
+ if (surface->container)
+ return wined3d_texture_decref(surface->container);
+
+ refcount = InterlockedDecrement(&surface->resource.ref);
+ TRACE("%p decreasing refcount to %u.\n", surface, refcount);
+
+ if (!refcount)
+ {
+ surface_cleanup(surface);
+ surface->resource.parent_ops->wined3d_object_destroyed(surface->resource.parent);
+
+ TRACE("Destroyed surface %p.\n", surface);
+ HeapFree(GetProcessHeap(), 0, surface);
+ }
+
+ return refcount;
+}
+
+DWORD CDECL wined3d_surface_set_priority(struct wined3d_surface *surface, DWORD priority)
+{
+ return resource_set_priority(&surface->resource, priority);
+}
+
+DWORD CDECL wined3d_surface_get_priority(const struct wined3d_surface *surface)
+{
+ return resource_get_priority(&surface->resource);
+}
+
+void CDECL wined3d_surface_preload(struct wined3d_surface *surface)
+{
+ TRACE("surface %p.\n", surface);
+
+ if (!surface->resource.device->d3d_initialized)
+ {
+ ERR("D3D not initialized.\n");
+ return;
+ }
+
+ surface_internal_preload(surface, SRGB_ANY);
+}
+
+void * CDECL wined3d_surface_get_parent(const struct wined3d_surface *surface)
+{
+ TRACE("surface %p.\n", surface);
+
+ return surface->resource.parent;
+}
+
+struct wined3d_resource * CDECL wined3d_surface_get_resource(struct wined3d_surface *surface)
+{
+ TRACE("surface %p.\n", surface);
+
+ return &surface->resource;
+}
+
+HRESULT CDECL wined3d_surface_get_blt_status(const struct wined3d_surface *surface, DWORD flags)
+{
+ TRACE("surface %p, flags %#x.\n", surface, flags);
+
+ switch (flags)
+ {
+ case WINEDDGBS_CANBLT:
+ case WINEDDGBS_ISBLTDONE:
+ return WINED3D_OK;
+
+ default:
+ return WINED3DERR_INVALIDCALL;
+ }
+}
+
+HRESULT CDECL wined3d_surface_get_flip_status(const struct wined3d_surface *surface, DWORD flags)
+{
+ TRACE("surface %p, flags %#x.\n", surface, flags);
+
+ /* XXX: DDERR_INVALIDSURFACETYPE */
+
+ switch (flags)
+ {
+ case WINEDDGFS_CANFLIP:
+ case WINEDDGFS_ISFLIPDONE:
+ return WINED3D_OK;
+
+ default:
+ return WINED3DERR_INVALIDCALL;
+ }
+}
+
+HRESULT CDECL wined3d_surface_is_lost(const struct wined3d_surface *surface)
+{
+ TRACE("surface %p.\n", surface);
+
+ /* D3D8 and 9 loose full devices, ddraw only surfaces. */
+ return surface->flags & SFLAG_LOST ? WINED3DERR_DEVICELOST : WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_surface_restore(struct wined3d_surface *surface)
+{
+ TRACE("surface %p.\n", surface);
+
+ surface->flags &= ~SFLAG_LOST;
+ return WINED3D_OK;
+}
+
+void CDECL wined3d_surface_set_palette(struct wined3d_surface *surface, struct wined3d_palette *palette)
+{
+ TRACE("surface %p, palette %p.\n", surface, palette);
+
+ if (surface->palette == palette)
+ {
+ TRACE("Nop palette change.\n");
+ return;
+ }
+
+ if (surface->palette && (surface->resource.usage & WINED3DUSAGE_RENDERTARGET))
+ surface->palette->flags &= ~WINEDDPCAPS_PRIMARYSURFACE;
+
+ surface->palette = palette;
+
+ if (palette)
+ {
+ if (surface->resource.usage & WINED3DUSAGE_RENDERTARGET)
+ palette->flags |= WINEDDPCAPS_PRIMARYSURFACE;
+
+ surface->surface_ops->surface_realize_palette(surface);
+ }
+}
+
+HRESULT CDECL wined3d_surface_set_color_key(struct wined3d_surface *surface,
+ DWORD flags, const struct wined3d_color_key *color_key)
+{
+ TRACE("surface %p, flags %#x, color_key %p.\n", surface, flags, color_key);
+
+ if (flags & WINEDDCKEY_COLORSPACE)
+ {
+ FIXME(" colorkey value not supported (%08x) !\n", flags);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ /* Dirtify the surface, but only if a key was changed. */
+ if (color_key)
+ {
+ switch (flags & ~WINEDDCKEY_COLORSPACE)
+ {
+ case WINEDDCKEY_DESTBLT:
+ surface->dst_blt_color_key = *color_key;
+ surface->CKeyFlags |= WINEDDSD_CKDESTBLT;
+ break;
+
+ case WINEDDCKEY_DESTOVERLAY:
+ surface->dst_overlay_color_key = *color_key;
+ surface->CKeyFlags |= WINEDDSD_CKDESTOVERLAY;
+ break;
+
+ case WINEDDCKEY_SRCOVERLAY:
+ surface->src_overlay_color_key = *color_key;
+ surface->CKeyFlags |= WINEDDSD_CKSRCOVERLAY;
+ break;
+
+ case WINEDDCKEY_SRCBLT:
+ surface->src_blt_color_key = *color_key;
+ surface->CKeyFlags |= WINEDDSD_CKSRCBLT;
+ break;
+ }
+ }
+ else
+ {
+ switch (flags & ~WINEDDCKEY_COLORSPACE)
+ {
+ case WINEDDCKEY_DESTBLT:
+ surface->CKeyFlags &= ~WINEDDSD_CKDESTBLT;
+ break;
+
+ case WINEDDCKEY_DESTOVERLAY:
+ surface->CKeyFlags &= ~WINEDDSD_CKDESTOVERLAY;
+ break;
+
+ case WINEDDCKEY_SRCOVERLAY:
+ surface->CKeyFlags &= ~WINEDDSD_CKSRCOVERLAY;
+ break;
+
+ case WINEDDCKEY_SRCBLT:
+ surface->CKeyFlags &= ~WINEDDSD_CKSRCBLT;
+ break;
+ }
+ }
+
+ return WINED3D_OK;
+}
+
+struct wined3d_palette * CDECL wined3d_surface_get_palette(const struct wined3d_surface *surface)
+{
+ TRACE("surface %p.\n", surface);
+
+ return surface->palette;
+}
+
+DWORD CDECL wined3d_surface_get_pitch(const struct wined3d_surface *surface)
+{
+ const struct wined3d_format *format = surface->resource.format;
+ DWORD pitch;
+
+ TRACE("surface %p.\n", surface);
+
+ if (surface->pitch)
+ return surface->pitch;
+
+ if (format->flags & WINED3DFMT_FLAG_BLOCKS)
+ {
+ /* Since compressed formats are block based, pitch means the amount of
+ * bytes to the next row of block rather than the next row of pixels. */
+ UINT row_block_count = (surface->resource.width + format->block_width - 1) / format->block_width;
+ pitch = row_block_count * format->block_byte_count;
+ }
+ else
+ {
+ unsigned char alignment = surface->resource.device->surface_alignment;
+ pitch = surface->resource.format->byte_count * surface->resource.width; /* Bytes / row */
+ pitch = (pitch + alignment - 1) & ~(alignment - 1);
+ }
+
+ TRACE("Returning %u.\n", pitch);
+
+ return pitch;
+}
+
+HRESULT CDECL wined3d_surface_set_mem(struct wined3d_surface *surface, void *mem, UINT pitch)
+{
+#ifndef VBOX_WITH_WDDM
+ TRACE("surface %p, mem %p.\n", surface, mem);
+
+ if (surface->resource.map_count || (surface->flags & SFLAG_DCINUSE))
+ {
+ WARN("Surface is mapped or the DC is in use.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ /* Render targets depend on their hdc, and we can't create an hdc on a user pointer. */
+ if (surface->resource.usage & WINED3DUSAGE_RENDERTARGET)
+ {
+ ERR("Not supported on render targets.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (mem && mem != surface->resource.allocatedMemory)
+ {
+ void *release = NULL;
+
+ /* Do I have to copy the old surface content? */
+ if (surface->flags & SFLAG_DIBSECTION)
+ {
+ DeleteDC(surface->hDC);
+ DeleteObject(surface->dib.DIBsection);
+ surface->dib.bitmap_data = NULL;
+ surface->resource.allocatedMemory = NULL;
+ surface->hDC = NULL;
+ surface->flags &= ~SFLAG_DIBSECTION;
+ }
+ else if (!(surface->flags & SFLAG_USERPTR))
+ {
+ release = surface->resource.heapMemory;
+ surface->resource.heapMemory = NULL;
+ }
+ surface->resource.allocatedMemory = mem;
+ surface->flags |= SFLAG_USERPTR;
+
+ /* Now the surface memory is most up do date. Invalidate drawable and texture. */
+ surface_modify_location(surface, SFLAG_INSYSMEM, TRUE);
+
+ /* For client textures OpenGL has to be notified. */
+ if (surface->flags & SFLAG_CLIENT)
+ surface_release_client_storage(surface);
+
+ /* Now free the old memory if any. */
+ HeapFree(GetProcessHeap(), 0, release);
+ }
+ else if (surface->flags & SFLAG_USERPTR)
+ {
+ /* HeapMemory should be NULL already. */
+ if (surface->resource.heapMemory)
+ ERR("User pointer surface has heap memory allocated.\n");
+
+ if (!mem)
+ {
+ surface->resource.allocatedMemory = NULL;
+ surface->flags &= ~(SFLAG_USERPTR | SFLAG_INSYSMEM);
+
+ if (surface->flags & SFLAG_CLIENT)
+ surface_release_client_storage(surface);
+
+ surface_prepare_system_memory(surface);
+ }
+
+ surface_modify_location(surface, SFLAG_INSYSMEM, TRUE);
+ }
+
+ surface->pitch = pitch;
+
+ return WINED3D_OK;
+#else
+ ERR("unsupported!");
+ return E_FAIL;
+#endif
+}
+
+HRESULT CDECL wined3d_surface_set_overlay_position(struct wined3d_surface *surface, LONG x, LONG y)
+{
+ LONG w, h;
+
+ TRACE("surface %p, x %d, y %d.\n", surface, x, y);
+
+ if (!(surface->resource.usage & WINED3DUSAGE_OVERLAY))
+ {
+ WARN("Not an overlay surface.\n");
+ return WINEDDERR_NOTAOVERLAYSURFACE;
+ }
+
+ w = surface->overlay_destrect.right - surface->overlay_destrect.left;
+ h = surface->overlay_destrect.bottom - surface->overlay_destrect.top;
+ surface->overlay_destrect.left = x;
+ surface->overlay_destrect.top = y;
+ surface->overlay_destrect.right = x + w;
+ surface->overlay_destrect.bottom = y + h;
+
+ surface_draw_overlay(surface);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_surface_get_overlay_position(const struct wined3d_surface *surface, LONG *x, LONG *y)
+{
+ TRACE("surface %p, x %p, y %p.\n", surface, x, y);
+
+ if (!(surface->resource.usage & WINED3DUSAGE_OVERLAY))
+ {
+ TRACE("Not an overlay surface.\n");
+ return WINEDDERR_NOTAOVERLAYSURFACE;
+ }
+
+ if (!surface->overlay_dest)
+ {
+ TRACE("Overlay not visible.\n");
+ *x = 0;
+ *y = 0;
+ return WINEDDERR_OVERLAYNOTVISIBLE;
+ }
+
+ *x = surface->overlay_destrect.left;
+ *y = surface->overlay_destrect.top;
+
+ TRACE("Returning position %d, %d.\n", *x, *y);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_surface_update_overlay_z_order(struct wined3d_surface *surface,
+ DWORD flags, struct wined3d_surface *ref)
+{
+ FIXME("surface %p, flags %#x, ref %p stub!\n", surface, flags, ref);
+
+ if (!(surface->resource.usage & WINED3DUSAGE_OVERLAY))
+ {
+ TRACE("Not an overlay surface.\n");
+ return WINEDDERR_NOTAOVERLAYSURFACE;
+ }
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_surface_update_overlay(struct wined3d_surface *surface, const RECT *src_rect,
+ struct wined3d_surface *dst_surface, const RECT *dst_rect, DWORD flags, const WINEDDOVERLAYFX *fx)
+{
+ TRACE("surface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n",
+ surface, wine_dbgstr_rect(src_rect), dst_surface, wine_dbgstr_rect(dst_rect), flags, fx);
+
+ if (!(surface->resource.usage & WINED3DUSAGE_OVERLAY))
+ {
+ WARN("Not an overlay surface.\n");
+ return WINEDDERR_NOTAOVERLAYSURFACE;
+ }
+ else if (!dst_surface)
+ {
+ WARN("Dest surface is NULL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (src_rect)
+ {
+ surface->overlay_srcrect = *src_rect;
+ }
+ else
+ {
+ surface->overlay_srcrect.left = 0;
+ surface->overlay_srcrect.top = 0;
+ surface->overlay_srcrect.right = surface->resource.width;
+ surface->overlay_srcrect.bottom = surface->resource.height;
+ }
+
+ if (dst_rect)
+ {
+ surface->overlay_destrect = *dst_rect;
+ }
+ else
+ {
+ surface->overlay_destrect.left = 0;
+ surface->overlay_destrect.top = 0;
+ surface->overlay_destrect.right = dst_surface ? dst_surface->resource.width : 0;
+ surface->overlay_destrect.bottom = dst_surface ? dst_surface->resource.height : 0;
+ }
+
+ if (surface->overlay_dest && (surface->overlay_dest != dst_surface || flags & WINEDDOVER_HIDE))
+ {
+ surface->overlay_dest = NULL;
+ list_remove(&surface->overlay_entry);
+ }
+
+ if (flags & WINEDDOVER_SHOW)
+ {
+ if (surface->overlay_dest != dst_surface)
+ {
+ surface->overlay_dest = dst_surface;
+ list_add_tail(&dst_surface->overlays, &surface->overlay_entry);
+ }
+ }
+ else if (flags & WINEDDOVER_HIDE)
+ {
+ /* tests show that the rectangles are erased on hide */
+ surface->overlay_srcrect.left = 0; surface->overlay_srcrect.top = 0;
+ surface->overlay_srcrect.right = 0; surface->overlay_srcrect.bottom = 0;
+ surface->overlay_destrect.left = 0; surface->overlay_destrect.top = 0;
+ surface->overlay_destrect.right = 0; surface->overlay_destrect.bottom = 0;
+ surface->overlay_dest = NULL;
+ }
+
+ surface_draw_overlay(surface);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_surface_update_desc(struct wined3d_surface *surface,
+ UINT width, UINT height, enum wined3d_format_id format_id,
+ enum wined3d_multisample_type multisample_type, UINT multisample_quality)
+{
+ struct wined3d_device *device = surface->resource.device;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ const struct wined3d_format *format = wined3d_get_format(gl_info, format_id);
+ UINT resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height);
+
+ TRACE("surface %p, width %u, height %u, format %s, multisample_type %#x, multisample_quality %u.\n",
+ surface, width, height, debug_d3dformat(format_id), multisample_type, multisample_type);
+
+ if (!resource_size)
+ return WINED3DERR_INVALIDCALL;
+
+ if (device->d3d_initialized)
+ surface->resource.resource_ops->resource_unload(&surface->resource);
+
+ if (surface->flags & SFLAG_DIBSECTION)
+ {
+ DeleteDC(surface->hDC);
+ DeleteObject(surface->dib.DIBsection);
+ surface->dib.bitmap_data = NULL;
+ surface->flags &= ~SFLAG_DIBSECTION;
+ }
+
+ surface->flags &= ~(SFLAG_LOCATIONS | SFLAG_USERPTR);
+ surface->resource.allocatedMemory = NULL;
+ HeapFree(GetProcessHeap(), 0, surface->resource.heapMemory);
+ surface->resource.heapMemory = NULL;
+
+ surface->resource.width = width;
+ surface->resource.height = height;
+ if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] || gl_info->supported[ARB_TEXTURE_RECTANGLE]
+ || gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT])
+ {
+ surface->pow2Width = width;
+ surface->pow2Height = height;
+ }
+ else
+ {
+ surface->pow2Width = surface->pow2Height = 1;
+ while (surface->pow2Width < width)
+ surface->pow2Width <<= 1;
+ while (surface->pow2Height < height)
+ surface->pow2Height <<= 1;
+ }
+
+ if (surface->pow2Width != width || surface->pow2Height != height)
+ surface->flags |= SFLAG_NONPOW2;
+ else
+ surface->flags &= ~SFLAG_NONPOW2;
+
+ surface->resource.format = format;
+ surface->resource.multisample_type = multisample_type;
+ surface->resource.multisample_quality = multisample_quality;
+ surface->resource.size = resource_size;
+
+ if (!surface_init_sysmem(surface))
+ return E_OUTOFMEMORY;
+
+ return WINED3D_OK;
+}
+
+static void convert_r32_float_r16_float(const BYTE *src, BYTE *dst,
+ DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+ unsigned short *dst_s;
+ const float *src_f;
+ unsigned int x, y;
+
+ TRACE("Converting %ux%u pixels, pitches %u %u.\n", w, h, pitch_in, pitch_out);
+
+ for (y = 0; y < h; ++y)
+ {
+ src_f = (const float *)(src + y * pitch_in);
+ dst_s = (unsigned short *) (dst + y * pitch_out);
+ for (x = 0; x < w; ++x)
+ {
+ dst_s[x] = float_32_to_16(src_f + x);
+ }
+ }
+}
+
+static void convert_r5g6b5_x8r8g8b8(const BYTE *src, BYTE *dst,
+ DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+ static const unsigned char convert_5to8[] =
+ {
+ 0x00, 0x08, 0x10, 0x19, 0x21, 0x29, 0x31, 0x3a,
+ 0x42, 0x4a, 0x52, 0x5a, 0x63, 0x6b, 0x73, 0x7b,
+ 0x84, 0x8c, 0x94, 0x9c, 0xa5, 0xad, 0xb5, 0xbd,
+ 0xc5, 0xce, 0xd6, 0xde, 0xe6, 0xef, 0xf7, 0xff,
+ };
+ static const unsigned char convert_6to8[] =
+ {
+ 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c,
+ 0x20, 0x24, 0x28, 0x2d, 0x31, 0x35, 0x39, 0x3d,
+ 0x41, 0x45, 0x49, 0x4d, 0x51, 0x55, 0x59, 0x5d,
+ 0x61, 0x65, 0x69, 0x6d, 0x71, 0x75, 0x79, 0x7d,
+ 0x82, 0x86, 0x8a, 0x8e, 0x92, 0x96, 0x9a, 0x9e,
+ 0xa2, 0xa6, 0xaa, 0xae, 0xb2, 0xb6, 0xba, 0xbe,
+ 0xc2, 0xc6, 0xca, 0xce, 0xd2, 0xd7, 0xdb, 0xdf,
+ 0xe3, 0xe7, 0xeb, 0xef, 0xf3, 0xf7, 0xfb, 0xff,
+ };
+ unsigned int x, y;
+
+ TRACE("Converting %ux%u pixels, pitches %u %u.\n", w, h, pitch_in, pitch_out);
+
+ for (y = 0; y < h; ++y)
+ {
+ const WORD *src_line = (const WORD *)(src + y * pitch_in);
+ DWORD *dst_line = (DWORD *)(dst + y * pitch_out);
+ for (x = 0; x < w; ++x)
+ {
+ WORD pixel = src_line[x];
+ dst_line[x] = 0xff000000
+ | convert_5to8[(pixel & 0xf800) >> 11] << 16
+ | convert_6to8[(pixel & 0x07e0) >> 5] << 8
+ | convert_5to8[(pixel & 0x001f)];
+ }
+ }
+}
+
+/* We use this for both B8G8R8A8 -> B8G8R8X8 and B8G8R8X8 -> B8G8R8A8, since
+ * in both cases we're just setting the X / Alpha channel to 0xff. */
+static void convert_a8r8g8b8_x8r8g8b8(const BYTE *src, BYTE *dst,
+ DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+ unsigned int x, y;
+
+ TRACE("Converting %ux%u pixels, pitches %u %u.\n", w, h, pitch_in, pitch_out);
+
+ for (y = 0; y < h; ++y)
+ {
+ const DWORD *src_line = (const DWORD *)(src + y * pitch_in);
+ DWORD *dst_line = (DWORD *)(dst + y * pitch_out);
+
+ for (x = 0; x < w; ++x)
+ {
+ dst_line[x] = 0xff000000 | (src_line[x] & 0xffffff);
+ }
+ }
+}
+
+static inline BYTE cliptobyte(int x)
+{
+ return (BYTE)((x < 0) ? 0 : ((x > 255) ? 255 : x));
+}
+
+static void convert_yuy2_x8r8g8b8(const BYTE *src, BYTE *dst,
+ DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+ int c2, d, e, r2 = 0, g2 = 0, b2 = 0;
+ unsigned int x, y;
+
+ TRACE("Converting %ux%u pixels, pitches %u %u.\n", w, h, pitch_in, pitch_out);
+
+ for (y = 0; y < h; ++y)
+ {
+ const BYTE *src_line = src + y * pitch_in;
+ DWORD *dst_line = (DWORD *)(dst + y * pitch_out);
+ for (x = 0; x < w; ++x)
+ {
+ /* YUV to RGB conversion formulas from http://en.wikipedia.org/wiki/YUV:
+ * C = Y - 16; D = U - 128; E = V - 128;
+ * R = cliptobyte((298 * C + 409 * E + 128) >> 8);
+ * G = cliptobyte((298 * C - 100 * D - 208 * E + 128) >> 8);
+ * B = cliptobyte((298 * C + 516 * D + 128) >> 8);
+ * Two adjacent YUY2 pixels are stored as four bytes: Y0 U Y1 V .
+ * U and V are shared between the pixels. */
+ if (!(x & 1)) /* For every even pixel, read new U and V. */
+ {
+ d = (int) src_line[1] - 128;
+ e = (int) src_line[3] - 128;
+ r2 = 409 * e + 128;
+ g2 = - 100 * d - 208 * e + 128;
+ b2 = 516 * d + 128;
+ }
+ c2 = 298 * ((int) src_line[0] - 16);
+ dst_line[x] = 0xff000000
+ | cliptobyte((c2 + r2) >> 8) << 16 /* red */
+ | cliptobyte((c2 + g2) >> 8) << 8 /* green */
+ | cliptobyte((c2 + b2) >> 8); /* blue */
+ /* Scale RGB values to 0..255 range,
+ * then clip them if still not in range (may be negative),
+ * then shift them within DWORD if necessary. */
+ src_line += 2;
+ }
+ }
+}
+
+static void convert_yuy2_r5g6b5(const BYTE *src, BYTE *dst,
+ DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
+{
+ unsigned int x, y;
+ int c2, d, e, r2 = 0, g2 = 0, b2 = 0;
+
+ TRACE("Converting %ux%u pixels, pitches %u %u\n", w, h, pitch_in, pitch_out);
+
+ for (y = 0; y < h; ++y)
+ {
+ const BYTE *src_line = src + y * pitch_in;
+ WORD *dst_line = (WORD *)(dst + y * pitch_out);
+ for (x = 0; x < w; ++x)
+ {
+ /* YUV to RGB conversion formulas from http://en.wikipedia.org/wiki/YUV:
+ * C = Y - 16; D = U - 128; E = V - 128;
+ * R = cliptobyte((298 * C + 409 * E + 128) >> 8);
+ * G = cliptobyte((298 * C - 100 * D - 208 * E + 128) >> 8);
+ * B = cliptobyte((298 * C + 516 * D + 128) >> 8);
+ * Two adjacent YUY2 pixels are stored as four bytes: Y0 U Y1 V .
+ * U and V are shared between the pixels. */
+ if (!(x & 1)) /* For every even pixel, read new U and V. */
+ {
+ d = (int) src_line[1] - 128;
+ e = (int) src_line[3] - 128;
+ r2 = 409 * e + 128;
+ g2 = - 100 * d - 208 * e + 128;
+ b2 = 516 * d + 128;
+ }
+ c2 = 298 * ((int) src_line[0] - 16);
+ dst_line[x] = (cliptobyte((c2 + r2) >> 8) >> 3) << 11 /* red */
+ | (cliptobyte((c2 + g2) >> 8) >> 2) << 5 /* green */
+ | (cliptobyte((c2 + b2) >> 8) >> 3); /* blue */
+ /* Scale RGB values to 0..255 range,
+ * then clip them if still not in range (may be negative),
+ * then shift them within DWORD if necessary. */
+ src_line += 2;
+ }
+ }
+}
+
+struct d3dfmt_converter_desc
+{
+ enum wined3d_format_id from, to;
+ void (*convert)(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h);
+};
+
+static const struct d3dfmt_converter_desc converters[] =
+{
+ {WINED3DFMT_R32_FLOAT, WINED3DFMT_R16_FLOAT, convert_r32_float_r16_float},
+ {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_B8G8R8X8_UNORM, convert_r5g6b5_x8r8g8b8},
+ {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_B8G8R8X8_UNORM, convert_a8r8g8b8_x8r8g8b8},
+ {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_B8G8R8A8_UNORM, convert_a8r8g8b8_x8r8g8b8},
+ {WINED3DFMT_YUY2, WINED3DFMT_B8G8R8X8_UNORM, convert_yuy2_x8r8g8b8},
+ {WINED3DFMT_YUY2, WINED3DFMT_B5G6R5_UNORM, convert_yuy2_r5g6b5},
+};
+
+static inline const struct d3dfmt_converter_desc *find_converter(enum wined3d_format_id from,
+ enum wined3d_format_id to)
+{
+ unsigned int i;
+
+ for (i = 0; i < (sizeof(converters) / sizeof(*converters)); ++i)
+ {
+ if (converters[i].from == from && converters[i].to == to)
+ return &converters[i];
+ }
+
+ return NULL;
+}
+
+/*****************************************************************************
+ * surface_convert_format
+ *
+ * Creates a duplicate of a surface in a different format. Is used by Blt to
+ * blit between surfaces with different formats.
+ *
+ * Parameters
+ * source: Source surface
+ * fmt: Requested destination format
+ *
+ *****************************************************************************/
+static struct wined3d_surface *surface_convert_format(struct wined3d_surface *source, enum wined3d_format_id to_fmt)
+{
+ struct wined3d_map_desc src_map, dst_map;
+ const struct d3dfmt_converter_desc *conv;
+ struct wined3d_surface *ret = NULL;
+ HRESULT hr;
+
+ conv = find_converter(source->resource.format->id, to_fmt);
+ if (!conv)
+ {
+ FIXME("Cannot find a conversion function from format %s to %s.\n",
+ debug_d3dformat(source->resource.format->id), debug_d3dformat(to_fmt));
+ return NULL;
+ }
+
+ /* FIXME: Multisampled conversion? */
+#ifdef VBOX_WITH_WDDM
+ if (FAILED(hr = wined3d_surface_create(source->resource.device, source->resource.width, source->resource.height,
+ to_fmt, 0, WINED3D_POOL_SCRATCH, WINED3D_MULTISAMPLE_NONE, 0,
+ WINED3D_SURFACE_MAPPABLE | WINED3D_SURFACE_DISCARD, NULL, &wined3d_null_parent_ops, &ret
+ , NULL, NULL
+ )))
+#else
+ if (FAILED(hr = wined3d_surface_create(source->resource.device, source->resource.width, source->resource.height,
+ to_fmt, 0, WINED3D_POOL_SCRATCH, WINED3D_MULTISAMPLE_NONE, 0,
+ WINED3D_SURFACE_MAPPABLE | WINED3D_SURFACE_DISCARD, NULL, &wined3d_null_parent_ops, &ret)))
+#endif
+ {
+ ERR("Failed to create a destination surface for conversion.\n");
+ return NULL;
+ }
+
+ memset(&src_map, 0, sizeof(src_map));
+ memset(&dst_map, 0, sizeof(dst_map));
+
+ if (FAILED(hr = wined3d_surface_map(source, &src_map, NULL, WINED3D_MAP_READONLY)))
+ {
+ ERR("Failed to lock the source surface.\n");
+ wined3d_surface_decref(ret);
+ return NULL;
+ }
+ if (FAILED(hr = wined3d_surface_map(ret, &dst_map, NULL, WINED3D_MAP_READONLY)))
+ {
+ ERR("Failed to lock the destination surface.\n");
+ wined3d_surface_unmap(source);
+ wined3d_surface_decref(ret);
+ return NULL;
+ }
+
+ conv->convert(src_map.data, dst_map.data, src_map.row_pitch, dst_map.row_pitch,
+ source->resource.width, source->resource.height);
+
+ wined3d_surface_unmap(ret);
+ wined3d_surface_unmap(source);
+
+ return ret;
+}
+
+static HRESULT _Blt_ColorFill(BYTE *buf, unsigned int width, unsigned int height,
+ unsigned int bpp, UINT pitch, DWORD color)
+{
+ BYTE *first;
+ unsigned int x, y;
+
+ /* Do first row */
+
+#define COLORFILL_ROW(type) \
+do { \
+ type *d = (type *)buf; \
+ for (x = 0; x < width; ++x) \
+ d[x] = (type)color; \
+} while(0)
+
+ switch (bpp)
+ {
+ case 1:
+ COLORFILL_ROW(BYTE);
+ break;
+
+ case 2:
+ COLORFILL_ROW(WORD);
+ break;
+
+ case 3:
+ {
+ BYTE *d = buf;
+ for (x = 0; x < width; ++x, d += 3)
+ {
+ d[0] = (color ) & 0xff;
+ d[1] = (color >> 8) & 0xff;
+ d[2] = (color >> 16) & 0xff;
+ }
+ break;
+ }
+ case 4:
+ COLORFILL_ROW(DWORD);
+ break;
+
+ default:
+ FIXME("Color fill not implemented for bpp %u!\n", bpp * 8);
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
+#undef COLORFILL_ROW
+
+ /* Now copy first row. */
+ first = buf;
+ for (y = 1; y < height; ++y)
+ {
+ buf += pitch;
+ memcpy(buf, first, width * bpp);
+ }
+
+ return WINED3D_OK;
+}
+
+struct wined3d_surface * CDECL wined3d_surface_from_resource(struct wined3d_resource *resource)
+{
+ return surface_from_resource(resource);
+}
+
+HRESULT CDECL wined3d_surface_unmap(struct wined3d_surface *surface)
+{
+ TRACE("surface %p.\n", surface);
+
+ if (!surface->resource.map_count)
+ {
+ WARN("Trying to unmap unmapped surface.\n");
+ return WINEDDERR_NOTLOCKED;
+ }
+ --surface->resource.map_count;
+
+ surface->surface_ops->surface_unmap(surface);
+
+#ifdef VBOX_WITH_WDDM
+ surface_shrc_unlock(surface);
+#endif
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface,
+ struct wined3d_map_desc *map_desc, const RECT *rect, DWORD flags)
+{
+ const struct wined3d_format *format = surface->resource.format;
+
+ TRACE("surface %p, map_desc %p, rect %s, flags %#x.\n",
+ surface, map_desc, wine_dbgstr_rect(rect), flags);
+
+ if (surface->resource.map_count)
+ {
+ WARN("Surface is already mapped.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if ((format->flags & WINED3DFMT_FLAG_BLOCKS) && rect
+ && !surface_check_block_align(surface, rect))
+ {
+ WARN("Map rect %s is misaligned for %ux%u blocks.\n",
+ wine_dbgstr_rect(rect), format->block_width, format->block_height);
+
+ if (surface->resource.pool == WINED3D_POOL_DEFAULT)
+ return WINED3DERR_INVALIDCALL;
+ }
+
+#ifdef VBOX_WITH_WDDM
+ surface_shrc_lock(surface);
+#endif
+
+ ++surface->resource.map_count;
+
+ if (!(surface->flags & SFLAG_LOCKABLE))
+ WARN("Trying to lock unlockable surface.\n");
+
+ /* Performance optimization: Count how often a surface is mapped, if it is
+ * mapped regularly do not throw away the system memory copy. This avoids
+ * the need to download the surface from OpenGL all the time. The surface
+ * is still downloaded if the OpenGL texture is changed. */
+ if (!(surface->flags & SFLAG_DYNLOCK))
+ {
+ if (++surface->lockCount > MAXLOCKCOUNT)
+ {
+ TRACE("Surface is mapped regularly, not freeing the system memory copy any more.\n");
+ surface->flags |= SFLAG_DYNLOCK;
+ }
+ }
+
+ surface->surface_ops->surface_map(surface, rect, flags);
+
+ if (format->flags & WINED3DFMT_FLAG_BROKEN_PITCH)
+ map_desc->row_pitch = surface->resource.width * format->byte_count;
+ else
+ map_desc->row_pitch = wined3d_surface_get_pitch(surface);
+ map_desc->slice_pitch = 0;
+
+ if (!rect)
+ {
+ map_desc->data = surface->resource.allocatedMemory;
+ surface->lockedRect.left = 0;
+ surface->lockedRect.top = 0;
+ surface->lockedRect.right = surface->resource.width;
+ surface->lockedRect.bottom = surface->resource.height;
+ }
+ else
+ {
+ if ((format->flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS)
+ {
+ /* Compressed textures are block based, so calculate the offset of
+ * the block that contains the top-left pixel of the locked rectangle. */
+ map_desc->data = surface->resource.allocatedMemory
+ + ((rect->top / format->block_height) * map_desc->row_pitch)
+ + ((rect->left / format->block_width) * format->block_byte_count);
+ }
+ else
+ {
+ map_desc->data = surface->resource.allocatedMemory
+ + (map_desc->row_pitch * rect->top)
+ + (rect->left * format->byte_count);
+ }
+ surface->lockedRect.left = rect->left;
+ surface->lockedRect.top = rect->top;
+ surface->lockedRect.right = rect->right;
+ surface->lockedRect.bottom = rect->bottom;
+ }
+
+ TRACE("Locked rect %s.\n", wine_dbgstr_rect(&surface->lockedRect));
+ TRACE("Returning memory %p, pitch %u.\n", map_desc->data, map_desc->row_pitch);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_surface_getdc(struct wined3d_surface *surface, HDC *dc)
+{
+ struct wined3d_map_desc map;
+ HRESULT hr;
+
+ TRACE("surface %p, dc %p.\n", surface, dc);
+
+ if (surface->flags & SFLAG_USERPTR)
+ {
+ ERR("Not supported on surfaces with application-provided memory.\n");
+ return WINEDDERR_NODC;
+ }
+
+ /* Give more detailed info for ddraw. */
+ if (surface->flags & SFLAG_DCINUSE)
+ return WINEDDERR_DCALREADYCREATED;
+
+ /* Can't GetDC if the surface is locked. */
+ if (surface->resource.map_count)
+ return WINED3DERR_INVALIDCALL;
+
+ /* Create a DIB section if there isn't a dc yet. */
+ if (!surface->hDC)
+ {
+ if (surface->flags & SFLAG_CLIENT)
+ {
+ surface_load_location(surface, SFLAG_INSYSMEM, NULL);
+ surface_release_client_storage(surface);
+ }
+ hr = surface_create_dib_section(surface);
+ if (FAILED(hr))
+ return WINED3DERR_INVALIDCALL;
+
+ /* Use the DIB section from now on if we are not using a PBO. */
+ if (!(surface->flags & (SFLAG_PBO | SFLAG_PIN_SYSMEM)))
+ {
+ HeapFree(GetProcessHeap(), 0, surface->resource.heapMemory);
+ surface->resource.heapMemory = NULL;
+ surface->resource.allocatedMemory = surface->dib.bitmap_data;
+ }
+ }
+
+ /* Map the surface. */
+ hr = wined3d_surface_map(surface, &map, NULL, 0);
+ if (FAILED(hr))
+ {
+ ERR("Map failed, hr %#x.\n", hr);
+ return hr;
+ }
+
+ /* Sync the DIB with the PBO. This can't be done earlier because Map()
+ * activates the allocatedMemory. */
+#ifdef VBOX_WITH_WINE_FIX_PBOPSM
+ if ((surface->flags & (SFLAG_PBO | SFLAG_PIN_SYSMEM)) == (SFLAG_PBO | SFLAG_PIN_SYSMEM))
+#else
+ if (surface->flags & (SFLAG_PBO | SFLAG_PIN_SYSMEM))
+#endif
+ memcpy(surface->dib.bitmap_data, surface->resource.allocatedMemory, surface->resource.size);
+
+ if (surface->resource.format->id == WINED3DFMT_P8_UINT
+ || surface->resource.format->id == WINED3DFMT_P8_UINT_A8_UNORM)
+ {
+ /* GetDC on palettized formats is unsupported in D3D9, and the method
+ * is missing in D3D8, so this should only be used for DX <=7
+ * surfaces (with non-device palettes). */
+ const PALETTEENTRY *pal = NULL;
+
+ if (surface->palette)
+ {
+ pal = surface->palette->palents;
+ }
+ else
+ {
+ struct wined3d_swapchain *swapchain = surface->resource.device->swapchains[0];
+ struct wined3d_surface *dds_primary = swapchain->front_buffer;
+
+ if (dds_primary && dds_primary->palette)
+ pal = dds_primary->palette->palents;
+ }
+
+ if (pal)
+ {
+ RGBQUAD col[256];
+ unsigned int i;
+
+ for (i = 0; i < 256; ++i)
+ {
+ col[i].rgbRed = pal[i].peRed;
+ col[i].rgbGreen = pal[i].peGreen;
+ col[i].rgbBlue = pal[i].peBlue;
+ col[i].rgbReserved = 0;
+ }
+ SetDIBColorTable(surface->hDC, 0, 256, col);
+ }
+ }
+
+ surface->flags |= SFLAG_DCINUSE;
+
+ *dc = surface->hDC;
+ TRACE("Returning dc %p.\n", *dc);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_surface_releasedc(struct wined3d_surface *surface, HDC dc)
+{
+ TRACE("surface %p, dc %p.\n", surface, dc);
+
+ if (!(surface->flags & SFLAG_DCINUSE))
+ return WINEDDERR_NODC;
+
+ if (surface->hDC != dc)
+ {
+ WARN("Application tries to release invalid DC %p, surface DC is %p.\n",
+ dc, surface->hDC);
+ return WINEDDERR_NODC;
+ }
+
+ /* Copy the contents of the DIB over to the PBO. */
+#ifdef VBOX_WITH_WINE_FIX_PBOPSM
+ if (((surface->flags & (SFLAG_PBO | SFLAG_PIN_SYSMEM)) == (SFLAG_PBO | SFLAG_PIN_SYSMEM)) && surface->resource.allocatedMemory)
+#else
+ if ((surface->flags & (SFLAG_PBO | SFLAG_PIN_SYSMEM)) && surface->resource.allocatedMemory)
+#endif
+ memcpy(surface->resource.allocatedMemory, surface->dib.bitmap_data, surface->resource.size);
+
+ /* We locked first, so unlock now. */
+ wined3d_surface_unmap(surface);
+
+ surface->flags &= ~SFLAG_DCINUSE;
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_surface_flip(struct wined3d_surface *surface, struct wined3d_surface *override, DWORD flags)
+{
+ TRACE("surface %p, override %p, flags %#x.\n", surface, override, flags);
+
+ if (flags)
+ {
+ static UINT once;
+ if (!once++)
+ FIXME("Ignoring flags %#x.\n", flags);
+ else
+ WARN("Ignoring flags %#x.\n", flags);
+ }
+
+ if (surface->swapchain)
+ {
+ ERR("Not supported on swapchain surfaces.\n");
+ return WINEDDERR_NOTFLIPPABLE;
+ }
+
+ /* Flipping is only supported on render targets and overlays. */
+ if (!(surface->resource.usage & (WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_OVERLAY)))
+ {
+ WARN("Tried to flip a non-render target, non-overlay surface.\n");
+ return WINEDDERR_NOTFLIPPABLE;
+ }
+
+ flip_surface(surface, override);
+
+ /* Update overlays if they're visible. */
+ if ((surface->resource.usage & WINED3DUSAGE_OVERLAY) && surface->overlay_dest)
+ return surface_draw_overlay(surface);
+
+ return WINED3D_OK;
+}
+
+/* Do not call while under the GL lock. */
+void surface_internal_preload(struct wined3d_surface *surface, enum WINED3DSRGB srgb)
+{
+ struct wined3d_device *device = surface->resource.device;
+
+ TRACE("iface %p, srgb %#x.\n", surface, srgb);
+
+ if (surface->container)
+ {
+ struct wined3d_texture *texture = surface->container;
+
+ TRACE("Passing to container (%p).\n", texture);
+ texture->texture_ops->texture_preload(texture, srgb);
+ }
+ else
+ {
+ struct wined3d_context *context;
+
+ TRACE("(%p) : About to load surface\n", surface);
+
+ /* TODO: Use already acquired context when possible. */
+ context = context_acquire(device, NULL);
+
+ surface_load(surface, srgb == SRGB_SRGB);
+
+#ifndef VBOX
+ if (surface->resource.pool == WINED3D_POOL_DEFAULT)
+ {
+ /* Tell opengl to try and keep this texture in video ram (well mostly) */
+ GLclampf tmp;
+ tmp = 0.9f;
+ context->gl_info->gl_ops.gl.p_glPrioritizeTextures(1, &surface->texture_name, &tmp);
+ }
+#else
+ /* chromium code on host fails to resolve texture name to texture obj,
+ * most likely because the texture does not get created until it is bound
+ * @todo: investigate */
+#endif
+ context_release(context);
+ }
+}
+
+/* Read the framebuffer back into the surface */
+static void read_from_framebuffer(struct wined3d_surface *surface, const RECT *rect, void *dest, UINT pitch)
+{
+ struct wined3d_device *device = surface->resource.device;
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+ BYTE *mem;
+ GLint fmt;
+ GLint type;
+ BYTE *row, *top, *bottom;
+ int i;
+ BOOL bpp;
+ RECT local_rect;
+ BOOL srcIsUpsideDown;
+ GLint rowLen = 0;
+ GLint skipPix = 0;
+ GLint skipRow = 0;
+
+ context = context_acquire(device, surface);
+ context_apply_blit_state(context, device);
+ gl_info = context->gl_info;
+
+ /* Select the correct read buffer, and give some debug output.
+ * There is no need to keep track of the current read buffer or reset it, every part of the code
+ * that reads sets the read buffer as desired.
+ */
+ if (surface_is_offscreen(surface))
+ {
+ /* Mapping the primary render target which is not on a swapchain.
+ * Read from the back buffer. */
+ TRACE("Mapping offscreen render target.\n");
+ gl_info->gl_ops.gl.p_glReadBuffer(device->offscreenBuffer);
+ srcIsUpsideDown = TRUE;
+ }
+ else
+ {
+ /* Onscreen surfaces are always part of a swapchain */
+ GLenum buffer = surface_get_gl_buffer(surface);
+ TRACE("Mapping %#x buffer.\n", buffer);
+ gl_info->gl_ops.gl.p_glReadBuffer(buffer);
+ checkGLcall("glReadBuffer");
+ srcIsUpsideDown = FALSE;
+ }
+
+ /* TODO: Get rid of the extra rectangle comparison and construction of a full surface rectangle */
+ if (!rect)
+ {
+ local_rect.left = 0;
+ local_rect.top = 0;
+ local_rect.right = surface->resource.width;
+ local_rect.bottom = surface->resource.height;
+ }
+ else
+ {
+ local_rect = *rect;
+ }
+ /* TODO: Get rid of the extra GetPitch call, LockRect does that too. Cache the pitch */
+
+ switch (surface->resource.format->id)
+ {
+ case WINED3DFMT_P8_UINT:
+ {
+ if (primary_render_target_is_p8(device))
+ {
+ /* In case of P8 render targets the index is stored in the alpha component */
+ fmt = GL_ALPHA;
+ type = GL_UNSIGNED_BYTE;
+ mem = dest;
+ bpp = surface->resource.format->byte_count;
+ }
+ else
+ {
+ /* GL can't return palettized data, so read ARGB pixels into a
+ * separate block of memory and convert them into palettized format
+ * in software. Slow, but if the app means to use palettized render
+ * targets and locks it...
+ *
+ * Use GL_RGB, GL_UNSIGNED_BYTE to read the surface for performance reasons
+ * Don't use GL_BGR as in the WINED3DFMT_R8G8B8 case, instead watch out
+ * for the color channels when palettizing the colors.
+ */
+ fmt = GL_RGB;
+ type = GL_UNSIGNED_BYTE;
+ pitch *= 3;
+ mem = HeapAlloc(GetProcessHeap(), 0, surface->resource.size * 3);
+ if (!mem)
+ {
+ ERR("Out of memory\n");
+ return;
+ }
+ bpp = surface->resource.format->byte_count * 3;
+ }
+ }
+ break;
+
+ default:
+ mem = dest;
+ fmt = surface->resource.format->glFormat;
+ type = surface->resource.format->glType;
+ bpp = surface->resource.format->byte_count;
+ }
+
+ if (surface->flags & SFLAG_PBO)
+ {
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, surface->pbo));
+ checkGLcall("glBindBufferARB");
+ if (mem)
+ {
+ ERR("mem not null for pbo -- unexpected\n");
+ mem = NULL;
+ }
+ }
+
+ /* Save old pixel store pack state */
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_PACK_ROW_LENGTH, &rowLen);
+ checkGLcall("glGetIntegerv");
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_PACK_SKIP_PIXELS, &skipPix);
+ checkGLcall("glGetIntegerv");
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_PACK_SKIP_ROWS, &skipRow);
+ checkGLcall("glGetIntegerv");
+
+ /* Setup pixel store pack state -- to glReadPixels into the correct place */
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, surface->resource.width);
+ checkGLcall("glPixelStorei");
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_SKIP_PIXELS, local_rect.left);
+ checkGLcall("glPixelStorei");
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_SKIP_ROWS, local_rect.top);
+ checkGLcall("glPixelStorei");
+
+ gl_info->gl_ops.gl.p_glReadPixels(local_rect.left,
+ !srcIsUpsideDown ? (surface->resource.height - local_rect.bottom) : local_rect.top,
+ local_rect.right - local_rect.left,
+ local_rect.bottom - local_rect.top,
+ fmt, type, mem);
+ checkGLcall("glReadPixels");
+
+ /* Reset previous pixel store pack state */
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, rowLen);
+ checkGLcall("glPixelStorei");
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_SKIP_PIXELS, skipPix);
+ checkGLcall("glPixelStorei");
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_SKIP_ROWS, skipRow);
+ checkGLcall("glPixelStorei");
+
+ if (surface->flags & SFLAG_PBO)
+ {
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
+ checkGLcall("glBindBufferARB");
+
+ /* Check if we need to flip the image. If we need to flip use glMapBufferARB
+ * to get a pointer to it and perform the flipping in software. This is a lot
+ * faster than calling glReadPixels for each line. In case we want more speed
+ * we should rerender it flipped in a FBO and read the data back from the FBO. */
+ if (!srcIsUpsideDown)
+ {
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo));
+ checkGLcall("glBindBufferARB");
+
+ mem = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_READ_WRITE_ARB));
+ checkGLcall("glMapBufferARB");
+ }
+ }
+
+ /* TODO: Merge this with the palettization loop below for P8 targets */
+ if(!srcIsUpsideDown) {
+ UINT len, off;
+ /* glReadPixels returns the image upside down, and there is no way to prevent this.
+ Flip the lines in software */
+ len = (local_rect.right - local_rect.left) * bpp;
+ off = local_rect.left * bpp;
+
+ row = HeapAlloc(GetProcessHeap(), 0, len);
+ if(!row) {
+ ERR("Out of memory\n");
+ if (surface->resource.format->id == WINED3DFMT_P8_UINT)
+ HeapFree(GetProcessHeap(), 0, mem);
+ return;
+ }
+
+ top = mem + pitch * local_rect.top;
+ bottom = mem + pitch * (local_rect.bottom - 1);
+ for(i = 0; i < (local_rect.bottom - local_rect.top) / 2; i++) {
+ memcpy(row, top + off, len);
+ memcpy(top + off, bottom + off, len);
+ memcpy(bottom + off, row, len);
+ top += pitch;
+ bottom -= pitch;
+ }
+ HeapFree(GetProcessHeap(), 0, row);
+
+ /* Unmap the temp PBO buffer */
+ if (surface->flags & SFLAG_PBO)
+ {
+ GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB));
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+ }
+ }
+
+ context_release(context);
+
+ /* For P8 textures we need to perform an inverse palette lookup. This is
+ * done by searching for a palette index which matches the RGB value.
+ * Note this isn't guaranteed to work when there are multiple entries for
+ * the same color but we have no choice. In case of P8 render targets,
+ * the index is stored in the alpha component so no conversion is needed. */
+ if (surface->resource.format->id == WINED3DFMT_P8_UINT && !primary_render_target_is_p8(device))
+ {
+ const PALETTEENTRY *pal = NULL;
+ DWORD width = pitch / 3;
+ int x, y, c;
+
+ if (surface->palette)
+ {
+ pal = surface->palette->palents;
+ }
+ else
+ {
+ ERR("Palette is missing, cannot perform inverse palette lookup\n");
+ HeapFree(GetProcessHeap(), 0, mem);
+ return;
+ }
+
+ for(y = local_rect.top; y < local_rect.bottom; y++) {
+ for(x = local_rect.left; x < local_rect.right; x++) {
+ /* start lines pixels */
+ const BYTE *blue = mem + y * pitch + x * (sizeof(BYTE) * 3);
+ const BYTE *green = blue + 1;
+ const BYTE *red = green + 1;
+
+ for(c = 0; c < 256; c++) {
+ if(*red == pal[c].peRed &&
+ *green == pal[c].peGreen &&
+ *blue == pal[c].peBlue)
+ {
+ *((BYTE *) dest + y * width + x) = c;
+ break;
+ }
+ }
+ }
+ }
+ HeapFree(GetProcessHeap(), 0, mem);
+ }
+}
+
+/* Read the framebuffer contents into a texture. Note that this function
+ * doesn't do any kind of flipping. Using this on an onscreen surface will
+ * result in a flipped D3D texture. */
+void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb)
+{
+ struct wined3d_device *device = surface->resource.device;
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+
+ context = context_acquire(device, surface);
+ gl_info = context->gl_info;
+ device_invalidate_state(device, STATE_FRAMEBUFFER);
+
+ surface_prepare_texture(surface, context, srgb);
+ surface_bind_and_dirtify(surface, context, srgb);
+
+ TRACE("Reading back offscreen render target %p.\n", surface);
+
+ if (surface_is_offscreen(surface))
+ gl_info->gl_ops.gl.p_glReadBuffer(device->offscreenBuffer);
+ else
+ gl_info->gl_ops.gl.p_glReadBuffer(surface_get_gl_buffer(surface));
+ checkGLcall("glReadBuffer");
+
+ gl_info->gl_ops.gl.p_glCopyTexSubImage2D(surface->texture_target, surface->texture_level,
+ 0, 0, 0, 0, surface->resource.width, surface->resource.height);
+ checkGLcall("glCopyTexSubImage2D");
+
+ context_release(context);
+}
+
+/* Context activation is done by the caller. */
+static void surface_prepare_texture_internal(struct wined3d_surface *surface,
+ struct wined3d_context *context, BOOL srgb)
+{
+ DWORD alloc_flag = srgb ? SFLAG_SRGBALLOCATED : SFLAG_ALLOCATED;
+ enum wined3d_conversion_type convert;
+ struct wined3d_format format;
+
+ if (surface->flags & alloc_flag) return;
+
+ d3dfmt_get_conv(surface, TRUE, TRUE, &format, &convert);
+ if (convert != WINED3D_CT_NONE || format.convert)
+ surface->flags |= SFLAG_CONVERTED;
+ else surface->flags &= ~SFLAG_CONVERTED;
+
+ surface_bind_and_dirtify(surface, context, srgb);
+ surface_allocate_surface(surface, context->gl_info, &format, srgb);
+ surface->flags |= alloc_flag;
+}
+
+/* Context activation is done by the caller. */
+void surface_prepare_texture(struct wined3d_surface *surface, struct wined3d_context *context, BOOL srgb)
+{
+ if (surface->container)
+ {
+ struct wined3d_texture *texture = surface->container;
+ UINT sub_count = texture->level_count * texture->layer_count;
+ UINT i;
+
+ TRACE("surface %p is a subresource of texture %p.\n", surface, texture);
+
+ for (i = 0; i < sub_count; ++i)
+ {
+ struct wined3d_surface *s = surface_from_resource(texture->sub_resources[i]);
+ surface_prepare_texture_internal(s, context, srgb);
+ }
+
+ return;
+ }
+
+ surface_prepare_texture_internal(surface, context, srgb);
+}
+
+void surface_prepare_rb(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info, BOOL multisample)
+{
+ if (multisample)
+ {
+ if (surface->rb_multisample)
+ return;
+
+ gl_info->fbo_ops.glGenRenderbuffers(1, &surface->rb_multisample);
+ gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, surface->rb_multisample);
+ gl_info->fbo_ops.glRenderbufferStorageMultisample(GL_RENDERBUFFER, surface->resource.multisample_type,
+ surface->resource.format->glInternal, surface->pow2Width, surface->pow2Height);
+ TRACE("Created multisample rb %u.\n", surface->rb_multisample);
+ }
+ else
+ {
+ if (surface->rb_resolved)
+ return;
+
+ gl_info->fbo_ops.glGenRenderbuffers(1, &surface->rb_resolved);
+ gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, surface->rb_resolved);
+ gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, surface->resource.format->glInternal,
+ surface->pow2Width, surface->pow2Height);
+ TRACE("Created resolved rb %u.\n", surface->rb_resolved);
+ }
+}
+
+static void flush_to_framebuffer_drawpixels(struct wined3d_surface *surface,
+ const RECT *rect, GLenum fmt, GLenum type, UINT bpp, const BYTE *mem)
+{
+ struct wined3d_device *device = surface->resource.device;
+ UINT pitch = wined3d_surface_get_pitch(surface);
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+ RECT local_rect;
+ UINT w, h;
+
+ surface_get_rect(surface, rect, &local_rect);
+
+ mem += local_rect.top * pitch + local_rect.left * bpp;
+ w = local_rect.right - local_rect.left;
+ h = local_rect.bottom - local_rect.top;
+
+ /* Activate the correct context for the render target */
+ context = context_acquire(device, surface);
+ context_apply_blit_state(context, device);
+ gl_info = context->gl_info;
+
+ if (!surface_is_offscreen(surface))
+ {
+ GLenum buffer = surface_get_gl_buffer(surface);
+ TRACE("Unlocking %#x buffer.\n", buffer);
+ context_set_draw_buffer(context, buffer);
+
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ surface_translate_drawable_coords(surface, context->win_handle, &local_rect);
+#else
+ surface_translate_drawable_coords(surface, context->swapchain->win_handle, &local_rect);
+#endif
+ gl_info->gl_ops.gl.p_glPixelZoom(1.0f, -1.0f);
+ }
+ else
+ {
+ /* Primary offscreen render target */
+ TRACE("Offscreen render target.\n");
+ context_set_draw_buffer(context, device->offscreenBuffer);
+
+ gl_info->gl_ops.gl.p_glPixelZoom(1.0f, 1.0f);
+ }
+
+ gl_info->gl_ops.gl.p_glRasterPos3i(local_rect.left, local_rect.top, 1);
+ checkGLcall("glRasterPos3i");
+
+ /* If not fullscreen, we need to skip a number of bytes to find the next row of data */
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->resource.width);
+
+ if (surface->flags & SFLAG_PBO)
+ {
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, surface->pbo));
+ checkGLcall("glBindBufferARB");
+ }
+
+ gl_info->gl_ops.gl.p_glDrawPixels(w, h, fmt, type, mem);
+ checkGLcall("glDrawPixels");
+
+ if (surface->flags & SFLAG_PBO)
+ {
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+ checkGLcall("glBindBufferARB");
+ }
+
+ gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ checkGLcall("glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)");
+
+ if (wined3d_settings.strict_draw_ordering
+ || (surface->swapchain && surface->swapchain->front_buffer == surface))
+ gl_info->gl_ops.gl.p_glFlush();
+
+ context_release(context);
+}
+
+static BOOL color_in_range(const struct wined3d_color_key *color_key, DWORD color)
+{
+ /* FIXME: Is this really how color keys are supposed to work? I think it
+ * makes more sense to compare the individual channels. */
+ return color >= color_key->color_space_low_value
+ && color <= color_key->color_space_high_value;
+}
+
+void d3dfmt_p8_init_palette(const struct wined3d_surface *surface, BYTE table[256][4], BOOL colorkey)
+{
+ const struct wined3d_device *device = surface->resource.device;
+ const struct wined3d_palette *pal = surface->palette;
+ BOOL index_in_alpha = FALSE;
+ unsigned int i;
+
+ /* Old games like StarCraft, C&C, Red Alert and others use P8 render targets.
+ * Reading back the RGB output each lockrect (each frame as they lock the whole screen)
+ * is slow. Further RGB->P8 conversion is not possible because palettes can have
+ * duplicate entries. Store the color key in the unused alpha component to speed the
+ * download up and to make conversion unneeded. */
+ index_in_alpha = primary_render_target_is_p8(device);
+
+ if (!pal)
+ {
+ FIXME("No palette set.\n");
+ if (index_in_alpha)
+ {
+ /* Guarantees that memory representation remains correct after sysmem<->texture transfers even if
+ * there's no palette at this time. */
+ for (i = 0; i < 256; i++) table[i][3] = i;
+ }
+ }
+ else
+ {
+ TRACE("Using surface palette %p\n", pal);
+ /* Get the surface's palette */
+ for (i = 0; i < 256; ++i)
+ {
+ table[i][0] = pal->palents[i].peRed;
+ table[i][1] = pal->palents[i].peGreen;
+ table[i][2] = pal->palents[i].peBlue;
+
+ /* When index_in_alpha is set the palette index is stored in the
+ * alpha component. In case of a readback we can then read
+ * GL_ALPHA. Color keying is handled in BltOverride using a
+ * GL_ALPHA_TEST using GL_NOT_EQUAL. In case of index_in_alpha the
+ * color key itself is passed to glAlphaFunc in other cases the
+ * alpha component of pixels that should be masked away is set to 0. */
+ if (index_in_alpha)
+ table[i][3] = i;
+ else if (colorkey && color_in_range(&surface->src_blt_color_key, i))
+ table[i][3] = 0x00;
+ else if (pal->flags & WINEDDPCAPS_ALPHA)
+ table[i][3] = pal->palents[i].peFlags;
+ else
+ table[i][3] = 0xff;
+ }
+ }
+}
+
+static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height,
+ UINT outpitch, enum wined3d_conversion_type conversion_type, struct wined3d_surface *surface)
+{
+ const BYTE *source;
+ BYTE *dest;
+
+ TRACE("src %p, dst %p, pitch %u, width %u, height %u, outpitch %u, conversion_type %#x, surface %p.\n",
+ src, dst, pitch, width, height, outpitch, conversion_type, surface);
+
+ switch (conversion_type)
+ {
+ case WINED3D_CT_NONE:
+ {
+ memcpy(dst, src, pitch * height);
+ break;
+ }
+
+ case WINED3D_CT_PALETTED:
+ case WINED3D_CT_PALETTED_CK:
+ {
+ BYTE table[256][4];
+ unsigned int x, y;
+
+ d3dfmt_p8_init_palette(surface, table, (conversion_type == WINED3D_CT_PALETTED_CK));
+
+ for (y = 0; y < height; y++)
+ {
+ source = src + pitch * y;
+ dest = dst + outpitch * y;
+ /* This is an 1 bpp format, using the width here is fine */
+ for (x = 0; x < width; x++) {
+ BYTE color = *source++;
+ *dest++ = table[color][0];
+ *dest++ = table[color][1];
+ *dest++ = table[color][2];
+ *dest++ = table[color][3];
+ }
+ }
+ }
+ break;
+
+ case WINED3D_CT_CK_565:
+ {
+ /* Converting the 565 format in 5551 packed to emulate color-keying.
+
+ Note : in all these conversion, it would be best to average the averaging
+ pixels to get the color of the pixel that will be color-keyed to
+ prevent 'color bleeding'. This will be done later on if ever it is
+ too visible.
+
+ Note2: Nvidia documents say that their driver does not support alpha + color keying
+ on the same surface and disables color keying in such a case
+ */
+ unsigned int x, y;
+ const WORD *Source;
+ WORD *Dest;
+
+ TRACE("Color keyed 565\n");
+
+ for (y = 0; y < height; y++) {
+ Source = (const WORD *)(src + y * pitch);
+ Dest = (WORD *) (dst + y * outpitch);
+ for (x = 0; x < width; x++ ) {
+ WORD color = *Source++;
+ *Dest = ((color & 0xffc0) | ((color & 0x1f) << 1));
+ if (!color_in_range(&surface->src_blt_color_key, color))
+ *Dest |= 0x0001;
+ Dest++;
+ }
+ }
+ }
+ break;
+
+ case WINED3D_CT_CK_5551:
+ {
+ /* Converting X1R5G5B5 format to R5G5B5A1 to emulate color-keying. */
+ unsigned int x, y;
+ const WORD *Source;
+ WORD *Dest;
+ TRACE("Color keyed 5551\n");
+ for (y = 0; y < height; y++) {
+ Source = (const WORD *)(src + y * pitch);
+ Dest = (WORD *) (dst + y * outpitch);
+ for (x = 0; x < width; x++ ) {
+ WORD color = *Source++;
+ *Dest = color;
+ if (!color_in_range(&surface->src_blt_color_key, color))
+ *Dest |= (1 << 15);
+ else
+ *Dest &= ~(1 << 15);
+ Dest++;
+ }
+ }
+ }
+ break;
+
+ case WINED3D_CT_CK_RGB24:
+ {
+ /* Converting R8G8B8 format to R8G8B8A8 with color-keying. */
+ unsigned int x, y;
+ for (y = 0; y < height; y++)
+ {
+ source = src + pitch * y;
+ dest = dst + outpitch * y;
+ for (x = 0; x < width; x++) {
+ DWORD color = ((DWORD)source[0] << 16) + ((DWORD)source[1] << 8) + (DWORD)source[2] ;
+ DWORD dstcolor = color << 8;
+ if (!color_in_range(&surface->src_blt_color_key, color))
+ dstcolor |= 0xff;
+ *(DWORD*)dest = dstcolor;
+ source += 3;
+ dest += 4;
+ }
+ }
+ }
+ break;
+
+ case WINED3D_CT_RGB32_888:
+ {
+ /* Converting X8R8G8B8 format to R8G8B8A8 with color-keying. */
+ unsigned int x, y;
+ for (y = 0; y < height; y++)
+ {
+ source = src + pitch * y;
+ dest = dst + outpitch * y;
+ for (x = 0; x < width; x++) {
+ DWORD color = 0xffffff & *(const DWORD*)source;
+ DWORD dstcolor = color << 8;
+ if (!color_in_range(&surface->src_blt_color_key, color))
+ dstcolor |= 0xff;
+ *(DWORD*)dest = dstcolor;
+ source += 4;
+ dest += 4;
+ }
+ }
+ }
+ break;
+
+ case WINED3D_CT_CK_ARGB32:
+ {
+ unsigned int x, y;
+ for (y = 0; y < height; ++y)
+ {
+ source = src + pitch * y;
+ dest = dst + outpitch * y;
+ for (x = 0; x < width; ++x)
+ {
+ DWORD color = *(const DWORD *)source;
+ if (color_in_range(&surface->src_blt_color_key, color))
+ color &= ~0xff000000;
+ *(DWORD*)dest = color;
+ source += 4;
+ dest += 4;
+ }
+ }
+ }
+ break;
+
+ default:
+ ERR("Unsupported conversion type %#x.\n", conversion_type);
+ }
+ return WINED3D_OK;
+}
+
+void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back)
+{
+ /* Flip the surface contents */
+ /* Flip the DC */
+ {
+ HDC tmp;
+ tmp = front->hDC;
+ front->hDC = back->hDC;
+ back->hDC = tmp;
+ }
+
+ /* Flip the DIBsection */
+ {
+ HBITMAP tmp = front->dib.DIBsection;
+ front->dib.DIBsection = back->dib.DIBsection;
+ back->dib.DIBsection = tmp;
+ }
+
+ /* Flip the surface data */
+ {
+ void* tmp;
+
+ tmp = front->dib.bitmap_data;
+ front->dib.bitmap_data = back->dib.bitmap_data;
+ back->dib.bitmap_data = tmp;
+
+ tmp = front->resource.allocatedMemory;
+ front->resource.allocatedMemory = back->resource.allocatedMemory;
+ back->resource.allocatedMemory = tmp;
+
+ tmp = front->resource.heapMemory;
+ front->resource.heapMemory = back->resource.heapMemory;
+ back->resource.heapMemory = tmp;
+ }
+
+ /* Flip the PBO */
+ {
+ GLuint tmp_pbo = front->pbo;
+ front->pbo = back->pbo;
+ back->pbo = tmp_pbo;
+ }
+
+ /* Flip the opengl texture */
+ {
+ GLuint tmp;
+
+ tmp = back->texture_name;
+ back->texture_name = front->texture_name;
+ front->texture_name = tmp;
+
+ tmp = back->texture_name_srgb;
+ back->texture_name_srgb = front->texture_name_srgb;
+ front->texture_name_srgb = tmp;
+
+ tmp = back->rb_multisample;
+ back->rb_multisample = front->rb_multisample;
+ front->rb_multisample = tmp;
+
+ tmp = back->rb_resolved;
+ back->rb_resolved = front->rb_resolved;
+ front->rb_resolved = tmp;
+
+ resource_unload(&back->resource);
+ resource_unload(&front->resource);
+ }
+
+ {
+ DWORD tmp_flags = back->flags;
+ back->flags = front->flags;
+ front->flags = tmp_flags;
+ }
+}
+
+/* Does a direct frame buffer -> texture copy. Stretching is done with single
+ * pixel copy calls. */
+static void fb_copy_to_texture_direct(struct wined3d_surface *dst_surface, struct wined3d_surface *src_surface,
+ const RECT *src_rect, const RECT *dst_rect_in, enum wined3d_texture_filter_type filter)
+{
+ struct wined3d_device *device = dst_surface->resource.device;
+ const struct wined3d_gl_info *gl_info;
+ float xrel, yrel;
+ struct wined3d_context *context;
+ BOOL upsidedown = FALSE;
+ RECT dst_rect = *dst_rect_in;
+ GLenum dst_target;
+
+ if (dst_surface->container)
+ dst_target = dst_surface->container->target;
+ else
+ dst_target = dst_surface->texture_target;
+
+ /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag
+ * glCopyTexSubImage is a bit picky about the parameters we pass to it
+ */
+ if(dst_rect.top > dst_rect.bottom) {
+ UINT tmp = dst_rect.bottom;
+ dst_rect.bottom = dst_rect.top;
+ dst_rect.top = tmp;
+ upsidedown = TRUE;
+ }
+
+ context = context_acquire(device, src_surface);
+ gl_info = context->gl_info;
+ context_apply_blit_state(context, device);
+ surface_internal_preload(dst_surface, SRGB_RGB);
+
+ /* Bind the target texture */
+ context_bind_texture(context, dst_target, dst_surface->texture_name);
+ if (surface_is_offscreen(src_surface))
+ {
+ TRACE("Reading from an offscreen target\n");
+ upsidedown = !upsidedown;
+ gl_info->gl_ops.gl.p_glReadBuffer(device->offscreenBuffer);
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glReadBuffer(surface_get_gl_buffer(src_surface));
+ }
+ checkGLcall("glReadBuffer");
+
+ xrel = (float) (src_rect->right - src_rect->left) / (float) (dst_rect.right - dst_rect.left);
+ yrel = (float) (src_rect->bottom - src_rect->top) / (float) (dst_rect.bottom - dst_rect.top);
+
+ if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps))
+ {
+ FIXME("Doing a pixel by pixel copy from the framebuffer to a texture, expect major performance issues\n");
+
+ if (filter != WINED3D_TEXF_NONE && filter != WINED3D_TEXF_POINT)
+ ERR("Texture filtering not supported in direct blit.\n");
+ }
+ else if ((filter != WINED3D_TEXF_NONE && filter != WINED3D_TEXF_POINT)
+ && ((yrel - 1.0f < -eps) || (yrel - 1.0f > eps)))
+ {
+ ERR("Texture filtering not supported in direct blit\n");
+ }
+
+ if (upsidedown
+ && !((xrel - 1.0f < -eps) || (xrel - 1.0f > eps))
+ && !((yrel - 1.0f < -eps) || (yrel - 1.0f > eps)))
+ {
+ /* Upside down copy without stretching is nice, one glCopyTexSubImage call will do. */
+ gl_info->gl_ops.gl.p_glCopyTexSubImage2D(dst_surface->texture_target, dst_surface->texture_level,
+ dst_rect.left /*xoffset */, dst_rect.top /* y offset */,
+ src_rect->left, src_surface->resource.height - src_rect->bottom,
+ dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top);
+ }
+ else
+ {
+ LONG row;
+ UINT yoffset = src_surface->resource.height - src_rect->top + dst_rect.top - 1;
+ /* I have to process this row by row to swap the image,
+ * otherwise it would be upside down, so stretching in y direction
+ * doesn't cost extra time
+ *
+ * However, stretching in x direction can be avoided if not necessary
+ */
+ for(row = dst_rect.top; row < dst_rect.bottom; row++) {
+ if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps))
+ {
+ /* Well, that stuff works, but it's very slow.
+ * find a better way instead
+ */
+ LONG col;
+
+ for (col = dst_rect.left; col < dst_rect.right; ++col)
+ {
+ gl_info->gl_ops.gl.p_glCopyTexSubImage2D(dst_surface->texture_target, dst_surface->texture_level,
+ dst_rect.left + col /* x offset */, row /* y offset */,
+ src_rect->left + col * xrel, yoffset - (int) (row * yrel), 1, 1);
+ }
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glCopyTexSubImage2D(dst_surface->texture_target, dst_surface->texture_level,
+ dst_rect.left /* x offset */, row /* y offset */,
+ src_rect->left, yoffset - (int) (row * yrel), dst_rect.right - dst_rect.left, 1);
+ }
+ }
+ }
+ checkGLcall("glCopyTexSubImage2D");
+
+ context_release(context);
+
+ /* The texture is now most up to date - If the surface is a render target and has a drawable, this
+ * path is never entered
+ */
+ surface_modify_location(dst_surface, SFLAG_INTEXTURE, TRUE);
+}
+
+/* Uses the hardware to stretch and flip the image */
+static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, struct wined3d_surface *src_surface,
+ const RECT *src_rect, const RECT *dst_rect_in, enum wined3d_texture_filter_type filter)
+{
+ struct wined3d_device *device = dst_surface->resource.device;
+ GLuint src, backup = 0;
+ float left, right, top, bottom; /* Texture coordinates */
+ UINT fbwidth = src_surface->resource.width;
+ UINT fbheight = src_surface->resource.height;
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+ GLenum drawBuffer = GL_BACK;
+ GLenum texture_target;
+ BOOL noBackBufferBackup;
+ BOOL src_offscreen;
+ BOOL upsidedown = FALSE;
+ RECT dst_rect = *dst_rect_in;
+
+ TRACE("Using hwstretch blit\n");
+ /* Activate the Proper context for reading from the source surface, set it up for blitting */
+ context = context_acquire(device, src_surface);
+ gl_info = context->gl_info;
+ context_apply_blit_state(context, device);
+ surface_internal_preload(dst_surface, SRGB_RGB);
+
+ src_offscreen = surface_is_offscreen(src_surface);
+ noBackBufferBackup = src_offscreen && wined3d_settings.offscreen_rendering_mode == ORM_FBO;
+ if (!noBackBufferBackup && !src_surface->texture_name)
+ {
+ /* Get it a description */
+ surface_internal_preload(src_surface, SRGB_RGB);
+ }
+
+ /* Try to use an aux buffer for drawing the rectangle. This way it doesn't need restoring.
+ * This way we don't have to wait for the 2nd readback to finish to leave this function.
+ */
+ if (context->aux_buffers >= 2)
+ {
+ /* Got more than one aux buffer? Use the 2nd aux buffer */
+ drawBuffer = GL_AUX1;
+ }
+ else if ((!src_offscreen || device->offscreenBuffer == GL_BACK) && context->aux_buffers >= 1)
+ {
+ /* Only one aux buffer, but it isn't used (Onscreen rendering, or non-aux orm)? Use it! */
+ drawBuffer = GL_AUX0;
+ }
+
+ if (noBackBufferBackup)
+ {
+ gl_info->gl_ops.gl.p_glGenTextures(1, &backup);
+ checkGLcall("glGenTextures");
+ context_bind_texture(context, GL_TEXTURE_2D, backup);
+ texture_target = GL_TEXTURE_2D;
+ }
+ else
+ {
+ /* Backup the back buffer and copy the source buffer into a texture to draw an upside down stretched quad. If
+ * we are reading from the back buffer, the backup can be used as source texture
+ */
+ texture_target = src_surface->texture_target;
+ context_bind_texture(context, texture_target, src_surface->texture_name);
+ gl_info->gl_ops.gl.p_glEnable(texture_target);
+ checkGLcall("glEnable(texture_target)");
+
+ /* For now invalidate the texture copy of the back buffer. Drawable and sysmem copy are untouched */
+ src_surface->flags &= ~SFLAG_INTEXTURE;
+ }
+
+ /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag
+ * glCopyTexSubImage is a bit picky about the parameters we pass to it
+ */
+ if(dst_rect.top > dst_rect.bottom) {
+ UINT tmp = dst_rect.bottom;
+ dst_rect.bottom = dst_rect.top;
+ dst_rect.top = tmp;
+ upsidedown = TRUE;
+ }
+
+ if (src_offscreen)
+ {
+ TRACE("Reading from an offscreen target\n");
+ upsidedown = !upsidedown;
+ gl_info->gl_ops.gl.p_glReadBuffer(device->offscreenBuffer);
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glReadBuffer(surface_get_gl_buffer(src_surface));
+ }
+
+ /* TODO: Only back up the part that will be overwritten */
+ gl_info->gl_ops.gl.p_glCopyTexSubImage2D(texture_target, 0, 0, 0, 0, 0, fbwidth, fbheight);
+
+ checkGLcall("glCopyTexSubImage2D");
+
+ /* No issue with overriding these - the sampler is dirty due to blit usage */
+ gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER,
+ wined3d_gl_mag_filter(magLookup, filter));
+ checkGLcall("glTexParameteri");
+ gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER,
+ wined3d_gl_min_mip_filter(minMipLookup, filter, WINED3D_TEXF_NONE));
+ checkGLcall("glTexParameteri");
+
+ if (!src_surface->swapchain || src_surface == src_surface->swapchain->back_buffers[0])
+ {
+ src = backup ? backup : src_surface->texture_name;
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glReadBuffer(GL_FRONT);
+ checkGLcall("glReadBuffer(GL_FRONT)");
+
+ gl_info->gl_ops.gl.p_glGenTextures(1, &src);
+ checkGLcall("glGenTextures(1, &src)");
+ context_bind_texture(context, GL_TEXTURE_2D, src);
+
+ /* TODO: Only copy the part that will be read. Use src_rect->left, src_rect->bottom as origin, but with the width watch
+ * out for power of 2 sizes
+ */
+ gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, src_surface->pow2Width,
+ src_surface->pow2Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ checkGLcall("glTexImage2D");
+ gl_info->gl_ops.gl.p_glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, fbwidth, fbheight);
+
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ checkGLcall("glTexParameteri");
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ checkGLcall("glTexParameteri");
+
+ gl_info->gl_ops.gl.p_glReadBuffer(GL_BACK);
+ checkGLcall("glReadBuffer(GL_BACK)");
+
+ if (texture_target != GL_TEXTURE_2D)
+ {
+ gl_info->gl_ops.gl.p_glDisable(texture_target);
+ gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
+ texture_target = GL_TEXTURE_2D;
+ }
+ }
+ checkGLcall("glEnd and previous");
+
+ left = src_rect->left;
+ right = src_rect->right;
+
+ if (!upsidedown)
+ {
+ top = src_surface->resource.height - src_rect->top;
+ bottom = src_surface->resource.height - src_rect->bottom;
+ }
+ else
+ {
+ top = src_surface->resource.height - src_rect->bottom;
+ bottom = src_surface->resource.height - src_rect->top;
+ }
+
+ if (src_surface->flags & SFLAG_NORMCOORD)
+ {
+ left /= src_surface->pow2Width;
+ right /= src_surface->pow2Width;
+ top /= src_surface->pow2Height;
+ bottom /= src_surface->pow2Height;
+ }
+
+ /* draw the source texture stretched and upside down. The correct surface is bound already */
+ gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP);
+
+ context_set_draw_buffer(context, drawBuffer);
+ gl_info->gl_ops.gl.p_glReadBuffer(drawBuffer);
+
+ gl_info->gl_ops.gl.p_glBegin(GL_QUADS);
+ /* bottom left */
+ gl_info->gl_ops.gl.p_glTexCoord2f(left, bottom);
+ gl_info->gl_ops.gl.p_glVertex2i(0, 0);
+
+ /* top left */
+ gl_info->gl_ops.gl.p_glTexCoord2f(left, top);
+ gl_info->gl_ops.gl.p_glVertex2i(0, dst_rect.bottom - dst_rect.top);
+
+ /* top right */
+ gl_info->gl_ops.gl.p_glTexCoord2f(right, top);
+ gl_info->gl_ops.gl.p_glVertex2i(dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top);
+
+ /* bottom right */
+ gl_info->gl_ops.gl.p_glTexCoord2f(right, bottom);
+ gl_info->gl_ops.gl.p_glVertex2i(dst_rect.right - dst_rect.left, 0);
+ gl_info->gl_ops.gl.p_glEnd();
+ checkGLcall("glEnd and previous");
+
+ if (texture_target != dst_surface->texture_target)
+ {
+ gl_info->gl_ops.gl.p_glDisable(texture_target);
+ gl_info->gl_ops.gl.p_glEnable(dst_surface->texture_target);
+ texture_target = dst_surface->texture_target;
+ }
+
+ /* Now read the stretched and upside down image into the destination texture */
+ context_bind_texture(context, texture_target, dst_surface->texture_name);
+ gl_info->gl_ops.gl.p_glCopyTexSubImage2D(texture_target,
+ 0,
+ dst_rect.left, dst_rect.top, /* xoffset, yoffset */
+ 0, 0, /* We blitted the image to the origin */
+ dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top);
+ checkGLcall("glCopyTexSubImage2D");
+
+ if (drawBuffer == GL_BACK)
+ {
+ /* Write the back buffer backup back. */
+ if (backup)
+ {
+ if (texture_target != GL_TEXTURE_2D)
+ {
+ gl_info->gl_ops.gl.p_glDisable(texture_target);
+ gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
+ texture_target = GL_TEXTURE_2D;
+ }
+ context_bind_texture(context, GL_TEXTURE_2D, backup);
+ }
+ else
+ {
+ if (texture_target != src_surface->texture_target)
+ {
+ gl_info->gl_ops.gl.p_glDisable(texture_target);
+ gl_info->gl_ops.gl.p_glEnable(src_surface->texture_target);
+ texture_target = src_surface->texture_target;
+ }
+ context_bind_texture(context, src_surface->texture_target, src_surface->texture_name);
+ }
+
+ gl_info->gl_ops.gl.p_glBegin(GL_QUADS);
+ /* top left */
+ gl_info->gl_ops.gl.p_glTexCoord2f(0.0f, 0.0f);
+ gl_info->gl_ops.gl.p_glVertex2i(0, fbheight);
+
+ /* bottom left */
+ gl_info->gl_ops.gl.p_glTexCoord2f(0.0f, (float)fbheight / (float)src_surface->pow2Height);
+ gl_info->gl_ops.gl.p_glVertex2i(0, 0);
+
+ /* bottom right */
+ gl_info->gl_ops.gl.p_glTexCoord2f((float)fbwidth / (float)src_surface->pow2Width,
+ (float)fbheight / (float)src_surface->pow2Height);
+ gl_info->gl_ops.gl.p_glVertex2i(fbwidth, 0);
+
+ /* top right */
+ gl_info->gl_ops.gl.p_glTexCoord2f((float)fbwidth / (float)src_surface->pow2Width, 0.0f);
+ gl_info->gl_ops.gl.p_glVertex2i(fbwidth, fbheight);
+ gl_info->gl_ops.gl.p_glEnd();
+ }
+ gl_info->gl_ops.gl.p_glDisable(texture_target);
+ checkGLcall("glDisable(texture_target)");
+
+ /* Cleanup */
+ if (src != src_surface->texture_name && src != backup)
+ {
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &src);
+ checkGLcall("glDeleteTextures(1, &src)");
+ }
+ if (backup)
+ {
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &backup);
+ checkGLcall("glDeleteTextures(1, &backup)");
+ }
+
+ if (wined3d_settings.strict_draw_ordering)
+ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
+
+ context_release(context);
+
+ /* The texture is now most up to date - If the surface is a render target and has a drawable, this
+ * path is never entered
+ */
+ surface_modify_location(dst_surface, SFLAG_INTEXTURE, TRUE);
+}
+
+/* Front buffer coordinates are always full screen coordinates, but our GL
+ * drawable is limited to the window's client area. The sysmem and texture
+ * copies do have the full screen size. Note that GL has a bottom-left
+ * origin, while D3D has a top-left origin. */
+void surface_translate_drawable_coords(const struct wined3d_surface *surface, HWND window, RECT *rect)
+{
+ UINT drawable_height;
+ if (surface->swapchain && surface == surface->swapchain->front_buffer)
+ {
+#ifndef VBOX_WITH_WINE_FIXES
+ POINT offset = {0, 0};
+ RECT windowsize;
+
+ ScreenToClient(window, &offset);
+ OffsetRect(rect, offset.x, offset.y);
+
+ GetClientRect(window, &windowsize);
+ drawable_height = windowsize.bottom - windowsize.top;
+#else
+# ifdef VBOX_WINE_STRICT
+ ERR("should not be here!");
+# else
+ WARN("should not be here!");
+# endif
+ drawable_height = surface->resource.height;
+#endif
+ }
+ else
+ {
+ drawable_height = surface->resource.height;
+ }
+
+ rect->top = drawable_height - rect->top;
+ rect->bottom = drawable_height - rect->bottom;
+}
+
+static void surface_blt_to_drawable(const struct wined3d_device *device,
+ enum wined3d_texture_filter_type filter, BOOL color_key,
+ struct wined3d_surface *src_surface, const RECT *src_rect_in,
+ struct wined3d_surface *dst_surface, const RECT *dst_rect_in)
+{
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+ RECT src_rect, dst_rect;
+
+ src_rect = *src_rect_in;
+ dst_rect = *dst_rect_in;
+
+ /* Make sure the surface is up-to-date. This should probably use
+ * surface_load_location() and worry about the destination surface too,
+ * unless we're overwriting it completely. */
+ surface_internal_preload(src_surface, SRGB_RGB);
+
+ /* Activate the destination context, set it up for blitting */
+ context = context_acquire(device, dst_surface);
+ gl_info = context->gl_info;
+ context_apply_blit_state(context, device);
+
+ if (!surface_is_offscreen(dst_surface))
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ surface_translate_drawable_coords(dst_surface, context->win_handle, &dst_rect);
+#else
+ surface_translate_drawable_coords(dst_surface, context->swapchain->win_handle, &dst_rect);
+#endif
+
+ device->blitter->set_shader(device->blit_priv, context, src_surface);
+
+ if (color_key)
+ {
+ gl_info->gl_ops.gl.p_glEnable(GL_ALPHA_TEST);
+ checkGLcall("glEnable(GL_ALPHA_TEST)");
+
+ /* When the primary render target uses P8, the alpha component
+ * contains the palette index. Which means that the colorkey is one of
+ * the palette entries. In other cases pixels that should be masked
+ * away have alpha set to 0. */
+ if (primary_render_target_is_p8(device))
+ gl_info->gl_ops.gl.p_glAlphaFunc(GL_NOTEQUAL,
+ (float)src_surface->src_blt_color_key.color_space_low_value / 256.0f);
+ else
+ gl_info->gl_ops.gl.p_glAlphaFunc(GL_NOTEQUAL, 0.0f);
+ checkGLcall("glAlphaFunc");
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST);
+ checkGLcall("glDisable(GL_ALPHA_TEST)");
+ }
+
+ draw_textured_quad(src_surface, context, &src_rect, &dst_rect, filter);
+
+ if (color_key)
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST);
+ checkGLcall("glDisable(GL_ALPHA_TEST)");
+ }
+
+ /* Leave the opengl state valid for blitting */
+ device->blitter->unset_shader(context->gl_info);
+
+ if (wined3d_settings.strict_draw_ordering
+ || (dst_surface->swapchain && dst_surface->swapchain->front_buffer == dst_surface))
+ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
+
+ context_release(context);
+}
+
+/* Do not call while under the GL lock. */
+HRESULT surface_color_fill(struct wined3d_surface *s, const RECT *rect, const struct wined3d_color *color)
+{
+ struct wined3d_device *device = s->resource.device;
+ const struct blit_shader *blitter;
+
+ blitter = wined3d_select_blitter(&device->adapter->gl_info, WINED3D_BLIT_OP_COLOR_FILL,
+ NULL, 0, 0, NULL, rect, s->resource.usage, s->resource.pool, s->resource.format);
+ if (!blitter)
+ {
+ FIXME("No blitter is capable of performing the requested color fill operation.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ return blitter->color_fill(device, s, rect, color);
+}
+
+/* Do not call while under the GL lock. */
+static HRESULT IWineD3DSurfaceImpl_BltOverride(struct wined3d_surface *dst_surface, const RECT *dst_rect,
+ struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, const WINEDDBLTFX *DDBltFx,
+ enum wined3d_texture_filter_type filter)
+{
+ struct wined3d_device *device = dst_surface->resource.device;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ struct wined3d_swapchain *src_swapchain, *dst_swapchain;
+
+ TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, blt_fx %p, filter %s.\n",
+ dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect),
+ flags, DDBltFx, debug_d3dtexturefiltertype(filter));
+
+ /* Get the swapchain. One of the surfaces has to be a primary surface */
+ if (dst_surface->resource.pool == WINED3D_POOL_SYSTEM_MEM)
+ {
+ WARN("Destination is in sysmem, rejecting gl blt\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ dst_swapchain = dst_surface->swapchain;
+
+ if (src_surface)
+ {
+ if (src_surface->resource.pool == WINED3D_POOL_SYSTEM_MEM)
+ {
+ WARN("Src is in sysmem, rejecting gl blt\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ src_swapchain = src_surface->swapchain;
+ }
+ else
+ {
+ src_swapchain = NULL;
+ }
+
+ /* Early sort out of cases where no render target is used */
+ if (!dst_swapchain && !src_swapchain
+ && src_surface != device->fb.render_targets[0]
+ && dst_surface != device->fb.render_targets[0])
+ {
+ TRACE("No surface is render target, not using hardware blit.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ /* No destination color keying supported */
+ if (flags & (WINEDDBLT_KEYDEST | WINEDDBLT_KEYDESTOVERRIDE))
+ {
+ /* Can we support that with glBlendFunc if blitting to the frame buffer? */
+ TRACE("Destination color key not supported in accelerated Blit, falling back to software\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (dst_swapchain && dst_swapchain == src_swapchain)
+ {
+ FIXME("Implement hardware blit between two surfaces on the same swapchain\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (dst_swapchain && src_swapchain)
+ {
+ FIXME("Implement hardware blit between two different swapchains\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (dst_swapchain)
+ {
+ /* Handled with regular texture -> swapchain blit */
+ if (src_surface == device->fb.render_targets[0])
+ TRACE("Blit from active render target to a swapchain\n");
+ }
+ else if (src_swapchain && dst_surface == device->fb.render_targets[0])
+ {
+ FIXME("Implement blit from a swapchain to the active render target\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if ((src_swapchain || src_surface == device->fb.render_targets[0]) && !dst_swapchain)
+ {
+ /* Blit from render target to texture */
+ BOOL stretchx;
+
+ /* P8 read back is not implemented */
+ if (src_surface->resource.format->id == WINED3DFMT_P8_UINT
+ || dst_surface->resource.format->id == WINED3DFMT_P8_UINT)
+ {
+ TRACE("P8 read back not supported by frame buffer to texture blit\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE))
+ {
+ TRACE("Color keying not supported by frame buffer to texture blit\n");
+ return WINED3DERR_INVALIDCALL;
+ /* Destination color key is checked above */
+ }
+
+ if (dst_rect->right - dst_rect->left != src_rect->right - src_rect->left)
+ stretchx = TRUE;
+ else
+ stretchx = FALSE;
+
+ /* Blt is a pretty powerful call, while glCopyTexSubImage2D is not. glCopyTexSubImage cannot
+ * flip the image nor scale it.
+ *
+ * -> If the app asks for a unscaled, upside down copy, just perform one glCopyTexSubImage2D call
+ * -> If the app wants a image width an unscaled width, copy it line per line
+ * -> If the app wants a image that is scaled on the x axis, and the destination rectangle is smaller
+ * than the frame buffer, draw an upside down scaled image onto the fb, read it back and restore the
+ * back buffer. This is slower than reading line per line, thus not used for flipping
+ * -> If the app wants a scaled image with a dest rect that is bigger than the fb, it has to be copied
+ * pixel by pixel. */
+ if (!stretchx || dst_rect->right - dst_rect->left > src_surface->resource.width
+ || dst_rect->bottom - dst_rect->top > src_surface->resource.height)
+ {
+ TRACE("No stretching in x direction, using direct framebuffer -> texture copy.\n");
+ fb_copy_to_texture_direct(dst_surface, src_surface, src_rect, dst_rect, filter);
+ }
+ else
+ {
+ TRACE("Using hardware stretching to flip / stretch the texture.\n");
+ fb_copy_to_texture_hwstretch(dst_surface, src_surface, src_rect, dst_rect, filter);
+ }
+
+ if (!dst_surface->resource.map_count && !(dst_surface->flags & SFLAG_DONOTFREE))
+ {
+ HeapFree(GetProcessHeap(), 0, dst_surface->resource.heapMemory);
+ dst_surface->resource.allocatedMemory = NULL;
+ dst_surface->resource.heapMemory = NULL;
+ }
+ else
+ {
+ dst_surface->flags &= ~SFLAG_INSYSMEM;
+ }
+
+ return WINED3D_OK;
+ }
+ else if (src_surface)
+ {
+ /* Blit from offscreen surface to render target */
+ struct wined3d_color_key old_blt_key = src_surface->src_blt_color_key;
+ DWORD oldCKeyFlags = src_surface->CKeyFlags;
+
+ TRACE("Blt from surface %p to rendertarget %p\n", src_surface, dst_surface);
+
+ if (!device->blitter->blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
+ src_rect, src_surface->resource.usage, src_surface->resource.pool, src_surface->resource.format,
+ dst_rect, dst_surface->resource.usage, dst_surface->resource.pool, dst_surface->resource.format))
+ {
+ FIXME("Unsupported blit operation falling back to software\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ /* Color keying: Check if we have to do a color keyed blt,
+ * and if not check if a color key is activated.
+ *
+ * Just modify the color keying parameters in the surface and restore them afterwards
+ * The surface keeps track of the color key last used to load the opengl surface.
+ * PreLoad will catch the change to the flags and color key and reload if necessary.
+ */
+ if (flags & WINEDDBLT_KEYSRC)
+ {
+ /* Use color key from surface */
+ }
+ else if (flags & WINEDDBLT_KEYSRCOVERRIDE)
+ {
+ /* Use color key from DDBltFx */
+ src_surface->CKeyFlags |= WINEDDSD_CKSRCBLT;
+ src_surface->src_blt_color_key = DDBltFx->ddckSrcColorkey;
+ }
+ else
+ {
+ /* Do not use color key */
+ src_surface->CKeyFlags &= ~WINEDDSD_CKSRCBLT;
+ }
+
+ surface_blt_to_drawable(device, filter, flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYSRCOVERRIDE),
+ src_surface, src_rect, dst_surface, dst_rect);
+
+ /* Restore the color key parameters */
+ src_surface->CKeyFlags = oldCKeyFlags;
+ src_surface->src_blt_color_key = old_blt_key;
+
+ surface_modify_location(dst_surface, dst_surface->draw_binding, TRUE);
+
+ return WINED3D_OK;
+ }
+
+ /* Default: Fall back to the generic blt. Not an error, a TRACE is enough */
+ TRACE("Didn't find any usable render target setup for hw blit, falling back to software\n");
+ return WINED3DERR_INVALIDCALL;
+}
+
+/* Context activation is done by the caller. */
+static void surface_depth_blt(const struct wined3d_surface *surface, struct wined3d_context *context,
+ GLuint texture, GLint x, GLint y, GLsizei w, GLsizei h, GLenum target)
+{
+ struct wined3d_device *device = surface->resource.device;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ GLint compare_mode = GL_NONE;
+ struct blt_info info;
+ GLint old_binding = 0;
+ RECT rect;
+
+ gl_info->gl_ops.gl.p_glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_VIEWPORT_BIT);
+
+ gl_info->gl_ops.gl.p_glDisable(GL_CULL_FACE);
+ gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
+ gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST);
+ gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
+ gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
+ gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_TEST);
+ gl_info->gl_ops.gl.p_glDepthFunc(GL_ALWAYS);
+ gl_info->gl_ops.gl.p_glDepthMask(GL_TRUE);
+ gl_info->gl_ops.gl.p_glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+ gl_info->gl_ops.gl.p_glViewport(x, y, w, h);
+ gl_info->gl_ops.gl.p_glDepthRange(0.0, 1.0);
+
+ SetRect(&rect, 0, h, w, 0);
+ surface_get_blt_info(target, &rect, surface->pow2Width, surface->pow2Height, &info);
+ context_active_texture(context, context->gl_info, 0);
+ gl_info->gl_ops.gl.p_glGetIntegerv(info.binding, &old_binding);
+ gl_info->gl_ops.gl.p_glBindTexture(info.bind_target, texture);
+ if (gl_info->supported[ARB_SHADOW])
+ {
+ gl_info->gl_ops.gl.p_glGetTexParameteriv(info.bind_target, GL_TEXTURE_COMPARE_MODE_ARB, &compare_mode);
+ if (compare_mode != GL_NONE)
+ gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
+ }
+
+ device->shader_backend->shader_select_depth_blt(device->shader_priv,
+ gl_info, info.tex_type, &surface->ds_current_size);
+
+ gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
+ gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[0]);
+ gl_info->gl_ops.gl.p_glVertex2f(-1.0f, -1.0f);
+ gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[1]);
+ gl_info->gl_ops.gl.p_glVertex2f(1.0f, -1.0f);
+ gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[2]);
+ gl_info->gl_ops.gl.p_glVertex2f(-1.0f, 1.0f);
+ gl_info->gl_ops.gl.p_glTexCoord3fv(info.coords[3]);
+ gl_info->gl_ops.gl.p_glVertex2f(1.0f, 1.0f);
+ gl_info->gl_ops.gl.p_glEnd();
+
+ if (compare_mode != GL_NONE)
+ gl_info->gl_ops.gl.p_glTexParameteri(info.bind_target, GL_TEXTURE_COMPARE_MODE_ARB, compare_mode);
+ gl_info->gl_ops.gl.p_glBindTexture(info.bind_target, old_binding);
+
+ gl_info->gl_ops.gl.p_glPopAttrib();
+
+ device->shader_backend->shader_deselect_depth_blt(device->shader_priv, gl_info);
+}
+
+void surface_modify_ds_location(struct wined3d_surface *surface,
+ DWORD location, UINT w, UINT h)
+{
+ TRACE("surface %p, new location %#x, w %u, h %u.\n", surface, location, w, h);
+
+ if (location & ~(SFLAG_LOCATIONS | SFLAG_DISCARDED))
+ FIXME("Invalid location (%#x) specified.\n", location);
+
+ if (((surface->flags & SFLAG_INTEXTURE) && !(location & SFLAG_INTEXTURE))
+ || (!(surface->flags & SFLAG_INTEXTURE) && (location & SFLAG_INTEXTURE)))
+ {
+ if (surface->container)
+ {
+ TRACE("Passing to container.\n");
+ wined3d_texture_set_dirty(surface->container, TRUE);
+ }
+ }
+
+ surface->ds_current_size.cx = w;
+ surface->ds_current_size.cy = h;
+ surface->flags &= ~(SFLAG_LOCATIONS | SFLAG_DISCARDED);
+ surface->flags |= location;
+}
+
+/* Context activation is done by the caller. */
+void surface_load_ds_location(struct wined3d_surface *surface, struct wined3d_context *context, DWORD location)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct wined3d_device *device = surface->resource.device;
+ GLsizei w, h;
+
+ TRACE("surface %p, new location %#x.\n", surface, location);
+
+ /* TODO: Make this work for modes other than FBO */
+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return;
+
+ if (!(surface->flags & location))
+ {
+ w = surface->ds_current_size.cx;
+ h = surface->ds_current_size.cy;
+ surface->ds_current_size.cx = 0;
+ surface->ds_current_size.cy = 0;
+ }
+ else
+ {
+ w = surface->resource.width;
+ h = surface->resource.height;
+ }
+
+ if (surface->ds_current_size.cx == surface->resource.width
+ && surface->ds_current_size.cy == surface->resource.height)
+ {
+ TRACE("Location (%#x) is already up to date.\n", location);
+ return;
+ }
+
+ if (surface->current_renderbuffer)
+ {
+ FIXME("Not supported with fixed up depth stencil.\n");
+ return;
+ }
+
+ if (surface->flags & SFLAG_DISCARDED)
+ {
+ TRACE("Surface was discarded, no need copy data.\n");
+ switch (location)
+ {
+ case SFLAG_INTEXTURE:
+ surface_prepare_texture(surface, context, FALSE);
+ break;
+ case SFLAG_INRB_MULTISAMPLE:
+ surface_prepare_rb(surface, gl_info, TRUE);
+ break;
+ case SFLAG_INDRAWABLE:
+ /* Nothing to do */
+ break;
+ default:
+ FIXME("Unhandled location %#x\n", location);
+ }
+ surface->flags &= ~SFLAG_DISCARDED;
+ surface->flags |= location;
+ surface->ds_current_size.cx = surface->resource.width;
+ surface->ds_current_size.cy = surface->resource.height;
+ return;
+ }
+
+ if (!(surface->flags & SFLAG_LOCATIONS))
+ {
+ FIXME("No up to date depth stencil location.\n");
+ surface->flags |= location;
+ surface->ds_current_size.cx = surface->resource.width;
+ surface->ds_current_size.cy = surface->resource.height;
+ return;
+ }
+
+ if (location == SFLAG_INTEXTURE)
+ {
+ GLint old_binding = 0;
+ GLenum bind_target;
+
+ /* The render target is allowed to be smaller than the depth/stencil
+ * buffer, so the onscreen depth/stencil buffer is potentially smaller
+ * than the offscreen surface. Don't overwrite the offscreen surface
+ * with undefined data. */
+ w = min(w, context->swapchain->desc.backbuffer_width);
+ h = min(h, context->swapchain->desc.backbuffer_height);
+
+ TRACE("Copying onscreen depth buffer to depth texture.\n");
+
+ if (!device->depth_blt_texture)
+ gl_info->gl_ops.gl.p_glGenTextures(1, &device->depth_blt_texture);
+
+ /* Note that we use depth_blt here as well, rather than glCopyTexImage2D
+ * directly on the FBO texture. That's because we need to flip. */
+ context_apply_fbo_state_blit(context, GL_FRAMEBUFFER,
+ context->swapchain->front_buffer, NULL, SFLAG_INDRAWABLE);
+ if (surface->texture_target == GL_TEXTURE_RECTANGLE_ARB)
+ {
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
+ bind_target = GL_TEXTURE_RECTANGLE_ARB;
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding);
+ bind_target = GL_TEXTURE_2D;
+ }
+ gl_info->gl_ops.gl.p_glBindTexture(bind_target, device->depth_blt_texture);
+ /* We use GL_DEPTH_COMPONENT instead of the surface's specific
+ * internal format, because the internal format might include stencil
+ * data. In principle we should copy stencil data as well, but unless
+ * the driver supports stencil export it's hard to do, and doesn't
+ * seem to be needed in practice. If the hardware doesn't support
+ * writing stencil data, the glCopyTexImage2D() call might trigger
+ * software fallbacks. */
+ gl_info->gl_ops.gl.p_glCopyTexImage2D(bind_target, 0, GL_DEPTH_COMPONENT, 0, 0, w, h, 0);
+ gl_info->gl_ops.gl.p_glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl_info->gl_ops.gl.p_glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ gl_info->gl_ops.gl.p_glTexParameteri(bind_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl_info->gl_ops.gl.p_glTexParameteri(bind_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ gl_info->gl_ops.gl.p_glTexParameteri(bind_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+ gl_info->gl_ops.gl.p_glTexParameteri(bind_target, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
+ gl_info->gl_ops.gl.p_glBindTexture(bind_target, old_binding);
+
+ context_apply_fbo_state_blit(context, GL_FRAMEBUFFER,
+ NULL, surface, SFLAG_INTEXTURE);
+ context_set_draw_buffer(context, GL_NONE);
+
+ /* Do the actual blit */
+ surface_depth_blt(surface, context, device->depth_blt_texture, 0, 0, w, h, bind_target);
+ checkGLcall("depth_blt");
+
+ context_invalidate_state(context, STATE_FRAMEBUFFER);
+
+ if (wined3d_settings.strict_draw_ordering)
+ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
+ }
+ else if (location == SFLAG_INDRAWABLE)
+ {
+ TRACE("Copying depth texture to onscreen depth buffer.\n");
+
+ context_apply_fbo_state_blit(context, GL_FRAMEBUFFER,
+ context->swapchain->front_buffer, NULL, SFLAG_INDRAWABLE);
+ surface_depth_blt(surface, context, surface->texture_name,
+ 0, surface->pow2Height - h, w, h, surface->texture_target);
+ checkGLcall("depth_blt");
+
+ context_invalidate_state(context, STATE_FRAMEBUFFER);
+
+ if (wined3d_settings.strict_draw_ordering)
+ gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
+ }
+ else
+ {
+ ERR("Invalid location (%#x) specified.\n", location);
+ }
+
+ surface->flags |= location;
+ surface->ds_current_size.cx = surface->resource.width;
+ surface->ds_current_size.cy = surface->resource.height;
+}
+
+void surface_modify_location(struct wined3d_surface *surface, DWORD location, BOOL persistent)
+{
+ const struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info;
+ struct wined3d_surface *overlay;
+
+ TRACE("surface %p, location %s, persistent %#x.\n",
+ surface, debug_surflocation(location), persistent);
+
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && surface_is_offscreen(surface)
+ && !(surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
+ && (location & SFLAG_INDRAWABLE))
+ ERR("Trying to invalidate the SFLAG_INDRAWABLE location of an offscreen surface.\n");
+
+ if (location & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)
+ && gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
+ location |= (SFLAG_INTEXTURE | SFLAG_INSRGBTEX);
+
+ if (persistent)
+ {
+ if (((surface->flags & SFLAG_INTEXTURE) && !(location & SFLAG_INTEXTURE))
+ || ((surface->flags & SFLAG_INSRGBTEX) && !(location & SFLAG_INSRGBTEX)))
+ {
+ if (surface->container)
+ {
+ TRACE("Passing to container.\n");
+ wined3d_texture_set_dirty(surface->container, TRUE);
+ }
+ }
+
+#ifdef VBOX_WITH_WDDM
+ {
+ /* sometimes wine can call ModifyLocation(SFLAG_INTEXTURE, TRUE) for surfaces that do not yet have
+ * ogl texture backend assigned, e.g. when doing ColorFill right after surface creation
+ * to prevent wine state breakage that could occur later on in that case, we check
+ * whether tex gen is needed here and generate it accordingly */
+ if (!surface->texture_name)
+ {
+ Assert(!(surface->flags & SFLAG_INTEXTURE));
+ if (location & SFLAG_INTEXTURE)
+ {
+ Assert(0);
+// struct wined3d_context *context = NULL;
+// IWineD3DDeviceImpl *device = This->resource.device;
+// const struct wined3d_gl_info *gl_info;
+//
+// if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+// gl_info = context->gl_info;
+//
+// surface_prepare_texture(This, gl_info, FALSE);
+//
+// if (context) context_release(context);
+ }
+ }
+
+ if (!surface->texture_name_srgb)
+ {
+ Assert(!(surface->flags & SFLAG_INSRGBTEX));
+ if (location & SFLAG_INSRGBTEX)
+ {
+ Assert(0);
+// struct wined3d_context *context = NULL;
+// IWineD3DDeviceImpl *device = This->resource.device;
+// const struct wined3d_gl_info *gl_info;
+//
+// if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
+// gl_info = context->gl_info;
+//
+// surface_prepare_texture(This, gl_info, TRUE);
+//
+// if (context) context_release(context);
+ }
+ }
+ }
+#endif
+
+ surface->flags &= ~SFLAG_LOCATIONS;
+ surface->flags |= location;
+
+ /* Redraw emulated overlays, if any */
+ if (location & SFLAG_INDRAWABLE && !list_empty(&surface->overlays))
+ {
+ LIST_FOR_EACH_ENTRY(overlay, &surface->overlays, struct wined3d_surface, overlay_entry)
+ {
+ surface_draw_overlay(overlay);
+ }
+ }
+ }
+ else
+ {
+ if ((surface->flags & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)) && (location & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)))
+ {
+ if (surface->container)
+ {
+ TRACE("Passing to container\n");
+ wined3d_texture_set_dirty(surface->container, TRUE);
+ }
+ }
+ surface->flags &= ~location;
+ }
+
+#ifdef VBOX_WITH_WDDM
+ if(VBOXSHRC_IS_SHARED_UNLOCKED(surface)) {
+ /* with the shared resource only texture can be considered valid
+ * to make sure changes done to the resource in the other device context are visible
+ * because the resource contents is shared via texture.
+ * This is why we ensure texture location is the one and only which is always valid */
+ if(!(surface->flags & SFLAG_INTEXTURE)) {
+ surface_load_location(surface, SFLAG_INTEXTURE, NULL);
+ } else {
+ surface->flags &= ~SFLAG_LOCATIONS;
+ surface->flags |= SFLAG_INTEXTURE;
+ }
+ }
+ else if (surface->flags & SFLAG_CLIENTMEM)
+ {
+ if(!(surface->flags & SFLAG_INSYSMEM)) {
+ surface_load_location(surface, SFLAG_INSYSMEM, NULL);
+ } else {
+ surface->flags &= ~SFLAG_LOCATIONS;
+ surface->flags |= SFLAG_INSYSMEM;
+ }
+ }
+#endif
+
+
+ if (!(surface->flags & SFLAG_LOCATIONS))
+ {
+ ERR("Surface %p does not have any up to date location.\n", surface);
+ }
+}
+
+static DWORD resource_access_from_location(DWORD location)
+{
+ switch (location)
+ {
+ case SFLAG_INSYSMEM:
+ return WINED3D_RESOURCE_ACCESS_CPU;
+
+ case SFLAG_INDRAWABLE:
+ case SFLAG_INSRGBTEX:
+ case SFLAG_INTEXTURE:
+ case SFLAG_INRB_MULTISAMPLE:
+ case SFLAG_INRB_RESOLVED:
+ return WINED3D_RESOURCE_ACCESS_GPU;
+
+ default:
+ FIXME("Unhandled location %#x.\n", location);
+ return 0;
+ }
+}
+
+static void surface_load_sysmem(struct wined3d_surface *surface,
+ const struct wined3d_gl_info *gl_info, const RECT *rect)
+{
+ surface_prepare_system_memory(surface);
+
+ if (surface->flags & (SFLAG_INRB_MULTISAMPLE | SFLAG_INRB_RESOLVED))
+ surface_load_location(surface, SFLAG_INTEXTURE, NULL);
+
+ /* Download the surface to system memory. */
+ if (surface->flags & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX))
+ {
+ struct wined3d_device *device = surface->resource.device;
+ struct wined3d_context *context;
+
+ /* TODO: Use already acquired context when possible. */
+ context = context_acquire(device, NULL);
+
+ surface_bind_and_dirtify(surface, context, !(surface->flags & SFLAG_INTEXTURE));
+ surface_download_data(surface, gl_info);
+
+ context_release(context);
+
+ return;
+ }
+
+ if (surface->flags & SFLAG_INDRAWABLE)
+ {
+ read_from_framebuffer(surface, rect, surface->resource.allocatedMemory,
+ wined3d_surface_get_pitch(surface));
+ return;
+ }
+
+ FIXME("Can't load surface %p with location flags %#x into sysmem.\n",
+ surface, surface->flags & SFLAG_LOCATIONS);
+}
+
+static HRESULT surface_load_drawable(struct wined3d_surface *surface,
+ const struct wined3d_gl_info *gl_info, const RECT *rect)
+{
+ struct wined3d_device *device = surface->resource.device;
+ enum wined3d_conversion_type convert;
+ struct wined3d_format format;
+ UINT byte_count;
+ BYTE *mem;
+
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && surface_is_offscreen(surface))
+ {
+ ERR("Trying to load offscreen surface into SFLAG_INDRAWABLE.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (wined3d_settings.rendertargetlock_mode == RTL_READTEX)
+ surface_load_location(surface, SFLAG_INTEXTURE, NULL);
+
+ if (surface->flags & SFLAG_INTEXTURE)
+ {
+ RECT r;
+
+ surface_get_rect(surface, rect, &r);
+ surface_blt_to_drawable(device, WINED3D_TEXF_POINT, FALSE, surface, &r, surface, &r);
+
+ return WINED3D_OK;
+ }
+
+ if ((surface->flags & SFLAG_LOCATIONS) == SFLAG_INSRGBTEX)
+ {
+ /* This needs colorspace conversion from sRGB to RGB. We take the slow
+ * path through sysmem. */
+ surface_load_location(surface, SFLAG_INSYSMEM, rect);
+ }
+
+ d3dfmt_get_conv(surface, FALSE, FALSE, &format, &convert);
+
+ /* Don't use PBOs for converted surfaces. During PBO conversion we look at
+ * SFLAG_CONVERTED but it isn't set (yet) in all cases where it is getting
+ * called. */
+ if ((convert != WINED3D_CT_NONE) && (surface->flags & SFLAG_PBO))
+ {
+ struct wined3d_context *context;
+
+ TRACE("Removing the pbo attached to surface %p.\n", surface);
+
+ /* TODO: Use already acquired context when possible. */
+ context = context_acquire(device, NULL);
+
+ surface_remove_pbo(surface, gl_info);
+
+ context_release(context);
+ }
+
+ if ((convert != WINED3D_CT_NONE) && surface->resource.allocatedMemory)
+ {
+ UINT height = surface->resource.height;
+ UINT width = surface->resource.width;
+ UINT src_pitch, dst_pitch;
+
+ byte_count = format.conv_byte_count;
+ src_pitch = wined3d_surface_get_pitch(surface);
+
+ /* Stick to the alignment for the converted surface too, makes it
+ * easier to load the surface. */
+ dst_pitch = width * byte_count;
+ dst_pitch = (dst_pitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1);
+
+ if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_pitch * height)))
+ {
+ ERR("Out of memory (%u).\n", dst_pitch * height);
+ return E_OUTOFMEMORY;
+ }
+
+ d3dfmt_convert_surface(surface->resource.allocatedMemory, mem,
+ src_pitch, width, height, dst_pitch, convert, surface);
+
+ surface->flags |= SFLAG_CONVERTED;
+ }
+ else
+ {
+ surface->flags &= ~SFLAG_CONVERTED;
+ mem = surface->resource.allocatedMemory;
+ byte_count = format.byte_count;
+ }
+
+ flush_to_framebuffer_drawpixels(surface, rect, format.glFormat, format.glType, byte_count, mem);
+
+ /* Don't delete PBO memory. */
+ if ((mem != surface->resource.allocatedMemory) && !(surface->flags & SFLAG_PBO))
+ HeapFree(GetProcessHeap(), 0, mem);
+
+ return WINED3D_OK;
+}
+
+static HRESULT surface_load_texture(struct wined3d_surface *surface,
+ const struct wined3d_gl_info *gl_info, const RECT *rect, BOOL srgb)
+{
+ RECT src_rect = {0, 0, surface->resource.width, surface->resource.height};
+ struct wined3d_device *device = surface->resource.device;
+ enum wined3d_conversion_type convert;
+ struct wined3d_context *context;
+ UINT width, src_pitch, dst_pitch;
+ struct wined3d_bo_address data;
+ struct wined3d_format format;
+ POINT dst_point = {0, 0};
+ BYTE *mem;
+
+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
+ && surface_is_offscreen(surface)
+ && (surface->flags & SFLAG_INDRAWABLE))
+ {
+ surface_load_fb_texture(surface, srgb);
+
+ return WINED3D_OK;
+ }
+
+ if (surface->flags & (SFLAG_INSRGBTEX | SFLAG_INTEXTURE)
+ && (surface->resource.format->flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB)
+ && fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
+ NULL, surface->resource.usage, surface->resource.pool, surface->resource.format,
+ NULL, surface->resource.usage, surface->resource.pool, surface->resource.format))
+ {
+ if (srgb)
+ surface_blt_fbo(device, WINED3D_TEXF_POINT, surface, SFLAG_INTEXTURE,
+ &src_rect, surface, SFLAG_INSRGBTEX, &src_rect);
+ else
+ surface_blt_fbo(device, WINED3D_TEXF_POINT, surface, SFLAG_INSRGBTEX,
+ &src_rect, surface, SFLAG_INTEXTURE, &src_rect);
+
+ return WINED3D_OK;
+ }
+
+ if (surface->flags & (SFLAG_INRB_MULTISAMPLE | SFLAG_INRB_RESOLVED)
+ && (!srgb || (surface->resource.format->flags & WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB))
+ && fbo_blit_supported(gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
+ NULL, surface->resource.usage, surface->resource.pool, surface->resource.format,
+ NULL, surface->resource.usage, surface->resource.pool, surface->resource.format))
+ {
+ DWORD src_location = surface->flags & SFLAG_INRB_RESOLVED ? SFLAG_INRB_RESOLVED : SFLAG_INRB_MULTISAMPLE;
+ DWORD dst_location = srgb ? SFLAG_INSRGBTEX : SFLAG_INTEXTURE;
+ RECT rect = {0, 0, surface->resource.width, surface->resource.height};
+
+ surface_blt_fbo(device, WINED3D_TEXF_POINT, surface, src_location,
+ &rect, surface, dst_location, &rect);
+
+ return WINED3D_OK;
+ }
+
+ /* Upload from system memory */
+
+ d3dfmt_get_conv(surface, TRUE /* We need color keying */,
+ TRUE /* We will use textures */, &format, &convert);
+
+ if (srgb)
+ {
+ if ((surface->flags & (SFLAG_INTEXTURE | SFLAG_INSYSMEM)) == SFLAG_INTEXTURE)
+ {
+ /* Performance warning... */
+ FIXME("Downloading RGB surface %p to reload it as sRGB.\n", surface);
+ surface_load_location(surface, SFLAG_INSYSMEM, rect);
+ }
+ }
+ else
+ {
+ if ((surface->flags & (SFLAG_INSRGBTEX | SFLAG_INSYSMEM)) == SFLAG_INSRGBTEX)
+ {
+ /* Performance warning... */
+ FIXME("Downloading sRGB surface %p to reload it as RGB.\n", surface);
+ surface_load_location(surface, SFLAG_INSYSMEM, rect);
+ }
+ }
+
+ if (!(surface->flags & SFLAG_INSYSMEM))
+ {
+ WARN("Trying to load a texture from sysmem, but SFLAG_INSYSMEM is not set.\n");
+ /* Lets hope we get it from somewhere... */
+ surface_load_location(surface, SFLAG_INSYSMEM, rect);
+ }
+
+ /* TODO: Use already acquired context when possible. */
+ context = context_acquire(device, NULL);
+
+ surface_prepare_texture(surface, context, srgb);
+ surface_bind_and_dirtify(surface, context, srgb);
+
+ if (surface->CKeyFlags & WINEDDSD_CKSRCBLT)
+ {
+ surface->flags |= SFLAG_GLCKEY;
+ surface->gl_color_key = surface->src_blt_color_key;
+ }
+ else surface->flags &= ~SFLAG_GLCKEY;
+
+ width = surface->resource.width;
+ src_pitch = wined3d_surface_get_pitch(surface);
+
+ /* Don't use PBOs for converted surfaces. During PBO conversion we look at
+ * SFLAG_CONVERTED but it isn't set (yet) in all cases it is getting
+ * called. */
+ if ((convert != WINED3D_CT_NONE || format.convert) && (surface->flags & SFLAG_PBO))
+ {
+ TRACE("Removing the pbo attached to surface %p.\n", surface);
+ surface_remove_pbo(surface, gl_info);
+ }
+
+ if (format.convert)
+ {
+ /* This code is entered for texture formats which need a fixup. */
+ UINT height = surface->resource.height;
+
+ /* Stick to the alignment for the converted surface too, makes it easier to load the surface */
+ dst_pitch = width * format.conv_byte_count;
+ dst_pitch = (dst_pitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1);
+
+ if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_pitch * height)))
+ {
+ ERR("Out of memory (%u).\n", dst_pitch * height);
+ context_release(context);
+ return E_OUTOFMEMORY;
+ }
+ format.convert(surface->resource.allocatedMemory, mem, src_pitch, width, height);
+ format.byte_count = format.conv_byte_count;
+ src_pitch = dst_pitch;
+ }
+ else if (convert != WINED3D_CT_NONE && surface->resource.allocatedMemory)
+ {
+ /* This code is only entered for color keying fixups */
+ UINT height = surface->resource.height;
+
+ /* Stick to the alignment for the converted surface too, makes it easier to load the surface */
+ dst_pitch = width * format.conv_byte_count;
+ dst_pitch = (dst_pitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1);
+
+ if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_pitch * height)))
+ {
+ ERR("Out of memory (%u).\n", dst_pitch * height);
+ context_release(context);
+ return E_OUTOFMEMORY;
+ }
+ d3dfmt_convert_surface(surface->resource.allocatedMemory, mem, src_pitch,
+ width, height, dst_pitch, convert, surface);
+ format.byte_count = format.conv_byte_count;
+ src_pitch = dst_pitch;
+ }
+ else
+ {
+ mem = surface->resource.allocatedMemory;
+ }
+
+ data.buffer_object = surface->pbo;
+ data.addr = mem;
+ surface_upload_data(surface, gl_info, &format, &src_rect, src_pitch, &dst_point, srgb, &data);
+
+ context_release(context);
+
+ /* Don't delete PBO memory. */
+ if ((mem != surface->resource.allocatedMemory) && !(surface->flags & SFLAG_PBO))
+ HeapFree(GetProcessHeap(), 0, mem);
+
+ return WINED3D_OK;
+}
+
+static void surface_multisample_resolve(struct wined3d_surface *surface)
+{
+ RECT rect = {0, 0, surface->resource.width, surface->resource.height};
+
+ if (!(surface->flags & SFLAG_INRB_MULTISAMPLE))
+ ERR("Trying to resolve multisampled surface %p, but location SFLAG_INRB_MULTISAMPLE not current.\n", surface);
+
+ surface_blt_fbo(surface->resource.device, WINED3D_TEXF_POINT,
+ surface, SFLAG_INRB_MULTISAMPLE, &rect, surface, SFLAG_INRB_RESOLVED, &rect);
+}
+
+HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location, const RECT *rect)
+{
+ struct wined3d_device *device = surface->resource.device;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ HRESULT hr;
+
+ TRACE("surface %p, location %s, rect %s.\n", surface, debug_surflocation(location), wine_dbgstr_rect(rect));
+
+ if (surface->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
+ {
+ if (location == SFLAG_INTEXTURE && surface->flags & SFLAG_INDRAWABLE)
+ {
+ struct wined3d_context *context = context_acquire(device, NULL);
+ surface_load_ds_location(surface, context, location);
+ context_release(context);
+#ifndef VBOX_WITH_WDDM
+ return WINED3D_OK;
+#else
+ goto post_process;
+#endif
+ }
+ else if (location & surface->flags && surface->draw_binding != SFLAG_INDRAWABLE)
+ {
+ /* Already up to date, nothing to do. */
+#ifndef VBOX_WITH_WDDM
+ return WINED3D_OK;
+#else
+ goto post_process;
+#endif
+ }
+ else
+ {
+ FIXME("Unimplemented copy from %s to %s for depth/stencil buffers.\n",
+ debug_surflocation(surface->flags & SFLAG_LOCATIONS), debug_surflocation(location));
+ return WINED3DERR_INVALIDCALL;
+ }
+ }
+
+ if (location == SFLAG_INSRGBTEX && gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
+ location = SFLAG_INTEXTURE;
+
+ if (surface->flags & location)
+ {
+ TRACE("Location already up to date.\n");
+
+ if (location == SFLAG_INSYSMEM && !(surface->flags & SFLAG_PBO)
+ && surface_need_pbo(surface, gl_info))
+ surface_load_pbo(surface, gl_info);
+
+#ifndef VBOX_WITH_WDDM
+ return WINED3D_OK;
+#else
+ goto post_process;
+#endif
+ }
+
+ if (WARN_ON(d3d_surface))
+ {
+ DWORD required_access = resource_access_from_location(location);
+ if ((surface->resource.access_flags & required_access) != required_access)
+ WARN("Operation requires %#x access, but surface only has %#x.\n",
+ required_access, surface->resource.access_flags);
+ }
+
+ if (!(surface->flags & SFLAG_LOCATIONS))
+ {
+ ERR("Surface %p does not have any up to date location.\n", surface);
+ surface->flags |= SFLAG_LOST;
+ return WINED3DERR_DEVICELOST;
+ }
+
+ switch (location)
+ {
+ case SFLAG_INSYSMEM:
+ surface_load_sysmem(surface, gl_info, rect);
+ break;
+
+ case SFLAG_INDRAWABLE:
+ if (FAILED(hr = surface_load_drawable(surface, gl_info, rect)))
+ return hr;
+ break;
+
+ case SFLAG_INRB_RESOLVED:
+ surface_multisample_resolve(surface);
+ break;
+
+ case SFLAG_INTEXTURE:
+ case SFLAG_INSRGBTEX:
+ if (FAILED(hr = surface_load_texture(surface, gl_info, rect, location == SFLAG_INSRGBTEX)))
+ return hr;
+ break;
+
+ default:
+ ERR("Don't know how to handle location %#x.\n", location);
+ break;
+ }
+
+#ifdef VBOX_WITH_WDDM
+post_process:
+
+ if (VBOXSHRC_IS_SHARED_UNLOCKED(surface))
+ {
+ /* with the shared resource only texture can be considered valid
+ * to make sure changes done to the resource in the other device context are visible
+ * because the resource contents is shared via texture.
+ * One can load and use other locations as needed,
+ * but they should be reloaded each time on each usage */
+ Assert(!!(surface->flags & SFLAG_INTEXTURE) || !!(location & SFLAG_INTEXTURE));
+ surface->flags &= ~SFLAG_LOCATIONS;
+ surface->flags |= SFLAG_INTEXTURE;
+ /* @todo: SFLAG_INSRGBTEX ?? */
+// if (in_fbo)
+// {
+// surface->flags |= SFLAG_INDRAWABLE;
+// }
+ }
+ else if (surface->flags & SFLAG_CLIENTMEM)
+ {
+ Assert(!!(surface->flags & SFLAG_INSYSMEM));
+ surface->flags &= ~SFLAG_LOCATIONS;
+ surface->flags |= SFLAG_INSYSMEM;
+ }
+ else
+#endif
+ {
+ if (!rect)
+ {
+ surface->flags |= location;
+
+ if (location != SFLAG_INSYSMEM && (surface->flags & SFLAG_INSYSMEM))
+ surface_evict_sysmem(surface);
+ }
+
+ if (surface->flags & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)
+ && gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
+ {
+ surface->flags |= (SFLAG_INTEXTURE | SFLAG_INSRGBTEX);
+ }
+ }
+
+ return WINED3D_OK;
+}
+
+BOOL surface_is_offscreen(const struct wined3d_surface *surface)
+{
+ struct wined3d_swapchain *swapchain;
+
+ /* Not on a swapchain - must be offscreen */
+ if (!(swapchain = surface->swapchain))
+ return TRUE;
+
+ /* The front buffer is always onscreen */
+ if (surface == swapchain->front_buffer) return FALSE;
+
+ /* If the swapchain is rendered to an FBO, the backbuffer is
+ * offscreen, otherwise onscreen */
+ return swapchain->render_to_fbo;
+}
+
+static HRESULT ffp_blit_alloc(struct wined3d_device *device) { return WINED3D_OK; }
+/* Context activation is done by the caller. */
+static void ffp_blit_free(struct wined3d_device *device) { }
+
+/* This function is used in case of 8bit paletted textures using GL_EXT_paletted_texture */
+/* Context activation is done by the caller. */
+static void ffp_blit_p8_upload_palette(const struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info)
+{
+ BYTE table[256][4];
+ BOOL colorkey_active = (surface->CKeyFlags & WINEDDSD_CKSRCBLT) != 0;
+ GLenum target;
+
+ if (surface->container)
+ target = surface->container->target;
+ else
+ target = surface->texture_target;
+
+ d3dfmt_p8_init_palette(surface, table, colorkey_active);
+
+ TRACE("Using GL_EXT_PALETTED_TEXTURE for 8-bit paletted texture support\n");
+ GL_EXTCALL(glColorTableEXT(target, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, table));
+}
+
+/* Context activation is done by the caller. */
+static HRESULT ffp_blit_set(void *blit_priv, struct wined3d_context *context, const struct wined3d_surface *surface)
+{
+ enum complex_fixup fixup = get_complex_fixup(surface->resource.format->color_fixup);
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ GLenum target;
+
+ if (surface->container)
+ target = surface->container->target;
+ else
+ target = surface->texture_target;
+
+ /* When EXT_PALETTED_TEXTURE is around, palette conversion is done by the GPU
+ * else the surface is converted in software at upload time in LoadLocation.
+ */
+ if (!(surface->flags & SFLAG_CONVERTED) && fixup == COMPLEX_FIXUP_P8
+ && gl_info->supported[EXT_PALETTED_TEXTURE])
+ ffp_blit_p8_upload_palette(surface, gl_info);
+
+ gl_info->gl_ops.gl.p_glEnable(target);
+ checkGLcall("glEnable(target)");
+ return WINED3D_OK;
+}
+
+/* Context activation is done by the caller. */
+static void ffp_blit_unset(const struct wined3d_gl_info *gl_info)
+{
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
+ checkGLcall("glDisable(GL_TEXTURE_2D)");
+ if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+ checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
+ }
+ if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
+ checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
+ }
+}
+
+static BOOL ffp_blit_supported(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
+ const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
+ const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
+{
+ enum complex_fixup src_fixup;
+
+ switch (blit_op)
+ {
+ case WINED3D_BLIT_OP_COLOR_BLIT:
+ if (src_pool == WINED3D_POOL_SYSTEM_MEM || dst_pool == WINED3D_POOL_SYSTEM_MEM)
+ return FALSE;
+
+ src_fixup = get_complex_fixup(src_format->color_fixup);
+ if (TRACE_ON(d3d_surface) && TRACE_ON(d3d))
+ {
+ TRACE("Checking support for fixup:\n");
+ dump_color_fixup_desc(src_format->color_fixup);
+ }
+
+ if (!is_identity_fixup(dst_format->color_fixup))
+ {
+ TRACE("Destination fixups are not supported\n");
+ return FALSE;
+ }
+
+ if (src_fixup == COMPLEX_FIXUP_P8 && gl_info->supported[EXT_PALETTED_TEXTURE])
+ {
+ TRACE("P8 fixup supported\n");
+ return TRUE;
+ }
+
+ /* We only support identity conversions. */
+ if (is_identity_fixup(src_format->color_fixup))
+ {
+ TRACE("[OK]\n");
+ return TRUE;
+ }
+
+ TRACE("[FAILED]\n");
+ return FALSE;
+
+ case WINED3D_BLIT_OP_COLOR_FILL:
+ if (dst_pool == WINED3D_POOL_SYSTEM_MEM)
+ return FALSE;
+
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ if (!((dst_format->flags & WINED3DFMT_FLAG_FBO_ATTACHABLE) || (dst_usage & WINED3DUSAGE_RENDERTARGET)))
+ return FALSE;
+ }
+ else if (!(dst_usage & WINED3DUSAGE_RENDERTARGET))
+ {
+ TRACE("Color fill not supported\n");
+ return FALSE;
+ }
+
+ /* FIXME: We should reject color fills on formats with fixups,
+ * but this would break P8 color fills for example. */
+
+ return TRUE;
+
+ case WINED3D_BLIT_OP_DEPTH_FILL:
+ return TRUE;
+
+ default:
+ TRACE("Unsupported blit_op=%d\n", blit_op);
+ return FALSE;
+ }
+}
+
+/* Do not call while under the GL lock. */
+static HRESULT ffp_blit_color_fill(struct wined3d_device *device, struct wined3d_surface *dst_surface,
+ const RECT *dst_rect, const struct wined3d_color *color)
+{
+ const RECT draw_rect = {0, 0, dst_surface->resource.width, dst_surface->resource.height};
+ struct wined3d_fb_state fb = {&dst_surface, NULL};
+
+ device_clear_render_targets(device, 1, &fb, 1, dst_rect, &draw_rect, WINED3DCLEAR_TARGET, color, 0.0f, 0);
+
+ return WINED3D_OK;
+}
+
+/* Do not call while under the GL lock. */
+static HRESULT ffp_blit_depth_fill(struct wined3d_device *device,
+ struct wined3d_surface *surface, const RECT *rect, float depth)
+{
+ const RECT draw_rect = {0, 0, surface->resource.width, surface->resource.height};
+ struct wined3d_fb_state fb = {NULL, surface};
+
+ device_clear_render_targets(device, 0, &fb, 1, rect, &draw_rect, WINED3DCLEAR_ZBUFFER, 0, depth, 0);
+
+ return WINED3D_OK;
+}
+
+const struct blit_shader ffp_blit = {
+ ffp_blit_alloc,
+ ffp_blit_free,
+ ffp_blit_set,
+ ffp_blit_unset,
+ ffp_blit_supported,
+ ffp_blit_color_fill,
+ ffp_blit_depth_fill,
+};
+
+static HRESULT cpu_blit_alloc(struct wined3d_device *device)
+{
+ return WINED3D_OK;
+}
+
+/* Context activation is done by the caller. */
+static void cpu_blit_free(struct wined3d_device *device)
+{
+}
+
+/* Context activation is done by the caller. */
+static HRESULT cpu_blit_set(void *blit_priv, struct wined3d_context *context, const struct wined3d_surface *surface)
+{
+ return WINED3D_OK;
+}
+
+/* Context activation is done by the caller. */
+static void cpu_blit_unset(const struct wined3d_gl_info *gl_info)
+{
+}
+
+static BOOL cpu_blit_supported(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
+ const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
+ const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
+{
+ if (blit_op == WINED3D_BLIT_OP_COLOR_FILL)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static HRESULT surface_cpu_blt_compressed(const BYTE *src_data, BYTE *dst_data,
+ UINT src_pitch, UINT dst_pitch, UINT update_w, UINT update_h,
+ const struct wined3d_format *format, DWORD flags, const WINEDDBLTFX *fx)
+{
+ UINT row_block_count;
+ const BYTE *src_row;
+ BYTE *dst_row;
+ UINT x, y;
+
+ src_row = src_data;
+ dst_row = dst_data;
+
+ row_block_count = (update_w + format->block_width - 1) / format->block_width;
+
+ if (!flags)
+ {
+ for (y = 0; y < update_h; y += format->block_height)
+ {
+ memcpy(dst_row, src_row, row_block_count * format->block_byte_count);
+ src_row += src_pitch;
+ dst_row += dst_pitch;
+ }
+
+ return WINED3D_OK;
+ }
+
+ if (flags == WINEDDBLT_DDFX && fx->dwDDFX == WINEDDBLTFX_MIRRORUPDOWN)
+ {
+ src_row += (((update_h / format->block_height) - 1) * src_pitch);
+
+ switch (format->id)
+ {
+ case WINED3DFMT_DXT1:
+ for (y = 0; y < update_h; y += format->block_height)
+ {
+ struct block
+ {
+ WORD color[2];
+ BYTE control_row[4];
+ };
+
+ const struct block *s = (const struct block *)src_row;
+ struct block *d = (struct block *)dst_row;
+
+ for (x = 0; x < row_block_count; ++x)
+ {
+ d[x].color[0] = s[x].color[0];
+ d[x].color[1] = s[x].color[1];
+ d[x].control_row[0] = s[x].control_row[3];
+ d[x].control_row[1] = s[x].control_row[2];
+ d[x].control_row[2] = s[x].control_row[1];
+ d[x].control_row[3] = s[x].control_row[0];
+ }
+ src_row -= src_pitch;
+ dst_row += dst_pitch;
+ }
+ return WINED3D_OK;
+
+ case WINED3DFMT_DXT3:
+ for (y = 0; y < update_h; y += format->block_height)
+ {
+ struct block
+ {
+ WORD alpha_row[4];
+ WORD color[2];
+ BYTE control_row[4];
+ };
+
+ const struct block *s = (const struct block *)src_row;
+ struct block *d = (struct block *)dst_row;
+
+ for (x = 0; x < row_block_count; ++x)
+ {
+ d[x].alpha_row[0] = s[x].alpha_row[3];
+ d[x].alpha_row[1] = s[x].alpha_row[2];
+ d[x].alpha_row[2] = s[x].alpha_row[1];
+ d[x].alpha_row[3] = s[x].alpha_row[0];
+ d[x].color[0] = s[x].color[0];
+ d[x].color[1] = s[x].color[1];
+ d[x].control_row[0] = s[x].control_row[3];
+ d[x].control_row[1] = s[x].control_row[2];
+ d[x].control_row[2] = s[x].control_row[1];
+ d[x].control_row[3] = s[x].control_row[0];
+ }
+ src_row -= src_pitch;
+ dst_row += dst_pitch;
+ }
+ return WINED3D_OK;
+
+ default:
+ FIXME("Compressed flip not implemented for format %s.\n",
+ debug_d3dformat(format->id));
+ return E_NOTIMPL;
+ }
+ }
+
+ FIXME("Unsupported blit on compressed surface (format %s, flags %#x, DDFX %#x).\n",
+ debug_d3dformat(format->id), flags, flags & WINEDDBLT_DDFX ? fx->dwDDFX : 0);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect,
+ struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags,
+ const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter)
+{
+ int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
+ const struct wined3d_format *src_format, *dst_format;
+ struct wined3d_surface *orig_src = src_surface;
+ struct wined3d_map_desc dst_map, src_map;
+ const BYTE *sbase = NULL;
+ HRESULT hr = WINED3D_OK;
+ const BYTE *sbuf;
+ BYTE *dbuf;
+ int x, y;
+
+ TRACE("dst_surface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p, filter %s.\n",
+ dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect),
+ flags, fx, debug_d3dtexturefiltertype(filter));
+
+ if (src_surface == dst_surface)
+ {
+ wined3d_surface_map(dst_surface, &dst_map, NULL, 0);
+ src_map = dst_map;
+ src_format = dst_surface->resource.format;
+ dst_format = src_format;
+ }
+ else
+ {
+ dst_format = dst_surface->resource.format;
+ if (src_surface)
+ {
+ if (dst_surface->resource.format->id != src_surface->resource.format->id)
+ {
+ src_surface = surface_convert_format(src_surface, dst_format->id);
+ if (!src_surface)
+ {
+ /* The conv function writes a FIXME */
+ WARN("Cannot convert source surface format to dest format.\n");
+ goto release;
+ }
+ }
+ wined3d_surface_map(src_surface, &src_map, NULL, WINED3D_MAP_READONLY);
+ src_format = src_surface->resource.format;
+ }
+ else
+ {
+ src_format = dst_format;
+ }
+
+ wined3d_surface_map(dst_surface, &dst_map, dst_rect, 0);
+ }
+
+ bpp = dst_surface->resource.format->byte_count;
+ srcheight = src_rect->bottom - src_rect->top;
+ srcwidth = src_rect->right - src_rect->left;
+ dstheight = dst_rect->bottom - dst_rect->top;
+ dstwidth = dst_rect->right - dst_rect->left;
+ width = (dst_rect->right - dst_rect->left) * bpp;
+
+ if (src_surface)
+ sbase = (BYTE *)src_map.data
+ + ((src_rect->top / src_format->block_height) * src_map.row_pitch)
+ + ((src_rect->left / src_format->block_width) * src_format->block_byte_count);
+ if (src_surface != dst_surface)
+ dbuf = dst_map.data;
+ else
+ dbuf = (BYTE *)dst_map.data
+ + ((dst_rect->top / dst_format->block_height) * dst_map.row_pitch)
+ + ((dst_rect->left / dst_format->block_width) * dst_format->block_byte_count);
+
+ if (src_format->flags & dst_format->flags & WINED3DFMT_FLAG_BLOCKS)
+ {
+ TRACE("%s -> %s copy.\n", debug_d3dformat(src_format->id), debug_d3dformat(dst_format->id));
+
+ if (src_surface == dst_surface)
+ {
+ FIXME("Only plain blits supported on compressed surfaces.\n");
+ hr = E_NOTIMPL;
+ goto release;
+ }
+
+ if (srcheight != dstheight || srcwidth != dstwidth)
+ {
+ WARN("Stretching not supported on compressed surfaces.\n");
+ hr = WINED3DERR_INVALIDCALL;
+ goto release;
+ }
+
+ if (!surface_check_block_align(src_surface, src_rect))
+ {
+ WARN("Source rectangle not block-aligned.\n");
+ hr = WINED3DERR_INVALIDCALL;
+ goto release;
+ }
+
+ if (!surface_check_block_align(dst_surface, dst_rect))
+ {
+ WARN("Destination rectangle not block-aligned.\n");
+ hr = WINED3DERR_INVALIDCALL;
+ goto release;
+ }
+
+ hr = surface_cpu_blt_compressed(sbase, dbuf,
+ src_map.row_pitch, dst_map.row_pitch, dstwidth, dstheight,
+ src_format, flags, fx);
+ goto release;
+ }
+
+ /* First, all the 'source-less' blits */
+ if (flags & WINEDDBLT_COLORFILL)
+ {
+ hr = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, dst_map.row_pitch, fx->u5.dwFillColor);
+ flags &= ~WINEDDBLT_COLORFILL;
+ }
+
+ if (flags & WINEDDBLT_DEPTHFILL)
+ {
+ FIXME("DDBLT_DEPTHFILL needs to be implemented!\n");
+ }
+ if (flags & WINEDDBLT_ROP)
+ {
+ /* Catch some degenerate cases here. */
+ switch (fx->dwROP)
+ {
+ case BLACKNESS:
+ hr = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, dst_map.row_pitch, 0);
+ break;
+ case 0xaa0029: /* No-op */
+ break;
+ case WHITENESS:
+ hr = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, dst_map.row_pitch, ~0U);
+ break;
+ case SRCCOPY: /* Well, we do that below? */
+ break;
+ default:
+ FIXME("Unsupported raster op: %08x Pattern: %p\n", fx->dwROP, fx->u5.lpDDSPattern);
+ goto error;
+ }
+ flags &= ~WINEDDBLT_ROP;
+ }
+ if (flags & WINEDDBLT_DDROPS)
+ {
+ FIXME("\tDdraw Raster Ops: %08x Pattern: %p\n", fx->dwDDROP, fx->u5.lpDDSPattern);
+ }
+ /* Now the 'with source' blits. */
+ if (src_surface)
+ {
+ int sx, xinc, sy, yinc;
+
+ if (!dstwidth || !dstheight) /* Hmm... stupid program? */
+ goto release;
+
+ if (filter != WINED3D_TEXF_NONE && filter != WINED3D_TEXF_POINT
+ && (srcwidth != dstwidth || srcheight != dstheight))
+ {
+ /* Can happen when d3d9 apps do a StretchRect() call which isn't handled in GL. */
+ FIXME("Filter %s not supported in software blit.\n", debug_d3dtexturefiltertype(filter));
+ }
+
+ xinc = (srcwidth << 16) / dstwidth;
+ yinc = (srcheight << 16) / dstheight;
+
+ if (!flags)
+ {
+ /* No effects, we can cheat here. */
+ if (dstwidth == srcwidth)
+ {
+ if (dstheight == srcheight)
+ {
+ /* No stretching in either direction. This needs to be as
+ * fast as possible. */
+ sbuf = sbase;
+
+ /* Check for overlapping surfaces. */
+ if (src_surface != dst_surface || dst_rect->top < src_rect->top
+ || dst_rect->right <= src_rect->left || src_rect->right <= dst_rect->left)
+ {
+ /* No overlap, or dst above src, so copy from top downwards. */
+ for (y = 0; y < dstheight; ++y)
+ {
+ memcpy(dbuf, sbuf, width);
+ sbuf += src_map.row_pitch;
+ dbuf += dst_map.row_pitch;
+ }
+ }
+ else if (dst_rect->top > src_rect->top)
+ {
+ /* Copy from bottom upwards. */
+ sbuf += src_map.row_pitch * dstheight;
+ dbuf += dst_map.row_pitch * dstheight;
+ for (y = 0; y < dstheight; ++y)
+ {
+ sbuf -= src_map.row_pitch;
+ dbuf -= dst_map.row_pitch;
+ memcpy(dbuf, sbuf, width);
+ }
+ }
+ else
+ {
+ /* Src and dst overlapping on the same line, use memmove. */
+ for (y = 0; y < dstheight; ++y)
+ {
+ memmove(dbuf, sbuf, width);
+ sbuf += src_map.row_pitch;
+ dbuf += dst_map.row_pitch;
+ }
+ }
+ }
+ else
+ {
+ /* Stretching in y direction only. */
+ for (y = sy = 0; y < dstheight; ++y, sy += yinc)
+ {
+ sbuf = sbase + (sy >> 16) * src_map.row_pitch;
+ memcpy(dbuf, sbuf, width);
+ dbuf += dst_map.row_pitch;
+ }
+ }
+ }
+ else
+ {
+ /* Stretching in X direction. */
+ int last_sy = -1;
+ for (y = sy = 0; y < dstheight; ++y, sy += yinc)
+ {
+ sbuf = sbase + (sy >> 16) * src_map.row_pitch;
+
+ if ((sy >> 16) == (last_sy >> 16))
+ {
+ /* This source row is the same as last source row -
+ * Copy the already stretched row. */
+ memcpy(dbuf, dbuf - dst_map.row_pitch, width);
+ }
+ else
+ {
+#define STRETCH_ROW(type) \
+do { \
+ const type *s = (const type *)sbuf; \
+ type *d = (type *)dbuf; \
+ for (x = sx = 0; x < dstwidth; ++x, sx += xinc) \
+ d[x] = s[sx >> 16]; \
+} while(0)
+
+ switch(bpp)
+ {
+ case 1:
+ STRETCH_ROW(BYTE);
+ break;
+ case 2:
+ STRETCH_ROW(WORD);
+ break;
+ case 4:
+ STRETCH_ROW(DWORD);
+ break;
+ case 3:
+ {
+ const BYTE *s;
+ BYTE *d = dbuf;
+ for (x = sx = 0; x < dstwidth; x++, sx+= xinc)
+ {
+ DWORD pixel;
+
+ s = sbuf + 3 * (sx >> 16);
+ pixel = s[0] | (s[1] << 8) | (s[2] << 16);
+ d[0] = (pixel ) & 0xff;
+ d[1] = (pixel >> 8) & 0xff;
+ d[2] = (pixel >> 16) & 0xff;
+ d += 3;
+ }
+ break;
+ }
+ default:
+ FIXME("Stretched blit not implemented for bpp %u!\n", bpp * 8);
+ hr = WINED3DERR_NOTAVAILABLE;
+ goto error;
+ }
+#undef STRETCH_ROW
+ }
+ dbuf += dst_map.row_pitch;
+ last_sy = sy;
+ }
+ }
+ }
+ else
+ {
+ LONG dstyinc = dst_map.row_pitch, dstxinc = bpp;
+ DWORD keylow = 0xffffffff, keyhigh = 0, keymask = 0xffffffff;
+ DWORD destkeylow = 0x0, destkeyhigh = 0xffffffff, destkeymask = 0xffffffff;
+ if (flags & (WINEDDBLT_KEYSRC | WINEDDBLT_KEYDEST | WINEDDBLT_KEYSRCOVERRIDE | WINEDDBLT_KEYDESTOVERRIDE))
+ {
+ /* The color keying flags are checked for correctness in ddraw */
+ if (flags & WINEDDBLT_KEYSRC)
+ {
+ keylow = src_surface->src_blt_color_key.color_space_low_value;
+ keyhigh = src_surface->src_blt_color_key.color_space_high_value;
+ }
+ else if (flags & WINEDDBLT_KEYSRCOVERRIDE)
+ {
+ keylow = fx->ddckSrcColorkey.color_space_low_value;
+ keyhigh = fx->ddckSrcColorkey.color_space_high_value;
+ }
+
+ if (flags & WINEDDBLT_KEYDEST)
+ {
+ /* Destination color keys are taken from the source surface! */
+ destkeylow = src_surface->dst_blt_color_key.color_space_low_value;
+ destkeyhigh = src_surface->dst_blt_color_key.color_space_high_value;
+ }
+ else if (flags & WINEDDBLT_KEYDESTOVERRIDE)
+ {
+ destkeylow = fx->ddckDestColorkey.color_space_low_value;
+ destkeyhigh = fx->ddckDestColorkey.color_space_high_value;
+ }
+
+ if (bpp == 1)
+ {
+ keymask = 0xff;
+ }
+ else
+ {
+ DWORD masks[3];
+ get_color_masks(src_format, masks);
+ keymask = masks[0]
+ | masks[1]
+ | masks[2];
+ }
+ flags &= ~(WINEDDBLT_KEYSRC | WINEDDBLT_KEYDEST | WINEDDBLT_KEYSRCOVERRIDE | WINEDDBLT_KEYDESTOVERRIDE);
+ }
+
+ if (flags & WINEDDBLT_DDFX)
+ {
+ BYTE *dTopLeft, *dTopRight, *dBottomLeft, *dBottomRight, *tmp;
+ LONG tmpxy;
+ dTopLeft = dbuf;
+ dTopRight = dbuf + ((dstwidth - 1) * bpp);
+ dBottomLeft = dTopLeft + ((dstheight - 1) * dst_map.row_pitch);
+ dBottomRight = dBottomLeft + ((dstwidth - 1) * bpp);
+
+ if (fx->dwDDFX & WINEDDBLTFX_ARITHSTRETCHY)
+ {
+ /* I don't think we need to do anything about this flag */
+ WARN("flags=DDBLT_DDFX nothing done for WINEDDBLTFX_ARITHSTRETCHY\n");
+ }
+ if (fx->dwDDFX & WINEDDBLTFX_MIRRORLEFTRIGHT)
+ {
+ tmp = dTopRight;
+ dTopRight = dTopLeft;
+ dTopLeft = tmp;
+ tmp = dBottomRight;
+ dBottomRight = dBottomLeft;
+ dBottomLeft = tmp;
+ dstxinc = dstxinc * -1;
+ }
+ if (fx->dwDDFX & WINEDDBLTFX_MIRRORUPDOWN)
+ {
+ tmp = dTopLeft;
+ dTopLeft = dBottomLeft;
+ dBottomLeft = tmp;
+ tmp = dTopRight;
+ dTopRight = dBottomRight;
+ dBottomRight = tmp;
+ dstyinc = dstyinc * -1;
+ }
+ if (fx->dwDDFX & WINEDDBLTFX_NOTEARING)
+ {
+ /* I don't think we need to do anything about this flag */
+ WARN("flags=DDBLT_DDFX nothing done for WINEDDBLTFX_NOTEARING\n");
+ }
+ if (fx->dwDDFX & WINEDDBLTFX_ROTATE180)
+ {
+ tmp = dBottomRight;
+ dBottomRight = dTopLeft;
+ dTopLeft = tmp;
+ tmp = dBottomLeft;
+ dBottomLeft = dTopRight;
+ dTopRight = tmp;
+ dstxinc = dstxinc * -1;
+ dstyinc = dstyinc * -1;
+ }
+ if (fx->dwDDFX & WINEDDBLTFX_ROTATE270)
+ {
+ tmp = dTopLeft;
+ dTopLeft = dBottomLeft;
+ dBottomLeft = dBottomRight;
+ dBottomRight = dTopRight;
+ dTopRight = tmp;
+ tmpxy = dstxinc;
+ dstxinc = dstyinc;
+ dstyinc = tmpxy;
+ dstxinc = dstxinc * -1;
+ }
+ if (fx->dwDDFX & WINEDDBLTFX_ROTATE90)
+ {
+ tmp = dTopLeft;
+ dTopLeft = dTopRight;
+ dTopRight = dBottomRight;
+ dBottomRight = dBottomLeft;
+ dBottomLeft = tmp;
+ tmpxy = dstxinc;
+ dstxinc = dstyinc;
+ dstyinc = tmpxy;
+ dstyinc = dstyinc * -1;
+ }
+ if (fx->dwDDFX & WINEDDBLTFX_ZBUFFERBASEDEST)
+ {
+ /* I don't think we need to do anything about this flag */
+ WARN("flags=WINEDDBLT_DDFX nothing done for WINEDDBLTFX_ZBUFFERBASEDEST\n");
+ }
+ dbuf = dTopLeft;
+ flags &= ~(WINEDDBLT_DDFX);
+ }
+
+#define COPY_COLORKEY_FX(type) \
+do { \
+ const type *s; \
+ type *d = (type *)dbuf, *dx, tmp; \
+ for (y = sy = 0; y < dstheight; ++y, sy += yinc) \
+ { \
+ s = (const type *)(sbase + (sy >> 16) * src_map.row_pitch); \
+ dx = d; \
+ for (x = sx = 0; x < dstwidth; ++x, sx += xinc) \
+ { \
+ tmp = s[sx >> 16]; \
+ if (((tmp & keymask) < keylow || (tmp & keymask) > keyhigh) \
+ && ((dx[0] & destkeymask) >= destkeylow && (dx[0] & destkeymask) <= destkeyhigh)) \
+ { \
+ dx[0] = tmp; \
+ } \
+ dx = (type *)(((BYTE *)dx) + dstxinc); \
+ } \
+ d = (type *)(((BYTE *)d) + dstyinc); \
+ } \
+} while(0)
+
+ switch (bpp)
+ {
+ case 1:
+ COPY_COLORKEY_FX(BYTE);
+ break;
+ case 2:
+ COPY_COLORKEY_FX(WORD);
+ break;
+ case 4:
+ COPY_COLORKEY_FX(DWORD);
+ break;
+ case 3:
+ {
+ const BYTE *s;
+ BYTE *d = dbuf, *dx;
+ for (y = sy = 0; y < dstheight; ++y, sy += yinc)
+ {
+ sbuf = sbase + (sy >> 16) * src_map.row_pitch;
+ dx = d;
+ for (x = sx = 0; x < dstwidth; ++x, sx+= xinc)
+ {
+ DWORD pixel, dpixel = 0;
+ s = sbuf + 3 * (sx>>16);
+ pixel = s[0] | (s[1] << 8) | (s[2] << 16);
+ dpixel = dx[0] | (dx[1] << 8 ) | (dx[2] << 16);
+ if (((pixel & keymask) < keylow || (pixel & keymask) > keyhigh)
+ && ((dpixel & keymask) >= destkeylow || (dpixel & keymask) <= keyhigh))
+ {
+ dx[0] = (pixel ) & 0xff;
+ dx[1] = (pixel >> 8) & 0xff;
+ dx[2] = (pixel >> 16) & 0xff;
+ }
+ dx += dstxinc;
+ }
+ d += dstyinc;
+ }
+ break;
+ }
+ default:
+ FIXME("%s color-keyed blit not implemented for bpp %u!\n",
+ (flags & WINEDDBLT_KEYSRC) ? "Source" : "Destination", bpp * 8);
+ hr = WINED3DERR_NOTAVAILABLE;
+ goto error;
+#undef COPY_COLORKEY_FX
+ }
+ }
+ }
+
+error:
+ if (flags && FIXME_ON(d3d_surface))
+ {
+ FIXME("\tUnsupported flags: %#x.\n", flags);
+ }
+
+release:
+ wined3d_surface_unmap(dst_surface);
+ if (src_surface && src_surface != dst_surface)
+ wined3d_surface_unmap(src_surface);
+ /* Release the converted surface, if any. */
+ if (src_surface && src_surface != orig_src)
+ wined3d_surface_decref(src_surface);
+
+ return hr;
+}
+
+/* Do not call while under the GL lock. */
+static HRESULT cpu_blit_color_fill(struct wined3d_device *device, struct wined3d_surface *dst_surface,
+ const RECT *dst_rect, const struct wined3d_color *color)
+{
+ static const RECT src_rect;
+ WINEDDBLTFX BltFx;
+
+ memset(&BltFx, 0, sizeof(BltFx));
+ BltFx.dwSize = sizeof(BltFx);
+ BltFx.u5.dwFillColor = wined3d_format_convert_from_float(dst_surface, color);
+ return surface_cpu_blt(dst_surface, dst_rect, NULL, &src_rect,
+ WINEDDBLT_COLORFILL, &BltFx, WINED3D_TEXF_POINT);
+}
+
+/* Do not call while under the GL lock. */
+static HRESULT cpu_blit_depth_fill(struct wined3d_device *device,
+ struct wined3d_surface *surface, const RECT *rect, float depth)
+{
+ FIXME("Depth filling not implemented by cpu_blit.\n");
+ return WINED3DERR_INVALIDCALL;
+}
+
+const struct blit_shader cpu_blit = {
+ cpu_blit_alloc,
+ cpu_blit_free,
+ cpu_blit_set,
+ cpu_blit_unset,
+ cpu_blit_supported,
+ cpu_blit_color_fill,
+ cpu_blit_depth_fill,
+};
+
+static HRESULT surface_init(struct wined3d_surface *surface, UINT alignment, UINT width, UINT height,
+ enum wined3d_multisample_type multisample_type, UINT multisample_quality,
+ struct wined3d_device *device, DWORD usage, enum wined3d_format_id format_id,
+ enum wined3d_pool pool, DWORD flags, void *parent, const struct wined3d_parent_ops *parent_ops
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void *pvClientMem
+#endif
+ )
+{
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ const struct wined3d_format *format = wined3d_get_format(gl_info, format_id);
+ BOOL lockable = flags & WINED3D_SURFACE_MAPPABLE;
+ unsigned int resource_size;
+ HRESULT hr;
+
+ if (multisample_quality > 0)
+ {
+ FIXME("multisample_quality set to %u, substituting 0.\n", multisample_quality);
+ multisample_quality = 0;
+ }
+
+ /* Quick lockable sanity check.
+ * TODO: remove this after surfaces, usage and lockability have been debugged properly
+ * this function is too deep to need to care about things like this.
+ * Levels need to be checked too, since they all affect what can be done. */
+ switch (pool)
+ {
+ case WINED3D_POOL_SCRATCH:
+ if (!lockable)
+ {
+ FIXME("Called with a pool of SCRATCH and a lockable of FALSE "
+ "which are mutually exclusive, setting lockable to TRUE.\n");
+ lockable = TRUE;
+ }
+ break;
+
+ case WINED3D_POOL_SYSTEM_MEM:
+ if (!lockable)
+ FIXME("Called with a pool of SYSTEMMEM and a lockable of FALSE, this is acceptable but unexpected.\n");
+ break;
+
+ case WINED3D_POOL_MANAGED:
+ if (usage & WINED3DUSAGE_DYNAMIC)
+ FIXME("Called with a pool of MANAGED and a usage of DYNAMIC which are mutually exclusive.\n");
+ break;
+
+ case WINED3D_POOL_DEFAULT:
+ if (lockable && !(usage & (WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL)))
+ WARN("Creating a lockable surface with a POOL of DEFAULT, that doesn't specify DYNAMIC usage.\n");
+ break;
+
+ default:
+ FIXME("Unknown pool %#x.\n", pool);
+ break;
+ };
+
+ if (usage & WINED3DUSAGE_RENDERTARGET && pool != WINED3D_POOL_DEFAULT)
+ FIXME("Trying to create a render target that isn't in the default pool.\n");
+
+ /* FIXME: Check that the format is supported by the device. */
+
+ resource_size = wined3d_format_calculate_size(format, alignment, width, height);
+ if (!resource_size)
+ return WINED3DERR_INVALIDCALL;
+
+ if (device->wined3d->flags & WINED3D_NO3D)
+ surface->surface_ops = &gdi_surface_ops;
+ else
+ surface->surface_ops = &surface_ops;
+
+ hr = resource_init(&surface->resource, device, WINED3D_RTYPE_SURFACE, format,
+ multisample_type, multisample_quality, usage, pool, width, height, 1,
+ resource_size, parent, parent_ops, &surface_resource_ops
+#ifdef VBOX_WITH_WDDM
+ , shared_handle
+ , pvClientMem
+#endif
+ );
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize resource, returning %#x.\n", hr);
+ return hr;
+ }
+
+#ifdef VBOX_WITH_WDDM
+ /* this will be a nop for the non-shared resource,
+ * for the shared resource this will ensure the surface is initialized properly */
+ surface_shrc_lock(surface);
+#endif
+
+ /* "Standalone" surface. */
+ surface_set_container(surface, NULL);
+
+ list_init(&surface->overlays);
+
+ /* Flags */
+ surface->flags = SFLAG_NORMCOORD; /* Default to normalized coords. */
+ if (flags & WINED3D_SURFACE_DISCARD)
+ surface->flags |= SFLAG_DISCARD;
+ if (flags & WINED3D_SURFACE_PIN_SYSMEM)
+ surface->flags |= SFLAG_PIN_SYSMEM;
+ if (lockable || format_id == WINED3DFMT_D16_LOCKABLE)
+ surface->flags |= SFLAG_LOCKABLE;
+ /* I'm not sure if this qualifies as a hack or as an optimization. It
+ * seems reasonable to assume that lockable render targets will get
+ * locked, so we might as well set SFLAG_DYNLOCK right at surface
+ * creation. However, the other reason we want to do this is that several
+ * ddraw applications access surface memory while the surface isn't
+ * mapped. The SFLAG_DYNLOCK behaviour of keeping SYSMEM around for
+ * future locks prevents these from crashing. */
+ if (lockable && (usage & WINED3DUSAGE_RENDERTARGET))
+ surface->flags |= SFLAG_DYNLOCK;
+#ifdef VBOX_WITH_WDDM
+ if (pool == WINED3D_POOL_SYSTEM_MEM && pvClientMem) surface->flags |= SFLAG_CLIENTMEM;
+#endif
+
+ /* Mark the texture as dirty so that it gets loaded first time around. */
+ surface_add_dirty_rect(surface, NULL);
+ list_init(&surface->renderbuffers);
+
+ TRACE("surface %p, memory %p, size %u\n",
+ surface, surface->resource.allocatedMemory, surface->resource.size);
+
+ /* Call the private setup routine */
+ hr = surface->surface_ops->surface_private_setup(surface);
+ if (FAILED(hr))
+ {
+ ERR("Private setup failed, returning %#x\n", hr);
+ surface_cleanup(surface);
+ return hr;
+ }
+
+ /* Similar to lockable rendertargets above, creating the DIB section
+ * during surface initialization prevents the sysmem pointer from changing
+ * after a wined3d_surface_getdc() call. */
+ if ((usage & WINED3DUSAGE_OWNDC) && !surface->hDC
+ && SUCCEEDED(surface_create_dib_section(surface)))
+ {
+ HeapFree(GetProcessHeap(), 0, surface->resource.heapMemory);
+ surface->resource.heapMemory = NULL;
+ surface->resource.allocatedMemory = surface->dib.bitmap_data;
+ }
+
+#ifdef VBOX_WITH_WDDM
+ if (VBOXSHRC_IS_SHARED(surface))
+ {
+ Assert(shared_handle);
+ if (!VBOXSHRC_IS_SHARED_OPENED(surface))
+ {
+ surface_shrc_unlock(surface);
+ Assert(!(*shared_handle));
+ *shared_handle = VBOXSHRC_GET_SHAREHANDLE(surface);
+ }
+ else
+ {
+ VBOXSHRC_UNLOCK(surface);
+ Assert(!VBOXSHRC_IS_LOCKED(surface));
+#ifdef DEBUG_misha
+ ERR("test this!");
+#endif
+ surface_setup_location_onopen(surface);
+ Assert(*shared_handle);
+ Assert(*shared_handle == VBOXSHRC_GET_SHAREHANDLE(surface));
+ }
+
+ Assert(!device->isInDraw);
+
+ /* flush to ensure the texture is allocated/referenced before it is used/released by another
+ * process opening/creating it */
+ /* flush to ensure the texture is allocated/referenced before it is used/released by another
+ * process opening/creating it */
+ Assert(device->context_count == 1);
+ pVBoxFlushToHost(device->contexts[0]->glCtx);
+ }
+ else
+ {
+ Assert(!shared_handle);
+ }
+#endif
+
+ return hr;
+}
+
+HRESULT CDECL wined3d_surface_create(struct wined3d_device *device, UINT width, UINT height,
+ enum wined3d_format_id format_id, DWORD usage, enum wined3d_pool pool,
+ enum wined3d_multisample_type multisample_type, DWORD multisample_quality, DWORD flags,
+ void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_surface **surface
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void *pvClientMem
+#endif
+ )
+{
+ struct wined3d_surface *object;
+ HRESULT hr;
+
+ TRACE("device %p, width %u, height %u, format %s\n",
+ device, width, height, debug_d3dformat(format_id));
+ TRACE("surface %p, usage %s (%#x), pool %s, multisample_type %#x, multisample_quality %u\n",
+ surface, debug_d3dusage(usage), usage, debug_d3dpool(pool), multisample_type, multisample_quality);
+ TRACE("flags %#x, parent %p, parent_ops %p.\n", flags, parent, parent_ops);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return WINED3DERR_OUTOFVIDEOMEMORY;
+
+#ifdef VBOX_WITH_WDDM
+ if (FAILED(hr = surface_init(object, device->surface_alignment, width, height, multisample_type,
+ multisample_quality, device, usage, format_id, pool, flags, parent, parent_ops
+ , shared_handle
+ , pvClientMem
+ )))
+#else
+ if (FAILED(hr = surface_init(object, device->surface_alignment, width, height, multisample_type,
+ multisample_quality, device, usage, format_id, pool, flags, parent, parent_ops)))
+#endif
+ {
+ WARN("Failed to initialize surface, returning %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created surface %p.\n", object);
+ *surface = object;
+
+ return hr;
+}
+
+#ifdef VBOX_WITH_WDDM
+HRESULT CDECL wined3d_surface_get_host_id(struct wined3d_surface *surface, uint32_t *id)
+{
+ struct wined3d_texture *texture;
+ surface_internal_preload(surface, SRGB_RGB);
+
+ texture = surface->container;
+ if (texture && texture->level_count != 1 && texture->layer_count != 1)
+ {
+ ERR("unsupported level(%d) or layer(%d) count", texture->level_count, texture->layer_count);
+ }
+
+ if (!surface->texture_name)
+ {
+ ERR("no texture name!");
+ return E_FAIL;
+ }
+
+ *id = surface->texture_name;
+ return S_OK;
+}
+
+HRESULT CDECL wined3d_surface_sync_to_host(struct wined3d_surface *surface)
+{
+ HRESULT hr = surface_load_location(surface, SFLAG_INTEXTURE, NULL);
+ if (!SUCCEEDED(hr))
+ {
+ ERR("surface_load_location failed hr 0x%x", hr);
+ return hr;
+ }
+
+ return S_OK;
+}
+#endif
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/swapchain.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/swapchain.c
new file mode 100644
index 00000000..58021a3b
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/swapchain.c
@@ -0,0 +1,1559 @@
+/*
+ * Copyright 2002-2003 Jason Edmeades
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2011 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(fps);
+
+#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
+static VOID swapchain_cleanup_rt_refs(struct wined3d_swapchain *swapchain, struct wined3d_surface * rt, int iBb)
+{
+ struct wined3d_device * device = swapchain->device;
+ struct wined3d_context *context;
+ UINT i;
+ for (i = 0; i < device->context_count; ++i)
+ {
+ context = device->contexts[i];
+
+ if (rt == context->current_rt)
+ {
+ context->current_rt = NULL;
+ }
+ }
+
+ if (device->swapchain_count)
+ {
+ struct wined3d_swapchain *default_swapchain = (struct wined3d_swapchain*)device->swapchains[0];
+ for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i)
+ {
+ if (device->fb.render_targets[i] == rt)
+ {
+ struct wined3d_surface *new_rt;
+ if (i)
+ new_rt = NULL;
+ else if (iBb == -1) /* front buffer */
+ new_rt = default_swapchain->front_buffer;
+ else
+ new_rt = default_swapchain->back_buffers ? default_swapchain->back_buffers[0] : default_swapchain->front_buffer;
+
+ wined3d_device_set_render_target(device, i, new_rt, TRUE);
+ }
+ }
+ }
+}
+
+static VOID swapchain_cleanup_refs(struct wined3d_swapchain *swapchain)
+{
+ /* first make sure the swapchain is not used by anyone */
+ struct wined3d_device * device = swapchain->device;
+ struct wined3d_context *context;
+ UINT i;
+
+ /* Release the swapchain's draw buffers. Make sure swapchain->back_buffers[0]
+ * is the last buffer to be destroyed, FindContext() depends on that. */
+ if (swapchain->front_buffer)
+ {
+ surface_set_swapchain(swapchain->front_buffer, NULL);
+ if (wined3d_surface_decref(swapchain->front_buffer))
+ WARN("Something's still holding the front buffer (%p).\n", swapchain->front_buffer);
+ swapchain->front_buffer = NULL;
+ }
+
+ if (swapchain->back_buffers)
+ {
+ i = swapchain->desc.backbuffer_count;
+
+ while (i--)
+ {
+ surface_set_swapchain(swapchain->back_buffers[i], NULL);
+ if (wined3d_surface_decref(swapchain->back_buffers[i]))
+ WARN("Something's still holding back buffer %u (%p).\n", i, swapchain->back_buffers[i]);
+ }
+ HeapFree(GetProcessHeap(), 0, swapchain->back_buffers);
+ swapchain->back_buffers = NULL;
+ }
+
+ for (i = 0; i < device->context_count; ++i)
+ {
+ context = device->contexts[i];
+ /* pretty hacky, @todo: check if the context is acquired and re-acquire it with a new swapchain */
+ if (context->swapchain == swapchain)
+ {
+ context->swapchain = NULL;
+ }
+ }
+//
+// if (swapchain->front_buffer)
+// swapchain_cleanup_rt_refs(swapchain, swapchain->front_buffer, -1);
+//
+// if (swapchain->back_buffers)
+// {
+// for (i = 0; i < swapchain->desc.backbuffer_count; ++i)
+// {
+// swapchain_cleanup_rt_refs(swapchain, swapchain->back_buffers[i], i);
+// }
+// }
+}
+#endif
+
+#ifdef VBOX_WITH_WDDM
+
+struct wined3d_swapchain * swapchain_find(struct wined3d_device * device, HWND hWnd)
+{
+ UINT i;
+ for (i = 0; i < device->swapchain_count; ++i)
+ {
+ struct wined3d_swapchain *swapchain = device->swapchains[i];
+ if (swapchain->win_handle == hWnd)
+ {
+ return swapchain;
+ }
+ }
+
+ return NULL;
+}
+
+static VOID swapchain_invalidate(struct wined3d_swapchain *swapchain)
+{
+ swapchain_cleanup_refs(swapchain);
+
+ swapchain->win_handle = NULL;
+ swapchain->hDC = NULL;
+}
+#endif
+
+/* Do not call while under the GL lock. */
+static void swapchain_cleanup(struct wined3d_swapchain *swapchain)
+{
+#ifndef VBOX_WITH_WDDM
+ struct wined3d_display_mode mode;
+ HRESULT hr;
+#endif
+ UINT i;
+
+ TRACE("Destroying swapchain %p.\n", swapchain);
+
+#ifndef VBOX_WITH_WDDM
+ wined3d_swapchain_set_gamma_ramp(swapchain, 0, &swapchain->orig_gamma);
+#endif
+
+ /* Release the swapchain's draw buffers. Make sure swapchain->back_buffers[0]
+ * is the last buffer to be destroyed, FindContext() depends on that. */
+ if (swapchain->front_buffer)
+ {
+ surface_set_swapchain(swapchain->front_buffer, NULL);
+ if (wined3d_surface_decref(swapchain->front_buffer))
+ WARN("Something's still holding the front buffer (%p).\n", swapchain->front_buffer);
+ swapchain->front_buffer = NULL;
+ }
+
+ if (swapchain->back_buffers)
+ {
+ i = swapchain->desc.backbuffer_count;
+
+ while (i--)
+ {
+ surface_set_swapchain(swapchain->back_buffers[i], NULL);
+ if (wined3d_surface_decref(swapchain->back_buffers[i]))
+ WARN("Something's still holding back buffer %u (%p).\n", i, swapchain->back_buffers[i]);
+ }
+ HeapFree(GetProcessHeap(), 0, swapchain->back_buffers);
+ swapchain->back_buffers = NULL;
+ }
+
+#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
+ swapchain_cleanup_refs(swapchain);
+#endif
+
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ for (i = 0; i < swapchain->num_contexts; ++i)
+ {
+ context_destroy(swapchain->device, swapchain->context[i]);
+ }
+ HeapFree(GetProcessHeap(), 0, swapchain->context);
+#endif
+#ifndef VBOX_WITH_WDDM
+ /* Restore the screen resolution if we rendered in fullscreen.
+ * This will restore the screen resolution to what it was before creating
+ * the swapchain. In case of d3d8 and d3d9 this will be the original
+ * desktop resolution. In case of d3d7 this will be a NOP because ddraw
+ * sets the resolution before starting up Direct3D, thus orig_width and
+ * orig_height will be equal to the modes in the presentation params. */
+ if (!swapchain->desc.windowed && swapchain->desc.auto_restore_display_mode)
+ {
+ mode.width = swapchain->orig_width;
+ mode.height = swapchain->orig_height;
+ mode.refresh_rate = 0;
+ mode.format_id = swapchain->orig_fmt;
+ mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
+ if (FAILED(hr = wined3d_set_adapter_display_mode(swapchain->device->wined3d,
+ swapchain->device->adapter->ordinal, &mode)))
+ ERR("Failed to restore display mode, hr %#x.\n", hr);
+ }
+
+ if (swapchain->backup_dc)
+ {
+ TRACE("Destroying backup wined3d window %p, dc %p.\n", swapchain->backup_wnd, swapchain->backup_dc);
+
+ ReleaseDC(swapchain->backup_wnd, swapchain->backup_dc);
+ DestroyWindow(swapchain->backup_wnd);
+ }
+#endif
+#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
+# ifdef VBOX_WITH_WDDM
+ if(swapchain->win_handle) {
+ VBoxExtWndDestroy(swapchain->win_handle, swapchain->hDC);
+ swapchain_invalidate(swapchain);
+ }
+# endif
+#endif
+}
+
+ULONG CDECL wined3d_swapchain_incref(struct wined3d_swapchain *swapchain)
+{
+ ULONG refcount = InterlockedIncrement(&swapchain->ref);
+
+ TRACE("%p increasing refcount to %u.\n", swapchain, refcount);
+
+ return refcount;
+}
+
+/* Do not call while under the GL lock. */
+ULONG CDECL wined3d_swapchain_decref(struct wined3d_swapchain *swapchain)
+{
+ ULONG refcount = InterlockedDecrement(&swapchain->ref);
+
+ TRACE("%p decreasing refcount to %u.\n", swapchain, refcount);
+
+ if (!refcount)
+ {
+ swapchain_cleanup(swapchain);
+ swapchain->parent_ops->wined3d_object_destroyed(swapchain->parent);
+ HeapFree(GetProcessHeap(), 0, swapchain);
+ }
+
+ return refcount;
+}
+
+void * CDECL wined3d_swapchain_get_parent(const struct wined3d_swapchain *swapchain)
+{
+ TRACE("swapchain %p.\n", swapchain);
+
+ return swapchain->parent;
+}
+
+void CDECL wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, HWND window)
+{
+#ifdef VBOX_WITH_WDDM
+ if (window)
+ ERR("not expected!");
+#else
+ if (!window)
+ window = swapchain->device_window;
+ if (window == swapchain->win_handle)
+ return;
+
+ TRACE("Setting swapchain %p window from %p to %p.\n",
+ swapchain, swapchain->win_handle, window);
+ swapchain->win_handle = window;
+#endif
+}
+
+HRESULT CDECL wined3d_swapchain_present(struct wined3d_swapchain *swapchain,
+ const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
+ const RGNDATA *dirty_region, DWORD flags)
+{
+ TRACE("swapchain %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p, flags %#x.\n",
+ swapchain, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect),
+ dst_window_override, dirty_region, flags);
+
+ if (flags)
+ FIXME("Ignoring flags %#x.\n", flags);
+
+ if (!swapchain->back_buffers)
+ {
+ WARN("Swapchain doesn't have a backbuffer, returning WINED3DERR_INVALIDCALL\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ wined3d_swapchain_set_window(swapchain, dst_window_override);
+
+ swapchain->swapchain_ops->swapchain_present(swapchain, src_rect, dst_rect, dirty_region, flags);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_swapchain_get_front_buffer_data(const struct wined3d_swapchain *swapchain,
+ struct wined3d_surface *dst_surface)
+{
+ struct wined3d_surface *src_surface;
+ RECT src_rect, dst_rect;
+
+ TRACE("swapchain %p, dst_surface %p.\n", swapchain, dst_surface);
+
+ src_surface = swapchain->front_buffer;
+ SetRect(&src_rect, 0, 0, src_surface->resource.width, src_surface->resource.height);
+ dst_rect = src_rect;
+
+#ifndef VBOX_WITH_WINE_FIXES
+ if (swapchain->desc.windowed)
+ {
+ MapWindowPoints(swapchain->win_handle, NULL, (POINT *)&dst_rect, 2);
+ FIXME("Using destination rect %s in windowed mode, this is likely wrong.\n",
+ wine_dbgstr_rect(&dst_rect));
+ }
+#endif
+
+ return wined3d_surface_blt(dst_surface, &dst_rect, src_surface, &src_rect, 0, NULL, WINED3D_TEXF_POINT);
+}
+
+struct wined3d_surface * CDECL wined3d_swapchain_get_back_buffer(const struct wined3d_swapchain *swapchain,
+ UINT back_buffer_idx, enum wined3d_backbuffer_type type)
+{
+ TRACE("swapchain %p, back_buffer_idx %u, type %#x.\n",
+ swapchain, back_buffer_idx, type);
+
+#ifdef VBOX_WITH_WDDM
+ if (back_buffer_idx == ~0UL)
+ {
+ return swapchain->front_buffer;
+ }
+#endif
+
+ /* Return invalid if there is no backbuffer array, otherwise it will
+ * crash when ddraw is used (there swapchain->back_buffers is always
+ * NULL). We need this because this function is called from
+ * stateblock_init_default_state() to get the default scissorrect
+ * dimensions. */
+ if (!swapchain->back_buffers || back_buffer_idx >= swapchain->desc.backbuffer_count)
+ {
+ WARN("Invalid back buffer index.\n");
+ /* Native d3d9 doesn't set NULL here, just as wine's d3d9. But set it
+ * here in wined3d to avoid problems in other libs. */
+ return NULL;
+ }
+
+ TRACE("Returning back buffer %p.\n", swapchain->back_buffers[back_buffer_idx]);
+
+ return swapchain->back_buffers[back_buffer_idx];
+}
+
+HRESULT CDECL wined3d_swapchain_get_raster_status(const struct wined3d_swapchain *swapchain,
+ struct wined3d_raster_status *raster_status)
+{
+ TRACE("swapchain %p, raster_status %p.\n", swapchain, raster_status);
+
+ return wined3d_get_adapter_raster_status(swapchain->device->wined3d,
+ swapchain->device->adapter->ordinal, raster_status);
+}
+
+HRESULT CDECL wined3d_swapchain_get_display_mode(const struct wined3d_swapchain *swapchain,
+ struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation)
+{
+ HRESULT hr;
+
+ TRACE("swapchain %p, mode %p, rotation %p.\n", swapchain, mode, rotation);
+
+ hr = wined3d_get_adapter_display_mode(swapchain->device->wined3d,
+ swapchain->device->adapter->ordinal, mode, rotation);
+
+ TRACE("Returning w %u, h %u, refresh rate %u, format %s.\n",
+ mode->width, mode->height, mode->refresh_rate, debug_d3dformat(mode->format_id));
+
+ return hr;
+}
+
+struct wined3d_device * CDECL wined3d_swapchain_get_device(const struct wined3d_swapchain *swapchain)
+{
+ TRACE("swapchain %p.\n", swapchain);
+
+ return swapchain->device;
+}
+
+void CDECL wined3d_swapchain_get_desc(const struct wined3d_swapchain *swapchain,
+ struct wined3d_swapchain_desc *desc)
+{
+ TRACE("swapchain %p, desc %p.\n", swapchain, desc);
+
+ *desc = swapchain->desc;
+}
+
+HRESULT CDECL wined3d_swapchain_set_gamma_ramp(const struct wined3d_swapchain *swapchain,
+ DWORD flags, const struct wined3d_gamma_ramp *ramp)
+{
+ HDC dc;
+
+ TRACE("swapchain %p, flags %#x, ramp %p.\n", swapchain, flags, ramp);
+
+ if (flags)
+ FIXME("Ignoring flags %#x.\n", flags);
+
+#ifdef VBOX_WITH_WDDM
+ dc = GetDC(swapchain->win_handle);
+#else
+ dc = GetDC(swapchain->device_window);
+#endif
+ SetDeviceGammaRamp(dc, (void *)ramp);
+#ifdef VBOX_WITH_WDDM
+ ReleaseDC(swapchain->win_handle, dc);
+#else
+ ReleaseDC(swapchain->device_window, dc);
+#endif
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_swapchain_get_gamma_ramp(const struct wined3d_swapchain *swapchain,
+ struct wined3d_gamma_ramp *ramp)
+{
+ HDC dc;
+
+ TRACE("swapchain %p, ramp %p.\n", swapchain, ramp);
+
+#ifdef VBOX_WITH_WDDM
+ dc = GetDC(swapchain->win_handle);
+#else
+ dc = GetDC(swapchain->device_window);
+#endif
+ GetDeviceGammaRamp(dc, ramp);
+#ifdef VBOX_WITH_WDDM
+ ReleaseDC(swapchain->win_handle, dc);
+#else
+ ReleaseDC(swapchain->device_window, dc);
+#endif
+
+ return WINED3D_OK;
+}
+
+/* A GL context is provided by the caller */
+static void swapchain_blit(const struct wined3d_swapchain *swapchain,
+ struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect)
+{
+ struct wined3d_surface *backbuffer = swapchain->back_buffers[0];
+ UINT src_w = src_rect->right - src_rect->left;
+ UINT src_h = src_rect->bottom - src_rect->top;
+ GLenum gl_filter;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ RECT win_rect;
+ UINT win_h;
+
+ TRACE("swapchain %p, context %p, src_rect %s, dst_rect %s.\n",
+ swapchain, context, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect));
+
+ if (src_w == dst_rect->right - dst_rect->left && src_h == dst_rect->bottom - dst_rect->top)
+ gl_filter = GL_NEAREST;
+ else
+ gl_filter = GL_LINEAR;
+
+ GetClientRect(swapchain->win_handle, &win_rect);
+ win_h = win_rect.bottom - win_rect.top;
+
+ if (gl_info->fbo_ops.glBlitFramebuffer && is_identity_fixup(backbuffer->resource.format->color_fixup))
+ {
+ DWORD location = SFLAG_INTEXTURE;
+
+ if (backbuffer->resource.multisample_type)
+ {
+ location = SFLAG_INRB_RESOLVED;
+ surface_load_location(backbuffer, location, NULL);
+ }
+
+ context_apply_fbo_state_blit(context, GL_READ_FRAMEBUFFER, backbuffer, NULL, location);
+ gl_info->gl_ops.gl.p_glReadBuffer(GL_COLOR_ATTACHMENT0);
+ context_check_fbo_status(context, GL_READ_FRAMEBUFFER);
+
+ context_apply_fbo_state_blit(context, GL_DRAW_FRAMEBUFFER, swapchain->front_buffer, NULL, SFLAG_INDRAWABLE);
+ context_set_draw_buffer(context, GL_BACK);
+ context_invalidate_state(context, STATE_FRAMEBUFFER);
+
+ gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE));
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1));
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2));
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3));
+
+ gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
+ context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE));
+
+ /* Note that the texture is upside down */
+ gl_info->fbo_ops.glBlitFramebuffer(src_rect->left, src_rect->top, src_rect->right, src_rect->bottom,
+ dst_rect->left, win_h - dst_rect->top, dst_rect->right, win_h - dst_rect->bottom,
+ GL_COLOR_BUFFER_BIT, gl_filter);
+ checkGLcall("Swapchain present blit(EXT_framebuffer_blit)\n");
+ }
+ else
+ {
+ struct wined3d_device *device = swapchain->device;
+ struct wined3d_context *context2;
+ float tex_left = src_rect->left;
+ float tex_top = src_rect->top;
+ float tex_right = src_rect->right;
+ float tex_bottom = src_rect->bottom;
+
+ context2 = context_acquire(device, swapchain->back_buffers[0]);
+ context_apply_blit_state(context2, device);
+
+ if (backbuffer->flags & SFLAG_NORMCOORD)
+ {
+ tex_left /= src_w;
+ tex_right /= src_w;
+ tex_top /= src_h;
+ tex_bottom /= src_h;
+ }
+
+ if (is_complex_fixup(backbuffer->resource.format->color_fixup))
+ gl_filter = GL_NEAREST;
+
+ context_apply_fbo_state_blit(context2, GL_FRAMEBUFFER, swapchain->front_buffer, NULL, SFLAG_INDRAWABLE);
+ context_bind_texture(context2, backbuffer->texture_target, backbuffer->texture_name);
+
+ /* Set up the texture. The surface is not in a wined3d_texture
+ * container, so there are no D3D texture settings to dirtify. */
+ device->blitter->set_shader(device->blit_priv, context2, backbuffer);
+ gl_info->gl_ops.gl.p_glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MIN_FILTER, gl_filter);
+ gl_info->gl_ops.gl.p_glTexParameteri(backbuffer->texture_target, GL_TEXTURE_MAG_FILTER, gl_filter);
+
+ context_set_draw_buffer(context, GL_BACK);
+
+ /* Set the viewport to the destination rectandle, disable any projection
+ * transformation set up by context_apply_blit_state(), and draw a
+ * (-1,-1)-(1,1) quad.
+ *
+ * Back up viewport and matrix to avoid breaking last_was_blit
+ *
+ * Note that context_apply_blit_state() set up viewport and ortho to
+ * match the surface size - we want the GL drawable(=window) size. */
+ gl_info->gl_ops.gl.p_glPushAttrib(GL_VIEWPORT_BIT);
+ gl_info->gl_ops.gl.p_glViewport(dst_rect->left, win_h - dst_rect->bottom,
+ dst_rect->right, win_h - dst_rect->top);
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
+ gl_info->gl_ops.gl.p_glPushMatrix();
+ gl_info->gl_ops.gl.p_glLoadIdentity();
+
+ gl_info->gl_ops.gl.p_glBegin(GL_QUADS);
+ /* bottom left */
+ gl_info->gl_ops.gl.p_glTexCoord2f(tex_left, tex_bottom);
+ gl_info->gl_ops.gl.p_glVertex2i(-1, -1);
+
+ /* top left */
+ gl_info->gl_ops.gl.p_glTexCoord2f(tex_left, tex_top);
+ gl_info->gl_ops.gl.p_glVertex2i(-1, 1);
+
+ /* top right */
+ gl_info->gl_ops.gl.p_glTexCoord2f(tex_right, tex_top);
+ gl_info->gl_ops.gl.p_glVertex2i(1, 1);
+
+ /* bottom right */
+ gl_info->gl_ops.gl.p_glTexCoord2f(tex_right, tex_bottom);
+ gl_info->gl_ops.gl.p_glVertex2i(1, -1);
+ gl_info->gl_ops.gl.p_glEnd();
+
+ gl_info->gl_ops.gl.p_glPopMatrix();
+ gl_info->gl_ops.gl.p_glPopAttrib();
+
+ device->blitter->unset_shader(context->gl_info);
+ checkGLcall("Swapchain present blit(manual)\n");
+
+ context_release(context2);
+ }
+}
+
+static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT *src_rect_in,
+ const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags)
+{
+ struct wined3d_surface *back_buffer = swapchain->back_buffers[0];
+ const struct wined3d_fb_state *fb = &swapchain->device->fb;
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+ RECT src_rect, dst_rect;
+ BOOL render_to_fbo;
+
+ context = context_acquire(swapchain->device, back_buffer);
+ if (!context->valid)
+ {
+ context_release(context);
+ WARN("Invalid context, skipping present.\n");
+ return;
+ }
+
+ gl_info = context->gl_info;
+
+ /* Render the cursor onto the back buffer, using our nifty directdraw blitting code :-) */
+ if (swapchain->device->bCursorVisible &&
+ swapchain->device->cursorTexture &&
+ !swapchain->device->hardwareCursor)
+ {
+ struct wined3d_surface cursor;
+ RECT destRect =
+ {
+ swapchain->device->xScreenSpace - swapchain->device->xHotSpot,
+ swapchain->device->yScreenSpace - swapchain->device->yHotSpot,
+ swapchain->device->xScreenSpace + swapchain->device->cursorWidth - swapchain->device->xHotSpot,
+ swapchain->device->yScreenSpace + swapchain->device->cursorHeight - swapchain->device->yHotSpot,
+ };
+ TRACE("Rendering the cursor. Creating fake surface at %p\n", &cursor);
+ /* Build a fake surface to call the Blitting code. It is not possible to use the interface passed by
+ * the application because we are only supposed to copy the information out. Using a fake surface
+ * allows us to use the Blitting engine and avoid copying the whole texture -> render target blitting code.
+ */
+ memset(&cursor, 0, sizeof(cursor));
+ cursor.resource.ref = 1;
+ cursor.resource.device = swapchain->device;
+ cursor.resource.pool = WINED3D_POOL_SCRATCH;
+ cursor.resource.format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM);
+ cursor.resource.type = WINED3D_RTYPE_SURFACE;
+ cursor.texture_name = swapchain->device->cursorTexture;
+ cursor.texture_target = GL_TEXTURE_2D;
+ cursor.texture_level = 0;
+ cursor.resource.width = swapchain->device->cursorWidth;
+ cursor.resource.height = swapchain->device->cursorHeight;
+ /* The cursor must have pow2 sizes */
+ cursor.pow2Width = cursor.resource.width;
+ cursor.pow2Height = cursor.resource.height;
+ /* The surface is in the texture */
+ cursor.flags |= SFLAG_INTEXTURE;
+ /* DDBLT_KEYSRC will cause BltOverride to enable the alpha test with GL_NOTEQUAL, 0.0,
+ * which is exactly what we want :-)
+ */
+#ifndef VBOX_WITH_WINE_FIXES
+ if (swapchain->desc.windowed)
+ MapWindowPoints(NULL, swapchain->win_handle, (POINT *)&destRect, 2);
+#endif
+ wined3d_surface_blt(back_buffer, &destRect, &cursor, NULL, WINEDDBLT_KEYSRC,
+ NULL, WINED3D_TEXF_POINT);
+ }
+
+ if (swapchain->device->logo_surface)
+ {
+ struct wined3d_surface *src_surface = swapchain->device->logo_surface;
+ RECT rect = {0, 0, src_surface->resource.width, src_surface->resource.height};
+
+ /* Blit the logo into the upper left corner of the drawable. */
+ wined3d_surface_blt(back_buffer, &rect, src_surface, &rect, WINEDDBLT_KEYSRC,
+ NULL, WINED3D_TEXF_POINT);
+ }
+
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ TRACE("Presenting HDC %p.\n", context->hdc);
+#else
+ TRACE("Presenting HDC %p.\n", context->swapchain->hDC);
+#endif
+
+ render_to_fbo = swapchain->render_to_fbo;
+
+ if (src_rect_in)
+ {
+ src_rect = *src_rect_in;
+ if (!render_to_fbo && (src_rect.left || src_rect.top
+ || src_rect.right != swapchain->desc.backbuffer_width
+ || src_rect.bottom != swapchain->desc.backbuffer_height))
+ {
+ render_to_fbo = TRUE;
+ }
+ }
+ else
+ {
+ src_rect.left = 0;
+ src_rect.top = 0;
+ src_rect.right = swapchain->desc.backbuffer_width;
+ src_rect.bottom = swapchain->desc.backbuffer_height;
+ }
+
+ if (dst_rect_in)
+ dst_rect = *dst_rect_in;
+ else
+ GetClientRect(swapchain->win_handle, &dst_rect);
+
+ if (!render_to_fbo && (dst_rect.left || dst_rect.top
+ || dst_rect.right != swapchain->desc.backbuffer_width
+ || dst_rect.bottom != swapchain->desc.backbuffer_height))
+ render_to_fbo = TRUE;
+
+ /* Rendering to a window of different size, presenting partial rectangles,
+ * or rendering to a different window needs help from FBO_blit or a textured
+ * draw. Render the swapchain to a FBO in the future.
+ *
+ * Note that FBO_blit from the backbuffer to the frontbuffer cannot solve
+ * all these issues - this fails if the window is smaller than the backbuffer.
+ */
+ if (!swapchain->render_to_fbo && render_to_fbo && wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ surface_load_location(back_buffer, SFLAG_INTEXTURE, NULL);
+ surface_modify_location(back_buffer, SFLAG_INDRAWABLE, FALSE);
+ swapchain->render_to_fbo = TRUE;
+ swapchain_update_draw_bindings(swapchain);
+ }
+ else
+ {
+ surface_load_location(back_buffer, back_buffer->draw_binding, NULL);
+ }
+
+ if (swapchain->render_to_fbo)
+ {
+ /* This codepath should only be hit with the COPY swapeffect. Otherwise a backbuffer-
+ * window size mismatch is impossible(fullscreen) and src and dst rectangles are
+ * not allowed(they need the COPY swapeffect)
+ *
+ * The DISCARD swap effect is ok as well since any backbuffer content is allowed after
+ * the swap. */
+ if (swapchain->desc.swap_effect == WINED3D_SWAP_EFFECT_FLIP)
+ FIXME("Render-to-fbo with WINED3D_SWAP_EFFECT_FLIP\n");
+
+ swapchain_blit(swapchain, context, &src_rect, &dst_rect);
+ }
+
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ if (swapchain->num_contexts > 1)
+ gl_info->gl_ops.gl.p_glFinish();
+#endif
+
+#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
+# ifdef DEBUG
+ {
+ HWND wnd = WindowFromDC(context->swapchain->hDC);
+ Assert(wnd == context->swapchain->win_handle);
+ }
+# endif
+ /* call wglSwapBuffers through the gl table to avoid confusing the Steam overlay */
+ gl_info->gl_ops.wgl.p_wglSwapBuffers(context->swapchain->hDC); /* TODO: cycle through the swapchain buffers */
+#else
+
+ /* call wglSwapBuffers through the gl table to avoid confusing the Steam overlay */
+ gl_info->gl_ops.wgl.p_wglSwapBuffers(context->hdc); /* TODO: cycle through the swapchain buffers */
+#endif
+
+ TRACE("SwapBuffers called, Starting new frame\n");
+ /* FPS support */
+ if (TRACE_ON(fps))
+ {
+ DWORD time = GetTickCount();
+ ++swapchain->frames;
+
+ /* every 1.5 seconds */
+ if (time - swapchain->prev_time > 1500)
+ {
+ TRACE_(fps)("%p @ approx %.2ffps\n",
+ swapchain, 1000.0 * swapchain->frames / (time - swapchain->prev_time));
+ swapchain->prev_time = time;
+ swapchain->frames = 0;
+ }
+ }
+
+ /* This is disabled, but the code left in for debug purposes.
+ *
+ * Since we're allowed to modify the new back buffer on a D3DSWAPEFFECT_DISCARD flip,
+ * we can clear it with some ugly color to make bad drawing visible and ease debugging.
+ * The Debug runtime does the same on Windows. However, a few games do not redraw the
+ * screen properly, like Max Payne 2, which leaves a few pixels undefined.
+ *
+ * Tests show that the content of the back buffer after a discard flip is indeed not
+ * reliable, so no game can depend on the exact content. However, it resembles the
+ * old contents in some way, for example by showing fragments at other locations. In
+ * general, the color theme is still intact. So Max payne, which draws rather dark scenes
+ * gets a dark background image. If we clear it with a bright ugly color, the game's
+ * bug shows up much more than it does on Windows, and the players see single pixels
+ * with wrong colors.
+ * (The Max Payne bug has been confirmed on Windows with the debug runtime) */
+ if (FALSE && swapchain->desc.swap_effect == WINED3D_SWAP_EFFECT_DISCARD)
+ {
+ static const struct wined3d_color cyan = {0.0f, 1.0f, 1.0f, 1.0f};
+
+ TRACE("Clearing the color buffer with cyan color\n");
+
+ wined3d_device_clear(swapchain->device, 0, NULL,
+ WINED3DCLEAR_TARGET, &cyan, 1.0f, 0);
+ }
+
+ if (!swapchain->render_to_fbo && ((swapchain->front_buffer->flags & SFLAG_INSYSMEM)
+ || (back_buffer->flags & SFLAG_INSYSMEM)))
+ {
+ /* Both memory copies of the surfaces are ok, flip them around too instead of dirtifying
+ * Doesn't work with render_to_fbo because we're not flipping
+ */
+ struct wined3d_surface *front = swapchain->front_buffer;
+
+ if (front->resource.size == back_buffer->resource.size)
+ {
+ DWORD fbflags;
+ flip_surface(front, back_buffer);
+
+ /* Tell the front buffer surface that is has been modified. However,
+ * the other locations were preserved during that, so keep the flags.
+ * This serves to update the emulated overlay, if any. */
+ fbflags = front->flags;
+ surface_modify_location(front, SFLAG_INDRAWABLE, TRUE);
+ front->flags = fbflags;
+ }
+ else
+ {
+ surface_modify_location(front, SFLAG_INDRAWABLE, TRUE);
+ surface_modify_location(back_buffer, SFLAG_INDRAWABLE, TRUE);
+ }
+ }
+ else
+ {
+ surface_modify_location(swapchain->front_buffer, SFLAG_INDRAWABLE, TRUE);
+ /* If the swapeffect is DISCARD, the back buffer is undefined. That means the SYSMEM
+ * and INTEXTURE copies can keep their old content if they have any defined content.
+ * If the swapeffect is COPY, the content remains the same. If it is FLIP however,
+ * the texture / sysmem copy needs to be reloaded from the drawable
+ */
+ if (swapchain->desc.swap_effect == WINED3D_SWAP_EFFECT_FLIP)
+ surface_modify_location(back_buffer, back_buffer->draw_binding, TRUE);
+ }
+
+ if (fb->depth_stencil)
+ {
+ if (swapchain->desc.flags & WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL
+ || fb->depth_stencil->flags & SFLAG_DISCARD)
+ {
+ surface_modify_ds_location(fb->depth_stencil, SFLAG_DISCARDED,
+ fb->depth_stencil->resource.width,
+ fb->depth_stencil->resource.height);
+ if (fb->depth_stencil == swapchain->device->onscreen_depth_stencil)
+ {
+ wined3d_surface_decref(swapchain->device->onscreen_depth_stencil);
+ swapchain->device->onscreen_depth_stencil = NULL;
+ }
+ }
+ }
+
+ context_release(context);
+}
+
+static const struct wined3d_swapchain_ops swapchain_gl_ops =
+{
+ swapchain_gl_present,
+};
+
+/* Helper function that blits the front buffer contents to the target window. */
+void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *rect)
+{
+ const struct wined3d_surface *front;
+ POINT offset = {0, 0};
+ HDC src_dc, dst_dc;
+ RECT draw_rect;
+ HWND window;
+
+ TRACE("swapchain %p, rect %s.\n", swapchain, wine_dbgstr_rect(rect));
+
+ front = swapchain->front_buffer;
+ if (!(front->resource.usage & WINED3DUSAGE_RENDERTARGET))
+ return;
+
+ if (front->resource.map_count)
+ ERR("Trying to blit a mapped surface.\n");
+
+ TRACE("Copying surface %p to screen.\n", front);
+
+ src_dc = front->hDC;
+ window = swapchain->win_handle;
+ dst_dc = GetDCEx(window, 0, DCX_CLIPSIBLINGS | DCX_CACHE);
+
+ /* Front buffer coordinates are screen coordinates. Map them to the
+ * destination window if not fullscreened. */
+ if (swapchain->desc.windowed)
+ {
+#ifndef VBOX_WITH_WINE_FIXES
+ ClientToScreen(window, &offset);
+#else
+ ERR("should not be here!");
+#endif
+ }
+
+ TRACE("offset %s.\n", wine_dbgstr_point(&offset));
+
+ draw_rect.left = 0;
+ draw_rect.right = front->resource.width;
+ draw_rect.top = 0;
+ draw_rect.bottom = front->resource.height;
+
+ if (rect)
+ IntersectRect(&draw_rect, &draw_rect, rect);
+
+ BitBlt(dst_dc, draw_rect.left - offset.x, draw_rect.top - offset.y,
+ draw_rect.right - draw_rect.left, draw_rect.bottom - draw_rect.top,
+ src_dc, draw_rect.left, draw_rect.top, SRCCOPY);
+ ReleaseDC(window, dst_dc);
+}
+
+static void swapchain_gdi_present(struct wined3d_swapchain *swapchain, const RECT *src_rect_in,
+ const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags)
+{
+ struct wined3d_surface *front, *back;
+
+ front = swapchain->front_buffer;
+ back = swapchain->back_buffers[0];
+
+ /* Flip the DC. */
+ {
+ HDC tmp;
+ tmp = front->hDC;
+ front->hDC = back->hDC;
+ back->hDC = tmp;
+ }
+
+ /* Flip the DIBsection. */
+ {
+ HBITMAP tmp;
+ tmp = front->dib.DIBsection;
+ front->dib.DIBsection = back->dib.DIBsection;
+ back->dib.DIBsection = tmp;
+ }
+
+ /* Flip the surface data. */
+ {
+ void *tmp;
+
+ tmp = front->dib.bitmap_data;
+ front->dib.bitmap_data = back->dib.bitmap_data;
+ back->dib.bitmap_data = tmp;
+
+ tmp = front->resource.allocatedMemory;
+ front->resource.allocatedMemory = back->resource.allocatedMemory;
+ back->resource.allocatedMemory = tmp;
+
+ if (front->resource.heapMemory)
+ ERR("GDI Surface %p has heap memory allocated.\n", front);
+
+ if (back->resource.heapMemory)
+ ERR("GDI Surface %p has heap memory allocated.\n", back);
+ }
+
+ /* FPS support */
+ if (TRACE_ON(fps))
+ {
+ static LONG prev_time, frames;
+ DWORD time = GetTickCount();
+
+ ++frames;
+
+ /* every 1.5 seconds */
+ if (time - prev_time > 1500)
+ {
+ TRACE_(fps)("@ approx %.2ffps\n", 1000.0 * frames / (time - prev_time));
+ prev_time = time;
+ frames = 0;
+ }
+ }
+
+ x11_copy_to_screen(swapchain, NULL);
+}
+
+static const struct wined3d_swapchain_ops swapchain_gdi_ops =
+{
+ swapchain_gdi_present,
+};
+
+void swapchain_update_render_to_fbo(struct wined3d_swapchain *swapchain)
+{
+ RECT client_rect;
+
+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO)
+ return;
+
+ if (!swapchain->desc.backbuffer_count)
+ {
+ TRACE("Single buffered rendering.\n");
+ swapchain->render_to_fbo = FALSE;
+ return;
+ }
+
+ GetClientRect(swapchain->win_handle, &client_rect);
+
+ TRACE("Backbuffer %ux%u, window %ux%u.\n",
+ swapchain->desc.backbuffer_width,
+ swapchain->desc.backbuffer_height,
+ client_rect.right, client_rect.bottom);
+ TRACE("Multisample type %#x, quality %#x.\n",
+ swapchain->desc.multisample_type,
+ swapchain->desc.multisample_quality);
+
+ if (!wined3d_settings.always_offscreen && !swapchain->desc.multisample_type
+ && swapchain->desc.backbuffer_width == client_rect.right
+ && swapchain->desc.backbuffer_height == client_rect.bottom)
+ {
+ TRACE("Backbuffer dimensions match window dimensions, rendering onscreen.\n");
+ swapchain->render_to_fbo = FALSE;
+ return;
+ }
+
+ TRACE("Rendering to FBO.\n");
+ swapchain->render_to_fbo = TRUE;
+}
+
+/* Do not call while under the GL lock. */
+static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3d_device *device,
+ struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops)
+{
+ const struct wined3d_adapter *adapter = device->adapter;
+ struct wined3d_resource_desc surface_desc;
+ const struct wined3d_format *format;
+ struct wined3d_display_mode mode;
+#ifndef VBOX_WITH_WDDM
+ BOOL displaymode_set = FALSE;
+#endif
+ RECT client_rect;
+ HWND window;
+ HRESULT hr;
+ UINT i;
+#ifdef VBOX_WITH_WDDM
+ struct wined3d_swapchain *overriden_swapchain = NULL;
+ HDC hDC = NULL;
+#endif
+
+ if (desc->backbuffer_count > WINED3DPRESENT_BACK_BUFFER_MAX)
+ {
+ FIXME("The application requested %u back buffers, this is not supported.\n",
+ desc->backbuffer_count);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (desc->backbuffer_count > 1)
+ {
+ FIXME("The application requested more than one back buffer, this is not properly supported.\n"
+ "Please configure the application to use double buffering (1 back buffer) if possible.\n");
+ }
+
+ if (device->wined3d->flags & WINED3D_NO3D)
+ swapchain->swapchain_ops = &swapchain_gdi_ops;
+ else
+ swapchain->swapchain_ops = &swapchain_gl_ops;
+
+#ifndef VBOX_WITH_WDDM
+ window = desc->device_window ? desc->device_window : device->create_parms.focus_window;
+#else
+ if (desc->device_window)
+ {
+ overriden_swapchain = swapchain_find(device, desc->device_window);
+ if (!overriden_swapchain)
+ {
+ ERR("invalid window handle supplied");
+ return E_FAIL;
+ }
+
+ window = overriden_swapchain->win_handle;
+ hDC = overriden_swapchain->hDC;
+ }
+ else
+ {
+ hr = VBoxExtWndCreate(desc->backbuffer_width, desc->backbuffer_height, &window, &hDC);
+ if (FAILED(hr))
+ {
+ ERR("VBoxExtWndCreate failed, hr 0x%x", hr);
+ return hr;
+ }
+ }
+ Assert(window);
+ Assert(hDC);
+ desc->device_window = window;
+#endif
+
+ swapchain->device = device;
+ swapchain->parent = parent;
+ swapchain->parent_ops = parent_ops;
+ swapchain->ref = 1;
+ swapchain->win_handle = window;
+#ifndef VBOX_WITH_WDDM
+ swapchain->device_window = window;
+# ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
+ swapchain->hDC = VBoxExtGetDC(window);
+ if (!swapchain->hDC)
+ {
+ ERR("failed to get window DC");
+ return E_FAIL;
+ }
+# endif
+#else
+ Assert(window);
+ swapchain->hDC = hDC;
+#endif
+
+ wined3d_get_adapter_display_mode(device->wined3d, adapter->ordinal, &mode, NULL);
+#ifndef VBOX_WITH_WDDM
+ swapchain->orig_width = mode.width;
+ swapchain->orig_height = mode.height;
+ swapchain->orig_fmt = mode.format_id;
+#endif
+ format = wined3d_get_format(&adapter->gl_info, mode.format_id);
+
+ GetClientRect(window, &client_rect);
+ if (desc->windowed
+ && (!desc->backbuffer_width || !desc->backbuffer_height
+ || desc->backbuffer_format == WINED3DFMT_UNKNOWN))
+ {
+
+ if (!desc->backbuffer_width)
+ {
+ desc->backbuffer_width = client_rect.right;
+ TRACE("Updating width to %u.\n", desc->backbuffer_width);
+ }
+
+ if (!desc->backbuffer_height)
+ {
+ desc->backbuffer_height = client_rect.bottom;
+ TRACE("Updating height to %u.\n", desc->backbuffer_height);
+ }
+#ifndef VBOX_WITH_WDDM
+ if (desc->backbuffer_format == WINED3DFMT_UNKNOWN)
+ {
+ desc->backbuffer_format = swapchain->orig_fmt;
+ TRACE("Updating format to %s.\n", debug_d3dformat(swapchain->orig_fmt));
+ }
+#endif
+ }
+ swapchain->desc = *desc;
+ swapchain_update_render_to_fbo(swapchain);
+
+ TRACE("Creating front buffer.\n");
+
+ surface_desc.resource_type = WINED3D_RTYPE_SURFACE;
+ surface_desc.format = swapchain->desc.backbuffer_format;
+ surface_desc.multisample_type = swapchain->desc.multisample_type;
+ surface_desc.multisample_quality = swapchain->desc.multisample_quality;
+ surface_desc.usage = WINED3DUSAGE_RENDERTARGET;
+ surface_desc.pool = WINED3D_POOL_DEFAULT;
+ surface_desc.width = swapchain->desc.backbuffer_width;
+ surface_desc.height = swapchain->desc.backbuffer_height;
+ surface_desc.depth = 1;
+ surface_desc.size = 0;
+
+ if (FAILED(hr = device->device_parent->ops->create_swapchain_surface(device->device_parent,
+ parent, &surface_desc, &swapchain->front_buffer)))
+ {
+ WARN("Failed to create front buffer, hr %#x.\n", hr);
+ goto err;
+ }
+
+ surface_set_swapchain(swapchain->front_buffer, swapchain);
+ if (!(device->wined3d->flags & WINED3D_NO3D))
+ surface_modify_location(swapchain->front_buffer, SFLAG_INDRAWABLE, TRUE);
+
+ /* MSDN says we're only allowed a single fullscreen swapchain per device,
+ * so we should really check to see if there is a fullscreen swapchain
+ * already. Does a single head count as full screen? */
+
+#ifndef VBOX_WITH_WDDM
+ if (!desc->windowed)
+ {
+ struct wined3d_display_mode mode;
+
+ /* Change the display settings */
+ mode.width = desc->backbuffer_width;
+ mode.height = desc->backbuffer_height;
+ mode.format_id = desc->backbuffer_format;
+ mode.refresh_rate = desc->refresh_rate;
+ mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
+
+ if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, device->adapter->ordinal, &mode)))
+ {
+ WARN("Failed to set display mode, hr %#x.\n", hr);
+ goto err;
+ }
+ displaymode_set = TRUE;
+ }
+#endif
+
+ if (!(device->wined3d->flags & WINED3D_NO3D))
+ {
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ static const enum wined3d_format_id formats[] =
+ {
+ WINED3DFMT_D24_UNORM_S8_UINT,
+ WINED3DFMT_D32_UNORM,
+ WINED3DFMT_R24_UNORM_X8_TYPELESS,
+ WINED3DFMT_D16_UNORM,
+ WINED3DFMT_S1_UINT_D15_UNORM
+ };
+
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+
+ swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context));
+ if (!swapchain->context)
+ {
+ ERR("Failed to create the context array.\n");
+ hr = E_OUTOFMEMORY;
+ goto err;
+ }
+ swapchain->num_contexts = 1;
+
+ /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate.
+ * You are able to add a depth + stencil surface at a later stage when you need it.
+ * In order to support this properly in WineD3D we need the ability to recreate the opengl context and
+ * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new
+ * context, need torecreate shaders, textures and other resources.
+ *
+ * The context manager already takes care of the state problem and for the other tasks code from Reset
+ * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now.
+ * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the
+ * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this
+ * issue needs to be fixed. */
+ for (i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
+ {
+ swapchain->ds_format = wined3d_get_format(gl_info, formats[i]);
+ swapchain->context[0] = context_create(swapchain, swapchain->front_buffer, swapchain->ds_format);
+ if (swapchain->context[0]) break;
+ TRACE("Depth stencil format %s is not supported, trying next format\n",
+ debug_d3dformat(formats[i]));
+ }
+
+ if (!swapchain->context[0])
+#else
+ struct wined3d_context * swapchain_context;
+ swapchain->ds_format = wined3d_get_format(&device->adapter->gl_info, WINED3DFMT_D24_UNORM_S8_UINT);
+ swapchain_context = context_find_create(device, swapchain, swapchain->ds_format);
+ if (!swapchain_context)
+#endif
+ {
+ WARN("Failed to create context.\n");
+ hr = WINED3DERR_NOTAVAILABLE;
+ goto err;
+ }
+
+ if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
+ && (!desc->enable_auto_depth_stencil
+ || swapchain->desc.auto_depth_stencil_format != swapchain->ds_format->id))
+ {
+ FIXME("Add OpenGL context recreation support to context_validate_onscreen_formats\n");
+ }
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ context_release(swapchain->context[0]);
+#else
+ context_release(swapchain_context);
+#endif
+ }
+
+ if (swapchain->desc.backbuffer_count > 0)
+ {
+ swapchain->back_buffers = HeapAlloc(GetProcessHeap(), 0,
+ sizeof(*swapchain->back_buffers) * swapchain->desc.backbuffer_count);
+ if (!swapchain->back_buffers)
+ {
+ ERR("Failed to allocate backbuffer array memory.\n");
+ hr = E_OUTOFMEMORY;
+ goto err;
+ }
+
+ for (i = 0; i < swapchain->desc.backbuffer_count; ++i)
+ {
+ TRACE("Creating back buffer %u.\n", i);
+ if (FAILED(hr = device->device_parent->ops->create_swapchain_surface(device->device_parent,
+ parent, &surface_desc, &swapchain->back_buffers[i])))
+ {
+ WARN("Failed to create back buffer %u, hr %#x.\n", i, hr);
+ goto err;
+ }
+ surface_set_swapchain(swapchain->back_buffers[i], swapchain);
+ }
+ }
+
+ /* Swapchains share the depth/stencil buffer, so only create a single depthstencil surface. */
+ if (desc->enable_auto_depth_stencil && !(device->wined3d->flags & WINED3D_NO3D))
+ {
+ TRACE("Creating depth/stencil buffer.\n");
+ if (!device->auto_depth_stencil)
+ {
+ surface_desc.format = swapchain->desc.auto_depth_stencil_format;
+ surface_desc.usage = WINED3DUSAGE_DEPTHSTENCIL;
+
+ if (FAILED(hr = device->device_parent->ops->create_swapchain_surface(device->device_parent,
+ device->device_parent, &surface_desc, &device->auto_depth_stencil)))
+ {
+ WARN("Failed to create the auto depth stencil, hr %#x.\n", hr);
+ goto err;
+ }
+ }
+ }
+
+#ifndef VBOX_WITH_WDDM
+ wined3d_swapchain_get_gamma_ramp(swapchain, &swapchain->orig_gamma);
+#else
+ if (overriden_swapchain)
+ {
+ swapchain_invalidate(overriden_swapchain);
+ }
+#endif
+
+ return WINED3D_OK;
+
+err:
+#ifndef VBOX_WITH_WDDM
+ if (displaymode_set)
+ {
+ DEVMODEW devmode;
+
+ ClipCursor(NULL);
+
+ /* Change the display settings */
+ memset(&devmode, 0, sizeof(devmode));
+ devmode.dmSize = sizeof(devmode);
+ devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
+ devmode.dmBitsPerPel = format->byte_count * CHAR_BIT;
+ devmode.dmPelsWidth = swapchain->orig_width;
+ devmode.dmPelsHeight = swapchain->orig_height;
+ ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL);
+ }
+#endif
+ if (swapchain->back_buffers)
+ {
+ for (i = 0; i < swapchain->desc.backbuffer_count; ++i)
+ {
+ if (swapchain->back_buffers[i])
+ {
+ surface_set_swapchain(swapchain->back_buffers[i], NULL);
+ wined3d_surface_decref(swapchain->back_buffers[i]);
+ }
+ }
+ HeapFree(GetProcessHeap(), 0, swapchain->back_buffers);
+#ifdef VBOX_WITH_WINE_FIX_INITCLEAR
+ swapchain->back_buffers = NULL;
+#endif
+ }
+#ifdef VBOX_WITH_WINE_FIX_INITCLEAR
+ swapchain->desc.backbuffer_count = 0;
+#endif
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ if (swapchain->context)
+ {
+ if (swapchain->context[0])
+ {
+ context_release(swapchain->context[0]);
+ context_destroy(device, swapchain->context[0]);
+ swapchain->num_contexts = 0;
+ }
+ HeapFree(GetProcessHeap(), 0, swapchain->context);
+ }
+#else
+ if (!device->swapchain_count)
+ {
+ while (device->context_count)
+ {
+ context_destroy(device, device->contexts[0]);
+ }
+ }
+#endif
+ if (swapchain->front_buffer)
+ {
+ surface_set_swapchain(swapchain->front_buffer, NULL);
+ wined3d_surface_decref(swapchain->front_buffer);
+ }
+
+#ifdef VBOX_WITH_WDDM
+ if (!overriden_swapchain && swapchain->win_handle)
+ {
+ VBoxExtWndDestroy(swapchain->win_handle, swapchain->hDC);
+ }
+ swapchain_invalidate(swapchain);
+#endif
+
+ return hr;
+}
+
+/* Do not call while under the GL lock. */
+HRESULT CDECL wined3d_swapchain_create(struct wined3d_device *device, struct wined3d_swapchain_desc *desc,
+ void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain)
+{
+ struct wined3d_swapchain *object;
+ HRESULT hr;
+
+ TRACE("device %p, desc %p, parent %p, parent_ops %p, swapchain %p.\n",
+ device, desc, parent, parent_ops, swapchain);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ hr = swapchain_init(object, device, desc, parent, parent_ops);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize swapchain, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created swapchain %p.\n", object);
+ *swapchain = object;
+
+ return WINED3D_OK;
+}
+
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+/* Do not call while under the GL lock. */
+static struct wined3d_context *swapchain_create_context(struct wined3d_swapchain *swapchain)
+{
+ struct wined3d_context **newArray;
+ struct wined3d_context *ctx;
+
+ TRACE("Creating a new context for swapchain %p, thread %u.\n", swapchain, GetCurrentThreadId());
+
+ if (!(ctx = context_create(swapchain, swapchain->front_buffer, swapchain->ds_format)))
+ {
+ ERR("Failed to create a new context for the swapchain\n");
+ return NULL;
+ }
+ context_release(ctx);
+
+ newArray = HeapAlloc(GetProcessHeap(), 0, sizeof(*newArray) * (swapchain->num_contexts + 1));
+ if(!newArray) {
+ ERR("Out of memory when trying to allocate a new context array\n");
+ context_destroy(swapchain->device, ctx);
+ return NULL;
+ }
+ memcpy(newArray, swapchain->context, sizeof(*newArray) * swapchain->num_contexts);
+ HeapFree(GetProcessHeap(), 0, swapchain->context);
+ newArray[swapchain->num_contexts] = ctx;
+ swapchain->context = newArray;
+ swapchain->num_contexts++;
+
+ TRACE("Returning context %p\n", ctx);
+ return ctx;
+}
+
+void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain)
+{
+ unsigned int i;
+
+ for (i = 0; i < swapchain->num_contexts; ++i)
+ {
+ context_destroy(swapchain->device, swapchain->context[i]);
+ }
+ swapchain->num_contexts = 0;
+}
+
+struct wined3d_context *swapchain_get_context(struct wined3d_swapchain *swapchain)
+{
+ DWORD tid = GetCurrentThreadId();
+ unsigned int i;
+
+ for (i = 0; i < swapchain->num_contexts; ++i)
+ {
+# ifdef VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT
+ if (VBoxTlsRefIsFunctional(swapchain->context[i]))
+# else
+ if (swapchain->context[i]->tid == tid)
+#endif
+ return swapchain->context[i];
+ }
+
+ /* Create a new context for the thread */
+ return swapchain_create_context(swapchain);
+}
+#else /* if defined VBOX_WINE_WITH_SINGLE_CONTEXT */
+struct wined3d_context *swapchain_get_context(struct wined3d_swapchain *swapchain)
+{
+ struct wined3d_context * context = swapchain->device->contexts[0];
+ return context;
+}
+#endif
+
+void get_drawable_size_swapchain(const struct wined3d_context *context, UINT *width, UINT *height)
+{
+ /* The drawable size of an onscreen drawable is the surface size.
+ * (Actually: The window size, but the surface is created in window size) */
+ *width = context->current_rt->resource.width;
+ *height = context->current_rt->resource.height;
+}
+
+#ifndef VBOX_WITH_WDDM
+HDC swapchain_get_backup_dc(struct wined3d_swapchain *swapchain)
+{
+ if (!swapchain->backup_dc)
+ {
+ TRACE("Creating the backup window for swapchain %p.\n", swapchain);
+
+ if (!(swapchain->backup_wnd = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D fake window",
+ WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL)))
+ {
+ ERR("Failed to create a window.\n");
+ return NULL;
+ }
+
+ if (!(swapchain->backup_dc = GetDC(swapchain->backup_wnd)))
+ {
+ ERR("Failed to get a DC.\n");
+ DestroyWindow(swapchain->backup_wnd);
+ swapchain->backup_wnd = NULL;
+ return NULL;
+ }
+ }
+
+ return swapchain->backup_dc;
+}
+#endif
+void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain)
+{
+ UINT i;
+
+ surface_update_draw_binding(swapchain->front_buffer);
+
+ for (i = 0; i < swapchain->desc.backbuffer_count; ++i)
+ {
+ surface_update_draw_binding(swapchain->back_buffers[i]);
+ }
+}
+
+#ifdef VBOX_WITH_WDDM
+HRESULT CDECL wined3d_swapchain_present_rt(struct wined3d_swapchain *swapchain, struct wined3d_surface *rt)
+{
+ struct wined3d_surface *bb = swapchain->back_buffers[0];
+ HRESULT hr = wined3d_surface_blt(bb, NULL, rt, NULL, 0, NULL, 0);
+ if (FAILED(hr))
+ {
+ ERR("wined3d_surface_blt failed with hr(%d)", hr);
+ return hr;
+ }
+
+ hr = wined3d_swapchain_present(swapchain, NULL, NULL, NULL, NULL, 0);
+ if (FAILED(hr))
+ {
+ ERR("wined3d_swapchain_present failed with hr(%d)", hr);
+ return hr;
+ }
+
+ return S_OK;
+}
+
+HRESULT CDECL wined3d_swapchain_get_host_win_id(struct wined3d_swapchain *swapchain, int32_t *pi32Id)
+{
+ int32_t id = pVBoxGetWindowId(swapchain->hDC);
+ if (!id)
+ {
+ *pi32Id = 0;
+ ERR("failed to get id for hdc 0x%x", swapchain->hDC);
+ return E_FAIL;
+ }
+ *pi32Id = id;
+ return S_OK;
+}
+#endif
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/texture.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/texture.c
new file mode 100644
index 00000000..99458d50
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/texture.c
@@ -0,0 +1,1791 @@
+/*
+ * Copyright 2002-2005 Jason Edmeades
+ * Copyright 2002-2005 Raphael Junqueira
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2007-2009, 2013 Stefan Dösinger for CodeWeavers
+ * Copyright 2009-2011 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+#include "wined3d_private.h"
+
+#ifdef VBOX_WITH_WDDM
+# include "../../common/VBoxVideoTools.h"
+#endif
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
+
+static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struct wined3d_texture_ops *texture_ops,
+ UINT layer_count, UINT level_count, const struct wined3d_resource_desc *desc, struct wined3d_device *device,
+ void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_resource_ops *resource_ops
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void **pavClientMem
+#endif
+ )
+{
+ const struct wined3d_format *format = wined3d_get_format(&device->adapter->gl_info, desc->format);
+ HRESULT hr;
+
+ TRACE("texture %p, texture_ops %p, layer_count %u, level_count %u, resource_type %s, format %s, "
+ "multisample_type %#x, multisample_quality %#x, usage %s, pool %s, width %u, height %u, depth %u, "
+ "device %p, parent %p, parent_ops %p, resource_ops %p.\n",
+ texture, texture_ops, layer_count, level_count, debug_d3dresourcetype(desc->resource_type),
+ debug_d3dformat(desc->format), desc->multisample_type, desc->multisample_quality,
+ debug_d3dusage(desc->usage), debug_d3dpool(desc->pool), desc->width, desc->height, desc->depth,
+ device, parent, parent_ops, resource_ops);
+
+#ifdef VBOX_WITH_WDDM
+ if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, format,
+ desc->multisample_type, desc->multisample_quality, desc->usage, desc->pool,
+ desc->width, desc->height, desc->depth, 0, parent, parent_ops, resource_ops,
+ shared_handle, pavClientMem ? pavClientMem[0] : NULL)))
+#else
+ if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, format,
+ desc->multisample_type, desc->multisample_quality, desc->usage, desc->pool,
+ desc->width, desc->height, desc->depth, 0, parent, parent_ops, resource_ops)))
+#endif
+ {
+ WARN("Failed to initialize resource, returning %#x\n", hr);
+ return hr;
+ }
+
+ texture->texture_ops = texture_ops;
+ texture->sub_resources = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ level_count * layer_count * sizeof(*texture->sub_resources));
+ if (!texture->sub_resources)
+ {
+ ERR("Failed to allocate sub-resource array.\n");
+ resource_cleanup(&texture->resource);
+ return E_OUTOFMEMORY;
+ }
+
+ texture->layer_count = layer_count;
+ texture->level_count = level_count;
+ texture->filter_type = (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3D_TEXF_LINEAR : WINED3D_TEXF_NONE;
+ texture->lod = 0;
+ texture->texture_rgb.dirty = TRUE;
+ texture->texture_srgb.dirty = TRUE;
+ texture->flags = WINED3D_TEXTURE_POW2_MAT_IDENT;
+
+ if (texture->resource.format->flags & WINED3DFMT_FLAG_FILTERING)
+ {
+ texture->min_mip_lookup = minMipLookup;
+ texture->mag_lookup = magLookup;
+ }
+ else
+ {
+ texture->min_mip_lookup = minMipLookup_noFilter;
+ texture->mag_lookup = magLookup_noFilter;
+ }
+
+ return WINED3D_OK;
+}
+
+/* A GL context is provided by the caller */
+static void gltexture_delete(const struct wined3d_gl_info *gl_info, struct gl_texture *tex)
+{
+#ifdef VBOX_WITH_WDDM
+ texture_gl_delete(tex->name);
+#else
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex->name);
+#endif
+ tex->name = 0;
+}
+
+static void wined3d_texture_unload(struct wined3d_texture *texture)
+{
+ struct wined3d_device *device = texture->resource.device;
+ struct wined3d_context *context = NULL;
+
+ if (texture->texture_rgb.name || texture->texture_srgb.name)
+ {
+ context = context_acquire(device, NULL);
+ }
+
+ if (texture->texture_rgb.name)
+ gltexture_delete(context->gl_info, &texture->texture_rgb);
+
+ if (texture->texture_srgb.name)
+ gltexture_delete(context->gl_info, &texture->texture_srgb);
+
+ if (context) context_release(context);
+
+ wined3d_texture_set_dirty(texture, TRUE);
+
+ resource_unload(&texture->resource);
+}
+
+static void wined3d_texture_cleanup(struct wined3d_texture *texture)
+{
+ UINT sub_count = texture->level_count * texture->layer_count;
+ UINT i;
+
+ TRACE("texture %p.\n", texture);
+
+#ifdef VBOX_WITH_WINE_FIX_TEXCLEAR
+ /* make texture unload first, because otherwise we may fail on context_acquire done for texture cleanup
+ * because the swapchain's surfaces might be destroyed and we may fail to select any render target in context_acquire */
+ wined3d_texture_unload(texture);
+#endif
+
+ for (i = 0; i < sub_count; ++i)
+ {
+ struct wined3d_resource *sub_resource = texture->sub_resources[i];
+
+ if (sub_resource)
+ texture->texture_ops->texture_sub_resource_cleanup(sub_resource);
+ }
+
+#ifndef VBOX_WITH_WINE_FIX_TEXCLEAR
+ wined3d_texture_unload(texture);
+#endif
+ HeapFree(GetProcessHeap(), 0, texture->sub_resources);
+ resource_cleanup(&texture->resource);
+}
+
+void wined3d_texture_set_dirty(struct wined3d_texture *texture, BOOL dirty)
+{
+ texture->texture_rgb.dirty = dirty;
+ texture->texture_srgb.dirty = dirty;
+}
+
+/* Context activation is done by the caller. */
+static HRESULT wined3d_texture_bind(struct wined3d_texture *texture,
+ struct wined3d_context *context, BOOL srgb, BOOL *set_surface_desc)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct gl_texture *gl_tex;
+ BOOL new_texture = FALSE;
+ HRESULT hr = WINED3D_OK;
+ GLenum target;
+
+ TRACE("texture %p, context %p, srgb %#x, set_surface_desc %p.\n", texture, context, srgb, set_surface_desc);
+
+ /* sRGB mode cache for preload() calls outside drawprim. */
+ if (srgb)
+ texture->flags |= WINED3D_TEXTURE_IS_SRGB;
+ else
+ texture->flags &= ~WINED3D_TEXTURE_IS_SRGB;
+
+ gl_tex = wined3d_texture_get_gl_texture(texture, context->gl_info, srgb);
+ target = texture->target;
+
+ /* Generate a texture name if we don't already have one. */
+ if (!gl_tex->name)
+ {
+#ifdef VBOX_WITH_WDDM
+ if (VBOXSHRC_IS_SHARED_OPENED(texture))
+ {
+ ERR("should not be here!");
+ gl_tex->name = (GLuint)VBOXSHRC_GET_SHAREHANDLE(texture);
+ pglChromiumParameteriCR(GL_RCUSAGE_TEXTURE_SET_CR, gl_tex->name);
+ TRACE("Assigned shared texture %d\n", gl_tex->name);
+ }
+ else
+#endif
+ {
+#ifdef VBOX_WITH_WDDM
+ new_texture = TRUE;
+#endif
+ *set_surface_desc = TRUE;
+ gl_info->gl_ops.gl.p_glGenTextures(1, &gl_tex->name);
+ checkGLcall("glGenTextures");
+ TRACE("Generated texture %d.\n", gl_tex->name);
+#ifdef VBOX_WITH_WDDM
+ if (VBOXSHRC_IS_SHARED(texture))
+ {
+ VBOXSHRC_SET_SHAREHANDLE(texture, gl_tex->name);
+ }
+#endif
+ }
+#ifndef VBOX
+ if (texture->resource.pool == WINED3D_POOL_DEFAULT)
+ {
+ /* Tell OpenGL to try and keep this texture in video ram (well mostly). */
+ GLclampf tmp = 0.9f;
+ gl_info->gl_ops.gl.p_glPrioritizeTextures(1, &gl_tex->name, &tmp);
+ }
+#else
+ /* chromium code on host fails to resolve texture name to texture obj,
+ * most likely because the texture does not get created until it is bound
+ * @todo: investigate */
+#endif
+ /* Initialise the state of the texture object to the OpenGL defaults,
+ * not the D3D defaults. */
+ gl_tex->states[WINED3DTEXSTA_ADDRESSU] = WINED3D_TADDRESS_WRAP;
+ gl_tex->states[WINED3DTEXSTA_ADDRESSV] = WINED3D_TADDRESS_WRAP;
+ gl_tex->states[WINED3DTEXSTA_ADDRESSW] = WINED3D_TADDRESS_WRAP;
+ gl_tex->states[WINED3DTEXSTA_BORDERCOLOR] = 0;
+ gl_tex->states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_LINEAR;
+ gl_tex->states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT; /* GL_NEAREST_MIPMAP_LINEAR */
+ gl_tex->states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_LINEAR; /* GL_NEAREST_MIPMAP_LINEAR */
+ gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] = 0;
+ gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] = 1;
+ if (context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
+ gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = TRUE;
+ else
+ gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = srgb;
+ gl_tex->states[WINED3DTEXSTA_SHADOW] = FALSE;
+ wined3d_texture_set_dirty(texture, TRUE);
+#ifndef VBOX_WITH_WDDM
+ new_texture = TRUE;
+#endif
+
+#ifdef VBOX_WITH_WDDM
+ if (new_texture
+ && texture->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP)
+#else
+ if (texture->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP)
+#endif
+ {
+ /* This means double binding the texture at creation, but keeps
+ * the code simpler all in all, and the run-time path free from
+ * additional checks. */
+ context_bind_texture(context, target, gl_tex->name);
+ gl_info->gl_ops.gl.p_glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
+ checkGLcall("glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE)");
+ }
+ }
+ else
+ {
+ *set_surface_desc = FALSE;
+ }
+
+ if (gl_tex->name)
+ {
+ context_bind_texture(context, target, gl_tex->name);
+ if (new_texture)
+ {
+ /* For a new texture we have to set the texture levels after
+ * binding the texture. Beware that texture rectangles do not
+ * support mipmapping, but set the maxmiplevel if we're relying
+ * on the partial GL_ARB_texture_non_power_of_two emulation with
+ * texture rectangles. (I.e., do not care about cond_np2 here,
+ * just look for GL_TEXTURE_RECTANGLE_ARB.) */
+ if (target != GL_TEXTURE_RECTANGLE_ARB)
+ {
+ TRACE("Setting GL_TEXTURE_MAX_LEVEL to %u.\n", texture->level_count - 1);
+ gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, texture->level_count - 1);
+ checkGLcall("glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, texture->level_count)");
+ }
+ if (target == GL_TEXTURE_CUBE_MAP_ARB)
+ {
+ /* Cubemaps are always set to clamp, regardless of the sampler state. */
+ gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+ }
+ }
+ }
+ else
+ {
+ ERR("This texture doesn't have an OpenGL texture assigned to it.\n");
+ hr = WINED3DERR_INVALIDCALL;
+ }
+
+ return hr;
+}
+
+/* Context activation is done by the caller. */
+static void apply_wrap(const struct wined3d_gl_info *gl_info, GLenum target,
+ enum wined3d_texture_address d3d_wrap, GLenum param, BOOL cond_np2)
+{
+ GLint gl_wrap;
+
+ if (d3d_wrap < WINED3D_TADDRESS_WRAP || d3d_wrap > WINED3D_TADDRESS_MIRROR_ONCE)
+ {
+ FIXME("Unrecognized or unsupported texture address mode %#x.\n", d3d_wrap);
+ return;
+ }
+
+ /* Cubemaps are always set to clamp, regardless of the sampler state. */
+ if (target == GL_TEXTURE_CUBE_MAP_ARB
+ || (cond_np2 && d3d_wrap == WINED3D_TADDRESS_WRAP))
+ gl_wrap = GL_CLAMP_TO_EDGE;
+ else
+ gl_wrap = gl_info->wrap_lookup[d3d_wrap - WINED3D_TADDRESS_WRAP];
+
+ TRACE("Setting param %#x to %#x for target %#x.\n", param, gl_wrap, target);
+ gl_info->gl_ops.gl.p_glTexParameteri(target, param, gl_wrap);
+ checkGLcall("glTexParameteri(target, param, gl_wrap)");
+}
+
+/* Context activation is done by the caller (state handler). */
+void wined3d_texture_apply_state_changes(struct wined3d_texture *texture,
+ const DWORD sampler_states[WINED3D_HIGHEST_SAMPLER_STATE + 1],
+ const struct wined3d_gl_info *gl_info)
+{
+ BOOL cond_np2 = texture->flags & WINED3D_TEXTURE_COND_NP2;
+ GLenum target = texture->target;
+ struct gl_texture *gl_tex;
+ DWORD state;
+ DWORD aniso;
+
+ TRACE("texture %p, sampler_states %p.\n", texture, sampler_states);
+
+ gl_tex = wined3d_texture_get_gl_texture(texture, gl_info,
+ texture->flags & WINED3D_TEXTURE_IS_SRGB);
+
+ /* This function relies on the correct texture being bound and loaded. */
+
+ if (sampler_states[WINED3D_SAMP_ADDRESS_U] != gl_tex->states[WINED3DTEXSTA_ADDRESSU])
+ {
+ state = sampler_states[WINED3D_SAMP_ADDRESS_U];
+ apply_wrap(gl_info, target, state, GL_TEXTURE_WRAP_S, cond_np2);
+ gl_tex->states[WINED3DTEXSTA_ADDRESSU] = state;
+ }
+
+ if (sampler_states[WINED3D_SAMP_ADDRESS_V] != gl_tex->states[WINED3DTEXSTA_ADDRESSV])
+ {
+ state = sampler_states[WINED3D_SAMP_ADDRESS_V];
+ apply_wrap(gl_info, target, state, GL_TEXTURE_WRAP_T, cond_np2);
+ gl_tex->states[WINED3DTEXSTA_ADDRESSV] = state;
+ }
+
+ if (sampler_states[WINED3D_SAMP_ADDRESS_W] != gl_tex->states[WINED3DTEXSTA_ADDRESSW])
+ {
+ state = sampler_states[WINED3D_SAMP_ADDRESS_W];
+ apply_wrap(gl_info, target, state, GL_TEXTURE_WRAP_R, cond_np2);
+ gl_tex->states[WINED3DTEXSTA_ADDRESSW] = state;
+ }
+
+ if (sampler_states[WINED3D_SAMP_BORDER_COLOR] != gl_tex->states[WINED3DTEXSTA_BORDERCOLOR])
+ {
+ float col[4];
+
+ state = sampler_states[WINED3D_SAMP_BORDER_COLOR];
+ D3DCOLORTOGLFLOAT4(state, col);
+ TRACE("Setting border color for %#x to %#x.\n", target, state);
+ gl_info->gl_ops.gl.p_glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, &col[0]);
+ checkGLcall("glTexParameterfv(..., GL_TEXTURE_BORDER_COLOR, ...)");
+ gl_tex->states[WINED3DTEXSTA_BORDERCOLOR] = state;
+ }
+
+ if (sampler_states[WINED3D_SAMP_MAG_FILTER] != gl_tex->states[WINED3DTEXSTA_MAGFILTER])
+ {
+ GLint gl_value;
+
+ state = sampler_states[WINED3D_SAMP_MAG_FILTER];
+ if (state > WINED3D_TEXF_ANISOTROPIC)
+ FIXME("Unrecognized or unsupported MAGFILTER* value %d.\n", state);
+
+ gl_value = wined3d_gl_mag_filter(texture->mag_lookup,
+ min(max(state, WINED3D_TEXF_POINT), WINED3D_TEXF_LINEAR));
+ TRACE("ValueMAG=%#x setting MAGFILTER to %#x.\n", state, gl_value);
+ gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, gl_value);
+
+ gl_tex->states[WINED3DTEXSTA_MAGFILTER] = state;
+ }
+
+ if ((sampler_states[WINED3D_SAMP_MIN_FILTER] != gl_tex->states[WINED3DTEXSTA_MINFILTER]
+ || sampler_states[WINED3D_SAMP_MIP_FILTER] != gl_tex->states[WINED3DTEXSTA_MIPFILTER]
+ || sampler_states[WINED3D_SAMP_MAX_MIP_LEVEL] != gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL]))
+ {
+ GLint gl_value;
+
+ gl_tex->states[WINED3DTEXSTA_MIPFILTER] = sampler_states[WINED3D_SAMP_MIP_FILTER];
+ gl_tex->states[WINED3DTEXSTA_MINFILTER] = sampler_states[WINED3D_SAMP_MIN_FILTER];
+ gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] = sampler_states[WINED3D_SAMP_MAX_MIP_LEVEL];
+
+ if (gl_tex->states[WINED3DTEXSTA_MINFILTER] > WINED3D_TEXF_ANISOTROPIC
+ || gl_tex->states[WINED3DTEXSTA_MIPFILTER] > WINED3D_TEXF_ANISOTROPIC)
+ {
+ FIXME("Unrecognized or unsupported MIN_FILTER value %#x MIP_FILTER value %#x.\n",
+ gl_tex->states[WINED3DTEXSTA_MINFILTER],
+ gl_tex->states[WINED3DTEXSTA_MIPFILTER]);
+ }
+ gl_value = wined3d_gl_min_mip_filter(texture->min_mip_lookup,
+ min(max(sampler_states[WINED3D_SAMP_MIN_FILTER], WINED3D_TEXF_POINT), WINED3D_TEXF_LINEAR),
+ min(max(sampler_states[WINED3D_SAMP_MIP_FILTER], WINED3D_TEXF_NONE), WINED3D_TEXF_LINEAR));
+
+ TRACE("ValueMIN=%#x, ValueMIP=%#x, setting MINFILTER to %#x.\n",
+ sampler_states[WINED3D_SAMP_MIN_FILTER],
+ sampler_states[WINED3D_SAMP_MIP_FILTER], gl_value);
+ gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MIN_FILTER, gl_value);
+ checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ...");
+
+ if (!cond_np2)
+ {
+ if (gl_tex->states[WINED3DTEXSTA_MIPFILTER] == WINED3D_TEXF_NONE)
+ gl_value = texture->lod;
+ else if (gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] >= texture->level_count)
+ gl_value = texture->level_count - 1;
+ else if (gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] < texture->lod)
+ /* texture->lod is already clamped in the setter. */
+ gl_value = texture->lod;
+ else
+ gl_value = gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL];
+
+ /* Note that WINED3D_SAMP_MAX_MIP_LEVEL specifies the largest mipmap
+ * (default 0), while GL_TEXTURE_MAX_LEVEL specifies the smallest
+ * mimap used (default 1000). So WINED3D_SAMP_MAX_MIP_LEVEL
+ * corresponds to GL_TEXTURE_BASE_LEVEL. */
+ gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, gl_value);
+ }
+ }
+
+ if ((gl_tex->states[WINED3DTEXSTA_MAGFILTER] != WINED3D_TEXF_ANISOTROPIC
+ && gl_tex->states[WINED3DTEXSTA_MINFILTER] != WINED3D_TEXF_ANISOTROPIC
+ && gl_tex->states[WINED3DTEXSTA_MIPFILTER] != WINED3D_TEXF_ANISOTROPIC)
+ || cond_np2)
+ aniso = 1;
+ else
+ aniso = sampler_states[WINED3D_SAMP_MAX_ANISOTROPY];
+
+ if (gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] != aniso)
+ {
+ if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
+ {
+ gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso);
+ checkGLcall("glTexParameteri(GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso)");
+ }
+ else
+ {
+ WARN("Anisotropic filtering not supported.\n");
+ }
+ gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] = aniso;
+ }
+
+ /* These should always be the same unless EXT_texture_sRGB_decode is supported. */
+ if (sampler_states[WINED3D_SAMP_SRGB_TEXTURE] != gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE])
+ {
+ gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT,
+ sampler_states[WINED3D_SAMP_SRGB_TEXTURE] ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT);
+ checkGLcall("glTexParameteri(GL_TEXTURE_SRGB_DECODE_EXT)");
+ gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = sampler_states[WINED3D_SAMP_SRGB_TEXTURE];
+ }
+
+ if (!(texture->resource.format->flags & WINED3DFMT_FLAG_SHADOW)
+ != !gl_tex->states[WINED3DTEXSTA_SHADOW])
+ {
+ if (texture->resource.format->flags & WINED3DFMT_FLAG_SHADOW)
+ {
+ gl_info->gl_ops.gl.p_glTexParameteri(target, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
+ gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
+ checkGLcall("glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB)");
+ gl_tex->states[WINED3DTEXSTA_SHADOW] = TRUE;
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
+ checkGLcall("glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE)");
+ gl_tex->states[WINED3DTEXSTA_SHADOW] = FALSE;
+ }
+ }
+}
+
+ULONG CDECL wined3d_texture_incref(struct wined3d_texture *texture)
+{
+ ULONG refcount = InterlockedIncrement(&texture->resource.ref);
+
+ TRACE("%p increasing refcount to %u.\n", texture, refcount);
+
+ return refcount;
+}
+
+/* Do not call while under the GL lock. */
+ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture)
+{
+ ULONG refcount = InterlockedDecrement(&texture->resource.ref);
+
+ TRACE("%p decreasing refcount to %u.\n", texture, refcount);
+
+ if (!refcount)
+ {
+ wined3d_texture_cleanup(texture);
+ texture->resource.parent_ops->wined3d_object_destroyed(texture->resource.parent);
+ HeapFree(GetProcessHeap(), 0, texture);
+ }
+
+ return refcount;
+}
+
+struct wined3d_resource * CDECL wined3d_texture_get_resource(struct wined3d_texture *texture)
+{
+ TRACE("texture %p.\n", texture);
+
+ return &texture->resource;
+}
+
+DWORD CDECL wined3d_texture_set_priority(struct wined3d_texture *texture, DWORD priority)
+{
+ return resource_set_priority(&texture->resource, priority);
+}
+
+DWORD CDECL wined3d_texture_get_priority(const struct wined3d_texture *texture)
+{
+ return resource_get_priority(&texture->resource);
+}
+
+/* Do not call while under the GL lock. */
+void CDECL wined3d_texture_preload(struct wined3d_texture *texture)
+{
+ texture->texture_ops->texture_preload(texture, SRGB_ANY);
+}
+
+void * CDECL wined3d_texture_get_parent(const struct wined3d_texture *texture)
+{
+ TRACE("texture %p.\n", texture);
+
+ return texture->resource.parent;
+}
+
+DWORD CDECL wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod)
+{
+ DWORD old = texture->lod;
+
+ TRACE("texture %p, lod %u.\n", texture, lod);
+
+ /* The d3d9:texture test shows that SetLOD is ignored on non-managed
+ * textures. The call always returns 0, and GetLOD always returns 0. */
+ if (texture->resource.pool != WINED3D_POOL_MANAGED)
+ {
+ TRACE("Ignoring SetLOD on %s texture, returning 0.\n", debug_d3dpool(texture->resource.pool));
+ return 0;
+ }
+
+ if (lod >= texture->level_count)
+ lod = texture->level_count - 1;
+
+ if (texture->lod != lod)
+ {
+ texture->lod = lod;
+
+ texture->texture_rgb.states[WINED3DTEXSTA_MAXMIPLEVEL] = ~0U;
+ texture->texture_srgb.states[WINED3DTEXSTA_MAXMIPLEVEL] = ~0U;
+ if (texture->resource.bind_count)
+ device_invalidate_state(texture->resource.device, STATE_SAMPLER(texture->sampler));
+ }
+
+ return old;
+}
+
+DWORD CDECL wined3d_texture_get_lod(const struct wined3d_texture *texture)
+{
+ TRACE("texture %p, returning %u.\n", texture, texture->lod);
+
+ return texture->lod;
+}
+
+DWORD CDECL wined3d_texture_get_level_count(const struct wined3d_texture *texture)
+{
+ TRACE("texture %p, returning %u.\n", texture, texture->level_count);
+
+ return texture->level_count;
+}
+
+HRESULT CDECL wined3d_texture_set_autogen_filter_type(struct wined3d_texture *texture,
+ enum wined3d_texture_filter_type filter_type)
+{
+ FIXME("texture %p, filter_type %s stub!\n", texture, debug_d3dtexturefiltertype(filter_type));
+
+ if (!(texture->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP))
+ {
+ WARN("Texture doesn't have AUTOGENMIPMAP usage.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ texture->filter_type = filter_type;
+
+ return WINED3D_OK;
+}
+
+enum wined3d_texture_filter_type CDECL wined3d_texture_get_autogen_filter_type(const struct wined3d_texture *texture)
+{
+ TRACE("texture %p.\n", texture);
+
+ return texture->filter_type;
+}
+
+void CDECL wined3d_texture_generate_mipmaps(struct wined3d_texture *texture)
+{
+ /* TODO: Implement filters using GL_SGI_generate_mipmaps. */
+ FIXME("texture %p stub!\n", texture);
+}
+
+struct wined3d_resource * CDECL wined3d_texture_get_sub_resource(struct wined3d_texture *texture,
+ UINT sub_resource_idx)
+{
+ UINT sub_count = texture->level_count * texture->layer_count;
+
+ TRACE("texture %p, sub_resource_idx %u.\n", texture, sub_resource_idx);
+
+ if (sub_resource_idx >= sub_count)
+ {
+ WARN("sub_resource_idx %u >= sub_count %u.\n", sub_resource_idx, sub_count);
+ return NULL;
+ }
+
+ return texture->sub_resources[sub_resource_idx];
+}
+
+HRESULT CDECL wined3d_texture_add_dirty_region(struct wined3d_texture *texture,
+ UINT layer, const struct wined3d_box *dirty_region)
+{
+ struct wined3d_resource *sub_resource;
+
+ TRACE("texture %p, layer %u, dirty_region %p.\n", texture, layer, dirty_region);
+
+ if (!(sub_resource = wined3d_texture_get_sub_resource(texture, layer * texture->level_count)))
+ {
+ WARN("Failed to get sub-resource.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ wined3d_texture_set_dirty(texture, TRUE);
+ texture->texture_ops->texture_sub_resource_add_dirty_region(sub_resource, dirty_region);
+
+ return WINED3D_OK;
+}
+
+/* Context activation is done by the caller. */
+static HRESULT texture2d_bind(struct wined3d_texture *texture,
+ struct wined3d_context *context, BOOL srgb)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ BOOL set_gl_texture_desc;
+ HRESULT hr;
+
+ TRACE("texture %p, context %p, srgb %#x.\n", texture, context, srgb);
+
+ hr = wined3d_texture_bind(texture, context, srgb, &set_gl_texture_desc);
+ if (set_gl_texture_desc && SUCCEEDED(hr))
+ {
+ UINT sub_count = texture->level_count * texture->layer_count;
+ BOOL srgb_tex = !context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE]
+ && (texture->flags & WINED3D_TEXTURE_IS_SRGB);
+ struct gl_texture *gl_tex;
+ UINT i;
+
+ gl_tex = wined3d_texture_get_gl_texture(texture, context->gl_info, srgb_tex);
+
+ for (i = 0; i < sub_count; ++i)
+ {
+ struct wined3d_surface *surface = surface_from_resource(texture->sub_resources[i]);
+ surface_set_texture_name(surface, gl_tex->name, srgb_tex);
+ }
+
+ /* Conditinal non power of two textures use a different clamping
+ * default. If we're using the GL_WINE_normalized_texrect partial
+ * driver emulation, we're dealing with a GL_TEXTURE_2D texture which
+ * has the address mode set to repeat - something that prevents us
+ * from hitting the accelerated codepath. Thus manually set the GL
+ * state. The same applies to filtering. Even if the texture has only
+ * one mip level, the default LINEAR_MIPMAP_LINEAR filter causes a SW
+ * fallback on macos. */
+ if (texture->flags & WINED3D_TEXTURE_COND_NP2)
+ {
+#ifdef VBOX_WITH_WDDM
+ Assert(!VBOXSHRC_IS_SHARED_OPENED(texture));
+ if (!VBOXSHRC_IS_SHARED_OPENED(texture))
+#endif
+ {
+ GLenum target = texture->target;
+
+ gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ checkGLcall("glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)");
+ gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ checkGLcall("glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)");
+ gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ checkGLcall("glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST)");
+ gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ checkGLcall("glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST)");
+ }
+ gl_tex->states[WINED3DTEXSTA_ADDRESSU] = WINED3D_TADDRESS_CLAMP;
+ gl_tex->states[WINED3DTEXSTA_ADDRESSV] = WINED3D_TADDRESS_CLAMP;
+ gl_tex->states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_POINT;
+ gl_tex->states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT;
+ gl_tex->states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_NONE;
+ }
+ }
+
+ return hr;
+}
+
+static BOOL texture_srgb_mode(const struct wined3d_texture *texture, enum WINED3DSRGB srgb)
+{
+ switch (srgb)
+ {
+ case SRGB_RGB:
+ return FALSE;
+
+ case SRGB_SRGB:
+ return TRUE;
+
+ default:
+ return texture->flags & WINED3D_TEXTURE_IS_SRGB;
+ }
+}
+
+/* Do not call while under the GL lock. */
+static void texture2d_preload(struct wined3d_texture *texture, enum WINED3DSRGB srgb)
+{
+ UINT sub_count = texture->level_count * texture->layer_count;
+ struct wined3d_device *device = texture->resource.device;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ struct wined3d_context *context = NULL;
+ struct gl_texture *gl_tex;
+ BOOL srgb_mode;
+ UINT i;
+
+ TRACE("texture %p, srgb %#x.\n", texture, srgb);
+
+ srgb_mode = texture_srgb_mode(texture, srgb);
+ gl_tex = wined3d_texture_get_gl_texture(texture, gl_info, srgb_mode);
+
+ if (!device->isInDraw)
+ {
+ /* No danger of recursive calls, context_acquire() sets isInDraw to TRUE
+ * when loading offscreen render targets into the texture. */
+ context = context_acquire(device, NULL);
+ }
+
+ if (gl_tex->dirty)
+ {
+ /* Reload the surfaces if the texture is marked dirty. */
+ for (i = 0; i < sub_count; ++i)
+ {
+ surface_load(surface_from_resource(texture->sub_resources[i]), srgb_mode);
+ }
+ }
+ else
+ {
+ TRACE("Texture %p not dirty, nothing to do.\n", texture);
+ }
+
+ /* No longer dirty. */
+ gl_tex->dirty = FALSE;
+
+ if (context) context_release(context);
+}
+
+static void texture2d_sub_resource_add_dirty_region(struct wined3d_resource *sub_resource,
+ const struct wined3d_box *dirty_region)
+{
+ surface_add_dirty_rect(surface_from_resource(sub_resource), dirty_region);
+}
+
+static void texture2d_sub_resource_cleanup(struct wined3d_resource *sub_resource)
+{
+ struct wined3d_surface *surface = surface_from_resource(sub_resource);
+
+ /* Clean out the texture name we gave to the surface so that the
+ * surface doesn't try and release it. */
+ surface_set_texture_name(surface, 0, TRUE);
+ surface_set_texture_name(surface, 0, FALSE);
+ surface_set_texture_target(surface, 0, 0);
+ surface_set_container(surface, NULL);
+ wined3d_surface_decref(surface);
+}
+
+/* Do not call while under the GL lock. */
+static void texture2d_unload(struct wined3d_resource *resource)
+{
+ struct wined3d_texture *texture = wined3d_texture_from_resource(resource);
+ UINT sub_count = texture->level_count * texture->layer_count;
+ UINT i;
+
+ TRACE("texture %p.\n", texture);
+
+ for (i = 0; i < sub_count; ++i)
+ {
+ struct wined3d_resource *sub_resource = texture->sub_resources[i];
+ struct wined3d_surface *surface = surface_from_resource(sub_resource);
+
+ sub_resource->resource_ops->resource_unload(sub_resource);
+ surface_set_texture_name(surface, 0, FALSE); /* Delete RGB name */
+ surface_set_texture_name(surface, 0, TRUE); /* Delete sRGB name */
+ }
+
+ wined3d_texture_unload(texture);
+}
+
+static const struct wined3d_texture_ops texture2d_ops =
+{
+ texture2d_bind,
+ texture2d_preload,
+ texture2d_sub_resource_add_dirty_region,
+ texture2d_sub_resource_cleanup,
+};
+
+static const struct wined3d_resource_ops texture2d_resource_ops =
+{
+ texture2d_unload,
+};
+
+static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
+ UINT levels, DWORD surface_flags, struct wined3d_device *device, void *parent,
+ const struct wined3d_parent_ops *parent_ops
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void **pavClientMem
+#endif
+ )
+{
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ struct wined3d_resource_desc surface_desc;
+ unsigned int i, j;
+ HRESULT hr;
+
+ /* TODO: It should only be possible to create textures for formats
+ * that are reported as supported. */
+ if (WINED3DFMT_UNKNOWN >= desc->format)
+ {
+ WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (!gl_info->supported[ARB_TEXTURE_CUBE_MAP] && desc->pool != WINED3D_POOL_SCRATCH)
+ {
+ WARN("(%p) : Tried to create not supported cube texture.\n", texture);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ /* Calculate levels for mip mapping */
+ if (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP)
+ {
+ if (!gl_info->supported[SGIS_GENERATE_MIPMAP])
+ {
+ WARN("No mipmap generation support, returning D3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (levels > 1)
+ {
+ WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ levels = 1;
+ }
+ else if (!levels)
+ {
+ levels = wined3d_log2i(desc->width) + 1;
+ TRACE("Calculated levels = %u.\n", levels);
+ }
+
+ if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
+ {
+ UINT pow2_edge_length = 1;
+ while (pow2_edge_length < desc->width)
+ pow2_edge_length <<= 1;
+
+ if (desc->width != pow2_edge_length)
+ {
+ if (desc->pool == WINED3D_POOL_SCRATCH)
+ {
+ /* SCRATCH textures cannot be used for texturing */
+ WARN("Creating a scratch NPOT cube texture despite lack of HW support.\n");
+ }
+ else
+ {
+ WARN("Attempted to create a NPOT cube texture (edge length %u) without GL support.\n", desc->width);
+ return WINED3DERR_INVALIDCALL;
+ }
+ }
+ }
+
+#ifdef VBOX_WITH_WDDM
+ if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 6, levels,
+ desc, device, parent, parent_ops, &texture2d_resource_ops,
+ shared_handle, pavClientMem)))
+#else
+ if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 6, levels,
+ desc, device, parent, parent_ops, &texture2d_resource_ops)))
+#endif
+ {
+ WARN("Failed to initialize texture, returning %#x\n", hr);
+ return hr;
+ }
+
+ texture->pow2_matrix[0] = 1.0f;
+ texture->pow2_matrix[5] = 1.0f;
+ texture->pow2_matrix[10] = 1.0f;
+ texture->pow2_matrix[15] = 1.0f;
+ texture->target = GL_TEXTURE_CUBE_MAP_ARB;
+
+ /* Generate all the surfaces. */
+ surface_desc = *desc;
+ surface_desc.resource_type = WINED3D_RTYPE_SURFACE;
+ for (i = 0; i < texture->level_count; ++i)
+ {
+ /* Create the 6 faces. */
+ for (j = 0; j < 6; ++j)
+ {
+ static const GLenum cube_targets[6] =
+ {
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
+ };
+ UINT idx = j * texture->level_count + i;
+ struct wined3d_surface *surface;
+
+
+#ifdef VBOX_WITH_WDDM
+ if (FAILED(hr = device->device_parent->ops->create_texture_surface(device->device_parent,
+ parent, &surface_desc, idx, surface_flags, &surface
+ ,NULL, pavClientMem ? pavClientMem[i * 6 + j] : NULL
+ )))
+#else
+ if (FAILED(hr = device->device_parent->ops->create_texture_surface(device->device_parent,
+ parent, &surface_desc, idx, surface_flags, &surface)))
+#endif
+ {
+ FIXME("(%p) Failed to create surface, hr %#x.\n", texture, hr);
+ wined3d_texture_cleanup(texture);
+ return hr;
+ }
+
+ surface_set_container(surface, texture);
+ surface_set_texture_target(surface, cube_targets[j], i);
+ texture->sub_resources[idx] = &surface->resource;
+ TRACE("Created surface level %u @ %p.\n", i, surface);
+ }
+ surface_desc.width = max(1, surface_desc.width >> 1);
+ surface_desc.height = surface_desc.width;
+ }
+
+#ifdef VBOX_WITH_WDDM
+ if (VBOXSHRC_IS_SHARED(texture))
+ {
+ Assert(shared_handle);
+ for (i = 0; i < texture->level_count; ++i)
+ {
+ for (j = 0; j < 6; ++j)
+ {
+ UINT idx = j * texture->level_count + i;
+ VBOXSHRC_COPY_SHAREDATA(surface_from_resource(texture->sub_resources[idx]), texture);
+ }
+ }
+#ifdef DEBUG
+ for (i = 0; i < texture->level_count; ++i)
+ {
+ for (j = 0; j < 6; ++j)
+ {
+ UINT idx = j * texture->level_count + i;
+ Assert(!surface_from_resource(texture->sub_resources[idx])->texture_name);
+ }
+ }
+#endif
+
+ if (!VBOXSHRC_IS_SHARED_OPENED(texture))
+ {
+ for (i = 0; i < texture->level_count; ++i)
+ {
+ for (j = 0; j < 6; ++j)
+ {
+ UINT idx = j * texture->level_count + i;
+ struct wined3d_surface *surface = surface_from_resource(texture->sub_resources[idx]);
+ surface_load_location(surface, SFLAG_INTEXTURE, NULL);
+ }
+ }
+
+ Assert(!(*shared_handle));
+ *shared_handle = VBOXSHRC_GET_SHAREHANDLE(texture);
+ }
+ else
+ {
+ struct wined3d_context *context = NULL;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ struct gl_texture *gl_tex = wined3d_texture_get_gl_texture(texture, gl_info, FALSE);
+ texture->texture_rgb.name = (GLuint)VBOXSHRC_GET_SHAREHANDLE(texture);
+ gl_tex->states[WINED3DTEXSTA_ADDRESSU] = WINED3D_TADDRESS_WRAP;
+ gl_tex->states[WINED3DTEXSTA_ADDRESSV] = WINED3D_TADDRESS_WRAP;
+ gl_tex->states[WINED3DTEXSTA_ADDRESSW] = WINED3D_TADDRESS_WRAP;
+ gl_tex->states[WINED3DTEXSTA_BORDERCOLOR] = 0;
+ gl_tex->states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_LINEAR;
+ gl_tex->states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT; /* GL_NEAREST_MIPMAP_LINEAR */
+ gl_tex->states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_LINEAR; /* GL_NEAREST_MIPMAP_LINEAR */
+ gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] = 0;
+ gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] = 1;
+ if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
+ gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = TRUE;
+ else
+ gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = FALSE;
+ gl_tex->states[WINED3DTEXSTA_SHADOW] = FALSE;
+ wined3d_texture_set_dirty(texture, TRUE);
+
+ context = context_acquire(device, NULL);
+ pglChromiumParameteriCR(GL_RCUSAGE_TEXTURE_SET_CR, (GLuint)VBOXSHRC_GET_SHAREHANDLE(texture));
+ context_release(context);
+
+ for (i = 0; i < texture->level_count; ++i)
+ {
+ for (j = 0; j < 6; ++j)
+ {
+ UINT idx = j * texture->level_count + i;
+ struct wined3d_surface *surface = surface_from_resource(texture->sub_resources[idx]);
+ surface_setup_location_onopen(surface);
+ Assert(*shared_handle);
+ Assert(*shared_handle == VBOXSHRC_GET_SHAREHANDLE(texture));
+ }
+ }
+ }
+#ifdef DEBUG
+ for (i = 0; i < texture->level_count; ++i)
+ {
+ for (j = 0; j < 6; ++j)
+ {
+ UINT idx = j * texture->level_count + i;
+ Assert((GLuint)(*shared_handle) == surface_from_resource(texture->sub_resources[idx])->texture_name);
+ }
+ }
+#endif
+
+#ifdef DEBUG
+ for (i = 0; i < texture->level_count; ++i)
+ {
+ for (j = 0; j < 6; ++j)
+ {
+ UINT idx = j * texture->level_count + i;
+ Assert((GLuint)(*shared_handle) == surface_from_resource(texture->sub_resources[idx])->texture_name);
+ }
+ }
+#endif
+
+ Assert(!device->isInDraw);
+
+ /* flush to ensure the texture is allocated/referenced before it is used/released by another
+ * process opening/creating it */
+ Assert(device->context_count == 1);
+ pVBoxFlushToHost(device->contexts[0]->glCtx);
+ }
+ else
+ {
+ Assert(!shared_handle);
+ }
+#endif
+
+ return WINED3D_OK;
+}
+
+static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
+ UINT levels, DWORD surface_flags, struct wined3d_device *device, void *parent,
+ const struct wined3d_parent_ops *parent_ops
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void **pavClientMem
+#endif
+ )
+{
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ struct wined3d_resource_desc surface_desc;
+ UINT pow2_width, pow2_height;
+ unsigned int i;
+ HRESULT hr;
+
+ /* TODO: It should only be possible to create textures for formats
+ * that are reported as supported. */
+ if (WINED3DFMT_UNKNOWN >= desc->format)
+ {
+ WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ /* Non-power2 support. */
+ if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
+ {
+ pow2_width = desc->width;
+ pow2_height = desc->height;
+ }
+ else
+ {
+ /* Find the nearest pow2 match. */
+ pow2_width = pow2_height = 1;
+ while (pow2_width < desc->width)
+ pow2_width <<= 1;
+ while (pow2_height < desc->height)
+ pow2_height <<= 1;
+
+ if (pow2_width != desc->width || pow2_height != desc->height)
+ {
+ /* levels == 0 returns an error as well */
+ if (levels != 1)
+ {
+ if (desc->pool == WINED3D_POOL_SCRATCH)
+ {
+ WARN("Creating a scratch mipmapped NPOT texture despite lack of HW support.\n");
+ }
+ else
+ {
+ WARN("Attempted to create a mipmapped NPOT texture without unconditional NPOT support.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+ }
+ }
+ }
+
+ /* Calculate levels for mip mapping. */
+ if (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP)
+ {
+ if (!gl_info->supported[SGIS_GENERATE_MIPMAP])
+ {
+ WARN("No mipmap generation support, returning WINED3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (levels > 1)
+ {
+ WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning WINED3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ levels = 1;
+ }
+ else if (!levels)
+ {
+ levels = wined3d_log2i(max(desc->width, desc->height)) + 1;
+ TRACE("Calculated levels = %u.\n", levels);
+ }
+
+#ifdef VBOX_WITH_WDDM
+ if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 1, levels,
+ desc, device, parent, parent_ops, &texture2d_resource_ops,
+ shared_handle, pavClientMem)))
+#else
+ if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 1, levels,
+ desc, device, parent, parent_ops, &texture2d_resource_ops)))
+#endif
+ {
+ WARN("Failed to initialize texture, returning %#x.\n", hr);
+ return hr;
+ }
+
+ /* Precalculated scaling for 'faked' non power of two texture coords.
+ * Second also don't use ARB_TEXTURE_RECTANGLE in case the surface format is P8 and EXT_PALETTED_TEXTURE
+ * is used in combination with texture uploads (RTL_READTEX). The reason is that EXT_PALETTED_TEXTURE
+ * doesn't work in combination with ARB_TEXTURE_RECTANGLE. */
+ if (gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT]
+ && (desc->width != pow2_width || desc->height != pow2_height))
+ {
+ texture->pow2_matrix[0] = 1.0f;
+ texture->pow2_matrix[5] = 1.0f;
+ texture->pow2_matrix[10] = 1.0f;
+ texture->pow2_matrix[15] = 1.0f;
+ texture->target = GL_TEXTURE_2D;
+ texture->flags |= WINED3D_TEXTURE_COND_NP2;
+ texture->min_mip_lookup = minMipLookup_noFilter;
+ }
+ else if (gl_info->supported[ARB_TEXTURE_RECTANGLE] && (desc->width != pow2_width || desc->height != pow2_height)
+ && !(desc->format == WINED3DFMT_P8_UINT && gl_info->supported[EXT_PALETTED_TEXTURE]
+ && wined3d_settings.rendertargetlock_mode == RTL_READTEX))
+ {
+ texture->pow2_matrix[0] = (float)desc->width;
+ texture->pow2_matrix[5] = (float)desc->height;
+ texture->pow2_matrix[10] = 1.0f;
+ texture->pow2_matrix[15] = 1.0f;
+ texture->target = GL_TEXTURE_RECTANGLE_ARB;
+ texture->flags |= WINED3D_TEXTURE_COND_NP2;
+ texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT;
+
+ if (texture->resource.format->flags & WINED3DFMT_FLAG_FILTERING)
+ texture->min_mip_lookup = minMipLookup_noMip;
+ else
+ texture->min_mip_lookup = minMipLookup_noFilter;
+ }
+ else
+ {
+ if ((desc->width != pow2_width) || (desc->height != pow2_height))
+ {
+ texture->pow2_matrix[0] = (((float)desc->width) / ((float)pow2_width));
+ texture->pow2_matrix[5] = (((float)desc->height) / ((float)pow2_height));
+ texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT;
+ }
+ else
+ {
+ texture->pow2_matrix[0] = 1.0f;
+ texture->pow2_matrix[5] = 1.0f;
+ }
+
+ texture->pow2_matrix[10] = 1.0f;
+ texture->pow2_matrix[15] = 1.0f;
+ texture->target = GL_TEXTURE_2D;
+ }
+ TRACE("xf(%f) yf(%f)\n", texture->pow2_matrix[0], texture->pow2_matrix[5]);
+
+ /* Generate all the surfaces. */
+ surface_desc = *desc;
+ surface_desc.resource_type = WINED3D_RTYPE_SURFACE;
+ for (i = 0; i < texture->level_count; ++i)
+ {
+ struct wined3d_surface *surface;
+
+ /* Use the callback to create the texture surface. */
+#ifdef VBOX_WITH_WDDM
+ if (FAILED(hr = device->device_parent->ops->create_texture_surface(device->device_parent,
+ parent, &surface_desc, i, surface_flags, &surface
+ , NULL /* <- we first create a surface in an average "non-shared" fashion and initialize its share properties later (see below)
+ * this is done this way because the surface does not have its parent (texture) setup properly
+ * thus we can not initialize texture at this stage */
+ , pavClientMem ? pavClientMem[i] : NULL
+ )))
+#else
+ if (FAILED(hr = device->device_parent->ops->create_texture_surface(device->device_parent,
+ parent, &surface_desc, i, surface_flags, &surface)))
+#endif
+ {
+ FIXME("Failed to create surface %p, hr %#x\n", texture, hr);
+ wined3d_texture_cleanup(texture);
+ return hr;
+ }
+
+ surface_set_container(surface, texture);
+ surface_set_texture_target(surface, texture->target, i);
+ texture->sub_resources[i] = &surface->resource;
+ TRACE("Created surface level %u @ %p.\n", i, surface);
+ /* Calculate the next mipmap level. */
+ surface_desc.width = max(1, surface_desc.width >> 1);
+ surface_desc.height = max(1, surface_desc.height >> 1);
+ }
+
+#ifdef VBOX_WITH_WDDM
+ if (VBOXSHRC_IS_SHARED(texture))
+ {
+ Assert(shared_handle);
+ for (i = 0; i < texture->level_count; ++i)
+ {
+ VBOXSHRC_COPY_SHAREDATA(surface_from_resource(texture->sub_resources[i]), texture);
+ }
+#ifdef DEBUG
+ for (i = 0; i < texture->level_count; ++i)
+ {
+ Assert(!surface_from_resource(texture->sub_resources[i])->texture_name);
+ }
+#endif
+ if (!VBOXSHRC_IS_SHARED_OPENED(texture))
+ {
+ for (i = 0; i < texture->level_count; ++i)
+ {
+ struct wined3d_surface *surface = surface_from_resource(texture->sub_resources[i]);
+ surface_load_location(surface, SFLAG_INTEXTURE, NULL);
+ }
+
+ Assert(!(*shared_handle));
+ *shared_handle = VBOXSHRC_GET_SHAREHANDLE(texture);
+ }
+ else
+ {
+ struct wined3d_context *context = NULL;
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ struct gl_texture *gl_tex = wined3d_texture_get_gl_texture(texture, gl_info, FALSE);
+ texture->texture_rgb.name = (GLuint)VBOXSHRC_GET_SHAREHANDLE(texture);
+ gl_tex->states[WINED3DTEXSTA_ADDRESSU] = WINED3D_TADDRESS_WRAP;
+ gl_tex->states[WINED3DTEXSTA_ADDRESSV] = WINED3D_TADDRESS_WRAP;
+ gl_tex->states[WINED3DTEXSTA_ADDRESSW] = WINED3D_TADDRESS_WRAP;
+ gl_tex->states[WINED3DTEXSTA_BORDERCOLOR] = 0;
+ gl_tex->states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_LINEAR;
+ gl_tex->states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT; /* GL_NEAREST_MIPMAP_LINEAR */
+ gl_tex->states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_LINEAR; /* GL_NEAREST_MIPMAP_LINEAR */
+ gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] = 0;
+ gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] = 1;
+ if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
+ gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = TRUE;
+ else
+ gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = FALSE;
+ gl_tex->states[WINED3DTEXSTA_SHADOW] = FALSE;
+ wined3d_texture_set_dirty(texture, TRUE);
+ if (texture->flags & WINED3D_TEXTURE_COND_NP2)
+ {
+ gl_tex->states[WINED3DTEXSTA_ADDRESSU] = WINED3D_TADDRESS_CLAMP;
+ gl_tex->states[WINED3DTEXSTA_ADDRESSV] = WINED3D_TADDRESS_CLAMP;
+ gl_tex->states[WINED3DTEXSTA_MAGFILTER] = WINED3D_TEXF_POINT;
+ gl_tex->states[WINED3DTEXSTA_MINFILTER] = WINED3D_TEXF_POINT;
+ gl_tex->states[WINED3DTEXSTA_MIPFILTER] = WINED3D_TEXF_NONE;
+ }
+
+ context = context_acquire(device, NULL);
+ pglChromiumParameteriCR(GL_RCUSAGE_TEXTURE_SET_CR, (GLuint)VBOXSHRC_GET_SHAREHANDLE(texture));
+ context_release(context);
+
+ for (i = 0; i < texture->level_count; ++i)
+ {
+ struct wined3d_surface *surface = surface_from_resource(texture->sub_resources[i]);
+ surface_setup_location_onopen(surface);
+ Assert(*shared_handle);
+ Assert(*shared_handle == VBOXSHRC_GET_SHAREHANDLE(texture));
+ }
+ }
+
+#ifdef DEBUG
+ for (i = 0; i < texture->level_count; ++i)
+ {
+ Assert((GLuint)(*shared_handle) == surface_from_resource(texture->sub_resources[i])->texture_name);
+ }
+#endif
+
+ Assert(!device->isInDraw);
+
+ /* flush to ensure the texture is allocated/referenced before it is used/released by another
+ * process opening/creating it */
+ Assert(device->context_count == 1);
+ pVBoxFlushToHost(device->contexts[0]->glCtx);
+ }
+ else
+ {
+ Assert(!shared_handle);
+ }
+#endif
+
+ return WINED3D_OK;
+}
+
+/* Context activation is done by the caller. */
+static HRESULT texture3d_bind(struct wined3d_texture *texture,
+ struct wined3d_context *context, BOOL srgb)
+{
+ BOOL dummy;
+
+ TRACE("texture %p, context %p, srgb %#x.\n", texture, context, srgb);
+
+ return wined3d_texture_bind(texture, context, srgb, &dummy);
+}
+
+/* Do not call while under the GL lock. */
+static void texture3d_preload(struct wined3d_texture *texture, enum WINED3DSRGB srgb)
+{
+ struct wined3d_device *device = texture->resource.device;
+ struct wined3d_context *context;
+ BOOL srgb_was_toggled = FALSE;
+ unsigned int i;
+
+ TRACE("texture %p, srgb %#x.\n", texture, srgb);
+
+ /* TODO: Use already acquired context when possible. */
+ context = context_acquire(device, NULL);
+ if (texture->resource.bind_count > 0)
+ {
+ BOOL texture_srgb = texture->flags & WINED3D_TEXTURE_IS_SRGB;
+ BOOL sampler_srgb = texture_srgb_mode(texture, srgb);
+ srgb_was_toggled = !texture_srgb != !sampler_srgb;
+
+ if (srgb_was_toggled)
+ {
+ if (sampler_srgb)
+ texture->flags |= WINED3D_TEXTURE_IS_SRGB;
+ else
+ texture->flags &= ~WINED3D_TEXTURE_IS_SRGB;
+ }
+ }
+
+ /* If the texture is marked dirty or the sRGB sampler setting has changed
+ * since the last load then reload the volumes. */
+ if (texture->texture_rgb.dirty)
+ {
+ for (i = 0; i < texture->level_count; ++i)
+ {
+ volume_load(volume_from_resource(texture->sub_resources[i]), context, i,
+ texture->flags & WINED3D_TEXTURE_IS_SRGB);
+ }
+ }
+ else if (srgb_was_toggled)
+ {
+ for (i = 0; i < texture->level_count; ++i)
+ {
+ struct wined3d_volume *volume = volume_from_resource(texture->sub_resources[i]);
+ volume_add_dirty_box(volume, NULL);
+ volume_load(volume, context, i, texture->flags & WINED3D_TEXTURE_IS_SRGB);
+ }
+ }
+ else
+ {
+ TRACE("Texture %p not dirty, nothing to do.\n", texture);
+ }
+
+ context_release(context);
+
+ /* No longer dirty */
+ texture->texture_rgb.dirty = FALSE;
+}
+
+static void texture3d_sub_resource_add_dirty_region(struct wined3d_resource *sub_resource,
+ const struct wined3d_box *dirty_region)
+{
+ volume_add_dirty_box(volume_from_resource(sub_resource), dirty_region);
+}
+
+static void texture3d_sub_resource_cleanup(struct wined3d_resource *sub_resource)
+{
+ struct wined3d_volume *volume = volume_from_resource(sub_resource);
+
+ /* Cleanup the container. */
+ volume_set_container(volume, NULL);
+ wined3d_volume_decref(volume);
+}
+
+/* Do not call while under the GL lock. */
+static void texture3d_unload(struct wined3d_resource *resource)
+{
+ struct wined3d_texture *texture = wined3d_texture_from_resource(resource);
+ UINT i;
+
+ TRACE("texture %p.\n", texture);
+
+ for (i = 0; i < texture->level_count; ++i)
+ {
+ struct wined3d_resource *sub_resource = texture->sub_resources[i];
+ sub_resource->resource_ops->resource_unload(sub_resource);
+ }
+
+ wined3d_texture_unload(texture);
+}
+
+static const struct wined3d_texture_ops texture3d_ops =
+{
+ texture3d_bind,
+ texture3d_preload,
+ texture3d_sub_resource_add_dirty_region,
+ texture3d_sub_resource_cleanup,
+};
+
+static const struct wined3d_resource_ops texture3d_resource_ops =
+{
+ texture3d_unload,
+};
+
+
+static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
+ UINT levels, struct wined3d_device *device, void *parent, const struct wined3d_parent_ops *parent_ops
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void **pavClientMem
+#endif
+ )
+{
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ UINT tmp_w, tmp_h, tmp_d;
+ unsigned int i;
+ HRESULT hr;
+
+#ifdef VBOX_WITH_WDDM
+ if (shared_handle)
+ {
+ ERR("shared handle support for volume textures not impemented yet, ignoring!");
+ }
+#endif
+
+ /* TODO: It should only be possible to create textures for formats
+ * that are reported as supported. */
+ if (WINED3DFMT_UNKNOWN >= desc->format)
+ {
+ WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (!gl_info->supported[EXT_TEXTURE3D])
+ {
+ WARN("(%p) : Texture cannot be created - no volume texture support.\n", texture);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ /* Calculate levels for mip mapping. */
+ if (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP)
+ {
+ if (!gl_info->supported[SGIS_GENERATE_MIPMAP])
+ {
+ WARN("No mipmap generation support, returning D3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ if (levels > 1)
+ {
+ WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ levels = 1;
+ }
+ else if (!levels)
+ {
+ levels = wined3d_log2i(max(max(desc->width, desc->height), desc->depth)) + 1;
+ TRACE("Calculated levels = %u.\n", levels);
+ }
+
+ if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
+ {
+ UINT pow2_w, pow2_h, pow2_d;
+ pow2_w = 1;
+ while (pow2_w < desc->width)
+ pow2_w <<= 1;
+ pow2_h = 1;
+ while (pow2_h < desc->height)
+ pow2_h <<= 1;
+ pow2_d = 1;
+ while (pow2_d < desc->depth)
+ pow2_d <<= 1;
+
+ if (pow2_w != desc->width || pow2_h != desc->height || pow2_d != desc->depth)
+ {
+ if (desc->pool == WINED3D_POOL_SCRATCH)
+ {
+ WARN("Creating a scratch NPOT volume texture despite lack of HW support.\n");
+ }
+ else
+ {
+ WARN("Attempted to create a NPOT volume texture (%u, %u, %u) without GL support.\n",
+ desc->width, desc->height, desc->depth);
+ return WINED3DERR_INVALIDCALL;
+ }
+ }
+ }
+
+#ifdef VBOX_WITH_WDDM
+ if (FAILED(hr = wined3d_texture_init(texture, &texture3d_ops, 1, levels,
+ desc, device, parent, parent_ops, &texture3d_resource_ops
+ , shared_handle, pavClientMem)))
+#else
+ if (FAILED(hr = wined3d_texture_init(texture, &texture3d_ops, 1, levels,
+ desc, device, parent, parent_ops, &texture3d_resource_ops)))
+#endif
+ {
+ WARN("Failed to initialize texture, returning %#x.\n", hr);
+ return hr;
+ }
+
+ texture->pow2_matrix[0] = 1.0f;
+ texture->pow2_matrix[5] = 1.0f;
+ texture->pow2_matrix[10] = 1.0f;
+ texture->pow2_matrix[15] = 1.0f;
+ texture->target = GL_TEXTURE_3D;
+
+ /* Generate all the surfaces. */
+ tmp_w = desc->width;
+ tmp_h = desc->height;
+ tmp_d = desc->depth;
+
+ for (i = 0; i < texture->level_count; ++i)
+ {
+ struct wined3d_volume *volume;
+
+ /* Create the volume. */
+ hr = device->device_parent->ops->create_volume(device->device_parent, parent,
+ tmp_w, tmp_h, tmp_d, desc->format, desc->pool, desc->usage, &volume
+#ifdef VBOX_WITH_WDDM
+ , shared_handle
+ , pavClientMem
+#endif
+ );
+ if (FAILED(hr))
+ {
+ ERR("Creating a volume for the volume texture failed, hr %#x.\n", hr);
+ wined3d_texture_cleanup(texture);
+ return hr;
+ }
+
+ /* Set its container to this texture. */
+ volume_set_container(volume, texture);
+ texture->sub_resources[i] = &volume->resource;
+
+ /* Calculate the next mipmap level. */
+ tmp_w = max(1, tmp_w >> 1);
+ tmp_h = max(1, tmp_h >> 1);
+ tmp_d = max(1, tmp_d >> 1);
+ }
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_texture_create_2d(struct wined3d_device *device, const struct wined3d_resource_desc *desc,
+ UINT level_count, DWORD surface_flags, void *parent, const struct wined3d_parent_ops *parent_ops,
+ struct wined3d_texture **texture
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void **pavClientMem
+#endif
+ )
+{
+ struct wined3d_texture *object;
+ HRESULT hr;
+
+ TRACE("device %p, desc %p, level_count %u, surface_flags %#x, parent %p, parent_ops %p, texture %p.\n",
+ device, desc, level_count, surface_flags, parent, parent_ops, texture);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ {
+ *texture = NULL;
+ return WINED3DERR_OUTOFVIDEOMEMORY;
+ }
+
+#ifdef VBOX_WITH_WDDM
+ if (FAILED(hr = texture_init(object, desc, level_count, surface_flags, device, parent, parent_ops
+ , shared_handle, pavClientMem)))
+#else
+ if (FAILED(hr = texture_init(object, desc, level_count, surface_flags, device, parent, parent_ops)))
+#endif
+ {
+ WARN("Failed to initialize texture, returning %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ *texture = NULL;
+ return hr;
+ }
+
+ TRACE("Created texture %p.\n", object);
+ *texture = object;
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_texture_create_3d(struct wined3d_device *device, const struct wined3d_resource_desc *desc,
+ UINT level_count, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void **pavClientMem
+#endif
+ )
+{
+ struct wined3d_texture *object;
+ HRESULT hr;
+
+ TRACE("device %p, desc %p, level_count %u, parent %p, parent_ops %p, texture %p.\n",
+ device, desc, level_count, parent, parent_ops, texture);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ {
+ *texture = NULL;
+ return WINED3DERR_OUTOFVIDEOMEMORY;
+ }
+
+#ifdef VBOX_WITH_WDDM
+ if (FAILED(hr = volumetexture_init(object, desc, level_count, device, parent, parent_ops
+ , shared_handle, pavClientMem)))
+#else
+ if (FAILED(hr = volumetexture_init(object, desc, level_count, device, parent, parent_ops)))
+#endif
+ {
+ WARN("Failed to initialize volumetexture, returning %#x\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ *texture = NULL;
+ return hr;
+ }
+
+ TRACE("Created texture %p.\n", object);
+ *texture = object;
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_texture_create_cube(struct wined3d_device *device, const struct wined3d_resource_desc *desc,
+ UINT level_count, DWORD surface_flags, void *parent, const struct wined3d_parent_ops *parent_ops,
+ struct wined3d_texture **texture
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void **pavClientMem
+#endif
+ )
+{
+ struct wined3d_texture *object;
+ HRESULT hr;
+
+ TRACE("device %p, desc %p, level_count %u, surface_flags %#x, parent %p, parent_ops %p, texture %p.\n",
+ device, desc, level_count, surface_flags, parent, parent_ops, texture);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ {
+ *texture = NULL;
+ return WINED3DERR_OUTOFVIDEOMEMORY;
+ }
+
+#ifdef VBOX_WITH_WDDM
+ if (FAILED(hr = cubetexture_init(object, desc, level_count, surface_flags, device, parent, parent_ops
+ , shared_handle, pavClientMem)))
+#else
+ if (FAILED(hr = cubetexture_init(object, desc, level_count, surface_flags, device, parent, parent_ops)))
+#endif
+ {
+ WARN("Failed to initialize cubetexture, returning %#x\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ *texture = NULL;
+ return hr;
+ }
+
+ TRACE("Created texture %p.\n", object);
+ *texture = object;
+
+ return WINED3D_OK;
+}
+
+#ifdef VBOX_WITH_WDDM
+HRESULT CDECL wined3d_device_blt_voltex(struct wined3d_device *device, struct wined3d_texture *src, struct wined3d_texture *dst,
+ const struct wined3d_box *pSrcBoxArg, const VBOXPOINT3D *pDstPoin3D)
+{
+ unsigned int level_count, i;
+ struct wined3d_volume *src_volume;
+ struct wined3d_volume *dst_volume;
+ HRESULT hr = S_OK;
+
+ level_count = src->level_count;
+ if (dst->level_count != level_count)
+ {
+ ERR("Source and destination have different level counts, returning WINED3DERR_INVALIDCALL.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ for (i = 0; i < level_count; ++i)
+ {
+ struct wined3d_box SrcBox, *pSrcBox;
+ VBOXPOINT3D DstPoint, *pDstPoint;
+
+ if (pSrcBoxArg)
+ {
+ vboxWddmBoxDivided((VBOXBOX3D*)&SrcBox, (VBOXBOX3D*)pSrcBoxArg, i + 1, true);
+ pSrcBox = &SrcBox;
+ }
+ else
+ {
+ pSrcBox = NULL;
+ }
+
+ if (pDstPoin3D)
+ {
+ vboxWddmPoint3DDivided(&DstPoint, pDstPoin3D, i + 1, true);
+ pDstPoint = &DstPoint;
+ }
+ else
+ {
+ pDstPoint = NULL;
+ }
+
+ src_volume = volume_from_resource(src->sub_resources[i]);
+ dst_volume = volume_from_resource(dst->sub_resources[i]);
+ hr = wined3d_device_blt_vol(device, src_volume, dst_volume, pSrcBox, pDstPoint);
+ if (FAILED(hr))
+ {
+ ERR("wined3d_device_blt_vol failed, hr %#x.\n", hr);
+ return hr;
+ }
+ }
+
+ return hr;
+}
+#endif
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/utils.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/utils.c
new file mode 100644
index 00000000..754b5b23
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/utils.c
@@ -0,0 +1,3718 @@
+/*
+ * Utility functions for the WineD3D Library
+ *
+ * Copyright 2002-2004 Jason Edmeades
+ * Copyright 2003-2004 Raphael Junqueira
+ * Copyright 2004 Christian Costa
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2006-2008 Henri Verbeet
+ * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2009-2010 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+
+struct wined3d_format_channels
+{
+ enum wined3d_format_id id;
+ DWORD red_size, green_size, blue_size, alpha_size;
+ DWORD red_offset, green_offset, blue_offset, alpha_offset;
+ UINT bpp;
+ BYTE depth_size, stencil_size;
+};
+
+static const struct wined3d_format_channels formats[] =
+{
+ /* size offset
+ * format id r g b a r g b a bpp depth stencil */
+ {WINED3DFMT_UNKNOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ /* FourCC formats */
+ {WINED3DFMT_UYVY, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
+ {WINED3DFMT_YUY2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
+ {WINED3DFMT_YV12, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
+ {WINED3DFMT_DXT1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
+ {WINED3DFMT_DXT2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
+ {WINED3DFMT_DXT3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
+ {WINED3DFMT_DXT4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
+ {WINED3DFMT_DXT5, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
+ {WINED3DFMT_MULTI2_ARGB8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
+ {WINED3DFMT_G8R8_G8B8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
+ {WINED3DFMT_R8G8_B8G8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
+ /* IEEE formats */
+ {WINED3DFMT_R32_FLOAT, 32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0},
+ {WINED3DFMT_R32G32_FLOAT, 32, 32, 0, 0, 0, 32, 0, 0, 8, 0, 0},
+ {WINED3DFMT_R32G32B32_FLOAT, 32, 32, 32, 0, 0, 32, 64, 0, 12, 0, 0},
+ {WINED3DFMT_R32G32B32A32_FLOAT, 32, 32, 32, 32, 0, 32, 64, 96, 16, 0, 0},
+ /* Hmm? */
+ {WINED3DFMT_R8G8_SNORM_Cx, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
+ /* Float */
+ {WINED3DFMT_R16_FLOAT, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
+ {WINED3DFMT_R16G16_FLOAT, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
+ {WINED3DFMT_R16G16_SINT, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
+ {WINED3DFMT_R16G16B16A16_FLOAT, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
+ {WINED3DFMT_R16G16B16A16_SINT, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
+ /* Palettized formats */
+ {WINED3DFMT_P8_UINT_A8_UNORM, 0, 0, 0, 8, 0, 0, 0, 8, 2, 0, 0},
+ {WINED3DFMT_P8_UINT, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
+ /* Standard ARGB formats. */
+ {WINED3DFMT_B8G8R8_UNORM, 8, 8, 8, 0, 16, 8, 0, 0, 3, 0, 0},
+ {WINED3DFMT_B8G8R8A8_UNORM, 8, 8, 8, 8, 16, 8, 0, 24, 4, 0, 0},
+ {WINED3DFMT_B8G8R8X8_UNORM, 8, 8, 8, 0, 16, 8, 0, 0, 4, 0, 0},
+ {WINED3DFMT_B5G6R5_UNORM, 5, 6, 5, 0, 11, 5, 0, 0, 2, 0, 0},
+ {WINED3DFMT_B5G5R5X1_UNORM, 5, 5, 5, 0, 10, 5, 0, 0, 2, 0, 0},
+ {WINED3DFMT_B5G5R5A1_UNORM, 5, 5, 5, 1, 10, 5, 0, 15, 2, 0, 0},
+ {WINED3DFMT_B4G4R4A4_UNORM, 4, 4, 4, 4, 8, 4, 0, 12, 2, 0, 0},
+ {WINED3DFMT_B2G3R3_UNORM, 3, 3, 2, 0, 5, 2, 0, 0, 1, 0, 0},
+ {WINED3DFMT_A8_UNORM, 0, 0, 0, 8, 0, 0, 0, 0, 1, 0, 0},
+ {WINED3DFMT_B2G3R3A8_UNORM, 3, 3, 2, 8, 5, 2, 0, 8, 2, 0, 0},
+ {WINED3DFMT_B4G4R4X4_UNORM, 4, 4, 4, 0, 8, 4, 0, 0, 2, 0, 0},
+ {WINED3DFMT_R10G10B10A2_UNORM, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
+ {WINED3DFMT_R10G10B10A2_UINT, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
+ {WINED3DFMT_R10G10B10A2_SNORM, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
+ {WINED3DFMT_R8G8B8A8_UNORM, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
+ {WINED3DFMT_R8G8B8A8_UINT, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
+ {WINED3DFMT_R8G8B8X8_UNORM, 8, 8, 8, 0, 0, 8, 16, 0, 4, 0, 0},
+ {WINED3DFMT_R16G16_UNORM, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
+ {WINED3DFMT_B10G10R10A2_UNORM, 10, 10, 10, 2, 20, 10, 0, 30, 4, 0, 0},
+ {WINED3DFMT_R16G16B16A16_UNORM, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
+ /* Luminance */
+ {WINED3DFMT_L8_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
+ {WINED3DFMT_L8A8_UNORM, 0, 0, 0, 8, 0, 0, 0, 8, 2, 0, 0},
+ {WINED3DFMT_L4A4_UNORM, 0, 0, 0, 4, 0, 0, 0, 4, 1, 0, 0},
+ {WINED3DFMT_L16_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
+ /* Bump mapping stuff */
+ {WINED3DFMT_R8G8_SNORM, 8, 8, 0, 0, 0, 8, 0, 0, 2, 0, 0},
+ {WINED3DFMT_R5G5_SNORM_L6_UNORM, 5, 5, 0, 0, 0, 5, 0, 0, 2, 0, 0},
+ {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, 8, 8, 0, 0, 0, 8, 0, 0, 4, 0, 0},
+ {WINED3DFMT_R8G8B8A8_SNORM, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
+ {WINED3DFMT_R16G16_SNORM, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
+ {WINED3DFMT_R10G11B11_SNORM, 10, 11, 11, 0, 0, 10, 21, 0, 4, 0, 0},
+ {WINED3DFMT_R10G10B10_SNORM_A2_UNORM, 10, 10, 10, 2, 0, 10, 20, 30, 4, 0, 0},
+ /* Depth stencil formats */
+ {WINED3DFMT_D16_LOCKABLE, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16, 0},
+ {WINED3DFMT_D32_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 32, 0},
+ {WINED3DFMT_S1_UINT_D15_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 15, 1},
+ {WINED3DFMT_D24_UNORM_S8_UINT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8},
+ {WINED3DFMT_X8D24_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 0},
+ {WINED3DFMT_S4X4_UINT_D24_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 4},
+ {WINED3DFMT_D16_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16, 0},
+ {WINED3DFMT_D32_FLOAT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 32, 0},
+ {WINED3DFMT_S8_UINT_D24_FLOAT, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8},
+ {WINED3DFMT_VERTEXDATA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {WINED3DFMT_R16_UINT, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
+ {WINED3DFMT_R32_UINT, 32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0},
+ {WINED3DFMT_R32G32_UINT, 32, 32, 0, 0, 0, 32, 0, 0, 8, 0, 0},
+ {WINED3DFMT_R32G32B32_UINT, 32, 32, 32, 0, 0, 32, 64, 0, 12, 0, 0},
+ {WINED3DFMT_R32G32B32A32_UINT, 32, 32, 32, 32, 0, 32, 64, 96, 16, 0, 0},
+ {WINED3DFMT_R16G16B16A16_SNORM, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
+ /* Vendor-specific formats */
+ {WINED3DFMT_ATI2N, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
+ {WINED3DFMT_NVDB, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {WINED3DFMT_INST, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {WINED3DFMT_INTZ, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 8},
+ {WINED3DFMT_RESZ, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {WINED3DFMT_NVHU, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
+ {WINED3DFMT_NVHS, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
+ {WINED3DFMT_NULL, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
+ /* Unsure about them, could not find a Windows driver that supports them */
+ {WINED3DFMT_R16, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
+ {WINED3DFMT_AL16, 0, 0, 0, 16, 0, 0, 0, 16, 4, 0, 0},
+ /* Typeless */
+ {WINED3DFMT_R8_TYPELESS, 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
+ {WINED3DFMT_R8G8_TYPELESS, 8, 8, 0, 0, 0, 8, 0, 0, 2, 0, 0},
+ {WINED3DFMT_R8G8B8A8_TYPELESS, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
+ {WINED3DFMT_R16_TYPELESS, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
+ {WINED3DFMT_R16G16_TYPELESS, 16, 16, 0, 0, 0, 16, 0, 0, 4, 0, 0},
+ {WINED3DFMT_R16G16B16A16_TYPELESS, 16, 16, 16, 16, 0, 16, 32, 48, 8, 0, 0},
+ {WINED3DFMT_R32_TYPELESS, 32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0},
+ {WINED3DFMT_R32G32_TYPELESS, 32, 32, 0, 0, 0, 32, 0, 0, 8, 0, 0},
+ {WINED3DFMT_R32G32B32_TYPELESS, 32, 32, 32, 0, 0, 32, 64, 0, 12, 0, 0},
+ {WINED3DFMT_R32G32B32A32_TYPELESS, 32, 32, 32, 32, 0, 32, 64, 96, 16, 0, 0},
+};
+
+struct wined3d_format_base_flags
+{
+ enum wined3d_format_id id;
+ DWORD flags;
+};
+
+/* The ATI2N format behaves like an uncompressed format in LockRect(), but
+ * still needs to use the correct block based calculation for e.g. the
+ * resource size. */
+static const struct wined3d_format_base_flags format_base_flags[] =
+{
+ {WINED3DFMT_P8_UINT, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_B8G8R8A8_UNORM, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_B8G8R8X8_UNORM, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_R8G8B8A8_UNORM, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_R8G8B8X8_UNORM, WINED3DFMT_FLAG_GETDC},
+ {WINED3DFMT_ATI2N, WINED3DFMT_FLAG_BROKEN_PITCH},
+ {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_FLOAT},
+ {WINED3DFMT_R32G32_FLOAT, WINED3DFMT_FLAG_FLOAT},
+ {WINED3DFMT_R32G32B32_FLOAT, WINED3DFMT_FLAG_FLOAT},
+ {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
+ {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_FLOAT},
+ {WINED3DFMT_R16G16_FLOAT, WINED3DFMT_FLAG_FLOAT},
+ {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
+ {WINED3DFMT_D32_FLOAT, WINED3DFMT_FLAG_FLOAT},
+ {WINED3DFMT_S8_UINT_D24_FLOAT, WINED3DFMT_FLAG_FLOAT},
+};
+
+struct wined3d_format_block_info
+{
+ enum wined3d_format_id id;
+ UINT block_width;
+ UINT block_height;
+ UINT block_byte_count;
+};
+
+static const struct wined3d_format_block_info format_block_info[] =
+{
+ {WINED3DFMT_DXT1, 4, 4, 8},
+ {WINED3DFMT_DXT2, 4, 4, 16},
+ {WINED3DFMT_DXT3, 4, 4, 16},
+ {WINED3DFMT_DXT4, 4, 4, 16},
+ {WINED3DFMT_DXT5, 4, 4, 16},
+ {WINED3DFMT_ATI2N, 4, 4, 16},
+ {WINED3DFMT_YUY2, 2, 1, 4},
+ {WINED3DFMT_UYVY, 2, 1, 4},
+};
+
+struct wined3d_format_vertex_info
+{
+ enum wined3d_format_id id;
+ enum wined3d_ffp_emit_idx emit_idx;
+ GLint component_count;
+ GLenum gl_vtx_type;
+ GLint gl_vtx_format;
+ GLboolean gl_normalized;
+ unsigned int component_size;
+};
+
+static const struct wined3d_format_vertex_info format_vertex_info[] =
+{
+ {WINED3DFMT_R32_FLOAT, WINED3D_FFP_EMIT_FLOAT1, 1, GL_FLOAT, 1, GL_FALSE, sizeof(float)},
+ {WINED3DFMT_R32G32_FLOAT, WINED3D_FFP_EMIT_FLOAT2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(float)},
+ {WINED3DFMT_R32G32B32_FLOAT, WINED3D_FFP_EMIT_FLOAT3, 3, GL_FLOAT, 3, GL_FALSE, sizeof(float)},
+ {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(float)},
+ {WINED3DFMT_B8G8R8A8_UNORM, WINED3D_FFP_EMIT_D3DCOLOR, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
+ {WINED3DFMT_R8G8B8A8_UINT, WINED3D_FFP_EMIT_UBYTE4, 4, GL_UNSIGNED_BYTE, 4, GL_FALSE, sizeof(BYTE)},
+ {WINED3DFMT_R16G16_SINT, WINED3D_FFP_EMIT_SHORT2, 2, GL_SHORT, 2, GL_FALSE, sizeof(short int)},
+ {WINED3DFMT_R16G16B16A16_SINT, WINED3D_FFP_EMIT_SHORT4, 4, GL_SHORT, 4, GL_FALSE, sizeof(short int)},
+ {WINED3DFMT_R8G8B8A8_UNORM, WINED3D_FFP_EMIT_UBYTE4N, 4, GL_UNSIGNED_BYTE, 4, GL_TRUE, sizeof(BYTE)},
+ {WINED3DFMT_R16G16_SNORM, WINED3D_FFP_EMIT_SHORT2N, 2, GL_SHORT, 2, GL_TRUE, sizeof(short int)},
+ {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N, 4, GL_SHORT, 4, GL_TRUE, sizeof(short int)},
+ {WINED3DFMT_R16G16_UNORM, WINED3D_FFP_EMIT_USHORT2N, 2, GL_UNSIGNED_SHORT, 2, GL_TRUE, sizeof(short int)},
+ {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N, 4, GL_UNSIGNED_SHORT, 4, GL_TRUE, sizeof(short int)},
+ {WINED3DFMT_R10G10B10A2_UINT, WINED3D_FFP_EMIT_UDEC3, 3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
+ {WINED3DFMT_R10G10B10A2_SNORM, WINED3D_FFP_EMIT_DEC3N, 3, GL_SHORT, 3, GL_TRUE, sizeof(short int)},
+ {WINED3DFMT_R16G16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT, 2, GL_FALSE, sizeof(GLhalfNV)},
+ {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT, 4, GL_FALSE, sizeof(GLhalfNV)},
+ {WINED3DFMT_R32_UINT, WINED3D_FFP_EMIT_INVALID, 1, GL_UNSIGNED_INT, 1, GL_FALSE, sizeof(UINT)},
+ {WINED3DFMT_R32G32_UINT, WINED3D_FFP_EMIT_INVALID, 2, GL_UNSIGNED_INT, 2, GL_FALSE, sizeof(UINT)},
+ {WINED3DFMT_R32G32B32_UINT, WINED3D_FFP_EMIT_INVALID, 3, GL_UNSIGNED_INT, 3, GL_FALSE, sizeof(UINT)},
+ {WINED3DFMT_R32G32B32A32_UINT, WINED3D_FFP_EMIT_INVALID, 4, GL_UNSIGNED_INT, 4, GL_FALSE, sizeof(UINT)},
+};
+
+struct wined3d_format_texture_info
+{
+ enum wined3d_format_id id;
+ GLint gl_internal;
+ GLint gl_srgb_internal;
+ GLint gl_rt_internal;
+ GLint gl_format;
+ GLint gl_type;
+ unsigned int conv_byte_count;
+ unsigned int flags;
+ enum wined3d_gl_extension extension;
+ void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
+};
+
+static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
+ * format+type combination to load it. Thus convert it to A8L8, then load it
+ * with A4L4 internal, but A8L8 format+type
+ */
+ unsigned int x, y;
+ const unsigned char *Source;
+ unsigned char *Dest;
+ UINT outpitch = pitch * 2;
+
+ for(y = 0; y < height; y++) {
+ Source = src + y * pitch;
+ Dest = dst + y * outpitch;
+ for (x = 0; x < width; x++ ) {
+ unsigned char color = (*Source++);
+ /* A */ Dest[1] = (color & 0xf0) << 0;
+ /* L */ Dest[0] = (color & 0x0f) << 4;
+ Dest += 2;
+ }
+ }
+}
+
+static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ const WORD *Source;
+
+ for(y = 0; y < height; y++)
+ {
+ unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
+ Source = (const WORD *)(src + y * pitch);
+ for (x = 0; x < width; x++ )
+ {
+ short color = (*Source++);
+ unsigned char l = ((color >> 10) & 0xfc);
+ short v = ((color >> 5) & 0x3e);
+ short u = ((color ) & 0x1f);
+ short v_conv = v + 16;
+ short u_conv = u + 16;
+
+ *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
+ Dest_s += 1;
+ }
+ }
+}
+
+static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ const WORD *Source;
+ unsigned char *Dest;
+ UINT outpitch = (pitch * 3)/2;
+
+ /* This makes the gl surface bigger(24 bit instead of 16), but it works with
+ * fixed function and shaders without further conversion once the surface is
+ * loaded
+ */
+ for(y = 0; y < height; y++) {
+ Source = (const WORD *)(src + y * pitch);
+ Dest = dst + y * outpitch;
+ for (x = 0; x < width; x++ ) {
+ short color = (*Source++);
+ unsigned char l = ((color >> 10) & 0xfc);
+ char v = ((color >> 5) & 0x3e);
+ char u = ((color ) & 0x1f);
+
+ /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
+ * and doubles the positive range. Thus shift left only once, gl does the 2nd
+ * shift. GL reads a signed value and converts it into an unsigned value.
+ */
+ /* M */ Dest[2] = l << 1;
+
+ /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
+ * from 5 bit values to 8 bit values.
+ */
+ /* V */ Dest[1] = v << 3;
+ /* U */ Dest[0] = u << 3;
+ Dest += 3;
+ }
+ }
+}
+
+static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ const short *Source;
+ unsigned char *Dest;
+ UINT outpitch = (pitch * 3)/2;
+
+ for(y = 0; y < height; y++)
+ {
+ Source = (const short *)(src + y * pitch);
+ Dest = dst + y * outpitch;
+ for (x = 0; x < width; x++ )
+ {
+ const short color = (*Source++);
+ /* B */ Dest[0] = 0xff;
+ /* G */ Dest[1] = (color >> 8) + 128; /* V */
+ /* R */ Dest[2] = (color & 0xff) + 128; /* U */
+ Dest += 3;
+ }
+ }
+}
+
+static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ const DWORD *Source;
+ unsigned char *Dest;
+
+ /* Doesn't work correctly with the fixed function pipeline, but can work in
+ * shaders if the shader is adjusted. (There's no use for this format in gl's
+ * standard fixed function pipeline anyway).
+ */
+ for(y = 0; y < height; y++)
+ {
+ Source = (const DWORD *)(src + y * pitch);
+ Dest = dst + y * pitch;
+ for (x = 0; x < width; x++ )
+ {
+ LONG color = (*Source++);
+ /* B */ Dest[0] = ((color >> 16) & 0xff); /* L */
+ /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
+ /* R */ Dest[2] = (color & 0xff) + 128; /* U */
+ Dest += 4;
+ }
+ }
+}
+
+static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ const DWORD *Source;
+ unsigned char *Dest;
+
+ /* This implementation works with the fixed function pipeline and shaders
+ * without further modification after converting the surface.
+ */
+ for(y = 0; y < height; y++)
+ {
+ Source = (const DWORD *)(src + y * pitch);
+ Dest = dst + y * pitch;
+ for (x = 0; x < width; x++ )
+ {
+ LONG color = (*Source++);
+ /* L */ Dest[2] = ((color >> 16) & 0xff); /* L */
+ /* V */ Dest[1] = ((color >> 8 ) & 0xff); /* V */
+ /* U */ Dest[0] = (color & 0xff); /* U */
+ /* I */ Dest[3] = 255; /* X */
+ Dest += 4;
+ }
+ }
+}
+
+static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ const DWORD *Source;
+ unsigned char *Dest;
+
+ for(y = 0; y < height; y++)
+ {
+ Source = (const DWORD *)(src + y * pitch);
+ Dest = dst + y * pitch;
+ for (x = 0; x < width; x++ )
+ {
+ LONG color = (*Source++);
+ /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
+ /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
+ /* R */ Dest[2] = (color & 0xff) + 128; /* U */
+ /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
+ Dest += 4;
+ }
+ }
+}
+
+static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ const DWORD *Source;
+ unsigned short *Dest;
+ UINT outpitch = (pitch * 3)/2;
+
+ for(y = 0; y < height; y++)
+ {
+ Source = (const DWORD *)(src + y * pitch);
+ Dest = (unsigned short *) (dst + y * outpitch);
+ for (x = 0; x < width; x++ )
+ {
+ const DWORD color = (*Source++);
+ /* B */ Dest[0] = 0xffff;
+ /* G */ Dest[1] = (color >> 16) + 32768; /* V */
+ /* R */ Dest[2] = (color & 0xffff) + 32768; /* U */
+ Dest += 3;
+ }
+ }
+}
+
+static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ const WORD *Source;
+ WORD *Dest;
+ UINT outpitch = (pitch * 3)/2;
+
+ for(y = 0; y < height; y++)
+ {
+ Source = (const WORD *)(src + y * pitch);
+ Dest = (WORD *) (dst + y * outpitch);
+ for (x = 0; x < width; x++ )
+ {
+ WORD green = (*Source++);
+ WORD red = (*Source++);
+ Dest[0] = green;
+ Dest[1] = red;
+ /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
+ * shader overwrites it anyway
+ */
+ Dest[2] = 0xffff;
+ Dest += 3;
+ }
+ }
+}
+
+static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ const float *Source;
+ float *Dest;
+ UINT outpitch = (pitch * 3)/2;
+
+ for(y = 0; y < height; y++)
+ {
+ Source = (const float *)(src + y * pitch);
+ Dest = (float *) (dst + y * outpitch);
+ for (x = 0; x < width; x++ )
+ {
+ float green = (*Source++);
+ float red = (*Source++);
+ Dest[0] = green;
+ Dest[1] = red;
+ Dest[2] = 1.0f;
+ Dest += 3;
+ }
+ }
+}
+
+static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ UINT outpitch = pitch * 2;
+
+ for (y = 0; y < height; ++y)
+ {
+ const WORD *source = (const WORD *)(src + y * pitch);
+ DWORD *dest = (DWORD *)(dst + y * outpitch);
+
+ for (x = 0; x < width; ++x)
+ {
+ /* The depth data is normalized, so needs to be scaled,
+ * the stencil data isn't. Scale depth data by
+ * (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
+ WORD d15 = source[x] >> 1;
+ DWORD d24 = (d15 << 9) + (d15 >> 6);
+ dest[x] = (d24 << 8) | (source[x] & 0x1);
+ }
+ }
+}
+
+static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+
+ for (y = 0; y < height; ++y)
+ {
+ const DWORD *source = (const DWORD *)(src + y * pitch);
+ DWORD *dest = (DWORD *)(dst + y * pitch);
+
+ for (x = 0; x < width; ++x)
+ {
+ /* Just need to clear out the X4 part. */
+ dest[x] = source[x] & ~0xf0;
+ }
+ }
+}
+
+static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
+{
+ unsigned int x, y;
+ UINT outpitch = pitch * 2;
+
+ for (y = 0; y < height; ++y)
+ {
+ const DWORD *source = (const DWORD *)(src + y * pitch);
+ float *dest_f = (float *)(dst + y * outpitch);
+ DWORD *dest_s = (DWORD *)(dst + y * outpitch);
+
+ for (x = 0; x < width; ++x)
+ {
+ dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
+ dest_s[x * 2 + 1] = source[x] & 0xff;
+ }
+ }
+}
+
+/* The following formats explicitly don't have WINED3DFMT_FLAG_TEXTURE set:
+ *
+ * These are never supported on native.
+ * WINED3DFMT_B8G8R8_UNORM
+ * WINED3DFMT_B2G3R3_UNORM
+ * WINED3DFMT_L4A4_UNORM
+ * WINED3DFMT_S1_UINT_D15_UNORM
+ * WINED3DFMT_S4X4_UINT_D24_UNORM
+ *
+ * Only some Geforce/Voodoo3/G400 cards offer 8-bit textures in case of ddraw.
+ * Since it is not widely available, don't offer it. Further no Windows driver
+ * offers WINED3DFMT_P8_UINT_A8_NORM, so don't offer it either.
+ * WINED3DFMT_P8_UINT
+ * WINED3DFMT_P8_UINT_A8_UNORM
+ *
+ * These formats seem to be similar to the HILO formats in
+ * GL_NV_texture_shader. NVHU is said to be GL_UNSIGNED_HILO16,
+ * NVHS GL_SIGNED_HILO16. Rumours say that D3D computes a 3rd channel
+ * similarly to D3DFMT_CxV8U8 (So NVHS could be called D3DFMT_CxV16U16). ATI
+ * refused to support formats which can easily be emulated with pixel shaders,
+ * so applications have to deal with not having NVHS and NVHU.
+ * WINED3DFMT_NVHU
+ * WINED3DFMT_NVHS */
+static const struct wined3d_format_texture_info format_texture_info[] =
+{
+ /* format id gl_internal gl_srgb_internal gl_rt_internal
+ gl_format gl_type conv_byte_count
+ flags
+ extension convert */
+ /* FourCC formats */
+ /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
+ * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
+ * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
+ * Macs, so probably the endianness differs. This could be tested as soon as we have a Windows and MacOS on a big
+ * endian machine
+ */
+ {WINED3DFMT_UYVY, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
+ GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_FILTERING,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0,
+ GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING,
+ APPLE_YCBCR_422, NULL},
+ {WINED3DFMT_YUY2, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, 0,
+ GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_FILTERING,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0,
+ GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING,
+ APPLE_YCBCR_422, NULL},
+ {WINED3DFMT_YV12, GL_ALPHA, GL_ALPHA, 0,
+ GL_ALPHA, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_FILTERING,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_DXT1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
+ EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ {WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
+ EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ {WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
+ EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ {WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
+ EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ {WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
+ EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ /* IEEE formats */
+ {WINED3DFMT_R32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
+ GL_RED, GL_FLOAT, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
+ ARB_TEXTURE_FLOAT, NULL},
+ {WINED3DFMT_R32_FLOAT, GL_R32F, GL_R32F, 0,
+ GL_RED, GL_FLOAT, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
+ ARB_TEXTURE_RG, NULL},
+ {WINED3DFMT_R32G32_FLOAT, GL_RGB32F_ARB, GL_RGB32F_ARB, 0,
+ GL_RGB, GL_FLOAT, 12,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
+ ARB_TEXTURE_FLOAT, convert_r32g32_float},
+ {WINED3DFMT_R32G32_FLOAT, GL_RG32F, GL_RG32F, 0,
+ GL_RG, GL_FLOAT, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
+ ARB_TEXTURE_RG, NULL},
+ {WINED3DFMT_R32G32B32A32_FLOAT, GL_RGBA32F_ARB, GL_RGBA32F_ARB, 0,
+ GL_RGBA, GL_FLOAT, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
+ ARB_TEXTURE_FLOAT, NULL},
+ /* Float */
+ {WINED3DFMT_R16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
+ GL_RED, GL_HALF_FLOAT_ARB, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
+ ARB_TEXTURE_FLOAT, NULL},
+ {WINED3DFMT_R16_FLOAT, GL_R16F, GL_R16F, 0,
+ GL_RED, GL_HALF_FLOAT_ARB, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
+ ARB_TEXTURE_RG, NULL},
+ {WINED3DFMT_R16G16_FLOAT, GL_RGB16F_ARB, GL_RGB16F_ARB, 0,
+ GL_RGB, GL_HALF_FLOAT_ARB, 6,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
+ ARB_TEXTURE_FLOAT, convert_r16g16},
+ {WINED3DFMT_R16G16_FLOAT, GL_RG16F, GL_RG16F, 0,
+ GL_RG, GL_HALF_FLOAT_ARB, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
+ ARB_TEXTURE_RG, NULL},
+ {WINED3DFMT_R16G16B16A16_FLOAT, GL_RGBA16F_ARB, GL_RGBA16F_ARB, 0,
+ GL_RGBA, GL_HALF_FLOAT_ARB, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET
+ | WINED3DFMT_FLAG_VTF,
+ ARB_TEXTURE_FLOAT, NULL},
+ /* Palettized formats */
+ {WINED3DFMT_P8_UINT, GL_RGBA, GL_RGBA, 0,
+ GL_ALPHA, GL_UNSIGNED_BYTE, 0,
+ 0,
+ ARB_FRAGMENT_PROGRAM, NULL},
+ {WINED3DFMT_P8_UINT, GL_COLOR_INDEX8_EXT, GL_COLOR_INDEX8_EXT, 0,
+ GL_COLOR_INDEX, GL_UNSIGNED_BYTE, 0,
+ 0,
+ EXT_PALETTED_TEXTURE, NULL},
+ /* Standard ARGB formats */
+ {WINED3DFMT_B8G8R8_UNORM, GL_RGB8, GL_RGB8, 0,
+ GL_BGR, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_B8G8R8A8_UNORM, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, 0,
+ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE
+ | WINED3DFMT_FLAG_VTF,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_B8G8R8X8_UNORM, GL_RGB8, GL_SRGB8_EXT, 0,
+ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_B5G6R5_UNORM, GL_RGB5, GL_RGB5, GL_RGB8,
+ GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_RENDERTARGET,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_B5G5R5X1_UNORM, GL_RGB5, GL_RGB5_A1, 0,
+ GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, 0,
+ GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_B4G4R4A4_UNORM, GL_RGBA4, GL_SRGB8_ALPHA8_EXT, 0,
+ GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_SRGB_READ,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_B2G3R3_UNORM, GL_R3_G3_B2, GL_R3_G3_B2, 0,
+ GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 0,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_A8_UNORM, GL_ALPHA8, GL_ALPHA8, 0,
+ GL_ALPHA, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_B4G4R4X4_UNORM, GL_RGB4, GL_RGB4, 0,
+ GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
+ GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_RENDERTARGET,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, 0,
+ GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_R8G8B8X8_UNORM, GL_RGB8, GL_RGB8, 0,
+ GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
+ GL_RGB, GL_UNSIGNED_SHORT, 6,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+ WINED3D_GL_EXT_NONE, convert_r16g16},
+ {WINED3DFMT_R16G16_UNORM, GL_RG16, GL_RG16, 0,
+ GL_RG, GL_UNSIGNED_SHORT, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_RENDERTARGET,
+ ARB_TEXTURE_RG, NULL},
+ {WINED3DFMT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, 0,
+ GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_RENDERTARGET,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
+ GL_RGBA, GL_UNSIGNED_SHORT, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_RENDERTARGET,
+ WINED3D_GL_EXT_NONE, NULL},
+ /* Luminance */
+ {WINED3DFMT_L8_UNORM, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, 0,
+ GL_LUMINANCE, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_SRGB_READ,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, 0,
+ GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_SRGB_READ,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_L4A4_UNORM, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE4_ALPHA4, 0,
+ GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2,
+ WINED3DFMT_FLAG_FILTERING,
+ WINED3D_GL_EXT_NONE, convert_l4a4_unorm},
+ /* Bump mapping stuff */
+ {WINED3DFMT_R8G8_SNORM, GL_RGB8, GL_RGB8, 0,
+ GL_BGR, GL_UNSIGNED_BYTE, 3,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_BUMPMAP,
+ WINED3D_GL_EXT_NONE, convert_r8g8_snorm},
+ {WINED3DFMT_R8G8_SNORM, GL_DSDT8_NV, GL_DSDT8_NV, 0,
+ GL_DSDT_NV, GL_BYTE, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_BUMPMAP,
+ NV_TEXTURE_SHADER, NULL},
+ {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_RGB5, GL_RGB5, 0,
+ GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_BUMPMAP,
+ WINED3D_GL_EXT_NONE, convert_r5g5_snorm_l6_unorm},
+ {WINED3DFMT_R5G5_SNORM_L6_UNORM, GL_DSDT8_MAG8_NV, GL_DSDT8_MAG8_NV, 0,
+ GL_DSDT_MAG_NV, GL_BYTE, 3,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_BUMPMAP,
+ NV_TEXTURE_SHADER, convert_r5g5_snorm_l6_unorm_nv},
+ {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_RGB8, GL_RGB8, 0,
+ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_BUMPMAP,
+ WINED3D_GL_EXT_NONE, convert_r8g8_snorm_l8x8_unorm},
+ {WINED3DFMT_R8G8_SNORM_L8X8_UNORM, GL_DSDT8_MAG8_INTENSITY8_NV, GL_DSDT8_MAG8_INTENSITY8_NV, 0,
+ GL_DSDT_MAG_VIB_NV, GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_BUMPMAP,
+ NV_TEXTURE_SHADER, convert_r8g8_snorm_l8x8_unorm_nv},
+ {WINED3DFMT_R8G8B8A8_SNORM, GL_RGBA8, GL_RGBA8, 0,
+ GL_BGRA, GL_UNSIGNED_BYTE, 4,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_BUMPMAP,
+ WINED3D_GL_EXT_NONE, convert_r8g8b8a8_snorm},
+ {WINED3DFMT_R8G8B8A8_SNORM, GL_SIGNED_RGBA8_NV, GL_SIGNED_RGBA8_NV, 0,
+ GL_RGBA, GL_BYTE, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_BUMPMAP,
+ NV_TEXTURE_SHADER, NULL},
+ {WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
+ GL_BGR, GL_UNSIGNED_SHORT, 6,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_BUMPMAP,
+ WINED3D_GL_EXT_NONE, convert_r16g16_snorm},
+ {WINED3DFMT_R16G16_SNORM, GL_SIGNED_HILO16_NV, GL_SIGNED_HILO16_NV, 0,
+ GL_HILO_NV, GL_SHORT, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_BUMPMAP,
+ NV_TEXTURE_SHADER, NULL},
+ /* Depth stencil formats */
+ {WINED3DFMT_D16_LOCKABLE, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
+ ARB_DEPTH_TEXTURE, NULL},
+ {WINED3DFMT_D32_UNORM, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT32_ARB, 0,
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
+ ARB_DEPTH_TEXTURE, NULL},
+ {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
+ WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
+ ARB_DEPTH_TEXTURE, NULL},
+ {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
+ GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
+ WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
+ EXT_PACKED_DEPTH_STENCIL, convert_s1_uint_d15_unorm},
+ {WINED3DFMT_S1_UINT_D15_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
+ GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
+ WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
+ ARB_FRAMEBUFFER_OBJECT, convert_s1_uint_d15_unorm},
+ {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
+ ARB_DEPTH_TEXTURE, NULL},
+ {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
+ GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
+ EXT_PACKED_DEPTH_STENCIL, NULL},
+ {WINED3DFMT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
+ GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
+ ARB_FRAMEBUFFER_OBJECT, NULL},
+ {WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
+ ARB_DEPTH_TEXTURE, NULL},
+ {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
+ WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
+ ARB_DEPTH_TEXTURE, NULL},
+ {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
+ GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 4,
+ WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
+ EXT_PACKED_DEPTH_STENCIL, convert_s4x4_uint_d24_unorm},
+ {WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
+ GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4,
+ WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
+ ARB_FRAMEBUFFER_OBJECT, convert_s4x4_uint_d24_unorm},
+ {WINED3DFMT_D16_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
+ ARB_DEPTH_TEXTURE, NULL},
+ {WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
+ GL_LUMINANCE, GL_UNSIGNED_SHORT, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, 0,
+ GL_DEPTH_COMPONENT, GL_FLOAT, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
+ ARB_DEPTH_BUFFER_FLOAT, NULL},
+ {WINED3DFMT_S8_UINT_D24_FLOAT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, 0,
+ GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
+ ARB_DEPTH_BUFFER_FLOAT, convert_s8_uint_d24_float},
+ /* Vendor-specific formats */
+ {WINED3DFMT_ATI2N, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
+ GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_COMPRESSED,
+ ATI_TEXTURE_COMPRESSION_3DC, NULL},
+ {WINED3DFMT_ATI2N, GL_COMPRESSED_RG_RGTC2, GL_COMPRESSED_RG_RGTC2, 0,
+ GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_COMPRESSED,
+ ARB_TEXTURE_COMPRESSION_RGTC, NULL},
+ {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
+ GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
+ EXT_PACKED_DEPTH_STENCIL, NULL},
+ {WINED3DFMT_INTZ, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
+ GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
+ ARB_FRAMEBUFFER_OBJECT, NULL},
+ {WINED3DFMT_NULL, 0, 0, 0,
+ GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET,
+ ARB_FRAMEBUFFER_OBJECT, NULL},
+};
+
+static inline int getFmtIdx(enum wined3d_format_id format_id)
+{
+ /* First check if the format is at the position of its value.
+ * This will catch the argb formats before the loop is entered. */
+ if (format_id < (sizeof(formats) / sizeof(*formats))
+ && formats[format_id].id == format_id)
+ {
+ return format_id;
+ }
+ else
+ {
+ unsigned int i;
+
+ for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
+ {
+ if (formats[i].id == format_id) return i;
+ }
+ }
+ return -1;
+}
+
+static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
+{
+ UINT format_count = sizeof(formats) / sizeof(*formats);
+ UINT i;
+
+ gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
+ if (!gl_info->formats)
+ {
+ ERR("Failed to allocate memory.\n");
+ return FALSE;
+ }
+
+ for (i = 0; i < format_count; ++i)
+ {
+ struct wined3d_format *format = &gl_info->formats[i];
+ format->id = formats[i].id;
+ format->red_size = formats[i].red_size;
+ format->green_size = formats[i].green_size;
+ format->blue_size = formats[i].blue_size;
+ format->alpha_size = formats[i].alpha_size;
+ format->red_offset = formats[i].red_offset;
+ format->green_offset = formats[i].green_offset;
+ format->blue_offset = formats[i].blue_offset;
+ format->alpha_offset = formats[i].alpha_offset;
+ format->byte_count = formats[i].bpp;
+ format->depth_size = formats[i].depth_size;
+ format->stencil_size = formats[i].stencil_size;
+ format->block_width = 1;
+ format->block_height = 1;
+ format->block_byte_count = formats[i].bpp;
+ }
+
+ for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
+ {
+ int fmt_idx = getFmtIdx(format_base_flags[i].id);
+
+ if (fmt_idx == -1)
+ {
+ ERR("Format %s (%#x) not found.\n",
+ debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
+ HeapFree(GetProcessHeap(), 0, gl_info->formats);
+ return FALSE;
+ }
+
+ gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
+ }
+
+ return TRUE;
+}
+
+static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
+{
+ unsigned int i;
+
+ for (i = 0; i < (sizeof(format_block_info) / sizeof(*format_block_info)); ++i)
+ {
+ struct wined3d_format *format;
+ int fmt_idx = getFmtIdx(format_block_info[i].id);
+
+ if (fmt_idx == -1)
+ {
+ ERR("Format %s (%#x) not found.\n",
+ debug_d3dformat(format_block_info[i].id), format_block_info[i].id);
+ return FALSE;
+ }
+
+ format = &gl_info->formats[fmt_idx];
+ format->block_width = format_block_info[i].block_width;
+ format->block_height = format_block_info[i].block_height;
+ format->block_byte_count = format_block_info[i].block_byte_count;
+ format->flags |= WINED3DFMT_FLAG_BLOCKS;
+ }
+
+ return TRUE;
+}
+
+/* Context activation is done by the caller. */
+static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
+{
+ /* Check if the default internal format is supported as a frame buffer
+ * target, otherwise fall back to the render target internal.
+ *
+ * Try to stick to the standard format if possible, this limits precision differences. */
+ GLenum status;
+ GLuint tex;
+
+ while (gl_info->gl_ops.gl.p_glGetError());
+ gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
+
+ gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
+
+ gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0,
+ format->glFormat, format->glType, NULL);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
+
+ status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ checkGLcall("Framebuffer format check");
+
+ if (status == GL_FRAMEBUFFER_COMPLETE)
+ {
+ TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
+ format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
+ format->rtInternal = format->glInternal;
+ }
+ else
+ {
+ if (!format->rtInternal)
+ {
+ if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
+ {
+ FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
+ " and no fallback specified.\n", debug_d3dformat(format->id));
+ format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
+ }
+ else
+ {
+ TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
+ }
+ format->rtInternal = format->glInternal;
+ }
+ else
+ {
+ TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
+ debug_d3dformat(format->id));
+
+ while (gl_info->gl_ops.gl.p_glGetError());
+
+ gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
+
+ gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0,
+ format->glFormat, format->glType, NULL);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
+
+ status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ checkGLcall("Framebuffer format check");
+
+ if (status == GL_FRAMEBUFFER_COMPLETE)
+ {
+ TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
+ debug_d3dformat(format->id));
+ }
+ else
+ {
+ FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
+ debug_d3dformat(format->id));
+ format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
+ }
+ }
+ }
+
+ if (status == GL_FRAMEBUFFER_COMPLETE && ((format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
+ || !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
+ && format->id != WINED3DFMT_NULL && format->id != WINED3DFMT_P8_UINT
+ && format->glFormat != GL_LUMINANCE && format->glFormat != GL_LUMINANCE_ALPHA
+ && (format->red_size || format->alpha_size))
+ {
+ DWORD readback[16 * 16], color, r_range, a_range;
+ BYTE r, a;
+ BOOL match = TRUE;
+ GLuint rb;
+
+ if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
+ || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
+ {
+ gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
+ gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
+ gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
+ gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
+ gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
+ checkGLcall("RB attachment");
+ }
+
+ gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
+ gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
+ if (gl_info->gl_ops.gl.p_glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
+ {
+ while (gl_info->gl_ops.gl.p_glGetError());
+ TRACE("Format doesn't support post-pixelshader blending.\n");
+ format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
+ gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 16);
+ gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
+ gl_info->gl_ops.gl.p_glLoadIdentity();
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
+ gl_info->gl_ops.gl.p_glLoadIdentity();
+
+ gl_info->gl_ops.gl.p_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ /* Draw a full-black quad */
+ gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
+ gl_info->gl_ops.gl.p_glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+ gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
+ gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
+ gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
+ gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
+ gl_info->gl_ops.gl.p_glEnd();
+
+ gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
+ /* Draw a half-transparent red quad */
+ gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
+ gl_info->gl_ops.gl.p_glColor4f(1.0f, 0.0f, 0.0f, 0.5f);
+ gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f, 0.0f);
+ gl_info->gl_ops.gl.p_glVertex3f(1.0f, -1.0f, 0.0f);
+ gl_info->gl_ops.gl.p_glVertex3f(-1.0f, 1.0f, 0.0f);
+ gl_info->gl_ops.gl.p_glVertex3f(1.0f, 1.0f, 0.0f);
+ gl_info->gl_ops.gl.p_glEnd();
+
+ gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
+
+ /* Rebinding texture to workaround a fglrx bug. */
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
+ gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
+ checkGLcall("Post-pixelshader blending check");
+
+ color = readback[7 * 16 + 7];
+ a = color >> 24;
+ r = (color & 0x00ff0000) >> 16;
+
+ r_range = format->red_size < 8 ? 1 << (8 - format->red_size) : 1;
+ a_range = format->alpha_size < 8 ? 1 << (8 - format->alpha_size) : 1;
+ if (format->red_size && (r < 0x7f - r_range || r > 0x7f + r_range))
+ match = FALSE;
+ else if (format->alpha_size > 1 && (a < 0xbf - a_range || a > 0xbf + a_range))
+ match = FALSE;
+ if (!match)
+ {
+ TRACE("Format doesn't support post-pixelshader blending.\n");
+ TRACE("Color output: %#x\n", color);
+ format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
+ }
+ else
+ {
+ TRACE("Format supports post-pixelshader blending.\n");
+ TRACE("Color output: %#x\n", color);
+ format->flags |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
+ }
+ }
+
+ if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
+ || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
+ {
+ gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
+ gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
+ gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
+ checkGLcall("RB cleanup");
+ }
+ }
+
+ if (format->glInternal != format->glGammaInternal)
+ {
+ gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0,
+ format->glFormat, format->glType, NULL);
+ gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
+
+ status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ checkGLcall("Framebuffer format check");
+
+ if (status == GL_FRAMEBUFFER_COMPLETE)
+ {
+ TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
+ format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
+ }
+ else
+ {
+ WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
+ }
+ }
+ else if (status == GL_FRAMEBUFFER_COMPLETE)
+ format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
+
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
+}
+
+static void query_format_flag(struct wined3d_gl_info *gl_info, struct wined3d_format *format,
+ GLint internal, GLenum pname, DWORD flag, const char *string)
+{
+ GLint value;
+
+ gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, internal, pname, 1, &value);
+ if (value == GL_FULL_SUPPORT)
+ {
+ TRACE("Format %s supports %s.\n", debug_d3dformat(format->id), string);
+ format->flags |= flag;
+ }
+ else
+ {
+ TRACE("Format %s doesn't support %s.\n", debug_d3dformat(format->id), string);
+ format->flags &= ~flag;
+ }
+}
+
+/* Context activation is done by the caller. */
+static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
+{
+ unsigned int i;
+ GLuint fbo;
+
+ if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
+ {
+ for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
+ {
+ GLint value;
+ struct wined3d_format *format = &gl_info->formats[i];
+
+ if (!format->glInternal)
+ continue;
+ if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
+ continue;
+
+ gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, format->glInternal,
+ GL_FRAMEBUFFER_RENDERABLE, 1, &value);
+ if (value == GL_FULL_SUPPORT)
+ {
+ TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
+ format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
+ format->rtInternal = format->glInternal;
+
+ query_format_flag(gl_info, format, format->glInternal, GL_FRAMEBUFFER_BLEND,
+ WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING, "post-pixelshader blending");
+ }
+ else
+ {
+ if (!format->rtInternal)
+ {
+ if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
+ {
+ WARN("Format %s with rendertarget flag is not supported as FBO color attachment"
+ " and no fallback specified.\n", debug_d3dformat(format->id));
+ format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
+ }
+ else
+ TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
+ format->rtInternal = format->glInternal;
+ }
+ else
+ {
+ gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, format->rtInternal,
+ GL_FRAMEBUFFER_RENDERABLE, 1, &value);
+ if (value == GL_FULL_SUPPORT)
+ {
+ TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
+ debug_d3dformat(format->id));
+ }
+ else
+ {
+ WARN("Format %s rtInternal format is not supported as FBO color attachment.\n",
+ debug_d3dformat(format->id));
+ format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
+ }
+ }
+ }
+
+ if (format->glInternal != format->glGammaInternal)
+ {
+ gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, format->glGammaInternal,
+ GL_FRAMEBUFFER_RENDERABLE, 1, &value);
+ if (value == GL_FULL_SUPPORT)
+ {
+ TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
+ format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
+ }
+ else
+ {
+ WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
+ }
+ }
+ else if (format->flags & WINED3DFMT_FLAG_FBO_ATTACHABLE)
+ format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
+ }
+ return;
+ }
+
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
+ gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
+ gl_info->gl_ops.gl.p_glReadBuffer(GL_COLOR_ATTACHMENT0);
+ }
+
+ for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
+ {
+ struct wined3d_format *format = &gl_info->formats[i];
+
+ if (!format->glInternal) continue;
+
+ if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
+ {
+ TRACE("Skipping format %s because it's a depth/stencil format.\n",
+ debug_d3dformat(format->id));
+ continue;
+ }
+
+ if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
+ {
+ TRACE("Skipping format %s because it's a compressed format.\n",
+ debug_d3dformat(format->id));
+ continue;
+ }
+
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ {
+ TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
+ check_fbo_compat(gl_info, format);
+ }
+ else
+ {
+ format->rtInternal = format->glInternal;
+ }
+ }
+
+ if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
+ gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
+}
+
+static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
+{
+ struct fragment_caps fragment_caps;
+ struct shader_caps shader_caps;
+ BOOL srgb_write;
+ unsigned int i;
+
+ adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
+ adapter->shader_backend->shader_get_caps(gl_info, &shader_caps);
+ srgb_write = (fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_SRGB_WRITE)
+ && (shader_caps.wined3d_caps & WINED3D_SHADER_CAP_SRGB_WRITE);
+
+ for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
+ {
+ int fmt_idx = getFmtIdx(format_texture_info[i].id);
+ struct wined3d_format *format;
+
+ if (fmt_idx == -1)
+ {
+ ERR("Format %s (%#x) not found.\n",
+ debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
+ return FALSE;
+ }
+
+ if (!gl_info->supported[format_texture_info[i].extension]) continue;
+
+ format = &gl_info->formats[fmt_idx];
+
+ /* ARB_texture_rg defines floating point formats, but only if
+ * ARB_texture_float is also supported. */
+ if (!gl_info->supported[ARB_TEXTURE_FLOAT]
+ && (format->flags & WINED3DFMT_FLAG_FLOAT))
+ continue;
+
+ format->glInternal = format_texture_info[i].gl_internal;
+ format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
+ format->rtInternal = format_texture_info[i].gl_rt_internal;
+ format->glFormat = format_texture_info[i].gl_format;
+ format->glType = format_texture_info[i].gl_type;
+ format->color_fixup = COLOR_FIXUP_IDENTITY;
+ format->flags |= format_texture_info[i].flags;
+ format->height_scale.numerator = 1;
+ format->height_scale.denominator = 1;
+
+ if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
+ {
+ query_format_flag(gl_info, format, format->glInternal, GL_VERTEX_TEXTURE,
+ WINED3DFMT_FLAG_VTF, "vertex texture usage");
+ query_format_flag(gl_info, format, format->glInternal, GL_FILTER,
+ WINED3DFMT_FLAG_FILTERING, "filtering");
+
+ if (format->glGammaInternal != format->glInternal)
+ {
+ query_format_flag(gl_info, format, format->glGammaInternal, GL_SRGB_READ,
+ WINED3DFMT_FLAG_SRGB_READ, "sRGB read");
+
+ if (srgb_write)
+ query_format_flag(gl_info, format, format->glGammaInternal, GL_SRGB_WRITE,
+ WINED3DFMT_FLAG_SRGB_WRITE, "sRGB write");
+ else
+ format->flags &= ~WINED3DFMT_FLAG_SRGB_WRITE;
+
+ if (!(format->flags & (WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE)))
+ format->glGammaInternal = format->glInternal;
+ else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
+ format->glInternal = format->glGammaInternal;
+ }
+ }
+ else
+ {
+ if (!gl_info->limits.vertex_samplers)
+ format->flags &= ~WINED3DFMT_FLAG_VTF;
+
+ if (!(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
+ format->flags |= WINED3DFMT_FLAG_FILTERING;
+ else if (format->id != WINED3DFMT_R32G32B32A32_FLOAT && format->id != WINED3DFMT_R32_FLOAT)
+ format->flags &= ~WINED3DFMT_FLAG_VTF;
+
+ if (format->glGammaInternal != format->glInternal)
+ {
+ /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
+ if (!gl_info->supported[EXT_TEXTURE_SRGB])
+ {
+ format->glGammaInternal = format->glInternal;
+ format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
+ }
+ else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
+ {
+ format->glInternal = format->glGammaInternal;
+ }
+ }
+
+ if ((format->flags & WINED3DFMT_FLAG_SRGB_WRITE) && !srgb_write)
+ format->flags &= ~WINED3DFMT_FLAG_SRGB_WRITE;
+ }
+
+ /* Texture conversion stuff */
+ format->convert = format_texture_info[i].convert;
+ format->conv_byte_count = format_texture_info[i].conv_byte_count;
+ }
+
+ return TRUE;
+}
+
+static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
+{
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+ c1 >>= 8; c2 >>= 8;
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+ c1 >>= 8; c2 >>= 8;
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+ c1 >>= 8; c2 >>= 8;
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
+ return TRUE;
+}
+
+/* A context is provided by the caller */
+static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
+{
+ static const DWORD data[] = {0x00000000, 0xffffffff};
+ GLuint tex, fbo, buffer;
+ DWORD readback[16 * 1];
+ BOOL ret = FALSE;
+
+ /* Render a filtered texture and see what happens. This is intended to detect the lack of
+ * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
+ * falling back to software. If this changes in the future this code will get fooled and
+ * apps might hit the software path due to incorrectly advertised caps.
+ *
+ * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
+ * disable fallback, if Apple or ATI ever change the driver behavior they will break more
+ * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
+ */
+
+ while (gl_info->gl_ops.gl.p_glGetError());
+
+ gl_info->gl_ops.gl.p_glGenTextures(1, &buffer);
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
+ memset(readback, 0x7e, sizeof(readback));
+ gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0,
+ GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+
+ gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
+ gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0,
+ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+ gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
+
+ gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
+ gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
+ gl_info->gl_ops.gl.p_glDrawBuffer(GL_COLOR_ATTACHMENT0);
+
+ gl_info->gl_ops.gl.p_glViewport(0, 0, 16, 1);
+ gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
+ gl_info->gl_ops.gl.p_glLoadIdentity();
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
+ gl_info->gl_ops.gl.p_glLoadIdentity();
+
+ gl_info->gl_ops.gl.p_glClearColor(0, 1, 0, 0);
+ gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
+
+ gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
+ gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 0.0);
+ gl_info->gl_ops.gl.p_glVertex2f(-1.0f, -1.0f);
+ gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 0.0);
+ gl_info->gl_ops.gl.p_glVertex2f(1.0f, -1.0f);
+ gl_info->gl_ops.gl.p_glTexCoord2f(0.0, 1.0);
+ gl_info->gl_ops.gl.p_glVertex2f(-1.0f, 1.0f);
+ gl_info->gl_ops.gl.p_glTexCoord2f(1.0, 1.0);
+ gl_info->gl_ops.gl.p_glVertex2f(1.0f, 1.0f);
+ gl_info->gl_ops.gl.p_glEnd();
+
+ gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, buffer);
+ memset(readback, 0x7f, sizeof(readback));
+ gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
+ if (color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5)
+ || color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
+ {
+ TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, assuming no filtering\n",
+ readback[6], readback[9]);
+ ret = FALSE;
+ }
+ else
+ {
+ TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
+ readback[6], readback[9]);
+ ret = TRUE;
+ }
+
+ gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &buffer);
+
+ if (gl_info->gl_ops.gl.p_glGetError())
+ {
+ FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
+ ret = FALSE;
+ }
+
+ return ret;
+}
+
+static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
+{
+ struct wined3d_format *format;
+ unsigned int fmt_idx, i;
+ static const enum wined3d_format_id fmts16[] =
+ {
+ WINED3DFMT_R16_FLOAT,
+ WINED3DFMT_R16G16_FLOAT,
+ WINED3DFMT_R16G16B16A16_FLOAT,
+ };
+ BOOL filtered;
+
+ if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
+ /* This was already handled by init_format_texture_info(). */
+ return;
+
+ if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
+ {
+ WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
+ if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
+ {
+ TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
+ filtered = TRUE;
+ }
+ else if (gl_info->limits.glsl_varyings > 44)
+ {
+ TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
+ filtered = TRUE;
+ }
+ else
+ {
+ TRACE("Assuming no float16 blending\n");
+ filtered = FALSE;
+ }
+
+ if(filtered)
+ {
+ for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
+ {
+ fmt_idx = getFmtIdx(fmts16[i]);
+ gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
+ }
+ }
+ return;
+ }
+
+ for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
+ {
+ fmt_idx = getFmtIdx(fmts16[i]);
+ format = &gl_info->formats[fmt_idx];
+ if (!format->glInternal) continue; /* Not supported by GL */
+
+ filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
+ if(filtered)
+ {
+ TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
+ format->flags |= WINED3DFMT_FLAG_FILTERING;
+ }
+ else
+ {
+ TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
+ }
+ }
+}
+
+static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
+{
+ unsigned int i;
+ int idx;
+
+ idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
+ gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
+
+ idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
+ gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
+
+ idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
+ gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
+
+ idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
+ gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
+
+ idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
+ gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
+
+ /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
+ * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
+ * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
+ * the only driver that implements it(fglrx) has a buggy implementation.
+ *
+ * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
+ * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
+ * conversion for this format.
+ */
+ if (!gl_info->supported[NV_TEXTURE_SHADER])
+ {
+ idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
+ gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
+ idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
+ gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
+ }
+ else
+ {
+ idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
+ gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
+
+ idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
+ gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
+ }
+
+ if (!gl_info->supported[NV_TEXTURE_SHADER])
+ {
+ /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
+ * with each other
+ */
+ idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
+ gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
+ idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
+ gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
+ idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
+ gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
+ }
+ else
+ {
+ /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
+ * are converted at surface loading time, but they do not need any modification in
+ * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
+ * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
+ */
+ }
+
+ if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
+ {
+ idx = getFmtIdx(WINED3DFMT_ATI2N);
+ gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
+ }
+ else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
+ {
+ idx = getFmtIdx(WINED3DFMT_ATI2N);
+ gl_info->formats[idx].color_fixup= create_color_fixup_desc(
+ 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
+ }
+
+ if (!gl_info->supported[APPLE_YCBCR_422])
+ {
+ idx = getFmtIdx(WINED3DFMT_YUY2);
+ gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
+
+ idx = getFmtIdx(WINED3DFMT_UYVY);
+ gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
+ }
+
+ idx = getFmtIdx(WINED3DFMT_YV12);
+ gl_info->formats[idx].flags |= WINED3DFMT_FLAG_HEIGHT_SCALE;
+ gl_info->formats[idx].height_scale.numerator = 3;
+ gl_info->formats[idx].height_scale.denominator = 2;
+ gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
+
+ if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
+ {
+ idx = getFmtIdx(WINED3DFMT_P8_UINT);
+ gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
+ }
+
+ if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
+ {
+ idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
+ gl_info->formats[idx].gl_vtx_format = GL_BGRA;
+ }
+
+ if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
+ {
+ /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
+ * It is the job of the vertex buffer code to make sure that the vbos have the right format */
+ idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
+ gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
+
+ idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
+ gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
+ }
+
+ if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL])
+ {
+ idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
+ gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
+
+ idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
+ gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
+
+ idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
+ gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
+ }
+
+ if (gl_info->quirks & WINED3D_QUIRK_BROKEN_RGBA16)
+ {
+ idx = getFmtIdx(WINED3DFMT_R16G16B16A16_UNORM);
+ gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
+ }
+
+ /* ATI instancing hack: Although ATI cards do not support Shader Model
+ * 3.0, they support instancing. To query if the card supports instancing
+ * CheckDeviceFormat() with the special format MAKEFOURCC('I','N','S','T')
+ * is used. Should an application check for this, provide a proper return
+ * value. We can do instancing with all shader versions, but we need
+ * vertex shaders.
+ *
+ * Additionally applications have to set the D3DRS_POINTSIZE render state
+ * to MAKEFOURCC('I','N','S','T') once to enable instancing. Wined3d
+ * doesn't need that and just ignores it.
+ *
+ * With Shader Model 3.0 capable cards Instancing 'just works' in Windows. */
+ /* FIXME: This should just check the shader backend caps. */
+ if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_VERTEX_SHADER])
+ {
+ idx = getFmtIdx(WINED3DFMT_INST);
+ gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
+ }
+
+ /* Depth bound test. To query if the card supports it CheckDeviceFormat()
+ * with the special format MAKEFOURCC('N','V','D','B') is used. It is
+ * enabled by setting D3DRS_ADAPTIVETESS_X render state to
+ * MAKEFOURCC('N','V','D','B') and then controlled by setting
+ * D3DRS_ADAPTIVETESS_Z (zMin) and D3DRS_ADAPTIVETESS_W (zMax) to test
+ * value. */
+ if (gl_info->supported[EXT_DEPTH_BOUNDS_TEST])
+ {
+ idx = getFmtIdx(WINED3DFMT_NVDB);
+ gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
+ }
+
+ /* RESZ aka AMD DX9-level hack for multisampled depth buffer resolve. You query for RESZ
+ * support by checking for availability of MAKEFOURCC('R','E','S','Z') surfaces with
+ * RENDERTARGET usage. */
+ if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
+ {
+ idx = getFmtIdx(WINED3DFMT_RESZ);
+ gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET;
+ }
+
+ for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
+ {
+ struct wined3d_format *format = &gl_info->formats[i];
+
+ if (!(format->flags & WINED3DFMT_FLAG_TEXTURE))
+ continue;
+
+ if (!adapter->shader_backend->shader_color_fixup_supported(format->color_fixup)
+ || !adapter->fragment_pipe->color_fixup_supported(format->color_fixup))
+ format->flags &= ~WINED3DFMT_FLAG_TEXTURE;
+ }
+}
+
+static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
+{
+ unsigned int i;
+
+ for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
+ {
+ struct wined3d_format *format;
+ int fmt_idx = getFmtIdx(format_vertex_info[i].id);
+
+ if (fmt_idx == -1)
+ {
+ ERR("Format %s (%#x) not found.\n",
+ debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
+ return FALSE;
+ }
+
+ format = &gl_info->formats[fmt_idx];
+ format->emit_idx = format_vertex_info[i].emit_idx;
+ format->component_count = format_vertex_info[i].component_count;
+ format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
+ format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
+ format->gl_normalized = format_vertex_info[i].gl_normalized;
+ format->component_size = format_vertex_info[i].component_size;
+ }
+
+ return TRUE;
+}
+
+BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
+{
+ if (!init_format_base_info(gl_info)) return FALSE;
+
+ if (!init_format_block_info(gl_info))
+ {
+ HeapFree(GetProcessHeap(), 0, gl_info->formats);
+ gl_info->formats = NULL;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Context activation is done by the caller. */
+BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter)
+{
+ struct wined3d_gl_info *gl_info = &adapter->gl_info;
+
+ if (!init_format_base_info(gl_info)) return FALSE;
+
+ if (!init_format_block_info(gl_info)) goto fail;
+ if (!init_format_texture_info(adapter, gl_info)) goto fail;
+ if (!init_format_vertex_info(gl_info)) goto fail;
+
+ apply_format_fixups(adapter, gl_info);
+ init_format_fbo_compat_info(gl_info);
+ init_format_filter_info(gl_info, adapter->driver_info.vendor);
+
+ return TRUE;
+
+fail:
+ HeapFree(GetProcessHeap(), 0, gl_info->formats);
+ gl_info->formats = NULL;
+ return FALSE;
+}
+
+const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
+ enum wined3d_format_id format_id)
+{
+ int idx = getFmtIdx(format_id);
+
+ if (idx == -1)
+ {
+ FIXME("Can't find format %s (%#x) in the format lookup table\n",
+ debug_d3dformat(format_id), format_id);
+ /* Get the caller a valid pointer */
+ idx = getFmtIdx(WINED3DFMT_UNKNOWN);
+ }
+
+ return &gl_info->formats[idx];
+}
+
+UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height)
+{
+ UINT size;
+
+ if (format->id == WINED3DFMT_UNKNOWN)
+ {
+ size = 0;
+ }
+ else if (format->flags & WINED3DFMT_FLAG_BLOCKS)
+ {
+ UINT row_block_count = (width + format->block_width - 1) / format->block_width;
+ UINT row_count = (height + format->block_height - 1) / format->block_height;
+ size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
+ }
+ else
+ {
+ size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
+ }
+
+ if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
+ {
+ /* The D3D format requirements make sure that the resulting format is an integer again */
+ size *= format->height_scale.numerator;
+ size /= format->height_scale.denominator;
+ }
+
+ return size;
+}
+
+/*****************************************************************************
+ * Trace formatting of useful values
+ */
+const char *debug_d3dformat(enum wined3d_format_id format_id)
+{
+ switch (format_id)
+ {
+#define FMT_TO_STR(format_id) case format_id: return #format_id
+ FMT_TO_STR(WINED3DFMT_UNKNOWN);
+ FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
+ FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
+ FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
+ FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
+ FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
+ FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
+ FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
+ FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
+ FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
+ FMT_TO_STR(WINED3DFMT_P8_UINT);
+ FMT_TO_STR(WINED3DFMT_L8_UNORM);
+ FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
+ FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
+ FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
+ FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
+ FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
+ FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
+ FMT_TO_STR(WINED3DFMT_UYVY);
+ FMT_TO_STR(WINED3DFMT_YUY2);
+ FMT_TO_STR(WINED3DFMT_YV12);
+ FMT_TO_STR(WINED3DFMT_DXT1);
+ FMT_TO_STR(WINED3DFMT_DXT2);
+ FMT_TO_STR(WINED3DFMT_DXT3);
+ FMT_TO_STR(WINED3DFMT_DXT4);
+ FMT_TO_STR(WINED3DFMT_DXT5);
+ FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
+ FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
+ FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
+ FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
+ FMT_TO_STR(WINED3DFMT_D32_UNORM);
+ FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
+ FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
+ FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
+ FMT_TO_STR(WINED3DFMT_L16_UNORM);
+ FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
+ FMT_TO_STR(WINED3DFMT_VERTEXDATA);
+ FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
+ FMT_TO_STR(WINED3DFMT_ATI2N);
+ FMT_TO_STR(WINED3DFMT_NVDB);
+ FMT_TO_STR(WINED3DFMT_NVHU);
+ FMT_TO_STR(WINED3DFMT_NVHS);
+ FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
+ FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
+ FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
+ FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
+ FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
+ FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
+ FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
+ FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
+ FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
+ FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
+ FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
+ FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
+ FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
+ FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
+ FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
+ FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
+ FMT_TO_STR(WINED3DFMT_R32G32_UINT);
+ FMT_TO_STR(WINED3DFMT_R32G32_SINT);
+ FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
+ FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
+ FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
+ FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
+ FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
+ FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
+ FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
+ FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
+ FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
+ FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
+ FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
+ FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
+ FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
+ FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
+ FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
+ FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
+ FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
+ FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
+ FMT_TO_STR(WINED3DFMT_R16G16_UINT);
+ FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
+ FMT_TO_STR(WINED3DFMT_R16G16_SINT);
+ FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
+ FMT_TO_STR(WINED3DFMT_D32_FLOAT);
+ FMT_TO_STR(WINED3DFMT_R32_FLOAT);
+ FMT_TO_STR(WINED3DFMT_R32_UINT);
+ FMT_TO_STR(WINED3DFMT_R32_SINT);
+ FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
+ FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
+ FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
+ FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
+ FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
+ FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
+ FMT_TO_STR(WINED3DFMT_R8G8_UINT);
+ FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
+ FMT_TO_STR(WINED3DFMT_R8G8_SINT);
+ FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
+ FMT_TO_STR(WINED3DFMT_R16_FLOAT);
+ FMT_TO_STR(WINED3DFMT_D16_UNORM);
+ FMT_TO_STR(WINED3DFMT_R16_UNORM);
+ FMT_TO_STR(WINED3DFMT_R16_UINT);
+ FMT_TO_STR(WINED3DFMT_R16_SNORM);
+ FMT_TO_STR(WINED3DFMT_R16_SINT);
+ FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
+ FMT_TO_STR(WINED3DFMT_R8_UNORM);
+ FMT_TO_STR(WINED3DFMT_R8_UINT);
+ FMT_TO_STR(WINED3DFMT_R8_SNORM);
+ FMT_TO_STR(WINED3DFMT_R8_SINT);
+ FMT_TO_STR(WINED3DFMT_A8_UNORM);
+ FMT_TO_STR(WINED3DFMT_R1_UNORM);
+ FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
+ FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
+ FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
+ FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
+ FMT_TO_STR(WINED3DFMT_BC1_UNORM);
+ FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
+ FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
+ FMT_TO_STR(WINED3DFMT_BC2_UNORM);
+ FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
+ FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
+ FMT_TO_STR(WINED3DFMT_BC3_UNORM);
+ FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
+ FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
+ FMT_TO_STR(WINED3DFMT_BC4_UNORM);
+ FMT_TO_STR(WINED3DFMT_BC4_SNORM);
+ FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
+ FMT_TO_STR(WINED3DFMT_BC5_UNORM);
+ FMT_TO_STR(WINED3DFMT_BC5_SNORM);
+ FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
+ FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
+ FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
+ FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
+ FMT_TO_STR(WINED3DFMT_INTZ);
+ FMT_TO_STR(WINED3DFMT_RESZ);
+ FMT_TO_STR(WINED3DFMT_NULL);
+ FMT_TO_STR(WINED3DFMT_R16);
+ FMT_TO_STR(WINED3DFMT_AL16);
+#undef FMT_TO_STR
+ default:
+ {
+ char fourcc[5];
+ fourcc[0] = (char)(format_id);
+ fourcc[1] = (char)(format_id >> 8);
+ fourcc[2] = (char)(format_id >> 16);
+ fourcc[3] = (char)(format_id >> 24);
+ fourcc[4] = 0;
+ if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
+ FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
+ else
+ FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
+ }
+ return "unrecognized";
+ }
+}
+
+const char *debug_d3ddevicetype(enum wined3d_device_type device_type)
+{
+ switch (device_type)
+ {
+#define DEVTYPE_TO_STR(dev) case dev: return #dev
+ DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_HAL);
+ DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_REF);
+ DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_SW);
+#undef DEVTYPE_TO_STR
+ default:
+ FIXME("Unrecognized device type %#x.\n", device_type);
+ return "unrecognized";
+ }
+}
+
+const char *debug_d3dusage(DWORD usage)
+{
+ char buf[333];
+
+ buf[0] = '\0';
+#define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
+ WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
+ WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
+ WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
+ WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
+ WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
+ WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
+ WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
+ WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
+ WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
+ WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
+ WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
+ WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
+ WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
+#undef WINED3DUSAGE_TO_STR
+ if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
+
+ return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
+}
+
+const char *debug_d3dusagequery(DWORD usagequery)
+{
+ char buf[238];
+
+ buf[0] = '\0';
+#define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
+ WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
+ WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
+ WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
+ WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
+ WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
+ WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
+ WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
+#undef WINED3DUSAGEQUERY_TO_STR
+ if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
+
+ return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
+}
+
+const char *debug_d3ddeclmethod(enum wined3d_decl_method method)
+{
+ switch (method)
+ {
+#define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
+ WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_DEFAULT);
+ WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_U);
+ WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_PARTIAL_V);
+ WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_CROSS_UV);
+ WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_UV);
+ WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP);
+ WINED3DDECLMETHOD_TO_STR(WINED3D_DECL_METHOD_LOOKUP_PRESAMPLED);
+#undef WINED3DDECLMETHOD_TO_STR
+ default:
+ FIXME("Unrecognized declaration method %#x.\n", method);
+ return "unrecognized";
+ }
+}
+
+const char *debug_d3ddeclusage(enum wined3d_decl_usage usage)
+{
+ switch (usage)
+ {
+#define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
+ WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITION);
+ WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_WEIGHT);
+ WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BLEND_INDICES);
+ WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_NORMAL);
+ WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_PSIZE);
+ WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TEXCOORD);
+ WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TANGENT);
+ WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_BINORMAL);
+ WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_TESS_FACTOR);
+ WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_POSITIONT);
+ WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_COLOR);
+ WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_FOG);
+ WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_DEPTH);
+ WINED3DDECLUSAGE_TO_STR(WINED3D_DECL_USAGE_SAMPLE);
+#undef WINED3DDECLUSAGE_TO_STR
+ default:
+ FIXME("Unrecognized %u declaration usage!\n", usage);
+ return "unrecognized";
+ }
+}
+
+const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type)
+{
+ switch (resource_type)
+ {
+#define RES_TO_STR(res) case res: return #res
+ RES_TO_STR(WINED3D_RTYPE_SURFACE);
+ RES_TO_STR(WINED3D_RTYPE_VOLUME);
+ RES_TO_STR(WINED3D_RTYPE_TEXTURE);
+ RES_TO_STR(WINED3D_RTYPE_VOLUME_TEXTURE);
+ RES_TO_STR(WINED3D_RTYPE_CUBE_TEXTURE);
+ RES_TO_STR(WINED3D_RTYPE_BUFFER);
+#undef RES_TO_STR
+ default:
+ FIXME("Unrecognized resource type %#x.\n", resource_type);
+ return "unrecognized";
+ }
+}
+
+const char *debug_d3dprimitivetype(enum wined3d_primitive_type primitive_type)
+{
+ switch (primitive_type)
+ {
+#define PRIM_TO_STR(prim) case prim: return #prim
+ PRIM_TO_STR(WINED3D_PT_UNDEFINED);
+ PRIM_TO_STR(WINED3D_PT_POINTLIST);
+ PRIM_TO_STR(WINED3D_PT_LINELIST);
+ PRIM_TO_STR(WINED3D_PT_LINESTRIP);
+ PRIM_TO_STR(WINED3D_PT_TRIANGLELIST);
+ PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP);
+ PRIM_TO_STR(WINED3D_PT_TRIANGLEFAN);
+ PRIM_TO_STR(WINED3D_PT_LINELIST_ADJ);
+ PRIM_TO_STR(WINED3D_PT_LINESTRIP_ADJ);
+ PRIM_TO_STR(WINED3D_PT_TRIANGLELIST_ADJ);
+ PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP_ADJ);
+#undef PRIM_TO_STR
+ default:
+ FIXME("Unrecognized %u primitive type!\n", primitive_type);
+ return "unrecognized";
+ }
+}
+
+const char *debug_d3drenderstate(enum wined3d_render_state state)
+{
+ switch (state)
+ {
+#define D3DSTATE_TO_STR(u) case u: return #u
+ D3DSTATE_TO_STR(WINED3D_RS_ANTIALIAS);
+ D3DSTATE_TO_STR(WINED3D_RS_TEXTUREPERSPECTIVE);
+ D3DSTATE_TO_STR(WINED3D_RS_WRAPU);
+ D3DSTATE_TO_STR(WINED3D_RS_WRAPV);
+ D3DSTATE_TO_STR(WINED3D_RS_ZENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_FILLMODE);
+ D3DSTATE_TO_STR(WINED3D_RS_SHADEMODE);
+ D3DSTATE_TO_STR(WINED3D_RS_LINEPATTERN);
+ D3DSTATE_TO_STR(WINED3D_RS_MONOENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_ROP2);
+ D3DSTATE_TO_STR(WINED3D_RS_PLANEMASK);
+ D3DSTATE_TO_STR(WINED3D_RS_ZWRITEENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_ALPHATESTENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_LASTPIXEL);
+ D3DSTATE_TO_STR(WINED3D_RS_SRCBLEND);
+ D3DSTATE_TO_STR(WINED3D_RS_DESTBLEND);
+ D3DSTATE_TO_STR(WINED3D_RS_CULLMODE);
+ D3DSTATE_TO_STR(WINED3D_RS_ZFUNC);
+ D3DSTATE_TO_STR(WINED3D_RS_ALPHAREF);
+ D3DSTATE_TO_STR(WINED3D_RS_ALPHAFUNC);
+ D3DSTATE_TO_STR(WINED3D_RS_DITHERENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_ALPHABLENDENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_FOGENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_SPECULARENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_ZVISIBLE);
+ D3DSTATE_TO_STR(WINED3D_RS_SUBPIXEL);
+ D3DSTATE_TO_STR(WINED3D_RS_SUBPIXELX);
+ D3DSTATE_TO_STR(WINED3D_RS_STIPPLEDALPHA);
+ D3DSTATE_TO_STR(WINED3D_RS_FOGCOLOR);
+ D3DSTATE_TO_STR(WINED3D_RS_FOGTABLEMODE);
+ D3DSTATE_TO_STR(WINED3D_RS_FOGSTART);
+ D3DSTATE_TO_STR(WINED3D_RS_FOGEND);
+ D3DSTATE_TO_STR(WINED3D_RS_FOGDENSITY);
+ D3DSTATE_TO_STR(WINED3D_RS_STIPPLEENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_EDGEANTIALIAS);
+ D3DSTATE_TO_STR(WINED3D_RS_COLORKEYENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_MIPMAPLODBIAS);
+ D3DSTATE_TO_STR(WINED3D_RS_RANGEFOGENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_ANISOTROPY);
+ D3DSTATE_TO_STR(WINED3D_RS_FLUSHBATCH);
+ D3DSTATE_TO_STR(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT);
+ D3DSTATE_TO_STR(WINED3D_RS_STENCILENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_STENCILFAIL);
+ D3DSTATE_TO_STR(WINED3D_RS_STENCILZFAIL);
+ D3DSTATE_TO_STR(WINED3D_RS_STENCILPASS);
+ D3DSTATE_TO_STR(WINED3D_RS_STENCILFUNC);
+ D3DSTATE_TO_STR(WINED3D_RS_STENCILREF);
+ D3DSTATE_TO_STR(WINED3D_RS_STENCILMASK);
+ D3DSTATE_TO_STR(WINED3D_RS_STENCILWRITEMASK);
+ D3DSTATE_TO_STR(WINED3D_RS_TEXTUREFACTOR);
+ D3DSTATE_TO_STR(WINED3D_RS_WRAP0);
+ D3DSTATE_TO_STR(WINED3D_RS_WRAP1);
+ D3DSTATE_TO_STR(WINED3D_RS_WRAP2);
+ D3DSTATE_TO_STR(WINED3D_RS_WRAP3);
+ D3DSTATE_TO_STR(WINED3D_RS_WRAP4);
+ D3DSTATE_TO_STR(WINED3D_RS_WRAP5);
+ D3DSTATE_TO_STR(WINED3D_RS_WRAP6);
+ D3DSTATE_TO_STR(WINED3D_RS_WRAP7);
+ D3DSTATE_TO_STR(WINED3D_RS_CLIPPING);
+ D3DSTATE_TO_STR(WINED3D_RS_LIGHTING);
+ D3DSTATE_TO_STR(WINED3D_RS_EXTENTS);
+ D3DSTATE_TO_STR(WINED3D_RS_AMBIENT);
+ D3DSTATE_TO_STR(WINED3D_RS_FOGVERTEXMODE);
+ D3DSTATE_TO_STR(WINED3D_RS_COLORVERTEX);
+ D3DSTATE_TO_STR(WINED3D_RS_LOCALVIEWER);
+ D3DSTATE_TO_STR(WINED3D_RS_NORMALIZENORMALS);
+ D3DSTATE_TO_STR(WINED3D_RS_COLORKEYBLENDENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_DIFFUSEMATERIALSOURCE);
+ D3DSTATE_TO_STR(WINED3D_RS_SPECULARMATERIALSOURCE);
+ D3DSTATE_TO_STR(WINED3D_RS_AMBIENTMATERIALSOURCE);
+ D3DSTATE_TO_STR(WINED3D_RS_EMISSIVEMATERIALSOURCE);
+ D3DSTATE_TO_STR(WINED3D_RS_VERTEXBLEND);
+ D3DSTATE_TO_STR(WINED3D_RS_CLIPPLANEENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_SOFTWAREVERTEXPROCESSING);
+ D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE);
+ D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MIN);
+ D3DSTATE_TO_STR(WINED3D_RS_POINTSPRITEENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_POINTSCALEENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_A);
+ D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_B);
+ D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_C);
+ D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEANTIALIAS);
+ D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEMASK);
+ D3DSTATE_TO_STR(WINED3D_RS_PATCHEDGESTYLE);
+ D3DSTATE_TO_STR(WINED3D_RS_PATCHSEGMENTS);
+ D3DSTATE_TO_STR(WINED3D_RS_DEBUGMONITORTOKEN);
+ D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MAX);
+ D3DSTATE_TO_STR(WINED3D_RS_INDEXEDVERTEXBLENDENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_TWEENFACTOR);
+ D3DSTATE_TO_STR(WINED3D_RS_BLENDOP);
+ D3DSTATE_TO_STR(WINED3D_RS_POSITIONDEGREE);
+ D3DSTATE_TO_STR(WINED3D_RS_NORMALDEGREE);
+ D3DSTATE_TO_STR(WINED3D_RS_SCISSORTESTENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_SLOPESCALEDEPTHBIAS);
+ D3DSTATE_TO_STR(WINED3D_RS_ANTIALIASEDLINEENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_MINTESSELLATIONLEVEL);
+ D3DSTATE_TO_STR(WINED3D_RS_MAXTESSELLATIONLEVEL);
+ D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_X);
+ D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Y);
+ D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Z);
+ D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_W);
+ D3DSTATE_TO_STR(WINED3D_RS_ENABLEADAPTIVETESSELLATION);
+ D3DSTATE_TO_STR(WINED3D_RS_TWOSIDEDSTENCILMODE);
+ D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFAIL);
+ D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILZFAIL);
+ D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILPASS);
+ D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFUNC);
+ D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1);
+ D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2);
+ D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3);
+ D3DSTATE_TO_STR(WINED3D_RS_BLENDFACTOR);
+ D3DSTATE_TO_STR(WINED3D_RS_SRGBWRITEENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIAS);
+ D3DSTATE_TO_STR(WINED3D_RS_WRAP8);
+ D3DSTATE_TO_STR(WINED3D_RS_WRAP9);
+ D3DSTATE_TO_STR(WINED3D_RS_WRAP10);
+ D3DSTATE_TO_STR(WINED3D_RS_WRAP11);
+ D3DSTATE_TO_STR(WINED3D_RS_WRAP12);
+ D3DSTATE_TO_STR(WINED3D_RS_WRAP13);
+ D3DSTATE_TO_STR(WINED3D_RS_WRAP14);
+ D3DSTATE_TO_STR(WINED3D_RS_WRAP15);
+ D3DSTATE_TO_STR(WINED3D_RS_SEPARATEALPHABLENDENABLE);
+ D3DSTATE_TO_STR(WINED3D_RS_SRCBLENDALPHA);
+ D3DSTATE_TO_STR(WINED3D_RS_DESTBLENDALPHA);
+ D3DSTATE_TO_STR(WINED3D_RS_BLENDOPALPHA);
+#undef D3DSTATE_TO_STR
+ default:
+ FIXME("Unrecognized %u render state!\n", state);
+ return "unrecognized";
+ }
+}
+
+const char *debug_d3dsamplerstate(enum wined3d_sampler_state state)
+{
+ switch (state)
+ {
+#define D3DSTATE_TO_STR(u) case u: return #u
+ D3DSTATE_TO_STR(WINED3D_SAMP_BORDER_COLOR);
+ D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_U);
+ D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_V);
+ D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_W);
+ D3DSTATE_TO_STR(WINED3D_SAMP_MAG_FILTER);
+ D3DSTATE_TO_STR(WINED3D_SAMP_MIN_FILTER);
+ D3DSTATE_TO_STR(WINED3D_SAMP_MIP_FILTER);
+ D3DSTATE_TO_STR(WINED3D_SAMP_MIPMAP_LOD_BIAS);
+ D3DSTATE_TO_STR(WINED3D_SAMP_MAX_MIP_LEVEL);
+ D3DSTATE_TO_STR(WINED3D_SAMP_MAX_ANISOTROPY);
+ D3DSTATE_TO_STR(WINED3D_SAMP_SRGB_TEXTURE);
+ D3DSTATE_TO_STR(WINED3D_SAMP_ELEMENT_INDEX);
+ D3DSTATE_TO_STR(WINED3D_SAMP_DMAP_OFFSET);
+#undef D3DSTATE_TO_STR
+ default:
+ FIXME("Unrecognized %u sampler state!\n", state);
+ return "unrecognized";
+ }
+}
+
+const char *debug_d3dtexturefiltertype(enum wined3d_texture_filter_type filter_type)
+{
+ switch (filter_type)
+ {
+#define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
+ D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_NONE);
+ D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_POINT);
+ D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_LINEAR);
+ D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_ANISOTROPIC);
+ D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_FLAT_CUBIC);
+ D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_CUBIC);
+ D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_PYRAMIDAL_QUAD);
+ D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_QUAD);
+#undef D3DTEXTUREFILTERTYPE_TO_STR
+ default:
+ FIXME("Unrecognied texture filter type 0x%08x.\n", filter_type);
+ return "unrecognized";
+ }
+}
+
+const char *debug_d3dtexturestate(enum wined3d_texture_stage_state state)
+{
+ switch (state)
+ {
+#define D3DSTATE_TO_STR(u) case u: return #u
+ D3DSTATE_TO_STR(WINED3D_TSS_COLOR_OP);
+ D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG1);
+ D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG2);
+ D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_OP);
+ D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG1);
+ D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG2);
+ D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT00);
+ D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT01);
+ D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT10);
+ D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT11);
+ D3DSTATE_TO_STR(WINED3D_TSS_TEXCOORD_INDEX);
+ D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LSCALE);
+ D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LOFFSET);
+ D3DSTATE_TO_STR(WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS);
+ D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG0);
+ D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG0);
+ D3DSTATE_TO_STR(WINED3D_TSS_RESULT_ARG);
+ D3DSTATE_TO_STR(WINED3D_TSS_CONSTANT);
+#undef D3DSTATE_TO_STR
+ default:
+ FIXME("Unrecognized %u texture state!\n", state);
+ return "unrecognized";
+ }
+}
+
+const char *debug_d3dtop(enum wined3d_texture_op d3dtop)
+{
+ switch (d3dtop)
+ {
+#define D3DTOP_TO_STR(u) case u: return #u
+ D3DTOP_TO_STR(WINED3D_TOP_DISABLE);
+ D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG1);
+ D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG2);
+ D3DTOP_TO_STR(WINED3D_TOP_MODULATE);
+ D3DTOP_TO_STR(WINED3D_TOP_MODULATE_2X);
+ D3DTOP_TO_STR(WINED3D_TOP_MODULATE_4X);
+ D3DTOP_TO_STR(WINED3D_TOP_ADD);
+ D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED);
+ D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED_2X);
+ D3DTOP_TO_STR(WINED3D_TOP_SUBTRACT);
+ D3DTOP_TO_STR(WINED3D_TOP_ADD_SMOOTH);
+ D3DTOP_TO_STR(WINED3D_TOP_BLEND_DIFFUSE_ALPHA);
+ D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA);
+ D3DTOP_TO_STR(WINED3D_TOP_BLEND_FACTOR_ALPHA);
+ D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM);
+ D3DTOP_TO_STR(WINED3D_TOP_BLEND_CURRENT_ALPHA);
+ D3DTOP_TO_STR(WINED3D_TOP_PREMODULATE);
+ D3DTOP_TO_STR(WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR);
+ D3DTOP_TO_STR(WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA);
+ D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR);
+ D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA);
+ D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP);
+ D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP_LUMINANCE);
+ D3DTOP_TO_STR(WINED3D_TOP_DOTPRODUCT3);
+ D3DTOP_TO_STR(WINED3D_TOP_MULTIPLY_ADD);
+ D3DTOP_TO_STR(WINED3D_TOP_LERP);
+#undef D3DTOP_TO_STR
+ default:
+ FIXME("Unrecognized texture op %#x.\n", d3dtop);
+ return "unrecognized";
+ }
+}
+
+const char *debug_d3dtstype(enum wined3d_transform_state tstype)
+{
+ switch (tstype)
+ {
+#define TSTYPE_TO_STR(tstype) case tstype: return #tstype
+ TSTYPE_TO_STR(WINED3D_TS_VIEW);
+ TSTYPE_TO_STR(WINED3D_TS_PROJECTION);
+ TSTYPE_TO_STR(WINED3D_TS_TEXTURE0);
+ TSTYPE_TO_STR(WINED3D_TS_TEXTURE1);
+ TSTYPE_TO_STR(WINED3D_TS_TEXTURE2);
+ TSTYPE_TO_STR(WINED3D_TS_TEXTURE3);
+ TSTYPE_TO_STR(WINED3D_TS_TEXTURE4);
+ TSTYPE_TO_STR(WINED3D_TS_TEXTURE5);
+ TSTYPE_TO_STR(WINED3D_TS_TEXTURE6);
+ TSTYPE_TO_STR(WINED3D_TS_TEXTURE7);
+ TSTYPE_TO_STR(WINED3D_TS_WORLD_MATRIX(0));
+#undef TSTYPE_TO_STR
+ default:
+ if (tstype > 256 && tstype < 512)
+ {
+ FIXME("WINED3D_TS_WORLD_MATRIX(%u). 1..255 not currently supported.\n", tstype);
+ return ("WINED3D_TS_WORLD_MATRIX > 0");
+ }
+ FIXME("Unrecognized transform state %#x.\n", tstype);
+ return "unrecognized";
+ }
+}
+
+const char *debug_d3dstate(DWORD state)
+{
+ if (STATE_IS_RENDER(state))
+ return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
+ if (STATE_IS_TEXTURESTAGE(state))
+ {
+ DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
+ DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
+ return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
+ texture_stage, debug_d3dtexturestate(texture_state));
+ }
+ if (STATE_IS_SAMPLER(state))
+ return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
+ if (STATE_IS_PIXELSHADER(state))
+ return "STATE_PIXELSHADER";
+ if (STATE_IS_TRANSFORM(state))
+ return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
+ if (STATE_IS_STREAMSRC(state))
+ return "STATE_STREAMSRC";
+ if (STATE_IS_INDEXBUFFER(state))
+ return "STATE_INDEXBUFFER";
+ if (STATE_IS_VDECL(state))
+ return "STATE_VDECL";
+ if (STATE_IS_VSHADER(state))
+ return "STATE_VSHADER";
+ if (STATE_IS_GEOMETRY_SHADER(state))
+ return "STATE_GEOMETRY_SHADER";
+ if (STATE_IS_VIEWPORT(state))
+ return "STATE_VIEWPORT";
+ if (STATE_IS_VERTEXSHADERCONSTANT(state))
+ return "STATE_VERTEXSHADERCONSTANT";
+ if (STATE_IS_PIXELSHADERCONSTANT(state))
+ return "STATE_PIXELSHADERCONSTANT";
+ if (STATE_IS_LIGHT_TYPE(state))
+ return "STATE_LIGHT_TYPE";
+ if (STATE_IS_ACTIVELIGHT(state))
+ return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
+ if (STATE_IS_SCISSORRECT(state))
+ return "STATE_SCISSORRECT";
+ if (STATE_IS_CLIPPLANE(state))
+ return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
+ if (STATE_IS_MATERIAL(state))
+ return "STATE_MATERIAL";
+ if (STATE_IS_FRONTFACE(state))
+ return "STATE_FRONTFACE";
+ if (STATE_IS_POINTSPRITECOORDORIGIN(state))
+ return "STATE_POINTSPRITECOORDORIGIN";
+ if (STATE_IS_BASEVERTEXINDEX(state))
+ return "STATE_BASEVERTEXINDEX";
+ if (STATE_IS_FRAMEBUFFER(state))
+ return "STATE_FRAMEBUFFER";
+ if (STATE_IS_POINT_SIZE_ENABLE(state))
+ return "STATE_POINT_SIZE_ENABLE";
+
+ return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
+}
+
+const char *debug_d3dpool(enum wined3d_pool pool)
+{
+ switch (pool)
+ {
+#define POOL_TO_STR(p) case p: return #p
+ POOL_TO_STR(WINED3D_POOL_DEFAULT);
+ POOL_TO_STR(WINED3D_POOL_MANAGED);
+ POOL_TO_STR(WINED3D_POOL_SYSTEM_MEM);
+ POOL_TO_STR(WINED3D_POOL_SCRATCH);
+#undef POOL_TO_STR
+ default:
+ FIXME("Unrecognized pool %#x.\n", pool);
+ return "unrecognized";
+ }
+}
+
+const char *debug_fbostatus(GLenum status) {
+ switch(status) {
+#define FBOSTATUS_TO_STR(u) case u: return #u
+ FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
+ FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
+ FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
+ FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
+ FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
+ FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
+ FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
+ FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
+ FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
+ FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
+#undef FBOSTATUS_TO_STR
+ default:
+ FIXME("Unrecognied FBO status 0x%08x\n", status);
+ return "unrecognized";
+ }
+}
+
+const char *debug_glerror(GLenum error) {
+ switch(error) {
+#define GLERROR_TO_STR(u) case u: return #u
+ GLERROR_TO_STR(GL_NO_ERROR);
+ GLERROR_TO_STR(GL_INVALID_ENUM);
+ GLERROR_TO_STR(GL_INVALID_VALUE);
+ GLERROR_TO_STR(GL_INVALID_OPERATION);
+ GLERROR_TO_STR(GL_STACK_OVERFLOW);
+ GLERROR_TO_STR(GL_STACK_UNDERFLOW);
+ GLERROR_TO_STR(GL_OUT_OF_MEMORY);
+ GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
+#undef GLERROR_TO_STR
+ default:
+ FIXME("Unrecognied GL error 0x%08x\n", error);
+ return "unrecognized";
+ }
+}
+
+static const char *debug_fixup_channel_source(enum fixup_channel_source source)
+{
+ switch(source)
+ {
+#define WINED3D_TO_STR(x) case x: return #x
+ WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
+ WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
+ WINED3D_TO_STR(CHANNEL_SOURCE_X);
+ WINED3D_TO_STR(CHANNEL_SOURCE_Y);
+ WINED3D_TO_STR(CHANNEL_SOURCE_Z);
+ WINED3D_TO_STR(CHANNEL_SOURCE_W);
+ WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
+ WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
+#undef WINED3D_TO_STR
+ default:
+ FIXME("Unrecognized fixup_channel_source %#x\n", source);
+ return "unrecognized";
+ }
+}
+
+static const char *debug_complex_fixup(enum complex_fixup fixup)
+{
+ switch(fixup)
+ {
+#define WINED3D_TO_STR(x) case x: return #x
+ WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
+ WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
+ WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
+ WINED3D_TO_STR(COMPLEX_FIXUP_P8);
+#undef WINED3D_TO_STR
+ default:
+ FIXME("Unrecognized complex fixup %#x\n", fixup);
+ return "unrecognized";
+ }
+}
+
+void dump_color_fixup_desc(struct color_fixup_desc fixup)
+{
+ if (is_complex_fixup(fixup))
+ {
+ TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
+ return;
+ }
+
+ TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
+ TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
+ TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
+ TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
+}
+
+const char *debug_surflocation(DWORD flag) {
+ char buf[128];
+
+ buf[0] = 0;
+ if (flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM"); /* 17 */
+ if (flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE"); /* 19 */
+ if (flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE"); /* 18 */
+ if (flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX"); /* 18 */
+ if (flag & SFLAG_INRB_MULTISAMPLE) strcat(buf, " | SFLAG_INRB_MULTISAMPLE"); /* 25 */
+ if (flag & SFLAG_INRB_RESOLVED) strcat(buf, " | SFLAG_INRB_RESOLVED"); /* 22 */
+ return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
+}
+
+BOOL is_invalid_op(const struct wined3d_state *state, int stage,
+ enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
+{
+ if (op == WINED3D_TOP_DISABLE)
+ return FALSE;
+ if (state->textures[stage])
+ return FALSE;
+
+ if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
+ && op != WINED3D_TOP_SELECT_ARG2)
+ return TRUE;
+ if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
+ && op != WINED3D_TOP_SELECT_ARG1)
+ return TRUE;
+ if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
+ && (op == WINED3D_TOP_MULTIPLY_ADD || op == WINED3D_TOP_LERP))
+ return TRUE;
+
+ return FALSE;
+}
+
+/* Setup this textures matrix according to the texture flags. */
+/* Context activation is done by the caller (state handler). */
+void set_texture_matrix(const struct wined3d_gl_info *gl_info, const float *smat, DWORD flags,
+ BOOL calculatedCoords, BOOL transformed, enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
+{
+ float mat[16];
+
+ gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE);
+ checkGLcall("glMatrixMode(GL_TEXTURE)");
+
+ if (flags == WINED3D_TTFF_DISABLE || flags == WINED3D_TTFF_COUNT1 || transformed)
+ {
+ gl_info->gl_ops.gl.p_glLoadIdentity();
+ checkGLcall("glLoadIdentity()");
+ return;
+ }
+
+ if (flags == (WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED))
+ {
+ ERR("Invalid texture transform flags: WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED.\n");
+ return;
+ }
+
+ memcpy(mat, smat, 16 * sizeof(float));
+
+ if (flags & WINED3D_TTFF_PROJECTED)
+ {
+ if (!ffp_proj_control)
+ {
+ switch (flags & ~WINED3D_TTFF_PROJECTED)
+ {
+ case WINED3D_TTFF_COUNT2:
+ mat[ 3] = mat[ 1];
+ mat[ 7] = mat[ 5];
+ mat[11] = mat[ 9];
+ mat[15] = mat[13];
+ mat[ 1] = mat[ 5] = mat[ 9] = mat[13] = 0.0f;
+ break;
+ case WINED3D_TTFF_COUNT3:
+ mat[ 3] = mat[ 2];
+ mat[ 7] = mat[ 6];
+ mat[11] = mat[10];
+ mat[15] = mat[14];
+ mat[ 2] = mat[ 6] = mat[10] = mat[14] = 0.0f;
+ break;
+ }
+ }
+ } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
+ if(!calculatedCoords) {
+ switch(vtx_fmt)
+ {
+ case WINED3DFMT_R32_FLOAT:
+ /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
+ * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
+ * the input value to the transformation will be 0, so the matrix value is irrelevant
+ */
+ mat[12] = mat[4];
+ mat[13] = mat[5];
+ mat[14] = mat[6];
+ mat[15] = mat[7];
+ break;
+ case WINED3DFMT_R32G32_FLOAT:
+ /* See above, just 3rd and 4th coord
+ */
+ mat[12] = mat[8];
+ mat[13] = mat[9];
+ mat[14] = mat[10];
+ mat[15] = mat[11];
+ break;
+ case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
+ case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
+
+ /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
+ * into a bad place. The division elimination below will apply to make sure the
+ * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
+ */
+ case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
+ break;
+ default:
+ FIXME("Unexpected fixed function texture coord input\n");
+ }
+ }
+ if (!ffp_proj_control)
+ {
+ switch (flags & ~WINED3D_TTFF_PROJECTED)
+ {
+ /* case WINED3D_TTFF_COUNT1: Won't ever get here. */
+ case WINED3D_TTFF_COUNT2:
+ mat[2] = mat[6] = mat[10] = mat[14] = 0;
+ /* OpenGL divides the first 3 vertex coord by the 4th by default,
+ * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
+ * the 4th coord evaluates to 1.0 to eliminate that.
+ *
+ * If the fixed function pipeline is used, the 4th value remains unused,
+ * so there is no danger in doing this. With vertex shaders we have a
+ * problem. Should an app hit that problem, the code here would have to
+ * check for pixel shaders, and the shader has to undo the default gl divide.
+ *
+ * A more serious problem occurs if the app passes 4 coordinates in, and the
+ * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
+ * or a replacement shader. */
+ default:
+ mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
+ }
+ }
+ }
+
+ gl_info->gl_ops.gl.p_glLoadMatrixf(mat);
+ checkGLcall("glLoadMatrixf(mat)");
+}
+
+/* This small helper function is used to convert a bitmask into the number of masked bits */
+unsigned int count_bits(unsigned int mask)
+{
+ unsigned int count;
+ for (count = 0; mask; ++count)
+ {
+ mask &= mask - 1;
+ }
+ return count;
+}
+
+/* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
+ * The later function requires individual color components. */
+BOOL getColorBits(const struct wined3d_format *format,
+ BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize)
+{
+ TRACE("format %s.\n", debug_d3dformat(format->id));
+
+ switch (format->id)
+ {
+ case WINED3DFMT_B10G10R10A2_UNORM:
+ case WINED3DFMT_R10G10B10A2_UNORM:
+ case WINED3DFMT_B8G8R8X8_UNORM:
+ case WINED3DFMT_B8G8R8_UNORM:
+ case WINED3DFMT_B8G8R8A8_UNORM:
+ case WINED3DFMT_R8G8B8A8_UNORM:
+ case WINED3DFMT_B5G5R5X1_UNORM:
+ case WINED3DFMT_B5G5R5A1_UNORM:
+ case WINED3DFMT_B5G6R5_UNORM:
+ case WINED3DFMT_B4G4R4X4_UNORM:
+ case WINED3DFMT_B4G4R4A4_UNORM:
+ case WINED3DFMT_B2G3R3_UNORM:
+ case WINED3DFMT_P8_UINT_A8_UNORM:
+ case WINED3DFMT_P8_UINT:
+ break;
+ default:
+ FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
+ return FALSE;
+ }
+
+ *redSize = format->red_size;
+ *greenSize = format->green_size;
+ *blueSize = format->blue_size;
+ *alphaSize = format->alpha_size;
+ *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
+
+ TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
+ *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
+ return TRUE;
+}
+
+/* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
+BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize)
+{
+ TRACE("format %s.\n", debug_d3dformat(format->id));
+
+ switch (format->id)
+ {
+ case WINED3DFMT_D16_LOCKABLE:
+ case WINED3DFMT_D16_UNORM:
+ case WINED3DFMT_S1_UINT_D15_UNORM:
+ case WINED3DFMT_X8D24_UNORM:
+ case WINED3DFMT_S4X4_UINT_D24_UNORM:
+ case WINED3DFMT_D24_UNORM_S8_UINT:
+ case WINED3DFMT_S8_UINT_D24_FLOAT:
+ case WINED3DFMT_D32_UNORM:
+ case WINED3DFMT_D32_FLOAT:
+ case WINED3DFMT_INTZ:
+ break;
+ default:
+ FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
+ return FALSE;
+ }
+
+ *depthSize = format->depth_size;
+ *stencilSize = format->stencil_size;
+
+ TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
+ *depthSize, *stencilSize, debug_d3dformat(format->id));
+ return TRUE;
+}
+
+/* Note: It's the caller's responsibility to ensure values can be expressed
+ * in the requested format. UNORM formats for example can only express values
+ * in the range 0.0f -> 1.0f. */
+DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, const struct wined3d_color *color)
+{
+ static const struct
+ {
+ enum wined3d_format_id format_id;
+ float r_mul;
+ float g_mul;
+ float b_mul;
+ float a_mul;
+ BYTE r_shift;
+ BYTE g_shift;
+ BYTE b_shift;
+ BYTE a_shift;
+ }
+ conv[] =
+ {
+ {WINED3DFMT_B8G8R8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
+ {WINED3DFMT_B8G8R8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
+ {WINED3DFMT_B8G8R8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 16, 8, 0, 24},
+ {WINED3DFMT_B5G6R5_UNORM, 31.0f, 63.0f, 31.0f, 0.0f, 11, 5, 0, 0},
+ {WINED3DFMT_B5G5R5A1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
+ {WINED3DFMT_B5G5R5X1_UNORM, 31.0f, 31.0f, 31.0f, 1.0f, 10, 5, 0, 15},
+ {WINED3DFMT_A8_UNORM, 0.0f, 0.0f, 0.0f, 255.0f, 0, 0, 0, 0},
+ {WINED3DFMT_B4G4R4A4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
+ {WINED3DFMT_B4G4R4X4_UNORM, 15.0f, 15.0f, 15.0f, 15.0f, 8, 4, 0, 12},
+ {WINED3DFMT_B2G3R3_UNORM, 7.0f, 7.0f, 3.0f, 0.0f, 5, 2, 0, 0},
+ {WINED3DFMT_R8G8B8A8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
+ {WINED3DFMT_R8G8B8X8_UNORM, 255.0f, 255.0f, 255.0f, 255.0f, 0, 8, 16, 24},
+ {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 20, 10, 0, 30},
+ {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f, 3.0f, 0, 10, 20, 30},
+ };
+ const struct wined3d_format *format = surface->resource.format;
+ unsigned int i;
+
+ TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
+ color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
+
+ for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
+ {
+ DWORD ret;
+
+ if (format->id != conv[i].format_id) continue;
+
+ ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
+ ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
+ ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
+ ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
+
+ TRACE("Returning 0x%08x.\n", ret);
+
+ return ret;
+ }
+
+ if (format->id == WINED3DFMT_P8_UINT)
+ {
+ PALETTEENTRY *e;
+ BYTE r, g, b, a;
+
+ if (!surface->palette)
+ {
+ WARN("Surface doesn't have a palette, returning 0.\n");
+ return 0;
+ }
+
+ r = (BYTE)((color->r * 255.0f) + 0.5f);
+ g = (BYTE)((color->g * 255.0f) + 0.5f);
+ b = (BYTE)((color->b * 255.0f) + 0.5f);
+ a = (BYTE)((color->a * 255.0f) + 0.5f);
+
+ e = &surface->palette->palents[a];
+ if (e->peRed == r && e->peGreen == g && e->peBlue == b)
+ return a;
+
+ WARN("Alpha didn't match index, searching full palette.\n");
+
+ for (i = 0; i < 256; ++i)
+ {
+ e = &surface->palette->palents[i];
+ if (e->peRed == r && e->peGreen == g && e->peBlue == b)
+ return i;
+ }
+
+ FIXME("Unable to convert color to palette index.\n");
+
+ return 0;
+ }
+
+ FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
+
+ return 0;
+}
+
+/* DirectDraw stuff */
+enum wined3d_format_id pixelformat_for_depth(DWORD depth)
+{
+ switch (depth)
+ {
+ case 8: return WINED3DFMT_P8_UINT;
+ case 15: return WINED3DFMT_B5G5R5X1_UNORM;
+ case 16: return WINED3DFMT_B5G6R5_UNORM;
+ case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
+ case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
+ default: return WINED3DFMT_UNKNOWN;
+ }
+}
+
+void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1,
+ const struct wined3d_matrix *src2)
+{
+ struct wined3d_matrix temp;
+
+ /* Now do the multiplication 'by hand'.
+ I know that all this could be optimised, but this will be done later :-) */
+ temp.u.s._11 = (src1->u.s._11 * src2->u.s._11) + (src1->u.s._21 * src2->u.s._12) + (src1->u.s._31 * src2->u.s._13) + (src1->u.s._41 * src2->u.s._14);
+ temp.u.s._21 = (src1->u.s._11 * src2->u.s._21) + (src1->u.s._21 * src2->u.s._22) + (src1->u.s._31 * src2->u.s._23) + (src1->u.s._41 * src2->u.s._24);
+ temp.u.s._31 = (src1->u.s._11 * src2->u.s._31) + (src1->u.s._21 * src2->u.s._32) + (src1->u.s._31 * src2->u.s._33) + (src1->u.s._41 * src2->u.s._34);
+ temp.u.s._41 = (src1->u.s._11 * src2->u.s._41) + (src1->u.s._21 * src2->u.s._42) + (src1->u.s._31 * src2->u.s._43) + (src1->u.s._41 * src2->u.s._44);
+
+ temp.u.s._12 = (src1->u.s._12 * src2->u.s._11) + (src1->u.s._22 * src2->u.s._12) + (src1->u.s._32 * src2->u.s._13) + (src1->u.s._42 * src2->u.s._14);
+ temp.u.s._22 = (src1->u.s._12 * src2->u.s._21) + (src1->u.s._22 * src2->u.s._22) + (src1->u.s._32 * src2->u.s._23) + (src1->u.s._42 * src2->u.s._24);
+ temp.u.s._32 = (src1->u.s._12 * src2->u.s._31) + (src1->u.s._22 * src2->u.s._32) + (src1->u.s._32 * src2->u.s._33) + (src1->u.s._42 * src2->u.s._34);
+ temp.u.s._42 = (src1->u.s._12 * src2->u.s._41) + (src1->u.s._22 * src2->u.s._42) + (src1->u.s._32 * src2->u.s._43) + (src1->u.s._42 * src2->u.s._44);
+
+ temp.u.s._13 = (src1->u.s._13 * src2->u.s._11) + (src1->u.s._23 * src2->u.s._12) + (src1->u.s._33 * src2->u.s._13) + (src1->u.s._43 * src2->u.s._14);
+ temp.u.s._23 = (src1->u.s._13 * src2->u.s._21) + (src1->u.s._23 * src2->u.s._22) + (src1->u.s._33 * src2->u.s._23) + (src1->u.s._43 * src2->u.s._24);
+ temp.u.s._33 = (src1->u.s._13 * src2->u.s._31) + (src1->u.s._23 * src2->u.s._32) + (src1->u.s._33 * src2->u.s._33) + (src1->u.s._43 * src2->u.s._34);
+ temp.u.s._43 = (src1->u.s._13 * src2->u.s._41) + (src1->u.s._23 * src2->u.s._42) + (src1->u.s._33 * src2->u.s._43) + (src1->u.s._43 * src2->u.s._44);
+
+ temp.u.s._14 = (src1->u.s._14 * src2->u.s._11) + (src1->u.s._24 * src2->u.s._12) + (src1->u.s._34 * src2->u.s._13) + (src1->u.s._44 * src2->u.s._14);
+ temp.u.s._24 = (src1->u.s._14 * src2->u.s._21) + (src1->u.s._24 * src2->u.s._22) + (src1->u.s._34 * src2->u.s._23) + (src1->u.s._44 * src2->u.s._24);
+ temp.u.s._34 = (src1->u.s._14 * src2->u.s._31) + (src1->u.s._24 * src2->u.s._32) + (src1->u.s._34 * src2->u.s._33) + (src1->u.s._44 * src2->u.s._34);
+ temp.u.s._44 = (src1->u.s._14 * src2->u.s._41) + (src1->u.s._24 * src2->u.s._42) + (src1->u.s._34 * src2->u.s._43) + (src1->u.s._44 * src2->u.s._44);
+
+ /* And copy the new matrix in the good storage.. */
+ memcpy(dest, &temp, 16 * sizeof(float));
+}
+
+DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
+ DWORD size = 0;
+ int i;
+ int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
+
+ if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
+ if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
+ if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
+ if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
+ switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
+ case WINED3DFVF_XYZ: size += 3 * sizeof(float); break;
+ case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
+ case WINED3DFVF_XYZB1: size += 4 * sizeof(float); break;
+ case WINED3DFVF_XYZB2: size += 5 * sizeof(float); break;
+ case WINED3DFVF_XYZB3: size += 6 * sizeof(float); break;
+ case WINED3DFVF_XYZB4: size += 7 * sizeof(float); break;
+ case WINED3DFVF_XYZB5: size += 8 * sizeof(float); break;
+ case WINED3DFVF_XYZW: size += 4 * sizeof(float); break;
+ default: ERR("Unexpected position mask\n");
+ }
+ for (i = 0; i < numTextures; i++) {
+ size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
+ }
+
+ return size;
+}
+
+void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d_state *state,
+ struct ffp_frag_settings *settings, BOOL ignore_textype)
+{
+#define ARG1 0x01
+#define ARG2 0x02
+#define ARG0 0x04
+ static const unsigned char args[WINED3D_TOP_LERP + 1] =
+ {
+ /* undefined */ 0,
+ /* D3DTOP_DISABLE */ 0,
+ /* D3DTOP_SELECTARG1 */ ARG1,
+ /* D3DTOP_SELECTARG2 */ ARG2,
+ /* D3DTOP_MODULATE */ ARG1 | ARG2,
+ /* D3DTOP_MODULATE2X */ ARG1 | ARG2,
+ /* D3DTOP_MODULATE4X */ ARG1 | ARG2,
+ /* D3DTOP_ADD */ ARG1 | ARG2,
+ /* D3DTOP_ADDSIGNED */ ARG1 | ARG2,
+ /* D3DTOP_ADDSIGNED2X */ ARG1 | ARG2,
+ /* D3DTOP_SUBTRACT */ ARG1 | ARG2,
+ /* D3DTOP_ADDSMOOTH */ ARG1 | ARG2,
+ /* D3DTOP_BLENDDIFFUSEALPHA */ ARG1 | ARG2,
+ /* D3DTOP_BLENDTEXTUREALPHA */ ARG1 | ARG2,
+ /* D3DTOP_BLENDFACTORALPHA */ ARG1 | ARG2,
+ /* D3DTOP_BLENDTEXTUREALPHAPM */ ARG1 | ARG2,
+ /* D3DTOP_BLENDCURRENTALPHA */ ARG1 | ARG2,
+ /* D3DTOP_PREMODULATE */ ARG1 | ARG2,
+ /* D3DTOP_MODULATEALPHA_ADDCOLOR */ ARG1 | ARG2,
+ /* D3DTOP_MODULATECOLOR_ADDALPHA */ ARG1 | ARG2,
+ /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */ ARG1 | ARG2,
+ /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */ ARG1 | ARG2,
+ /* D3DTOP_BUMPENVMAP */ ARG1 | ARG2,
+ /* D3DTOP_BUMPENVMAPLUMINANCE */ ARG1 | ARG2,
+ /* D3DTOP_DOTPRODUCT3 */ ARG1 | ARG2,
+ /* D3DTOP_MULTIPLYADD */ ARG1 | ARG2 | ARG0,
+ /* D3DTOP_LERP */ ARG1 | ARG2 | ARG0
+ };
+ unsigned int i;
+ DWORD ttff;
+ DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
+ const struct wined3d_surface *rt = state->fb->render_targets[0];
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const struct wined3d_d3d_info *d3d_info = context->d3d_info;
+
+#ifdef VBOX_WITH_WINE_FIX_INITCLEAR
+ memset(settings, 0, sizeof(*settings));
+#endif
+
+ for (i = 0; i < d3d_info->limits.ffp_blend_stages; ++i)
+ {
+ const struct wined3d_texture *texture;
+
+ settings->op[i].padding = 0;
+ if (state->texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE)
+ {
+ settings->op[i].cop = WINED3D_TOP_DISABLE;
+ settings->op[i].aop = WINED3D_TOP_DISABLE;
+ settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
+ settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
+ settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
+ settings->op[i].dst = resultreg;
+ settings->op[i].tex_type = tex_1d;
+ settings->op[i].projected = proj_none;
+ i++;
+ break;
+ }
+
+ if ((texture = state->textures[i]))
+ {
+ settings->op[i].color_fixup = texture->resource.format->color_fixup;
+ if (ignore_textype)
+ {
+ settings->op[i].tex_type = tex_1d;
+ }
+ else
+ {
+ switch (texture->target)
+ {
+ case GL_TEXTURE_1D:
+ settings->op[i].tex_type = tex_1d;
+ break;
+ case GL_TEXTURE_2D:
+ settings->op[i].tex_type = tex_2d;
+ break;
+ case GL_TEXTURE_3D:
+ settings->op[i].tex_type = tex_3d;
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ settings->op[i].tex_type = tex_cube;
+ break;
+ case GL_TEXTURE_RECTANGLE_ARB:
+ settings->op[i].tex_type = tex_rect;
+ break;
+ }
+ }
+ } else {
+ settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
+ settings->op[i].tex_type = tex_1d;
+ }
+
+ cop = state->texture_states[i][WINED3D_TSS_COLOR_OP];
+ aop = state->texture_states[i][WINED3D_TSS_ALPHA_OP];
+
+ carg1 = (args[cop] & ARG1) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG1] : ARG_UNUSED;
+ carg2 = (args[cop] & ARG2) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG2] : ARG_UNUSED;
+ carg0 = (args[cop] & ARG0) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG0] : ARG_UNUSED;
+
+ if (is_invalid_op(state, i, cop, carg1, carg2, carg0))
+ {
+ carg0 = ARG_UNUSED;
+ carg2 = ARG_UNUSED;
+ carg1 = WINED3DTA_CURRENT;
+ cop = WINED3D_TOP_SELECT_ARG1;
+ }
+
+ if (cop == WINED3D_TOP_DOTPRODUCT3)
+ {
+ /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
+ * the color result to the alpha component of the destination
+ */
+ aop = cop;
+ aarg1 = carg1;
+ aarg2 = carg2;
+ aarg0 = carg0;
+ }
+ else
+ {
+ aarg1 = (args[aop] & ARG1) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] : ARG_UNUSED;
+ aarg2 = (args[aop] & ARG2) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] : ARG_UNUSED;
+ aarg0 = (args[aop] & ARG0) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] : ARG_UNUSED;
+ }
+
+ if (!i && state->textures[0] && state->render_states[WINED3D_RS_COLORKEYENABLE])
+ {
+ GLenum texture_dimensions;
+
+ texture = state->textures[0];
+ texture_dimensions = texture->target;
+
+ if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
+ {
+ struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
+
+ if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_size)
+ {
+ if (aop == WINED3D_TOP_DISABLE)
+ {
+ aarg1 = WINED3DTA_TEXTURE;
+ aop = WINED3D_TOP_SELECT_ARG1;
+ }
+ else if (aop == WINED3D_TOP_SELECT_ARG1 && aarg1 != WINED3DTA_TEXTURE)
+ {
+ if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
+ {
+ aarg2 = WINED3DTA_TEXTURE;
+ aop = WINED3D_TOP_MODULATE;
+ }
+ else aarg1 = WINED3DTA_TEXTURE;
+ }
+ else if (aop == WINED3D_TOP_SELECT_ARG2 && aarg2 != WINED3DTA_TEXTURE)
+ {
+ if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
+ {
+ aarg1 = WINED3DTA_TEXTURE;
+ aop = WINED3D_TOP_MODULATE;
+ }
+ else aarg2 = WINED3DTA_TEXTURE;
+ }
+ }
+ }
+ }
+
+ if (is_invalid_op(state, i, aop, aarg1, aarg2, aarg0))
+ {
+ aarg0 = ARG_UNUSED;
+ aarg2 = ARG_UNUSED;
+ aarg1 = WINED3DTA_CURRENT;
+ aop = WINED3D_TOP_SELECT_ARG1;
+ }
+
+ if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
+ || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
+ {
+ ttff = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS];
+ if (ttff == (WINED3D_TTFF_PROJECTED | WINED3D_TTFF_COUNT3))
+ settings->op[i].projected = proj_count3;
+ else if (ttff & WINED3D_TTFF_PROJECTED)
+ settings->op[i].projected = proj_count4;
+ else
+ settings->op[i].projected = proj_none;
+ }
+ else
+ {
+ settings->op[i].projected = proj_none;
+ }
+
+ settings->op[i].cop = cop;
+ settings->op[i].aop = aop;
+ settings->op[i].carg0 = carg0;
+ settings->op[i].carg1 = carg1;
+ settings->op[i].carg2 = carg2;
+ settings->op[i].aarg0 = aarg0;
+ settings->op[i].aarg1 = aarg1;
+ settings->op[i].aarg2 = aarg2;
+
+ if (state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP)
+ settings->op[i].dst = tempreg;
+ else
+ settings->op[i].dst = resultreg;
+ }
+
+ /* Clear unsupported stages */
+ for(; i < MAX_TEXTURES; i++) {
+ memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
+ }
+
+ if (!state->render_states[WINED3D_RS_FOGENABLE])
+ {
+ settings->fog = WINED3D_FFP_PS_FOG_OFF;
+ }
+ else if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
+ {
+ if (use_vs(state) || state->vertex_declaration->position_transformed)
+ {
+ settings->fog = WINED3D_FFP_PS_FOG_LINEAR;
+ }
+ else
+ {
+ switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
+ {
+ case WINED3D_FOG_NONE:
+ case WINED3D_FOG_LINEAR:
+ settings->fog = WINED3D_FFP_PS_FOG_LINEAR;
+ break;
+ case WINED3D_FOG_EXP:
+ settings->fog = WINED3D_FFP_PS_FOG_EXP;
+ break;
+ case WINED3D_FOG_EXP2:
+ settings->fog = WINED3D_FFP_PS_FOG_EXP2;
+ break;
+ }
+ }
+ }
+ else
+ {
+ switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
+ {
+ case WINED3D_FOG_LINEAR:
+ settings->fog = WINED3D_FFP_PS_FOG_LINEAR;
+ break;
+ case WINED3D_FOG_EXP:
+ settings->fog = WINED3D_FFP_PS_FOG_EXP;
+ break;
+ case WINED3D_FOG_EXP2:
+ settings->fog = WINED3D_FFP_PS_FOG_EXP2;
+ break;
+ }
+ }
+ if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB]
+ && state->render_states[WINED3D_RS_SRGBWRITEENABLE]
+ && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
+ {
+ settings->sRGB_write = 1;
+ } else {
+ settings->sRGB_write = 0;
+ }
+ if (d3d_info->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING]
+ || !state->render_states[WINED3D_RS_CLIPPLANEENABLE])
+ {
+ /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
+ * the fixed function vertex pipeline is used(which always supports clipplanes), or
+ * if no clipplane is enabled
+ */
+ settings->emul_clipplanes = 0;
+ } else {
+ settings->emul_clipplanes = 1;
+ }
+}
+
+const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
+ const struct ffp_frag_settings *settings)
+{
+ struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
+ return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
+}
+
+void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
+{
+ /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
+ * whereas desc points to an extended structure with implementation specific parts. */
+ if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
+ {
+ ERR("Failed to insert ffp frag shader.\n");
+ }
+}
+
+/* Activates the texture dimension according to the bound D3D texture. Does
+ * not care for the colorop or correct gl texture unit (when using nvrc).
+ * Requires the caller to activate the correct unit. */
+/* Context activation is done by the caller (state handler). */
+void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
+{
+ if (texture)
+ {
+ switch (texture->target)
+ {
+ case GL_TEXTURE_2D:
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
+ checkGLcall("glDisable(GL_TEXTURE_3D)");
+ if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+ checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
+ }
+ if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
+ checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
+ }
+ gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
+ checkGLcall("glEnable(GL_TEXTURE_2D)");
+ break;
+ case GL_TEXTURE_RECTANGLE_ARB:
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
+ checkGLcall("glDisable(GL_TEXTURE_2D)");
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
+ checkGLcall("glDisable(GL_TEXTURE_3D)");
+ if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+ checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
+ }
+ gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_RECTANGLE_ARB);
+ checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
+ break;
+ case GL_TEXTURE_3D:
+ if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+ checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
+ }
+ if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
+ checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
+ }
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
+ checkGLcall("glDisable(GL_TEXTURE_2D)");
+ gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_3D);
+ checkGLcall("glEnable(GL_TEXTURE_3D)");
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
+ checkGLcall("glDisable(GL_TEXTURE_2D)");
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
+ checkGLcall("glDisable(GL_TEXTURE_3D)");
+ if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
+ checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
+ }
+ gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_CUBE_MAP_ARB);
+ checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
+ break;
+ }
+ }
+ else
+ {
+ gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D);
+ checkGLcall("glEnable(GL_TEXTURE_2D)");
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
+ checkGLcall("glDisable(GL_TEXTURE_3D)");
+ if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+ checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
+ }
+ if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+ {
+ gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
+ checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
+ }
+ /* Binding textures is done by samplers. A dummy texture will be bound */
+ }
+}
+
+/* Context activation is done by the caller (state handler). */
+void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+ DWORD sampler = state_id - STATE_SAMPLER(0);
+ DWORD mapped_stage = context->swapchain->device->texUnitMap[sampler];
+
+ /* No need to enable / disable anything here for unused samplers. The
+ * tex_colorop handler takes care. Also no action is needed with pixel
+ * shaders, or if tex_colorop will take care of this business. */
+ if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures)
+ return;
+ if (sampler >= state->lowest_disabled_stage)
+ return;
+ if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)))
+ return;
+
+ texture_activate_dimensions(state->textures[sampler], context->gl_info);
+}
+
+void *wined3d_rb_alloc(size_t size)
+{
+ return HeapAlloc(GetProcessHeap(), 0, size);
+}
+
+void *wined3d_rb_realloc(void *ptr, size_t size)
+{
+ return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
+}
+
+void wined3d_rb_free(void *ptr)
+{
+ HeapFree(GetProcessHeap(), 0, ptr);
+}
+
+static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
+{
+ const struct ffp_frag_settings *ka = key;
+ const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
+
+ return memcmp(ka, kb, sizeof(*ka));
+}
+
+const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
+{
+ wined3d_rb_alloc,
+ wined3d_rb_realloc,
+ wined3d_rb_free,
+ ffp_frag_program_key_compare,
+};
+
+void wined3d_ffp_get_vs_settings(const struct wined3d_state *state, const struct wined3d_stream_info *si,
+ struct wined3d_ffp_vs_settings *settings)
+{
+ unsigned int coord_idx, i;
+
+ if (si->position_transformed)
+ {
+ memset(settings, 0, sizeof(*settings));
+
+ settings->transformed = 1;
+ settings->point_size = state->gl_primitive_type == GL_POINTS;
+ if (!state->render_states[WINED3D_RS_FOGENABLE])
+ settings->fog_mode = WINED3D_FFP_VS_FOG_OFF;
+ else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
+ settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH;
+ else
+ settings->fog_mode = WINED3D_FFP_VS_FOG_FOGCOORD;
+
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
+ if (coord_idx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coord_idx))))
+ settings->texcoords |= 1 << i;
+ settings->texgen[i] = (state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] >> WINED3D_FFP_TCI_SHIFT)
+ & WINED3D_FFP_TCI_MASK;
+ }
+ return;
+ }
+
+ settings->transformed = 0;
+ settings->clipping = state->render_states[WINED3D_RS_CLIPPING]
+ && state->render_states[WINED3D_RS_CLIPPLANEENABLE];
+ settings->normal = !!(si->use_map & (1 << WINED3D_FFP_NORMAL));
+ settings->normalize = settings->normal && state->render_states[WINED3D_RS_NORMALIZENORMALS];
+ settings->lighting = !!state->render_states[WINED3D_RS_LIGHTING];
+ settings->localviewer = !!state->render_states[WINED3D_RS_LOCALVIEWER];
+ settings->point_size = state->gl_primitive_type == GL_POINTS;
+
+ if (state->render_states[WINED3D_RS_COLORVERTEX] && (si->use_map & (1 << WINED3D_FFP_DIFFUSE)))
+ {
+ settings->diffuse_source = state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE];
+ settings->emission_source = state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE];
+ settings->ambient_source = state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE];
+ settings->specular_source = state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE];
+ }
+ else
+ {
+ settings->diffuse_source = WINED3D_MCS_MATERIAL;
+ settings->emission_source = WINED3D_MCS_MATERIAL;
+ settings->ambient_source = WINED3D_MCS_MATERIAL;
+ settings->specular_source = WINED3D_MCS_MATERIAL;
+ }
+
+ settings->texcoords = 0;
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
+ if (coord_idx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coord_idx))))
+ settings->texcoords |= 1 << i;
+ settings->texgen[i] = (state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] >> WINED3D_FFP_TCI_SHIFT)
+ & WINED3D_FFP_TCI_MASK;
+ }
+
+ settings->light_type = 0;
+ for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i)
+ {
+ if (state->lights[i])
+ settings->light_type |= (state->lights[i]->OriginalParms.type
+ & WINED3D_FFP_LIGHT_TYPE_MASK) << WINED3D_FFP_LIGHT_TYPE_SHIFT(i);
+ }
+
+ if (!state->render_states[WINED3D_RS_FOGENABLE])
+ settings->fog_mode = WINED3D_FFP_VS_FOG_OFF;
+ else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
+ settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH;
+ else if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE)
+ settings->fog_mode = WINED3D_FFP_VS_FOG_FOGCOORD;
+ else if (state->render_states[WINED3D_RS_RANGEFOGENABLE])
+ settings->fog_mode = WINED3D_FFP_VS_FOG_RANGE;
+ else
+ settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH;
+
+ settings->padding = 0;
+}
+
+static int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb_entry *entry)
+{
+ const struct wined3d_ffp_vs_settings *ka = key;
+ const struct wined3d_ffp_vs_settings *kb = &WINE_RB_ENTRY_VALUE(entry,
+ const struct wined3d_ffp_vs_desc, entry)->settings;
+
+ return memcmp(ka, kb, sizeof(*ka));
+}
+
+const struct wine_rb_functions wined3d_ffp_vertex_program_rb_functions =
+{
+ wined3d_rb_alloc,
+ wined3d_rb_realloc,
+ wined3d_rb_free,
+ wined3d_ffp_vertex_program_key_compare,
+};
+
+UINT wined3d_log2i(UINT32 x)
+{
+ static const UINT l[] =
+ {
+ ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ };
+ UINT32 i;
+
+ return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
+}
+
+const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
+ const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
+ const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
+{
+ static const struct blit_shader * const blitters[] =
+ {
+ &arbfp_blit,
+ &ffp_blit,
+ &cpu_blit,
+ };
+ unsigned int i;
+
+ for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
+ {
+ if (blitters[i]->blit_supported(gl_info, blit_op,
+ src_rect, src_usage, src_pool, src_format,
+ dst_rect, dst_usage, dst_pool, dst_format))
+ return blitters[i];
+ }
+
+ return NULL;
+}
+
+void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect)
+{
+ const struct wined3d_viewport *vp = &state->viewport;
+
+ SetRect(rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height);
+
+ if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
+ IntersectRect(rect, rect, &state->scissor_rect);
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/vboxext.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/vboxext.c
new file mode 100644
index 00000000..df6cf217
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/vboxext.c
@@ -0,0 +1,860 @@
+/* $Id: vboxext.c $ */
+/** @file
+ *
+ * VBox extension to Wine D3D
+ *
+ * Copyright (C) 2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+#include "config.h"
+#include "wine/port.h"
+#include "wined3d_private.h"
+#include "vboxext.h"
+#ifdef VBOX_WITH_WDDM
+#include <VBox/VBoxCrHgsmi.h>
+#include <iprt/err.h>
+#endif
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_vbox);
+
+typedef DECLCALLBACK(void) FNVBOXEXTWORKERCB(void *pvUser);
+typedef FNVBOXEXTWORKERCB *PFNVBOXEXTWORKERCB;
+
+HRESULT VBoxExtDwSubmitProcSync(PFNVBOXEXTWORKERCB pfnCb, void *pvCb);
+HRESULT VBoxExtDwSubmitProcAsync(PFNVBOXEXTWORKERCB pfnCb, void *pvCb);
+
+/*******************************/
+#ifdef VBOX_WITH_WDDM
+# if defined(VBOX_WDDM_WOW64)
+# define VBOXEXT_WINE_MODULE_NAME "wined3dwddm-x86.dll"
+# else
+# define VBOXEXT_WINE_MODULE_NAME "wined3dwddm.dll"
+# endif
+#else
+/* both 32bit and 64bit versions of xpdm wine libs are named identically */
+# define VBOXEXT_WINE_MODULE_NAME "wined3d.dll"
+#endif
+
+typedef struct VBOXEXT_WORKER
+{
+ CRITICAL_SECTION CritSect;
+
+ HANDLE hEvent;
+
+ HANDLE hThread;
+ DWORD idThread;
+ /* wine does not seem to guarantie the dll is not unloaded in case FreeLibrary is used
+ * while d3d object is not terminated, keep an extra reference to ensure we're not unloaded
+ * while we are active */
+ HMODULE hSelf;
+} VBOXEXT_WORKER, *PVBOXEXT_WORKER;
+
+
+
+HRESULT VBoxExtWorkerCreate(PVBOXEXT_WORKER pWorker);
+HRESULT VBoxExtWorkerDestroy(PVBOXEXT_WORKER pWorker);
+HRESULT VBoxExtWorkerSubmitProc(PVBOXEXT_WORKER pWorker, PFNVBOXEXTWORKERCB pfnCb, void *pvCb);
+
+
+/*******************************/
+typedef struct VBOXEXT_GLOBAL
+{
+ VBOXEXT_WORKER Worker;
+} VBOXEXT_GLOBAL, *PVBOXEXT_GLOBAL;
+
+static VBOXEXT_GLOBAL g_VBoxExtGlobal;
+
+#define WM_VBOXEXT_CALLPROC (WM_APP+1)
+#define WM_VBOXEXT_INIT_QUIT (WM_APP+2)
+
+typedef struct VBOXEXT_CALLPROC
+{
+ PFNVBOXEXTWORKERCB pfnCb;
+ void *pvCb;
+} VBOXEXT_CALLPROC, *PVBOXEXT_CALLPROC;
+
+static DWORD WINAPI vboxExtWorkerThread(void *pvUser)
+{
+ PVBOXEXT_WORKER pWorker = (PVBOXEXT_WORKER)pvUser;
+ MSG Msg;
+
+ PeekMessage(&Msg,
+ NULL /* HWND hWnd */,
+ WM_USER /* UINT wMsgFilterMin */,
+ WM_USER /* UINT wMsgFilterMax */,
+ PM_NOREMOVE);
+ SetEvent(pWorker->hEvent);
+
+ do
+ {
+ BOOL bResult = GetMessage(&Msg,
+ 0 /*HWND hWnd*/,
+ 0 /*UINT wMsgFilterMin*/,
+ 0 /*UINT wMsgFilterMax*/
+ );
+
+ if(!bResult) /* WM_QUIT was posted */
+ break;
+
+ Assert(bResult != -1);
+ if(bResult == -1) /* error occurred */
+ break;
+
+ switch (Msg.message)
+ {
+ case WM_VBOXEXT_CALLPROC:
+ {
+ VBOXEXT_CALLPROC* pData = (VBOXEXT_CALLPROC*)Msg.lParam;
+ pData->pfnCb(pData->pvCb);
+ SetEvent(pWorker->hEvent);
+ break;
+ }
+ case WM_VBOXEXT_INIT_QUIT:
+ case WM_CLOSE:
+ {
+ PostQuitMessage(0);
+ break;
+ }
+ default:
+ TranslateMessage(&Msg);
+ DispatchMessage(&Msg);
+ }
+ } while (1);
+ return 0;
+}
+
+HRESULT VBoxExtWorkerCreate(PVBOXEXT_WORKER pWorker)
+{
+ if(!GetModuleHandleEx(0, VBOXEXT_WINE_MODULE_NAME, &pWorker->hSelf))
+ {
+ DWORD dwEr = GetLastError();
+ ERR("GetModuleHandleEx failed, %d", dwEr);
+ return E_FAIL;
+ }
+
+ InitializeCriticalSection(&pWorker->CritSect);
+ pWorker->hEvent = CreateEvent(NULL, /* LPSECURITY_ATTRIBUTES lpEventAttributes */
+ FALSE, /* BOOL bManualReset */
+ FALSE, /* BOOL bInitialState */
+ NULL /* LPCTSTR lpName */
+ );
+ if (pWorker->hEvent)
+ {
+ pWorker->hThread = CreateThread(
+ NULL /* LPSECURITY_ATTRIBUTES lpThreadAttributes */,
+ 0 /* SIZE_T dwStackSize */,
+ vboxExtWorkerThread,
+ pWorker,
+ 0 /* DWORD dwCreationFlags */,
+ &pWorker->idThread);
+ if (pWorker->hThread)
+ {
+ DWORD dwResult = WaitForSingleObject(pWorker->hEvent, INFINITE);
+ if (WAIT_OBJECT_0 == dwResult)
+ return S_OK;
+ ERR("WaitForSingleObject returned %d\n", dwResult);
+ }
+ else
+ {
+ DWORD winErr = GetLastError();
+ ERR("CreateThread failed, winErr = (%d)", winErr);
+ }
+
+ DeleteCriticalSection(&pWorker->CritSect);
+ }
+ else
+ {
+ DWORD winErr = GetLastError();
+ ERR("CreateEvent failed, winErr = (%d)", winErr);
+ }
+
+ FreeLibrary(pWorker->hSelf);
+
+ return E_FAIL;
+}
+
+HRESULT VBoxExtWorkerDestroy(PVBOXEXT_WORKER pWorker)
+{
+ BOOL bResult = PostThreadMessage(pWorker->idThread, WM_VBOXEXT_INIT_QUIT, 0, 0);
+ DWORD dwErr;
+ if (!bResult)
+ {
+ DWORD winErr = GetLastError();
+ ERR("PostThreadMessage failed, winErr = (%d)", winErr);
+ return E_FAIL;
+ }
+
+ dwErr = WaitForSingleObject(pWorker->hThread, INFINITE);
+ if (dwErr != WAIT_OBJECT_0)
+ {
+ ERR("WaitForSingleObject returned (%d)", dwErr);
+ return E_FAIL;
+ }
+
+ CloseHandle(pWorker->hEvent);
+ DeleteCriticalSection(&pWorker->CritSect);
+
+ FreeLibrary(pWorker->hSelf);
+
+ CloseHandle(pWorker->hThread);
+
+ return S_OK;
+}
+
+static HRESULT vboxExtWorkerSubmit(VBOXEXT_WORKER *pWorker, UINT Msg, LPARAM lParam, BOOL fSync)
+{
+ HRESULT hr = E_FAIL;
+ BOOL bResult;
+ /* need to serialize since vboxExtWorkerThread is using one pWorker->hEvent
+ * to signal job completion */
+ EnterCriticalSection(&pWorker->CritSect);
+ bResult = PostThreadMessage(pWorker->idThread, Msg, 0, lParam);
+ if (bResult)
+ {
+ if (fSync)
+ {
+ DWORD dwErr = WaitForSingleObject(pWorker->hEvent, INFINITE);
+ if (dwErr == WAIT_OBJECT_0)
+ {
+ hr = S_OK;
+ }
+ else
+ {
+ ERR("WaitForSingleObject returned (%d)", dwErr);
+ }
+ }
+ else
+ hr = S_OK;
+ }
+ else
+ {
+ DWORD winErr = GetLastError();
+ ERR("PostThreadMessage failed, winErr = (%d)", winErr);
+ return E_FAIL;
+ }
+ LeaveCriticalSection(&pWorker->CritSect);
+ return hr;
+}
+
+HRESULT VBoxExtWorkerSubmitProcSync(PVBOXEXT_WORKER pWorker, PFNVBOXEXTWORKERCB pfnCb, void *pvCb)
+{
+ VBOXEXT_CALLPROC Ctx;
+ Ctx.pfnCb = pfnCb;
+ Ctx.pvCb = pvCb;
+ return vboxExtWorkerSubmit(pWorker, WM_VBOXEXT_CALLPROC, (LPARAM)&Ctx, TRUE);
+}
+
+static DECLCALLBACK(void) vboxExtWorkerSubmitProcAsyncWorker(void *pvUser)
+{
+ PVBOXEXT_CALLPROC pCallInfo = (PVBOXEXT_CALLPROC)pvUser;
+ pCallInfo[1].pfnCb(pCallInfo[1].pvCb);
+ HeapFree(GetProcessHeap(), 0, pCallInfo);
+}
+
+HRESULT VBoxExtWorkerSubmitProcAsync(PVBOXEXT_WORKER pWorker, PFNVBOXEXTWORKERCB pfnCb, void *pvCb)
+{
+ HRESULT hr;
+ PVBOXEXT_CALLPROC pCallInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (VBOXEXT_CALLPROC) * 2);
+ if (!pCallInfo)
+ {
+ ERR("HeapAlloc failed\n");
+ return E_OUTOFMEMORY;
+ }
+ pCallInfo[0].pfnCb = vboxExtWorkerSubmitProcAsyncWorker;
+ pCallInfo[0].pvCb = pCallInfo;
+ pCallInfo[1].pfnCb = pfnCb;
+ pCallInfo[1].pvCb = pvCb;
+ hr = vboxExtWorkerSubmit(pWorker, WM_VBOXEXT_CALLPROC, (LPARAM)pCallInfo, FALSE);
+ if (FAILED(hr))
+ {
+ ERR("vboxExtWorkerSubmit failed, hr 0x%x\n", hr);
+ HeapFree(GetProcessHeap(), 0, pCallInfo);
+ return hr;
+ }
+ return S_OK;
+}
+
+
+static HRESULT vboxExtInit()
+{
+ HRESULT hr = S_OK;
+#ifdef VBOX_WITH_WDDM
+ int rc = VBoxCrHgsmiInit();
+ if (!RT_SUCCESS(rc))
+ {
+ ERR("VBoxCrHgsmiInit failed rc %d", rc);
+ return E_FAIL;
+ }
+#endif
+ memset(&g_VBoxExtGlobal, 0, sizeof (g_VBoxExtGlobal));
+ hr = VBoxExtWorkerCreate(&g_VBoxExtGlobal.Worker);
+ if (SUCCEEDED(hr))
+ return S_OK;
+
+ /* failure branch */
+#ifdef VBOX_WITH_WDDM
+ VBoxCrHgsmiTerm();
+#endif
+ return hr;
+}
+
+
+static HRESULT vboxExtWndCleanup();
+
+static HRESULT vboxExtTerm()
+{
+ HRESULT hr = vboxExtWndCleanup();
+ if (!SUCCEEDED(hr))
+ {
+ ERR("vboxExtWndCleanup failed, hr %d", hr);
+ return hr;
+ }
+
+ hr = VBoxExtWorkerDestroy(&g_VBoxExtGlobal.Worker);
+ if (!SUCCEEDED(hr))
+ {
+ ERR("VBoxExtWorkerDestroy failed, hr %d", hr);
+ return hr;
+ }
+
+#ifdef VBOX_WITH_WDDM
+ VBoxCrHgsmiTerm();
+#endif
+
+ return S_OK;
+}
+
+/* wine serializes all calls to us, so no need for any synchronization here */
+static DWORD g_cVBoxExtInits = 0;
+
+static DWORD vboxExtAddRef()
+{
+ return ++g_cVBoxExtInits;
+}
+
+static DWORD vboxExtRelease()
+{
+ DWORD cVBoxExtInits = --g_cVBoxExtInits;
+ Assert(cVBoxExtInits < UINT32_MAX/2);
+ return cVBoxExtInits;
+}
+
+static DWORD vboxExtGetRef()
+{
+ return g_cVBoxExtInits;
+}
+
+HRESULT VBoxExtCheckInit()
+{
+ HRESULT hr = S_OK;
+ if (!vboxExtGetRef())
+ {
+ hr = vboxExtInit();
+ if (FAILED(hr))
+ {
+ ERR("vboxExtInit failed, hr (0x%x)", hr);
+ return hr;
+ }
+ }
+ vboxExtAddRef();
+ return S_OK;
+}
+
+HRESULT VBoxExtCheckTerm()
+{
+ HRESULT hr = S_OK;
+ if (vboxExtGetRef() == 1)
+ {
+ hr = vboxExtTerm();
+ if (FAILED(hr))
+ {
+ ERR("vboxExtTerm failed, hr (0x%x)", hr);
+ return hr;
+ }
+ }
+ vboxExtRelease();
+ return S_OK;
+}
+
+HRESULT VBoxExtDwSubmitProcSync(PFNVBOXEXTWORKERCB pfnCb, void *pvCb)
+{
+ return VBoxExtWorkerSubmitProcSync(&g_VBoxExtGlobal.Worker, pfnCb, pvCb);
+}
+
+HRESULT VBoxExtDwSubmitProcAsync(PFNVBOXEXTWORKERCB pfnCb, void *pvCb)
+{
+ return VBoxExtWorkerSubmitProcAsync(&g_VBoxExtGlobal.Worker, pfnCb, pvCb);
+}
+
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+# ifndef VBOX_WITH_WDDM
+typedef struct VBOXEXT_GETDC_CB
+{
+ HWND hWnd;
+ HDC hDC;
+} VBOXEXT_GETDC_CB, *PVBOXEXT_GETDC_CB;
+
+static DECLCALLBACK(void) vboxExtGetDCWorker(void *pvUser)
+{
+ PVBOXEXT_GETDC_CB pData = (PVBOXEXT_GETDC_CB)pvUser;
+ pData->hDC = GetDC(pData->hWnd);
+}
+
+typedef struct VBOXEXT_RELEASEDC_CB
+{
+ HWND hWnd;
+ HDC hDC;
+ int ret;
+} VBOXEXT_RELEASEDC_CB, *PVBOXEXT_RELEASEDC_CB;
+
+static DECLCALLBACK(void) vboxExtReleaseDCWorker(void *pvUser)
+{
+ PVBOXEXT_RELEASEDC_CB pData = (PVBOXEXT_RELEASEDC_CB)pvUser;
+ pData->ret = ReleaseDC(pData->hWnd, pData->hDC);
+}
+
+HDC VBoxExtGetDC(HWND hWnd)
+{
+ HRESULT hr;
+ VBOXEXT_GETDC_CB Data = {0};
+ Data.hWnd = hWnd;
+ Data.hDC = NULL;
+
+ hr = VBoxExtDwSubmitProcSync(vboxExtGetDCWorker, &Data);
+ if (FAILED(hr))
+ {
+ ERR("VBoxExtDwSubmitProcSync feiled, hr (0x%x)\n", hr);
+ return NULL;
+ }
+
+ return Data.hDC;
+}
+
+int VBoxExtReleaseDC(HWND hWnd, HDC hDC)
+{
+ HRESULT hr;
+ VBOXEXT_RELEASEDC_CB Data = {0};
+ Data.hWnd = hWnd;
+ Data.hDC = hDC;
+ Data.ret = 0;
+
+ hr = VBoxExtDwSubmitProcSync(vboxExtReleaseDCWorker, &Data);
+ if (FAILED(hr))
+ {
+ ERR("VBoxExtDwSubmitProcSync feiled, hr (0x%x)\n", hr);
+ return -1;
+ }
+
+ return Data.ret;
+}
+# endif /* #ifndef VBOX_WITH_WDDM */
+
+static DECLCALLBACK(void) vboxExtReleaseContextWorker(void *pvUser)
+{
+ struct wined3d_context *context = (struct wined3d_context *)pvUser;
+ VBoxTlsRefRelease(context);
+}
+
+void VBoxExtReleaseContextAsync(struct wined3d_context *context)
+{
+ HRESULT hr;
+
+ hr = VBoxExtDwSubmitProcAsync(vboxExtReleaseContextWorker, context);
+ if (FAILED(hr))
+ {
+ ERR("VBoxExtDwSubmitProcAsync feiled, hr (0x%x)\n", hr);
+ return;
+ }
+}
+
+#endif /* #if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT) */
+
+/* window creation API */
+static LRESULT CALLBACK vboxExtWndProc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam
+)
+{
+ switch(uMsg)
+ {
+ case WM_CLOSE:
+ TRACE("got WM_CLOSE for hwnd(0x%x)", hwnd);
+ return 0;
+ case WM_DESTROY:
+ TRACE("got WM_DESTROY for hwnd(0x%x)", hwnd);
+ return 0;
+ case WM_NCHITTEST:
+ TRACE("got WM_NCHITTEST for hwnd(0x%x)\n", hwnd);
+ return HTNOWHERE;
+ }
+
+ return DefWindowProc(hwnd, uMsg, wParam, lParam);
+}
+
+#define VBOXEXTWND_NAME "VboxDispD3DWineWnd"
+
+static HRESULT vboxExtWndDoCleanup()
+{
+ HRESULT hr = S_OK;
+ HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
+ WNDCLASS wc;
+ if (GetClassInfo(hInstance, VBOXEXTWND_NAME, &wc))
+ {
+ if (!UnregisterClass(VBOXEXTWND_NAME, hInstance))
+ {
+ DWORD winEr = GetLastError();
+ ERR("UnregisterClass failed, winErr(%d)\n", winEr);
+ hr = E_FAIL;
+ }
+ }
+ return hr;
+}
+
+static HRESULT vboxExtWndDoCreate(DWORD w, DWORD h, HWND *phWnd, HDC *phDC)
+{
+ HRESULT hr = S_OK;
+ HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
+ /* Register the Window Class. */
+ WNDCLASS wc;
+ if (!GetClassInfo(hInstance, VBOXEXTWND_NAME, &wc))
+ {
+ wc.style = 0;//CS_OWNDC;
+ wc.lpfnWndProc = vboxExtWndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = hInstance;
+ wc.hIcon = NULL;
+ wc.hCursor = NULL;
+ wc.hbrBackground = NULL;
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = VBOXEXTWND_NAME;
+ if (!RegisterClass(&wc))
+ {
+ DWORD winErr = GetLastError();
+ ERR("RegisterClass failed, winErr(%d)\n", winErr);
+ hr = E_FAIL;
+ }
+ }
+
+ if (hr == S_OK)
+ {
+ HWND hWnd = CreateWindowEx (WS_EX_TOOLWINDOW,
+ VBOXEXTWND_NAME, VBOXEXTWND_NAME,
+ WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED,
+ 0, 0,
+ w, h,
+ NULL, //GetDesktopWindow() /* hWndParent */,
+ NULL /* hMenu */,
+ hInstance,
+ NULL /* lpParam */);
+ Assert(hWnd);
+ if (hWnd)
+ {
+ *phWnd = hWnd;
+ *phDC = GetDC(hWnd);
+ /* make sure we keep inited until the window is active */
+ vboxExtAddRef();
+ }
+ else
+ {
+ DWORD winErr = GetLastError();
+ ERR("CreateWindowEx failed, winErr(%d)\n", winErr);
+ hr = E_FAIL;
+ }
+ }
+
+ return hr;
+}
+
+static HRESULT vboxExtWndDoDestroy(HWND hWnd, HDC hDC)
+{
+ BOOL bResult;
+ DWORD winErr;
+ ReleaseDC(hWnd, hDC);
+ bResult = DestroyWindow(hWnd);
+ Assert(bResult);
+ if (bResult)
+ {
+ /* release the reference we previously acquired on window creation */
+ vboxExtRelease();
+ return S_OK;
+ }
+
+ winErr = GetLastError();
+ ERR("DestroyWindow failed, winErr(%d) for hWnd(0x%x)\n", winErr, hWnd);
+
+ return E_FAIL;
+}
+
+typedef struct VBOXEXTWND_CREATE_INFO
+{
+ int hr;
+ HWND hWnd;
+ HDC hDC;
+ DWORD width;
+ DWORD height;
+} VBOXEXTWND_CREATE_INFO;
+
+typedef struct VBOXEXTWND_DESTROY_INFO
+{
+ int hr;
+ HWND hWnd;
+ HDC hDC;
+} VBOXEXTWND_DESTROY_INFO;
+
+typedef struct VBOXEXTWND_CLEANUP_INFO
+{
+ int hr;
+} VBOXEXTWND_CLEANUP_INFO;
+
+static DECLCALLBACK(void) vboxExtWndDestroyWorker(void *pvUser)
+{
+ VBOXEXTWND_DESTROY_INFO *pInfo = (VBOXEXTWND_DESTROY_INFO*)pvUser;
+ pInfo->hr = vboxExtWndDoDestroy(pInfo->hWnd, pInfo->hDC);
+ Assert(pInfo->hr == S_OK);
+}
+
+static DECLCALLBACK(void) vboxExtWndCreateWorker(void *pvUser)
+{
+ VBOXEXTWND_CREATE_INFO *pInfo = (VBOXEXTWND_CREATE_INFO*)pvUser;
+ pInfo->hr = vboxExtWndDoCreate(pInfo->width, pInfo->height, &pInfo->hWnd, &pInfo->hDC);
+ Assert(pInfo->hr == S_OK);
+}
+
+static DECLCALLBACK(void) vboxExtWndCleanupWorker(void *pvUser)
+{
+ VBOXEXTWND_CLEANUP_INFO *pInfo = (VBOXEXTWND_CLEANUP_INFO*)pvUser;
+ pInfo-> hr = vboxExtWndDoCleanup();
+}
+
+HRESULT VBoxExtWndDestroy(HWND hWnd, HDC hDC)
+{
+ HRESULT hr;
+ VBOXEXTWND_DESTROY_INFO Info;
+ Info.hr = E_FAIL;
+ Info.hWnd = hWnd;
+ Info.hDC = hDC;
+ hr = VBoxExtDwSubmitProcSync(vboxExtWndDestroyWorker, &Info);
+ if (!SUCCEEDED(hr))
+ {
+ ERR("VBoxExtDwSubmitProcSync-vboxExtWndDestroyWorker failed hr %d", hr);
+ return hr;
+ }
+
+ if (!SUCCEEDED(Info.hr))
+ {
+ ERR("vboxExtWndDestroyWorker failed hr %d", Info.hr);
+ return Info.hr;
+ }
+
+ return S_OK;
+}
+
+HRESULT VBoxExtWndCreate(DWORD width, DWORD height, HWND *phWnd, HDC *phDC)
+{
+ HRESULT hr;
+ VBOXEXTWND_CREATE_INFO Info;
+ Info.hr = E_FAIL;
+ Info.width = width;
+ Info.height = height;
+ hr = VBoxExtDwSubmitProcSync(vboxExtWndCreateWorker, &Info);
+ if (!SUCCEEDED(hr))
+ {
+ ERR("VBoxExtDwSubmitProcSync-vboxExtWndCreateWorker failed hr %d", hr);
+ return hr;
+ }
+
+ Assert(Info.hr == S_OK);
+ if (!SUCCEEDED(Info.hr))
+ {
+ ERR("vboxExtWndCreateWorker failed hr %d", Info.hr);
+ return Info.hr;
+ }
+
+ *phWnd = Info.hWnd;
+ *phDC = Info.hDC;
+ return S_OK;
+}
+
+static HRESULT vboxExtWndCleanup()
+{
+ HRESULT hr;
+ VBOXEXTWND_CLEANUP_INFO Info;
+ Info.hr = E_FAIL;
+ hr = VBoxExtDwSubmitProcSync(vboxExtWndCleanupWorker, &Info);
+ if (!SUCCEEDED(hr))
+ {
+ ERR("VBoxExtDwSubmitProcSync-vboxExtWndCleanupWorker failed hr %d", hr);
+ return hr;
+ }
+
+ if (!SUCCEEDED(Info.hr))
+ {
+ ERR("vboxExtWndCleanupWorker failed hr %d", Info.hr);
+ return Info.hr;
+ }
+
+ return S_OK;
+}
+
+
+/* hash map impl */
+static void vboxExtHashInitEntries(PVBOXEXT_HASHMAP pMap)
+{
+ uint32_t i;
+ pMap->cEntries = 0;
+ for (i = 0; i < RT_ELEMENTS(pMap->aBuckets); ++i)
+ {
+ RTListInit(&pMap->aBuckets[i].EntryList);
+ }
+}
+
+void VBoxExtHashInit(PVBOXEXT_HASHMAP pMap, PFNVBOXEXT_HASHMAP_HASH pfnHash, PFNVBOXEXT_HASHMAP_EQUAL pfnEqual)
+{
+ pMap->pfnHash = pfnHash;
+ pMap->pfnEqual = pfnEqual;
+ vboxExtHashInitEntries(pMap);
+}
+
+static DECLINLINE(uint32_t) vboxExtHashIdx(uint32_t u32Hash)
+{
+ return u32Hash % VBOXEXT_HASHMAP_NUM_BUCKETS;
+}
+
+#define VBOXEXT_FOREACH_NODE(_pNode, _pList, _op) do { \
+ PRTLISTNODE _pNode; \
+ PRTLISTNODE __pNext; \
+ for (_pNode = (_pList)->pNext; \
+ _pNode != (_pList); \
+ _pNode = __pNext) \
+ { \
+ __pNext = _pNode->pNext; /* <- the _pNode should not be referenced after the _op */ \
+ _op \
+ } \
+ } while (0)
+
+DECLINLINE(PVBOXEXT_HASHMAP_ENTRY) vboxExtHashSearchEntry(PVBOXEXT_HASHMAP pMap, void *pvKey)
+{
+ uint32_t u32Hash = pMap->pfnHash(pvKey);
+ uint32_t u32HashIdx = vboxExtHashIdx(u32Hash);
+ PVBOXEXT_HASHMAP_BUCKET pBucket = &pMap->aBuckets[u32HashIdx];
+ PVBOXEXT_HASHMAP_ENTRY pEntry;
+ VBOXEXT_FOREACH_NODE(pNode, &pBucket->EntryList,
+ pEntry = RT_FROM_MEMBER(pNode, VBOXEXT_HASHMAP_ENTRY, ListNode);
+ if (pEntry->u32Hash != u32Hash)
+ continue;
+
+ if (!pMap->pfnEqual(pvKey, pEntry->pvKey))
+ continue;
+ return pEntry;
+ );
+ return NULL;
+}
+
+void* VBoxExtHashRemoveEntry(PVBOXEXT_HASHMAP pMap, PVBOXEXT_HASHMAP_ENTRY pEntry)
+{
+ RTListNodeRemove(&pEntry->ListNode);
+ --pMap->cEntries;
+ Assert(pMap->cEntries <= UINT32_MAX/2);
+ return pEntry->pvKey;
+}
+
+static void vboxExtHashPutEntry(PVBOXEXT_HASHMAP pMap, PVBOXEXT_HASHMAP_BUCKET pBucket, PVBOXEXT_HASHMAP_ENTRY pEntry)
+{
+ RTListNodeInsertAfter(&pBucket->EntryList, &pEntry->ListNode);
+ ++pMap->cEntries;
+}
+
+PVBOXEXT_HASHMAP_ENTRY VBoxExtHashRemove(PVBOXEXT_HASHMAP pMap, void *pvKey)
+{
+ PVBOXEXT_HASHMAP_ENTRY pEntry = vboxExtHashSearchEntry(pMap, pvKey);
+ if (!pEntry)
+ return NULL;
+
+ VBoxExtHashRemoveEntry(pMap, pEntry);
+ return pEntry;
+}
+
+PVBOXEXT_HASHMAP_ENTRY VBoxExtHashPut(PVBOXEXT_HASHMAP pMap, void *pvKey, PVBOXEXT_HASHMAP_ENTRY pEntry)
+{
+ PVBOXEXT_HASHMAP_ENTRY pOldEntry = VBoxExtHashRemove(pMap, pvKey);
+ uint32_t u32Hash = pMap->pfnHash(pvKey);
+ uint32_t u32HashIdx = vboxExtHashIdx(u32Hash);
+ pEntry->pvKey = pvKey;
+ pEntry->u32Hash = u32Hash;
+ vboxExtHashPutEntry(pMap, &pMap->aBuckets[u32HashIdx], pEntry);
+ return pOldEntry;
+}
+
+
+PVBOXEXT_HASHMAP_ENTRY VBoxExtHashGet(PVBOXEXT_HASHMAP pMap, void *pvKey)
+{
+ return vboxExtHashSearchEntry(pMap, pvKey);
+}
+
+void VBoxExtHashVisit(PVBOXEXT_HASHMAP pMap, PFNVBOXEXT_HASHMAP_VISITOR pfnVisitor, void *pvVisitor)
+{
+ uint32_t iBucket = 0, iEntry = 0;
+ uint32_t cEntries = pMap->cEntries;
+
+ if (!cEntries)
+ return;
+
+ for (; ; ++iBucket)
+ {
+ PVBOXEXT_HASHMAP_ENTRY pEntry;
+ PVBOXEXT_HASHMAP_BUCKET pBucket = &pMap->aBuckets[iBucket];
+ Assert(iBucket < RT_ELEMENTS(pMap->aBuckets));
+ VBOXEXT_FOREACH_NODE(pNode, &pBucket->EntryList,
+ pEntry = RT_FROM_MEMBER(pNode, VBOXEXT_HASHMAP_ENTRY, ListNode);
+ if (!pfnVisitor(pMap, pEntry->pvKey, pEntry, pvVisitor))
+ return;
+
+ if (++iEntry == cEntries)
+ return;
+ );
+ }
+
+ /* should not be here! */
+ AssertFailed();
+}
+
+void VBoxExtHashCleanup(PVBOXEXT_HASHMAP pMap, PFNVBOXEXT_HASHMAP_VISITOR pfnVisitor, void *pvVisitor)
+{
+ VBoxExtHashVisit(pMap, pfnVisitor, pvVisitor);
+ vboxExtHashInitEntries(pMap);
+}
+
+static DECLCALLBACK(bool) vboxExtCacheCleanupCb(struct VBOXEXT_HASHMAP *pMap, void *pvKey, struct VBOXEXT_HASHMAP_ENTRY *pValue, void *pvVisitor)
+{
+ PVBOXEXT_HASHCACHE pCache = VBOXEXT_HASHCACHE_FROM_MAP(pMap);
+ PVBOXEXT_HASHCACHE_ENTRY pCacheEntry = VBOXEXT_HASHCACHE_ENTRY_FROM_MAP(pValue);
+ pCache->pfnCleanupEntry(pvKey, pCacheEntry);
+ return TRUE;
+}
+
+void VBoxExtCacheCleanup(PVBOXEXT_HASHCACHE pCache)
+{
+ VBoxExtHashCleanup(&pCache->Map, vboxExtCacheCleanupCb, NULL);
+}
+
+#if defined(VBOXWINEDBG_SHADERS) || defined(VBOX_WINE_WITH_PROFILE)
+void vboxWDbgPrintF(char * szString, ...)
+{
+ char szBuffer[4096*2] = {0};
+ va_list pArgList;
+ va_start(pArgList, szString);
+ _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
+ va_end(pArgList);
+
+ OutputDebugStringA(szBuffer);
+}
+#endif
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/vboxext.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/vboxext.h
new file mode 100644
index 00000000..94da2edb
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/vboxext.h
@@ -0,0 +1,313 @@
+/* $Id: vboxext.h $ */
+/** @file
+ *
+ * VBox extension to Wine D3D
+ *
+ * Copyright (C) 2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+#ifndef ___VBOXEXT_H__
+#define ___VBOXEXT_H__
+
+#ifdef VBOX_WINE_WITHOUT_LIBWINE
+# include <windows.h>
+#endif
+
+#include <iprt/list.h>
+
+HRESULT VBoxExtCheckInit();
+HRESULT VBoxExtCheckTerm();
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+# ifndef VBOX_WITH_WDDM
+/* Windows destroys HDC created by a given thread when the thread is terminated
+ * this leads to a mess-up in Wine & Chromium code in some situations, e.g.
+ * D3D device is created in one thread, then the thread is terminated,
+ * then device is started to be used in another thread */
+HDC VBoxExtGetDC(HWND hWnd);
+int VBoxExtReleaseDC(HWND hWnd, HDC hDC);
+# endif
+/* We need to do a VBoxTlsRefRelease for the current thread context on thread exit to avoid memory leaking
+ * Calling VBoxTlsRefRelease may result in a call to context dtor callback, which is supposed to be run under wined3d lock.
+ * We can not acquire a wined3d lock in DllMain since this would result in a lock order violation, which may result in a deadlock.
+ * In other words, wined3d may internally call Win32 API functions which result in a DLL lock acquisition while holding wined3d lock.
+ * So lock order should always be "wined3d lock" -> "dll lock".
+ * To avoid possible deadlocks we make an asynchronous call to a worker thread to make a context release from there. */
+void VBoxExtReleaseContextAsync(struct wined3d_context *context);
+#endif
+
+/* API for creating & destroying windows */
+HRESULT VBoxExtWndDestroy(HWND hWnd, HDC hDC);
+HRESULT VBoxExtWndCreate(DWORD width, DWORD height, HWND *phWnd, HDC *phDC);
+
+
+/* hashmap */
+typedef DECLCALLBACK(uint32_t) FNVBOXEXT_HASHMAP_HASH(void *pvKey);
+typedef FNVBOXEXT_HASHMAP_HASH *PFNVBOXEXT_HASHMAP_HASH;
+
+typedef DECLCALLBACK(bool) FNVBOXEXT_HASHMAP_EQUAL(void *pvKey1, void *pvKey2);
+typedef FNVBOXEXT_HASHMAP_EQUAL *PFNVBOXEXT_HASHMAP_EQUAL;
+
+typedef DECLCALLBACK(bool) FNVBOXEXT_HASHMAP_VISITOR(struct VBOXEXT_HASHMAP *pMap, void *pvKey, struct VBOXEXT_HASHMAP_ENTRY *pValue, void *pvVisitor);
+typedef FNVBOXEXT_HASHMAP_VISITOR *PFNVBOXEXT_HASHMAP_VISITOR;
+
+typedef struct VBOXEXT_HASHMAP_ENTRY
+{
+ RTLISTNODE ListNode;
+ void *pvKey;
+ uint32_t u32Hash;
+} VBOXEXT_HASHMAP_ENTRY, *PVBOXEXT_HASHMAP_ENTRY;
+
+typedef struct VBOXEXT_HASHMAP_BUCKET
+{
+ RTLISTNODE EntryList;
+} VBOXEXT_HASHMAP_BUCKET, *PVBOXEXT_HASHMAP_BUCKET;
+
+#define VBOXEXT_HASHMAP_NUM_BUCKETS 29
+
+typedef struct VBOXEXT_HASHMAP
+{
+ PFNVBOXEXT_HASHMAP_HASH pfnHash;
+ PFNVBOXEXT_HASHMAP_EQUAL pfnEqual;
+ uint32_t cEntries;
+ VBOXEXT_HASHMAP_BUCKET aBuckets[VBOXEXT_HASHMAP_NUM_BUCKETS];
+} VBOXEXT_HASHMAP, *PVBOXEXT_HASHMAP;
+
+void VBoxExtHashInit(PVBOXEXT_HASHMAP pMap, PFNVBOXEXT_HASHMAP_HASH pfnHash, PFNVBOXEXT_HASHMAP_EQUAL pfnEqual);
+PVBOXEXT_HASHMAP_ENTRY VBoxExtHashPut(PVBOXEXT_HASHMAP pMap, void *pvKey, PVBOXEXT_HASHMAP_ENTRY pEntry);
+PVBOXEXT_HASHMAP_ENTRY VBoxExtHashGet(PVBOXEXT_HASHMAP pMap, void *pvKey);
+PVBOXEXT_HASHMAP_ENTRY VBoxExtHashRemove(PVBOXEXT_HASHMAP pMap, void *pvKey);
+void* VBoxExtHashRemoveEntry(PVBOXEXT_HASHMAP pMap, PVBOXEXT_HASHMAP_ENTRY pEntry);
+void VBoxExtHashVisit(PVBOXEXT_HASHMAP pMap, PFNVBOXEXT_HASHMAP_VISITOR pfnVisitor, void *pvVisitor);
+void VBoxExtHashCleanup(PVBOXEXT_HASHMAP pMap, PFNVBOXEXT_HASHMAP_VISITOR pfnVisitor, void *pvVisitor);
+
+DECLINLINE(uint32_t) VBoxExtHashSize(PVBOXEXT_HASHMAP pMap)
+{
+ return pMap->cEntries;
+}
+
+DECLINLINE(void*) VBoxExtHashEntryKey(PVBOXEXT_HASHMAP_ENTRY pEntry)
+{
+ return pEntry->pvKey;
+}
+
+typedef DECLCALLBACK(void) FNVBOXEXT_HASHCACHE_CLEANUP_ENTRY(void *pvKey, struct VBOXEXT_HASHCACHE_ENTRY *pEntry);
+typedef FNVBOXEXT_HASHCACHE_CLEANUP_ENTRY *PFNVBOXEXT_HASHCACHE_CLEANUP_ENTRY;
+
+typedef struct VBOXEXT_HASHCACHE_ENTRY
+{
+ VBOXEXT_HASHMAP_ENTRY MapEntry;
+ uint32_t u32Usage;
+} VBOXEXT_HASHCACHE_ENTRY, *PVBOXEXT_HASHCACHE_ENTRY;
+
+typedef struct VBOXEXT_HASHCACHE
+{
+ VBOXEXT_HASHMAP Map;
+ uint32_t cMaxElements;
+ PFNVBOXEXT_HASHCACHE_CLEANUP_ENTRY pfnCleanupEntry;
+} VBOXEXT_HASHCACHE, *PVBOXEXT_HASHCACHE;
+
+#define VBOXEXT_HASHCACHE_FROM_MAP(_pMap) RT_FROM_MEMBER((_pMap), VBOXEXT_HASHCACHE, Map)
+#define VBOXEXT_HASHCACHE_ENTRY_FROM_MAP(_pEntry) RT_FROM_MEMBER((_pEntry), VBOXEXT_HASHCACHE_ENTRY, MapEntry)
+
+DECLINLINE(void) VBoxExtCacheInit(PVBOXEXT_HASHCACHE pCache, uint32_t cMaxElements,
+ PFNVBOXEXT_HASHMAP_HASH pfnHash,
+ PFNVBOXEXT_HASHMAP_EQUAL pfnEqual,
+ PFNVBOXEXT_HASHCACHE_CLEANUP_ENTRY pfnCleanupEntry)
+{
+ VBoxExtHashInit(&pCache->Map, pfnHash, pfnEqual);
+ pCache->cMaxElements = cMaxElements;
+ pCache->pfnCleanupEntry = pfnCleanupEntry;
+}
+
+DECLINLINE(PVBOXEXT_HASHCACHE_ENTRY) VBoxExtCacheGet(PVBOXEXT_HASHCACHE pCache, void *pvKey)
+{
+ PVBOXEXT_HASHMAP_ENTRY pEntry = VBoxExtHashRemove(&pCache->Map, pvKey);
+ return VBOXEXT_HASHCACHE_ENTRY_FROM_MAP(pEntry);
+}
+
+DECLINLINE(void) VBoxExtCachePut(PVBOXEXT_HASHCACHE pCache, void *pvKey, PVBOXEXT_HASHCACHE_ENTRY pEntry)
+{
+ PVBOXEXT_HASHMAP_ENTRY pOldEntry = VBoxExtHashPut(&pCache->Map, pvKey, &pEntry->MapEntry);
+ PVBOXEXT_HASHCACHE_ENTRY pOld;
+ if (!pOldEntry)
+ return;
+ pOld = VBOXEXT_HASHCACHE_ENTRY_FROM_MAP(pOldEntry);
+ if (pOld != pEntry)
+ pCache->pfnCleanupEntry(pvKey, pOld);
+}
+
+void VBoxExtCacheCleanup(PVBOXEXT_HASHCACHE pCache);
+
+DECLINLINE(void) VBoxExtCacheTerm(PVBOXEXT_HASHCACHE pCache)
+{
+ VBoxExtCacheCleanup(pCache);
+}
+
+#ifdef VBOX_WINE_WITH_PROFILE
+
+#include <iprt/time.h>
+
+void vboxWDbgPrintF(char * szString, ...);
+
+#define VBOXWINEPROFILE_GET_TIME_NANO() RTTimeNanoTS()
+#define VBOXWINEPROFILE_GET_TIME_MILLI() RTTimeMilliTS()
+
+# define PRLOG(_m) do {\
+ vboxWDbgPrintF _m ; \
+ } while (0)
+
+typedef struct VBOXWINEPROFILE_ELEMENT
+{
+ uint64_t u64Time;
+ uint32_t cu32Calls;
+} VBOXWINEPROFILE_ELEMENT, *PVBOXWINEPROFILE_ELEMENT;
+
+typedef struct VBOXWINEPROFILE_HASHMAP_ELEMENT
+{
+ VBOXEXT_HASHMAP_ENTRY MapEntry;
+ VBOXWINEPROFILE_ELEMENT Data;
+} VBOXWINEPROFILE_HASHMAP_ELEMENT, *PVBOXWINEPROFILE_HASHMAP_ELEMENT;
+
+#define VBOXWINEPROFILE_HASHMAP_ELEMENT_FROMENTRY(_p) ((PVBOXWINEPROFILE_HASHMAP_ELEMENT)(((uint8_t*)(_p)) - RT_OFFSETOF(VBOXWINEPROFILE_HASHMAP_ELEMENT, MapEntry)))
+
+#define VBOXWINEPROFILE_ELEMENT_DUMP(_p, _pn) do { \
+ PRLOG(("%s: t(%u);c(%u)\n", \
+ (_pn), \
+ (uint32_t)((_p)->u64Time / 1000000), \
+ (_p)->cu32Calls \
+ )); \
+ } while (0)
+
+#define VBOXWINEPROFILE_ELEMENT_RESET(_p) do { \
+ memset(_p, 0, sizeof (*(_p))); \
+ } while (0)
+
+#define VBOXWINEPROFILE_ELEMENT_STEP(_p, _t) do { \
+ (_p)->u64Time += (_t); \
+ ++(_p)->cu32Calls; \
+ } while (0)
+
+#define VBOXWINEPROFILE_HASHMAP_ELEMENT_CREATE() ( (PVBOXWINEPROFILE_HASHMAP_ELEMENT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (VBOXWINEPROFILE_HASHMAP_ELEMENT)) )
+
+#define VBOXWINEPROFILE_HASHMAP_ELEMENT_TERM(_pe) do { \
+ HeapFree(GetProcessHeap(), 0, (_pe)); \
+ } while (0)
+
+DECLINLINE(PVBOXWINEPROFILE_HASHMAP_ELEMENT) vboxWineProfileHashMapElementGet(PVBOXEXT_HASHMAP pMap, void *pvKey)
+{
+ PVBOXEXT_HASHMAP_ENTRY pEntry = VBoxExtHashGet(pMap, pvKey);
+ if (pEntry)
+ {
+ return VBOXWINEPROFILE_HASHMAP_ELEMENT_FROMENTRY(pEntry);
+ }
+ else
+ {
+ PVBOXWINEPROFILE_HASHMAP_ELEMENT pElement = VBOXWINEPROFILE_HASHMAP_ELEMENT_CREATE();
+ Assert(pElement);
+ if (pElement)
+ VBoxExtHashPut(pMap, pvKey, &pElement->MapEntry);
+ return pElement;
+ }
+}
+
+#define VBOXWINEPROFILE_HASHMAP_ELEMENT_STEP(_pm, _pk, _t) do { \
+ PVBOXWINEPROFILE_HASHMAP_ELEMENT pElement = vboxWineProfileHashMapElementGet(_pm, _pk); \
+ VBOXWINEPROFILE_ELEMENT_STEP(&pElement->Data, _t); \
+ } while (0)
+
+static DECLCALLBACK(bool) vboxWineProfileElementResetCb(struct VBOXEXT_HASHMAP *pMap, void *pvKey, struct VBOXEXT_HASHMAP_ENTRY *pValue, void *pvVisitor)
+{
+ PVBOXWINEPROFILE_HASHMAP_ELEMENT pElement = VBOXWINEPROFILE_HASHMAP_ELEMENT_FROMENTRY(pValue);
+ VBOXWINEPROFILE_ELEMENT_RESET(&pElement->Data);
+ return true;
+}
+
+static DECLCALLBACK(bool) vboxWineProfileElementDumpCb(struct VBOXEXT_HASHMAP *pMap, void *pvKey, struct VBOXEXT_HASHMAP_ENTRY *pValue, void *pvVisitor)
+{
+ PVBOXWINEPROFILE_HASHMAP_ELEMENT pElement = VBOXWINEPROFILE_HASHMAP_ELEMENT_FROMENTRY(pValue);
+ char *pName = (char*)pvVisitor;
+ PRLOG(("%s[%d]:", pName, (uint32_t)pvKey));
+ VBOXWINEPROFILE_ELEMENT_DUMP(&pElement->Data, "");
+ return true;
+}
+
+
+#define VBOXWINEPROFILE_HASHMAP_RESET(_pm) do { \
+ VBoxExtHashVisit((_pm), vboxWineProfileElementResetCb, NULL); \
+ } while (0)
+
+#define VBOXWINEPROFILE_HASHMAP_DUMP(_pm, _pn) do { \
+ VBoxExtHashVisit((_pm), vboxWineProfileElementDumpCb, (_pn)); \
+ } while (0)
+
+static DECLCALLBACK(bool) vboxWineProfileElementCleanupCb(struct VBOXEXT_HASHMAP *pMap, void *pvKey, struct VBOXEXT_HASHMAP_ENTRY *pValue, void *pvVisitor)
+{
+ PVBOXWINEPROFILE_HASHMAP_ELEMENT pElement = VBOXWINEPROFILE_HASHMAP_ELEMENT_FROMENTRY(pValue);
+ VBOXWINEPROFILE_HASHMAP_ELEMENT_TERM(pElement);
+ return true;
+}
+
+#define VBOXWINEPROFILE_HASHMAP_TERM(_pm) do { \
+ VBoxExtHashCleanup((_pm), vboxWineProfileElementCleanupCb, NULL); \
+ VBoxExtHashVisit((_pm), vboxWineProfileElementResetCb, NULL); \
+ } while (0)
+
+typedef struct VBOXWINEPROFILE_DRAWPRIM
+{
+ uint64_t u64LoadLocationTime;
+ uint64_t u64CtxAcquireTime;
+ uint64_t u64PostProcess;
+ VBOXEXT_HASHMAP MapDrawPrimSlowVs;
+ VBOXEXT_HASHMAP MapDrawPrimSlow;
+ VBOXEXT_HASHMAP MapDrawPrimStrided;
+ VBOXEXT_HASHMAP MapDrawPrimFast;
+ uint32_t cu32Calls;
+} VBOXWINEPROFILE_DRAWPRIM, *PVBOXWINEPROFILE_DRAWPRIM;
+
+#define VBOXWINEPROFILE_DRAWPRIM_RESET_NEXT(_p) do { \
+ (_p)->u64LoadLocationTime = 0; \
+ (_p)->u64CtxAcquireTime = 0; \
+ (_p)->u64PostProcess = 0; \
+ VBOXWINEPROFILE_HASHMAP_RESET(&(_p)->MapDrawPrimSlowVs); \
+ VBOXWINEPROFILE_HASHMAP_RESET(&(_p)->MapDrawPrimSlow); \
+ VBOXWINEPROFILE_HASHMAP_RESET(&(_p)->MapDrawPrimStrided); \
+ VBOXWINEPROFILE_HASHMAP_RESET(&(_p)->MapDrawPrimFast); \
+ } while (0)
+
+static DECLCALLBACK(uint32_t) vboxWineProfileDrawPrimHashMapHash(void *pvKey)
+{
+ return (uint32_t)pvKey;
+}
+
+static DECLCALLBACK(bool) vboxWineProfileDrawPrimHashMapEqual(void *pvKey1, void *pvKey2)
+{
+ return ((uint32_t)pvKey1) == ((uint32_t)pvKey2);
+}
+
+#define VBOXWINEPROFILE_DRAWPRIM_INIT(_p) do { \
+ memset((_p), 0, sizeof (*(_p))); \
+ VBoxExtHashInit(&(_p)->MapDrawPrimSlowVs, vboxWineProfileDrawPrimHashMapHash, vboxWineProfileDrawPrimHashMapEqual); \
+ VBoxExtHashInit(&(_p)->MapDrawPrimSlow, vboxWineProfileDrawPrimHashMapHash, vboxWineProfileDrawPrimHashMapEqual); \
+ VBoxExtHashInit(&(_p)->MapDrawPrimStrided, vboxWineProfileDrawPrimHashMapHash, vboxWineProfileDrawPrimHashMapEqual); \
+ VBoxExtHashInit(&(_p)->MapDrawPrimFast, vboxWineProfileDrawPrimHashMapHash, vboxWineProfileDrawPrimHashMapEqual); \
+ } while (0)
+
+#define VBOXWINEPROFILE_DRAWPRIM_TERM(_p) do { \
+ memset((_p), 0, sizeof (*(_p))); \
+ VBOXWINEPROFILE_HASHMAP_TERM(&(_p)->MapDrawPrimSlowVs); \
+ VBOXWINEPROFILE_HASHMAP_TERM(&(_p)->MapDrawPrimSlow); \
+ VBOXWINEPROFILE_HASHMAP_TERM(&(_p)->MapDrawPrimStrided); \
+ VBOXWINEPROFILE_HASHMAP_TERM(&(_p)->MapDrawPrimFast); \
+ } while (0)
+#else
+# define PRLOG(_m) do {} while (0)
+#endif
+
+#endif /* #ifndef ___VBOXEXT_H__*/
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/vboxsharedrc.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/vboxsharedrc.h
new file mode 100644
index 00000000..6ea458b7
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/vboxsharedrc.h
@@ -0,0 +1,49 @@
+/* $Id: vboxsharedrc.h $ */
+/** @file
+ *
+ * VBox extension to Wine D3D - shared resource
+ *
+ * Copyright (C) 2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+#ifndef ___vboxsharedrc_h___
+#define ___vboxsharedrc_h___
+
+#define VBOXSHRC_F_SHARED 0x00000001 /* shared rc */
+#define VBOXSHRC_F_SHARED_OPENED 0x00000002 /* if set shared rc is opened, otherwise it is created */
+
+#define VBOXSHRC_GET_SHAREFLAFS(_o) ((_o)->resource.sharerc_flags)
+#define VBOXSHRC_GET_SHAREHANDLE(_o) ((HANDLE)(_o)->resource.sharerc_handle)
+#define VBOXSHRC_SET_SHAREHANDLE(_o, _h) ((_o)->resource.sharerc_handle = (DWORD)(_h))
+#define VBOXSHRC_COPY_SHAREDATA(_oDst, _oSrc) do { \
+ VBOXSHRC_GET_SHAREFLAFS(_oDst) = VBOXSHRC_GET_SHAREFLAFS(_oSrc); \
+ VBOXSHRC_SET_SHAREHANDLE(_oDst, VBOXSHRC_GET_SHAREHANDLE(_oSrc)); \
+ } while (0)
+#define VBOXSHRC_SET_SHARED(_o) (VBOXSHRC_GET_SHAREFLAFS(_o) |= VBOXSHRC_F_SHARED)
+#define VBOXSHRC_SET_SHARED_OPENED(_o) (VBOXSHRC_GET_SHAREFLAFS(_o) |= VBOXSHRC_F_SHARED_OPENED)
+
+#define VBOXSHRC_IS_SHARED(_o) (!!(VBOXSHRC_GET_SHAREFLAFS(_o) & VBOXSHRC_F_SHARED))
+#define VBOXSHRC_IS_SHARED_OPENED(_o) (!!(VBOXSHRC_GET_SHAREFLAFS(_o) & VBOXSHRC_F_SHARED_OPENED))
+#define VBOXSHRC_IS_SHARED_UNLOCKED(_o) (VBOXSHRC_IS_SHARED(_o) && !VBOXSHRC_IS_LOCKED(_o))
+
+#define VBOXSHRC_LOCK(_o) do{ \
+ Assert(VBOXSHRC_IS_SHARED(_o)); \
+ ++(_o)->resource.sharerc_locks; \
+ } while (0)
+#define VBOXSHRC_UNLOCK(_o) do{ \
+ Assert(VBOXSHRC_IS_SHARED(_o)); \
+ --(_o)->resource.sharerc_locks; \
+ Assert((_o)->resource.sharerc_locks < UINT32_MAX/2); \
+ } while (0)
+#define VBOXSHRC_IS_LOCKED(_o) ( \
+ !!((_o)->resource.sharerc_locks) \
+ )
+
+#endif /* #ifndef ___vboxsharedrc_h___ */
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/version.rc b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/version.rc
new file mode 100644
index 00000000..ffdbf67b
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/version.rc
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2009 Austin English
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h" /* Needed to get PACKAGE_VERSION */
+
+#define WINE_FILEDESCRIPTION_STR "Wine D3D"
+#define WINE_FILENAME_STR "wined3d.dll"
+#define WINE_FILEVERSION_STR PACKAGE_VERSION
+#define WINE_PRODUCTVERSION_STR PACKAGE_VERSION
+#define WINE_PRODUCTNAME_STR "Wine D3D"
+
+#include "wine/wine_common_ver.rc"
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/vertexdeclaration.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/vertexdeclaration.c
new file mode 100644
index 00000000..4eca90de
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/vertexdeclaration.c
@@ -0,0 +1,429 @@
+/*
+ * vertex declaration implementation
+ *
+ * Copyright 2002-2005 Raphael Junqueira
+ * Copyright 2004 Jason Edmeades
+ * Copyright 2004 Christian Costa
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2009 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_decl);
+
+static void dump_wined3d_vertex_element(const struct wined3d_vertex_element *element)
+{
+ TRACE(" format: %s (%#x)\n", debug_d3dformat(element->format), element->format);
+ TRACE(" input_slot: %u\n", element->input_slot);
+ TRACE(" offset: %u\n", element->offset);
+ TRACE("output_slot: %u\n", element->output_slot);
+ TRACE(" method: %s (%#x)\n", debug_d3ddeclmethod(element->method), element->method);
+ TRACE(" usage: %s (%#x)\n", debug_d3ddeclusage(element->usage), element->usage);
+ TRACE(" usage_idx: %u\n", element->usage_idx);
+}
+
+ULONG CDECL wined3d_vertex_declaration_incref(struct wined3d_vertex_declaration *declaration)
+{
+ ULONG refcount = InterlockedIncrement(&declaration->ref);
+
+ TRACE("%p increasing refcount to %u.\n", declaration, refcount);
+
+ return refcount;
+}
+
+ULONG CDECL wined3d_vertex_declaration_decref(struct wined3d_vertex_declaration *declaration)
+{
+ ULONG refcount = InterlockedDecrement(&declaration->ref);
+
+ TRACE("%p decreasing refcount to %u.\n", declaration, refcount);
+
+ if (!refcount)
+ {
+ HeapFree(GetProcessHeap(), 0, declaration->elements);
+ declaration->parent_ops->wined3d_object_destroyed(declaration->parent);
+ HeapFree(GetProcessHeap(), 0, declaration);
+ }
+
+ return refcount;
+}
+
+void * CDECL wined3d_vertex_declaration_get_parent(const struct wined3d_vertex_declaration *declaration)
+{
+ TRACE("declaration %p.\n", declaration);
+
+ return declaration->parent;
+}
+
+static BOOL declaration_element_valid_ffp(const struct wined3d_vertex_element *element)
+{
+ switch(element->usage)
+ {
+ case WINED3D_DECL_USAGE_POSITION:
+ case WINED3D_DECL_USAGE_POSITIONT:
+ switch(element->format)
+ {
+ case WINED3DFMT_R32G32_FLOAT:
+ case WINED3DFMT_R32G32B32_FLOAT:
+ case WINED3DFMT_R32G32B32A32_FLOAT:
+ case WINED3DFMT_R16G16_SINT:
+ case WINED3DFMT_R16G16B16A16_SINT:
+ case WINED3DFMT_R16G16_FLOAT:
+ case WINED3DFMT_R16G16B16A16_FLOAT:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+
+ case WINED3D_DECL_USAGE_BLEND_WEIGHT:
+ switch(element->format)
+ {
+ case WINED3DFMT_R32_FLOAT:
+ case WINED3DFMT_R32G32_FLOAT:
+ case WINED3DFMT_R32G32B32_FLOAT:
+ case WINED3DFMT_R32G32B32A32_FLOAT:
+ case WINED3DFMT_B8G8R8A8_UNORM:
+ case WINED3DFMT_R8G8B8A8_UINT:
+ case WINED3DFMT_R16G16_SINT:
+ case WINED3DFMT_R16G16B16A16_SINT:
+ case WINED3DFMT_R16G16_FLOAT:
+ case WINED3DFMT_R16G16B16A16_FLOAT:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+
+ case WINED3D_DECL_USAGE_NORMAL:
+ switch(element->format)
+ {
+ case WINED3DFMT_R32G32B32_FLOAT:
+ case WINED3DFMT_R32G32B32A32_FLOAT:
+ case WINED3DFMT_R16G16B16A16_SINT:
+ case WINED3DFMT_R16G16B16A16_FLOAT:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+
+ case WINED3D_DECL_USAGE_TEXCOORD:
+ switch(element->format)
+ {
+ case WINED3DFMT_R32_FLOAT:
+ case WINED3DFMT_R32G32_FLOAT:
+ case WINED3DFMT_R32G32B32_FLOAT:
+ case WINED3DFMT_R32G32B32A32_FLOAT:
+ case WINED3DFMT_R16G16_SINT:
+ case WINED3DFMT_R16G16B16A16_SINT:
+ case WINED3DFMT_R16G16_FLOAT:
+ case WINED3DFMT_R16G16B16A16_FLOAT:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+
+ case WINED3D_DECL_USAGE_COLOR:
+ switch(element->format)
+ {
+ case WINED3DFMT_R32G32B32_FLOAT:
+ case WINED3DFMT_R32G32B32A32_FLOAT:
+ case WINED3DFMT_B8G8R8A8_UNORM:
+ case WINED3DFMT_R8G8B8A8_UINT:
+ case WINED3DFMT_R16G16B16A16_SINT:
+ case WINED3DFMT_R8G8B8A8_UNORM:
+ case WINED3DFMT_R16G16B16A16_SNORM:
+ case WINED3DFMT_R16G16B16A16_UNORM:
+ case WINED3DFMT_R16G16B16A16_FLOAT:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+
+ default:
+ return FALSE;
+ }
+}
+
+static HRESULT vertexdeclaration_init(struct wined3d_vertex_declaration *declaration,
+ struct wined3d_device *device, const struct wined3d_vertex_element *elements, UINT element_count,
+ void *parent, const struct wined3d_parent_ops *parent_ops)
+{
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ unsigned int i;
+
+ if (TRACE_ON(d3d_decl))
+ {
+ for (i = 0; i < element_count; ++i)
+ {
+ dump_wined3d_vertex_element(elements + i);
+ }
+ }
+
+ declaration->ref = 1;
+ declaration->parent = parent;
+ declaration->parent_ops = parent_ops;
+ declaration->device = device;
+ declaration->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*declaration->elements) * element_count);
+ if (!declaration->elements)
+ {
+ ERR("Failed to allocate elements memory.\n");
+ return E_OUTOFMEMORY;
+ }
+ declaration->element_count = element_count;
+
+ /* Do some static analysis on the elements to make reading the
+ * declaration more comfortable for the drawing code. */
+ for (i = 0; i < element_count; ++i)
+ {
+ struct wined3d_vertex_declaration_element *e = &declaration->elements[i];
+
+ e->format = wined3d_get_format(gl_info, elements[i].format);
+ e->ffp_valid = declaration_element_valid_ffp(&elements[i]);
+ e->input_slot = elements[i].input_slot;
+ e->offset = elements[i].offset;
+ e->output_slot = elements[i].output_slot;
+ e->method = elements[i].method;
+ e->usage = elements[i].usage;
+ e->usage_idx = elements[i].usage_idx;
+
+ if (e->usage == WINED3D_DECL_USAGE_POSITIONT)
+ declaration->position_transformed = TRUE;
+
+ /* Find the streams used in the declaration. The vertex buffers have
+ * to be loaded when drawing, but filter tesselation pseudo streams. */
+ if (e->input_slot >= MAX_STREAMS) continue;
+
+ if (!e->format->gl_vtx_format)
+ {
+ FIXME("The application tries to use an unsupported format (%s), returning E_FAIL.\n",
+ debug_d3dformat(elements[i].format));
+ HeapFree(GetProcessHeap(), 0, declaration->elements);
+ return E_FAIL;
+ }
+
+ if (e->offset & 0x3)
+ {
+ WARN("Declaration element %u is not 4 byte aligned(%u), returning E_FAIL.\n", i, e->offset);
+ HeapFree(GetProcessHeap(), 0, declaration->elements);
+ return E_FAIL;
+ }
+
+ if (elements[i].format == WINED3DFMT_R16G16_FLOAT || elements[i].format == WINED3DFMT_R16G16B16A16_FLOAT)
+ {
+ if (!gl_info->supported[ARB_HALF_FLOAT_VERTEX]) declaration->half_float_conv_needed = TRUE;
+ }
+ }
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_vertex_declaration_create(struct wined3d_device *device,
+ const struct wined3d_vertex_element *elements, UINT element_count, void *parent,
+ const struct wined3d_parent_ops *parent_ops, struct wined3d_vertex_declaration **declaration)
+{
+ struct wined3d_vertex_declaration *object;
+ HRESULT hr;
+
+ TRACE("device %p, elements %p, element_count %u, parent %p, parent_ops %p, declaration %p.\n",
+ device, elements, element_count, parent, parent_ops, declaration);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if(!object)
+ return E_OUTOFMEMORY;
+
+ hr = vertexdeclaration_init(object, device, elements, element_count, parent, parent_ops);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created vertex declaration %p.\n", object);
+ *declaration = object;
+
+ return WINED3D_OK;
+}
+
+struct wined3d_fvf_convert_state
+{
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_vertex_element *elements;
+ UINT offset;
+ UINT idx;
+};
+
+static void append_decl_element(struct wined3d_fvf_convert_state *state,
+ enum wined3d_format_id format_id, enum wined3d_decl_usage usage, UINT usage_idx)
+{
+ struct wined3d_vertex_element *elements = state->elements;
+ const struct wined3d_format *format;
+ UINT offset = state->offset;
+ UINT idx = state->idx;
+
+ elements[idx].format = format_id;
+ elements[idx].input_slot = 0;
+ elements[idx].offset = offset;
+ elements[idx].output_slot = 0;
+ elements[idx].method = WINED3D_DECL_METHOD_DEFAULT;
+ elements[idx].usage = usage;
+ elements[idx].usage_idx = usage_idx;
+
+ format = wined3d_get_format(state->gl_info, format_id);
+ state->offset += format->component_count * format->component_size;
+ ++state->idx;
+}
+
+static unsigned int convert_fvf_to_declaration(const struct wined3d_gl_info *gl_info,
+ DWORD fvf, struct wined3d_vertex_element **elements)
+{
+ BOOL has_pos = !!(fvf & WINED3DFVF_POSITION_MASK);
+ BOOL has_blend = (fvf & WINED3DFVF_XYZB5) > WINED3DFVF_XYZRHW;
+ BOOL has_blend_idx = has_blend &&
+ (((fvf & WINED3DFVF_XYZB5) == WINED3DFVF_XYZB5) ||
+ (fvf & WINED3DFVF_LASTBETA_D3DCOLOR) ||
+ (fvf & WINED3DFVF_LASTBETA_UBYTE4));
+ BOOL has_normal = !!(fvf & WINED3DFVF_NORMAL);
+ BOOL has_psize = !!(fvf & WINED3DFVF_PSIZE);
+ BOOL has_diffuse = !!(fvf & WINED3DFVF_DIFFUSE);
+ BOOL has_specular = !!(fvf & WINED3DFVF_SPECULAR);
+
+ DWORD num_textures = (fvf & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
+ DWORD texcoords = (fvf & 0xffff0000) >> 16;
+ struct wined3d_fvf_convert_state state;
+ unsigned int size;
+ unsigned int idx;
+ DWORD num_blends = 1 + (((fvf & WINED3DFVF_XYZB5) - WINED3DFVF_XYZB1) >> 1);
+ if (has_blend_idx) num_blends--;
+
+ /* Compute declaration size */
+ size = has_pos + (has_blend && num_blends > 0) + has_blend_idx + has_normal +
+ has_psize + has_diffuse + has_specular + num_textures;
+
+ state.gl_info = gl_info;
+ state.elements = HeapAlloc(GetProcessHeap(), 0, size * sizeof(*state.elements));
+ if (!state.elements) return ~0U;
+ state.offset = 0;
+ state.idx = 0;
+
+ if (has_pos)
+ {
+ if (!has_blend && (fvf & WINED3DFVF_XYZRHW))
+ append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_DECL_USAGE_POSITIONT, 0);
+ else if ((fvf & WINED3DFVF_XYZW) == WINED3DFVF_XYZW)
+ append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_DECL_USAGE_POSITION, 0);
+ else
+ append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3D_DECL_USAGE_POSITION, 0);
+ }
+
+ if (has_blend && (num_blends > 0))
+ {
+ if ((fvf & WINED3DFVF_XYZB5) == WINED3DFVF_XYZB2 && (fvf & WINED3DFVF_LASTBETA_D3DCOLOR))
+ append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3D_DECL_USAGE_BLEND_WEIGHT, 0);
+ else
+ {
+ switch (num_blends)
+ {
+ case 1:
+ append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3D_DECL_USAGE_BLEND_WEIGHT, 0);
+ break;
+ case 2:
+ append_decl_element(&state, WINED3DFMT_R32G32_FLOAT, WINED3D_DECL_USAGE_BLEND_WEIGHT, 0);
+ break;
+ case 3:
+ append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3D_DECL_USAGE_BLEND_WEIGHT, 0);
+ break;
+ case 4:
+ append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_DECL_USAGE_BLEND_WEIGHT, 0);
+ break;
+ default:
+ ERR("Unexpected amount of blend values: %u\n", num_blends);
+ }
+ }
+ }
+
+ if (has_blend_idx)
+ {
+ if ((fvf & WINED3DFVF_LASTBETA_UBYTE4)
+ || ((fvf & WINED3DFVF_XYZB5) == WINED3DFVF_XYZB2 && (fvf & WINED3DFVF_LASTBETA_D3DCOLOR)))
+ append_decl_element(&state, WINED3DFMT_R8G8B8A8_UINT, WINED3D_DECL_USAGE_BLEND_INDICES, 0);
+ else if (fvf & WINED3DFVF_LASTBETA_D3DCOLOR)
+ append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3D_DECL_USAGE_BLEND_INDICES, 0);
+ else
+ append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3D_DECL_USAGE_BLEND_INDICES, 0);
+ }
+
+ if (has_normal)
+ append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3D_DECL_USAGE_NORMAL, 0);
+ if (has_psize)
+ append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3D_DECL_USAGE_PSIZE, 0);
+ if (has_diffuse)
+ append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3D_DECL_USAGE_COLOR, 0);
+ if (has_specular)
+ append_decl_element(&state, WINED3DFMT_B8G8R8A8_UNORM, WINED3D_DECL_USAGE_COLOR, 1);
+
+ for (idx = 0; idx < num_textures; ++idx)
+ {
+ switch ((texcoords >> (idx * 2)) & 0x03)
+ {
+ case WINED3DFVF_TEXTUREFORMAT1:
+ append_decl_element(&state, WINED3DFMT_R32_FLOAT, WINED3D_DECL_USAGE_TEXCOORD, idx);
+ break;
+ case WINED3DFVF_TEXTUREFORMAT2:
+ append_decl_element(&state, WINED3DFMT_R32G32_FLOAT, WINED3D_DECL_USAGE_TEXCOORD, idx);
+ break;
+ case WINED3DFVF_TEXTUREFORMAT3:
+ append_decl_element(&state, WINED3DFMT_R32G32B32_FLOAT, WINED3D_DECL_USAGE_TEXCOORD, idx);
+ break;
+ case WINED3DFVF_TEXTUREFORMAT4:
+ append_decl_element(&state, WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_DECL_USAGE_TEXCOORD, idx);
+ break;
+ }
+ }
+
+ *elements = state.elements;
+ return size;
+}
+
+HRESULT CDECL wined3d_vertex_declaration_create_from_fvf(struct wined3d_device *device,
+ DWORD fvf, void *parent, const struct wined3d_parent_ops *parent_ops,
+ struct wined3d_vertex_declaration **declaration)
+{
+ struct wined3d_vertex_element *elements;
+ unsigned int size;
+ DWORD hr;
+
+ TRACE("device %p, fvf %#x, parent %p, parent_ops %p, declaration %p.\n",
+ device, fvf, parent, parent_ops, declaration);
+
+ size = convert_fvf_to_declaration(&device->adapter->gl_info, fvf, &elements);
+ if (size == ~0U) return E_OUTOFMEMORY;
+
+ hr = wined3d_vertex_declaration_create(device, elements, size, parent, parent_ops, declaration);
+ HeapFree(GetProcessHeap(), 0, elements);
+ return hr;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/view.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/view.c
new file mode 100644
index 00000000..dec41659
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/view.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2009, 2011 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+
+ULONG CDECL wined3d_rendertarget_view_incref(struct wined3d_rendertarget_view *view)
+{
+ ULONG refcount = InterlockedIncrement(&view->refcount);
+
+ TRACE("%p increasing refcount to %u.\n", view, refcount);
+
+ return refcount;
+}
+
+ULONG CDECL wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *view)
+{
+ ULONG refcount = InterlockedDecrement(&view->refcount);
+
+ TRACE("%p decreasing refcount to %u.\n", view, refcount);
+
+ if (!refcount)
+ HeapFree(GetProcessHeap(), 0, view);
+
+ return refcount;
+}
+
+void * CDECL wined3d_rendertarget_view_get_parent(const struct wined3d_rendertarget_view *view)
+{
+ TRACE("view %p.\n", view);
+
+ return view->parent;
+}
+
+struct wined3d_resource * CDECL wined3d_rendertarget_view_get_resource(const struct wined3d_rendertarget_view *view)
+{
+ TRACE("view %p.\n", view);
+
+ return view->resource;
+}
+
+static void wined3d_rendertarget_view_init(struct wined3d_rendertarget_view *view,
+ struct wined3d_resource *resource, void *parent)
+{
+ view->refcount = 1;
+ view->resource = resource;
+ view->parent = parent;
+}
+
+HRESULT CDECL wined3d_rendertarget_view_create(struct wined3d_resource *resource,
+ void *parent, struct wined3d_rendertarget_view **rendertarget_view)
+{
+ struct wined3d_rendertarget_view *object;
+
+ TRACE("resource %p, parent %p, rendertarget_view %p.\n",
+ resource, parent, rendertarget_view);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ wined3d_rendertarget_view_init(object, resource, parent);
+
+ TRACE("Created render target view %p.\n", object);
+ *rendertarget_view = object;
+
+ return WINED3D_OK;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/volume.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/volume.c
new file mode 100644
index 00000000..807f0a27
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/volume.c
@@ -0,0 +1,474 @@
+/*
+ * Copyright 2002-2005 Jason Edmeades
+ * Copyright 2002-2005 Raphael Junqueira
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2009-2011 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+#include "wined3d_private.h"
+
+#ifdef VBOX_WITH_WDDM
+# include "../../common/VBoxVideoTools.h"
+#endif
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
+
+/* Context activation is done by the caller. */
+static void volume_bind_and_dirtify(const struct wined3d_volume *volume, struct wined3d_context *context)
+{
+ struct wined3d_texture *container = volume->container;
+ DWORD active_sampler;
+
+ /* We don't need a specific texture unit, but after binding the texture the current unit is dirty.
+ * Read the unit back instead of switching to 0, this avoids messing around with the state manager's
+ * gl states. The current texture unit should always be a valid one.
+ *
+ * To be more specific, this is tricky because we can implicitly be called
+ * from sampler() in state.c. This means we can't touch anything other than
+ * whatever happens to be the currently active texture, or we would risk
+ * marking already applied sampler states dirty again. */
+ active_sampler = volume->resource.device->rev_tex_unit_map[context->active_texture];
+
+ if (active_sampler != WINED3D_UNMAPPED_STAGE)
+ device_invalidate_state(volume->resource.device, STATE_SAMPLER(active_sampler));
+
+ container->texture_ops->texture_bind(container, context, FALSE);
+}
+
+void volume_add_dirty_box(struct wined3d_volume *volume, const struct wined3d_box *dirty_box)
+{
+ volume->dirty = TRUE;
+ if (dirty_box)
+ {
+ volume->lockedBox.left = min(volume->lockedBox.left, dirty_box->left);
+ volume->lockedBox.top = min(volume->lockedBox.top, dirty_box->top);
+ volume->lockedBox.front = min(volume->lockedBox.front, dirty_box->front);
+ volume->lockedBox.right = max(volume->lockedBox.right, dirty_box->right);
+ volume->lockedBox.bottom = max(volume->lockedBox.bottom, dirty_box->bottom);
+ volume->lockedBox.back = max(volume->lockedBox.back, dirty_box->back);
+ }
+ else
+ {
+ volume->lockedBox.left = 0;
+ volume->lockedBox.top = 0;
+ volume->lockedBox.front = 0;
+ volume->lockedBox.right = volume->resource.width;
+ volume->lockedBox.bottom = volume->resource.height;
+ volume->lockedBox.back = volume->resource.depth;
+ }
+}
+
+void volume_set_container(struct wined3d_volume *volume, struct wined3d_texture *container)
+{
+ TRACE("volume %p, container %p.\n", volume, container);
+
+ volume->container = container;
+}
+
+/* Context activation is done by the caller. */
+void volume_load(const struct wined3d_volume *volume, struct wined3d_context *context, UINT level, BOOL srgb_mode)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const struct wined3d_format *format = volume->resource.format;
+
+ TRACE("volume %p, context %p, level %u, srgb %#x, format %s (%#x).\n",
+ volume, context, level, srgb_mode, debug_d3dformat(format->id), format->id);
+
+ volume_bind_and_dirtify(volume, context);
+
+ GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D, level, format->glInternal,
+ volume->resource.width, volume->resource.height, volume->resource.depth,
+ 0, format->glFormat, format->glType, volume->resource.allocatedMemory));
+ checkGLcall("glTexImage3D");
+
+ /* When adding code releasing volume->resource.allocatedMemory to save
+ * data keep in mind that GL_UNPACK_CLIENT_STORAGE_APPLE is enabled by
+ * default if supported(GL_APPLE_client_storage). Thus do not release
+ * volume->resource.allocatedMemory if GL_APPLE_client_storage is
+ * supported. */
+}
+
+/* Do not call while under the GL lock. */
+static void volume_unload(struct wined3d_resource *resource)
+{
+ TRACE("texture %p.\n", resource);
+
+ /* The whole content is shadowed on This->resource.allocatedMemory, and
+ * the texture name is managed by the VolumeTexture container. */
+
+ resource_unload(resource);
+}
+
+ULONG CDECL wined3d_volume_incref(struct wined3d_volume *volume)
+{
+ ULONG refcount;
+
+ if (volume->container)
+ {
+ TRACE("Forwarding to container %p.\n", volume->container);
+ return wined3d_texture_incref(volume->container);
+ }
+
+ refcount = InterlockedIncrement(&volume->resource.ref);
+
+ TRACE("%p increasing refcount to %u.\n", volume, refcount);
+
+ return refcount;
+}
+
+/* Do not call while under the GL lock. */
+ULONG CDECL wined3d_volume_decref(struct wined3d_volume *volume)
+{
+ ULONG refcount;
+
+ if (volume->container)
+ {
+ TRACE("Forwarding to container %p.\n", volume->container);
+ return wined3d_texture_decref(volume->container);
+ }
+
+ refcount = InterlockedDecrement(&volume->resource.ref);
+
+ TRACE("%p decreasing refcount to %u.\n", volume, refcount);
+
+ if (!refcount)
+ {
+ resource_cleanup(&volume->resource);
+ volume->resource.parent_ops->wined3d_object_destroyed(volume->resource.parent);
+ HeapFree(GetProcessHeap(), 0, volume);
+ }
+
+ return refcount;
+}
+
+void * CDECL wined3d_volume_get_parent(const struct wined3d_volume *volume)
+{
+ TRACE("volume %p.\n", volume);
+
+ return volume->resource.parent;
+}
+
+DWORD CDECL wined3d_volume_set_priority(struct wined3d_volume *volume, DWORD priority)
+{
+ return resource_set_priority(&volume->resource, priority);
+}
+
+DWORD CDECL wined3d_volume_get_priority(const struct wined3d_volume *volume)
+{
+ return resource_get_priority(&volume->resource);
+}
+
+/* Do not call while under the GL lock. */
+void CDECL wined3d_volume_preload(struct wined3d_volume *volume)
+{
+ FIXME("volume %p stub!\n", volume);
+}
+
+struct wined3d_resource * CDECL wined3d_volume_get_resource(struct wined3d_volume *volume)
+{
+ TRACE("volume %p.\n", volume);
+
+ return &volume->resource;
+}
+
+HRESULT CDECL wined3d_volume_map(struct wined3d_volume *volume,
+ struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags)
+{
+ TRACE("volume %p, map_desc %p, box %p, flags %#x.\n",
+ volume, map_desc, box, flags);
+
+ if (!volume->resource.allocatedMemory)
+ volume->resource.allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, volume->resource.size);
+
+ TRACE("allocatedMemory %p.\n", volume->resource.allocatedMemory);
+
+ map_desc->row_pitch = volume->resource.format->byte_count * volume->resource.width; /* Bytes / row */
+ map_desc->slice_pitch = volume->resource.format->byte_count
+ * volume->resource.width * volume->resource.height; /* Bytes / slice */
+ if (!box)
+ {
+ TRACE("No box supplied - all is ok\n");
+ map_desc->data = volume->resource.allocatedMemory;
+ volume->lockedBox.left = 0;
+ volume->lockedBox.top = 0;
+ volume->lockedBox.front = 0;
+ volume->lockedBox.right = volume->resource.width;
+ volume->lockedBox.bottom = volume->resource.height;
+ volume->lockedBox.back = volume->resource.depth;
+ }
+ else
+ {
+#ifdef VBOX_WITH_WDDM
+ if (box->right <= box->left
+ || box->right > volume->resource.width
+ || box->bottom <= box->top
+ || box->bottom > volume->resource.height
+ || box->back <= box->front
+ || box->back > volume->resource.depth
+ )
+ {
+ ERR("invalid dimensions!");
+ return WINED3DERR_INVALIDCALL;
+ }
+#endif
+ TRACE("Lock Box (%p) = l %u, t %u, r %u, b %u, fr %u, ba %u\n",
+ box, box->left, box->top, box->right, box->bottom, box->front, box->back);
+ map_desc->data = volume->resource.allocatedMemory
+ + (map_desc->slice_pitch * box->front) /* FIXME: is front < back or vica versa? */
+ + (map_desc->row_pitch * box->top)
+ + (box->left * volume->resource.format->byte_count);
+ volume->lockedBox.left = box->left;
+ volume->lockedBox.top = box->top;
+ volume->lockedBox.front = box->front;
+ volume->lockedBox.right = box->right;
+ volume->lockedBox.bottom = box->bottom;
+ volume->lockedBox.back = box->back;
+ }
+
+ if (!(flags & (WINED3D_MAP_NO_DIRTY_UPDATE | WINED3D_MAP_READONLY)))
+ {
+ volume_add_dirty_box(volume, &volume->lockedBox);
+ wined3d_texture_set_dirty(volume->container, TRUE);
+ }
+
+ volume->locked = TRUE;
+
+ TRACE("Returning memory %p, row pitch %d, slice pitch %d.\n",
+ map_desc->data, map_desc->row_pitch, map_desc->slice_pitch);
+
+ return WINED3D_OK;
+}
+
+struct wined3d_volume * CDECL wined3d_volume_from_resource(struct wined3d_resource *resource)
+{
+ return volume_from_resource(resource);
+}
+
+HRESULT CDECL wined3d_volume_unmap(struct wined3d_volume *volume)
+{
+ TRACE("volume %p.\n", volume);
+
+ if (!volume->locked)
+ {
+ WARN("Trying to unlock unlocked volume %p.\n", volume);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ volume->locked = FALSE;
+ memset(&volume->lockedBox, 0, sizeof(volume->lockedBox));
+
+ return WINED3D_OK;
+}
+
+static const struct wined3d_resource_ops volume_resource_ops =
+{
+ volume_unload,
+};
+
+static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_device *device, UINT width,
+ UINT height, UINT depth, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool,
+ void *parent, const struct wined3d_parent_ops *parent_ops
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void *pvClientMem
+#endif
+ )
+{
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ const struct wined3d_format *format = wined3d_get_format(gl_info, format_id);
+ HRESULT hr;
+
+ if (!gl_info->supported[EXT_TEXTURE3D])
+ {
+ WARN("Volume cannot be created - no volume texture support.\n");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ hr = resource_init(&volume->resource, device, WINED3D_RTYPE_VOLUME, format,
+ WINED3D_MULTISAMPLE_NONE, 0, usage, pool, width, height, depth,
+ width * height * depth * format->byte_count, parent, parent_ops,
+ &volume_resource_ops
+#ifdef VBOX_WITH_WDDM
+ , shared_handle, pvClientMem
+#endif
+ );
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize resource, returning %#x.\n", hr);
+ return hr;
+ }
+
+ volume->lockable = TRUE;
+ volume->locked = FALSE;
+ memset(&volume->lockedBox, 0, sizeof(volume->lockedBox));
+ volume->dirty = TRUE;
+
+ volume_add_dirty_box(volume, NULL);
+
+ return WINED3D_OK;
+}
+
+HRESULT CDECL wined3d_volume_create(struct wined3d_device *device, UINT width, UINT height,
+ UINT depth, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool, void *parent,
+ const struct wined3d_parent_ops *parent_ops, struct wined3d_volume **volume
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void *pvClientMem
+#endif
+ )
+{
+ struct wined3d_volume *object;
+ HRESULT hr;
+
+ TRACE("device %p, width %u, height %u, depth %u, usage %#x, format %s, pool %s\n",
+ device, width, height, depth, usage, debug_d3dformat(format_id), debug_d3dpool(pool));
+ TRACE("parent %p, parent_ops %p, volume %p.\n", parent, parent_ops, volume);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ {
+ *volume = NULL;
+ return WINED3DERR_OUTOFVIDEOMEMORY;
+ }
+
+ hr = volume_init(object, device, width, height, depth, usage, format_id, pool, parent, parent_ops
+#ifdef VBOX_WITH_WDDM
+ , shared_handle
+ , pvClientMem
+#endif
+ );
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize volume, returning %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created volume %p.\n", object);
+ *volume = object;
+
+ return WINED3D_OK;
+}
+
+#ifdef VBOX_WITH_WDDM
+HRESULT CDECL wined3d_device_blt_vol(struct wined3d_device *device, struct wined3d_volume *src, struct wined3d_volume *dst,
+ const struct wined3d_box *pSrcBoxArg,
+ const VBOXPOINT3D *pDstPoin3D)
+{
+ struct wined3d_map_desc src_desc, dst_desc;
+ HRESULT hr;
+ struct wined3d_box DstBox, SrcBox;
+ const struct wined3d_box *pDstBox;
+ const struct wined3d_box *pSrcBox;
+ int dstW, dstH, dstD, srcW, srcH, srcD;
+ int j, k;
+ uint8_t * pDstBits;
+ uint8_t * pSrcBits;
+
+
+ TRACE("device %p, src_volume %p, dst_volume %p.\n",
+ device, src, dst);
+
+ pSrcBox = pSrcBoxArg;
+ if (!pSrcBox)
+ {
+ SrcBox.left = 0;
+ SrcBox.top = 0;
+ SrcBox.front = 0;
+ SrcBox.right = src->resource.width;
+ SrcBox.bottom = src->resource.height;
+ SrcBox.back = src->resource.depth;
+ pSrcBox = &SrcBox;
+ }
+
+ if (!pDstPoin3D)
+ pDstBox = pSrcBox;
+ else
+ {
+ vboxWddmBoxTranslated((VBOXBOX3D*)&DstBox, (const VBOXBOX3D *)pSrcBox, pDstPoin3D->x, pDstPoin3D->y, pDstPoin3D->z);
+ pDstBox = &DstBox;
+ }
+
+ dstW = pDstBox->right - pDstBox->left;
+ dstH = pDstBox->bottom - pDstBox->top;
+ dstD = pDstBox->back - pDstBox->front;
+
+ srcW = pSrcBox->right - pSrcBox->left;
+ srcH = pSrcBox->bottom - pSrcBox->top;
+ srcD = pSrcBox->back - pSrcBox->front;
+
+ if (srcW != dstW || srcH != dstH || srcD != dstD)
+ {
+ ERR("dimensions do not match, stretching not supported for volumes!");
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ /* TODO: Implement direct loading into the gl volume instead of using memcpy and
+ * dirtification to improve loading performance.
+ */
+ hr = wined3d_volume_map(src, &src_desc, pSrcBox, WINED3D_MAP_READONLY);
+ if(FAILED(hr))
+ {
+ ERR("wined3d_volume_map src failed");
+ return hr;
+ }
+
+ hr = wined3d_volume_map(dst, &dst_desc, pDstBox, WINED3D_MAP_DISCARD);
+ if(FAILED(hr))
+ {
+ ERR("wined3d_volume_map dst failed");
+ wined3d_volume_unmap(src);
+ return hr;
+ }
+
+ pDstBits = dst_desc.data;
+ pSrcBits = src_desc.data;
+ for (k = 0; k < srcD; ++k)
+ {
+ uint8_t * pRowDstBits = pDstBits;
+ uint8_t * pRowSrcBits = pSrcBits;
+
+ for (j = 0; j < srcH; ++j)
+ {
+ memcpy(pRowDstBits, pRowSrcBits, srcW * dst->resource.format->byte_count);
+ pRowDstBits += dst_desc.row_pitch;
+ pRowSrcBits += src_desc.row_pitch;
+ }
+ pDstBits += dst_desc.slice_pitch;
+ pSrcBits += src_desc.slice_pitch;
+ }
+
+ hr = wined3d_volume_unmap(dst);
+ if(FAILED(hr)) {
+ wined3d_volume_unmap(src);
+ } else {
+ hr = wined3d_volume_unmap(src);
+ }
+ return hr;
+}
+#endif
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d.def b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d.def
new file mode 100644
index 00000000..354f7fd7
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d.def
@@ -0,0 +1,255 @@
+; File generated automatically from ./dlls/wined3d/wined3d.spec; do not edit!
+
+EXPORTS
+ wined3d_mutex_lock
+ wined3d_mutex_unlock
+ wined3d_check_depth_stencil_match
+ wined3d_check_device_format
+ wined3d_check_device_format_conversion
+ wined3d_check_device_multisample_type
+ wined3d_check_device_type
+ wined3d_create
+ wined3d_decref
+ wined3d_enum_adapter_modes
+ wined3d_get_adapter_count
+ wined3d_get_adapter_display_mode
+ wined3d_get_adapter_identifier
+ wined3d_get_adapter_mode_count
+ wined3d_get_adapter_monitor
+ wined3d_get_adapter_raster_status
+ wined3d_get_device_caps
+ wined3d_incref
+ wined3d_register_software_device
+ wined3d_set_adapter_display_mode
+ wined3d_buffer_create
+ wined3d_buffer_create_ib
+ wined3d_buffer_create_vb
+ wined3d_buffer_decref
+ wined3d_buffer_get_parent
+ wined3d_buffer_get_priority
+ wined3d_buffer_get_resource
+ wined3d_buffer_incref
+ wined3d_buffer_map
+ wined3d_buffer_preload
+ wined3d_buffer_set_priority
+ wined3d_buffer_unmap
+ wined3d_device_acquire_focus_window
+ wined3d_device_begin_scene
+ wined3d_device_begin_stateblock
+ wined3d_device_clear
+ wined3d_device_clear_rendertarget_view
+ wined3d_device_color_fill
+ wined3d_device_create
+ wined3d_device_decref
+ wined3d_device_draw_indexed_primitive
+ wined3d_device_draw_primitive
+ wined3d_device_end_scene
+ wined3d_device_end_stateblock
+ wined3d_device_evict_managed_resources
+ wined3d_device_get_available_texture_mem
+ wined3d_device_get_back_buffer
+ wined3d_device_get_base_vertex_index
+ wined3d_device_get_clip_plane
+ wined3d_device_get_clip_status
+ wined3d_device_get_creation_parameters
+ wined3d_device_get_depth_stencil
+ wined3d_device_get_device_caps
+ wined3d_device_get_display_mode
+ wined3d_device_get_front_buffer_data
+ wined3d_device_get_gamma_ramp
+ wined3d_device_get_index_buffer
+ wined3d_device_get_light
+ wined3d_device_get_light_enable
+ wined3d_device_get_material
+ wined3d_device_get_npatch_mode
+ wined3d_device_get_pixel_shader
+ wined3d_device_get_primitive_type
+ wined3d_device_get_ps_consts_b
+ wined3d_device_get_ps_consts_f
+ wined3d_device_get_ps_consts_i
+ wined3d_device_get_raster_status
+ wined3d_device_get_render_state
+ wined3d_device_get_render_target
+ wined3d_device_get_sampler_state
+ wined3d_device_get_scissor_rect
+ wined3d_device_get_software_vertex_processing
+ wined3d_device_get_stream_source
+ wined3d_device_get_stream_source_freq
+ wined3d_device_get_surface_from_dc
+ wined3d_device_get_swapchain
+ wined3d_device_get_swapchain_count
+ wined3d_device_get_texture
+ wined3d_device_get_texture_stage_state
+ wined3d_device_get_transform
+ wined3d_device_get_vertex_declaration
+ wined3d_device_get_vertex_shader
+ wined3d_device_get_viewport
+ wined3d_device_get_vs_consts_b
+ wined3d_device_get_vs_consts_f
+ wined3d_device_get_vs_consts_i
+ wined3d_device_incref
+ wined3d_device_init_3d
+ wined3d_device_init_gdi
+ wined3d_device_multiply_transform
+ wined3d_device_present
+ wined3d_device_process_vertices
+ wined3d_device_release_focus_window
+ wined3d_device_reset
+ wined3d_device_restore_fullscreen_window
+ wined3d_device_set_base_vertex_index
+ wined3d_device_set_clip_plane
+ wined3d_device_set_clip_status
+ wined3d_device_set_cursor_position
+ wined3d_device_set_cursor_properties
+ wined3d_device_set_depth_stencil
+ wined3d_device_set_dialog_box_mode
+ wined3d_device_set_gamma_ramp
+ wined3d_device_set_index_buffer
+ wined3d_device_set_light
+ wined3d_device_set_light_enable
+ wined3d_device_set_material
+ wined3d_device_set_multithreaded
+ wined3d_device_set_npatch_mode
+ wined3d_device_set_pixel_shader
+ wined3d_device_set_primitive_type
+ wined3d_device_set_ps_consts_b
+ wined3d_device_set_ps_consts_f
+ wined3d_device_set_ps_consts_i
+ wined3d_device_set_render_state
+ wined3d_device_set_render_target
+ wined3d_device_set_sampler_state
+ wined3d_device_set_scissor_rect
+ wined3d_device_set_software_vertex_processing
+ wined3d_device_set_stream_source
+ wined3d_device_set_stream_source_freq
+ wined3d_device_set_texture
+ wined3d_device_set_texture_stage_state
+ wined3d_device_set_transform
+ wined3d_device_set_vertex_declaration
+ wined3d_device_set_vertex_shader
+ wined3d_device_set_viewport
+ wined3d_device_set_vs_consts_b
+ wined3d_device_set_vs_consts_f
+ wined3d_device_set_vs_consts_i
+ wined3d_device_setup_fullscreen_window
+ wined3d_device_show_cursor
+ wined3d_device_uninit_3d
+ wined3d_device_uninit_gdi
+ wined3d_device_update_surface
+ wined3d_device_update_texture
+ wined3d_device_validate_device
+ wined3d_palette_create
+ wined3d_palette_decref
+ wined3d_palette_get_entries
+ wined3d_palette_get_flags
+ wined3d_palette_get_parent
+ wined3d_palette_incref
+ wined3d_palette_set_entries
+ wined3d_query_create
+ wined3d_query_decref
+ wined3d_query_get_data
+ wined3d_query_get_data_size
+ wined3d_query_get_type
+ wined3d_query_incref
+ wined3d_query_issue
+ wined3d_resource_free_private_data
+ wined3d_resource_get_desc
+ wined3d_resource_get_parent
+ wined3d_resource_get_private_data
+ wined3d_resource_set_private_data
+ wined3d_rendertarget_view_create
+ wined3d_rendertarget_view_decref
+ wined3d_rendertarget_view_get_parent
+ wined3d_rendertarget_view_get_resource
+ wined3d_rendertarget_view_incref
+ wined3d_shader_create_gs
+ wined3d_shader_create_ps
+ wined3d_shader_create_vs
+ wined3d_shader_decref
+ wined3d_shader_get_byte_code
+ wined3d_shader_get_parent
+ wined3d_shader_incref
+ wined3d_shader_set_local_constants_float
+ wined3d_stateblock_apply
+ wined3d_stateblock_capture
+ wined3d_stateblock_create
+ wined3d_stateblock_decref
+ wined3d_stateblock_incref
+ wined3d_surface_blt
+ wined3d_surface_create
+ wined3d_surface_decref
+ wined3d_surface_flip
+ wined3d_surface_from_resource
+ wined3d_surface_get_blt_status
+ wined3d_surface_get_flip_status
+ wined3d_surface_get_overlay_position
+ wined3d_surface_get_palette
+ wined3d_surface_get_parent
+ wined3d_surface_get_pitch
+ wined3d_surface_get_priority
+ wined3d_surface_get_render_target_data
+ wined3d_surface_get_resource
+ wined3d_surface_getdc
+ wined3d_surface_incref
+ wined3d_surface_is_lost
+ wined3d_surface_map
+ wined3d_surface_preload
+ wined3d_surface_releasedc
+ wined3d_surface_restore
+ wined3d_surface_set_color_key
+ wined3d_surface_set_mem
+ wined3d_surface_set_overlay_position
+ wined3d_surface_set_palette
+ wined3d_surface_set_priority
+ wined3d_surface_unmap
+ wined3d_surface_update_desc
+ wined3d_surface_update_overlay
+ wined3d_surface_update_overlay_z_order
+ wined3d_swapchain_create
+ wined3d_swapchain_decref
+ wined3d_swapchain_get_back_buffer
+ wined3d_swapchain_get_device
+ wined3d_swapchain_get_display_mode
+ wined3d_swapchain_get_front_buffer_data
+ wined3d_swapchain_get_gamma_ramp
+ wined3d_swapchain_get_parent
+ wined3d_swapchain_get_desc
+ wined3d_swapchain_get_raster_status
+ wined3d_swapchain_incref
+ wined3d_swapchain_present
+ wined3d_swapchain_set_gamma_ramp
+ wined3d_swapchain_set_window
+ wined3d_texture_add_dirty_region
+ wined3d_texture_create_2d
+ wined3d_texture_create_3d
+ wined3d_texture_create_cube
+ wined3d_texture_decref
+ wined3d_texture_generate_mipmaps
+ wined3d_texture_get_autogen_filter_type
+ wined3d_texture_get_level_count
+ wined3d_texture_get_lod
+ wined3d_texture_get_parent
+ wined3d_texture_get_priority
+ wined3d_texture_get_resource
+ wined3d_texture_get_sub_resource
+ wined3d_texture_incref
+ wined3d_texture_preload
+ wined3d_texture_set_autogen_filter_type
+ wined3d_texture_set_lod
+ wined3d_texture_set_priority
+ wined3d_vertex_declaration_create
+ wined3d_vertex_declaration_create_from_fvf
+ wined3d_vertex_declaration_decref
+ wined3d_vertex_declaration_get_parent
+ wined3d_vertex_declaration_incref
+ wined3d_volume_create
+ wined3d_volume_decref
+ wined3d_volume_from_resource
+ wined3d_volume_get_parent
+ wined3d_volume_get_priority
+ wined3d_volume_get_resource
+ wined3d_volume_incref
+ wined3d_volume_map
+ wined3d_volume_preload
+ wined3d_volume_set_priority
+ wined3d_volume_unmap
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d.spec b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d.spec
new file mode 100644
index 00000000..f451b7a3
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d.spec
@@ -0,0 +1,288 @@
+@ stdcall wined3d_mutex_lock()
+@ stdcall wined3d_mutex_unlock()
+
+@ cdecl wined3d_check_depth_stencil_match(ptr long long long long long)
+@ cdecl wined3d_check_device_format(ptr long long long long long long)
+@ cdecl wined3d_check_device_format_conversion(ptr long long long long)
+@ cdecl wined3d_check_device_multisample_type(ptr long long long long long ptr)
+@ cdecl wined3d_check_device_type(ptr long long long long long)
+@ cdecl wined3d_create(long long)
+@ cdecl wined3d_decref(ptr)
+@ cdecl wined3d_enum_adapter_modes(ptr long long long long ptr)
+@ cdecl wined3d_get_adapter_count(ptr)
+@ cdecl wined3d_get_adapter_display_mode(ptr long ptr ptr)
+@ cdecl wined3d_get_adapter_identifier(ptr long long ptr)
+@ cdecl wined3d_get_adapter_mode_count(ptr long long long)
+@ cdecl wined3d_get_adapter_monitor(ptr long)
+@ cdecl wined3d_get_adapter_raster_status(ptr long ptr)
+@ cdecl wined3d_get_device_caps(ptr long long ptr)
+@ cdecl wined3d_incref(ptr)
+@ cdecl wined3d_register_software_device(ptr ptr)
+@ cdecl wined3d_set_adapter_display_mode(ptr long ptr)
+
+@ cdecl wined3d_buffer_create(ptr ptr ptr ptr ptr ptr)
+@ cdecl wined3d_buffer_create_ib(ptr long long long ptr ptr ptr)
+@ cdecl wined3d_buffer_create_vb(ptr long long long ptr ptr ptr)
+@ cdecl wined3d_buffer_decref(ptr)
+@ cdecl wined3d_buffer_get_parent(ptr)
+@ cdecl wined3d_buffer_get_priority(ptr)
+@ cdecl wined3d_buffer_get_resource(ptr)
+@ cdecl wined3d_buffer_incref(ptr)
+@ cdecl wined3d_buffer_map(ptr long long ptr long)
+@ cdecl wined3d_buffer_preload(ptr)
+@ cdecl wined3d_buffer_set_priority(ptr long)
+@ cdecl wined3d_buffer_unmap(ptr)
+
+@ cdecl wined3d_device_acquire_focus_window(ptr ptr)
+@ cdecl wined3d_device_begin_scene(ptr)
+@ cdecl wined3d_device_begin_stateblock(ptr)
+@ cdecl wined3d_device_clear(ptr long ptr long ptr float long)
+@ cdecl wined3d_device_clear_rendertarget_view(ptr ptr ptr)
+@ cdecl wined3d_device_color_fill(ptr ptr ptr ptr)
+@ cdecl wined3d_device_create(ptr long long ptr long long ptr ptr)
+@ cdecl wined3d_device_decref(ptr)
+@ cdecl wined3d_device_draw_indexed_primitive(ptr long long)
+@ cdecl wined3d_device_draw_indexed_primitive_instanced(ptr long long long long)
+@ cdecl wined3d_device_draw_primitive(ptr long long)
+@ cdecl wined3d_device_end_scene(ptr)
+@ cdecl wined3d_device_end_stateblock(ptr ptr)
+@ cdecl wined3d_device_evict_managed_resources(ptr)
+@ cdecl wined3d_device_get_available_texture_mem(ptr)
+@ cdecl wined3d_device_get_back_buffer(ptr long long long ptr)
+@ cdecl wined3d_device_get_base_vertex_index(ptr)
+@ cdecl wined3d_device_get_clip_plane(ptr long ptr)
+@ cdecl wined3d_device_get_clip_status(ptr ptr)
+@ cdecl wined3d_device_get_creation_parameters(ptr ptr)
+@ cdecl wined3d_device_get_depth_stencil(ptr)
+@ cdecl wined3d_device_get_device_caps(ptr ptr)
+@ cdecl wined3d_device_get_display_mode(ptr long ptr ptr)
+@ cdecl wined3d_device_get_front_buffer_data(ptr long ptr)
+@ cdecl wined3d_device_get_gamma_ramp(ptr long ptr)
+@ cdecl wined3d_device_get_geometry_shader(ptr)
+@ cdecl wined3d_device_get_gs_cb(ptr long)
+@ cdecl wined3d_device_get_gs_sampler(ptr long)
+@ cdecl wined3d_device_get_index_buffer(ptr ptr)
+@ cdecl wined3d_device_get_light(ptr long ptr)
+@ cdecl wined3d_device_get_light_enable(ptr long ptr)
+@ cdecl wined3d_device_get_material(ptr ptr)
+@ cdecl wined3d_device_get_npatch_mode(ptr)
+@ cdecl wined3d_device_get_pixel_shader(ptr)
+@ cdecl wined3d_device_get_primitive_type(ptr ptr)
+@ cdecl wined3d_device_get_ps_cb(ptr long)
+@ cdecl wined3d_device_get_ps_consts_b(ptr long ptr long)
+@ cdecl wined3d_device_get_ps_consts_f(ptr long ptr long)
+@ cdecl wined3d_device_get_ps_consts_i(ptr long ptr long)
+@ cdecl wined3d_device_get_ps_sampler(ptr long)
+@ cdecl wined3d_device_get_raster_status(ptr long ptr)
+@ cdecl wined3d_device_get_render_state(ptr long)
+@ cdecl wined3d_device_get_render_target(ptr long)
+@ cdecl wined3d_device_get_sampler_state(ptr long long)
+@ cdecl wined3d_device_get_scissor_rect(ptr ptr)
+@ cdecl wined3d_device_get_software_vertex_processing(ptr)
+@ cdecl wined3d_device_get_stream_output(ptr long ptr)
+@ cdecl wined3d_device_get_stream_source(ptr long ptr ptr ptr)
+@ cdecl wined3d_device_get_stream_source_freq(ptr long ptr)
+@ cdecl wined3d_device_get_surface_from_dc(ptr ptr)
+@ cdecl wined3d_device_get_swapchain(ptr long)
+@ cdecl wined3d_device_get_swapchain_count(ptr)
+@ cdecl wined3d_device_get_texture(ptr long)
+@ cdecl wined3d_device_get_texture_stage_state(ptr long long)
+@ cdecl wined3d_device_get_transform(ptr long ptr)
+@ cdecl wined3d_device_get_vertex_declaration(ptr)
+@ cdecl wined3d_device_get_vertex_shader(ptr)
+@ cdecl wined3d_device_get_viewport(ptr ptr)
+@ cdecl wined3d_device_get_vs_cb(ptr long)
+@ cdecl wined3d_device_get_vs_consts_b(ptr long ptr long)
+@ cdecl wined3d_device_get_vs_consts_f(ptr long ptr long)
+@ cdecl wined3d_device_get_vs_consts_i(ptr long ptr long)
+@ cdecl wined3d_device_get_vs_sampler(ptr long)
+@ cdecl wined3d_device_incref(ptr)
+@ cdecl wined3d_device_init_3d(ptr ptr)
+@ cdecl wined3d_device_init_gdi(ptr ptr)
+@ cdecl wined3d_device_multiply_transform(ptr long ptr)
+@ cdecl wined3d_device_present(ptr ptr ptr ptr ptr long)
+@ cdecl wined3d_device_process_vertices(ptr long long long ptr ptr long long)
+@ cdecl wined3d_device_release_focus_window(ptr)
+@ cdecl wined3d_device_reset(ptr ptr ptr ptr long)
+@ cdecl wined3d_device_restore_fullscreen_window(ptr ptr)
+@ cdecl wined3d_device_set_base_vertex_index(ptr long)
+@ cdecl wined3d_device_set_clip_plane(ptr long ptr)
+@ cdecl wined3d_device_set_clip_status(ptr ptr)
+@ cdecl wined3d_device_set_cursor_position(ptr long long long)
+@ cdecl wined3d_device_set_cursor_properties(ptr long long ptr)
+@ cdecl wined3d_device_set_depth_stencil(ptr ptr)
+@ cdecl wined3d_device_set_dialog_box_mode(ptr long)
+@ cdecl wined3d_device_set_gamma_ramp(ptr long long ptr)
+@ cdecl wined3d_device_set_geometry_shader(ptr ptr)
+@ cdecl wined3d_device_set_gs_cb(ptr long ptr)
+@ cdecl wined3d_device_set_gs_sampler(ptr long ptr)
+@ cdecl wined3d_device_set_index_buffer(ptr ptr long)
+@ cdecl wined3d_device_set_light(ptr long ptr)
+@ cdecl wined3d_device_set_light_enable(ptr long long)
+@ cdecl wined3d_device_set_material(ptr ptr)
+@ cdecl wined3d_device_set_multithreaded(ptr)
+@ cdecl wined3d_device_set_npatch_mode(ptr float)
+@ cdecl wined3d_device_set_pixel_shader(ptr ptr)
+@ cdecl wined3d_device_set_primitive_type(ptr long)
+@ cdecl wined3d_device_set_ps_cb(ptr long ptr)
+@ cdecl wined3d_device_set_ps_consts_b(ptr long ptr long)
+@ cdecl wined3d_device_set_ps_consts_f(ptr long ptr long)
+@ cdecl wined3d_device_set_ps_consts_i(ptr long ptr long)
+@ cdecl wined3d_device_set_ps_sampler(ptr long ptr)
+@ cdecl wined3d_device_set_render_state(ptr long long)
+@ cdecl wined3d_device_set_render_target(ptr long ptr long)
+@ cdecl wined3d_device_set_sampler_state(ptr long long long)
+@ cdecl wined3d_device_set_scissor_rect(ptr ptr)
+@ cdecl wined3d_device_set_software_vertex_processing(ptr long)
+@ cdecl wined3d_device_set_stream_output(ptr long ptr long)
+@ cdecl wined3d_device_set_stream_source(ptr long ptr long long)
+@ cdecl wined3d_device_set_stream_source_freq(ptr long long)
+@ cdecl wined3d_device_set_texture(ptr long ptr)
+@ cdecl wined3d_device_set_texture_stage_state(ptr long long long)
+@ cdecl wined3d_device_set_transform(ptr long ptr)
+@ cdecl wined3d_device_set_vertex_declaration(ptr ptr)
+@ cdecl wined3d_device_set_vertex_shader(ptr ptr)
+@ cdecl wined3d_device_set_viewport(ptr ptr)
+@ cdecl wined3d_device_set_vs_cb(ptr long ptr)
+@ cdecl wined3d_device_set_vs_consts_b(ptr long ptr long)
+@ cdecl wined3d_device_set_vs_consts_f(ptr long ptr long)
+@ cdecl wined3d_device_set_vs_consts_i(ptr long ptr long)
+@ cdecl wined3d_device_set_vs_sampler(ptr long ptr)
+@ cdecl wined3d_device_setup_fullscreen_window(ptr ptr long long)
+@ cdecl wined3d_device_show_cursor(ptr long)
+@ cdecl wined3d_device_uninit_3d(ptr)
+@ cdecl wined3d_device_uninit_gdi(ptr)
+@ cdecl wined3d_device_update_surface(ptr ptr ptr ptr ptr)
+@ cdecl wined3d_device_update_texture(ptr ptr ptr)
+@ cdecl wined3d_device_validate_device(ptr ptr)
+
+@ cdecl wined3d_palette_create(ptr long ptr ptr ptr)
+@ cdecl wined3d_palette_decref(ptr)
+@ cdecl wined3d_palette_get_entries(ptr long long long ptr)
+@ cdecl wined3d_palette_get_flags(ptr)
+@ cdecl wined3d_palette_get_parent(ptr)
+@ cdecl wined3d_palette_incref(ptr)
+@ cdecl wined3d_palette_set_entries(ptr long long long ptr)
+
+@ cdecl wined3d_query_create(ptr long ptr)
+@ cdecl wined3d_query_decref(ptr)
+@ cdecl wined3d_query_get_data(ptr ptr long long)
+@ cdecl wined3d_query_get_data_size(ptr)
+@ cdecl wined3d_query_get_type(ptr)
+@ cdecl wined3d_query_incref(ptr)
+@ cdecl wined3d_query_issue(ptr long)
+
+@ cdecl wined3d_resource_free_private_data(ptr ptr)
+@ cdecl wined3d_resource_get_desc(ptr ptr)
+@ cdecl wined3d_resource_get_parent(ptr)
+@ cdecl wined3d_resource_get_private_data(ptr ptr ptr ptr)
+@ cdecl wined3d_resource_set_private_data(ptr ptr ptr long long)
+
+@ cdecl wined3d_rendertarget_view_create(ptr ptr ptr)
+@ cdecl wined3d_rendertarget_view_decref(ptr)
+@ cdecl wined3d_rendertarget_view_get_parent(ptr)
+@ cdecl wined3d_rendertarget_view_get_resource(ptr)
+@ cdecl wined3d_rendertarget_view_incref(ptr)
+
+@ cdecl wined3d_sampler_create(ptr ptr)
+@ cdecl wined3d_sampler_decref(ptr)
+@ cdecl wined3d_sampler_get_parent(ptr)
+@ cdecl wined3d_sampler_incref(ptr)
+
+@ cdecl wined3d_shader_create_gs(ptr ptr ptr ptr ptr ptr long)
+@ cdecl wined3d_shader_create_ps(ptr ptr ptr ptr ptr ptr long)
+@ cdecl wined3d_shader_create_vs(ptr ptr ptr ptr ptr ptr long)
+@ cdecl wined3d_shader_decref(ptr)
+@ cdecl wined3d_shader_get_byte_code(ptr ptr ptr)
+@ cdecl wined3d_shader_get_parent(ptr)
+@ cdecl wined3d_shader_incref(ptr)
+@ cdecl wined3d_shader_set_local_constants_float(ptr long ptr long)
+
+@ cdecl wined3d_stateblock_apply(ptr)
+@ cdecl wined3d_stateblock_capture(ptr)
+@ cdecl wined3d_stateblock_create(ptr long ptr)
+@ cdecl wined3d_stateblock_decref(ptr)
+@ cdecl wined3d_stateblock_incref(ptr)
+
+@ cdecl wined3d_surface_blt(ptr ptr ptr ptr long ptr long)
+@ cdecl wined3d_surface_create(ptr long long long long long long long long ptr ptr ptr)
+@ cdecl wined3d_surface_decref(ptr)
+@ cdecl wined3d_surface_flip(ptr ptr long)
+@ cdecl wined3d_surface_from_resource(ptr)
+@ cdecl wined3d_surface_get_blt_status(ptr long)
+@ cdecl wined3d_surface_get_flip_status(ptr long)
+@ cdecl wined3d_surface_get_overlay_position(ptr ptr ptr)
+@ cdecl wined3d_surface_get_palette(ptr)
+@ cdecl wined3d_surface_get_parent(ptr)
+@ cdecl wined3d_surface_get_pitch(ptr)
+@ cdecl wined3d_surface_get_priority(ptr)
+@ cdecl wined3d_surface_get_render_target_data(ptr ptr)
+@ cdecl wined3d_surface_get_resource(ptr)
+@ cdecl wined3d_surface_getdc(ptr ptr)
+@ cdecl wined3d_surface_incref(ptr)
+@ cdecl wined3d_surface_is_lost(ptr)
+@ cdecl wined3d_surface_map(ptr ptr ptr long)
+@ cdecl wined3d_surface_preload(ptr)
+@ cdecl wined3d_surface_releasedc(ptr ptr)
+@ cdecl wined3d_surface_restore(ptr)
+@ cdecl wined3d_surface_set_color_key(ptr long ptr)
+@ cdecl wined3d_surface_set_mem(ptr ptr long)
+@ cdecl wined3d_surface_set_overlay_position(ptr long long)
+@ cdecl wined3d_surface_set_palette(ptr ptr)
+@ cdecl wined3d_surface_set_priority(ptr long)
+@ cdecl wined3d_surface_unmap(ptr)
+@ cdecl wined3d_surface_update_desc(ptr long long long long long)
+@ cdecl wined3d_surface_update_overlay(ptr ptr ptr ptr long ptr)
+@ cdecl wined3d_surface_update_overlay_z_order(ptr long ptr)
+
+@ cdecl wined3d_swapchain_create(ptr ptr ptr ptr ptr)
+@ cdecl wined3d_swapchain_decref(ptr)
+@ cdecl wined3d_swapchain_get_back_buffer(ptr long long)
+@ cdecl wined3d_swapchain_get_device(ptr)
+@ cdecl wined3d_swapchain_get_display_mode(ptr ptr ptr)
+@ cdecl wined3d_swapchain_get_front_buffer_data(ptr ptr)
+@ cdecl wined3d_swapchain_get_gamma_ramp(ptr ptr)
+@ cdecl wined3d_swapchain_get_parent(ptr)
+@ cdecl wined3d_swapchain_get_desc(ptr ptr)
+@ cdecl wined3d_swapchain_get_raster_status(ptr ptr)
+@ cdecl wined3d_swapchain_incref(ptr)
+@ cdecl wined3d_swapchain_present(ptr ptr ptr ptr ptr long)
+@ cdecl wined3d_swapchain_set_gamma_ramp(ptr long ptr)
+@ cdecl wined3d_swapchain_set_window(ptr ptr)
+
+@ cdecl wined3d_texture_add_dirty_region(ptr long ptr)
+@ cdecl wined3d_texture_create_2d(ptr ptr long long ptr ptr ptr)
+@ cdecl wined3d_texture_create_3d(ptr ptr long ptr ptr ptr)
+@ cdecl wined3d_texture_create_cube(ptr ptr long long ptr ptr ptr)
+@ cdecl wined3d_texture_decref(ptr)
+@ cdecl wined3d_texture_generate_mipmaps(ptr)
+@ cdecl wined3d_texture_get_autogen_filter_type(ptr)
+@ cdecl wined3d_texture_get_level_count(ptr)
+@ cdecl wined3d_texture_get_lod(ptr)
+@ cdecl wined3d_texture_get_parent(ptr)
+@ cdecl wined3d_texture_get_priority(ptr)
+@ cdecl wined3d_texture_get_resource(ptr)
+@ cdecl wined3d_texture_get_sub_resource(ptr long)
+@ cdecl wined3d_texture_incref(ptr)
+@ cdecl wined3d_texture_preload(ptr)
+@ cdecl wined3d_texture_set_autogen_filter_type(ptr long)
+@ cdecl wined3d_texture_set_lod(ptr long)
+@ cdecl wined3d_texture_set_priority(ptr long)
+
+@ cdecl wined3d_vertex_declaration_create(ptr ptr long ptr ptr ptr)
+@ cdecl wined3d_vertex_declaration_create_from_fvf(ptr long ptr ptr ptr)
+@ cdecl wined3d_vertex_declaration_decref(ptr)
+@ cdecl wined3d_vertex_declaration_get_parent(ptr)
+@ cdecl wined3d_vertex_declaration_incref(ptr)
+
+@ cdecl wined3d_volume_create(ptr long long long long long long ptr ptr ptr)
+@ cdecl wined3d_volume_decref(ptr)
+@ cdecl wined3d_volume_from_resource(ptr)
+@ cdecl wined3d_volume_get_parent(ptr)
+@ cdecl wined3d_volume_get_priority(ptr)
+@ cdecl wined3d_volume_get_resource(ptr)
+@ cdecl wined3d_volume_incref(ptr)
+@ cdecl wined3d_volume_map(ptr ptr ptr long)
+@ cdecl wined3d_volume_preload(ptr)
+@ cdecl wined3d_volume_set_priority(ptr long)
+@ cdecl wined3d_volume_unmap(ptr)
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d_gl.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d_gl.h
new file mode 100644
index 00000000..dbc53562
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d_gl.h
@@ -0,0 +1,634 @@
+/*
+ * Direct3D wine OpenGL include file
+ *
+ * Copyright 2002-2003 The wine-d3d team
+ * Copyright 2002-2004 Jason Edmeades
+ * Raphael Junqueira
+ * Copyright 2007 Roderick Colenbrander
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#ifndef __WINE_WINED3D_GL_H
+#define __WINE_WINED3D_GL_H
+
+#include "wine/wgl.h"
+
+#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837 /* not in the gl spec */
+
+void (WINE_GLAPI *glDisableWINE)(GLenum cap) DECLSPEC_HIDDEN;
+void (WINE_GLAPI *glEnableWINE)(GLenum cap) DECLSPEC_HIDDEN;
+
+/* OpenGL extensions. */
+enum wined3d_gl_extension
+{
+ WINED3D_GL_EXT_NONE,
+
+ /* APPLE */
+ APPLE_CLIENT_STORAGE,
+ APPLE_FENCE,
+ APPLE_FLOAT_PIXELS,
+ APPLE_FLUSH_BUFFER_RANGE,
+ APPLE_YCBCR_422,
+ /* ARB */
+ ARB_COLOR_BUFFER_FLOAT,
+ ARB_DEBUG_OUTPUT,
+ ARB_DEPTH_BUFFER_FLOAT,
+ ARB_DEPTH_CLAMP,
+ ARB_DEPTH_TEXTURE,
+ ARB_DRAW_BUFFERS,
+ ARB_DRAW_ELEMENTS_BASE_VERTEX,
+ ARB_DRAW_INSTANCED,
+ ARB_FRAGMENT_PROGRAM,
+ ARB_FRAGMENT_SHADER,
+ ARB_FRAMEBUFFER_OBJECT,
+ ARB_FRAMEBUFFER_SRGB,
+ ARB_GEOMETRY_SHADER4,
+ ARB_HALF_FLOAT_PIXEL,
+ ARB_HALF_FLOAT_VERTEX,
+ ARB_INSTANCED_ARRAYS,
+ ARB_INTERNALFORMAT_QUERY2,
+ ARB_MAP_BUFFER_ALIGNMENT,
+ ARB_MAP_BUFFER_RANGE,
+ ARB_MULTISAMPLE,
+ ARB_MULTITEXTURE,
+ ARB_OCCLUSION_QUERY,
+ ARB_PIXEL_BUFFER_OBJECT,
+ ARB_POINT_PARAMETERS,
+ ARB_POINT_SPRITE,
+ ARB_PROVOKING_VERTEX,
+ ARB_SHADER_BIT_ENCODING,
+ ARB_SHADER_OBJECTS,
+ ARB_SHADER_TEXTURE_LOD,
+ ARB_SHADING_LANGUAGE_100,
+ ARB_SHADOW,
+ ARB_SYNC,
+ ARB_TEXTURE_BORDER_CLAMP,
+ ARB_TEXTURE_COMPRESSION,
+ ARB_TEXTURE_COMPRESSION_RGTC,
+ ARB_TEXTURE_CUBE_MAP,
+ ARB_TEXTURE_ENV_ADD,
+ ARB_TEXTURE_ENV_COMBINE,
+ ARB_TEXTURE_ENV_DOT3,
+ ARB_TEXTURE_FLOAT,
+ ARB_TEXTURE_MIRRORED_REPEAT,
+ ARB_TEXTURE_NON_POWER_OF_TWO,
+ ARB_TEXTURE_RECTANGLE,
+ ARB_TEXTURE_RG,
+ ARB_VERTEX_ARRAY_BGRA,
+ ARB_VERTEX_BLEND,
+ ARB_VERTEX_BUFFER_OBJECT,
+ ARB_VERTEX_PROGRAM,
+ ARB_VERTEX_SHADER,
+ /* ATI */
+ ATI_FRAGMENT_SHADER,
+ ATI_SEPARATE_STENCIL,
+ ATI_TEXTURE_COMPRESSION_3DC,
+ ATI_TEXTURE_ENV_COMBINE3,
+ ATI_TEXTURE_MIRROR_ONCE,
+ /* EXT */
+ EXT_BLEND_COLOR,
+ EXT_BLEND_EQUATION_SEPARATE,
+ EXT_BLEND_FUNC_SEPARATE,
+ EXT_BLEND_MINMAX,
+ EXT_BLEND_SUBTRACT,
+ EXT_DRAW_BUFFERS2,
+ EXT_DEPTH_BOUNDS_TEST,
+ EXT_FOG_COORD,
+ EXT_FRAMEBUFFER_BLIT,
+ EXT_FRAMEBUFFER_MULTISAMPLE,
+ EXT_FRAMEBUFFER_OBJECT,
+ EXT_GPU_PROGRAM_PARAMETERS,
+ EXT_GPU_SHADER4,
+ EXT_PACKED_DEPTH_STENCIL,
+ EXT_PALETTED_TEXTURE,
+ EXT_POINT_PARAMETERS,
+ EXT_PROVOKING_VERTEX,
+ EXT_SECONDARY_COLOR,
+ EXT_STENCIL_TWO_SIDE,
+ EXT_STENCIL_WRAP,
+ EXT_TEXTURE3D,
+ EXT_TEXTURE_COMPRESSION_RGTC,
+ EXT_TEXTURE_COMPRESSION_S3TC,
+ EXT_TEXTURE_ENV_ADD,
+ EXT_TEXTURE_ENV_COMBINE,
+ EXT_TEXTURE_ENV_DOT3,
+ EXT_TEXTURE_FILTER_ANISOTROPIC,
+ EXT_TEXTURE_LOD_BIAS,
+ EXT_TEXTURE_SRGB,
+ EXT_TEXTURE_SRGB_DECODE,
+ EXT_VERTEX_ARRAY_BGRA,
+ /* NVIDIA */
+ NV_DEPTH_CLAMP,
+ NV_FENCE,
+ NV_FOG_DISTANCE,
+ NV_FRAGMENT_PROGRAM,
+ NV_FRAGMENT_PROGRAM2,
+ NV_FRAGMENT_PROGRAM_OPTION,
+ NV_HALF_FLOAT,
+ NV_LIGHT_MAX_EXPONENT,
+ NV_POINT_SPRITE,
+ NV_REGISTER_COMBINERS,
+ NV_REGISTER_COMBINERS2,
+ NV_TEXGEN_REFLECTION,
+ NV_TEXTURE_ENV_COMBINE4,
+ NV_TEXTURE_SHADER,
+ NV_TEXTURE_SHADER2,
+ NV_VERTEX_PROGRAM,
+ NV_VERTEX_PROGRAM1_1,
+ NV_VERTEX_PROGRAM2,
+ NV_VERTEX_PROGRAM2_OPTION,
+ NV_VERTEX_PROGRAM3,
+ /* SGI */
+ SGIS_GENERATE_MIPMAP,
+ /* WGL extensions */
+ WGL_ARB_PIXEL_FORMAT,
+ WGL_EXT_SWAP_CONTROL,
+ WGL_WINE_PIXEL_FORMAT_PASSTHROUGH,
+ /* Internally used */
+ WINED3D_GL_NORMALIZED_TEXRECT,
+ WINED3D_GL_VERSION_2_0,
+
+ WINED3D_GL_EXT_COUNT,
+};
+
+#include "wine/wglext.h"
+
+#ifdef VBOX
+/*Global resource ids sharing*/
+#define GL_SHARE_CONTEXT_RESOURCES_CR 0x8B27
+/*do flush for the command buffer of a thread the context was previusly current for*/
+#define GL_FLUSH_ON_THREAD_SWITCH_CR 0x8B28
+/*report that the shared resource is used by this context, the parameter value is a texture name*/
+#define GL_RCUSAGE_TEXTURE_SET_CR 0x8B29
+/*report that the shared resource is no longer used by this context, the parameter value is a texture name*/
+#define GL_RCUSAGE_TEXTURE_CLEAR_CR 0x8B2A
+/*configures host to create windows initially hidden*/
+#define GL_HOST_WND_CREATED_HIDDEN_CR 0x8B2B
+
+typedef void (WINE_GLAPI *PGLFNCHROMIUMPARAMETERUCR)(GLenum param, GLint value);
+PGLFNCHROMIUMPARAMETERUCR pglChromiumParameteriCR;
+
+HGLRC (WINAPI *pVBoxCreateContext)(HDC, struct VBOXUHGSMI*) DECLSPEC_HIDDEN;
+void (WINAPI *pVBoxCtxChromiumParameteriCR)(HGLRC , GLenum , GLint) DECLSPEC_HIDDEN;
+void (WINAPI *pVBoxFlushToHost)(HGLRC) DECLSPEC_HIDDEN;
+GLint (WINAPI *pVBoxGetWindowId)(HDC) DECLSPEC_HIDDEN;
+GLint (WINAPI *pVBoxGetContextId)(HGLRC) DECLSPEC_HIDDEN;
+
+
+#define VBOX_USE_GL_FUNC(pfn) p##pfn = (void *)wglGetProcAddress(#pfn);
+
+# define VBOX_GL_FUNCS_GEN \
+ VBOX_USE_FUNC(VBoxCreateContext) \
+ VBOX_USE_FUNC(VBoxCtxChromiumParameteriCR) \
+ VBOX_USE_FUNC(VBoxFlushToHost) \
+ VBOX_USE_FUNC(VBoxGetWindowId) \
+ VBOX_USE_FUNC(VBoxGetContextId)
+
+# define VBOX_GL_EXT_FUNCS_GEN \
+ VBOX_USE_GL_FUNC(glChromiumParameteriCR)
+
+#endif
+
+#define GL_EXT_FUNCS_GEN \
+ /* GL_APPLE_fence */ \
+ USE_GL_FUNC(glDeleteFencesAPPLE) \
+ USE_GL_FUNC(glFinishFenceAPPLE) \
+ USE_GL_FUNC(glFinishObjectAPPLE) \
+ USE_GL_FUNC(glGenFencesAPPLE) \
+ USE_GL_FUNC(glIsFenceAPPLE) \
+ USE_GL_FUNC(glSetFenceAPPLE) \
+ USE_GL_FUNC(glTestFenceAPPLE) \
+ USE_GL_FUNC(glTestObjectAPPLE) \
+ /* GL_APPLE_flush_buffer_range */ \
+ USE_GL_FUNC(glBufferParameteriAPPLE) \
+ USE_GL_FUNC(glFlushMappedBufferRangeAPPLE) \
+ /* GL_ARB_color_buffer_float */ \
+ USE_GL_FUNC(glClampColorARB) \
+ /* GL_ARB_debug_output */ \
+ USE_GL_FUNC(glDebugMessageCallbackARB) \
+ USE_GL_FUNC(glDebugMessageControlARB) \
+ USE_GL_FUNC(glDebugMessageInsertARB) \
+ USE_GL_FUNC(glGetDebugMessageLogARB) \
+ /* GL_ARB_draw_buffers */ \
+ USE_GL_FUNC(glDrawBuffersARB) \
+ /* GL_ARB_draw_elements_base_vertex */ \
+ USE_GL_FUNC(glDrawElementsBaseVertex) \
+ USE_GL_FUNC(glDrawElementsInstancedBaseVertex) \
+ USE_GL_FUNC(glDrawRangeElementsBaseVertex) \
+ USE_GL_FUNC(glMultiDrawElementsBaseVertex) \
+ /* GL_ARB_draw_instanced */ \
+ USE_GL_FUNC(glDrawArraysInstancedARB) \
+ USE_GL_FUNC(glDrawElementsInstancedARB) \
+ /* GL_ARB_framebuffer_object */ \
+ USE_GL_FUNC(glBindFramebuffer) \
+ USE_GL_FUNC(glBindRenderbuffer) \
+ USE_GL_FUNC(glBlitFramebuffer) \
+ USE_GL_FUNC(glCheckFramebufferStatus) \
+ USE_GL_FUNC(glDeleteFramebuffers) \
+ USE_GL_FUNC(glDeleteRenderbuffers) \
+ USE_GL_FUNC(glFramebufferRenderbuffer) \
+ USE_GL_FUNC(glFramebufferTexture1D) \
+ USE_GL_FUNC(glFramebufferTexture2D) \
+ USE_GL_FUNC(glFramebufferTexture3D) \
+ USE_GL_FUNC(glFramebufferTextureLayer) \
+ USE_GL_FUNC(glGenFramebuffers) \
+ USE_GL_FUNC(glGenRenderbuffers) \
+ USE_GL_FUNC(glGenerateMipmap) \
+ USE_GL_FUNC(glGetFramebufferAttachmentParameteriv) \
+ USE_GL_FUNC(glGetRenderbufferParameteriv) \
+ USE_GL_FUNC(glIsFramebuffer) \
+ USE_GL_FUNC(glIsRenderbuffer) \
+ USE_GL_FUNC(glRenderbufferStorage) \
+ USE_GL_FUNC(glRenderbufferStorageMultisample) \
+ /* GL_ARB_geometry_shader4 */ \
+ USE_GL_FUNC(glFramebufferTextureARB) \
+ USE_GL_FUNC(glFramebufferTextureFaceARB) \
+ USE_GL_FUNC(glFramebufferTextureLayerARB) \
+ USE_GL_FUNC(glProgramParameteriARB) \
+ /* GL_ARB_instanced_arrays */ \
+ USE_GL_FUNC(glVertexAttribDivisorARB) \
+ /* GL_ARB_internalformat_query */ \
+ USE_GL_FUNC(glGetInternalformativ) \
+ /* GL_ARB_internalformat_query2 */ \
+ USE_GL_FUNC(glGetInternalformati64v) \
+ /* GL_ARB_map_buffer_range */ \
+ USE_GL_FUNC(glFlushMappedBufferRange) \
+ USE_GL_FUNC(glMapBufferRange) \
+ /* GL_ARB_multisample */ \
+ USE_GL_FUNC(glSampleCoverageARB) \
+ /* GL_ARB_multitexture */ \
+ USE_GL_FUNC(glActiveTextureARB) \
+ USE_GL_FUNC(glClientActiveTextureARB) \
+ USE_GL_FUNC(glMultiTexCoord1fARB) \
+ USE_GL_FUNC(glMultiTexCoord1fvARB) \
+ USE_GL_FUNC(glMultiTexCoord2fARB) \
+ USE_GL_FUNC(glMultiTexCoord2fvARB) \
+ USE_GL_FUNC(glMultiTexCoord2svARB) \
+ USE_GL_FUNC(glMultiTexCoord3fARB) \
+ USE_GL_FUNC(glMultiTexCoord3fvARB) \
+ USE_GL_FUNC(glMultiTexCoord4fARB) \
+ USE_GL_FUNC(glMultiTexCoord4fvARB) \
+ USE_GL_FUNC(glMultiTexCoord4svARB) \
+ /* GL_ARB_occlusion_query */ \
+ USE_GL_FUNC(glBeginQueryARB) \
+ USE_GL_FUNC(glDeleteQueriesARB) \
+ USE_GL_FUNC(glEndQueryARB) \
+ USE_GL_FUNC(glGenQueriesARB) \
+ USE_GL_FUNC(glGetQueryivARB) \
+ USE_GL_FUNC(glGetQueryObjectivARB) \
+ USE_GL_FUNC(glGetQueryObjectuivARB) \
+ USE_GL_FUNC(glIsQueryARB) \
+ /* GL_ARB_point_parameters */ \
+ USE_GL_FUNC(glPointParameterfARB) \
+ USE_GL_FUNC(glPointParameterfvARB) \
+ /* GL_ARB_provoking_vertex */ \
+ USE_GL_FUNC(glProvokingVertex) \
+ /* GL_ARB_shader_objects */ \
+ USE_GL_FUNC(glAttachObjectARB) \
+ USE_GL_FUNC(glBindAttribLocationARB) \
+ USE_GL_FUNC(glCompileShaderARB) \
+ USE_GL_FUNC(glCreateProgramObjectARB) \
+ USE_GL_FUNC(glCreateShaderObjectARB) \
+ USE_GL_FUNC(glDeleteObjectARB) \
+ USE_GL_FUNC(glDetachObjectARB) \
+ USE_GL_FUNC(glGetActiveUniformARB) \
+ USE_GL_FUNC(glGetAttachedObjectsARB) \
+ USE_GL_FUNC(glGetAttribLocationARB) \
+ USE_GL_FUNC(glGetHandleARB) \
+ USE_GL_FUNC(glGetInfoLogARB) \
+ USE_GL_FUNC(glGetObjectParameterfvARB) \
+ USE_GL_FUNC(glGetObjectParameterivARB) \
+ USE_GL_FUNC(glGetShaderSourceARB) \
+ USE_GL_FUNC(glGetUniformLocationARB) \
+ USE_GL_FUNC(glGetUniformfvARB) \
+ USE_GL_FUNC(glGetUniformivARB) \
+ USE_GL_FUNC(glLinkProgramARB) \
+ USE_GL_FUNC(glShaderSourceARB) \
+ USE_GL_FUNC(glUniform1fARB) \
+ USE_GL_FUNC(glUniform1fvARB) \
+ USE_GL_FUNC(glUniform1iARB) \
+ USE_GL_FUNC(glUniform1ivARB) \
+ USE_GL_FUNC(glUniform2fARB) \
+ USE_GL_FUNC(glUniform2fvARB) \
+ USE_GL_FUNC(glUniform2iARB) \
+ USE_GL_FUNC(glUniform2ivARB) \
+ USE_GL_FUNC(glUniform3fARB) \
+ USE_GL_FUNC(glUniform3fvARB) \
+ USE_GL_FUNC(glUniform3iARB) \
+ USE_GL_FUNC(glUniform3ivARB) \
+ USE_GL_FUNC(glUniform4fARB) \
+ USE_GL_FUNC(glUniform4fvARB) \
+ USE_GL_FUNC(glUniform4iARB) \
+ USE_GL_FUNC(glUniform4ivARB) \
+ USE_GL_FUNC(glUniformMatrix2fvARB) \
+ USE_GL_FUNC(glUniformMatrix3fvARB) \
+ USE_GL_FUNC(glUniformMatrix4fvARB) \
+ USE_GL_FUNC(glUseProgramObjectARB) \
+ USE_GL_FUNC(glValidateProgramARB) \
+ /* GL_ARB_sync */ \
+ USE_GL_FUNC(glClientWaitSync) \
+ USE_GL_FUNC(glDeleteSync) \
+ USE_GL_FUNC(glFenceSync) \
+ USE_GL_FUNC(glGetInteger64v) \
+ USE_GL_FUNC(glGetSynciv) \
+ USE_GL_FUNC(glIsSync) \
+ USE_GL_FUNC(glWaitSync) \
+ /* GL_ARB_texture_compression */ \
+ USE_GL_FUNC(glCompressedTexImage2DARB) \
+ USE_GL_FUNC(glCompressedTexImage3DARB) \
+ USE_GL_FUNC(glCompressedTexSubImage2DARB) \
+ USE_GL_FUNC(glCompressedTexSubImage3DARB) \
+ USE_GL_FUNC(glGetCompressedTexImageARB) \
+ /* GL_ARB_vertex_blend */ \
+ USE_GL_FUNC(glVertexBlendARB) \
+ USE_GL_FUNC(glWeightPointerARB) \
+ USE_GL_FUNC(glWeightbvARB) \
+ USE_GL_FUNC(glWeightdvARB) \
+ USE_GL_FUNC(glWeightfvARB) \
+ USE_GL_FUNC(glWeightivARB) \
+ USE_GL_FUNC(glWeightsvARB) \
+ USE_GL_FUNC(glWeightubvARB) \
+ USE_GL_FUNC(glWeightuivARB) \
+ USE_GL_FUNC(glWeightusvARB) \
+ /* GL_ARB_vertex_buffer_object */ \
+ USE_GL_FUNC(glBindBufferARB) \
+ USE_GL_FUNC(glBufferDataARB) \
+ USE_GL_FUNC(glBufferSubDataARB) \
+ USE_GL_FUNC(glDeleteBuffersARB) \
+ USE_GL_FUNC(glGenBuffersARB) \
+ USE_GL_FUNC(glGetBufferParameterivARB) \
+ USE_GL_FUNC(glGetBufferPointervARB) \
+ USE_GL_FUNC(glGetBufferSubDataARB) \
+ USE_GL_FUNC(glIsBufferARB) \
+ USE_GL_FUNC(glMapBufferARB) \
+ USE_GL_FUNC(glUnmapBufferARB) \
+ /* GL_ARB_vertex_program */ \
+ USE_GL_FUNC(glBindProgramARB) \
+ USE_GL_FUNC(glDeleteProgramsARB) \
+ USE_GL_FUNC(glDisableVertexAttribArrayARB) \
+ USE_GL_FUNC(glEnableVertexAttribArrayARB) \
+ USE_GL_FUNC(glGenProgramsARB) \
+ USE_GL_FUNC(glGetProgramivARB) \
+ USE_GL_FUNC(glProgramEnvParameter4fvARB) \
+ USE_GL_FUNC(glProgramLocalParameter4fvARB) \
+ USE_GL_FUNC(glProgramStringARB) \
+ USE_GL_FUNC(glVertexAttrib1dARB) \
+ USE_GL_FUNC(glVertexAttrib1dvARB) \
+ USE_GL_FUNC(glVertexAttrib1fARB) \
+ USE_GL_FUNC(glVertexAttrib1fvARB) \
+ USE_GL_FUNC(glVertexAttrib1sARB) \
+ USE_GL_FUNC(glVertexAttrib1svARB) \
+ USE_GL_FUNC(glVertexAttrib2dARB) \
+ USE_GL_FUNC(glVertexAttrib2dvARB) \
+ USE_GL_FUNC(glVertexAttrib2fARB) \
+ USE_GL_FUNC(glVertexAttrib2fvARB) \
+ USE_GL_FUNC(glVertexAttrib2sARB) \
+ USE_GL_FUNC(glVertexAttrib2svARB) \
+ USE_GL_FUNC(glVertexAttrib3dARB) \
+ USE_GL_FUNC(glVertexAttrib3dvARB) \
+ USE_GL_FUNC(glVertexAttrib3fARB) \
+ USE_GL_FUNC(glVertexAttrib3fvARB) \
+ USE_GL_FUNC(glVertexAttrib3sARB) \
+ USE_GL_FUNC(glVertexAttrib3svARB) \
+ USE_GL_FUNC(glVertexAttrib4NbvARB) \
+ USE_GL_FUNC(glVertexAttrib4NivARB) \
+ USE_GL_FUNC(glVertexAttrib4NsvARB) \
+ USE_GL_FUNC(glVertexAttrib4NubARB) \
+ USE_GL_FUNC(glVertexAttrib4NubvARB) \
+ USE_GL_FUNC(glVertexAttrib4NuivARB) \
+ USE_GL_FUNC(glVertexAttrib4NusvARB) \
+ USE_GL_FUNC(glVertexAttrib4bvARB) \
+ USE_GL_FUNC(glVertexAttrib4dARB) \
+ USE_GL_FUNC(glVertexAttrib4dvARB) \
+ USE_GL_FUNC(glVertexAttrib4fARB) \
+ USE_GL_FUNC(glVertexAttrib4fvARB) \
+ USE_GL_FUNC(glVertexAttrib4ivARB) \
+ USE_GL_FUNC(glVertexAttrib4sARB) \
+ USE_GL_FUNC(glVertexAttrib4svARB) \
+ USE_GL_FUNC(glVertexAttrib4ubvARB) \
+ USE_GL_FUNC(glVertexAttrib4uivARB) \
+ USE_GL_FUNC(glVertexAttrib4usvARB) \
+ USE_GL_FUNC(glVertexAttribPointerARB) \
+ /* GL_ATI_fragment_shader */ \
+ USE_GL_FUNC(glAlphaFragmentOp1ATI) \
+ USE_GL_FUNC(glAlphaFragmentOp2ATI) \
+ USE_GL_FUNC(glAlphaFragmentOp3ATI) \
+ USE_GL_FUNC(glBeginFragmentShaderATI) \
+ USE_GL_FUNC(glBindFragmentShaderATI) \
+ USE_GL_FUNC(glColorFragmentOp1ATI) \
+ USE_GL_FUNC(glColorFragmentOp2ATI) \
+ USE_GL_FUNC(glColorFragmentOp3ATI) \
+ USE_GL_FUNC(glDeleteFragmentShaderATI) \
+ USE_GL_FUNC(glEndFragmentShaderATI) \
+ USE_GL_FUNC(glGenFragmentShadersATI) \
+ USE_GL_FUNC(glPassTexCoordATI) \
+ USE_GL_FUNC(glSampleMapATI) \
+ USE_GL_FUNC(glSetFragmentShaderConstantATI) \
+ /* GL_ATI_separate_stencil */ \
+ USE_GL_FUNC(glStencilOpSeparateATI) \
+ USE_GL_FUNC(glStencilFuncSeparateATI) \
+ /* GL_EXT_blend_color */ \
+ USE_GL_FUNC(glBlendColorEXT) \
+ /* GL_EXT_blend_equation_separate */ \
+ USE_GL_FUNC(glBlendFuncSeparateEXT) \
+ /* GL_EXT_blend_func_separate */ \
+ USE_GL_FUNC(glBlendEquationSeparateEXT) \
+ /* GL_EXT_blend_minmax */ \
+ USE_GL_FUNC(glBlendEquationEXT) \
+ /* GL_EXT_depth_bounds_test */ \
+ USE_GL_FUNC(glDepthBoundsEXT) \
+ /* GL_EXT_draw_buffers2 */ \
+ USE_GL_FUNC(glColorMaskIndexedEXT) \
+ USE_GL_FUNC(glDisableIndexedEXT) \
+ USE_GL_FUNC(glEnableIndexedEXT) \
+ USE_GL_FUNC(glGetBooleanIndexedvEXT) \
+ USE_GL_FUNC(glGetIntegerIndexedvEXT) \
+ USE_GL_FUNC(glIsEnabledIndexedEXT) \
+ /* GL_EXT_fog_coord */ \
+ USE_GL_FUNC(glFogCoordPointerEXT) \
+ USE_GL_FUNC(glFogCoorddEXT) \
+ USE_GL_FUNC(glFogCoorddvEXT) \
+ USE_GL_FUNC(glFogCoordfEXT) \
+ USE_GL_FUNC(glFogCoordfvEXT) \
+ /* GL_EXT_framebuffer_blit */ \
+ USE_GL_FUNC(glBlitFramebufferEXT) \
+ /* GL_EXT_framebuffer_multisample */ \
+ USE_GL_FUNC(glRenderbufferStorageMultisampleEXT) \
+ /* GL_EXT_framebuffer_object */ \
+ USE_GL_FUNC(glBindFramebufferEXT) \
+ USE_GL_FUNC(glBindRenderbufferEXT) \
+ USE_GL_FUNC(glCheckFramebufferStatusEXT) \
+ USE_GL_FUNC(glDeleteFramebuffersEXT) \
+ USE_GL_FUNC(glDeleteRenderbuffersEXT) \
+ USE_GL_FUNC(glFramebufferRenderbufferEXT) \
+ USE_GL_FUNC(glFramebufferTexture1DEXT) \
+ USE_GL_FUNC(glFramebufferTexture2DEXT) \
+ USE_GL_FUNC(glFramebufferTexture3DEXT) \
+ USE_GL_FUNC(glGenFramebuffersEXT) \
+ USE_GL_FUNC(glGenRenderbuffersEXT) \
+ USE_GL_FUNC(glGenerateMipmapEXT) \
+ USE_GL_FUNC(glGetFramebufferAttachmentParameterivEXT) \
+ USE_GL_FUNC(glGetRenderbufferParameterivEXT) \
+ USE_GL_FUNC(glIsFramebufferEXT) \
+ USE_GL_FUNC(glIsRenderbufferEXT) \
+ USE_GL_FUNC(glRenderbufferStorageEXT) \
+ /* GL_EXT_gpu_program_parameters */ \
+ USE_GL_FUNC(glProgramEnvParameters4fvEXT) \
+ USE_GL_FUNC(glProgramLocalParameters4fvEXT) \
+ /* GL_EXT_gpu_shader4 */\
+ USE_GL_FUNC(glBindFragDataLocationEXT) \
+ USE_GL_FUNC(glGetFragDataLocationEXT) \
+ USE_GL_FUNC(glGetUniformuivEXT) \
+ USE_GL_FUNC(glGetVertexAttribIivEXT) \
+ USE_GL_FUNC(glGetVertexAttribIuivEXT) \
+ USE_GL_FUNC(glUniform1uiEXT) \
+ USE_GL_FUNC(glUniform1uivEXT) \
+ USE_GL_FUNC(glUniform2uiEXT) \
+ USE_GL_FUNC(glUniform2uivEXT) \
+ USE_GL_FUNC(glUniform3uiEXT) \
+ USE_GL_FUNC(glUniform3uivEXT) \
+ USE_GL_FUNC(glUniform4uiEXT) \
+ USE_GL_FUNC(glUniform4uivEXT) \
+ USE_GL_FUNC(glVertexAttribI1iEXT) \
+ USE_GL_FUNC(glVertexAttribI1ivEXT) \
+ USE_GL_FUNC(glVertexAttribI1uiEXT) \
+ USE_GL_FUNC(glVertexAttribI1uivEXT) \
+ USE_GL_FUNC(glVertexAttribI2iEXT) \
+ USE_GL_FUNC(glVertexAttribI2ivEXT) \
+ USE_GL_FUNC(glVertexAttribI2uiEXT) \
+ USE_GL_FUNC(glVertexAttribI2uivEXT) \
+ USE_GL_FUNC(glVertexAttribI3iEXT) \
+ USE_GL_FUNC(glVertexAttribI3ivEXT) \
+ USE_GL_FUNC(glVertexAttribI3uiEXT) \
+ USE_GL_FUNC(glVertexAttribI3uivEXT) \
+ USE_GL_FUNC(glVertexAttribI4bvEXT) \
+ USE_GL_FUNC(glVertexAttribI4iEXT) \
+ USE_GL_FUNC(glVertexAttribI4ivEXT) \
+ USE_GL_FUNC(glVertexAttribI4svEXT) \
+ USE_GL_FUNC(glVertexAttribI4ubvEXT) \
+ USE_GL_FUNC(glVertexAttribI4uiEXT) \
+ USE_GL_FUNC(glVertexAttribI4uivEXT) \
+ USE_GL_FUNC(glVertexAttribI4usvEXT) \
+ USE_GL_FUNC(glVertexAttribIPointerEXT) \
+ /* GL_EXT_paletted_texture */ \
+ USE_GL_FUNC(glColorTableEXT) \
+ /* GL_EXT_point_parameters */ \
+ USE_GL_FUNC(glPointParameterfEXT) \
+ USE_GL_FUNC(glPointParameterfvEXT) \
+ /* GL_EXT_provoking_vertex */ \
+ USE_GL_FUNC(glProvokingVertexEXT) \
+ /* GL_EXT_secondary_color */ \
+ USE_GL_FUNC(glSecondaryColor3fEXT) \
+ USE_GL_FUNC(glSecondaryColor3fvEXT) \
+ USE_GL_FUNC(glSecondaryColor3ubEXT) \
+ USE_GL_FUNC(glSecondaryColor3ubvEXT) \
+ USE_GL_FUNC(glSecondaryColorPointerEXT) \
+ /* GL_EXT_stencil_two_side */ \
+ USE_GL_FUNC(glActiveStencilFaceEXT) \
+ /* GL_EXT_texture3D */ \
+ USE_GL_FUNC(glTexImage3D) \
+ USE_GL_FUNC(glTexImage3DEXT) \
+ USE_GL_FUNC(glTexSubImage3D) \
+ USE_GL_FUNC(glTexSubImage3DEXT) \
+ /* GL_NV_fence */ \
+ USE_GL_FUNC(glDeleteFencesNV) \
+ USE_GL_FUNC(glFinishFenceNV) \
+ USE_GL_FUNC(glGenFencesNV) \
+ USE_GL_FUNC(glGetFenceivNV) \
+ USE_GL_FUNC(glIsFenceNV) \
+ USE_GL_FUNC(glSetFenceNV) \
+ USE_GL_FUNC(glTestFenceNV) \
+ /* GL_NV_half_float */ \
+ USE_GL_FUNC(glColor3hNV) \
+ USE_GL_FUNC(glColor3hvNV) \
+ USE_GL_FUNC(glColor4hNV) \
+ USE_GL_FUNC(glColor4hvNV) \
+ USE_GL_FUNC(glFogCoordhNV) \
+ USE_GL_FUNC(glFogCoordhvNV) \
+ USE_GL_FUNC(glMultiTexCoord1hNV) \
+ USE_GL_FUNC(glMultiTexCoord1hvNV) \
+ USE_GL_FUNC(glMultiTexCoord2hNV) \
+ USE_GL_FUNC(glMultiTexCoord2hvNV) \
+ USE_GL_FUNC(glMultiTexCoord3hNV) \
+ USE_GL_FUNC(glMultiTexCoord3hvNV) \
+ USE_GL_FUNC(glMultiTexCoord4hNV) \
+ USE_GL_FUNC(glMultiTexCoord4hvNV) \
+ USE_GL_FUNC(glNormal3hNV) \
+ USE_GL_FUNC(glNormal3hvNV) \
+ USE_GL_FUNC(glSecondaryColor3hNV) \
+ USE_GL_FUNC(glSecondaryColor3hvNV) \
+ USE_GL_FUNC(glTexCoord1hNV) \
+ USE_GL_FUNC(glTexCoord1hvNV) \
+ USE_GL_FUNC(glTexCoord2hNV) \
+ USE_GL_FUNC(glTexCoord2hvNV) \
+ USE_GL_FUNC(glTexCoord3hNV) \
+ USE_GL_FUNC(glTexCoord3hvNV) \
+ USE_GL_FUNC(glTexCoord4hNV) \
+ USE_GL_FUNC(glTexCoord4hvNV) \
+ USE_GL_FUNC(glVertex2hNV) \
+ USE_GL_FUNC(glVertex2hvNV) \
+ USE_GL_FUNC(glVertex3hNV) \
+ USE_GL_FUNC(glVertex3hvNV) \
+ USE_GL_FUNC(glVertex4hNV) \
+ USE_GL_FUNC(glVertex4hvNV) \
+ USE_GL_FUNC(glVertexAttrib1hNV) \
+ USE_GL_FUNC(glVertexAttrib1hvNV) \
+ USE_GL_FUNC(glVertexAttrib2hNV) \
+ USE_GL_FUNC(glVertexAttrib2hvNV) \
+ USE_GL_FUNC(glVertexAttrib3hNV) \
+ USE_GL_FUNC(glVertexAttrib3hvNV) \
+ USE_GL_FUNC(glVertexAttrib4hNV) \
+ USE_GL_FUNC(glVertexAttrib4hvNV) \
+ USE_GL_FUNC(glVertexAttribs1hvNV) \
+ USE_GL_FUNC(glVertexAttribs2hvNV) \
+ USE_GL_FUNC(glVertexAttribs3hvNV) \
+ USE_GL_FUNC(glVertexAttribs4hvNV) \
+ USE_GL_FUNC(glVertexWeighthNV) \
+ USE_GL_FUNC(glVertexWeighthvNV) \
+ /* GL_NV_point_sprite */ \
+ USE_GL_FUNC(glPointParameteri) \
+ USE_GL_FUNC(glPointParameteriNV) \
+ USE_GL_FUNC(glPointParameteriv) \
+ USE_GL_FUNC(glPointParameterivNV) \
+ /* GL_NV_register_combiners */ \
+ USE_GL_FUNC(glCombinerInputNV) \
+ USE_GL_FUNC(glCombinerOutputNV) \
+ USE_GL_FUNC(glCombinerParameterfNV) \
+ USE_GL_FUNC(glCombinerParameterfvNV) \
+ USE_GL_FUNC(glCombinerParameteriNV) \
+ USE_GL_FUNC(glCombinerParameterivNV) \
+ USE_GL_FUNC(glFinalCombinerInputNV) \
+ /* WGL extensions */ \
+ USE_GL_FUNC(wglChoosePixelFormatARB) \
+ USE_GL_FUNC(wglGetExtensionsStringARB) \
+ USE_GL_FUNC(wglGetPixelFormatAttribfvARB) \
+ USE_GL_FUNC(wglGetPixelFormatAttribivARB) \
+ USE_GL_FUNC(wglSetPixelFormatWINE) \
+ USE_GL_FUNC(wglSwapIntervalEXT) \
+ /* #ifdef VBOX */ \
+ VBOX_GL_EXT_FUNCS_GEN \
+ /* #endif */
+
+#endif /* __WINE_WINED3D_GL */
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d_main.c b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d_main.c
new file mode 100644
index 00000000..6771b35e
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d_main.c
@@ -0,0 +1,584 @@
+/*
+ * Direct3D wine internal interface main
+ *
+ * Copyright 2002-2003 The wine-d3d team
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2004 Jason Edmeades
+ * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
+ * Copyright 2009 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "initguid.h"
+#include "wined3d_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(winediag);
+
+#ifndef VBOX_WITH_WDDM
+struct wined3d_wndproc
+{
+ HWND window;
+ BOOL unicode;
+ WNDPROC proc;
+ struct wined3d_device *device;
+};
+
+struct wined3d_wndproc_table
+{
+ struct wined3d_wndproc *entries;
+ unsigned int count;
+ unsigned int size;
+};
+
+static struct wined3d_wndproc_table wndproc_table;
+
+static CRITICAL_SECTION wined3d_cs;
+static CRITICAL_SECTION_DEBUG wined3d_cs_debug =
+{
+ 0, 0, &wined3d_cs,
+ {&wined3d_cs_debug.ProcessLocksList,
+ &wined3d_cs_debug.ProcessLocksList},
+ 0, 0, {(DWORD_PTR)(__FILE__ ": wined3d_cs")}
+};
+static CRITICAL_SECTION wined3d_cs = {&wined3d_cs_debug, -1, 0, 0, 0, 0};
+
+static CRITICAL_SECTION wined3d_wndproc_cs;
+static CRITICAL_SECTION_DEBUG wined3d_wndproc_cs_debug =
+{
+ 0, 0, &wined3d_wndproc_cs,
+ {&wined3d_wndproc_cs_debug.ProcessLocksList,
+ &wined3d_wndproc_cs_debug.ProcessLocksList},
+ 0, 0, {(DWORD_PTR)(__FILE__ ": wined3d_wndproc_cs")}
+};
+static CRITICAL_SECTION wined3d_wndproc_cs = {&wined3d_wndproc_cs_debug, -1, 0, 0, 0, 0};
+#endif
+
+/* When updating default value here, make sure to update winecfg as well,
+ * where appropriate. */
+struct wined3d_settings wined3d_settings =
+{
+ TRUE, /* Use of GLSL enabled by default */
+ ORM_FBO, /* Use FBOs to do offscreen rendering */
+ RTL_READTEX, /* Default render target locking method */
+ PCI_VENDOR_NONE,/* PCI Vendor ID */
+ PCI_DEVICE_NONE,/* PCI Device ID */
+ 0, /* The default of memory is set in init_driver_info */
+ NULL, /* No wine logo by default */
+ TRUE, /* Multisampling enabled by default. */
+ FALSE, /* No strict draw ordering. */
+ TRUE, /* Don't try to render onscreen by default. */
+ ~0U, /* No VS shader model limit by default. */
+ ~0U, /* No GS shader model limit by default. */
+ ~0U, /* No PS shader model limit by default. */
+ FALSE, /* 3D support enabled by default. */
+};
+
+/* Do not call while under the GL lock. */
+struct wined3d * CDECL wined3d_create(UINT version, DWORD flags)
+{
+ struct wined3d *object;
+ HRESULT hr;
+
+#ifdef VBOX
+ hr = VBoxExtCheckInit();
+ if (FAILED(hr))
+ {
+ ERR("VBoxExtCheckInit failed, hr (0x%x)\n", hr);
+ return NULL;
+ }
+#endif
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET(struct wined3d, adapters[1]));
+ if (!object)
+ {
+ ERR("Failed to allocate wined3d object memory.\n");
+#ifdef VBOX
+ VBoxExtCheckTerm();
+#endif
+ return NULL;
+ }
+
+ if (version == 7 && wined3d_settings.no_3d)
+ flags |= WINED3D_NO3D;
+
+ hr = wined3d_init(object, version, flags);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize wined3d object, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+#ifdef VBOX
+ VBoxExtCheckTerm();
+#endif
+ return NULL;
+ }
+
+ TRACE("Created wined3d object %p for d3d%d support.\n", object, version);
+
+ return object;
+}
+
+static DWORD get_config_key(HKEY defkey, HKEY appkey, const char *name, char *buffer, DWORD size)
+{
+ if (appkey && !RegQueryValueExA(appkey, name, 0, NULL, (BYTE *)buffer, &size)) return 0;
+ if (defkey && !RegQueryValueExA(defkey, name, 0, NULL, (BYTE *)buffer, &size)) return 0;
+ return ERROR_FILE_NOT_FOUND;
+}
+
+static DWORD get_config_key_dword(HKEY defkey, HKEY appkey, const char *name, DWORD *data)
+{
+ DWORD type;
+ DWORD size = sizeof(DWORD);
+ if (appkey && !RegQueryValueExA(appkey, name, 0, &type, (BYTE *)data, &size) && (type == REG_DWORD)) return 0;
+ if (defkey && !RegQueryValueExA(defkey, name, 0, &type, (BYTE *)data, &size) && (type == REG_DWORD)) return 0;
+ return ERROR_FILE_NOT_FOUND;
+}
+
+static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
+{
+ DWORD wined3d_context_tls_idx;
+ char buffer[MAX_PATH+10];
+ DWORD size = sizeof(buffer);
+ HKEY hkey = 0;
+ HKEY appkey = 0;
+ DWORD len, tmpvalue;
+ WNDCLASSA wc;
+#ifdef VBOX
+# ifndef VBOX_WITH_WDDM
+ InitializeCriticalSection(&wined3d_cs);
+ InitializeCriticalSection(&wined3d_wndproc_cs);
+# endif
+#endif
+
+ wined3d_context_tls_idx = TlsAlloc();
+ if (wined3d_context_tls_idx == TLS_OUT_OF_INDEXES)
+ {
+ DWORD err = GetLastError();
+ ERR("Failed to allocate context TLS index, err %#x.\n", err);
+ return FALSE;
+ }
+ context_set_tls_idx(wined3d_context_tls_idx);
+
+ /* We need our own window class for a fake window which we use to retrieve GL capabilities */
+ /* We might need CS_OWNDC in the future if we notice strange things on Windows.
+ * Various articles/posts about OpenGL problems on Windows recommend this. */
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = DefWindowProcA;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = hInstDLL;
+ wc.hIcon = LoadIconA(NULL, (LPCSTR)IDI_WINLOGO);
+ wc.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_ARROW);
+ wc.hbrBackground = NULL;
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = WINED3D_OPENGL_WINDOW_CLASS_NAME;
+
+ if (!RegisterClassA(&wc))
+ {
+ ERR("Failed to register window class 'WineD3D_OpenGL'!\n");
+ if (!TlsFree(wined3d_context_tls_idx))
+ {
+ DWORD err = GetLastError();
+ ERR("Failed to free context TLS index, err %#x.\n", err);
+ }
+ return FALSE;
+ }
+
+ DisableThreadLibraryCalls(hInstDLL);
+
+ /* @@ Wine registry key: HKCU\Software\Wine\Direct3D */
+ if ( RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Direct3D", &hkey ) ) hkey = 0;
+
+ len = GetModuleFileNameA( 0, buffer, MAX_PATH );
+ if (len && len < MAX_PATH)
+ {
+ HKEY tmpkey;
+ /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\Direct3D */
+ if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
+ {
+ char *p, *appname = buffer;
+ if ((p = strrchr( appname, '/' ))) appname = p + 1;
+ if ((p = strrchr( appname, '\\' ))) appname = p + 1;
+ strcat( appname, "\\Direct3D" );
+ TRACE("appname = [%s]\n", appname);
+ if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
+ RegCloseKey( tmpkey );
+ }
+ }
+
+ if (hkey || appkey)
+ {
+ if ( !get_config_key( hkey, appkey, "UseGLSL", buffer, size) )
+ {
+ if (!strcmp(buffer,"disabled"))
+ {
+ ERR_(winediag)("The GLSL shader backend has been disabled. You get to keep all the pieces if it breaks.\n");
+ TRACE("Use of GL Shading Language disabled\n");
+ wined3d_settings.glslRequested = FALSE;
+ }
+ }
+ if ( !get_config_key( hkey, appkey, "OffscreenRenderingMode", buffer, size) )
+ {
+ if (!strcmp(buffer,"backbuffer"))
+ {
+ TRACE("Using the backbuffer for offscreen rendering\n");
+ wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
+ }
+ else if (!strcmp(buffer,"fbo"))
+ {
+ TRACE("Using FBOs for offscreen rendering\n");
+ wined3d_settings.offscreen_rendering_mode = ORM_FBO;
+ }
+ }
+ if ( !get_config_key( hkey, appkey, "RenderTargetLockMode", buffer, size) )
+ {
+ if (!strcmp(buffer,"readdraw"))
+ {
+ TRACE("Using glReadPixels for render target reading and glDrawPixels for writing\n");
+ wined3d_settings.rendertargetlock_mode = RTL_READDRAW;
+ }
+ else if (!strcmp(buffer,"readtex"))
+ {
+ TRACE("Using glReadPixels for render target reading and textures for writing\n");
+ wined3d_settings.rendertargetlock_mode = RTL_READTEX;
+ }
+ }
+ if ( !get_config_key_dword( hkey, appkey, "VideoPciDeviceID", &tmpvalue) )
+ {
+ int pci_device_id = tmpvalue;
+
+ /* A pci device id is 16-bit */
+ if(pci_device_id > 0xffff)
+ {
+ ERR("Invalid value for VideoPciDeviceID. The value should be smaller or equal to 65535 or 0xffff\n");
+ }
+ else
+ {
+ TRACE("Using PCI Device ID %04x\n", pci_device_id);
+ wined3d_settings.pci_device_id = pci_device_id;
+ }
+ }
+ if ( !get_config_key_dword( hkey, appkey, "VideoPciVendorID", &tmpvalue) )
+ {
+ int pci_vendor_id = tmpvalue;
+
+ /* A pci device id is 16-bit */
+ if(pci_vendor_id > 0xffff)
+ {
+ ERR("Invalid value for VideoPciVendorID. The value should be smaller or equal to 65535 or 0xffff\n");
+ }
+ else
+ {
+ TRACE("Using PCI Vendor ID %04x\n", pci_vendor_id);
+ wined3d_settings.pci_vendor_id = pci_vendor_id;
+ }
+ }
+ if ( !get_config_key( hkey, appkey, "VideoMemorySize", buffer, size) )
+ {
+ int TmpVideoMemorySize = atoi(buffer);
+ if(TmpVideoMemorySize > 0)
+ {
+ wined3d_settings.emulated_textureram = TmpVideoMemorySize *1024*1024;
+ TRACE("Use %iMB = %d byte for emulated_textureram\n",
+ TmpVideoMemorySize,
+ wined3d_settings.emulated_textureram);
+ }
+ else
+ ERR("VideoMemorySize is %i but must be >0\n", TmpVideoMemorySize);
+ }
+ if ( !get_config_key( hkey, appkey, "WineLogo", buffer, size) )
+ {
+ size_t len = strlen(buffer) + 1;
+
+ wined3d_settings.logo = HeapAlloc(GetProcessHeap(), 0, len);
+ if (!wined3d_settings.logo) ERR("Failed to allocate logo path memory.\n");
+ else memcpy(wined3d_settings.logo, buffer, len);
+ }
+ if ( !get_config_key( hkey, appkey, "Multisampling", buffer, size) )
+ {
+ if (!strcmp(buffer, "disabled"))
+ {
+ TRACE("Multisampling disabled.\n");
+ wined3d_settings.allow_multisampling = FALSE;
+ }
+ }
+ if (!get_config_key(hkey, appkey, "StrictDrawOrdering", buffer, size)
+ && !strcmp(buffer,"enabled"))
+ {
+ TRACE("Enforcing strict draw ordering.\n");
+ wined3d_settings.strict_draw_ordering = TRUE;
+ }
+ if (!get_config_key(hkey, appkey, "AlwaysOffscreen", buffer, size)
+ && !strcmp(buffer,"disabled"))
+ {
+ TRACE("Not always rendering backbuffers offscreen.\n");
+ wined3d_settings.always_offscreen = FALSE;
+ }
+ if (!get_config_key_dword(hkey, appkey, "MaxShaderModelVS", &wined3d_settings.max_sm_vs))
+ TRACE("Limiting VS shader model to %u.\n", wined3d_settings.max_sm_vs);
+ if (!get_config_key_dword(hkey, appkey, "MaxShaderModelGS", &wined3d_settings.max_sm_gs))
+ TRACE("Limiting GS shader model to %u.\n", wined3d_settings.max_sm_gs);
+ if (!get_config_key_dword(hkey, appkey, "MaxShaderModelPS", &wined3d_settings.max_sm_ps))
+ TRACE("Limiting PS shader model to %u.\n", wined3d_settings.max_sm_ps);
+ if (!get_config_key(hkey, appkey, "DirectDrawRenderer", buffer, size)
+ && !strcmp(buffer, "gdi"))
+ {
+ TRACE("Disabling 3D support.\n");
+ wined3d_settings.no_3d = TRUE;
+ }
+ }
+
+ if (appkey) RegCloseKey( appkey );
+ if (hkey) RegCloseKey( hkey );
+
+ return TRUE;
+}
+
+static BOOL wined3d_dll_destroy(HINSTANCE hInstDLL)
+{
+ DWORD wined3d_context_tls_idx = context_get_tls_idx();
+#ifndef VBOX_WITH_WDDM
+ unsigned int i;
+#endif
+
+ if (!TlsFree(wined3d_context_tls_idx))
+ {
+ DWORD err = GetLastError();
+ ERR("Failed to free context TLS index, err %#x.\n", err);
+ }
+
+#ifndef VBOX_WITH_WDDM
+ for (i = 0; i < wndproc_table.count; ++i)
+ {
+ /* Trying to unregister these would be futile. These entries can only
+ * exist if either we skipped them in wined3d_unregister_window() due
+ * to the application replacing the wndproc after the entry was
+ * registered, or if the application still has an active wined3d
+ * device. In the latter case the application has bigger problems than
+ * these entries. */
+ WARN("Leftover wndproc table entry %p.\n", &wndproc_table.entries[i]);
+ }
+ HeapFree(GetProcessHeap(), 0, wndproc_table.entries);
+#endif
+
+ HeapFree(GetProcessHeap(), 0, wined3d_settings.logo);
+ UnregisterClassA(WINED3D_OPENGL_WINDOW_CLASS_NAME, hInstDLL);
+
+#ifndef VBOX_WITH_WDDM
+ DeleteCriticalSection(&wined3d_wndproc_cs);
+ DeleteCriticalSection(&wined3d_cs);
+#endif
+ return TRUE;
+}
+
+#ifndef VBOX_WITH_WDDM
+void WINAPI wined3d_mutex_lock(void)
+{
+ EnterCriticalSection(&wined3d_cs);
+}
+
+void WINAPI wined3d_mutex_unlock(void)
+{
+ LeaveCriticalSection(&wined3d_cs);
+}
+
+static void wined3d_wndproc_mutex_lock(void)
+{
+ EnterCriticalSection(&wined3d_wndproc_cs);
+}
+
+static void wined3d_wndproc_mutex_unlock(void)
+{
+ LeaveCriticalSection(&wined3d_wndproc_cs);
+}
+
+static struct wined3d_wndproc *wined3d_find_wndproc(HWND window)
+{
+ unsigned int i;
+
+ for (i = 0; i < wndproc_table.count; ++i)
+ {
+ if (wndproc_table.entries[i].window == window)
+ {
+ return &wndproc_table.entries[i];
+ }
+ }
+
+ return NULL;
+}
+
+static LRESULT CALLBACK wined3d_wndproc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
+{
+ struct wined3d_wndproc *entry;
+ struct wined3d_device *device;
+ BOOL unicode;
+ WNDPROC proc;
+
+ wined3d_wndproc_mutex_lock();
+ entry = wined3d_find_wndproc(window);
+
+ if (!entry)
+ {
+ wined3d_wndproc_mutex_unlock();
+ ERR("Window %p is not registered with wined3d.\n", window);
+ return DefWindowProcW(window, message, wparam, lparam);
+ }
+
+ device = entry->device;
+ unicode = entry->unicode;
+ proc = entry->proc;
+ wined3d_wndproc_mutex_unlock();
+
+ if (device)
+ return device_process_message(device, window, unicode, message, wparam, lparam, proc);
+ if (unicode)
+ return CallWindowProcW(proc, window, message, wparam, lparam);
+ return CallWindowProcA(proc, window, message, wparam, lparam);
+}
+
+BOOL wined3d_register_window(HWND window, struct wined3d_device *device)
+{
+ struct wined3d_wndproc *entry;
+
+ wined3d_wndproc_mutex_lock();
+
+ if (wined3d_find_wndproc(window))
+ {
+ wined3d_wndproc_mutex_unlock();
+ WARN("Window %p is already registered with wined3d.\n", window);
+ return TRUE;
+ }
+
+ if (wndproc_table.size == wndproc_table.count)
+ {
+ unsigned int new_size = max(1, wndproc_table.size * 2);
+ struct wined3d_wndproc *new_entries;
+
+ if (!wndproc_table.entries) new_entries = HeapAlloc(GetProcessHeap(), 0, new_size * sizeof(*new_entries));
+ else new_entries = HeapReAlloc(GetProcessHeap(), 0, wndproc_table.entries, new_size * sizeof(*new_entries));
+
+ if (!new_entries)
+ {
+ wined3d_wndproc_mutex_unlock();
+ ERR("Failed to grow table.\n");
+ return FALSE;
+ }
+
+ wndproc_table.entries = new_entries;
+ wndproc_table.size = new_size;
+ }
+
+ entry = &wndproc_table.entries[wndproc_table.count++];
+ entry->window = window;
+ entry->unicode = IsWindowUnicode(window);
+ /* Set a window proc that matches the window. Some applications (e.g. NoX)
+ * replace the window proc after we've set ours, and expect to be able to
+ * call the previous one (ours) directly, without using CallWindowProc(). */
+ if (entry->unicode)
+ entry->proc = (WNDPROC)SetWindowLongPtrW(window, GWLP_WNDPROC, (LONG_PTR)wined3d_wndproc);
+ else
+ entry->proc = (WNDPROC)SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)wined3d_wndproc);
+ entry->device = device;
+
+ wined3d_wndproc_mutex_unlock();
+
+ return TRUE;
+}
+
+void wined3d_unregister_window(HWND window)
+{
+ struct wined3d_wndproc *entry, *last;
+ LONG_PTR proc;
+
+ wined3d_wndproc_mutex_lock();
+
+ if (!(entry = wined3d_find_wndproc(window)))
+ {
+ wined3d_wndproc_mutex_unlock();
+ ERR("Window %p is not registered with wined3d.\n", window);
+ return;
+ }
+
+ if (entry->unicode)
+ {
+ proc = GetWindowLongPtrW(window, GWLP_WNDPROC);
+ if (proc != (LONG_PTR)wined3d_wndproc)
+ {
+ entry->device = NULL;
+ wined3d_wndproc_mutex_unlock();
+ WARN("Not unregistering window %p, window proc %#lx doesn't match wined3d window proc %p.\n",
+ window, proc, wined3d_wndproc);
+ return;
+ }
+
+ SetWindowLongPtrW(window, GWLP_WNDPROC, (LONG_PTR)entry->proc);
+ }
+ else
+ {
+ proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
+ if (proc != (LONG_PTR)wined3d_wndproc)
+ {
+ entry->device = NULL;
+ wined3d_wndproc_mutex_unlock();
+ WARN("Not unregistering window %p, window proc %#lx doesn't match wined3d window proc %p.\n",
+ window, proc, wined3d_wndproc);
+ return;
+ }
+
+ SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)entry->proc);
+ }
+
+ last = &wndproc_table.entries[--wndproc_table.count];
+ if (entry != last) *entry = *last;
+
+ wined3d_wndproc_mutex_unlock();
+}
+#endif
+/* At process attach */
+BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
+{
+ TRACE("WineD3D DLLMain Reason=%u\n", fdwReason);
+
+ switch (fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ return wined3d_dll_init(hInstDLL);
+
+ case DLL_PROCESS_DETACH:
+ if (lpv) break;
+ return wined3d_dll_destroy(hInstDLL);
+
+ case DLL_THREAD_DETACH:
+ if (!context_set_current(NULL))
+ {
+ ERR("Failed to clear current context.\n");
+ }
+ return TRUE;
+ }
+ return TRUE;
+}
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d_private.h b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d_private.h
new file mode 100644
index 00000000..35c9e41c
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3d_private.h
@@ -0,0 +1,3187 @@
+/*
+ * Direct3D wine internal private include file
+ *
+ * Copyright 2002-2003 The wine-d3d team
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2002-2003, 2004 Jason Edmeades
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2006-2011, 2013 Stefan Dösinger for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#ifndef __WINE_WINED3D_PRIVATE_H
+#define __WINE_WINED3D_PRIVATE_H
+
+#ifdef USE_WIN32_OPENGL
+#define WINE_GLAPI __stdcall
+#else
+#define WINE_GLAPI
+#endif
+
+#include <stdarg.h>
+#include <math.h>
+#include <limits.h>
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#define COBJMACROS
+#ifndef VBOX_WINE_WITHOUT_LIBWINE
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "wingdi.h"
+#include "winuser.h"
+#else
+#include <windows.h>
+#ifndef DUMMYUNIONNAME1
+# define DUMMYUNIONNAME1 u1
+#endif
+#endif
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+#ifndef VBOX_WINE_WITHOUT_LIBWINE
+#include "objbase.h"
+#endif
+#include "wine/wined3d.h"
+#include "wined3d_gl.h"
+#include "wine/list.h"
+#include "wine/rbtree.h"
+#include "wine/wgl_driver.h"
+
+#ifdef VBOX
+#include "vboxext.h"
+#endif
+
+#ifdef VBOX_WITH_WDDM
+# include "vboxsharedrc.h"
+#endif
+
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+# define VBoxTlsRefGetImpl(_tls) (TlsGetValue((DWORD)(_tls)))
+# define VBoxTlsRefSetImpl(_tls, _val) (TlsSetValue((DWORD)(_tls), (_val)))
+# define VBoxTlsRefAssertImpl Assert
+# include <VBox/VBoxVideo3D.h>
+#endif
+
+/* Driver quirks */
+#define WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT 0x00000001
+#define WINED3D_QUIRK_SET_TEXCOORD_W 0x00000002
+#define WINED3D_QUIRK_GLSL_CLIP_VARYING 0x00000004
+#define WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA 0x00000008
+#define WINED3D_QUIRK_NV_CLIP_BROKEN 0x00000010
+#define WINED3D_QUIRK_FBO_TEX_UPDATE 0x00000020
+#define WINED3D_QUIRK_BROKEN_RGBA16 0x00000040
+#define WINED3D_QUIRK_INFO_LOG_SPAM 0x00000080
+#define WINED3D_QUIRK_LIMITED_TEX_FILTERING 0x00000100
+#define WINED3D_QUIRK_BROKEN_ARB_FOG 0x00000200
+#ifdef VBOX_WITH_WINE_FIX_QUIRKS
+#define WINED3D_QUIRK_FULLSIZE_BLIT 0x02000000
+#define WINED3D_QUIRK_FORCE_BLIT 0x04000000
+#define WINED3D_QUIRK_NO_SHADER_V3 0x08000000
+#endif
+
+/* Texture format fixups */
+
+enum fixup_channel_source
+{
+ CHANNEL_SOURCE_ZERO = 0,
+ CHANNEL_SOURCE_ONE = 1,
+ CHANNEL_SOURCE_X = 2,
+ CHANNEL_SOURCE_Y = 3,
+ CHANNEL_SOURCE_Z = 4,
+ CHANNEL_SOURCE_W = 5,
+ CHANNEL_SOURCE_COMPLEX0 = 6,
+ CHANNEL_SOURCE_COMPLEX1 = 7,
+};
+
+enum complex_fixup
+{
+ COMPLEX_FIXUP_NONE = 0,
+ COMPLEX_FIXUP_YUY2 = 1,
+ COMPLEX_FIXUP_UYVY = 2,
+ COMPLEX_FIXUP_YV12 = 3,
+ COMPLEX_FIXUP_P8 = 4,
+};
+
+#include <pshpack2.h>
+struct color_fixup_desc
+{
+ unsigned x_sign_fixup : 1;
+ unsigned x_source : 3;
+ unsigned y_sign_fixup : 1;
+ unsigned y_source : 3;
+ unsigned z_sign_fixup : 1;
+ unsigned z_source : 3;
+ unsigned w_sign_fixup : 1;
+ unsigned w_source : 3;
+};
+#include <poppack.h>
+
+static const struct color_fixup_desc COLOR_FIXUP_IDENTITY =
+ {0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W};
+
+static inline struct color_fixup_desc create_color_fixup_desc(
+ int sign0, enum fixup_channel_source src0, int sign1, enum fixup_channel_source src1,
+ int sign2, enum fixup_channel_source src2, int sign3, enum fixup_channel_source src3)
+{
+ struct color_fixup_desc fixup =
+ {
+ sign0, src0,
+ sign1, src1,
+ sign2, src2,
+ sign3, src3,
+ };
+ return fixup;
+}
+
+static inline struct color_fixup_desc create_complex_fixup_desc(enum complex_fixup complex_fixup)
+{
+ struct color_fixup_desc fixup =
+ {
+ 0, complex_fixup & (1 << 0) ? CHANNEL_SOURCE_COMPLEX1 : CHANNEL_SOURCE_COMPLEX0,
+ 0, complex_fixup & (1 << 1) ? CHANNEL_SOURCE_COMPLEX1 : CHANNEL_SOURCE_COMPLEX0,
+ 0, complex_fixup & (1 << 2) ? CHANNEL_SOURCE_COMPLEX1 : CHANNEL_SOURCE_COMPLEX0,
+ 0, complex_fixup & (1 << 3) ? CHANNEL_SOURCE_COMPLEX1 : CHANNEL_SOURCE_COMPLEX0,
+ };
+ return fixup;
+}
+
+static inline BOOL is_identity_fixup(struct color_fixup_desc fixup)
+{
+ return !memcmp(&fixup, &COLOR_FIXUP_IDENTITY, sizeof(fixup));
+}
+
+static inline BOOL is_complex_fixup(struct color_fixup_desc fixup)
+{
+ return fixup.x_source == CHANNEL_SOURCE_COMPLEX0 || fixup.x_source == CHANNEL_SOURCE_COMPLEX1;
+}
+
+static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup)
+{
+ enum complex_fixup complex_fixup = 0;
+ if (fixup.x_source == CHANNEL_SOURCE_COMPLEX1) complex_fixup |= (1 << 0);
+ if (fixup.y_source == CHANNEL_SOURCE_COMPLEX1) complex_fixup |= (1 << 1);
+ if (fixup.z_source == CHANNEL_SOURCE_COMPLEX1) complex_fixup |= (1 << 2);
+ if (fixup.w_source == CHANNEL_SOURCE_COMPLEX1) complex_fixup |= (1 << 3);
+ return complex_fixup;
+}
+
+void *wined3d_rb_alloc(size_t size) DECLSPEC_HIDDEN;
+void *wined3d_rb_realloc(void *ptr, size_t size) DECLSPEC_HIDDEN;
+void wined3d_rb_free(void *ptr) DECLSPEC_HIDDEN;
+
+/* Device caps */
+#define MAX_PALETTES 65536
+#define MAX_STREAM_OUT 4
+#define MAX_STREAMS 16
+#define MAX_TEXTURES 8
+#define MAX_FRAGMENT_SAMPLERS 16
+#define MAX_VERTEX_SAMPLERS 4
+#define MAX_COMBINED_SAMPLERS (MAX_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS)
+#define MAX_ACTIVE_LIGHTS 8
+#define MAX_CLIPPLANES WINED3DMAXUSERCLIPPLANES
+#define MAX_CONSTANT_BUFFERS 15
+#define MAX_SAMPLER_OBJECTS 16
+
+struct min_lookup
+{
+ GLenum mip[WINED3D_TEXF_LINEAR + 1];
+};
+
+extern const struct min_lookup minMipLookup[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
+extern const struct min_lookup minMipLookup_noFilter[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
+extern const struct min_lookup minMipLookup_noMip[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
+extern const GLenum magLookup[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
+extern const GLenum magLookup_noFilter[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
+
+static inline GLenum wined3d_gl_mag_filter(const GLenum mag_lookup[], enum wined3d_texture_filter_type mag_filter)
+{
+ return mag_lookup[mag_filter];
+}
+
+static inline GLenum wined3d_gl_min_mip_filter(const struct min_lookup min_mip_lookup[],
+ enum wined3d_texture_filter_type min_filter, enum wined3d_texture_filter_type mip_filter)
+{
+ return min_mip_lookup[min_filter].mip[mip_filter];
+}
+
+/* float_16_to_32() and float_32_to_16() (see implementation in
+ * surface_base.c) convert 16 bit floats in the FLOAT16 data type
+ * to standard C floats and vice versa. They do not depend on the encoding
+ * of the C float, so they are platform independent, but slow. On x86 and
+ * other IEEE 754 compliant platforms the conversion can be accelerated by
+ * bit shifting the exponent and mantissa. There are also some SSE-based
+ * assembly routines out there.
+ *
+ * See GL_NV_half_float for a reference of the FLOAT16 / GL_HALF format
+ */
+static inline float float_16_to_32(const unsigned short *in)
+{
+ const unsigned short s = ((*in) & 0x8000);
+ const unsigned short e = ((*in) & 0x7c00) >> 10;
+ const unsigned short m = (*in) & 0x3ff;
+ const float sgn = (s ? -1.0f : 1.0f);
+
+ if(e == 0) {
+ if(m == 0) return sgn * 0.0f; /* +0.0 or -0.0 */
+ else return sgn * powf(2, -14.0f) * ((float)m / 1024.0f);
+ } else if(e < 31) {
+ return sgn * powf(2, (float)e - 15.0f) * (1.0f + ((float)m / 1024.0f));
+ } else {
+ if(m == 0) return sgn * INFINITY;
+ else return NAN;
+ }
+}
+
+static inline float float_24_to_32(DWORD in)
+{
+ const float sgn = in & 0x800000 ? -1.0f : 1.0f;
+ const unsigned short e = (in & 0x780000) >> 19;
+ const unsigned int m = in & 0x7ffff;
+
+ if (e == 0)
+ {
+ if (m == 0) return sgn * 0.0f; /* +0.0 or -0.0 */
+ else return sgn * powf(2, -6.0f) * ((float)m / 524288.0f);
+ }
+ else if (e < 15)
+ {
+ return sgn * powf(2, (float)e - 7.0f) * (1.0f + ((float)m / 524288.0f));
+ }
+ else
+ {
+ if (m == 0) return sgn * INFINITY;
+ else return NAN;
+ }
+}
+
+#define ORM_BACKBUFFER 0
+#define ORM_FBO 1
+
+#define RTL_READDRAW 1
+#define RTL_READTEX 2
+
+#define PCI_VENDOR_NONE 0xffff /* e.g. 0x8086 for Intel and 0x10de for Nvidia */
+#define PCI_DEVICE_NONE 0xffff /* e.g. 0x14f for a Geforce6200 */
+
+/* NOTE: When adding fields to this structure, make sure to update the default
+ * values in wined3d_main.c as well. */
+struct wined3d_settings
+{
+ /* Ideally, we don't want the user to have to request GLSL. If the
+ * hardware supports GLSL, we should use it. However, until it's fully
+ * implemented, we'll leave it as a registry setting for developers. */
+ BOOL glslRequested;
+ int offscreen_rendering_mode;
+ int rendertargetlock_mode;
+ unsigned short pci_vendor_id;
+ unsigned short pci_device_id;
+ /* Memory tracking and object counting. */
+ unsigned int emulated_textureram;
+ char *logo;
+ int allow_multisampling;
+ BOOL strict_draw_ordering;
+ BOOL always_offscreen;
+ unsigned int max_sm_vs;
+ unsigned int max_sm_gs;
+ unsigned int max_sm_ps;
+ BOOL no_3d;
+};
+
+extern struct wined3d_settings wined3d_settings DECLSPEC_HIDDEN;
+
+enum wined3d_sampler_texture_type
+{
+ WINED3DSTT_UNKNOWN = 0,
+ WINED3DSTT_1D = 1,
+ WINED3DSTT_2D = 2,
+ WINED3DSTT_CUBE = 3,
+ WINED3DSTT_VOLUME = 4,
+};
+
+enum wined3d_shader_register_type
+{
+ WINED3DSPR_TEMP = 0,
+ WINED3DSPR_INPUT = 1,
+ WINED3DSPR_CONST = 2,
+ WINED3DSPR_ADDR = 3,
+ WINED3DSPR_TEXTURE = 3,
+ WINED3DSPR_RASTOUT = 4,
+ WINED3DSPR_ATTROUT = 5,
+ WINED3DSPR_TEXCRDOUT = 6,
+ WINED3DSPR_OUTPUT = 6,
+ WINED3DSPR_CONSTINT = 7,
+ WINED3DSPR_COLOROUT = 8,
+ WINED3DSPR_DEPTHOUT = 9,
+ WINED3DSPR_SAMPLER = 10,
+ WINED3DSPR_CONST2 = 11,
+ WINED3DSPR_CONST3 = 12,
+ WINED3DSPR_CONST4 = 13,
+ WINED3DSPR_CONSTBOOL = 14,
+ WINED3DSPR_LOOP = 15,
+ WINED3DSPR_TEMPFLOAT16 = 16,
+ WINED3DSPR_MISCTYPE = 17,
+ WINED3DSPR_LABEL = 18,
+ WINED3DSPR_PREDICATE = 19,
+ WINED3DSPR_IMMCONST,
+ WINED3DSPR_CONSTBUFFER,
+ WINED3DSPR_PRIMID,
+ WINED3DSPR_NULL,
+ WINED3DSPR_RESOURCE,
+};
+
+enum wined3d_data_type
+{
+ WINED3D_DATA_FLOAT,
+ WINED3D_DATA_INT,
+ WINED3D_DATA_RESOURCE,
+ WINED3D_DATA_SAMPLER,
+ WINED3D_DATA_UINT,
+};
+
+enum wined3d_immconst_type
+{
+ WINED3D_IMMCONST_SCALAR,
+ WINED3D_IMMCONST_VEC4,
+};
+
+#define WINED3DSP_NOSWIZZLE (0 | (1 << 2) | (2 << 4) | (3 << 6))
+
+enum wined3d_shader_src_modifier
+{
+ WINED3DSPSM_NONE = 0,
+ WINED3DSPSM_NEG = 1,
+ WINED3DSPSM_BIAS = 2,
+ WINED3DSPSM_BIASNEG = 3,
+ WINED3DSPSM_SIGN = 4,
+ WINED3DSPSM_SIGNNEG = 5,
+ WINED3DSPSM_COMP = 6,
+ WINED3DSPSM_X2 = 7,
+ WINED3DSPSM_X2NEG = 8,
+ WINED3DSPSM_DZ = 9,
+ WINED3DSPSM_DW = 10,
+ WINED3DSPSM_ABS = 11,
+ WINED3DSPSM_ABSNEG = 12,
+ WINED3DSPSM_NOT = 13,
+};
+
+#define WINED3DSP_WRITEMASK_0 0x1 /* .x r */
+#define WINED3DSP_WRITEMASK_1 0x2 /* .y g */
+#define WINED3DSP_WRITEMASK_2 0x4 /* .z b */
+#define WINED3DSP_WRITEMASK_3 0x8 /* .w a */
+#define WINED3DSP_WRITEMASK_ALL 0xf /* all */
+
+enum wined3d_shader_dst_modifier
+{
+ WINED3DSPDM_NONE = 0,
+ WINED3DSPDM_SATURATE = 1,
+ WINED3DSPDM_PARTIALPRECISION = 2,
+ WINED3DSPDM_MSAMPCENTROID = 4,
+};
+
+/* Undocumented opcode control to identify projective texture lookups in ps 2.0 and later */
+#define WINED3DSI_TEXLD_PROJECT 0x1
+#define WINED3DSI_TEXLD_BIAS 0x2
+#define WINED3DSI_INDEXED_DYNAMIC 0x4
+
+enum wined3d_shader_rel_op
+{
+ WINED3D_SHADER_REL_OP_GT = 1,
+ WINED3D_SHADER_REL_OP_EQ = 2,
+ WINED3D_SHADER_REL_OP_GE = 3,
+ WINED3D_SHADER_REL_OP_LT = 4,
+ WINED3D_SHADER_REL_OP_NE = 5,
+ WINED3D_SHADER_REL_OP_LE = 6,
+};
+
+#define WINED3D_SM1_VS 0xfffe
+#define WINED3D_SM1_PS 0xffff
+#define WINED3D_SM4_PS 0x0000
+#define WINED3D_SM4_VS 0x0001
+#define WINED3D_SM4_GS 0x0002
+
+/* Shader version tokens, and shader end tokens */
+#define WINED3DPS_VERSION(major, minor) ((WINED3D_SM1_PS << 16) | ((major) << 8) | (minor))
+#define WINED3DVS_VERSION(major, minor) ((WINED3D_SM1_VS << 16) | ((major) << 8) | (minor))
+
+/* Shader backends */
+
+/* TODO: Make this dynamic, based on shader limits ? */
+#define MAX_ATTRIBS 16
+#define MAX_REG_ADDR 1
+#define MAX_REG_TEMP 32
+#define MAX_REG_TEXCRD 8
+#define MAX_REG_INPUT 32
+#define MAX_REG_OUTPUT 32
+#define MAX_CONST_I 16
+#define MAX_CONST_B 16
+#define WINED3D_MAX_CBS 15
+
+/* FIXME: This needs to go up to 2048 for
+ * Shader model 3 according to msdn (and for software shaders) */
+#define MAX_LABELS 16
+
+#define SHADER_PGMSIZE 16384
+
+struct wined3d_shader_buffer
+{
+ char *buffer;
+ unsigned int buffer_size;
+ unsigned int content_size;
+ unsigned int lineNo;
+ BOOL newline;
+};
+
+enum WINED3D_SHADER_INSTRUCTION_HANDLER
+{
+ WINED3DSIH_ABS,
+ WINED3DSIH_ADD,
+ WINED3DSIH_AND,
+ WINED3DSIH_BEM,
+ WINED3DSIH_BREAK,
+ WINED3DSIH_BREAKC,
+ WINED3DSIH_BREAKP,
+ WINED3DSIH_CALL,
+ WINED3DSIH_CALLNZ,
+ WINED3DSIH_CMP,
+ WINED3DSIH_CND,
+ WINED3DSIH_CRS,
+ WINED3DSIH_CUT,
+ WINED3DSIH_DCL,
+ WINED3DSIH_DCL_CONSTANT_BUFFER,
+ WINED3DSIH_DCL_INPUT_PRIMITIVE,
+ WINED3DSIH_DCL_OUTPUT_TOPOLOGY,
+ WINED3DSIH_DCL_VERTICES_OUT,
+ WINED3DSIH_DEF,
+ WINED3DSIH_DEFB,
+ WINED3DSIH_DEFI,
+ WINED3DSIH_DIV,
+ WINED3DSIH_DP2ADD,
+ WINED3DSIH_DP3,
+ WINED3DSIH_DP4,
+ WINED3DSIH_DST,
+ WINED3DSIH_DSX,
+ WINED3DSIH_DSY,
+ WINED3DSIH_ELSE,
+ WINED3DSIH_EMIT,
+ WINED3DSIH_ENDIF,
+ WINED3DSIH_ENDLOOP,
+ WINED3DSIH_ENDREP,
+ WINED3DSIH_EQ,
+ WINED3DSIH_EXP,
+ WINED3DSIH_EXPP,
+ WINED3DSIH_FRC,
+ WINED3DSIH_FTOI,
+ WINED3DSIH_GE,
+ WINED3DSIH_IADD,
+ WINED3DSIH_IEQ,
+ WINED3DSIH_IF,
+ WINED3DSIH_IFC,
+ WINED3DSIH_IGE,
+ WINED3DSIH_IMUL,
+ WINED3DSIH_ITOF,
+ WINED3DSIH_LABEL,
+ WINED3DSIH_LD,
+ WINED3DSIH_LIT,
+ WINED3DSIH_LOG,
+ WINED3DSIH_LOGP,
+ WINED3DSIH_LOOP,
+ WINED3DSIH_LRP,
+ WINED3DSIH_LT,
+ WINED3DSIH_M3x2,
+ WINED3DSIH_M3x3,
+ WINED3DSIH_M3x4,
+ WINED3DSIH_M4x3,
+ WINED3DSIH_M4x4,
+ WINED3DSIH_MAD,
+ WINED3DSIH_MAX,
+ WINED3DSIH_MIN,
+ WINED3DSIH_MOV,
+ WINED3DSIH_MOVA,
+ WINED3DSIH_MOVC,
+ WINED3DSIH_MUL,
+ WINED3DSIH_NOP,
+ WINED3DSIH_NRM,
+ WINED3DSIH_PHASE,
+ WINED3DSIH_POW,
+ WINED3DSIH_RCP,
+ WINED3DSIH_REP,
+ WINED3DSIH_RET,
+ WINED3DSIH_ROUND_NI,
+ WINED3DSIH_RSQ,
+ WINED3DSIH_SAMPLE,
+ WINED3DSIH_SAMPLE_GRAD,
+ WINED3DSIH_SAMPLE_LOD,
+ WINED3DSIH_SETP,
+ WINED3DSIH_SGE,
+ WINED3DSIH_SGN,
+ WINED3DSIH_SINCOS,
+ WINED3DSIH_SLT,
+ WINED3DSIH_SQRT,
+ WINED3DSIH_SUB,
+ WINED3DSIH_TEX,
+ WINED3DSIH_TEXBEM,
+ WINED3DSIH_TEXBEML,
+ WINED3DSIH_TEXCOORD,
+ WINED3DSIH_TEXDEPTH,
+ WINED3DSIH_TEXDP3,
+ WINED3DSIH_TEXDP3TEX,
+ WINED3DSIH_TEXKILL,
+ WINED3DSIH_TEXLDD,
+ WINED3DSIH_TEXLDL,
+ WINED3DSIH_TEXM3x2DEPTH,
+ WINED3DSIH_TEXM3x2PAD,
+ WINED3DSIH_TEXM3x2TEX,
+ WINED3DSIH_TEXM3x3,
+ WINED3DSIH_TEXM3x3DIFF,
+ WINED3DSIH_TEXM3x3PAD,
+ WINED3DSIH_TEXM3x3SPEC,
+ WINED3DSIH_TEXM3x3TEX,
+ WINED3DSIH_TEXM3x3VSPEC,
+ WINED3DSIH_TEXREG2AR,
+ WINED3DSIH_TEXREG2GB,
+ WINED3DSIH_TEXREG2RGB,
+ WINED3DSIH_UDIV,
+ WINED3DSIH_USHR,
+ WINED3DSIH_UTOF,
+ WINED3DSIH_XOR,
+ WINED3DSIH_TABLE_SIZE
+};
+
+enum wined3d_shader_type
+{
+ WINED3D_SHADER_TYPE_PIXEL,
+ WINED3D_SHADER_TYPE_VERTEX,
+ WINED3D_SHADER_TYPE_GEOMETRY,
+};
+
+struct wined3d_shader_version
+{
+ enum wined3d_shader_type type;
+ BYTE major;
+ BYTE minor;
+};
+
+#define WINED3D_SHADER_VERSION(major, minor) (((major) << 8) | (minor))
+
+struct wined3d_shader_reg_maps
+{
+ struct wined3d_shader_version shader_version;
+ BYTE texcoord; /* MAX_REG_TEXCRD, 8 */
+ BYTE address; /* MAX_REG_ADDR, 1 */
+ WORD labels; /* MAX_LABELS, 16 */
+ DWORD temporary; /* MAX_REG_TEMP, 32 */
+ DWORD *constf; /* pixel, vertex */
+ DWORD texcoord_mask[MAX_REG_TEXCRD]; /* vertex < 3.0 */
+ DWORD input_registers; /* max(MAX_REG_INPUT, MAX_ATTRIBS), 32 */
+ DWORD output_registers; /* MAX_REG_OUTPUT, 32 */
+ WORD integer_constants; /* MAX_CONST_I, 16 */
+ WORD boolean_constants; /* MAX_CONST_B, 16 */
+ WORD local_int_consts; /* MAX_CONST_I, 16 */
+ WORD local_bool_consts; /* MAX_CONST_B, 16 */
+ UINT cb_sizes[WINED3D_MAX_CBS];
+
+ enum wined3d_sampler_texture_type sampler_type[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
+ BYTE bumpmat; /* MAX_TEXTURES, 8 */
+ BYTE luminanceparams; /* MAX_TEXTURES, 8 */
+
+ WORD usesnrm : 1;
+ WORD vpos : 1;
+ WORD usesdsx : 1;
+ WORD usesdsy : 1;
+ WORD usestexldd : 1;
+ WORD usesmova : 1;
+ WORD usesfacing : 1;
+ WORD usesrelconstF : 1;
+ WORD fog : 1;
+ WORD usestexldl : 1;
+ WORD usesifc : 1;
+ WORD usescall : 1;
+ WORD usespow : 1;
+ WORD padding : 3;
+
+ DWORD rt_mask; /* Used render targets, 32 max. */
+
+ /* Whether or not loops are used in this shader, and nesting depth */
+ unsigned loop_depth;
+ UINT min_rel_offset, max_rel_offset;
+};
+
+/* Keeps track of details for TEX_M#x# instructions which need to maintain
+ * state information between multiple instructions. */
+struct wined3d_shader_tex_mx
+{
+ unsigned int current_row;
+ DWORD texcoord_w[2];
+};
+
+struct wined3d_shader_loop_state
+{
+ UINT current_depth;
+ UINT current_reg;
+};
+
+struct wined3d_shader_context
+{
+ const struct wined3d_shader *shader;
+ const struct wined3d_gl_info *gl_info;
+ const struct wined3d_shader_reg_maps *reg_maps;
+ struct wined3d_shader_buffer *buffer;
+ struct wined3d_shader_tex_mx *tex_mx;
+ struct wined3d_shader_loop_state *loop_state;
+ void *backend_data;
+};
+
+struct wined3d_shader_register_index
+{
+ const struct wined3d_shader_src_param *rel_addr;
+ unsigned int offset;
+};
+
+struct wined3d_shader_register
+{
+ enum wined3d_shader_register_type type;
+ enum wined3d_data_type data_type;
+ struct wined3d_shader_register_index idx[2];
+ enum wined3d_immconst_type immconst_type;
+ DWORD immconst_data[4];
+};
+
+struct wined3d_shader_dst_param
+{
+ struct wined3d_shader_register reg;
+ DWORD write_mask;
+ DWORD modifiers;
+ DWORD shift;
+};
+
+struct wined3d_shader_src_param
+{
+ struct wined3d_shader_register reg;
+ DWORD swizzle;
+ enum wined3d_shader_src_modifier modifiers;
+};
+
+struct wined3d_shader_semantic
+{
+ enum wined3d_decl_usage usage;
+ UINT usage_idx;
+ enum wined3d_sampler_texture_type sampler_type;
+ struct wined3d_shader_dst_param reg;
+};
+
+struct wined3d_shader_instruction
+{
+ const struct wined3d_shader_context *ctx;
+ enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx;
+ DWORD flags;
+ BOOL coissue;
+ const struct wined3d_shader_src_param *predicate;
+ UINT dst_count;
+ const struct wined3d_shader_dst_param *dst;
+ UINT src_count;
+ const struct wined3d_shader_src_param *src;
+ union
+ {
+ struct wined3d_shader_semantic semantic;
+ enum wined3d_primitive_type primitive_type;
+ struct wined3d_shader_src_param src;
+ UINT count;
+ } declaration;
+};
+
+struct wined3d_shader_attribute
+{
+ enum wined3d_decl_usage usage;
+ UINT usage_idx;
+};
+
+struct wined3d_shader_loop_control
+{
+ unsigned int count;
+ unsigned int start;
+ int step;
+};
+
+struct wined3d_shader_frontend
+{
+ void *(*shader_init)(const DWORD *ptr, const struct wined3d_shader_signature *output_signature);
+ void (*shader_free)(void *data);
+ void (*shader_read_header)(void *data, const DWORD **ptr, struct wined3d_shader_version *shader_version);
+ void (*shader_read_instruction)(void *data, const DWORD **ptr, struct wined3d_shader_instruction *ins);
+ BOOL (*shader_is_end)(void *data, const DWORD **ptr);
+};
+
+extern const struct wined3d_shader_frontend sm1_shader_frontend DECLSPEC_HIDDEN;
+extern const struct wined3d_shader_frontend sm4_shader_frontend DECLSPEC_HIDDEN;
+
+typedef void (*SHADER_HANDLER)(const struct wined3d_shader_instruction *);
+
+#define WINED3D_SHADER_CAP_VS_CLIPPING 0x00000001
+#define WINED3D_SHADER_CAP_SRGB_WRITE 0x00000002
+
+struct shader_caps
+{
+ UINT vs_version;
+ UINT gs_version;
+ UINT ps_version;
+
+ DWORD vs_uniform_count;
+ DWORD ps_uniform_count;
+ float ps_1x_max_value;
+
+ DWORD wined3d_caps;
+};
+
+enum tex_types
+{
+ tex_1d = 0,
+ tex_2d = 1,
+ tex_3d = 2,
+ tex_cube = 3,
+ tex_rect = 4,
+ tex_type_count = 5,
+};
+
+enum vertexprocessing_mode {
+ fixedfunction,
+ vertexshader,
+ pretransformed
+};
+
+#define WINED3D_CONST_NUM_UNUSED ~0U
+
+enum wined3d_ffp_ps_fog_mode
+{
+ WINED3D_FFP_PS_FOG_OFF,
+ WINED3D_FFP_PS_FOG_LINEAR,
+ WINED3D_FFP_PS_FOG_EXP,
+ WINED3D_FFP_PS_FOG_EXP2,
+};
+
+/* Stateblock dependent parameters which have to be hardcoded
+ * into the shader code
+ */
+
+#define WINED3D_PSARGS_PROJECTED (1 << 3)
+#define WINED3D_PSARGS_TEXTRANSFORM_SHIFT 4
+#define WINED3D_PSARGS_TEXTRANSFORM_MASK 0xf
+#define WINED3D_PSARGS_TEXTYPE_SHIFT 2
+#define WINED3D_PSARGS_TEXTYPE_MASK 0x3
+
+/* Similar to tex_types, except that it doesn't have 1d textures
+ * (can't be bound), rect textures (handled via np2_fixup) and
+ * none / unknown (treated as 2d and handled via dummy textures). */
+enum wined3d_shader_tex_types
+{
+ WINED3D_SHADER_TEX_2D = 0,
+ WINED3D_SHADER_TEX_3D = 1,
+ WINED3D_SHADER_TEX_CUBE = 2,
+};
+
+struct ps_compile_args {
+ struct color_fixup_desc color_fixup[MAX_FRAGMENT_SAMPLERS];
+ enum vertexprocessing_mode vp_mode;
+ enum wined3d_ffp_ps_fog_mode fog;
+ WORD tex_transform; /* ps 1.0-1.3, 4 textures */
+ WORD tex_types; /* ps 1.0 - 1.4, 6 textures */
+ WORD srgb_correction;
+ WORD np2_fixup;
+ /* Bitmap for NP2 texcoord fixups (16 samplers max currently).
+ D3D9 has a limit of 16 samplers and the fixup is superfluous
+ in D3D10 (unconditional NP2 support mandatory). */
+ WORD shadow; /* MAX_FRAGMENT_SAMPLERS, 16 */
+};
+
+enum fog_src_type {
+ VS_FOG_Z = 0,
+ VS_FOG_COORD = 1
+};
+
+struct vs_compile_args {
+ BYTE fog_src;
+ BYTE clip_enabled;
+ WORD swizzle_map; /* MAX_ATTRIBS, 16 */
+};
+
+struct wined3d_context;
+struct wined3d_state;
+struct fragment_pipeline;
+struct wined3d_vertex_pipe_ops;
+
+struct wined3d_shader_backend_ops
+{
+ void (*shader_handle_instruction)(const struct wined3d_shader_instruction *);
+ void (*shader_select)(void *shader_priv, const struct wined3d_context *context,
+ const struct wined3d_state *state);
+ void (*shader_disable)(void *shader_priv, const struct wined3d_context *context);
+ void (*shader_select_depth_blt)(void *shader_priv, const struct wined3d_gl_info *gl_info,
+ enum tex_types tex_type, const SIZE *ds_mask_size);
+ void (*shader_deselect_depth_blt)(void *shader_priv, const struct wined3d_gl_info *gl_info);
+ void (*shader_update_float_vertex_constants)(struct wined3d_device *device, UINT start, UINT count);
+ void (*shader_update_float_pixel_constants)(struct wined3d_device *device, UINT start, UINT count);
+ void (*shader_load_constants)(void *shader_priv, const struct wined3d_context *context,
+ const struct wined3d_state *state);
+ void (*shader_load_np2fixup_constants)(void *shader_priv, const struct wined3d_gl_info *gl_info,
+ const struct wined3d_state *state);
+ void (*shader_destroy)(struct wined3d_shader *shader);
+ HRESULT (*shader_alloc_private)(struct wined3d_device *device, const struct wined3d_vertex_pipe_ops *vertex_pipe,
+ const struct fragment_pipeline *fragment_pipe);
+ void (*shader_free_private)(struct wined3d_device *device);
+ void (*shader_context_destroyed)(void *shader_priv, const struct wined3d_context *context);
+ void (*shader_get_caps)(const struct wined3d_gl_info *gl_info, struct shader_caps *caps);
+ BOOL (*shader_color_fixup_supported)(struct color_fixup_desc fixup);
+ BOOL (*shader_has_ffp_proj_control)(void *shader_priv);
+};
+
+extern const struct wined3d_shader_backend_ops glsl_shader_backend DECLSPEC_HIDDEN;
+extern const struct wined3d_shader_backend_ops arb_program_shader_backend DECLSPEC_HIDDEN;
+extern const struct wined3d_shader_backend_ops none_shader_backend DECLSPEC_HIDDEN;
+
+#define GL_EXTCALL(f) (gl_info->gl_ops.ext.p_##f)
+
+#define D3DCOLOR_B_R(dw) (((dw) >> 16) & 0xff)
+#define D3DCOLOR_B_G(dw) (((dw) >> 8) & 0xff)
+#define D3DCOLOR_B_B(dw) (((dw) >> 0) & 0xff)
+#define D3DCOLOR_B_A(dw) (((dw) >> 24) & 0xff)
+
+#define D3DCOLOR_R(dw) (((float) (((dw) >> 16) & 0xff)) / 255.0f)
+#define D3DCOLOR_G(dw) (((float) (((dw) >> 8) & 0xff)) / 255.0f)
+#define D3DCOLOR_B(dw) (((float) (((dw) >> 0) & 0xff)) / 255.0f)
+#define D3DCOLOR_A(dw) (((float) (((dw) >> 24) & 0xff)) / 255.0f)
+
+#define D3DCOLORTOGLFLOAT4(dw, vec) do { \
+ (vec)[0] = D3DCOLOR_R(dw); \
+ (vec)[1] = D3DCOLOR_G(dw); \
+ (vec)[2] = D3DCOLOR_B(dw); \
+ (vec)[3] = D3DCOLOR_A(dw); \
+} while(0)
+
+#define HIGHEST_TRANSFORMSTATE WINED3D_TS_WORLD_MATRIX(255) /* Highest value in wined3d_transform_state. */
+
+/* Checking of API calls */
+/* --------------------- */
+#ifndef WINE_NO_DEBUG_MSGS
+#define checkGLcall(A) \
+do { \
+ GLint err; \
+ if (!__WINE_IS_DEBUG_ON(_ERR, __wine_dbch___default)) break; \
+ err = gl_info->gl_ops.gl.p_glGetError(); \
+ /* #ifdef VBOX */ \
+ if (!wglGetCurrentContext()) \
+ { \
+ ERR(">>>>>>>>>>>>>>>>> NULL ctx issuing %s @ %s / %d\n", \
+ A, __FILE__, __LINE__); \
+ break; \
+ } \
+ /*#endif*/ \
+ if (err == GL_NO_ERROR) { \
+ TRACE("%s call ok %s / %d\n", A, __FILE__, __LINE__); \
+ \
+ } else do { \
+ ERR(">>>>>>>>>>>>>>>>> %s (%#x) from %s @ %s / %d\n", \
+ debug_glerror(err), err, A, __FILE__, __LINE__); \
+ err = gl_info->gl_ops.gl.p_glGetError(); \
+ } while (err != GL_NO_ERROR); \
+} while(0)
+#else
+#define checkGLcall(A) do {} while(0)
+#endif
+
+enum wined3d_ffp_idx
+{
+ WINED3D_FFP_POSITION = 0,
+ WINED3D_FFP_BLENDWEIGHT = 1,
+ WINED3D_FFP_BLENDINDICES = 2,
+ WINED3D_FFP_NORMAL = 3,
+ WINED3D_FFP_PSIZE = 4,
+ WINED3D_FFP_DIFFUSE = 5,
+ WINED3D_FFP_SPECULAR = 6,
+ WINED3D_FFP_TEXCOORD0 = 7,
+ WINED3D_FFP_TEXCOORD1 = 8,
+ WINED3D_FFP_TEXCOORD2 = 9,
+ WINED3D_FFP_TEXCOORD3 = 10,
+ WINED3D_FFP_TEXCOORD4 = 11,
+ WINED3D_FFP_TEXCOORD5 = 12,
+ WINED3D_FFP_TEXCOORD6 = 13,
+ WINED3D_FFP_TEXCOORD7 = 14,
+};
+
+enum wined3d_ffp_emit_idx
+{
+ WINED3D_FFP_EMIT_FLOAT1 = 0,
+ WINED3D_FFP_EMIT_FLOAT2 = 1,
+ WINED3D_FFP_EMIT_FLOAT3 = 2,
+ WINED3D_FFP_EMIT_FLOAT4 = 3,
+ WINED3D_FFP_EMIT_D3DCOLOR = 4,
+ WINED3D_FFP_EMIT_UBYTE4 = 5,
+ WINED3D_FFP_EMIT_SHORT2 = 6,
+ WINED3D_FFP_EMIT_SHORT4 = 7,
+ WINED3D_FFP_EMIT_UBYTE4N = 8,
+ WINED3D_FFP_EMIT_SHORT2N = 9,
+ WINED3D_FFP_EMIT_SHORT4N = 10,
+ WINED3D_FFP_EMIT_USHORT2N = 11,
+ WINED3D_FFP_EMIT_USHORT4N = 12,
+ WINED3D_FFP_EMIT_UDEC3 = 13,
+ WINED3D_FFP_EMIT_DEC3N = 14,
+ WINED3D_FFP_EMIT_FLOAT16_2 = 15,
+ WINED3D_FFP_EMIT_FLOAT16_4 = 16,
+ WINED3D_FFP_EMIT_INVALID = 17,
+ WINED3D_FFP_EMIT_COUNT = 18
+};
+
+struct wined3d_bo_address
+{
+ GLuint buffer_object;
+ const BYTE *addr;
+};
+
+struct wined3d_stream_info_element
+{
+ const struct wined3d_format *format;
+ struct wined3d_bo_address data;
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ UINT offset;
+#endif
+ GLsizei stride;
+ UINT stream_idx;
+};
+
+struct wined3d_stream_info
+{
+ struct wined3d_stream_info_element elements[MAX_ATTRIBS];
+ DWORD position_transformed : 1;
+ DWORD all_vbo : 1;
+ WORD swizzle_map; /* MAX_ATTRIBS, 16 */
+ WORD use_map; /* MAX_ATTRIBS, 16 */
+};
+
+void draw_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count,
+ UINT start_instance, UINT instance_count, BOOL indexed) DECLSPEC_HIDDEN;
+DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN;
+
+typedef void (WINE_GLAPI *glAttribFunc)(const void *data);
+typedef void (WINE_GLAPI *glMultiTexCoordFunc)(GLenum unit, const void *data);
+extern glAttribFunc position_funcs[WINED3D_FFP_EMIT_COUNT] DECLSPEC_HIDDEN;
+extern glAttribFunc diffuse_funcs[WINED3D_FFP_EMIT_COUNT] DECLSPEC_HIDDEN;
+extern glAttribFunc specular_func_3ubv DECLSPEC_HIDDEN;
+extern glAttribFunc specular_funcs[WINED3D_FFP_EMIT_COUNT] DECLSPEC_HIDDEN;
+extern glAttribFunc normal_funcs[WINED3D_FFP_EMIT_COUNT] DECLSPEC_HIDDEN;
+extern glMultiTexCoordFunc multi_texcoord_funcs[WINED3D_FFP_EMIT_COUNT] DECLSPEC_HIDDEN;
+
+#define eps 1e-8
+
+#define GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_num) \
+ (((((d3dvtVertexType) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1)
+
+/* Routines and structures related to state management */
+
+#define STATE_RENDER(a) (a)
+#define STATE_IS_RENDER(a) ((a) >= STATE_RENDER(1) && (a) <= STATE_RENDER(WINEHIGHEST_RENDER_STATE))
+
+#define STATE_TEXTURESTAGE(stage, num) (STATE_RENDER(WINEHIGHEST_RENDER_STATE) + 1 + (stage) * (WINED3D_HIGHEST_TEXTURE_STATE + 1) + (num))
+#define STATE_IS_TEXTURESTAGE(a) ((a) >= STATE_TEXTURESTAGE(0, 1) && (a) <= STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE))
+
+/* + 1 because samplers start with 0 */
+#define STATE_SAMPLER(num) (STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE) + 1 + (num))
+#define STATE_IS_SAMPLER(num) ((num) >= STATE_SAMPLER(0) && (num) <= STATE_SAMPLER(MAX_COMBINED_SAMPLERS - 1))
+
+#define STATE_PIXELSHADER (STATE_SAMPLER(MAX_COMBINED_SAMPLERS - 1) + 1)
+#define STATE_IS_PIXELSHADER(a) ((a) == STATE_PIXELSHADER)
+
+#define STATE_TRANSFORM(a) (STATE_PIXELSHADER + (a))
+#define STATE_IS_TRANSFORM(a) ((a) >= STATE_TRANSFORM(1) && (a) <= STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)))
+
+#define STATE_STREAMSRC (STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)) + 1)
+#define STATE_IS_STREAMSRC(a) ((a) == STATE_STREAMSRC)
+#define STATE_INDEXBUFFER (STATE_STREAMSRC + 1)
+#define STATE_IS_INDEXBUFFER(a) ((a) == STATE_INDEXBUFFER)
+
+#define STATE_VDECL (STATE_INDEXBUFFER + 1)
+#define STATE_IS_VDECL(a) ((a) == STATE_VDECL)
+
+#define STATE_VSHADER (STATE_VDECL + 1)
+#define STATE_IS_VSHADER(a) ((a) == STATE_VSHADER)
+
+#define STATE_GEOMETRY_SHADER (STATE_VSHADER + 1)
+#define STATE_IS_GEOMETRY_SHADER(a) ((a) == STATE_GEOMETRY_SHADER)
+
+#define STATE_VIEWPORT (STATE_GEOMETRY_SHADER + 1)
+#define STATE_IS_VIEWPORT(a) ((a) == STATE_VIEWPORT)
+
+#define STATE_VERTEXSHADERCONSTANT (STATE_VIEWPORT + 1)
+#define STATE_PIXELSHADERCONSTANT (STATE_VERTEXSHADERCONSTANT + 1)
+#define STATE_IS_VERTEXSHADERCONSTANT(a) ((a) == STATE_VERTEXSHADERCONSTANT)
+#define STATE_IS_PIXELSHADERCONSTANT(a) ((a) == STATE_PIXELSHADERCONSTANT)
+
+#define STATE_LIGHT_TYPE (STATE_PIXELSHADERCONSTANT + 1)
+#define STATE_IS_LIGHT_TYPE(a) ((a) == STATE_LIGHT_TYPE)
+#define STATE_ACTIVELIGHT(a) (STATE_LIGHT_TYPE + 1 + (a))
+#define STATE_IS_ACTIVELIGHT(a) ((a) >= STATE_ACTIVELIGHT(0) && (a) < STATE_ACTIVELIGHT(MAX_ACTIVE_LIGHTS))
+
+#define STATE_SCISSORRECT (STATE_ACTIVELIGHT(MAX_ACTIVE_LIGHTS - 1) + 1)
+#define STATE_IS_SCISSORRECT(a) ((a) == STATE_SCISSORRECT)
+
+#define STATE_CLIPPLANE(a) (STATE_SCISSORRECT + 1 + (a))
+#define STATE_IS_CLIPPLANE(a) ((a) >= STATE_CLIPPLANE(0) && (a) <= STATE_CLIPPLANE(MAX_CLIPPLANES - 1))
+
+#define STATE_MATERIAL (STATE_CLIPPLANE(MAX_CLIPPLANES))
+#define STATE_IS_MATERIAL(a) ((a) == STATE_MATERIAL)
+
+#define STATE_FRONTFACE (STATE_MATERIAL + 1)
+#define STATE_IS_FRONTFACE(a) ((a) == STATE_FRONTFACE)
+
+#define STATE_POINTSPRITECOORDORIGIN (STATE_FRONTFACE + 1)
+#define STATE_IS_POINTSPRITECOORDORIGIN(a) ((a) == STATE_POINTSPRITECOORDORIGIN)
+
+#define STATE_BASEVERTEXINDEX (STATE_POINTSPRITECOORDORIGIN + 1)
+#define STATE_IS_BASEVERTEXINDEX(a) ((a) == STATE_BASEVERTEXINDEX)
+
+#define STATE_FRAMEBUFFER (STATE_BASEVERTEXINDEX + 1)
+#define STATE_IS_FRAMEBUFFER(a) ((a) == STATE_FRAMEBUFFER)
+
+#define STATE_POINT_SIZE_ENABLE (STATE_FRAMEBUFFER + 1)
+#define STATE_IS_POINT_SIZE_ENABLE(a) ((a) == STATE_POINT_SIZE_ENABLE)
+
+#define STATE_HIGHEST (STATE_POINT_SIZE_ENABLE)
+
+enum fogsource {
+ FOGSOURCE_FFP,
+ FOGSOURCE_VS,
+ FOGSOURCE_COORD,
+};
+
+#define WINED3D_MAX_FBO_ENTRIES 64
+
+struct wined3d_occlusion_query
+{
+ struct list entry;
+ GLuint id;
+ struct wined3d_context *context;
+};
+
+union wined3d_gl_query_object
+{
+ GLuint id;
+ GLsync sync;
+};
+
+struct wined3d_event_query
+{
+ struct list entry;
+ union wined3d_gl_query_object object;
+ struct wined3d_context *context;
+};
+
+enum wined3d_event_query_result
+{
+ WINED3D_EVENT_QUERY_OK,
+ WINED3D_EVENT_QUERY_WAITING,
+ WINED3D_EVENT_QUERY_NOT_STARTED,
+ WINED3D_EVENT_QUERY_WRONG_THREAD,
+ WINED3D_EVENT_QUERY_ERROR
+};
+
+void wined3d_event_query_destroy(struct wined3d_event_query *query) DECLSPEC_HIDDEN;
+enum wined3d_event_query_result wined3d_event_query_finish(const struct wined3d_event_query *query,
+ const struct wined3d_device *device) DECLSPEC_HIDDEN;
+void wined3d_event_query_issue(struct wined3d_event_query *query, const struct wined3d_device *device) DECLSPEC_HIDDEN;
+BOOL wined3d_event_query_supported(const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
+
+struct wined3d_context
+{
+ const struct wined3d_gl_info *gl_info;
+ const struct wined3d_d3d_info *d3d_info;
+ const struct StateEntry *state_table;
+ /* State dirtification
+ * dirtyArray is an array that contains markers for dirty states. numDirtyEntries states are dirty, their numbers are in indices
+ * 0...numDirtyEntries - 1. isStateDirty is a redundant copy of the dirtyArray. Technically only one of them would be needed,
+ * but with the help of both it is easy to find out if a state is dirty(just check the array index), and for applying dirty states
+ * only numDirtyEntries array elements have to be checked, not STATE_HIGHEST states.
+ */
+ DWORD dirtyArray[STATE_HIGHEST + 1]; /* Won't get bigger than that, a state is never marked dirty 2 times */
+ DWORD numDirtyEntries;
+ DWORD isStateDirty[STATE_HIGHEST / (sizeof(DWORD) * CHAR_BIT) + 1]; /* Bitmap to find out quickly if a state is dirty */
+
+ struct wined3d_swapchain *swapchain;
+
+ struct wined3d_surface *current_rt;
+ DWORD tid; /* Thread ID which owns this context at the moment */
+
+ /* Stores some information about the context state for optimization */
+ DWORD render_offscreen : 1;
+ DWORD last_was_rhw : 1; /* true iff last draw_primitive was in xyzrhw mode */
+ DWORD last_was_pshader : 1;
+ DWORD last_was_vshader : 1;
+ DWORD namedArraysLoaded : 1;
+ DWORD numberedArraysLoaded : 1;
+ DWORD last_was_blit : 1;
+ DWORD last_was_ckey : 1;
+ DWORD fog_coord : 1;
+ DWORD fog_enabled : 1;
+ DWORD num_untracked_materials : 2; /* Max value 2 */
+ DWORD current : 1;
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ DWORD destroyed : 1;
+#endif
+ DWORD valid : 1;
+ DWORD select_shader : 1;
+ DWORD load_constants : 1;
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ DWORD padding : 15;
+#else
+ DWORD padding : 16;
+#endif
+
+ BYTE texShaderBumpMap; /* MAX_TEXTURES, 8 */
+ BYTE lastWasPow2Texture; /* MAX_TEXTURES, 8 */
+ DWORD numbered_array_mask;
+ GLenum tracking_parm; /* Which source is tracking current colour */
+ GLenum untracked_materials[2];
+ UINT blit_w, blit_h;
+ enum fogsource fog_source;
+ DWORD active_texture;
+ DWORD texture_type[MAX_COMBINED_SAMPLERS];
+
+ /* The actual opengl context */
+ UINT level;
+ HGLRC restore_ctx;
+ HDC restore_dc;
+ int restore_pf;
+ HGLRC glCtx;
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ HWND win_handle;
+ HDC hdc;
+#else
+ struct wined3d_device *device;
+#endif
+
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+ VBOXTLSREFDATA
+#endif
+
+ int pixel_format;
+ GLint aux_buffers;
+
+ /* FBOs */
+ UINT fbo_entry_count;
+ struct list fbo_list;
+ struct list fbo_destroy_list;
+ struct fbo_entry *current_fbo;
+ GLuint fbo_read_binding;
+ GLuint fbo_draw_binding;
+ BOOL rebind_fbo;
+ struct wined3d_surface **blit_targets;
+ GLenum *draw_buffers;
+ DWORD draw_buffers_mask; /* Enabled draw buffers, 31 max. */
+
+ /* Queries */
+ GLuint *free_occlusion_queries;
+ UINT free_occlusion_query_size;
+ UINT free_occlusion_query_count;
+ struct list occlusion_queries;
+
+ union wined3d_gl_query_object *free_event_queries;
+ UINT free_event_query_size;
+ UINT free_event_query_count;
+ struct list event_queries;
+
+ /* Extension emulation */
+ GLint gl_fog_source;
+ GLfloat fog_coord_value;
+ GLfloat color[4], fogstart, fogend, fogcolor[4];
+ GLuint dummy_arbfp_prog;
+};
+
+struct wined3d_fb_state
+{
+ struct wined3d_surface **render_targets;
+ struct wined3d_surface *depth_stencil;
+};
+
+typedef void (*APPLYSTATEFUNC)(struct wined3d_context *ctx, const struct wined3d_state *state, DWORD state_id);
+
+struct StateEntry
+{
+ DWORD representative;
+ APPLYSTATEFUNC apply;
+};
+
+struct StateEntryTemplate
+{
+ DWORD state;
+ struct StateEntry content;
+ enum wined3d_gl_extension extension;
+};
+
+#define WINED3D_FRAGMENT_CAP_PROJ_CONTROL 0x00000001
+#define WINED3D_FRAGMENT_CAP_SRGB_WRITE 0x00000002
+
+struct fragment_caps
+{
+ DWORD wined3d_caps;
+ DWORD PrimitiveMiscCaps;
+ DWORD TextureOpCaps;
+ DWORD MaxTextureBlendStages;
+ DWORD MaxSimultaneousTextures;
+};
+
+struct fragment_pipeline
+{
+ void (*enable_extension)(const struct wined3d_gl_info *gl_info, BOOL enable);
+ void (*get_caps)(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps);
+ void *(*alloc_private)(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv);
+ void (*free_private)(struct wined3d_device *device);
+ BOOL (*color_fixup_supported)(struct color_fixup_desc fixup);
+ const struct StateEntryTemplate *states;
+};
+
+struct wined3d_vertex_caps
+{
+ BOOL xyzrhw;
+ DWORD max_active_lights;
+ DWORD max_vertex_blend_matrices;
+ DWORD max_vertex_blend_matrix_index;
+ DWORD vertex_processing_caps;
+ DWORD fvf_caps;
+ DWORD max_user_clip_planes;
+ DWORD raster_caps;
+};
+
+struct wined3d_vertex_pipe_ops
+{
+ void (*vp_enable)(const struct wined3d_gl_info *gl_info, BOOL enable);
+ void (*vp_get_caps)(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps);
+ void *(*vp_alloc)(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv);
+ void (*vp_free)(struct wined3d_device *device);
+ const struct StateEntryTemplate *vp_states;
+};
+
+extern const struct StateEntryTemplate misc_state_template[] DECLSPEC_HIDDEN;
+extern const struct fragment_pipeline none_fragment_pipe DECLSPEC_HIDDEN;
+extern const struct fragment_pipeline ffp_fragment_pipeline DECLSPEC_HIDDEN;
+extern const struct fragment_pipeline atifs_fragment_pipeline DECLSPEC_HIDDEN;
+extern const struct fragment_pipeline arbfp_fragment_pipeline DECLSPEC_HIDDEN;
+extern const struct fragment_pipeline nvts_fragment_pipeline DECLSPEC_HIDDEN;
+extern const struct fragment_pipeline nvrc_fragment_pipeline DECLSPEC_HIDDEN;
+extern const struct fragment_pipeline glsl_fragment_pipe DECLSPEC_HIDDEN;
+
+extern const struct wined3d_vertex_pipe_ops none_vertex_pipe DECLSPEC_HIDDEN;
+extern const struct wined3d_vertex_pipe_ops ffp_vertex_pipe DECLSPEC_HIDDEN;
+extern const struct wined3d_vertex_pipe_ops glsl_vertex_pipe DECLSPEC_HIDDEN;
+
+/* "Base" state table */
+HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
+ const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info,
+ const struct wined3d_vertex_pipe_ops *vertex, const struct fragment_pipeline *fragment,
+ const struct StateEntryTemplate *misc) DECLSPEC_HIDDEN;
+
+enum wined3d_blit_op
+{
+ WINED3D_BLIT_OP_COLOR_BLIT,
+ WINED3D_BLIT_OP_COLOR_FILL,
+ WINED3D_BLIT_OP_DEPTH_FILL,
+ WINED3D_BLIT_OP_DEPTH_BLIT,
+};
+
+/* Shaders for color conversions in blits. Do not do blit operations while
+ * already under the GL lock. */
+struct blit_shader
+{
+ HRESULT (*alloc_private)(struct wined3d_device *device);
+ void (*free_private)(struct wined3d_device *device);
+ HRESULT (*set_shader)(void *blit_priv, struct wined3d_context *context, const struct wined3d_surface *surface);
+ void (*unset_shader)(const struct wined3d_gl_info *gl_info);
+ BOOL (*blit_supported)(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
+ const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
+ const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format);
+ HRESULT (*color_fill)(struct wined3d_device *device, struct wined3d_surface *dst_surface,
+ const RECT *dst_rect, const struct wined3d_color *color);
+ HRESULT (*depth_fill)(struct wined3d_device *device,
+ struct wined3d_surface *surface, const RECT *rect, float depth);
+};
+
+extern const struct blit_shader ffp_blit DECLSPEC_HIDDEN;
+extern const struct blit_shader arbfp_blit DECLSPEC_HIDDEN;
+extern const struct blit_shader cpu_blit DECLSPEC_HIDDEN;
+
+const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
+ const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
+ const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
+ DECLSPEC_HIDDEN;
+
+/* Temporary blit_shader helper functions */
+HRESULT arbfp_blit_surface(struct wined3d_device *device, DWORD filter,
+ struct wined3d_surface *src_surface, const RECT *src_rect,
+ struct wined3d_surface *dst_surface, const RECT *dst_rect) DECLSPEC_HIDDEN;
+
+struct wined3d_context *context_acquire(const struct wined3d_device *device,
+ struct wined3d_surface *target) DECLSPEC_HIDDEN;
+void context_alloc_event_query(struct wined3d_context *context,
+ struct wined3d_event_query *query) DECLSPEC_HIDDEN;
+void context_alloc_occlusion_query(struct wined3d_context *context,
+ struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN;
+void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device) DECLSPEC_HIDDEN;
+BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_device *device,
+ UINT rt_count, const struct wined3d_fb_state *fb) DECLSPEC_HIDDEN;
+BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_device *device) DECLSPEC_HIDDEN;
+void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target,
+ struct wined3d_surface *render_target, struct wined3d_surface *depth_stencil, DWORD location) DECLSPEC_HIDDEN;
+void context_active_texture(struct wined3d_context *context, const struct wined3d_gl_info *gl_info,
+ unsigned int unit) DECLSPEC_HIDDEN;
+void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint name) DECLSPEC_HIDDEN;
+void context_check_fbo_status(const struct wined3d_context *context, GLenum target) DECLSPEC_HIDDEN;
+struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, struct wined3d_surface *target,
+ const struct wined3d_format *ds_format
+#ifdef VBOX_WITH_WDDM
+ , struct VBOXUHGSMI *pHgsmi
+#endif
+ ) DECLSPEC_HIDDEN;
+BOOL context_debug_output_enabled(const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
+void context_destroy(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
+void context_free_event_query(struct wined3d_event_query *query) DECLSPEC_HIDDEN;
+void context_free_occlusion_query(struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN;
+struct wined3d_context *context_get_current(void) DECLSPEC_HIDDEN;
+DWORD context_get_tls_idx(void) DECLSPEC_HIDDEN;
+void context_invalidate_state(struct wined3d_context *context, DWORD state_id) DECLSPEC_HIDDEN;
+void context_release(struct wined3d_context *context) DECLSPEC_HIDDEN;
+void context_resource_released(const struct wined3d_device *device,
+ struct wined3d_resource *resource, enum wined3d_resource_type type) DECLSPEC_HIDDEN;
+void context_resource_unloaded(const struct wined3d_device *device,
+ struct wined3d_resource *resource, enum wined3d_resource_type type) DECLSPEC_HIDDEN;
+BOOL context_set_current(struct wined3d_context *ctx) DECLSPEC_HIDDEN;
+void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) DECLSPEC_HIDDEN;
+void context_set_tls_idx(DWORD idx) DECLSPEC_HIDDEN;
+void context_state_drawbuf(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void context_state_fb(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void context_surface_update(struct wined3d_context *context, const struct wined3d_surface *surface) DECLSPEC_HIDDEN;
+
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+void context_clear_on_thread_detach();
+#endif
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT)
+struct wined3d_context *context_find_create(struct wined3d_device *device,
+ struct wined3d_swapchain *swapchain,
+ const struct wined3d_format *ds_format);
+#endif
+
+/*****************************************************************************
+ * Internal representation of a light
+ */
+struct wined3d_light_info
+{
+ struct wined3d_light OriginalParms; /* Note D3D8LIGHT == D3D9LIGHT */
+ DWORD OriginalIndex;
+ LONG glIndex;
+ BOOL enabled;
+
+ /* Converted parms to speed up swapping lights */
+ float lightPosn[4];
+ float lightDirn[4];
+ float exponent;
+ float cutoff;
+
+ struct list entry;
+};
+
+/* The default light parameters */
+extern const struct wined3d_light WINED3D_default_light DECLSPEC_HIDDEN;
+
+struct wined3d_pixel_format
+{
+ int iPixelFormat; /* WGL pixel format */
+ int iPixelType; /* WGL pixel type e.g. WGL_TYPE_RGBA_ARB, WGL_TYPE_RGBA_FLOAT_ARB or WGL_TYPE_COLORINDEX_ARB */
+ int redSize, greenSize, blueSize, alphaSize, colorSize;
+ int depthSize, stencilSize;
+ BOOL windowDrawable;
+ BOOL doubleBuffer;
+ int auxBuffers;
+ int numSamples;
+};
+
+enum wined3d_pci_vendor
+{
+ HW_VENDOR_SOFTWARE = 0x0000,
+ HW_VENDOR_AMD = 0x1002,
+ HW_VENDOR_NVIDIA = 0x10de,
+ HW_VENDOR_INTEL = 0x8086,
+};
+
+enum wined3d_pci_device
+{
+ CARD_WINE = 0x0000,
+
+ CARD_AMD_RAGE_128PRO = 0x5246,
+ CARD_AMD_RADEON_7200 = 0x5144,
+ CARD_AMD_RADEON_8500 = 0x514c,
+ CARD_AMD_RADEON_9500 = 0x4144,
+ CARD_AMD_RADEON_XPRESS_200M = 0x5955,
+ CARD_AMD_RADEON_X700 = 0x5e4c,
+ CARD_AMD_RADEON_X1600 = 0x71c2,
+ CARD_AMD_RADEON_HD2350 = 0x94c7,
+ CARD_AMD_RADEON_HD2600 = 0x9581,
+ CARD_AMD_RADEON_HD2900 = 0x9400,
+ CARD_AMD_RADEON_HD3200 = 0x9620,
+ CARD_AMD_RADEON_HD4200M = 0x9712,
+ CARD_AMD_RADEON_HD4350 = 0x954f,
+ CARD_AMD_RADEON_HD4600 = 0x9495,
+ CARD_AMD_RADEON_HD4700 = 0x944e,
+ CARD_AMD_RADEON_HD4800 = 0x944c,
+ CARD_AMD_RADEON_HD5400 = 0x68f9,
+ CARD_AMD_RADEON_HD5600 = 0x68d8,
+ CARD_AMD_RADEON_HD5700 = 0x68be,
+ CARD_AMD_RADEON_HD5800 = 0x6898,
+ CARD_AMD_RADEON_HD5900 = 0x689c,
+ CARD_AMD_RADEON_HD6300 = 0x9803,
+ CARD_AMD_RADEON_HD6400 = 0x6770,
+ CARD_AMD_RADEON_HD6410D = 0x9644,
+ CARD_AMD_RADEON_HD6550D = 0x9640,
+ CARD_AMD_RADEON_HD6600 = 0x6758,
+ CARD_AMD_RADEON_HD6600M = 0x6741,
+ CARD_AMD_RADEON_HD6700 = 0x68ba,
+ CARD_AMD_RADEON_HD6800 = 0x6739,
+ CARD_AMD_RADEON_HD6900 = 0x6719,
+ CARD_AMD_RADEON_HD7700 = 0x683d,
+ CARD_AMD_RADEON_HD7800 = 0x6819,
+ CARD_AMD_RADEON_HD7900 = 0x679a,
+
+ CARD_NVIDIA_RIVA_128 = 0x0018,
+ CARD_NVIDIA_RIVA_TNT = 0x0020,
+ CARD_NVIDIA_RIVA_TNT2 = 0x0028,
+ CARD_NVIDIA_GEFORCE = 0x0100,
+ CARD_NVIDIA_GEFORCE2_MX = 0x0110,
+ CARD_NVIDIA_GEFORCE2 = 0x0150,
+ CARD_NVIDIA_GEFORCE3 = 0x0200,
+ CARD_NVIDIA_GEFORCE4_MX = 0x0170,
+ CARD_NVIDIA_GEFORCE4_TI4200 = 0x0253,
+ CARD_NVIDIA_GEFORCEFX_5200 = 0x0320,
+ CARD_NVIDIA_GEFORCEFX_5600 = 0x0312,
+ CARD_NVIDIA_GEFORCEFX_5800 = 0x0302,
+ CARD_NVIDIA_GEFORCE_6200 = 0x014f,
+ CARD_NVIDIA_GEFORCE_6600GT = 0x0140,
+ CARD_NVIDIA_GEFORCE_6800 = 0x0041,
+ CARD_NVIDIA_GEFORCE_7400 = 0x01d8,
+ CARD_NVIDIA_GEFORCE_7300 = 0x01d7, /* GeForce Go 7300 */
+ CARD_NVIDIA_GEFORCE_7600 = 0x0391,
+ CARD_NVIDIA_GEFORCE_7800GT = 0x0092,
+ CARD_NVIDIA_GEFORCE_8200 = 0x0849, /* Other PCI ID 0x084b */
+ CARD_NVIDIA_GEFORCE_8300GS = 0x0423,
+ CARD_NVIDIA_GEFORCE_8400GS = 0x0404,
+ CARD_NVIDIA_GEFORCE_8500GT = 0x0421,
+ CARD_NVIDIA_GEFORCE_8600GT = 0x0402,
+ CARD_NVIDIA_GEFORCE_8600MGT = 0x0407,
+ CARD_NVIDIA_GEFORCE_8800GTS = 0x0193,
+ CARD_NVIDIA_GEFORCE_8800GTX = 0x0191,
+ CARD_NVIDIA_GEFORCE_9200 = 0x086d,
+ CARD_NVIDIA_GEFORCE_9300 = 0x086c,
+ CARD_NVIDIA_GEFORCE_9400M = 0x0863,
+ CARD_NVIDIA_GEFORCE_9400GT = 0x042c,
+ CARD_NVIDIA_GEFORCE_9500GT = 0x0640,
+ CARD_NVIDIA_GEFORCE_9600GT = 0x0622,
+ CARD_NVIDIA_GEFORCE_9800GT = 0x0614,
+ CARD_NVIDIA_GEFORCE_210 = 0x0a23,
+ CARD_NVIDIA_GEFORCE_GT220 = 0x0a20,
+ CARD_NVIDIA_GEFORCE_GT240 = 0x0ca3,
+ CARD_NVIDIA_GEFORCE_GTX260 = 0x05e2,
+ CARD_NVIDIA_GEFORCE_GTX275 = 0x05e6,
+ CARD_NVIDIA_GEFORCE_GTX280 = 0x05e1,
+ CARD_NVIDIA_GEFORCE_315M = 0x0a7a,
+ CARD_NVIDIA_GEFORCE_320M = 0x08a3,
+ CARD_NVIDIA_GEFORCE_GT320M = 0x0a2d,
+ CARD_NVIDIA_GEFORCE_GT325M = 0x0a35,
+ CARD_NVIDIA_GEFORCE_GT330 = 0x0ca0,
+ CARD_NVIDIA_GEFORCE_GTS350M = 0x0cb0,
+ CARD_NVIDIA_GEFORCE_410M = 0x1055,
+ CARD_NVIDIA_GEFORCE_GT420 = 0x0de2,
+ CARD_NVIDIA_GEFORCE_GT430 = 0x0de1,
+ CARD_NVIDIA_GEFORCE_GT440 = 0x0de0,
+ CARD_NVIDIA_GEFORCE_GTS450 = 0x0dc4,
+ CARD_NVIDIA_GEFORCE_GTX460 = 0x0e22,
+ CARD_NVIDIA_GEFORCE_GTX460M = 0x0dd1,
+ CARD_NVIDIA_GEFORCE_GTX465 = 0x06c4,
+ CARD_NVIDIA_GEFORCE_GTX470 = 0x06cd,
+ CARD_NVIDIA_GEFORCE_GTX480 = 0x06c0,
+ CARD_NVIDIA_GEFORCE_GT520 = 0x1040,
+ CARD_NVIDIA_GEFORCE_GT540M = 0x0df4,
+ CARD_NVIDIA_GEFORCE_GTX550 = 0x1244,
+ CARD_NVIDIA_GEFORCE_GT555M = 0x04b8,
+ CARD_NVIDIA_GEFORCE_GTX560TI = 0x1200,
+ CARD_NVIDIA_GEFORCE_GTX560 = 0x1201,
+ CARD_NVIDIA_GEFORCE_GTX570 = 0x1081,
+ CARD_NVIDIA_GEFORCE_GTX580 = 0x1080,
+ CARD_NVIDIA_GEFORCE_GT610 = 0x104a,
+ CARD_NVIDIA_GEFORCE_GT630 = 0x0f00,
+ CARD_NVIDIA_GEFORCE_GT630M = 0x0de9,
+ CARD_NVIDIA_GEFORCE_GT640M = 0x0fd2,
+ CARD_NVIDIA_GEFORCE_GT650M = 0x0fd1,
+ CARD_NVIDIA_GEFORCE_GTX650 = 0x0fc6,
+ CARD_NVIDIA_GEFORCE_GTX650TI = 0x11c6,
+ CARD_NVIDIA_GEFORCE_GTX660 = 0x11c0,
+ CARD_NVIDIA_GEFORCE_GTX660TI = 0x1183,
+ CARD_NVIDIA_GEFORCE_GTX670 = 0x1189,
+ CARD_NVIDIA_GEFORCE_GTX670MX = 0x11a1,
+ CARD_NVIDIA_GEFORCE_GTX680 = 0x1180,
+ CARD_NVIDIA_GEFORCE_GTX770M = 0x11e0,
+
+ CARD_INTEL_830M = 0x3577,
+ CARD_INTEL_855GM = 0x3582,
+ CARD_INTEL_845G = 0x2562,
+ CARD_INTEL_865G = 0x2572,
+ CARD_INTEL_915G = 0x2582,
+ CARD_INTEL_E7221G = 0x258a,
+ CARD_INTEL_915GM = 0x2592,
+ CARD_INTEL_945G = 0x2772,
+ CARD_INTEL_945GM = 0x27a2,
+ CARD_INTEL_945GME = 0x27ae,
+ CARD_INTEL_Q35 = 0x29b2,
+ CARD_INTEL_G33 = 0x29c2,
+ CARD_INTEL_Q33 = 0x29d2,
+ CARD_INTEL_PNVG = 0xa001,
+ CARD_INTEL_PNVM = 0xa011,
+ CARD_INTEL_965Q = 0x2992,
+ CARD_INTEL_965G = 0x2982,
+ CARD_INTEL_946GZ = 0x2972,
+ CARD_INTEL_965GM = 0x2a02,
+ CARD_INTEL_965GME = 0x2a12,
+ CARD_INTEL_GM45 = 0x2a42,
+ CARD_INTEL_IGD = 0x2e02,
+ CARD_INTEL_Q45 = 0x2e12,
+ CARD_INTEL_G45 = 0x2e22,
+ CARD_INTEL_G41 = 0x2e32,
+ CARD_INTEL_B43 = 0x2e92,
+ CARD_INTEL_ILKD = 0x0042,
+ CARD_INTEL_ILKM = 0x0046,
+ CARD_INTEL_SNBD = 0x0122,
+ CARD_INTEL_SNBM = 0x0126,
+ CARD_INTEL_SNBS = 0x010a,
+ CARD_INTEL_IVBD = 0x0162,
+ CARD_INTEL_IVBM = 0x0166,
+ CARD_INTEL_IVBS = 0x015a,
+};
+
+struct wined3d_fbo_ops
+{
+ GLboolean (WINE_GLAPI *glIsRenderbuffer)(GLuint renderbuffer);
+ void (WINE_GLAPI *glBindRenderbuffer)(GLenum target, GLuint renderbuffer);
+ void (WINE_GLAPI *glDeleteRenderbuffers)(GLsizei n, const GLuint *renderbuffers);
+ void (WINE_GLAPI *glGenRenderbuffers)(GLsizei n, GLuint *renderbuffers);
+ void (WINE_GLAPI *glRenderbufferStorage)(GLenum target, GLenum internalformat,
+ GLsizei width, GLsizei height);
+ void (WINE_GLAPI *glRenderbufferStorageMultisample)(GLenum target, GLsizei samples,
+ GLenum internalformat, GLsizei width, GLsizei height);
+ void (WINE_GLAPI *glGetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint *params);
+ GLboolean (WINE_GLAPI *glIsFramebuffer)(GLuint framebuffer);
+ void (WINE_GLAPI *glBindFramebuffer)(GLenum target, GLuint framebuffer);
+ void (WINE_GLAPI *glDeleteFramebuffers)(GLsizei n, const GLuint *framebuffers);
+ void (WINE_GLAPI *glGenFramebuffers)(GLsizei n, GLuint *framebuffers);
+ GLenum (WINE_GLAPI *glCheckFramebufferStatus)(GLenum target);
+ void (WINE_GLAPI *glFramebufferTexture1D)(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture, GLint level);
+ void (WINE_GLAPI *glFramebufferTexture2D)(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture, GLint level);
+ void (WINE_GLAPI *glFramebufferTexture3D)(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture, GLint level, GLint layer);
+ void (WINE_GLAPI *glFramebufferRenderbuffer)(GLenum target, GLenum attachment,
+ GLenum renderbuffertarget, GLuint renderbuffer);
+ void (WINE_GLAPI *glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment,
+ GLenum pname, GLint *params);
+ void (WINE_GLAPI *glBlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+ void (WINE_GLAPI *glGenerateMipmap)(GLenum target);
+};
+
+struct wined3d_gl_limits
+{
+ UINT buffers;
+ UINT lights;
+ UINT textures;
+ UINT texture_coords;
+ UINT fragment_samplers;
+ UINT vertex_samplers;
+ UINT combined_samplers;
+ UINT general_combiners;
+ UINT clipplanes;
+ UINT texture_size;
+ UINT texture3d_size;
+ float pointsize_max;
+ float pointsize_min;
+ UINT blends;
+ UINT anisotropy;
+ float shininess;
+ UINT samples;
+ UINT vertex_attribs;
+
+ UINT glsl_varyings;
+ UINT glsl_vs_float_constants;
+ UINT glsl_ps_float_constants;
+
+ UINT arb_vs_float_constants;
+ UINT arb_vs_native_constants;
+ UINT arb_vs_instructions;
+ UINT arb_vs_temps;
+ UINT arb_ps_float_constants;
+ UINT arb_ps_local_constants;
+ UINT arb_ps_native_constants;
+ UINT arb_ps_instructions;
+ UINT arb_ps_temps;
+};
+
+struct wined3d_gl_info
+{
+ DWORD glsl_version;
+ struct wined3d_gl_limits limits;
+ DWORD reserved_glsl_constants, reserved_arb_constants;
+ DWORD quirks;
+ BOOL supported[WINED3D_GL_EXT_COUNT];
+ GLint wrap_lookup[WINED3D_TADDRESS_MIRROR_ONCE - WINED3D_TADDRESS_WRAP + 1];
+
+ HGLRC (WINAPI *p_wglCreateContextAttribsARB)(HDC dc, HGLRC share, const GLint *attribs);
+ struct opengl_funcs gl_ops;
+ struct wined3d_fbo_ops fbo_ops;
+
+ struct wined3d_format *formats;
+};
+
+struct wined3d_driver_info
+{
+ enum wined3d_pci_vendor vendor;
+ enum wined3d_pci_device device;
+ const char *name;
+ const char *description;
+ unsigned int vidmem;
+ DWORD version_high;
+ DWORD version_low;
+};
+
+struct wined3d_d3d_limits
+{
+ UINT vs_version, gs_version, ps_version;
+ DWORD vs_uniform_count;
+ DWORD ps_uniform_count;
+ UINT ffp_textures;
+ UINT ffp_blend_stages;
+};
+
+struct wined3d_d3d_info
+{
+ struct wined3d_d3d_limits limits;
+ BOOL xyzrhw;
+ BOOL vs_clipping;
+ DWORD valid_rt_mask;
+};
+
+/* The adapter structure */
+struct wined3d_adapter
+{
+ UINT ordinal;
+ POINT monitorPoint;
+ enum wined3d_format_id screen_format;
+
+ struct wined3d_gl_info gl_info;
+ struct wined3d_d3d_info d3d_info;
+ struct wined3d_driver_info driver_info;
+ WCHAR DeviceName[CCHDEVICENAME]; /* DeviceName for use with e.g. ChangeDisplaySettings */
+ unsigned int cfg_count;
+ struct wined3d_pixel_format *cfgs;
+#ifndef VBOX_WITH_WDDM
+ unsigned int TextureRam; /* Amount of texture memory both video ram + AGP/TurboCache/HyperMemory/.. */
+ unsigned int UsedTextureRam;
+#endif
+ LUID luid;
+
+ const struct wined3d_vertex_pipe_ops *vertex_pipe;
+ const struct fragment_pipeline *fragment_pipe;
+ const struct wined3d_shader_backend_ops *shader_backend;
+ const struct blit_shader *blitter;
+};
+
+BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter) DECLSPEC_HIDDEN;
+
+#ifndef VBOX_WITH_WDDM
+unsigned int adapter_adjust_memory(struct wined3d_adapter *adapter, int amount) DECLSPEC_HIDDEN;
+#endif
+
+BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
+extern void add_gl_compat_wrappers(struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
+
+enum projection_types
+{
+ proj_none = 0,
+ proj_count3 = 1,
+ proj_count4 = 2
+};
+
+enum dst_arg
+{
+ resultreg = 0,
+ tempreg = 1
+};
+
+/*****************************************************************************
+ * Fixed function pipeline replacements
+ */
+#define ARG_UNUSED 0xff
+struct texture_stage_op
+{
+ unsigned cop : 8;
+ unsigned carg1 : 8;
+ unsigned carg2 : 8;
+ unsigned carg0 : 8;
+
+ unsigned aop : 8;
+ unsigned aarg1 : 8;
+ unsigned aarg2 : 8;
+ unsigned aarg0 : 8;
+
+ struct color_fixup_desc color_fixup;
+ unsigned tex_type : 3;
+ unsigned dst : 1;
+ unsigned projected : 2;
+ unsigned padding : 10;
+};
+
+struct ffp_frag_settings
+{
+ struct texture_stage_op op[MAX_TEXTURES];
+ enum wined3d_ffp_ps_fog_mode fog;
+ /* Use shorts instead of chars to get dword alignment */
+ unsigned short sRGB_write;
+ unsigned short emul_clipplanes;
+};
+
+struct ffp_frag_desc
+{
+ struct wine_rb_entry entry;
+ struct ffp_frag_settings settings;
+};
+
+extern const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions DECLSPEC_HIDDEN;
+extern const struct wine_rb_functions wined3d_ffp_vertex_program_rb_functions DECLSPEC_HIDDEN;
+extern const struct wined3d_parent_ops wined3d_null_parent_ops DECLSPEC_HIDDEN;
+
+void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d_state *state,
+ struct ffp_frag_settings *settings, BOOL ignore_textype) DECLSPEC_HIDDEN;
+const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
+ const struct ffp_frag_settings *settings) DECLSPEC_HIDDEN;
+void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc) DECLSPEC_HIDDEN;
+void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect) DECLSPEC_HIDDEN;
+
+enum wined3d_ffp_vs_fog_mode
+{
+ WINED3D_FFP_VS_FOG_OFF = 0,
+ WINED3D_FFP_VS_FOG_FOGCOORD = 1,
+ WINED3D_FFP_VS_FOG_DEPTH = 2,
+ WINED3D_FFP_VS_FOG_RANGE = 3,
+};
+
+#define WINED3D_FFP_TCI_SHIFT 16
+#define WINED3D_FFP_TCI_MASK 0xff
+
+#define WINED3D_FFP_LIGHT_TYPE_SHIFT(idx) (3 * (idx))
+#define WINED3D_FFP_LIGHT_TYPE_MASK 0x7
+
+struct wined3d_ffp_vs_settings
+{
+ DWORD light_type : 24; /* MAX_ACTIVE_LIGHTS, 8 * 3 */
+ DWORD diffuse_source : 2;
+ DWORD emission_source : 2;
+ DWORD ambient_source : 2;
+ DWORD specular_source : 2;
+
+ DWORD transformed : 1;
+ DWORD clipping : 1;
+ DWORD normal : 1;
+ DWORD normalize : 1;
+ DWORD lighting : 1;
+ DWORD localviewer : 1;
+ DWORD point_size : 1;
+ DWORD fog_mode : 2;
+ DWORD texcoords : 8; /* MAX_TEXTURES */
+ DWORD padding : 15;
+
+ BYTE texgen[MAX_TEXTURES];
+};
+
+struct wined3d_ffp_vs_desc
+{
+ struct wine_rb_entry entry;
+ struct wined3d_ffp_vs_settings settings;
+};
+
+void wined3d_ffp_get_vs_settings(const struct wined3d_state *state, const struct wined3d_stream_info *si,
+ struct wined3d_ffp_vs_settings *settings) DECLSPEC_HIDDEN;
+
+struct wined3d
+{
+ LONG ref;
+ DWORD flags;
+ UINT dxVersion;
+ UINT adapter_count;
+ struct wined3d_adapter adapters[1];
+};
+
+HRESULT wined3d_init(struct wined3d *wined3d, UINT version, DWORD flags) DECLSPEC_HIDDEN;
+#ifndef VBOX_WITH_WDDM
+BOOL wined3d_register_window(HWND window, struct wined3d_device *device) DECLSPEC_HIDDEN;
+void wined3d_unregister_window(HWND window) DECLSPEC_HIDDEN;
+#endif
+
+/*****************************************************************************
+ * IWineD3DDevice implementation structure
+ */
+#define WINED3D_UNMAPPED_STAGE ~0U
+
+/* Multithreaded flag. Removed from the public header to signal that IWineD3D::CreateDevice ignores it */
+#define WINED3DCREATE_MULTITHREADED 0x00000004
+
+struct wined3d_device
+{
+ LONG ref;
+
+ /* WineD3D Information */
+ struct wined3d_device_parent *device_parent;
+ struct wined3d *wined3d;
+ struct wined3d_adapter *adapter;
+
+ /* Window styles to restore when switching fullscreen mode */
+ LONG style;
+ LONG exStyle;
+
+ /* X and GL Information */
+ GLenum offscreenBuffer;
+
+ const struct wined3d_shader_backend_ops *shader_backend;
+ void *shader_priv;
+ void *fragment_priv;
+ void *vertex_priv;
+ void *blit_priv;
+ struct StateEntry StateTable[STATE_HIGHEST + 1];
+ /* Array of functions for states which are handled by more than one pipeline part */
+ APPLYSTATEFUNC *multistate_funcs[STATE_HIGHEST + 1];
+ const struct blit_shader *blitter;
+
+ UINT instance_count;
+
+ WORD vertexBlendUsed : 1; /* To avoid needless setting of the blend matrices */
+ WORD isRecordingState : 1;
+ WORD isInDraw : 1;
+ WORD bCursorVisible : 1;
+ WORD d3d_initialized : 1;
+ WORD inScene : 1; /* A flag to check for proper BeginScene / EndScene call pairs */
+ WORD softwareVertexProcessing : 1; /* process vertex shaders using software or hardware */
+ WORD useDrawStridedSlow : 1;
+ WORD filter_messages : 1;
+ WORD padding : 7;
+
+ BYTE fixed_function_usage_map; /* MAX_TEXTURES, 8 */
+
+#define DDRAW_PITCH_ALIGNMENT 8
+#define D3D8_PITCH_ALIGNMENT 4
+ unsigned char surface_alignment; /* Line Alignment of surfaces */
+
+ /* State block related */
+ struct wined3d_stateblock *stateBlock;
+ struct wined3d_stateblock *updateStateBlock;
+
+ /* Internal use fields */
+ struct wined3d_device_creation_parameters create_parms;
+#ifndef VBOX_WITH_WDDM
+ HWND focus_window;
+#endif
+
+ struct wined3d_swapchain **swapchains;
+ UINT swapchain_count;
+
+ struct list resources; /* a linked list to track resources created by the device */
+ struct list shaders; /* a linked list to track shaders (pixel and vertex) */
+
+ /* Render Target Support */
+ struct wined3d_fb_state fb;
+ struct wined3d_surface *onscreen_depth_stencil;
+ struct wined3d_surface *auto_depth_stencil;
+
+ /* For rendering to a texture using glCopyTexImage */
+ GLuint depth_blt_texture;
+
+ /* Cursor management */
+ UINT xHotSpot;
+ UINT yHotSpot;
+ UINT xScreenSpace;
+ UINT yScreenSpace;
+ UINT cursorWidth, cursorHeight;
+ GLuint cursorTexture;
+ HCURSOR hardwareCursor;
+
+ /* The Wine logo surface */
+ struct wined3d_surface *logo_surface;
+
+ /* Textures for when no other textures are mapped */
+ UINT dummy_texture_2d[MAX_COMBINED_SAMPLERS];
+ UINT dummy_texture_rect[MAX_COMBINED_SAMPLERS];
+ UINT dummy_texture_3d[MAX_COMBINED_SAMPLERS];
+ UINT dummy_texture_cube[MAX_COMBINED_SAMPLERS];
+
+ /* With register combiners we can skip junk texture stages */
+ DWORD texUnitMap[MAX_COMBINED_SAMPLERS];
+ DWORD rev_tex_unit_map[MAX_COMBINED_SAMPLERS];
+
+ /* Stream source management */
+ struct wined3d_stream_info stream_info;
+ struct wined3d_event_query *buffer_queries[MAX_ATTRIBS];
+ unsigned int num_buffer_queries;
+
+ /* Context management */
+ struct wined3d_context **contexts;
+ UINT context_count;
+
+#ifdef VBOX_WITH_WINE_FIX_ZEROVERTATTR
+ /* number of vertices in the current draw operation */
+ GLuint czvDrawVertices;
+ /* ogl 2.1 requires 0 vertattr to be present
+ * GL_ARRAY_BUFFER_ARB buffer */
+ GLuint zvBuffer;
+ /* buffer length */
+ GLuint cbzvBuffer;
+ /* current buffer value type */
+ GLenum enmzvValue;
+ /* number of values stored in the buffer currently */
+ GLuint czvValue;
+ /* number of elements in a value */
+ GLuint czvValueElements;
+ /* current buffer value */
+ union
+ {
+ GLfloat f[4];
+ GLuint ui[4];
+ GLubyte ub[4];
+ GLshort s[4];
+ GLushort us[4];
+ } zvValue;
+#endif
+
+#ifdef VBOX_WITH_WDDM
+ struct VBOXUHGSMI *pHgsmi;
+#endif
+
+#ifdef VBOX_WINE_WITH_SHADER_CACHE
+ VBOXEXT_HASHCACHE vshaderCache;
+ VBOXEXT_HASHCACHE pshaderCache;
+#endif
+
+#ifdef VBOX_WINE_WITH_PROFILE
+ VBOXWINEPROFILE_DRAWPRIM DrawPrimProfile;
+#endif
+};
+
+void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, const struct wined3d_fb_state *fb,
+ UINT rect_count, const RECT *rects, const RECT *draw_rect, DWORD flags,
+ const struct wined3d_color *color, float depth, DWORD stencil) DECLSPEC_HIDDEN;
+BOOL device_context_add(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
+void device_context_remove(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
+HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
+ UINT adapter_idx, enum wined3d_device_type device_type, HWND focus_window, DWORD flags,
+ BYTE surface_alignment, struct wined3d_device_parent *device_parent) DECLSPEC_HIDDEN;
+void device_preload_textures(const struct wined3d_device *device) DECLSPEC_HIDDEN;
+#ifndef VBOX_WITH_WDDM
+LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL unicode,
+ UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc) DECLSPEC_HIDDEN;
+#else
+void surface_setup_location_onopen(struct wined3d_surface *surface);
+#endif
+void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
+void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
+void device_switch_onscreen_ds(struct wined3d_device *device, struct wined3d_context *context,
+ struct wined3d_surface *depth_stencil) DECLSPEC_HIDDEN;
+void device_update_stream_info(struct wined3d_device *device, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
+void device_update_tex_unit_map(struct wined3d_device *device) DECLSPEC_HIDDEN;
+void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN;
+
+static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state)
+{
+ DWORD idx = state / (sizeof(*context->isStateDirty) * CHAR_BIT);
+ BYTE shift = state & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1);
+ return context->isStateDirty[idx] & (1 << shift);
+}
+
+static inline void invalidate_active_texture(const struct wined3d_device *device, struct wined3d_context *context)
+{
+ DWORD sampler = device->rev_tex_unit_map[context->active_texture];
+ if (sampler != WINED3D_UNMAPPED_STAGE)
+ context_invalidate_state(context, STATE_SAMPLER(sampler));
+}
+
+#define WINED3D_RESOURCE_ACCESS_GPU 0x1
+#define WINED3D_RESOURCE_ACCESS_CPU 0x2
+/* SCRATCH is mostly the same as CPU, but can't be used by the GPU at all,
+ * not even for resource uploads. */
+#define WINED3D_RESOURCE_ACCESS_SCRATCH 0x4
+
+struct wined3d_resource_ops
+{
+ void (*resource_unload)(struct wined3d_resource *resource);
+};
+
+struct wined3d_resource
+{
+ LONG ref;
+ LONG bind_count;
+ LONG map_count;
+ struct wined3d_device *device;
+ enum wined3d_resource_type type;
+ const struct wined3d_format *format;
+ enum wined3d_multisample_type multisample_type;
+ UINT multisample_quality;
+ DWORD usage;
+ enum wined3d_pool pool;
+ DWORD access_flags;
+ UINT width;
+ UINT height;
+ UINT depth;
+ UINT size;
+ DWORD priority;
+ BYTE *allocatedMemory; /* Pointer to the real data location */
+ BYTE *heapMemory; /* Pointer to the HeapAlloced block of memory */
+#ifdef VBOX_WITH_WDDM
+ DWORD sharerc_flags; /* shared resource flags */
+ DWORD sharerc_handle; /* shared resource handle */
+ DWORD sharerc_locks; /* lock count */
+#endif
+ struct list privateData;
+ struct list resource_list_entry;
+
+ void *parent;
+ const struct wined3d_parent_ops *parent_ops;
+ const struct wined3d_resource_ops *resource_ops;
+};
+
+void resource_cleanup(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
+DWORD resource_get_priority(const struct wined3d_resource *resource) DECLSPEC_HIDDEN;
+HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *device,
+ enum wined3d_resource_type type, const struct wined3d_format *format,
+ enum wined3d_multisample_type multisample_type, UINT multisample_quality,
+ DWORD usage, enum wined3d_pool pool, UINT width, UINT height, UINT depth, UINT size,
+ void *parent, const struct wined3d_parent_ops *parent_ops,
+ const struct wined3d_resource_ops *resource_ops
+#ifdef VBOX_WITH_WDDM
+ , HANDLE *shared_handle
+ , void *pvClientMem
+#endif
+ ) DECLSPEC_HIDDEN;
+DWORD resource_set_priority(struct wined3d_resource *resource, DWORD priority) DECLSPEC_HIDDEN;
+void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
+
+/* Tests show that the start address of resources is 32 byte aligned */
+#define RESOURCE_ALIGNMENT 16
+
+enum wined3d_texture_state
+{
+ WINED3DTEXSTA_ADDRESSU = 0,
+ WINED3DTEXSTA_ADDRESSV = 1,
+ WINED3DTEXSTA_ADDRESSW = 2,
+ WINED3DTEXSTA_BORDERCOLOR = 3,
+ WINED3DTEXSTA_MAGFILTER = 4,
+ WINED3DTEXSTA_MINFILTER = 5,
+ WINED3DTEXSTA_MIPFILTER = 6,
+ WINED3DTEXSTA_MAXMIPLEVEL = 7,
+ WINED3DTEXSTA_MAXANISOTROPY = 8,
+ WINED3DTEXSTA_SRGBTEXTURE = 9,
+ WINED3DTEXSTA_SHADOW = 10,
+ MAX_WINETEXTURESTATES = 11,
+};
+
+enum WINED3DSRGB
+{
+ SRGB_ANY = 0, /* Uses the cached value(e.g. external calls) */
+ SRGB_RGB = 1, /* Loads the rgb texture */
+ SRGB_SRGB = 2, /* Loads the srgb texture */
+};
+
+struct gl_texture
+{
+ DWORD states[MAX_WINETEXTURESTATES];
+ BOOL dirty;
+ GLuint name;
+};
+
+struct wined3d_texture_ops
+{
+ HRESULT (*texture_bind)(struct wined3d_texture *texture,
+ struct wined3d_context *context, BOOL srgb);
+ void (*texture_preload)(struct wined3d_texture *texture, enum WINED3DSRGB srgb);
+ void (*texture_sub_resource_add_dirty_region)(struct wined3d_resource *sub_resource,
+ const struct wined3d_box *dirty_region);
+ void (*texture_sub_resource_cleanup)(struct wined3d_resource *sub_resource);
+};
+
+#define WINED3D_TEXTURE_COND_NP2 0x1
+#define WINED3D_TEXTURE_POW2_MAT_IDENT 0x2
+#define WINED3D_TEXTURE_IS_SRGB 0x4
+
+struct wined3d_texture
+{
+ struct wined3d_resource resource;
+ const struct wined3d_texture_ops *texture_ops;
+ struct gl_texture texture_rgb, texture_srgb;
+ struct wined3d_resource **sub_resources;
+ UINT layer_count;
+ UINT level_count;
+ float pow2_matrix[16];
+ UINT lod;
+ enum wined3d_texture_filter_type filter_type;
+ DWORD sampler;
+ DWORD flags;
+ const struct min_lookup *min_mip_lookup;
+ const GLenum *mag_lookup;
+ GLenum target;
+};
+
+#ifdef VBOX
+# ifdef VBOX_WITH_WDDM
+#define texture_gl_delete(_t) do { \
+ pglChromiumParameteriCR(GL_RCUSAGE_TEXTURE_CLEAR_CR, _t); \
+ } while (0)
+# else
+#define texture_gl_delete(_t) do { \
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &_t); \
+ } while (0)
+
+# endif
+#endif
+
+static inline struct wined3d_texture *wined3d_texture_from_resource(struct wined3d_resource *resource)
+{
+ return CONTAINING_RECORD(resource, struct wined3d_texture, resource);
+}
+
+static inline struct gl_texture *wined3d_texture_get_gl_texture(struct wined3d_texture *texture,
+ const struct wined3d_gl_info *gl_info, BOOL srgb)
+{
+ return srgb && !gl_info->supported[EXT_TEXTURE_SRGB_DECODE]
+ ? &texture->texture_srgb : &texture->texture_rgb;
+}
+
+void wined3d_texture_apply_state_changes(struct wined3d_texture *texture,
+ const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1],
+ const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
+void wined3d_texture_set_dirty(struct wined3d_texture *texture, BOOL dirty) DECLSPEC_HIDDEN;
+
+struct wined3d_volume
+{
+ struct wined3d_resource resource;
+ struct wined3d_texture *container;
+ BOOL lockable;
+ BOOL locked;
+ struct wined3d_box lockedBox;
+ struct wined3d_box dirtyBox;
+ BOOL dirty;
+};
+
+static inline struct wined3d_volume *volume_from_resource(struct wined3d_resource *resource)
+{
+ return CONTAINING_RECORD(resource, struct wined3d_volume, resource);
+}
+
+void volume_add_dirty_box(struct wined3d_volume *volume, const struct wined3d_box *dirty_box) DECLSPEC_HIDDEN;
+void volume_load(const struct wined3d_volume *volume, struct wined3d_context *context, UINT level, BOOL srgb_mode) DECLSPEC_HIDDEN;
+void volume_set_container(struct wined3d_volume *volume, struct wined3d_texture *container) DECLSPEC_HIDDEN;
+
+struct wined3d_surface_dib
+{
+ HBITMAP DIBsection;
+ void *bitmap_data;
+ UINT bitmap_size;
+};
+
+struct wined3d_renderbuffer_entry
+{
+ struct list entry;
+ GLuint id;
+ UINT width;
+ UINT height;
+};
+
+struct fbo_entry
+{
+ struct list entry;
+ struct wined3d_surface **render_targets;
+ struct wined3d_surface *depth_stencil;
+ DWORD location;
+ DWORD rt_mask;
+ BOOL attached;
+ GLuint id;
+};
+
+struct wined3d_surface_ops
+{
+ HRESULT (*surface_private_setup)(struct wined3d_surface *surface);
+ void (*surface_realize_palette)(struct wined3d_surface *surface);
+ void (*surface_map)(struct wined3d_surface *surface, const RECT *rect, DWORD flags);
+ void (*surface_unmap)(struct wined3d_surface *surface);
+};
+
+struct wined3d_surface
+{
+ struct wined3d_resource resource;
+ const struct wined3d_surface_ops *surface_ops;
+ struct wined3d_texture *container;
+ struct wined3d_swapchain *swapchain;
+ struct wined3d_palette *palette; /* D3D7 style palette handling */
+ DWORD draw_binding;
+
+ DWORD flags;
+
+ UINT pitch;
+ UINT pow2Width;
+ UINT pow2Height;
+
+ /* A method to retrieve the drawable size. Not in the Vtable to make it changeable */
+ void (*get_drawable_size)(const struct wined3d_context *context, UINT *width, UINT *height);
+
+ /* PBO */
+ GLuint pbo;
+ GLuint rb_multisample;
+ GLuint rb_resolved;
+ GLuint texture_name;
+ GLuint texture_name_srgb;
+ GLint texture_level;
+ GLenum texture_target;
+
+ RECT lockedRect;
+ RECT dirtyRect;
+ int lockCount;
+#define MAXLOCKCOUNT 50 /* After this amount of locks do not free the sysmem copy */
+
+ /* For GetDC */
+ struct wined3d_surface_dib dib;
+ HDC hDC;
+
+ /* Color keys for DDraw */
+ struct wined3d_color_key dst_blt_color_key;
+ struct wined3d_color_key src_blt_color_key;
+ struct wined3d_color_key dst_overlay_color_key;
+ struct wined3d_color_key src_overlay_color_key;
+ DWORD CKeyFlags;
+
+ struct wined3d_color_key gl_color_key;
+
+ struct list renderbuffers;
+ const struct wined3d_renderbuffer_entry *current_renderbuffer;
+ SIZE ds_current_size;
+
+ /* DirectDraw Overlay handling */
+ RECT overlay_srcrect;
+ RECT overlay_destrect;
+ struct wined3d_surface *overlay_dest;
+ struct list overlays;
+ struct list overlay_entry;
+};
+
+static inline struct wined3d_surface *surface_from_resource(struct wined3d_resource *resource)
+{
+ return CONTAINING_RECORD(resource, struct wined3d_surface, resource);
+}
+
+static inline GLuint surface_get_texture_name(const struct wined3d_surface *surface,
+ const struct wined3d_gl_info *gl_info, BOOL srgb)
+{
+ return srgb && !gl_info->supported[EXT_TEXTURE_SRGB_DECODE]
+ ? surface->texture_name_srgb : surface->texture_name;
+}
+
+void surface_add_dirty_rect(struct wined3d_surface *surface, const struct wined3d_box *dirty_rect) DECLSPEC_HIDDEN;
+HRESULT surface_color_fill(struct wined3d_surface *s,
+ const RECT *rect, const struct wined3d_color *color) DECLSPEC_HIDDEN;
+GLenum surface_get_gl_buffer(const struct wined3d_surface *surface) DECLSPEC_HIDDEN;
+void surface_internal_preload(struct wined3d_surface *surface, enum WINED3DSRGB srgb) DECLSPEC_HIDDEN;
+BOOL surface_is_offscreen(const struct wined3d_surface *surface) DECLSPEC_HIDDEN;
+HRESULT surface_load(struct wined3d_surface *surface, BOOL srgb) DECLSPEC_HIDDEN;
+void surface_load_ds_location(struct wined3d_surface *surface,
+ struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN;
+void surface_load_fb_texture(struct wined3d_surface *surface, BOOL srgb) DECLSPEC_HIDDEN;
+HRESULT surface_load_location(struct wined3d_surface *surface, DWORD location, const RECT *rect) DECLSPEC_HIDDEN;
+void surface_modify_ds_location(struct wined3d_surface *surface, DWORD location, UINT w, UINT h) DECLSPEC_HIDDEN;
+void surface_modify_location(struct wined3d_surface *surface, DWORD location, BOOL persistent) DECLSPEC_HIDDEN;
+void surface_prepare_rb(struct wined3d_surface *surface,
+ const struct wined3d_gl_info *gl_info, BOOL multisample) DECLSPEC_HIDDEN;
+void surface_prepare_texture(struct wined3d_surface *surface,
+ struct wined3d_context *context, BOOL srgb) DECLSPEC_HIDDEN;
+void surface_set_compatible_renderbuffer(struct wined3d_surface *surface,
+ const struct wined3d_surface *rt) DECLSPEC_HIDDEN;
+void surface_set_container(struct wined3d_surface *surface, struct wined3d_texture *container) DECLSPEC_HIDDEN;
+void surface_set_swapchain(struct wined3d_surface *surface, struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
+void surface_set_texture_name(struct wined3d_surface *surface, GLuint name, BOOL srgb_name) DECLSPEC_HIDDEN;
+void surface_set_texture_target(struct wined3d_surface *surface, GLenum target, GLint level) DECLSPEC_HIDDEN;
+void surface_translate_drawable_coords(const struct wined3d_surface *surface, HWND window, RECT *rect) DECLSPEC_HIDDEN;
+void surface_update_draw_binding(struct wined3d_surface *surface) DECLSPEC_HIDDEN;
+HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const POINT *dst_point,
+ struct wined3d_surface *src_surface, const RECT *src_rect) DECLSPEC_HIDDEN;
+
+void get_drawable_size_swapchain(const struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN;
+void get_drawable_size_backbuffer(const struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN;
+void get_drawable_size_fbo(const struct wined3d_context *context, UINT *width, UINT *height) DECLSPEC_HIDDEN;
+
+void draw_textured_quad(const struct wined3d_surface *src_surface, struct wined3d_context *context,
+ const RECT *src_rect, const RECT *dst_rect, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
+void flip_surface(struct wined3d_surface *front, struct wined3d_surface *back) DECLSPEC_HIDDEN;
+
+/* Surface flags: */
+#define SFLAG_CONVERTED 0x00000001 /* Converted for color keying or palettized. */
+#define SFLAG_DISCARD 0x00000002 /* ??? */
+#define SFLAG_NONPOW2 0x00000004 /* Surface sizes are not a power of 2 */
+#define SFLAG_NORMCOORD 0x00000008 /* Set if GL texture coordinates are normalized (non-texture rectangle). */
+#define SFLAG_LOCKABLE 0x00000010 /* Surface can be locked. */
+#define SFLAG_DYNLOCK 0x00000020 /* Surface is often locked by the application. */
+#define SFLAG_PIN_SYSMEM 0x00000040 /* Keep the surface in sysmem, at the same address. */
+#define SFLAG_DCINUSE 0x00000080 /* Set between GetDC and ReleaseDC calls. */
+#define SFLAG_LOST 0x00000100 /* Surface lost flag for ddraw. */
+#define SFLAG_GLCKEY 0x00000200 /* The GL texture was created with a color key. */
+#define SFLAG_CLIENT 0x00000400 /* GL_APPLE_client_storage is used with this surface. */
+#define SFLAG_INOVERLAYDRAW 0x00000800 /* Overlay drawing is in progress. Recursion prevention. */
+#define SFLAG_DIBSECTION 0x00001000 /* Has a DIB section attached for GetDC. */
+#define SFLAG_USERPTR 0x00002000 /* The application allocated the memory for this surface. */
+#define SFLAG_ALLOCATED 0x00004000 /* A GL texture is allocated for this surface. */
+#define SFLAG_SRGBALLOCATED 0x00008000 /* A sRGB GL texture is allocated for this surface. */
+#define SFLAG_PBO 0x00010000 /* The surface has a PBO. */
+#define SFLAG_INSYSMEM 0x00020000 /* The system memory copy is current. */
+#define SFLAG_INTEXTURE 0x00040000 /* The GL texture is current. */
+#define SFLAG_INSRGBTEX 0x00080000 /* The GL sRGB texture is current. */
+#define SFLAG_INDRAWABLE 0x00100000 /* The GL drawable is current. */
+#define SFLAG_INRB_MULTISAMPLE 0x00200000 /* The multisample renderbuffer is current. */
+#define SFLAG_INRB_RESOLVED 0x00400000 /* The resolved renderbuffer is current. */
+#define SFLAG_DISCARDED 0x00800000 /* Surface was discarded, allocating new location is enough. */
+
+#ifdef VBOX_WITH_WDDM
+# define SFLAG_CLIENTMEM 0x10000000 /* SYSMEM surface using client-supplied memory buffer */
+# define SFLAG_DONOTFREE_VBOXWDDM SFLAG_CLIENTMEM
+#else
+# define SFLAG_DONOTFREE_VBOXWDDM 0
+#endif
+
+/* In some conditions the surface memory must not be freed:
+ * SFLAG_CONVERTED: Converting the data back would take too long
+ * SFLAG_DIBSECTION: The dib code manages the memory
+ * SFLAG_DYNLOCK: Avoid freeing the data for performance
+ * SFLAG_PBO: PBOs don't use 'normal' memory. It is either allocated by the driver or must be NULL.
+ * SFLAG_CLIENT: OpenGL uses our memory as backup
+ */
+#define SFLAG_DONOTFREE (SFLAG_CONVERTED | \
+ SFLAG_DYNLOCK | \
+ SFLAG_CLIENT | \
+ SFLAG_DIBSECTION | \
+ SFLAG_USERPTR | \
+ SFLAG_PBO | \
+ SFLAG_PIN_SYSMEM | \
+ /* #ifdef VBOX */ \
+ SFLAG_DONOTFREE_VBOXWDDM \
+ /* #endif */ \
+ )
+
+#define SFLAG_LOCATIONS (SFLAG_INSYSMEM | \
+ SFLAG_INTEXTURE | \
+ SFLAG_INSRGBTEX | \
+ SFLAG_INDRAWABLE | \
+ SFLAG_INRB_MULTISAMPLE | \
+ SFLAG_INRB_RESOLVED)
+
+enum wined3d_conversion_type
+{
+ WINED3D_CT_NONE,
+ WINED3D_CT_PALETTED,
+ WINED3D_CT_PALETTED_CK,
+ WINED3D_CT_CK_565,
+ WINED3D_CT_CK_5551,
+ WINED3D_CT_CK_RGB24,
+ WINED3D_CT_RGB32_888,
+ WINED3D_CT_CK_ARGB32,
+};
+
+void d3dfmt_p8_init_palette(const struct wined3d_surface *surface, BYTE table[256][4], BOOL colorkey) DECLSPEC_HIDDEN;
+
+struct wined3d_sampler
+{
+ LONG refcount;
+ void *parent;
+};
+
+struct wined3d_vertex_declaration_element
+{
+ const struct wined3d_format *format;
+ BOOL ffp_valid;
+ WORD input_slot;
+ WORD offset;
+ UINT output_slot;
+ BYTE method;
+ BYTE usage;
+ BYTE usage_idx;
+};
+
+struct wined3d_vertex_declaration
+{
+ LONG ref;
+ void *parent;
+ const struct wined3d_parent_ops *parent_ops;
+ struct wined3d_device *device;
+
+ struct wined3d_vertex_declaration_element *elements;
+ UINT element_count;
+
+ BOOL position_transformed;
+ BOOL half_float_conv_needed;
+};
+
+struct wined3d_saved_states
+{
+ DWORD transform[(HIGHEST_TRANSFORMSTATE >> 5) + 1];
+ WORD streamSource; /* MAX_STREAMS, 16 */
+ WORD streamFreq; /* MAX_STREAMS, 16 */
+ DWORD renderState[(WINEHIGHEST_RENDER_STATE >> 5) + 1];
+ DWORD textureState[MAX_TEXTURES]; /* WINED3D_HIGHEST_TEXTURE_STATE + 1, 18 */
+ WORD samplerState[MAX_COMBINED_SAMPLERS]; /* WINED3D_HIGHEST_SAMPLER_STATE + 1, 14 */
+ DWORD clipplane; /* WINED3DMAXUSERCLIPPLANES, 32 */
+ WORD pixelShaderConstantsB; /* MAX_CONST_B, 16 */
+ WORD pixelShaderConstantsI; /* MAX_CONST_I, 16 */
+ BOOL *pixelShaderConstantsF;
+ WORD vertexShaderConstantsB; /* MAX_CONST_B, 16 */
+ WORD vertexShaderConstantsI; /* MAX_CONST_I, 16 */
+ BOOL *vertexShaderConstantsF;
+ DWORD textures : 20; /* MAX_COMBINED_SAMPLERS, 20 */
+ DWORD primitive_type : 1;
+ DWORD indices : 1;
+ DWORD material : 1;
+ DWORD viewport : 1;
+ DWORD vertexDecl : 1;
+ DWORD pixelShader : 1;
+ DWORD vertexShader : 1;
+ DWORD scissorRect : 1;
+ DWORD padding : 4;
+};
+
+struct StageState {
+ DWORD stage;
+ DWORD state;
+};
+
+struct wined3d_stream_output
+{
+ struct wined3d_buffer *buffer;
+ UINT offset;
+};
+
+struct wined3d_stream_state
+{
+ struct wined3d_buffer *buffer;
+ UINT offset;
+ UINT stride;
+ UINT frequency;
+ UINT flags;
+};
+
+struct wined3d_state
+{
+ const struct wined3d_fb_state *fb;
+
+ struct wined3d_vertex_declaration *vertex_declaration;
+ struct wined3d_stream_output stream_output[MAX_STREAM_OUT];
+ struct wined3d_stream_state streams[MAX_STREAMS + 1 /* tesselated pseudo-stream */];
+ struct wined3d_buffer *index_buffer;
+ enum wined3d_format_id index_format;
+ INT base_vertex_index;
+ INT load_base_vertex_index; /* Non-indexed drawing needs 0 here, indexed needs base_vertex_index. */
+ GLenum gl_primitive_type;
+
+ struct wined3d_shader *vertex_shader;
+ struct wined3d_buffer *vs_cb[MAX_CONSTANT_BUFFERS];
+ struct wined3d_sampler *vs_sampler[MAX_SAMPLER_OBJECTS];
+ BOOL vs_consts_b[MAX_CONST_B];
+ INT vs_consts_i[MAX_CONST_I * 4];
+ float *vs_consts_f;
+
+ struct wined3d_shader *geometry_shader;
+ struct wined3d_buffer *gs_cb[MAX_CONSTANT_BUFFERS];
+ struct wined3d_sampler *gs_sampler[MAX_SAMPLER_OBJECTS];
+
+ struct wined3d_shader *pixel_shader;
+ struct wined3d_buffer *ps_cb[MAX_CONSTANT_BUFFERS];
+ struct wined3d_sampler *ps_sampler[MAX_SAMPLER_OBJECTS];
+ BOOL ps_consts_b[MAX_CONST_B];
+ INT ps_consts_i[MAX_CONST_I * 4];
+ float *ps_consts_f;
+
+ struct wined3d_texture *textures[MAX_COMBINED_SAMPLERS];
+ DWORD sampler_states[MAX_COMBINED_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1];
+ DWORD texture_states[MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1];
+ DWORD lowest_disabled_stage;
+
+ struct wined3d_matrix transforms[HIGHEST_TRANSFORMSTATE + 1];
+ struct wined3d_vec4 clip_planes[MAX_CLIPPLANES];
+ struct wined3d_material material;
+ struct wined3d_viewport viewport;
+ RECT scissor_rect;
+
+ /* Light hashmap . Collisions are handled using standard wine double linked lists */
+#define LIGHTMAP_SIZE 43 /* Use of a prime number recommended. Set to 1 for a linked list! */
+#define LIGHTMAP_HASHFUNC(x) ((x) % LIGHTMAP_SIZE) /* Primitive and simple function */
+ struct list light_map[LIGHTMAP_SIZE]; /* Hash map containing the lights */
+ const struct wined3d_light_info *lights[MAX_ACTIVE_LIGHTS]; /* Map of opengl lights to d3d lights */
+
+ DWORD render_states[WINEHIGHEST_RENDER_STATE + 1];
+};
+
+struct wined3d_stateblock
+{
+ LONG ref; /* Note: Ref counting not required */
+ struct wined3d_device *device;
+
+ /* Array indicating whether things have been set or changed */
+ struct wined3d_saved_states changed;
+ struct wined3d_state state;
+
+ /* Contained state management */
+ DWORD contained_render_states[WINEHIGHEST_RENDER_STATE + 1];
+ unsigned int num_contained_render_states;
+ DWORD contained_transform_states[HIGHEST_TRANSFORMSTATE + 1];
+ unsigned int num_contained_transform_states;
+ DWORD contained_vs_consts_i[MAX_CONST_I];
+ unsigned int num_contained_vs_consts_i;
+ DWORD contained_vs_consts_b[MAX_CONST_B];
+ unsigned int num_contained_vs_consts_b;
+ DWORD *contained_vs_consts_f;
+ unsigned int num_contained_vs_consts_f;
+ DWORD contained_ps_consts_i[MAX_CONST_I];
+ unsigned int num_contained_ps_consts_i;
+ DWORD contained_ps_consts_b[MAX_CONST_B];
+ unsigned int num_contained_ps_consts_b;
+ DWORD *contained_ps_consts_f;
+ unsigned int num_contained_ps_consts_f;
+ struct StageState contained_tss_states[MAX_TEXTURES * (WINED3D_HIGHEST_TEXTURE_STATE + 1)];
+ unsigned int num_contained_tss_states;
+ struct StageState contained_sampler_states[MAX_COMBINED_SAMPLERS * WINED3D_HIGHEST_SAMPLER_STATE];
+ unsigned int num_contained_sampler_states;
+};
+
+void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) DECLSPEC_HIDDEN;
+void stateblock_init_default_state(struct wined3d_stateblock *stateblock) DECLSPEC_HIDDEN;
+void stateblock_unbind_resources(struct wined3d_stateblock *stateblock) DECLSPEC_HIDDEN;
+
+/* Direct3D terminology with little modifications. We do not have an issued state
+ * because only the driver knows about it, but we have a created state because d3d
+ * allows GetData on a created issue, but opengl doesn't
+ */
+enum query_state {
+ QUERY_CREATED,
+ QUERY_SIGNALLED,
+ QUERY_BUILDING
+};
+
+struct wined3d_query_ops
+{
+ HRESULT (*query_get_data)(struct wined3d_query *query, void *data, DWORD data_size, DWORD flags);
+ HRESULT (*query_issue)(struct wined3d_query *query, DWORD flags);
+};
+
+struct wined3d_query
+{
+ LONG ref;
+ const struct wined3d_query_ops *query_ops;
+ struct wined3d_device *device;
+ enum query_state state;
+ enum wined3d_query_type type;
+ DWORD data_size;
+ void *extendedData;
+};
+
+/* TODO: Add tests and support for FLOAT16_4 POSITIONT, D3DCOLOR position, other
+ * fixed function semantics as D3DCOLOR or FLOAT16 */
+enum wined3d_buffer_conversion_type
+{
+ CONV_NONE,
+ CONV_D3DCOLOR,
+ CONV_POSITIONT,
+};
+
+struct wined3d_map_range
+{
+ UINT offset;
+ UINT size;
+};
+
+#define WINED3D_BUFFER_OPTIMIZED 0x01 /* Optimize has been called for the buffer */
+#define WINED3D_BUFFER_HASDESC 0x02 /* A vertex description has been found */
+#define WINED3D_BUFFER_CREATEBO 0x04 /* Attempt to create a buffer object next PreLoad */
+#define WINED3D_BUFFER_DOUBLEBUFFER 0x08 /* Use a vbo and local allocated memory */
+#define WINED3D_BUFFER_FLUSH 0x10 /* Manual unmap flushing */
+#define WINED3D_BUFFER_DISCARD 0x20 /* A DISCARD lock has occurred since the last PreLoad */
+#define WINED3D_BUFFER_NOSYNC 0x40 /* All locks since the last PreLoad had NOOVERWRITE set */
+#define WINED3D_BUFFER_APPLESYNC 0x80 /* Using sync as in GL_APPLE_flush_buffer_range */
+
+struct wined3d_buffer
+{
+ struct wined3d_resource resource;
+
+ struct wined3d_buffer_desc desc;
+
+ GLuint buffer_object;
+ GLenum buffer_object_usage;
+ GLenum buffer_type_hint;
+ UINT buffer_object_size;
+ DWORD flags;
+
+ struct wined3d_map_range *maps;
+ ULONG maps_size, modified_areas;
+ struct wined3d_event_query *query;
+
+ /* conversion stuff */
+ UINT decl_change_count, full_conversion_count;
+ UINT draw_count;
+ UINT stride; /* 0 if no conversion */
+#ifdef VBOX_WITH_WINE_FIX_BUFOFFSET
+ UINT offset;
+#endif
+ UINT conversion_stride; /* 0 if no shifted conversion */
+ enum wined3d_buffer_conversion_type *conversion_map; /* NULL if no conversion */
+};
+
+static inline struct wined3d_buffer *buffer_from_resource(struct wined3d_resource *resource)
+{
+ return CONTAINING_RECORD(resource, struct wined3d_buffer, resource);
+}
+
+void buffer_get_memory(struct wined3d_buffer *buffer, const struct wined3d_gl_info *gl_info,
+ struct wined3d_bo_address *data) DECLSPEC_HIDDEN;
+BYTE *buffer_get_sysmem(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
+
+struct wined3d_rendertarget_view
+{
+ LONG refcount;
+
+ struct wined3d_resource *resource;
+ void *parent;
+};
+
+struct wined3d_swapchain_ops
+{
+ void (*swapchain_present)(struct wined3d_swapchain *swapchain, const RECT *src_rect,
+ const RECT *dst_rect, const RGNDATA *dirty_region, DWORD flags);
+};
+
+struct wined3d_swapchain
+{
+ LONG ref;
+ void *parent;
+ const struct wined3d_parent_ops *parent_ops;
+ const struct wined3d_swapchain_ops *swapchain_ops;
+ struct wined3d_device *device;
+
+ struct wined3d_surface **back_buffers;
+ struct wined3d_surface *front_buffer;
+ struct wined3d_swapchain_desc desc;
+#ifndef VBOX_WITH_WDDM
+ DWORD orig_width, orig_height;
+ enum wined3d_format_id orig_fmt;
+ struct wined3d_gamma_ramp orig_gamma;
+#endif
+ BOOL render_to_fbo;
+ const struct wined3d_format *ds_format;
+
+ LONG prev_time, frames; /* Performance tracking */
+
+#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+ struct wined3d_context **context;
+ unsigned int num_contexts;
+#else
+ HDC hDC;
+#endif
+ HWND win_handle;
+#ifndef VBOX_WITH_WDDM
+ HWND device_window;
+
+ HDC backup_dc;
+ HWND backup_wnd;
+#endif
+};
+
+void x11_copy_to_screen(const struct wined3d_swapchain *swapchain, const RECT *rect) DECLSPEC_HIDDEN;
+
+struct wined3d_context *swapchain_get_context(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
+void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
+HDC swapchain_get_backup_dc(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
+void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
+void swapchain_update_render_to_fbo(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
+
+#define DEFAULT_REFRESH_RATE 0
+
+/*****************************************************************************
+ * Utility function prototypes
+ */
+
+/* Trace routines */
+const char *debug_d3dformat(enum wined3d_format_id format_id) DECLSPEC_HIDDEN;
+const char *debug_d3ddevicetype(enum wined3d_device_type device_type) DECLSPEC_HIDDEN;
+const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type) DECLSPEC_HIDDEN;
+const char *debug_d3dusage(DWORD usage) DECLSPEC_HIDDEN;
+const char *debug_d3dusagequery(DWORD usagequery) DECLSPEC_HIDDEN;
+const char *debug_d3ddeclmethod(enum wined3d_decl_method method) DECLSPEC_HIDDEN;
+const char *debug_d3ddeclusage(enum wined3d_decl_usage usage) DECLSPEC_HIDDEN;
+const char *debug_d3dprimitivetype(enum wined3d_primitive_type primitive_type) DECLSPEC_HIDDEN;
+const char *debug_d3drenderstate(enum wined3d_render_state state) DECLSPEC_HIDDEN;
+const char *debug_d3dsamplerstate(enum wined3d_sampler_state state) DECLSPEC_HIDDEN;
+const char *debug_d3dstate(DWORD state) DECLSPEC_HIDDEN;
+const char *debug_d3dtexturefiltertype(enum wined3d_texture_filter_type filter_type) DECLSPEC_HIDDEN;
+const char *debug_d3dtexturestate(enum wined3d_texture_stage_state state) DECLSPEC_HIDDEN;
+const char *debug_d3dtstype(enum wined3d_transform_state tstype) DECLSPEC_HIDDEN;
+const char *debug_d3dpool(enum wined3d_pool pool) DECLSPEC_HIDDEN;
+const char *debug_fbostatus(GLenum status) DECLSPEC_HIDDEN;
+const char *debug_glerror(GLenum error) DECLSPEC_HIDDEN;
+const char *debug_d3dtop(enum wined3d_texture_op d3dtop) DECLSPEC_HIDDEN;
+void dump_color_fixup_desc(struct color_fixup_desc fixup) DECLSPEC_HIDDEN;
+const char *debug_surflocation(DWORD flag) DECLSPEC_HIDDEN;
+
+BOOL is_invalid_op(const struct wined3d_state *state, int stage,
+ enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3) DECLSPEC_HIDDEN;
+void set_tex_op_nvrc(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state,
+ BOOL is_alpha, int stage, enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3,
+ INT texture_idx, DWORD dst) DECLSPEC_HIDDEN;
+void set_texture_matrix(const struct wined3d_gl_info *gl_info, const float *smat, DWORD flags,
+ BOOL calculatedCoords, BOOL transformed, enum wined3d_format_id coordtype,
+ BOOL ffp_can_disable_proj) DECLSPEC_HIDDEN;
+void texture_activate_dimensions(const struct wined3d_texture *texture,
+ const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
+void sampler_texdim(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void tex_alphaop(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void apply_pixelshader(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_fogcolor(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_fogdensity(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_fogstartend(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_fog_fragpart(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_srgbwrite(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+
+void sampler_texmatrix(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_specularenable(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void transform_world(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void transform_view(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void transform_projection(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void transform_texture(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_ambient(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void viewport_vertexpart(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_clipping(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void light(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void vertexdeclaration(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void clipplane(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_psizemin_w(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_psizemin_ext(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_psizemin_arb(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_pointsprite_w(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_pointsprite(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_pscale(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+
+BOOL getColorBits(const struct wined3d_format *format,
+ BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize) DECLSPEC_HIDDEN;
+BOOL getDepthStencilBits(const struct wined3d_format *format,
+ BYTE *depthSize, BYTE *stencilSize) DECLSPEC_HIDDEN;
+GLenum gl_primitive_type_from_d3d(enum wined3d_primitive_type primitive_type) DECLSPEC_HIDDEN;
+
+/* Math utils */
+void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1,
+ const struct wined3d_matrix *src2) DECLSPEC_HIDDEN;
+UINT wined3d_log2i(UINT32 x) DECLSPEC_HIDDEN;
+unsigned int count_bits(unsigned int mask) DECLSPEC_HIDDEN;
+
+struct wined3d_shader_lconst
+{
+ struct list entry;
+ unsigned int idx;
+ DWORD value[4];
+};
+
+struct wined3d_shader_limits
+{
+ unsigned int sampler;
+ unsigned int constant_int;
+ unsigned int constant_float;
+ unsigned int constant_bool;
+ unsigned int packed_output;
+ unsigned int packed_input;
+};
+
+#ifdef __GNUC__
+#define PRINTF_ATTR(fmt,args) __attribute__((format (printf,fmt,args)))
+#else
+#define PRINTF_ATTR(fmt,args)
+#endif
+
+/* Base Shader utility functions. */
+int shader_addline(struct wined3d_shader_buffer *buffer, const char *fmt, ...) PRINTF_ATTR(2,3) DECLSPEC_HIDDEN;
+int shader_vaddline(struct wined3d_shader_buffer *buffer, const char *fmt, va_list args) DECLSPEC_HIDDEN;
+
+/* Vertex shader utility functions */
+BOOL vshader_get_input(const struct wined3d_shader *shader,
+ BYTE usage_req, BYTE usage_idx_req, unsigned int *regnum) DECLSPEC_HIDDEN;
+
+struct wined3d_vertex_shader
+{
+ struct wined3d_shader_attribute attributes[MAX_ATTRIBS];
+};
+
+struct wined3d_geometry_shader
+{
+ enum wined3d_primitive_type input_type;
+ enum wined3d_primitive_type output_type;
+ UINT vertices_out;
+};
+
+struct wined3d_pixel_shader
+{
+ /* Pixel shader input semantics */
+ DWORD input_reg_map[MAX_REG_INPUT];
+ BOOL input_reg_used[MAX_REG_INPUT];
+ unsigned int declared_in_count;
+
+ /* Some information about the shader behavior */
+ BOOL color0_mov;
+ DWORD color0_reg;
+};
+
+struct wined3d_shader
+{
+ LONG ref;
+ struct wined3d_shader_limits limits;
+ DWORD *function;
+ UINT functionLength;
+ BOOL load_local_constsF;
+ const struct wined3d_shader_frontend *frontend;
+ void *frontend_data;
+ void *backend_data;
+
+ void *parent;
+ const struct wined3d_parent_ops *parent_ops;
+
+ /* Programs this shader is linked with */
+ struct list linked_programs;
+
+ /* Immediate constants (override global ones) */
+ struct list constantsB;
+ struct list constantsF;
+ struct list constantsI;
+ struct wined3d_shader_reg_maps reg_maps;
+ BOOL lconst_inf_or_nan;
+
+ struct wined3d_shader_signature_element input_signature[max(MAX_ATTRIBS, MAX_REG_INPUT)];
+ struct wined3d_shader_signature_element output_signature[MAX_REG_OUTPUT];
+
+ /* Pointer to the parent device */
+ struct wined3d_device *device;
+ struct list shader_list_entry;
+
+ union
+ {
+ struct wined3d_vertex_shader vs;
+ struct wined3d_geometry_shader gs;
+ struct wined3d_pixel_shader ps;
+ } u;
+
+#ifdef VBOX_WINE_WITH_SHADER_CACHE
+ VBOXEXT_HASHCACHE_ENTRY CacheEntry;
+ uint32_t u32CacheDataInited;
+ uint32_t u32Hash;
+ PVBOXEXT_HASHCACHE shaderCache;
+#endif
+};
+
+void pixelshader_update_samplers(struct wined3d_shader *shader, WORD tex_types) DECLSPEC_HIDDEN;
+void find_ps_compile_args(const struct wined3d_state *state,
+ const struct wined3d_shader *shader, struct ps_compile_args *args) DECLSPEC_HIDDEN;
+
+void find_vs_compile_args(const struct wined3d_state *state,
+ const struct wined3d_shader *shader, struct vs_compile_args *args) DECLSPEC_HIDDEN;
+
+void shader_buffer_clear(struct wined3d_shader_buffer *buffer) DECLSPEC_HIDDEN;
+BOOL shader_buffer_init(struct wined3d_shader_buffer *buffer) DECLSPEC_HIDDEN;
+void shader_buffer_free(struct wined3d_shader_buffer *buffer) DECLSPEC_HIDDEN;
+void shader_dump_src_param(const struct wined3d_shader_src_param *param,
+ const struct wined3d_shader_version *shader_version) DECLSPEC_HIDDEN;
+void shader_dump_dst_param(const struct wined3d_shader_dst_param *param,
+ const struct wined3d_shader_version *shader_version) DECLSPEC_HIDDEN;
+unsigned int shader_find_free_input_register(const struct wined3d_shader_reg_maps *reg_maps,
+ unsigned int max) DECLSPEC_HIDDEN;
+void shader_generate_main(const struct wined3d_shader *shader, struct wined3d_shader_buffer *buffer,
+ const struct wined3d_shader_reg_maps *reg_maps, const DWORD *byte_code, void *backend_ctx) DECLSPEC_HIDDEN;
+BOOL shader_match_semantic(const char *semantic_name, enum wined3d_decl_usage usage) DECLSPEC_HIDDEN;
+
+static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg)
+{
+ switch (reg->type)
+ {
+ case WINED3DSPR_RASTOUT:
+ /* oFog & oPts */
+ if (reg->idx[0].offset)
+ return TRUE;
+ /* oPos */
+ return FALSE;
+
+ case WINED3DSPR_DEPTHOUT: /* oDepth */
+ case WINED3DSPR_CONSTBOOL: /* b# */
+ case WINED3DSPR_LOOP: /* aL */
+ case WINED3DSPR_PREDICATE: /* p0 */
+ case WINED3DSPR_PRIMID: /* primID */
+ return TRUE;
+
+ case WINED3DSPR_MISCTYPE:
+ switch (reg->idx[0].offset)
+ {
+ case 0: /* vPos */
+ return FALSE;
+ case 1: /* vFace */
+ return TRUE;
+ default:
+ return FALSE;
+ }
+
+ case WINED3DSPR_IMMCONST:
+ return reg->immconst_type == WINED3D_IMMCONST_SCALAR;
+
+ default:
+ return FALSE;
+ }
+}
+
+static inline void shader_get_position_fixup(const struct wined3d_context *context,
+ const struct wined3d_state *state, float *position_fixup)
+{
+ position_fixup[0] = 1.0f;
+ position_fixup[1] = 1.0f;
+ position_fixup[2] = (63.0f / 64.0f) / state->viewport.width;
+ position_fixup[3] = -(63.0f / 64.0f) / state->viewport.height;
+
+ if (context->render_offscreen)
+ {
+ position_fixup[1] *= -1.0f;
+ position_fixup[3] *= -1.0f;
+ }
+}
+
+static inline BOOL shader_constant_is_local(const struct wined3d_shader *shader, DWORD reg)
+{
+ struct wined3d_shader_lconst *lconst;
+
+ if (shader->load_local_constsF)
+ return FALSE;
+
+ LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, struct wined3d_shader_lconst, entry)
+ {
+ if (lconst->idx == reg)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Using additional shader constants (uniforms in GLSL / program environment
+ * or local parameters in ARB) is costly:
+ * ARB only knows float4 parameters and GLSL compiler are not really smart
+ * when it comes to efficiently pack float2 uniforms, so no space is wasted
+ * (in fact most compilers map a float2 to a full float4 uniform).
+ *
+ * For NP2 texcoord fixup we only need 2 floats (width and height) for each
+ * 2D texture used in the shader. We therefore pack fixup info for 2 textures
+ * into a single shader constant (uniform / program parameter).
+ *
+ * This structure is shared between the GLSL and the ARB backend.*/
+struct ps_np2fixup_info {
+ unsigned char idx[MAX_FRAGMENT_SAMPLERS]; /* indices to the real constant */
+ WORD active; /* bitfield indicating if we can apply the fixup */
+ WORD num_consts;
+};
+
+#ifdef VBOX_WINE_WITH_SHADER_CACHE
+struct wined3d_shader * vertexshader_check_cached(struct wined3d_device *device, struct wined3d_shader *object) DECLSPEC_HIDDEN;
+struct wined3d_shader * pixelshader_check_cached(struct wined3d_device *device, struct wined3d_shader *object) DECLSPEC_HIDDEN;
+void shader_chaches_init(struct wined3d_device *device) DECLSPEC_HIDDEN;
+void shader_chaches_term(struct wined3d_device *device) DECLSPEC_HIDDEN;
+#endif
+
+#ifdef VBOX_WITH_WINE_FIX_ZEROVERTATTR
+void zv_destroy(struct wined3d_device *device);
+void zv_bind(struct wined3d_context *context, GLenum enmzvValue, GLuint czvValue, GLuint czvValueElements, GLboolean bzvNormalized, const GLvoid *pzvValue);
+void zv_bind_by_element(struct wined3d_context *context, const struct wined3d_stream_info_element *element, GLuint czvValue, const GLvoid *pzvValue);
+#endif
+
+struct wined3d_palette
+{
+ LONG ref;
+ void *parent;
+ struct wined3d_device *device;
+
+ HPALETTE hpal;
+ WORD palVersion; /*| */
+ WORD palNumEntries; /*| LOGPALETTE */
+ PALETTEENTRY palents[256]; /*| */
+ /* This is to store the palette in 'screen format' */
+ int screen_palents[256];
+ DWORD flags;
+};
+
+/* DirectDraw utility functions */
+extern enum wined3d_format_id pixelformat_for_depth(DWORD depth) DECLSPEC_HIDDEN;
+
+/*****************************************************************************
+ * Pixel format management
+ */
+
+/* WineD3D pixel format flags */
+#define WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING 0x00000001
+#define WINED3DFMT_FLAG_FILTERING 0x00000002
+#define WINED3DFMT_FLAG_DEPTH 0x00000004
+#define WINED3DFMT_FLAG_STENCIL 0x00000008
+#define WINED3DFMT_FLAG_RENDERTARGET 0x00000010
+#define WINED3DFMT_FLAG_FBO_ATTACHABLE 0x00000040
+#define WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB 0x00000080
+#define WINED3DFMT_FLAG_GETDC 0x00000100
+#define WINED3DFMT_FLAG_FLOAT 0x00000200
+#define WINED3DFMT_FLAG_BUMPMAP 0x00000400
+#define WINED3DFMT_FLAG_SRGB_READ 0x00000800
+#define WINED3DFMT_FLAG_SRGB_WRITE 0x00001000
+#define WINED3DFMT_FLAG_VTF 0x00002000
+#define WINED3DFMT_FLAG_SHADOW 0x00004000
+#define WINED3DFMT_FLAG_COMPRESSED 0x00008000
+#define WINED3DFMT_FLAG_BROKEN_PITCH 0x00010000
+#define WINED3DFMT_FLAG_BLOCKS 0x00020000
+#define WINED3DFMT_FLAG_HEIGHT_SCALE 0x00040000
+#define WINED3DFMT_FLAG_TEXTURE 0x00080000
+
+struct wined3d_rational
+{
+ UINT numerator;
+ UINT denominator;
+};
+
+struct wined3d_format
+{
+ enum wined3d_format_id id;
+
+ DWORD red_size;
+ DWORD green_size;
+ DWORD blue_size;
+ DWORD alpha_size;
+ DWORD red_offset;
+ DWORD green_offset;
+ DWORD blue_offset;
+ DWORD alpha_offset;
+ UINT byte_count;
+ BYTE depth_size;
+ BYTE stencil_size;
+
+ UINT block_width;
+ UINT block_height;
+ UINT block_byte_count;
+
+ enum wined3d_ffp_emit_idx emit_idx;
+ GLint component_count;
+ GLenum gl_vtx_type;
+ GLint gl_vtx_format;
+ GLboolean gl_normalized;
+ unsigned int component_size;
+
+ GLint glInternal;
+ GLint glGammaInternal;
+ GLint rtInternal;
+ GLint glFormat;
+ GLint glType;
+ UINT conv_byte_count;
+ unsigned int flags;
+ struct wined3d_rational height_scale;
+ struct color_fixup_desc color_fixup;
+ void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
+};
+
+const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
+ enum wined3d_format_id format_id) DECLSPEC_HIDDEN;
+UINT wined3d_format_calculate_size(const struct wined3d_format *format,
+ UINT alignment, UINT width, UINT height) DECLSPEC_HIDDEN;
+DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface,
+ const struct wined3d_color *color) DECLSPEC_HIDDEN;
+
+static inline BOOL use_vs(const struct wined3d_state *state)
+{
+ /* Check stateblock->vertexDecl to allow this to be used from
+ * IWineD3DDeviceImpl_FindTexUnitMap(). This is safe because
+ * stateblock->vertexShader implies a vertex declaration instead of ddraw
+ * style strided data. */
+ return state->vertex_shader && !state->vertex_declaration->position_transformed;
+}
+
+static inline BOOL use_ps(const struct wined3d_state *state)
+{
+ return !!state->pixel_shader;
+}
+
+static inline void context_apply_state(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id)
+{
+ const struct StateEntry *state_table = context->state_table;
+ DWORD rep = state_table[state_id].representative;
+ state_table[rep].apply(context, state, rep);
+}
+
+/* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
+#define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
+
+#define MAKEDWORD_VERSION(maj, min) (((maj & 0xffff) << 16) | (min & 0xffff))
+
+#ifdef VBOX_WINE_WITHOUT_LIBWINE
+#include <float.h>
+
+# define isnan(_a) (_isnan(_a))
+# define isinf(_a) (!_finite(_a))
+#endif
+
+#endif
diff --git a/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3dwddm.def b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3dwddm.def
new file mode 100644
index 00000000..3d1de92f
--- /dev/null
+++ b/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/wined3dwddm.def
@@ -0,0 +1,263 @@
+; File generated automatically from ./dlls/wined3d/wined3d.spec; do not edit!
+
+EXPORTS
+ wined3d_check_depth_stencil_match
+ wined3d_check_device_format
+ wined3d_check_device_format_conversion
+ wined3d_check_device_multisample_type
+ wined3d_check_device_type
+ wined3d_create
+ wined3d_decref
+ wined3d_enum_adapter_modes
+ wined3d_get_adapter_count
+ wined3d_get_adapter_display_mode
+ wined3d_get_adapter_identifier
+ wined3d_get_adapter_mode_count
+ wined3d_get_adapter_monitor
+ wined3d_get_adapter_raster_status
+ wined3d_get_device_caps
+ wined3d_incref
+ wined3d_register_software_device
+ wined3d_set_adapter_display_mode
+ wined3d_buffer_create
+ wined3d_buffer_create_ib
+ wined3d_buffer_create_vb
+ wined3d_buffer_decref
+ wined3d_buffer_get_parent
+ wined3d_buffer_get_priority
+ wined3d_buffer_get_resource
+ wined3d_buffer_incref
+ wined3d_buffer_map
+ wined3d_buffer_preload
+ wined3d_buffer_set_priority
+ wined3d_buffer_unmap
+ wined3d_device_acquire_focus_window
+ wined3d_device_begin_scene
+ wined3d_device_begin_stateblock
+ wined3d_device_clear
+ wined3d_device_clear_rendertarget_view
+ wined3d_device_color_fill
+ wined3d_device_create
+ wined3d_device_decref
+ wined3d_device_draw_indexed_primitive
+ wined3d_device_draw_primitive
+ wined3d_device_end_scene
+ wined3d_device_end_stateblock
+ wined3d_device_evict_managed_resources
+ wined3d_device_get_available_texture_mem
+ wined3d_device_get_back_buffer
+ wined3d_device_get_base_vertex_index
+ wined3d_device_get_clip_plane
+ wined3d_device_get_clip_status
+ wined3d_device_get_creation_parameters
+ wined3d_device_get_depth_stencil
+ wined3d_device_get_device_caps
+ wined3d_device_get_display_mode
+ wined3d_device_get_front_buffer_data
+ wined3d_device_get_gamma_ramp
+ wined3d_device_get_index_buffer
+ wined3d_device_get_light
+ wined3d_device_get_light_enable
+ wined3d_device_get_material
+ wined3d_device_get_npatch_mode
+ wined3d_device_get_pixel_shader
+ wined3d_device_get_primitive_type
+ wined3d_device_get_ps_consts_b
+ wined3d_device_get_ps_consts_f
+ wined3d_device_get_ps_consts_i
+ wined3d_device_get_raster_status
+ wined3d_device_get_render_state
+ wined3d_device_get_render_target
+ wined3d_device_get_sampler_state
+ wined3d_device_get_scissor_rect
+ wined3d_device_get_software_vertex_processing
+ wined3d_device_get_stream_source
+ wined3d_device_get_stream_source_freq
+ wined3d_device_get_surface_from_dc
+ wined3d_device_get_swapchain
+ wined3d_device_get_swapchain_count
+ wined3d_device_get_texture
+ wined3d_device_get_texture_stage_state
+ wined3d_device_get_transform
+ wined3d_device_get_vertex_declaration
+ wined3d_device_get_vertex_shader
+ wined3d_device_get_viewport
+ wined3d_device_get_vs_consts_b
+ wined3d_device_get_vs_consts_f
+ wined3d_device_get_vs_consts_i
+ wined3d_device_incref
+ wined3d_device_init_3d
+ wined3d_device_init_gdi
+ wined3d_device_multiply_transform
+ wined3d_device_present
+ wined3d_device_process_vertices
+ wined3d_device_release_focus_window
+ wined3d_device_reset
+ wined3d_device_restore_fullscreen_window
+ wined3d_device_set_base_vertex_index
+ wined3d_device_set_clip_plane
+ wined3d_device_set_clip_status
+ wined3d_device_set_cursor_position
+ wined3d_device_set_cursor_properties
+ wined3d_device_set_depth_stencil
+ wined3d_device_set_dialog_box_mode
+ wined3d_device_set_gamma_ramp
+ wined3d_device_set_index_buffer
+ wined3d_device_set_light
+ wined3d_device_set_light_enable
+ wined3d_device_set_material
+ wined3d_device_set_multithreaded
+ wined3d_device_set_npatch_mode
+ wined3d_device_set_pixel_shader
+ wined3d_device_set_primitive_type
+ wined3d_device_set_ps_consts_b
+ wined3d_device_set_ps_consts_f
+ wined3d_device_set_ps_consts_i
+ wined3d_device_set_render_state
+ wined3d_device_set_render_target
+ wined3d_device_set_sampler_state
+ wined3d_device_set_scissor_rect
+ wined3d_device_set_software_vertex_processing
+ wined3d_device_set_stream_source
+ wined3d_device_set_stream_source_freq
+ wined3d_device_set_texture
+ wined3d_device_set_texture_stage_state
+ wined3d_device_set_transform
+ wined3d_device_set_vertex_declaration
+ wined3d_device_set_vertex_shader
+ wined3d_device_set_viewport
+ wined3d_device_set_vs_consts_b
+ wined3d_device_set_vs_consts_f
+ wined3d_device_set_vs_consts_i
+ wined3d_device_setup_fullscreen_window
+ wined3d_device_show_cursor
+ wined3d_device_uninit_3d
+ wined3d_device_uninit_gdi
+ wined3d_device_update_surface
+ wined3d_device_update_texture
+ wined3d_device_validate_device
+ wined3d_palette_create
+ wined3d_palette_decref
+ wined3d_palette_get_entries
+ wined3d_palette_get_flags
+ wined3d_palette_get_parent
+ wined3d_palette_incref
+ wined3d_palette_set_entries
+ wined3d_query_create
+ wined3d_query_decref
+ wined3d_query_get_data
+ wined3d_query_get_data_size
+ wined3d_query_get_type
+ wined3d_query_incref
+ wined3d_query_issue
+ wined3d_resource_free_private_data
+ wined3d_resource_get_desc
+ wined3d_resource_get_parent
+ wined3d_resource_get_private_data
+ wined3d_resource_set_private_data
+ wined3d_rendertarget_view_create
+ wined3d_rendertarget_view_decref
+ wined3d_rendertarget_view_get_parent
+ wined3d_rendertarget_view_get_resource
+ wined3d_rendertarget_view_incref
+ wined3d_shader_create_gs
+ wined3d_shader_create_ps
+ wined3d_shader_create_vs
+ wined3d_shader_decref
+ wined3d_shader_get_byte_code
+ wined3d_shader_get_parent
+ wined3d_shader_incref
+ wined3d_shader_set_local_constants_float
+ wined3d_stateblock_apply
+ wined3d_stateblock_capture
+ wined3d_stateblock_create
+ wined3d_stateblock_decref
+ wined3d_stateblock_incref
+ wined3d_surface_blt
+ wined3d_surface_create
+ wined3d_surface_decref
+ wined3d_surface_flip
+ wined3d_surface_from_resource
+ wined3d_surface_get_blt_status
+ wined3d_surface_get_flip_status
+ wined3d_surface_get_overlay_position
+ wined3d_surface_get_palette
+ wined3d_surface_get_parent
+ wined3d_surface_get_pitch
+ wined3d_surface_get_priority
+ wined3d_surface_get_render_target_data
+ wined3d_surface_get_resource
+ wined3d_surface_getdc
+ wined3d_surface_incref
+ wined3d_surface_is_lost
+ wined3d_surface_map
+ wined3d_surface_preload
+ wined3d_surface_releasedc
+ wined3d_surface_restore
+ wined3d_surface_set_color_key
+ wined3d_surface_set_mem
+ wined3d_surface_set_overlay_position
+ wined3d_surface_set_palette
+ wined3d_surface_set_priority
+ wined3d_surface_unmap
+ wined3d_surface_update_desc
+ wined3d_surface_update_overlay
+ wined3d_surface_update_overlay_z_order
+ wined3d_swapchain_create
+ wined3d_swapchain_decref
+ wined3d_swapchain_get_back_buffer
+ wined3d_swapchain_get_device
+ wined3d_swapchain_get_display_mode
+ wined3d_swapchain_get_front_buffer_data
+ wined3d_swapchain_get_gamma_ramp
+ wined3d_swapchain_get_parent
+ wined3d_swapchain_get_desc
+ wined3d_swapchain_get_raster_status
+ wined3d_swapchain_incref
+ wined3d_swapchain_present
+ wined3d_swapchain_set_gamma_ramp
+ wined3d_swapchain_set_window
+ wined3d_texture_add_dirty_region
+ wined3d_texture_create_2d
+ wined3d_texture_create_3d
+ wined3d_texture_create_cube
+ wined3d_texture_decref
+ wined3d_texture_generate_mipmaps
+ wined3d_texture_get_autogen_filter_type
+ wined3d_texture_get_level_count
+ wined3d_texture_get_lod
+ wined3d_texture_get_parent
+ wined3d_texture_get_priority
+ wined3d_texture_get_resource
+ wined3d_texture_get_sub_resource
+ wined3d_texture_incref
+ wined3d_texture_preload
+ wined3d_texture_set_autogen_filter_type
+ wined3d_texture_set_lod
+ wined3d_texture_set_priority
+ wined3d_vertex_declaration_create
+ wined3d_vertex_declaration_create_from_fvf
+ wined3d_vertex_declaration_decref
+ wined3d_vertex_declaration_get_parent
+ wined3d_vertex_declaration_incref
+ wined3d_volume_create
+ wined3d_volume_decref
+ wined3d_volume_from_resource
+ wined3d_volume_get_parent
+ wined3d_volume_get_priority
+ wined3d_volume_get_resource
+ wined3d_volume_incref
+ wined3d_volume_map
+ wined3d_volume_preload
+ wined3d_volume_set_priority
+ wined3d_volume_unmap
+ wined3d_device_flush
+ wined3d_device_flush_to_host
+ wined3d_device_finish
+ wined3d_device_blt_vol
+ wined3d_device_blt_voltex
+ wined3d_swapchain_present_rt
+ wined3d_surface_get_host_id
+ wined3d_surface_sync_to_host
+ wined3d_swapchain_get_host_win_id
+ wined3d_device_get_host_id