Work of Joakim Sindholt (zhasha) and Christoph Bumiller (chrisbmr). DRI3 port done by Axel Davy (mannerov). v2: - nine_debug.c: klass extended from 32 chars to 96 (for sure) by glennk - Nine improvements by Axel Davy (which also fixed some wine tests) - by Emil Velikov: - convert to static/shared drivers - Sort and cleanup the includes - Use AM_CPPFLAGS for the defines - Add the linker garbage collector - Restrict the exported symbols (think llvm) v3: - small nine fixes - build system improvements by Emil Velikov v4: [Emil Velikov] - Do no link against libudev. No longer needed. Acked-by: Jose Fonseca <jfonseca@vmware.com> Reviewed-by: Marek Olšák <marek.olsak@amd.com> Reviewed-by: Axel Davy <axel.davy@ens.fr> Signed-off-by: David Heidelberg <david@ixit.cz>tags/10.5-branchpoint
@@ -669,6 +669,11 @@ AC_ARG_ENABLE([gbm], | |||
[enable gbm library @<:@default=auto@:>@])], | |||
[enable_gbm="$enableval"], | |||
[enable_gbm=auto]) | |||
AC_ARG_ENABLE([nine], | |||
[AS_HELP_STRING([--enable-nine], | |||
[enable build of the nine Direct3D9 API @<:@default=no@:>@])], | |||
[enable_nine="$enableval"], | |||
[enable_nine=no]) | |||
AC_ARG_ENABLE([xvmc], | |||
[AS_HELP_STRING([--enable-xvmc], | |||
@@ -742,6 +747,7 @@ esac | |||
if test "x$enable_opengl" = xno -a \ | |||
"x$enable_gles1" = xno -a \ | |||
"x$enable_gles2" = xno -a \ | |||
"x$enable_nine" = xno -a \ | |||
"x$enable_openvg" = xno -a \ | |||
"x$enable_xa" = xno -a \ | |||
"x$enable_xvmc" = xno -a \ | |||
@@ -1394,6 +1400,24 @@ if test "x$enable_va" = xyes; then | |||
fi | |||
AM_CONDITIONAL(HAVE_ST_VA, test "x$enable_va" = xyes) | |||
dnl | |||
dnl Nine Direct3D9 configuration | |||
dnl | |||
if test "x$enable_nine" = xyes; then | |||
if ! echo "$with_gallium_drivers" | grep -q 'swrast'; then | |||
AC_MSG_ERROR([nine requires the gallium swrast driver]) | |||
fi | |||
if test "x$with_gallium_drivers" == xswrast; then | |||
AC_MSG_ERROR([nine requires at least one non-swrast gallium driver]) | |||
fi | |||
if test "x$enable_dri3" = xno; then | |||
AC_MSG_WARN([using nine together with wine requires DRI3 enabled system]) | |||
fi | |||
enable_gallium_loader=$enable_shared_pipe_drivers | |||
fi | |||
AM_CONDITIONAL(HAVE_ST_NINE, test "x$enable_nine" = xyes) | |||
dnl | |||
dnl OpenCL configuration | |||
dnl | |||
@@ -1768,6 +1792,13 @@ AC_ARG_WITH([va-libdir], | |||
[VA_LIB_INSTALL_DIR="${libdir}/dri"]) | |||
AC_SUBST([VA_LIB_INSTALL_DIR]) | |||
AC_ARG_WITH([d3d-libdir], | |||
[AS_HELP_STRING([--with-d3d-libdir=DIR], | |||
[directory for the D3D modules @<:@${libdir}/d3d@:>@])], | |||
[D3D_DRIVER_INSTALL_DIR="$withval"], | |||
[D3D_DRIVER_INSTALL_DIR="${libdir}/d3d"]) | |||
AC_SUBST([D3D_DRIVER_INSTALL_DIR]) | |||
dnl | |||
dnl Gallium helper functions | |||
dnl | |||
@@ -2052,6 +2083,9 @@ AM_CONDITIONAL(HAVE_X86_ASM, test "x$asm_arch" = xx86 -o "x$asm_arch" = xx86_64) | |||
AM_CONDITIONAL(HAVE_X86_64_ASM, test "x$asm_arch" = xx86_64) | |||
AM_CONDITIONAL(HAVE_SPARC_ASM, test "x$asm_arch" = xsparc) | |||
AC_SUBST([NINE_MAJOR], 1) | |||
AC_SUBST([NINE_MINOR], 0) | |||
AC_SUBST([VDPAU_MAJOR], 1) | |||
AC_SUBST([VDPAU_MINOR], 0) | |||
@@ -2121,6 +2155,7 @@ AC_CONFIG_FILES([Makefile | |||
src/gallium/state_trackers/clover/Makefile | |||
src/gallium/state_trackers/dri/Makefile | |||
src/gallium/state_trackers/glx/xlib/Makefile | |||
src/gallium/state_trackers/nine/Makefile | |||
src/gallium/state_trackers/omx/Makefile | |||
src/gallium/state_trackers/osmesa/Makefile | |||
src/gallium/state_trackers/va/Makefile | |||
@@ -2128,6 +2163,8 @@ AC_CONFIG_FILES([Makefile | |||
src/gallium/state_trackers/vega/Makefile | |||
src/gallium/state_trackers/xa/Makefile | |||
src/gallium/state_trackers/xvmc/Makefile | |||
src/gallium/targets/d3dadapter9/Makefile | |||
src/gallium/targets/d3dadapter9/d3d.pc | |||
src/gallium/targets/dri/Makefile | |||
src/gallium/targets/egl-static/Makefile | |||
src/gallium/targets/gbm/Makefile |
@@ -0,0 +1,387 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _D3D9CAPS_H_ | |||
#define _D3D9CAPS_H_ | |||
#include "d3d9types.h" | |||
/* Caps flags */ | |||
#define D3DCAPS2_FULLSCREENGAMMA 0x00020000 | |||
#define D3DCAPS2_CANCALIBRATEGAMMA 0x00100000 | |||
#define D3DCAPS2_RESERVED 0x02000000 | |||
#define D3DCAPS2_CANMANAGERESOURCE 0x10000000 | |||
#define D3DCAPS2_DYNAMICTEXTURES 0x20000000 | |||
#define D3DCAPS2_CANAUTOGENMIPMAP 0x40000000 | |||
#define D3DCAPS2_CANSHARERESOURCE 0x80000000 | |||
#define D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD 0x00000020 | |||
#define D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION 0x00000080 | |||
#define D3DCAPS3_COPY_TO_VIDMEM 0x00000100 | |||
#define D3DCAPS3_COPY_TO_SYSTEMMEM 0x00000200 | |||
#define D3DCAPS3_DXVAHD 0x00000400 | |||
#define D3DCAPS3_RESERVED 0x8000001F | |||
#define D3DPRESENT_INTERVAL_DEFAULT 0x00000000 | |||
#define D3DPRESENT_INTERVAL_ONE 0x00000001 | |||
#define D3DPRESENT_INTERVAL_TWO 0x00000002 | |||
#define D3DPRESENT_INTERVAL_THREE 0x00000004 | |||
#define D3DPRESENT_INTERVAL_FOUR 0x00000008 | |||
#define D3DPRESENT_INTERVAL_IMMEDIATE 0x80000000 | |||
#define D3DCURSORCAPS_COLOR 0x00000001 | |||
#define D3DCURSORCAPS_LOWRES 0x00000002 | |||
#define D3DDEVCAPS_EXECUTESYSTEMMEMORY 0x00000010 | |||
#define D3DDEVCAPS_EXECUTEVIDEOMEMORY 0x00000020 | |||
#define D3DDEVCAPS_TLVERTEXSYSTEMMEMORY 0x00000040 | |||
#define D3DDEVCAPS_TLVERTEXVIDEOMEMORY 0x00000080 | |||
#define D3DDEVCAPS_TEXTURESYSTEMMEMORY 0x00000100 | |||
#define D3DDEVCAPS_TEXTUREVIDEOMEMORY 0x00000200 | |||
#define D3DDEVCAPS_DRAWPRIMTLVERTEX 0x00000400 | |||
#define D3DDEVCAPS_CANRENDERAFTERFLIP 0x00000800 | |||
#define D3DDEVCAPS_TEXTURENONLOCALVIDMEM 0x00001000 | |||
#define D3DDEVCAPS_DRAWPRIMITIVES2 0x00002000 | |||
#define D3DDEVCAPS_SEPARATETEXTUREMEMORIES 0x00004000 | |||
#define D3DDEVCAPS_DRAWPRIMITIVES2EX 0x00008000 | |||
#define D3DDEVCAPS_HWTRANSFORMANDLIGHT 0x00010000 | |||
#define D3DDEVCAPS_CANBLTSYSTONONLOCAL 0x00020000 | |||
#define D3DDEVCAPS_HWRASTERIZATION 0x00080000 | |||
#define D3DDEVCAPS_PUREDEVICE 0x00100000 | |||
#define D3DDEVCAPS_QUINTICRTPATCHES 0x00200000 | |||
#define D3DDEVCAPS_RTPATCHES 0x00400000 | |||
#define D3DDEVCAPS_RTPATCHHANDLEZERO 0x00800000 | |||
#define D3DDEVCAPS_NPATCHES 0x01000000 | |||
#define D3DPMISCCAPS_MASKZ 0x00000002 | |||
#define D3DPMISCCAPS_CULLNONE 0x00000010 | |||
#define D3DPMISCCAPS_CULLCW 0x00000020 | |||
#define D3DPMISCCAPS_CULLCCW 0x00000040 | |||
#define D3DPMISCCAPS_COLORWRITEENABLE 0x00000080 | |||
#define D3DPMISCCAPS_CLIPPLANESCALEDPOINTS 0x00000100 | |||
#define D3DPMISCCAPS_CLIPTLVERTS 0x00000200 | |||
#define D3DPMISCCAPS_TSSARGTEMP 0x00000400 | |||
#define D3DPMISCCAPS_BLENDOP 0x00000800 | |||
#define D3DPMISCCAPS_NULLREFERENCE 0x00001000 | |||
#define D3DPMISCCAPS_INDEPENDENTWRITEMASKS 0x00004000 | |||
#define D3DPMISCCAPS_PERSTAGECONSTANT 0x00008000 | |||
#define D3DPMISCCAPS_FOGANDSPECULARALPHA 0x00010000 | |||
#define D3DPMISCCAPS_SEPARATEALPHABLEND 0x00020000 | |||
#define D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS 0x00040000 | |||
#define D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING 0x00080000 | |||
#define D3DPMISCCAPS_FOGVERTEXCLAMPED 0x00100000 | |||
#define D3DPMISCCAPS_POSTBLENDSRGBCONVERT 0x00200000 | |||
#define D3DPRASTERCAPS_DITHER 0x00000001 | |||
#define D3DPRASTERCAPS_ZTEST 0x00000010 | |||
#define D3DPRASTERCAPS_FOGVERTEX 0x00000080 | |||
#define D3DPRASTERCAPS_FOGTABLE 0x00000100 | |||
#define D3DPRASTERCAPS_MIPMAPLODBIAS 0x00002000 | |||
#define D3DPRASTERCAPS_ZBUFFERLESSHSR 0x00008000 | |||
#define D3DPRASTERCAPS_FOGRANGE 0x00010000 | |||
#define D3DPRASTERCAPS_ANISOTROPY 0x00020000 | |||
#define D3DPRASTERCAPS_WBUFFER 0x00040000 | |||
#define D3DPRASTERCAPS_WFOG 0x00100000 | |||
#define D3DPRASTERCAPS_ZFOG 0x00200000 | |||
#define D3DPRASTERCAPS_COLORPERSPECTIVE 0x00400000 | |||
#define D3DPRASTERCAPS_SCISSORTEST 0x01000000 | |||
#define D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS 0x02000000 | |||
#define D3DPRASTERCAPS_DEPTHBIAS 0x04000000 | |||
#define D3DPRASTERCAPS_MULTISAMPLE_TOGGLE 0x08000000 | |||
#define D3DPCMPCAPS_NEVER 0x00000001 | |||
#define D3DPCMPCAPS_LESS 0x00000002 | |||
#define D3DPCMPCAPS_EQUAL 0x00000004 | |||
#define D3DPCMPCAPS_LESSEQUAL 0x00000008 | |||
#define D3DPCMPCAPS_GREATER 0x00000010 | |||
#define D3DPCMPCAPS_NOTEQUAL 0x00000020 | |||
#define D3DPCMPCAPS_GREATEREQUAL 0x00000040 | |||
#define D3DPCMPCAPS_ALWAYS 0x00000080 | |||
#define D3DPBLENDCAPS_ZERO 0x00000001 | |||
#define D3DPBLENDCAPS_ONE 0x00000002 | |||
#define D3DPBLENDCAPS_SRCCOLOR 0x00000004 | |||
#define D3DPBLENDCAPS_INVSRCCOLOR 0x00000008 | |||
#define D3DPBLENDCAPS_SRCALPHA 0x00000010 | |||
#define D3DPBLENDCAPS_INVSRCALPHA 0x00000020 | |||
#define D3DPBLENDCAPS_DESTALPHA 0x00000040 | |||
#define D3DPBLENDCAPS_INVDESTALPHA 0x00000080 | |||
#define D3DPBLENDCAPS_DESTCOLOR 0x00000100 | |||
#define D3DPBLENDCAPS_INVDESTCOLOR 0x00000200 | |||
#define D3DPBLENDCAPS_SRCALPHASAT 0x00000400 | |||
#define D3DPBLENDCAPS_BOTHSRCALPHA 0x00000800 | |||
#define D3DPBLENDCAPS_BOTHINVSRCALPHA 0x00001000 | |||
#define D3DPBLENDCAPS_BLENDFACTOR 0x00002000 | |||
#ifndef D3D_DISABLE_9EX | |||
# define D3DPBLENDCAPS_SRCCOLOR2 0x00004000 | |||
# define D3DPBLENDCAPS_INVSRCCOLOR2 0x00008000 | |||
#endif | |||
#define D3DPSHADECAPS_COLORGOURAUDRGB 0x00000008 | |||
#define D3DPSHADECAPS_SPECULARGOURAUDRGB 0x00000200 | |||
#define D3DPSHADECAPS_ALPHAGOURAUDBLEND 0x00004000 | |||
#define D3DPSHADECAPS_FOGGOURAUD 0x00080000 | |||
#define D3DPTEXTURECAPS_PERSPECTIVE 0x00000001 | |||
#define D3DPTEXTURECAPS_POW2 0x00000002 | |||
#define D3DPTEXTURECAPS_ALPHA 0x00000004 | |||
#define D3DPTEXTURECAPS_SQUAREONLY 0x00000020 | |||
#define D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE 0x00000040 | |||
#define D3DPTEXTURECAPS_ALPHAPALETTE 0x00000080 | |||
#define D3DPTEXTURECAPS_NONPOW2CONDITIONAL 0x00000100 | |||
#define D3DPTEXTURECAPS_PROJECTED 0x00000400 | |||
#define D3DPTEXTURECAPS_CUBEMAP 0x00000800 | |||
#define D3DPTEXTURECAPS_VOLUMEMAP 0x00002000 | |||
#define D3DPTEXTURECAPS_MIPMAP 0x00004000 | |||
#define D3DPTEXTURECAPS_MIPVOLUMEMAP 0x00008000 | |||
#define D3DPTEXTURECAPS_MIPCUBEMAP 0x00010000 | |||
#define D3DPTEXTURECAPS_CUBEMAP_POW2 0x00020000 | |||
#define D3DPTEXTURECAPS_VOLUMEMAP_POW2 0x00040000 | |||
#define D3DPTEXTURECAPS_NOPROJECTEDBUMPENV 0x00200000 | |||
#define D3DPTFILTERCAPS_MINFPOINT 0x00000100 | |||
#define D3DPTFILTERCAPS_MINFLINEAR 0x00000200 | |||
#define D3DPTFILTERCAPS_MINFANISOTROPIC 0x00000400 | |||
#define D3DPTFILTERCAPS_MINFPYRAMIDALQUAD 0x00000800 | |||
#define D3DPTFILTERCAPS_MINFGAUSSIANQUAD 0x00001000 | |||
#define D3DPTFILTERCAPS_MIPFPOINT 0x00010000 | |||
#define D3DPTFILTERCAPS_MIPFLINEAR 0x00020000 | |||
#define D3DPTFILTERCAPS_MAGFPOINT 0x01000000 | |||
#define D3DPTFILTERCAPS_MAGFLINEAR 0x02000000 | |||
#define D3DPTFILTERCAPS_MAGFANISOTROPIC 0x04000000 | |||
#define D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD 0x08000000 | |||
#define D3DPTFILTERCAPS_MAGFGAUSSIANQUAD 0x10000000 | |||
#define D3DPTADDRESSCAPS_WRAP 0x00000001 | |||
#define D3DPTADDRESSCAPS_MIRROR 0x00000002 | |||
#define D3DPTADDRESSCAPS_CLAMP 0x00000004 | |||
#define D3DPTADDRESSCAPS_BORDER 0x00000008 | |||
#define D3DPTADDRESSCAPS_INDEPENDENTUV 0x00000010 | |||
#define D3DPTADDRESSCAPS_MIRRORONCE 0x00000020 | |||
#define D3DLINECAPS_TEXTURE 0x00000001 | |||
#define D3DLINECAPS_ZTEST 0x00000002 | |||
#define D3DLINECAPS_BLEND 0x00000004 | |||
#define D3DLINECAPS_ALPHACMP 0x00000008 | |||
#define D3DLINECAPS_FOG 0x00000010 | |||
#define D3DLINECAPS_ANTIALIAS 0x00000020 | |||
#define D3DSTENCILCAPS_KEEP 0x00000001 | |||
#define D3DSTENCILCAPS_ZERO 0x00000002 | |||
#define D3DSTENCILCAPS_REPLACE 0x00000004 | |||
#define D3DSTENCILCAPS_INCRSAT 0x00000008 | |||
#define D3DSTENCILCAPS_DECRSAT 0x00000010 | |||
#define D3DSTENCILCAPS_INVERT 0x00000020 | |||
#define D3DSTENCILCAPS_INCR 0x00000040 | |||
#define D3DSTENCILCAPS_DECR 0x00000080 | |||
#define D3DSTENCILCAPS_TWOSIDED 0x00000100 | |||
#define D3DFVFCAPS_TEXCOORDCOUNTMASK 0x0000FFFF | |||
#define D3DFVFCAPS_DONOTSTRIPELEMENTS 0x00080000 | |||
#define D3DFVFCAPS_PSIZE 0x00100000 | |||
#define D3DTEXOPCAPS_DISABLE 0x00000001 | |||
#define D3DTEXOPCAPS_SELECTARG1 0x00000002 | |||
#define D3DTEXOPCAPS_SELECTARG2 0x00000004 | |||
#define D3DTEXOPCAPS_MODULATE 0x00000008 | |||
#define D3DTEXOPCAPS_MODULATE2X 0x00000010 | |||
#define D3DTEXOPCAPS_MODULATE4X 0x00000020 | |||
#define D3DTEXOPCAPS_ADD 0x00000040 | |||
#define D3DTEXOPCAPS_ADDSIGNED 0x00000080 | |||
#define D3DTEXOPCAPS_ADDSIGNED2X 0x00000100 | |||
#define D3DTEXOPCAPS_SUBTRACT 0x00000200 | |||
#define D3DTEXOPCAPS_ADDSMOOTH 0x00000400 | |||
#define D3DTEXOPCAPS_BLENDDIFFUSEALPHA 0x00000800 | |||
#define D3DTEXOPCAPS_BLENDTEXTUREALPHA 0x00001000 | |||
#define D3DTEXOPCAPS_BLENDFACTORALPHA 0x00002000 | |||
#define D3DTEXOPCAPS_BLENDTEXTUREALPHAPM 0x00004000 | |||
#define D3DTEXOPCAPS_BLENDCURRENTALPHA 0x00008000 | |||
#define D3DTEXOPCAPS_PREMODULATE 0x00010000 | |||
#define D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR 0x00020000 | |||
#define D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA 0x00040000 | |||
#define D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR 0x00080000 | |||
#define D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA 0x00100000 | |||
#define D3DTEXOPCAPS_BUMPENVMAP 0x00200000 | |||
#define D3DTEXOPCAPS_BUMPENVMAPLUMINANCE 0x00400000 | |||
#define D3DTEXOPCAPS_DOTPRODUCT3 0x00800000 | |||
#define D3DTEXOPCAPS_MULTIPLYADD 0x01000000 | |||
#define D3DTEXOPCAPS_LERP 0x02000000 | |||
#define D3DVTXPCAPS_TEXGEN 0x00000001 | |||
#define D3DVTXPCAPS_MATERIALSOURCE7 0x00000002 | |||
#define D3DVTXPCAPS_DIRECTIONALLIGHTS 0x00000008 | |||
#define D3DVTXPCAPS_POSITIONALLIGHTS 0x00000010 | |||
#define D3DVTXPCAPS_LOCALVIEWER 0x00000020 | |||
#define D3DVTXPCAPS_TWEENING 0x00000040 | |||
#define D3DVTXPCAPS_TEXGEN_SPHEREMAP 0x00000100 | |||
#define D3DVTXPCAPS_NO_TEXGEN_NONLOCALVIEWER 0x00000200 | |||
#define D3DDEVCAPS2_STREAMOFFSET 0x00000001 | |||
#define D3DDEVCAPS2_DMAPNPATCH 0x00000002 | |||
#define D3DDEVCAPS2_ADAPTIVETESSRTPATCH 0x00000004 | |||
#define D3DDEVCAPS2_ADAPTIVETESSNPATCH 0x00000008 | |||
#define D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES 0x00000010 | |||
#define D3DDEVCAPS2_PRESAMPLEDDMAPNPATCH 0x00000020 | |||
#define D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET 0x00000040 | |||
#define D3DDTCAPS_UBYTE4 0x00000001 | |||
#define D3DDTCAPS_UBYTE4N 0x00000002 | |||
#define D3DDTCAPS_SHORT2N 0x00000004 | |||
#define D3DDTCAPS_SHORT4N 0x00000008 | |||
#define D3DDTCAPS_USHORT2N 0x00000010 | |||
#define D3DDTCAPS_USHORT4N 0x00000020 | |||
#define D3DDTCAPS_UDEC3 0x00000040 | |||
#define D3DDTCAPS_DEC3N 0x00000080 | |||
#define D3DDTCAPS_FLOAT16_2 0x00000100 | |||
#define D3DDTCAPS_FLOAT16_4 0x00000200 | |||
#define D3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH 24 | |||
#define D3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH 0 | |||
#define D3DVS20_MAX_NUMTEMPS 32 | |||
#define D3DVS20_MIN_NUMTEMPS 12 | |||
#define D3DVS20_MAX_STATICFLOWCONTROLDEPTH 4 | |||
#define D3DVS20_MIN_STATICFLOWCONTROLDEPTH 1 | |||
#define D3DVS20CAPS_PREDICATION (1 << 0) | |||
#define D3DPS20CAPS_ARBITRARYSWIZZLE (1 << 0) | |||
#define D3DPS20CAPS_GRADIENTINSTRUCTIONS (1 << 1) | |||
#define D3DPS20CAPS_PREDICATION (1 << 2) | |||
#define D3DPS20CAPS_NODEPENDENTREADLIMIT (1 << 3) | |||
#define D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT (1 << 4) | |||
#define D3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH 24 | |||
#define D3DPS20_MIN_DYNAMICFLOWCONTROLDEPTH 0 | |||
#define D3DPS20_MAX_NUMTEMPS 32 | |||
#define D3DPS20_MIN_NUMTEMPS 12 | |||
#define D3DPS20_MAX_STATICFLOWCONTROLDEPTH 4 | |||
#define D3DPS20_MIN_STATICFLOWCONTROLDEPTH 0 | |||
#define D3DPS20_MAX_NUMINSTRUCTIONSLOTS 512 | |||
#define D3DPS20_MIN_NUMINSTRUCTIONSLOTS 96 | |||
#define D3DMIN30SHADERINSTRUCTIONS 512 | |||
#define D3DMAX30SHADERINSTRUCTIONS 32768 | |||
/* Structs */ | |||
typedef struct _D3DVSHADERCAPS2_0 { | |||
DWORD Caps; | |||
INT DynamicFlowControlDepth; | |||
INT NumTemps; | |||
INT StaticFlowControlDepth; | |||
} D3DVSHADERCAPS2_0, *PD3DVSHADERCAPS2_0, *LPD3DVSHADERCAPS2_0; | |||
typedef struct _D3DPSHADERCAPS2_0 { | |||
DWORD Caps; | |||
INT DynamicFlowControlDepth; | |||
INT NumTemps; | |||
INT StaticFlowControlDepth; | |||
INT NumInstructionSlots; | |||
} D3DPSHADERCAPS2_0, *PD3DPSHADERCAPS2_0, *LPD3DPSHADERCAPS2_0; | |||
typedef struct _D3DCAPS9 { | |||
D3DDEVTYPE 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; | |||
DWORD DevCaps2; | |||
float MaxNpatchTessellationLevel; | |||
DWORD Reserved5; | |||
UINT MasterAdapterOrdinal; | |||
UINT AdapterOrdinalInGroup; | |||
UINT NumberOfAdaptersInGroup; | |||
DWORD DeclTypes; | |||
DWORD NumSimultaneousRTs; | |||
DWORD StretchRectFilterCaps; | |||
D3DVSHADERCAPS2_0 VS20Caps; | |||
D3DPSHADERCAPS2_0 PS20Caps; | |||
DWORD VertexTextureFilterCaps; | |||
DWORD MaxVShaderInstructionsExecuted; | |||
DWORD MaxPShaderInstructionsExecuted; | |||
DWORD MaxVertexShader30InstructionSlots; | |||
DWORD MaxPixelShader30InstructionSlots; | |||
} D3DCAPS9, *PD3DCAPS9, *LPD3DCAPS9; | |||
typedef struct _D3DCONTENTPROTECTIONCAPS { | |||
DWORD Caps; | |||
GUID KeyExchangeType; | |||
UINT BufferAlignmentStart; | |||
UINT BlockAlignmentSize; | |||
ULONGLONG ProtectedMemorySize; | |||
} D3DCONTENTPROTECTIONCAPS, *PD3DCONTENTPROTECTIONCAPS, *LPD3DCONTENTPROTECTIONCAPS; | |||
typedef struct _D3DOVERLAYCAPS { | |||
UINT Caps; | |||
UINT MaxOverlayDisplayWidth; | |||
UINT MaxOverlayDisplayHeight; | |||
} D3DOVERLAYCAPS, *PD3DOVERLAYCAPS, *LPD3DOVERLAYCAPS; | |||
#endif /* _D3D9CAPS_H_ */ |
@@ -0,0 +1,101 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _D3DADAPTER9_H_ | |||
#define _D3DADAPTER9_H_ | |||
#include "present.h" | |||
#ifndef __cplusplus | |||
/* Representation of an adapter group, although since this is implemented by | |||
* the driver, it knows nothing about the windowing system it's on */ | |||
typedef struct ID3DAdapter9Vtbl | |||
{ | |||
/* IUnknown */ | |||
HRESULT (WINAPI *QueryInterface)(ID3DAdapter9 *This, REFIID riid, void **ppvObject); | |||
ULONG (WINAPI *AddRef)(ID3DAdapter9 *This); | |||
ULONG (WINAPI *Release)(ID3DAdapter9 *This); | |||
/* ID3DAdapter9 */ | |||
HRESULT (WINAPI *GetAdapterIdentifier)(ID3DAdapter9 *This, DWORD Flags, D3DADAPTER_IDENTIFIER9 *pIdentifier); | |||
HRESULT (WINAPI *CheckDeviceType)(ID3DAdapter9 *This, D3DDEVTYPE DevType, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, BOOL bWindowed); | |||
HRESULT (WINAPI *CheckDeviceFormat)(ID3DAdapter9 *This, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat); | |||
HRESULT (WINAPI *CheckDeviceMultiSampleType)(ID3DAdapter9 *This, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD *pQualityLevels); | |||
HRESULT (WINAPI *CheckDepthStencilMatch)(ID3DAdapter9 *This, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat); | |||
HRESULT (WINAPI *CheckDeviceFormatConversion)(ID3DAdapter9 *This, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat); | |||
HRESULT (WINAPI *GetDeviceCaps)(ID3DAdapter9 *This, D3DDEVTYPE DeviceType, D3DCAPS9 *pCaps); | |||
HRESULT (WINAPI *CreateDevice)(ID3DAdapter9 *This, UINT RealAdapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS *pPresentationParameters, IDirect3D9 *pD3D9, ID3DPresentGroup *pPresentationFactory, IDirect3DDevice9 **ppReturnedDeviceInterface); | |||
HRESULT (WINAPI *CreateDeviceEx)(ID3DAdapter9 *This, UINT RealAdapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS *pPresentationParameters, D3DDISPLAYMODEEX *pFullscreenDisplayMode, IDirect3D9Ex *pD3D9Ex, ID3DPresentGroup *pPresentationFactory, IDirect3DDevice9Ex **ppReturnedDeviceInterface); | |||
} ID3DAdapter9Vtbl; | |||
struct ID3DAdapter9 | |||
{ | |||
ID3DAdapter9Vtbl *lpVtbl; | |||
}; | |||
/* IUnknown macros */ | |||
#define ID3DAdapter9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) | |||
#define ID3DAdapter9_AddRef(p) (p)->lpVtbl->AddRef(p) | |||
#define ID3DAdapter9_Release(p) (p)->lpVtbl->Release(p) | |||
/* ID3DAdapter9 macros */ | |||
#define ID3DAdapter9_GetAdapterIdentifier(p,a,b) (p)->lpVtbl->GetAdapterIdentifier(p,a,b) | |||
#define ID3DAdapter9_CheckDeviceType(p,a,b,c,d) (p)->lpVtbl->CheckDeviceType(p,a,b,c,d) | |||
#define ID3DAdapter9_CheckDeviceFormat(p,a,b,c,d,e) (p)->lpVtbl->CheckDeviceFormat(p,a,b,c,d,e) | |||
#define ID3DAdapter9_CheckDeviceMultiSampleType(p,a,b,c,d,e) (p)->lpVtbl->CheckDeviceMultiSampleType(p,a,b,c,d,e) | |||
#define ID3DAdapter9_CheckDepthStencilMatch(p,a,b,c,d) (p)->lpVtbl->CheckDepthStencilMatch(p,a,b,c,d) | |||
#define ID3DAdapter9_CheckDeviceFormatConversion(p,a,b,c) (p)->lpVtbl->CheckDeviceFormatConversion(p,a,b,c) | |||
#define ID3DAdapter9_GetDeviceCaps(p,a,b) (p)->lpVtbl->GetDeviceCaps(p,a,b) | |||
#define ID3DAdapter9_CreateDevice(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->CreateDevice(p,a,b,c,d,e,f,g,h) | |||
#define ID3DAdapter9_CreateDeviceEx(p,a,b,c,d,e,f,g,h,i) (p)->lpVtbl->CreateDeviceEx(p,a,b,c,d,e,f,g,h,i) | |||
#else /* __cplusplus */ | |||
struct ID3DAdapter9 : public IUnknown | |||
{ | |||
HRESULT WINAPI GetAdapterIdentifier(DWORD Flags, D3DADAPTER_IDENTIFIER9 *pIdentifier); | |||
HRESULT WINAPI CheckDeviceType(D3DDEVTYPE DevType, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, BOOL bWindowed); | |||
HRESULT WINAPI CheckDeviceFormat(D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat); | |||
HRESULT WINAPI CheckDeviceMultiSampleType(D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD *pQualityLevels); | |||
HRESULT WINAPI CheckDepthStencilMatch(D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat); | |||
HRESULT WINAPI CheckDeviceFormatConversion(D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat); | |||
HRESULT WINAPI GetDeviceCaps(D3DDEVTYPE DeviceType, D3DCAPS9 *pCaps); | |||
HRESULT WINAPI CreateDevice(UINT RealAdapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS *pPresentationParameters, IDirect3D9 *pD3D9, ID3DPresentGroup *pPresentationFactory, IDirect3DDevice9 **ppReturnedDeviceInterface); | |||
HRESULT WINAPI CreateDeviceEx(UINT RealAdapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS *pPresentationParameters, D3DDISPLAYMODEEX *pFullscreenDisplayMode, IDirect3D9Ex *pD3D9Ex, ID3DPresentGroup *pPresentationFactory, IDirect3DDevice9Ex **ppReturnedDeviceInterface); | |||
}; | |||
#endif /* __cplusplus */ | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif /* __cplusplus */ | |||
/* acquire a const struct D3DAdapter9* structure describing the interface | |||
* queried. See */ | |||
const void * WINAPI | |||
D3DAdapter9GetProc( const char *name ); | |||
#ifdef __cplusplus | |||
} | |||
#endif /* __cplusplus */ | |||
#endif /* _D3DADAPTER9_H_ */ |
@@ -0,0 +1,44 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _D3DADAPTER9_DRM_H_ | |||
#define _D3DADAPTER9_DRM_H_ | |||
#include "d3dadapter9.h" | |||
/* query driver support name */ | |||
#define D3DADAPTER9DRM_NAME "drm" | |||
/* current version */ | |||
#define D3DADAPTER9DRM_MAJOR 0 | |||
#define D3DADAPTER9DRM_MINOR 0 | |||
struct D3DAdapter9DRM | |||
{ | |||
unsigned major_version; /* ABI break */ | |||
unsigned minor_version; /* backwards compatible feature additions */ | |||
/* NOTE: upon passing an fd to this function, it's now owned by this | |||
function. If this function fails, the fd will be closed here as well */ | |||
HRESULT (WINAPI *create_adapter)(int fd, ID3DAdapter9 **ppAdapter); | |||
}; | |||
#endif /* _D3DADAPTER9_DRM_H_ */ |
@@ -0,0 +1,136 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _D3DADAPTER_PRESENT_H_ | |||
#define _D3DADAPTER_PRESENT_H_ | |||
#include <d3d9.h> | |||
#ifndef D3DOK_WINDOW_OCCLUDED | |||
#define D3DOK_WINDOW_OCCLUDED MAKE_D3DSTATUS(2531) | |||
#endif /* D3DOK_WINDOW_OCCLUDED */ | |||
#ifndef __cplusplus | |||
typedef struct ID3DPresent ID3DPresent; | |||
typedef struct ID3DPresentGroup ID3DPresentGroup; | |||
typedef struct ID3DAdapter9 ID3DAdapter9; | |||
typedef struct D3DWindowBuffer D3DWindowBuffer; | |||
/* Presentation backend for drivers to display their brilliant work */ | |||
typedef struct ID3DPresentVtbl | |||
{ | |||
/* IUnknown */ | |||
HRESULT (WINAPI *QueryInterface)(ID3DPresent *This, REFIID riid, void **ppvObject); | |||
ULONG (WINAPI *AddRef)(ID3DPresent *This); | |||
ULONG (WINAPI *Release)(ID3DPresent *This); | |||
/* ID3DPresent */ | |||
/* This function initializes the screen and window provided at creation. | |||
* Hence why this should always be called as the one of first things a new | |||
* swap chain does */ | |||
HRESULT (WINAPI *SetPresentParameters)(ID3DPresent *This, D3DPRESENT_PARAMETERS *pPresentationParameters, D3DDISPLAYMODEEX *pFullscreenDisplayMode); | |||
/* Make a buffer visible to the window system via dma-buf fd. | |||
* For better compatibility, it must be 32bpp and format ARGB/XRGB */ | |||
HRESULT (WINAPI *NewD3DWindowBufferFromDmaBuf)(ID3DPresent *This, int dmaBufFd, int width, int height, int stride, int depth, int bpp, D3DWindowBuffer **out); | |||
HRESULT (WINAPI *DestroyD3DWindowBuffer)(ID3DPresent *This, D3DWindowBuffer *buffer); | |||
/* After presenting a buffer to the window system, the buffer | |||
* may be used as is (no copy of the content) by the window system. | |||
* You must not use a non-released buffer, else the user may see undefined content. */ | |||
HRESULT (WINAPI *WaitBufferReleased)(ID3DPresent *This, D3DWindowBuffer *buffer); | |||
HRESULT (WINAPI *FrontBufferCopy)(ID3DPresent *This, D3DWindowBuffer *buffer); | |||
/* It is possible to do partial copy, but impossible to do resizing, which must | |||
* be done by the client after checking the front buffer size */ | |||
HRESULT (WINAPI *PresentBuffer)(ID3DPresent *This, D3DWindowBuffer *buffer, HWND hWndOverride, const RECT *pSourceRect, const RECT *pDestRect, const RGNDATA *pDirtyRegion, DWORD Flags); | |||
HRESULT (WINAPI *GetRasterStatus)(ID3DPresent *This, D3DRASTER_STATUS *pRasterStatus); | |||
HRESULT (WINAPI *GetDisplayMode)(ID3DPresent *This, D3DDISPLAYMODEEX *pMode, D3DDISPLAYROTATION *pRotation); | |||
HRESULT (WINAPI *GetPresentStats)(ID3DPresent *This, D3DPRESENTSTATS *pStats); | |||
HRESULT (WINAPI *GetCursorPos)(ID3DPresent *This, POINT *pPoint); | |||
HRESULT (WINAPI *SetCursorPos)(ID3DPresent *This, POINT *pPoint); | |||
/* Cursor size is always 32x32. pBitmap and pHotspot can be NULL. */ | |||
HRESULT (WINAPI *SetCursor)(ID3DPresent *This, void *pBitmap, POINT *pHotspot, BOOL bShow); | |||
HRESULT (WINAPI *SetGammaRamp)(ID3DPresent *This, const D3DGAMMARAMP *pRamp, HWND hWndOverride); | |||
HRESULT (WINAPI *GetWindowInfo)(ID3DPresent *This, HWND hWnd, int *width, int *height, int *depth); | |||
} ID3DPresentVtbl; | |||
struct ID3DPresent | |||
{ | |||
ID3DPresentVtbl *lpVtbl; | |||
}; | |||
/* IUnknown macros */ | |||
#define ID3DPresent_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) | |||
#define ID3DPresent_AddRef(p) (p)->lpVtbl->AddRef(p) | |||
#define ID3DPresent_Release(p) (p)->lpVtbl->Release(p) | |||
/* ID3DPresent macros */ | |||
#define ID3DPresent_GetPresentParameters(p,a) (p)->lpVtbl->GetPresentParameters(p,a) | |||
#define ID3DPresent_SetPresentParameters(p,a,b) (p)->lpVtbl->SetPresentParameters(p,a,b) | |||
#define ID3DPresent_NewD3DWindowBufferFromDmaBuf(p,a,b,c,d,e,f,g) (p)->lpVtbl->NewD3DWindowBufferFromDmaBuf(p,a,b,c,d,e,f,g) | |||
#define ID3DPresent_DestroyD3DWindowBuffer(p,a) (p)->lpVtbl->DestroyD3DWindowBuffer(p,a) | |||
#define ID3DPresent_WaitBufferReleased(p,a) (p)->lpVtbl->WaitBufferReleased(p,a) | |||
#define ID3DPresent_FrontBufferCopy(p,a) (p)->lpVtbl->FrontBufferCopy(p,a) | |||
#define ID3DPresent_PresentBuffer(p,a,b,c,d,e,f) (p)->lpVtbl->PresentBuffer(p,a,b,c,d,e,f) | |||
#define ID3DPresent_GetRasterStatus(p,a) (p)->lpVtbl->GetRasterStatus(p,a) | |||
#define ID3DPresent_GetDisplayMode(p,a,b) (p)->lpVtbl->GetDisplayMode(p,a,b) | |||
#define ID3DPresent_GetPresentStats(p,a) (p)->lpVtbl->GetPresentStats(p,a) | |||
#define ID3DPresent_GetCursorPos(p,a) (p)->lpVtbl->GetCursorPos(p,a) | |||
#define ID3DPresent_SetCursorPos(p,a) (p)->lpVtbl->SetCursorPos(p,a) | |||
#define ID3DPresent_SetCursor(p,a,b,c) (p)->lpVtbl->SetCursor(p,a,b,c) | |||
#define ID3DPresent_SetGammaRamp(p,a,b) (p)->lpVtbl->SetGammaRamp(p,a,b) | |||
#define ID3DPresent_GetWindowInfo(p,a,b,c,d) (p)->lpVtbl->GetWindowSize(p,a,b,c,d) | |||
typedef struct ID3DPresentGroupVtbl | |||
{ | |||
/* IUnknown */ | |||
HRESULT (WINAPI *QueryInterface)(ID3DPresentGroup *This, REFIID riid, void **ppvObject); | |||
ULONG (WINAPI *AddRef)(ID3DPresentGroup *This); | |||
ULONG (WINAPI *Release)(ID3DPresentGroup *This); | |||
/* ID3DPresentGroup */ | |||
/* When creating a device, it's relevant for the driver to know how many | |||
* implicit swap chains to create. It has to create one per monitor in a | |||
* multi-monitor setup */ | |||
UINT (WINAPI *GetMultiheadCount)(ID3DPresentGroup *This); | |||
/* returns only the implicit present interfaces */ | |||
HRESULT (WINAPI *GetPresent)(ID3DPresentGroup *This, UINT Index, ID3DPresent **ppPresent); | |||
/* used to create additional presentation interfaces along the way */ | |||
HRESULT (WINAPI *CreateAdditionalPresent)(ID3DPresentGroup *This, D3DPRESENT_PARAMETERS *pPresentationParameters, ID3DPresent **ppPresent); | |||
void (WINAPI *GetVersion) (ID3DPresentGroup *This, int *major, int *minor); | |||
} ID3DPresentGroupVtbl; | |||
struct ID3DPresentGroup | |||
{ | |||
ID3DPresentGroupVtbl *lpVtbl; | |||
}; | |||
/* IUnknown macros */ | |||
#define ID3DPresentGroup_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) | |||
#define ID3DPresentGroup_AddRef(p) (p)->lpVtbl->AddRef(p) | |||
#define ID3DPresentGroup_Release(p) (p)->lpVtbl->Release(p) | |||
/* ID3DPresentGroup */ | |||
#define ID3DPresentGroup_GetMultiheadCount(p) (p)->lpVtbl->GetMultiheadCount(p) | |||
#define ID3DPresentGroup_GetPresent(p,a,b) (p)->lpVtbl->GetPresent(p,a,b) | |||
#define ID3DPresentGroup_CreateAdditionalPresent(p,a,b) (p)->lpVtbl->CreateAdditionalPresent(p,a,b) | |||
#define ID3DPresentGroup_GetVersion(p,a,b) (p)->lpVtbl->GetVersion(p,a,b) | |||
#endif /* __cplusplus */ | |||
#endif /* _D3DADAPTER_PRESENT_H_ */ |
@@ -166,6 +166,10 @@ if HAVE_ST_XVMC | |||
SUBDIRS += state_trackers/xvmc targets/xvmc | |||
endif | |||
if HAVE_ST_NINE | |||
SUBDIRS += state_trackers/nine targets/d3dadapter9 | |||
endif | |||
## | |||
## Don't forget to bundle the remaining (non autotools) state-trackers/targets | |||
## |
@@ -91,6 +91,34 @@ drisw_create_screen(struct drisw_loader_funcs *lf) | |||
return screen; | |||
} | |||
#endif // DRI_TARGET | |||
#if defined(NINE_TARGET) | |||
#include "sw/wrapper/wrapper_sw_winsys.h" | |||
#include "target-helpers/inline_debug_helper.h" | |||
extern struct pipe_screen *ninesw_create_screen(struct pipe_screen *screen); | |||
INLINE struct pipe_screen * | |||
ninesw_create_screen(struct pipe_screen *pscreen) | |||
{ | |||
struct sw_winsys *winsys = NULL; | |||
struct pipe_screen *screen = NULL; | |||
winsys = wrapper_sw_winsys_wrap_pipe_screen(pscreen); | |||
if (winsys == NULL) | |||
return NULL; | |||
screen = sw_screen_create(winsys); | |||
if (screen == NULL) { | |||
winsys->destroy(winsys); | |||
return NULL; | |||
} | |||
screen = debug_screen_wrap(screen); | |||
return screen; | |||
} | |||
#endif // NINE_TARGET | |||
#endif // GALLIUM_SOFTPIPE | |||
@@ -0,0 +1,13 @@ | |||
include Makefile.sources | |||
include $(top_srcdir)/src/gallium/Automake.inc | |||
AM_CFLAGS = \ | |||
-I$(top_srcdir)/include/D3D9 \ | |||
$(GALLIUM_CFLAGS) \ | |||
$(VISIBILITY_CFLAGS) | |||
noinst_LTLIBRARIES = libninetracker.la | |||
libninetracker_la_SOURCES = $(C_SOURCES) | |||
EXTRA_DIST = README |
@@ -0,0 +1,71 @@ | |||
C_SOURCES := \ | |||
adapter9.c \ | |||
adapter9.h \ | |||
authenticatedchannel9.c \ | |||
authenticatedchannel9.h \ | |||
basetexture9.c \ | |||
basetexture9.h \ | |||
cryptosession9.c \ | |||
cryptosession9.h \ | |||
cubetexture9.c \ | |||
cubetexture9.h \ | |||
device9.c \ | |||
device9.h \ | |||
device9ex.c \ | |||
device9ex.h \ | |||
device9video.c \ | |||
device9video.h \ | |||
guid.c \ | |||
guid.h \ | |||
indexbuffer9.c \ | |||
indexbuffer9.h \ | |||
iunknown.c \ | |||
iunknown.h \ | |||
nine_debug.c \ | |||
nine_debug.h \ | |||
nine_defines.h \ | |||
nine_dump.c \ | |||
nine_dump.h \ | |||
nineexoverlayextension.c \ | |||
nineexoverlayextension.h \ | |||
nine_ff.c \ | |||
nine_ff.h \ | |||
nine_helpers.c \ | |||
nine_helpers.h \ | |||
nine_lock.c \ | |||
nine_lock.h \ | |||
nine_pdata.h \ | |||
nine_pipe.c \ | |||
nine_pipe.h \ | |||
nine_quirk.c \ | |||
nine_quirk.h \ | |||
nine_shader.c \ | |||
nine_shader.h \ | |||
nine_state.c \ | |||
nine_state.h \ | |||
pixelshader9.c \ | |||
pixelshader9.h \ | |||
query9.c \ | |||
query9.h \ | |||
resource9.c \ | |||
resource9.h \ | |||
stateblock9.c \ | |||
stateblock9.h \ | |||
surface9.c \ | |||
surface9.h \ | |||
swapchain9.c \ | |||
swapchain9ex.c \ | |||
swapchain9ex.h \ | |||
swapchain9.h \ | |||
texture9.c \ | |||
texture9.h \ | |||
vertexbuffer9.c \ | |||
vertexbuffer9.h \ | |||
vertexdeclaration9.c \ | |||
vertexdeclaration9.h \ | |||
vertexshader9.c \ | |||
vertexshader9.h \ | |||
volume9.c \ | |||
volume9.h \ | |||
volumetexture9.c \ | |||
volumetexture9.h |
@@ -0,0 +1,78 @@ | |||
Quickstart Guide | |||
*** Configure and build mesa | |||
CFLAGS="-m32" CXXFLAGS="-m32" ./autogen.sh --prefix=/usr \ | |||
--with-gallium-drivers=nouveau,r600,swrast --enable-nine \ | |||
--with-gallium-driver-dir="`pwd`/src/gallium/targets/pipe-loader/.libs" \ | |||
--enable-debug --enable-texture-float --with-dri-drivers= --disable-dri \ | |||
--disable-opengl --disable-egl --disable-vdpau --disable-xvmc --disable-gbm \ | |||
--disable-gallium-llvm | |||
make | |||
*** Then we create some symlinks to mesa: | |||
ln -s "`pwd`/lib/gallium/libd3dadapter9.so.0.0.0" /usr/lib/ | |||
ln -s "`pwd`/lib/gallium/libd3dadapter9.so.0" /usr/lib/ | |||
ln -s "`pwd`/lib/gallium/libd3dadapter9.so" /usr/lib/ | |||
ln -s "`pwd`/include/d3dadapter" /usr/include/ | |||
*** Clone and build a patched wine | |||
git clone git@github.com:iXit/wine.git | |||
./configure | |||
make | |||
*** And finally we create some symlinks to our patched wine files: | |||
for f in d3d9.dll gdi32.dll user32.dll wineps.drv winex11.drv; | |||
do | |||
mv /usr/lib/wine/$f.so /usr/lib/wine/$f.so.old | |||
ln -s "`pwd`/dlls/`basename -s .dll $f`/$f.so" /usr/lib/wine/ | |||
done | |||
*** Activating it within wine | |||
regedit | |||
Navigate to HKCU\Software\Wine\Direct3D | |||
If it's not there, create it | |||
Create a new DWORD value called UseNative | |||
Set its value to 1 | |||
Every Direct3D9 program will now try using nine before wined3d | |||
If you want to selectively enable it per-exe instead, use the key: | |||
HKCU\Software\Wine\AppDefaults\app.exe\Direct3D\UseNative | |||
where app.exe is the name of your .exe file | |||
*** HOW IT WORKS *** | |||
Nine implements the full IDirect3DDevice9 COM interface and a custom COM | |||
interface called ID3DAdapter9 which is used to implement a final IDirect3D9Ex | |||
COM interface. | |||
ID3DAdapter9 is completely devoid of window system code, meaning this can be | |||
provided by wine, Xlib, Wayland, etc. It's inadvisible to write a non-Windows | |||
backend though, as we don't want to encourage linux developers to use this API. | |||
The state tracker is compiled, along with pipe-loader, into a library called | |||
libd3dadapter9.so. This library loads pipe_[driver].so drivers on demand and | |||
exports a single symbol for getting a subsystem driver. Currently only DRM is | |||
supported. | |||
This library is then linked to the library implementing the IDirect3D9[Ex] | |||
interface and the actual Direct3D9 entry points (Direct3DCreate9[Ex]) | |||
The implementation of IDirect3D9[Ex] lies within wine and coexists with | |||
wined3d. It's loaded on demand and so if it's not there, it doesn't have any | |||
drivers or something else is wrong, d3d9.dll will automatically revert to using | |||
wined3d. | |||
Whether or not it's even tried is determined by 2 DWORD registry keys. | |||
> HKCU\Software\Wine\Direct3D\UseNative | |||
> HKCU\Software\Wine\AppDefaults\app.exe\Direct3D\UseNative | |||
The former is the global on-switch. The latter is per-exe. | |||
The driver search path can be set at configure time with | |||
--with-gallium-driver-dir and overridden at runtime with D3D9_DRIVERS_PATH. | |||
Debugging information can be gotten with the WINEDEBUG channels d3d9 and | |||
d3dadapter, and state_tracker debug information can be gotten with NINE_DEBUG. | |||
Help on NINE_DEBUG is shown through NINE_DEBUG=help | |||
Finally, the ID3DPresent[Group] and ID3DAdapter9 interfaces are not set in | |||
stone, so feel free to hack on those as well as st/nine. | |||
Happy Hacking! |
@@ -0,0 +1,137 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_ADAPTER9_H_ | |||
#define _NINE_ADAPTER9_H_ | |||
#include "iunknown.h" | |||
#include "d3dadapter/d3dadapter9.h" | |||
struct pipe_screen; | |||
struct pipe_resource; | |||
struct d3dadapter9_context | |||
{ | |||
struct pipe_screen *hal, *ref; | |||
D3DADAPTER_IDENTIFIER9 identifier; | |||
BOOL linear_framebuffer; | |||
BOOL throttling; | |||
int throttling_value; | |||
void (*destroy)( struct d3dadapter9_context *ctx ); | |||
}; | |||
struct NineAdapter9 | |||
{ | |||
struct NineUnknown base; | |||
struct d3dadapter9_context *ctx; | |||
}; | |||
static INLINE struct NineAdapter9 * | |||
NineAdapter9( void *data ) | |||
{ | |||
return (struct NineAdapter9 *)data; | |||
} | |||
HRESULT | |||
NineAdapter9_new( struct d3dadapter9_context *pCTX, | |||
struct NineAdapter9 **ppOut ); | |||
HRESULT | |||
NineAdapter9_ctor( struct NineAdapter9 *This, | |||
struct NineUnknownParams *pParams, | |||
struct d3dadapter9_context *pCTX ); | |||
void | |||
NineAdapter9_dtor( struct NineAdapter9 *This ); | |||
HRESULT WINAPI | |||
NineAdapter9_GetAdapterIdentifier( struct NineAdapter9 *This, | |||
DWORD Flags, | |||
D3DADAPTER_IDENTIFIER9 *pIdentifier ); | |||
HRESULT WINAPI | |||
NineAdapter9_CheckDeviceType( struct NineAdapter9 *This, | |||
D3DDEVTYPE DevType, | |||
D3DFORMAT AdapterFormat, | |||
D3DFORMAT BackBufferFormat, | |||
BOOL bWindowed ); | |||
HRESULT WINAPI | |||
NineAdapter9_CheckDeviceFormat( struct NineAdapter9 *This, | |||
D3DDEVTYPE DeviceType, | |||
D3DFORMAT AdapterFormat, | |||
DWORD Usage, | |||
D3DRESOURCETYPE RType, | |||
D3DFORMAT CheckFormat ); | |||
HRESULT WINAPI | |||
NineAdapter9_CheckDeviceMultiSampleType( struct NineAdapter9 *This, | |||
D3DDEVTYPE DeviceType, | |||
D3DFORMAT SurfaceFormat, | |||
BOOL Windowed, | |||
D3DMULTISAMPLE_TYPE MultiSampleType, | |||
DWORD *pQualityLevels ); | |||
HRESULT WINAPI | |||
NineAdapter9_CheckDepthStencilMatch( struct NineAdapter9 *This, | |||
D3DDEVTYPE DeviceType, | |||
D3DFORMAT AdapterFormat, | |||
D3DFORMAT RenderTargetFormat, | |||
D3DFORMAT DepthStencilFormat ); | |||
HRESULT WINAPI | |||
NineAdapter9_CheckDeviceFormatConversion( struct NineAdapter9 *This, | |||
D3DDEVTYPE DeviceType, | |||
D3DFORMAT SourceFormat, | |||
D3DFORMAT TargetFormat ); | |||
HRESULT WINAPI | |||
NineAdapter9_GetDeviceCaps( struct NineAdapter9 *This, | |||
D3DDEVTYPE DeviceType, | |||
D3DCAPS9 *pCaps ); | |||
HRESULT WINAPI | |||
NineAdapter9_CreateDevice( struct NineAdapter9 *This, | |||
UINT RealAdapter, | |||
D3DDEVTYPE DeviceType, | |||
HWND hFocusWindow, | |||
DWORD BehaviorFlags, | |||
D3DPRESENT_PARAMETERS *pPresentationParameters, | |||
IDirect3D9 *pD3D9, | |||
ID3DPresentGroup *pPresentationGroup, | |||
IDirect3DDevice9 **ppReturnedDeviceInterface ); | |||
HRESULT WINAPI | |||
NineAdapter9_CreateDeviceEx( struct NineAdapter9 *This, | |||
UINT RealAdapter, | |||
D3DDEVTYPE DeviceType, | |||
HWND hFocusWindow, | |||
DWORD BehaviorFlags, | |||
D3DPRESENT_PARAMETERS *pPresentationParameters, | |||
D3DDISPLAYMODEEX *pFullscreenDisplayMode, | |||
IDirect3D9Ex *pD3D9Ex, | |||
ID3DPresentGroup *pPresentationGroup, | |||
IDirect3DDevice9Ex **ppReturnedDeviceInterface ); | |||
#endif /* _NINE_ADAPTER9_H_ */ |
@@ -0,0 +1,78 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "authenticatedchannel9.h" | |||
#define DBG_CHANNEL DBG_AUTHENTICATEDCHANNEL | |||
HRESULT WINAPI | |||
NineAuthenticatedChannel9_GetCertificateSize( struct NineAuthenticatedChannel9 *This, | |||
UINT *pCertificateSize ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineAuthenticatedChannel9_GetCertificate( struct NineAuthenticatedChannel9 *This, | |||
UINT CertifacteSize, | |||
BYTE *ppCertificate ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineAuthenticatedChannel9_NegotiateKeyExchange( struct NineAuthenticatedChannel9 *This, | |||
UINT DataSize, | |||
void *pData ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineAuthenticatedChannel9_Query( struct NineAuthenticatedChannel9 *This, | |||
UINT InputSize, | |||
const void *pInput, | |||
UINT OutputSize, | |||
void *pOutput ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineAuthenticatedChannel9_Configure( struct NineAuthenticatedChannel9 *This, | |||
UINT InputSize, | |||
const void *pInput, | |||
D3DAUTHENTICATEDCHANNEL_CONFIGURE_OUTPUT *pOutput ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
IDirect3DAuthenticatedChannel9Vtbl NineAuthenticatedChannel9_vtable = { | |||
(void *)NineUnknown_QueryInterface, | |||
(void *)NineUnknown_AddRef, | |||
(void *)NineUnknown_Release, | |||
(void *)NineAuthenticatedChannel9_GetCertificateSize, | |||
(void *)NineAuthenticatedChannel9_GetCertificate, | |||
(void *)NineAuthenticatedChannel9_NegotiateKeyExchange, | |||
(void *)NineAuthenticatedChannel9_Query, | |||
(void *)NineAuthenticatedChannel9_Configure | |||
}; |
@@ -0,0 +1,65 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_AUTHENTICATEDCHANNEL9_H_ | |||
#define _NINE_AUTHENTICATEDCHANNEL9_H_ | |||
#include "iunknown.h" | |||
struct NineAuthenticatedChannel9 | |||
{ | |||
struct NineUnknown base; | |||
}; | |||
static INLINE struct NineAuthenticatedChannel9 * | |||
NineAuthenticatedChannel9( void *data ) | |||
{ | |||
return (struct NineAuthenticatedChannel9 *)data; | |||
} | |||
HRESULT WINAPI | |||
NineAuthenticatedChannel9_GetCertificateSize( struct NineAuthenticatedChannel9 *This, | |||
UINT *pCertificateSize ); | |||
HRESULT WINAPI | |||
NineAuthenticatedChannel9_GetCertificate( struct NineAuthenticatedChannel9 *This, | |||
UINT CertifacteSize, | |||
BYTE *ppCertificate ); | |||
HRESULT WINAPI | |||
NineAuthenticatedChannel9_NegotiateKeyExchange( struct NineAuthenticatedChannel9 *This, | |||
UINT DataSize, | |||
void *pData ); | |||
HRESULT WINAPI | |||
NineAuthenticatedChannel9_Query( struct NineAuthenticatedChannel9 *This, | |||
UINT InputSize, | |||
const void *pInput, | |||
UINT OutputSize, | |||
void *pOutput ); | |||
HRESULT WINAPI | |||
NineAuthenticatedChannel9_Configure( struct NineAuthenticatedChannel9 *This, | |||
UINT InputSize, | |||
const void *pInput, | |||
D3DAUTHENTICATEDCHANNEL_CONFIGURE_OUTPUT *pOutput ); | |||
#endif /* _NINE_AUTHENTICATEDCHANNEL9_H_ */ |
@@ -0,0 +1,504 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "basetexture9.h" | |||
#include "device9.h" | |||
/* For UploadSelf: */ | |||
#include "texture9.h" | |||
#include "cubetexture9.h" | |||
#include "volumetexture9.h" | |||
#ifdef DEBUG | |||
#include "nine_pipe.h" | |||
#include "nine_dump.h" | |||
#endif | |||
#include "util/u_format.h" | |||
#include "util/u_gen_mipmap.h" | |||
#define DBG_CHANNEL DBG_BASETEXTURE | |||
HRESULT | |||
NineBaseTexture9_ctor( struct NineBaseTexture9 *This, | |||
struct NineUnknownParams *pParams, | |||
D3DRESOURCETYPE Type, | |||
D3DPOOL Pool ) | |||
{ | |||
BOOL alloc = (Pool == D3DPOOL_DEFAULT) && !This->base.resource && | |||
(This->format != D3DFMT_NULL); | |||
HRESULT hr; | |||
DWORD usage = This->base.usage; | |||
user_assert(!(usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) || | |||
Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); | |||
user_assert(!(usage & D3DUSAGE_DYNAMIC) || | |||
Pool != D3DPOOL_MANAGED, D3DERR_INVALIDCALL); | |||
hr = NineResource9_ctor(&This->base, pParams, alloc, Type, Pool); | |||
if (FAILED(hr)) | |||
return hr; | |||
This->pipe = pParams->device->pipe; | |||
This->mipfilter = (This->base.usage & D3DUSAGE_AUTOGENMIPMAP) ? | |||
D3DTEXF_LINEAR : D3DTEXF_NONE; | |||
This->lod = 0; | |||
This->lod_resident = -1; | |||
This->shadow = This->format != D3DFMT_INTZ && util_format_has_depth( | |||
util_format_description(This->base.info.format)); | |||
list_inithead(&This->list); | |||
return D3D_OK; | |||
} | |||
void | |||
NineBaseTexture9_dtor( struct NineBaseTexture9 *This ) | |||
{ | |||
DBG("This=%p\n", This); | |||
pipe_sampler_view_reference(&This->view[0], NULL); | |||
pipe_sampler_view_reference(&This->view[1], NULL); | |||
list_del(&This->list), | |||
NineResource9_dtor(&This->base); | |||
} | |||
DWORD WINAPI | |||
NineBaseTexture9_SetLOD( struct NineBaseTexture9 *This, | |||
DWORD LODNew ) | |||
{ | |||
DWORD old = This->lod; | |||
user_assert(This->base.pool == D3DPOOL_MANAGED, 0); | |||
This->lod = MIN2(LODNew, This->base.info.last_level); | |||
if (This->lod != old && This->bind_count && LIST_IS_EMPTY(&This->list)) | |||
list_add(&This->list, &This->base.base.device->update_textures); | |||
return old; | |||
} | |||
DWORD WINAPI | |||
NineBaseTexture9_GetLOD( struct NineBaseTexture9 *This ) | |||
{ | |||
return This->lod; | |||
} | |||
DWORD WINAPI | |||
NineBaseTexture9_GetLevelCount( struct NineBaseTexture9 *This ) | |||
{ | |||
if (This->base.usage & D3DUSAGE_AUTOGENMIPMAP) | |||
return 1; | |||
return This->base.info.last_level + 1; | |||
} | |||
HRESULT WINAPI | |||
NineBaseTexture9_SetAutoGenFilterType( struct NineBaseTexture9 *This, | |||
D3DTEXTUREFILTERTYPE FilterType ) | |||
{ | |||
if (!(This->base.usage & D3DUSAGE_AUTOGENMIPMAP)) | |||
return D3D_OK; | |||
user_assert(FilterType != D3DTEXF_NONE, D3DERR_INVALIDCALL); | |||
This->mipfilter = FilterType; | |||
return D3D_OK; | |||
} | |||
D3DTEXTUREFILTERTYPE WINAPI | |||
NineBaseTexture9_GetAutoGenFilterType( struct NineBaseTexture9 *This ) | |||
{ | |||
return This->mipfilter; | |||
} | |||
HRESULT | |||
NineBaseTexture9_UploadSelf( struct NineBaseTexture9 *This ) | |||
{ | |||
HRESULT hr; | |||
unsigned last_level = This->base.info.last_level; | |||
unsigned l; | |||
DBG("This=%p dirty=%i type=%s\n", This, This->dirty, | |||
nine_D3DRTYPE_to_str(This->base.type)); | |||
assert(This->base.pool == D3DPOOL_MANAGED); | |||
if (This->base.usage & D3DUSAGE_AUTOGENMIPMAP) | |||
last_level = 0; /* TODO: What if level 0 is not resident ? */ | |||
if (This->lod_resident != This->lod) { | |||
struct pipe_resource *res; | |||
DBG("updating LOD from %u to %u ...\n", This->lod_resident, This->lod); | |||
pipe_sampler_view_reference(&This->view[0], NULL); | |||
pipe_sampler_view_reference(&This->view[1], NULL); | |||
if (This->bind_count) { | |||
/* mark state dirty */ | |||
struct nine_state *state = &This->base.base.device->state; | |||
unsigned s; | |||
for (s = 0; s < NINE_MAX_SAMPLERS; ++s) | |||
if (state->texture[s] == This) | |||
state->changed.texture |= 1 << s; | |||
if (state->changed.texture) | |||
state->changed.group |= NINE_STATE_TEXTURE; | |||
} | |||
hr = NineBaseTexture9_CreatePipeResource(This, This->lod_resident != -1); | |||
if (FAILED(hr)) | |||
return hr; | |||
res = This->base.resource; | |||
if (This->lod_resident == -1) /* no levels were resident */ | |||
This->lod_resident = This->base.info.last_level + 1; | |||
if (This->base.type == D3DRTYPE_TEXTURE) { | |||
struct NineTexture9 *tex = NineTexture9(This); | |||
struct pipe_box box; | |||
/* Mark uninitialized levels as dirty. */ | |||
box.x = box.y = box.z = 0; | |||
box.depth = 1; | |||
for (l = This->lod; l < This->lod_resident; ++l) { | |||
box.width = u_minify(This->base.info.width0, l); | |||
box.height = u_minify(This->base.info.height0, l); | |||
NineSurface9_AddDirtyRect(tex->surfaces[l], &box); | |||
} | |||
for (l = 0; l < This->lod; ++l) | |||
NineSurface9_SetResource(tex->surfaces[l], NULL, -1); | |||
for (; l <= This->base.info.last_level; ++l) | |||
NineSurface9_SetResource(tex->surfaces[l], res, l - This->lod); | |||
} else | |||
if (This->base.type == D3DRTYPE_CUBETEXTURE) { | |||
struct NineCubeTexture9 *tex = NineCubeTexture9(This); | |||
struct pipe_box box; | |||
unsigned z; | |||
/* Mark uninitialized levels as dirty. */ | |||
box.x = box.y = box.z = 0; | |||
box.depth = 1; | |||
for (l = This->lod; l < This->lod_resident; ++l) { | |||
box.width = u_minify(This->base.info.width0, l); | |||
box.height = u_minify(This->base.info.height0, l); | |||
for (z = 0; z < 6; ++z) | |||
NineSurface9_AddDirtyRect(tex->surfaces[l * 6 + z], &box); | |||
} | |||
for (l = 0; l < This->lod; ++l) { | |||
for (z = 0; z < 6; ++z) | |||
NineSurface9_SetResource(tex->surfaces[l * 6 + z], | |||
NULL, -1); | |||
} | |||
for (; l <= This->base.info.last_level; ++l) { | |||
for (z = 0; z < 6; ++z) | |||
NineSurface9_SetResource(tex->surfaces[l * 6 + z], | |||
res, l - This->lod); | |||
} | |||
} else | |||
if (This->base.type == D3DRTYPE_VOLUMETEXTURE) { | |||
struct NineVolumeTexture9 *tex = NineVolumeTexture9(This); | |||
struct pipe_box box; | |||
/* Mark uninitialized levels as dirty. */ | |||
box.x = box.y = box.z = 0; | |||
for (l = This->lod; l < This->lod_resident; ++l) { | |||
box.width = u_minify(This->base.info.width0, l); | |||
box.height = u_minify(This->base.info.height0, l); | |||
box.depth = u_minify(This->base.info.depth0, l); | |||
NineVolume9_AddDirtyRegion(tex->volumes[l], &box); | |||
} | |||
for (l = 0; l < This->lod; ++l) | |||
NineVolume9_SetResource(tex->volumes[l], NULL, -1); | |||
for (; l <= This->base.info.last_level; ++l) | |||
NineVolume9_SetResource(tex->volumes[l], res, l - This->lod); | |||
} else { | |||
assert(!"invalid texture type"); | |||
} | |||
if (This->lod < This->lod_resident) | |||
This->dirty = TRUE; | |||
This->lod_resident = This->lod; | |||
} | |||
if (!This->dirty) | |||
return D3D_OK; | |||
if (This->base.type == D3DRTYPE_TEXTURE) { | |||
struct NineTexture9 *tex = NineTexture9(This); | |||
struct pipe_box box; | |||
box.z = 0; | |||
box.depth = 1; | |||
DBG("TEXTURE: dirty rect=(%u,%u) (%ux%u)\n", | |||
tex->dirty_rect.x, tex->dirty_rect.y, | |||
tex->dirty_rect.width, tex->dirty_rect.height); | |||
if (tex->dirty_rect.width) { | |||
for (l = 0; l <= last_level; ++l) { | |||
u_box_minify_2d(&box, &tex->dirty_rect, l); | |||
NineSurface9_AddDirtyRect(tex->surfaces[l], &box); | |||
} | |||
memset(&tex->dirty_rect, 0, sizeof(tex->dirty_rect)); | |||
tex->dirty_rect.depth = 1; | |||
} | |||
for (l = This->lod; l <= last_level; ++l) | |||
NineSurface9_UploadSelf(tex->surfaces[l]); | |||
} else | |||
if (This->base.type == D3DRTYPE_CUBETEXTURE) { | |||
struct NineCubeTexture9 *tex = NineCubeTexture9(This); | |||
unsigned z; | |||
struct pipe_box box; | |||
box.z = 0; | |||
box.depth = 1; | |||
for (z = 0; z < 6; ++z) { | |||
DBG("FACE[%u]: dirty rect=(%u,%u) (%ux%u)\n", z, | |||
tex->dirty_rect[z].x, tex->dirty_rect[z].y, | |||
tex->dirty_rect[z].width, tex->dirty_rect[z].height); | |||
if (tex->dirty_rect[z].width) { | |||
for (l = 0; l <= last_level; ++l) { | |||
u_box_minify_2d(&box, &tex->dirty_rect[z], l); | |||
NineSurface9_AddDirtyRect(tex->surfaces[l * 6 + z], &box); | |||
} | |||
memset(&tex->dirty_rect[z], 0, sizeof(tex->dirty_rect[z])); | |||
tex->dirty_rect[z].depth = 1; | |||
} | |||
for (l = This->lod; l <= last_level; ++l) | |||
NineSurface9_UploadSelf(tex->surfaces[l * 6 + z]); | |||
} | |||
} else | |||
if (This->base.type == D3DRTYPE_VOLUMETEXTURE) { | |||
struct NineVolumeTexture9 *tex = NineVolumeTexture9(This); | |||
struct pipe_box box; | |||
DBG("VOLUME: dirty_box=(%u,%u,%u) (%ux%ux%u)\n", | |||
tex->dirty_box.x, tex->dirty_box.y, tex->dirty_box.y, | |||
tex->dirty_box.width, tex->dirty_box.height, tex->dirty_box.depth); | |||
if (tex->dirty_box.width) { | |||
for (l = 0; l <= last_level; ++l) { | |||
u_box_minify_2d(&box, &tex->dirty_box, l); | |||
NineVolume9_AddDirtyRegion(tex->volumes[l], &tex->dirty_box); | |||
} | |||
memset(&tex->dirty_box, 0, sizeof(tex->dirty_box)); | |||
} | |||
for (l = This->lod; l <= last_level; ++l) | |||
NineVolume9_UploadSelf(tex->volumes[l]); | |||
} else { | |||
assert(!"invalid texture type"); | |||
} | |||
This->dirty = FALSE; | |||
if (This->base.usage & D3DUSAGE_AUTOGENMIPMAP) | |||
This->dirty_mip = TRUE; | |||
/* TODO: if dirty only because of lod change, only generate added levels */ | |||
DBG("DONE, generate mip maps = %i\n", This->dirty_mip); | |||
return D3D_OK; | |||
} | |||
void WINAPI | |||
NineBaseTexture9_GenerateMipSubLevels( struct NineBaseTexture9 *This ) | |||
{ | |||
struct pipe_resource *resource = This->base.resource; | |||
unsigned base_level = 0; | |||
unsigned last_level = This->base.info.last_level - This->lod; | |||
unsigned first_layer = 0; | |||
unsigned last_layer; | |||
unsigned filter = This->mipfilter == D3DTEXF_POINT ? PIPE_TEX_FILTER_NEAREST | |||
: PIPE_TEX_FILTER_LINEAR; | |||
DBG("This=%p\n", This); | |||
if (This->base.pool == D3DPOOL_MANAGED) | |||
NineBaseTexture9_UploadSelf(This); | |||
if (!This->dirty_mip) | |||
return; | |||
if (This->lod) { | |||
ERR("AUTOGENMIPMAP if level 0 is not resident not supported yet !\n"); | |||
return; | |||
} | |||
if (!This->view[0]) | |||
NineBaseTexture9_UpdateSamplerView(This, 0); | |||
last_layer = util_max_layer(This->view[0]->texture, base_level); | |||
util_gen_mipmap(This->pipe, resource, | |||
resource->format, base_level, last_level, | |||
first_layer, last_layer, filter); | |||
This->dirty_mip = FALSE; | |||
NineDevice9_RestoreNonCSOState(This->base.base.device, ~0x3); | |||
} | |||
HRESULT | |||
NineBaseTexture9_CreatePipeResource( struct NineBaseTexture9 *This, | |||
BOOL CopyData ) | |||
{ | |||
struct pipe_context *pipe = This->pipe; | |||
struct pipe_screen *screen = This->base.info.screen; | |||
struct pipe_resource templ; | |||
unsigned l, m; | |||
struct pipe_resource *res; | |||
struct pipe_resource *old = This->base.resource; | |||
DBG("This=%p lod=%u last_level=%u\n", This, | |||
This->lod, This->base.info.last_level); | |||
assert(This->base.pool == D3DPOOL_MANAGED); | |||
templ = This->base.info; | |||
if (This->lod) { | |||
templ.width0 = u_minify(templ.width0, This->lod); | |||
templ.height0 = u_minify(templ.height0, This->lod); | |||
templ.depth0 = u_minify(templ.depth0, This->lod); | |||
} | |||
templ.last_level = This->base.info.last_level - This->lod; | |||
if (old) { | |||
/* LOD might have changed. */ | |||
if (old->width0 == templ.width0 && | |||
old->height0 == templ.height0 && | |||
old->depth0 == templ.depth0) | |||
return D3D_OK; | |||
} | |||
res = screen->resource_create(screen, &templ); | |||
if (!res) | |||
return D3DERR_OUTOFVIDEOMEMORY; | |||
This->base.resource = res; | |||
if (old && CopyData) { /* Don't return without releasing old ! */ | |||
struct pipe_box box; | |||
box.x = 0; | |||
box.y = 0; | |||
box.z = 0; | |||
l = (This->lod < This->lod_resident) ? This->lod_resident - This->lod : 0; | |||
m = (This->lod < This->lod_resident) ? 0 : This->lod - This->lod_resident; | |||
box.width = u_minify(templ.width0, l); | |||
box.height = u_minify(templ.height0, l); | |||
box.depth = u_minify(templ.depth0, l); | |||
for (; l <= templ.last_level; ++l, ++m) { | |||
pipe->resource_copy_region(pipe, | |||
res, l, 0, 0, 0, | |||
old, m, &box); | |||
box.width = u_minify(box.width, 1); | |||
box.height = u_minify(box.height, 1); | |||
box.depth = u_minify(box.depth, 1); | |||
} | |||
} | |||
pipe_resource_reference(&old, NULL); | |||
return D3D_OK; | |||
} | |||
HRESULT | |||
NineBaseTexture9_UpdateSamplerView( struct NineBaseTexture9 *This, | |||
const int sRGB ) | |||
{ | |||
const struct util_format_description *desc; | |||
struct pipe_context *pipe = This->pipe; | |||
struct pipe_resource *resource = This->base.resource; | |||
struct pipe_sampler_view templ; | |||
uint8_t swizzle[4]; | |||
if (unlikely(!resource)) { | |||
if (unlikely(This->format == D3DFMT_NULL)) | |||
return D3D_OK; | |||
NineBaseTexture9_Dump(This); | |||
} | |||
assert(resource); | |||
pipe_sampler_view_reference(&This->view[sRGB], NULL); | |||
swizzle[0] = PIPE_SWIZZLE_RED; | |||
swizzle[1] = PIPE_SWIZZLE_GREEN; | |||
swizzle[2] = PIPE_SWIZZLE_BLUE; | |||
swizzle[3] = PIPE_SWIZZLE_ALPHA; | |||
desc = util_format_description(resource->format); | |||
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) { | |||
/* ZZZ1 -> 0Z01 (see end of docs/source/tgsi.rst) | |||
* XXX: but it's wrong | |||
swizzle[0] = PIPE_SWIZZLE_ZERO; | |||
swizzle[2] = PIPE_SWIZZLE_ZERO; */ | |||
} else | |||
if (desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_X && | |||
desc->swizzle[3] == UTIL_FORMAT_SWIZZLE_1) { | |||
/* R001/RG01 -> R111/RG11 */ | |||
if (desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_0) | |||
swizzle[1] = PIPE_SWIZZLE_ONE; | |||
if (desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_0) | |||
swizzle[2] = PIPE_SWIZZLE_ONE; | |||
} | |||
/* but 000A remains unchanged */ | |||
templ.format = sRGB ? util_format_srgb(resource->format) : resource->format; | |||
templ.u.tex.first_layer = 0; | |||
templ.u.tex.last_layer = (resource->target == PIPE_TEXTURE_CUBE) ? | |||
5 : (This->base.info.depth0 - 1); | |||
templ.u.tex.first_level = 0; | |||
templ.u.tex.last_level = resource->last_level; | |||
templ.swizzle_r = swizzle[0]; | |||
templ.swizzle_g = swizzle[1]; | |||
templ.swizzle_b = swizzle[2]; | |||
templ.swizzle_a = swizzle[3]; | |||
templ.target = resource->target; | |||
This->view[sRGB] = pipe->create_sampler_view(pipe, resource, &templ); | |||
DBG("sampler view = %p(resource = %p)\n", This->view[sRGB], resource); | |||
return This->view ? D3D_OK : D3DERR_DRIVERINTERNALERROR; | |||
} | |||
void WINAPI | |||
NineBaseTexture9_PreLoad( struct NineBaseTexture9 *This ) | |||
{ | |||
if (This->dirty && This->base.pool == D3DPOOL_MANAGED) | |||
NineBaseTexture9_UploadSelf(This); | |||
} | |||
#ifdef DEBUG | |||
void | |||
NineBaseTexture9_Dump( struct NineBaseTexture9 *This ) | |||
{ | |||
DBG("\nNineBaseTexture9(%p->%p/%p): Pool=%s Type=%s Usage=%s\n" | |||
"Format=%s Dims=%ux%ux%u/%u LastLevel=%u Lod=%u(%u)\n", This, | |||
This->base.resource, This->base.data, | |||
nine_D3DPOOL_to_str(This->base.pool), | |||
nine_D3DRTYPE_to_str(This->base.type), | |||
nine_D3DUSAGE_to_str(This->base.usage), | |||
d3dformat_to_string(This->format), | |||
This->base.info.width0, This->base.info.height0, This->base.info.depth0, | |||
This->base.info.array_size, This->base.info.last_level, | |||
This->lod, This->lod_resident); | |||
} | |||
#endif /* DEBUG */ |
@@ -0,0 +1,138 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_BASETEXTURE9_H_ | |||
#define _NINE_BASETEXTURE9_H_ | |||
#include "resource9.h" | |||
#include "util/u_inlines.h" | |||
#include "util/u_double_list.h" | |||
struct NineBaseTexture9 | |||
{ | |||
struct NineResource9 base; | |||
struct list_head list; | |||
/* g3d */ | |||
struct pipe_context *pipe; | |||
struct pipe_sampler_view *view[2]; /* linear and sRGB */ | |||
D3DFORMAT format; | |||
D3DTEXTUREFILTERTYPE mipfilter; | |||
DWORD lod; | |||
DWORD lod_resident; | |||
int16_t bind_count; /* to Device9->state.texture */ | |||
boolean shadow; | |||
uint8_t pstype; /* 0: 2D, 1: 1D, 2: CUBE, 3: 3D */ | |||
boolean dirty; | |||
boolean dirty_mip; | |||
}; | |||
static INLINE struct NineBaseTexture9 * | |||
NineBaseTexture9( void *data ) | |||
{ | |||
return (struct NineBaseTexture9 *)data; | |||
} | |||
HRESULT | |||
NineBaseTexture9_ctor( struct NineBaseTexture9 *This, | |||
struct NineUnknownParams *pParams, | |||
D3DRESOURCETYPE Type, | |||
D3DPOOL Pool ); | |||
void | |||
NineBaseTexture9_dtor( struct NineBaseTexture9 *This ); | |||
DWORD WINAPI | |||
NineBaseTexture9_SetLOD( struct NineBaseTexture9 *This, | |||
DWORD LODNew ); | |||
DWORD WINAPI | |||
NineBaseTexture9_GetLOD( struct NineBaseTexture9 *This ); | |||
DWORD WINAPI | |||
NineBaseTexture9_GetLevelCount( struct NineBaseTexture9 *This ); | |||
HRESULT WINAPI | |||
NineBaseTexture9_SetAutoGenFilterType( struct NineBaseTexture9 *This, | |||
D3DTEXTUREFILTERTYPE FilterType ); | |||
D3DTEXTUREFILTERTYPE WINAPI | |||
NineBaseTexture9_GetAutoGenFilterType( struct NineBaseTexture9 *This ); | |||
void WINAPI | |||
NineBaseTexture9_GenerateMipSubLevels( struct NineBaseTexture9 *This ); | |||
void WINAPI | |||
NineBaseTexture9_PreLoad( struct NineBaseTexture9 *This ); | |||
/* For D3DPOOL_MANAGED only (after SetLOD change): */ | |||
HRESULT | |||
NineBaseTexture9_CreatePipeResource( struct NineBaseTexture9 *This, | |||
BOOL CopyData ); | |||
/* For D3DPOOL_MANAGED only: */ | |||
HRESULT | |||
NineBaseTexture9_UploadSelf( struct NineBaseTexture9 *This ); | |||
HRESULT | |||
NineBaseTexture9_UpdateSamplerView( struct NineBaseTexture9 *This, | |||
const int sRGB ); | |||
static INLINE void | |||
NineBaseTexture9_Validate( struct NineBaseTexture9 *This ) | |||
{ | |||
DBG_FLAG(DBG_BASETEXTURE, "This=%p dirty=%i dirty_mip=%i lod=%u/%u\n", | |||
This, This->dirty, This->dirty_mip, This->lod, This->lod_resident); | |||
if ((This->base.pool == D3DPOOL_MANAGED) && | |||
(This->dirty || This->lod != This->lod_resident)) | |||
NineBaseTexture9_UploadSelf(This); | |||
if (This->dirty_mip) | |||
NineBaseTexture9_GenerateMipSubLevels(This); | |||
} | |||
static INLINE struct pipe_sampler_view * | |||
NineBaseTexture9_GetSamplerView( struct NineBaseTexture9 *This, const int sRGB ) | |||
{ | |||
if (!This->view[sRGB]) | |||
NineBaseTexture9_UpdateSamplerView(This, sRGB); | |||
return This->view[sRGB]; | |||
} | |||
#ifdef DEBUG | |||
void | |||
NineBaseTexture9_Dump( struct NineBaseTexture9 *This ); | |||
#else | |||
static INLINE void | |||
NineBaseTexture9_Dump( struct NineBaseTexture9 *This ) { } | |||
#endif | |||
#define BASETEX_REGISTER_UPDATE(t) do { \ | |||
if (((t)->dirty | ((t)->dirty_mip)) && (t)->base.base.bind) \ | |||
if (LIST_IS_EMPTY(&(t)->list)) \ | |||
list_add(&(t)->list, &(t)->base.base.device->update_textures); \ | |||
} while(0) | |||
#endif /* _NINE_BASETEXTURE9_H_ */ |
@@ -0,0 +1,115 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "cryptosession9.h" | |||
#define DBG_CHANNEL DBG_CRYPTOSESSION | |||
HRESULT WINAPI | |||
NineCryptoSession9_GetCertificateSize( struct NineCryptoSession9 *This, | |||
UINT *pCertificateSize ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineCryptoSession9_GetCertificate( struct NineCryptoSession9 *This, | |||
UINT CertifacteSize, | |||
BYTE *ppCertificate ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineCryptoSession9_NegotiateKeyExchange( struct NineCryptoSession9 *This, | |||
UINT DataSize, | |||
void *pData ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineCryptoSession9_EncryptionBlt( struct NineCryptoSession9 *This, | |||
IDirect3DSurface9 *pSrcSurface, | |||
IDirect3DSurface9 *pDstSurface, | |||
UINT DstSurfaceSize, | |||
void *pIV ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineCryptoSession9_DecryptionBlt( struct NineCryptoSession9 *This, | |||
IDirect3DSurface9 *pSrcSurface, | |||
IDirect3DSurface9 *pDstSurface, | |||
UINT SrcSurfaceSize, | |||
D3DENCRYPTED_BLOCK_INFO *pEncryptedBlockInfo, | |||
void *pContentKey, | |||
void *pIV ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineCryptoSession9_GetSurfacePitch( struct NineCryptoSession9 *This, | |||
IDirect3DSurface9 *pSrcSurface, | |||
UINT *pSurfacePitch ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineCryptoSession9_StartSessionKeyRefresh( struct NineCryptoSession9 *This, | |||
void *pRandomNumber, | |||
UINT RandomNumberSize ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineCryptoSession9_FinishSessionKeyRefresh( struct NineCryptoSession9 *This ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineCryptoSession9_GetEncryptionBltKey( struct NineCryptoSession9 *This, | |||
void *pReadbackKey, | |||
UINT KeySize ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
IDirect3DCryptoSession9Vtbl NineCryptoSession9_vtable = { | |||
(void *)NineUnknown_QueryInterface, | |||
(void *)NineUnknown_AddRef, | |||
(void *)NineUnknown_Release, | |||
(void *)NineCryptoSession9_GetCertificateSize, | |||
(void *)NineCryptoSession9_GetCertificate, | |||
(void *)NineCryptoSession9_NegotiateKeyExchange, | |||
(void *)NineCryptoSession9_EncryptionBlt, | |||
(void *)NineCryptoSession9_DecryptionBlt, | |||
(void *)NineCryptoSession9_GetSurfacePitch, | |||
(void *)NineCryptoSession9_StartSessionKeyRefresh, | |||
(void *)NineCryptoSession9_FinishSessionKeyRefresh, | |||
(void *)NineCryptoSession9_GetEncryptionBltKey | |||
}; |
@@ -0,0 +1,86 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_CRYPTOSESSION9_H_ | |||
#define _NINE_CRYPTOSESSION9_H_ | |||
#include "iunknown.h" | |||
struct NineCryptoSession9 | |||
{ | |||
struct NineUnknown base; | |||
}; | |||
static INLINE struct NineCryptoSession9 * | |||
NineCryptoSession9( void *data ) | |||
{ | |||
return (struct NineCryptoSession9 *)data; | |||
} | |||
HRESULT WINAPI | |||
NineCryptoSession9_GetCertificateSize( struct NineCryptoSession9 *This, | |||
UINT *pCertificateSize ); | |||
HRESULT WINAPI | |||
NineCryptoSession9_GetCertificate( struct NineCryptoSession9 *This, | |||
UINT CertifacteSize, | |||
BYTE *ppCertificate ); | |||
HRESULT WINAPI | |||
NineCryptoSession9_NegotiateKeyExchange( struct NineCryptoSession9 *This, | |||
UINT DataSize, | |||
void *pData ); | |||
HRESULT WINAPI | |||
NineCryptoSession9_EncryptionBlt( struct NineCryptoSession9 *This, | |||
IDirect3DSurface9 *pSrcSurface, | |||
IDirect3DSurface9 *pDstSurface, | |||
UINT DstSurfaceSize, | |||
void *pIV ); | |||
HRESULT WINAPI | |||
NineCryptoSession9_DecryptionBlt( struct NineCryptoSession9 *This, | |||
IDirect3DSurface9 *pSrcSurface, | |||
IDirect3DSurface9 *pDstSurface, | |||
UINT SrcSurfaceSize, | |||
D3DENCRYPTED_BLOCK_INFO *pEncryptedBlockInfo, | |||
void *pContentKey, | |||
void *pIV ); | |||
HRESULT WINAPI | |||
NineCryptoSession9_GetSurfacePitch( struct NineCryptoSession9 *This, | |||
IDirect3DSurface9 *pSrcSurface, | |||
UINT *pSurfacePitch ); | |||
HRESULT WINAPI | |||
NineCryptoSession9_StartSessionKeyRefresh( struct NineCryptoSession9 *This, | |||
void *pRandomNumber, | |||
UINT RandomNumberSize ); | |||
HRESULT WINAPI | |||
NineCryptoSession9_FinishSessionKeyRefresh( struct NineCryptoSession9 *This ); | |||
HRESULT WINAPI | |||
NineCryptoSession9_GetEncryptionBltKey( struct NineCryptoSession9 *This, | |||
void *pReadbackKey, | |||
UINT KeySize ); | |||
#endif /* _NINE_CRYPTOSESSION9_H_ */ |
@@ -0,0 +1,274 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "device9.h" | |||
#include "cubetexture9.h" | |||
#include "nine_helpers.h" | |||
#include "nine_pipe.h" | |||
#define DBG_CHANNEL DBG_CUBETEXTURE | |||
static HRESULT | |||
NineCubeTexture9_ctor( struct NineCubeTexture9 *This, | |||
struct NineUnknownParams *pParams, | |||
UINT EdgeLength, UINT Levels, | |||
DWORD Usage, | |||
D3DFORMAT Format, | |||
D3DPOOL Pool, | |||
HANDLE *pSharedHandle ) | |||
{ | |||
struct pipe_resource *info = &This->base.base.info; | |||
unsigned i; | |||
D3DSURFACE_DESC sfdesc; | |||
HRESULT hr; | |||
user_assert(!(Usage & D3DUSAGE_AUTOGENMIPMAP) || | |||
(Pool != D3DPOOL_SYSTEMMEM && Levels <= 1), D3DERR_INVALIDCALL); | |||
user_assert(!pSharedHandle, D3DERR_INVALIDCALL); /* TODO */ | |||
if (Usage & D3DUSAGE_AUTOGENMIPMAP) | |||
Levels = 0; | |||
This->base.format = Format; | |||
This->base.base.usage = Usage; | |||
info->screen = pParams->device->screen; | |||
info->target = PIPE_TEXTURE_CUBE; | |||
info->format = d3d9_to_pipe_format(Format); | |||
info->width0 = EdgeLength; | |||
info->height0 = EdgeLength; | |||
info->depth0 = 1; | |||
if (Levels) | |||
info->last_level = Levels - 1; | |||
else | |||
info->last_level = util_logbase2(EdgeLength); | |||
info->array_size = 6; | |||
info->nr_samples = 0; | |||
info->bind = PIPE_BIND_SAMPLER_VIEW; | |||
info->usage = PIPE_USAGE_DEFAULT; | |||
info->flags = 0; | |||
if (Usage & D3DUSAGE_RENDERTARGET) | |||
info->bind |= PIPE_BIND_RENDER_TARGET; | |||
if (Usage & D3DUSAGE_DEPTHSTENCIL) | |||
info->bind |= PIPE_BIND_DEPTH_STENCIL; | |||
if (Usage & D3DUSAGE_DYNAMIC) { | |||
info->usage = PIPE_USAGE_DYNAMIC; | |||
info->bind |= | |||
PIPE_BIND_TRANSFER_READ | | |||
PIPE_BIND_TRANSFER_WRITE; | |||
} | |||
This->surfaces = CALLOC(6 * (info->last_level + 1), sizeof(*This->surfaces)); | |||
if (!This->surfaces) | |||
return E_OUTOFMEMORY; | |||
hr = NineBaseTexture9_ctor(&This->base, pParams, D3DRTYPE_CUBETEXTURE, | |||
Pool); | |||
if (FAILED(hr)) | |||
return hr; | |||
This->base.pstype = 2; | |||
/* Create all the surfaces right away. | |||
* They manage backing storage, and transfers (LockRect) are deferred | |||
* to them. | |||
*/ | |||
sfdesc.Format = Format; | |||
sfdesc.Type = D3DRTYPE_SURFACE; | |||
sfdesc.Usage = Usage; | |||
sfdesc.Pool = Pool; | |||
sfdesc.MultiSampleType = D3DMULTISAMPLE_NONE; | |||
sfdesc.MultiSampleQuality = 0; | |||
for (i = 0; i < (info->last_level + 1) * 6; ++i) { | |||
sfdesc.Width = sfdesc.Height = u_minify(EdgeLength, i / 6); | |||
hr = NineSurface9_new(This->base.base.base.device, NineUnknown(This), | |||
This->base.base.resource, D3DRTYPE_CUBETEXTURE, | |||
i / 6, i % 6, | |||
&sfdesc, &This->surfaces[i]); | |||
if (FAILED(hr)) | |||
return hr; | |||
} | |||
for (i = 0; i < 6; ++i) /* width = 0 means empty, depth stays 1 */ | |||
This->dirty_rect[i].depth = 1; | |||
return D3D_OK; | |||
} | |||
static void | |||
NineCubeTexture9_dtor( struct NineCubeTexture9 *This ) | |||
{ | |||
unsigned i; | |||
DBG("This=%p\n", This); | |||
if (This->surfaces) { | |||
for (i = 0; i < This->base.base.info.last_level * 6; ++i) | |||
NineUnknown_Destroy(&This->surfaces[i]->base.base); | |||
FREE(This->surfaces); | |||
} | |||
NineBaseTexture9_dtor(&This->base); | |||
} | |||
HRESULT WINAPI | |||
NineCubeTexture9_GetLevelDesc( struct NineCubeTexture9 *This, | |||
UINT Level, | |||
D3DSURFACE_DESC *pDesc ) | |||
{ | |||
user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL); | |||
user_assert(Level == 0 || !(This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP), | |||
D3DERR_INVALIDCALL); | |||
*pDesc = This->surfaces[Level]->desc; | |||
return D3D_OK; | |||
} | |||
HRESULT WINAPI | |||
NineCubeTexture9_GetCubeMapSurface( struct NineCubeTexture9 *This, | |||
D3DCUBEMAP_FACES FaceType, | |||
UINT Level, | |||
IDirect3DSurface9 **ppCubeMapSurface ) | |||
{ | |||
const unsigned s = Level * 6 + FaceType; | |||
user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL); | |||
user_assert(Level == 0 || !(This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP), | |||
D3DERR_INVALIDCALL); | |||
user_assert(FaceType < 6, D3DERR_INVALIDCALL); | |||
NineUnknown_AddRef(NineUnknown(This->surfaces[s])); | |||
*ppCubeMapSurface = (IDirect3DSurface9 *)This->surfaces[s]; | |||
return D3D_OK; | |||
} | |||
HRESULT WINAPI | |||
NineCubeTexture9_LockRect( struct NineCubeTexture9 *This, | |||
D3DCUBEMAP_FACES FaceType, | |||
UINT Level, | |||
D3DLOCKED_RECT *pLockedRect, | |||
const RECT *pRect, | |||
DWORD Flags ) | |||
{ | |||
const unsigned s = Level * 6 + FaceType; | |||
user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL); | |||
user_assert(Level == 0 || !(This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP), | |||
D3DERR_INVALIDCALL); | |||
user_assert(FaceType < 6, D3DERR_INVALIDCALL); | |||
return NineSurface9_LockRect(This->surfaces[s], pLockedRect, pRect, Flags); | |||
} | |||
HRESULT WINAPI | |||
NineCubeTexture9_UnlockRect( struct NineCubeTexture9 *This, | |||
D3DCUBEMAP_FACES FaceType, | |||
UINT Level ) | |||
{ | |||
const unsigned s = Level * 6 + FaceType; | |||
user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL); | |||
user_assert(FaceType < 6, D3DERR_INVALIDCALL); | |||
return NineSurface9_UnlockRect(This->surfaces[s]); | |||
} | |||
HRESULT WINAPI | |||
NineCubeTexture9_AddDirtyRect( struct NineCubeTexture9 *This, | |||
D3DCUBEMAP_FACES FaceType, | |||
const RECT *pDirtyRect ) | |||
{ | |||
user_assert(FaceType < 6, D3DERR_INVALIDCALL); | |||
if (This->base.base.pool != D3DPOOL_MANAGED) { | |||
if (This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP) | |||
This->base.dirty_mip = TRUE; | |||
return D3D_OK; | |||
} | |||
This->base.dirty = TRUE; | |||
BASETEX_REGISTER_UPDATE(&This->base); | |||
if (!pDirtyRect) { | |||
u_box_origin_2d(This->base.base.info.width0, | |||
This->base.base.info.height0, | |||
&This->dirty_rect[FaceType]); | |||
} else { | |||
struct pipe_box box; | |||
rect_to_pipe_box_clamp(&box, pDirtyRect); | |||
u_box_union_2d(&This->dirty_rect[FaceType], &This->dirty_rect[FaceType], | |||
&box); | |||
} | |||
return D3D_OK; | |||
} | |||
IDirect3DCubeTexture9Vtbl NineCubeTexture9_vtable = { | |||
(void *)NineUnknown_QueryInterface, | |||
(void *)NineUnknown_AddRef, | |||
(void *)NineUnknown_Release, | |||
(void *)NineUnknown_GetDevice, /* actually part of Resource9 iface */ | |||
(void *)NineResource9_SetPrivateData, | |||
(void *)NineResource9_GetPrivateData, | |||
(void *)NineResource9_FreePrivateData, | |||
(void *)NineResource9_SetPriority, | |||
(void *)NineResource9_GetPriority, | |||
(void *)NineBaseTexture9_PreLoad, | |||
(void *)NineResource9_GetType, | |||
(void *)NineBaseTexture9_SetLOD, | |||
(void *)NineBaseTexture9_GetLOD, | |||
(void *)NineBaseTexture9_GetLevelCount, | |||
(void *)NineBaseTexture9_SetAutoGenFilterType, | |||
(void *)NineBaseTexture9_GetAutoGenFilterType, | |||
(void *)NineBaseTexture9_GenerateMipSubLevels, | |||
(void *)NineCubeTexture9_GetLevelDesc, | |||
(void *)NineCubeTexture9_GetCubeMapSurface, | |||
(void *)NineCubeTexture9_LockRect, | |||
(void *)NineCubeTexture9_UnlockRect, | |||
(void *)NineCubeTexture9_AddDirtyRect | |||
}; | |||
static const GUID *NineCubeTexture9_IIDs[] = { | |||
&IID_IDirect3DCubeTexture9, | |||
&IID_IDirect3DBaseTexture9, | |||
&IID_IDirect3DResource9, | |||
&IID_IUnknown, | |||
NULL | |||
}; | |||
HRESULT | |||
NineCubeTexture9_new( struct NineDevice9 *pDevice, | |||
UINT EdgeLength, UINT Levels, | |||
DWORD Usage, | |||
D3DFORMAT Format, | |||
D3DPOOL Pool, | |||
struct NineCubeTexture9 **ppOut, | |||
HANDLE *pSharedHandle ) | |||
{ | |||
NINE_DEVICE_CHILD_NEW(CubeTexture9, ppOut, pDevice, | |||
EdgeLength, Levels, | |||
Usage, Format, Pool, pSharedHandle); | |||
} |
@@ -0,0 +1,79 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_CUBETEXTURE9_H_ | |||
#define _NINE_CUBETEXTURE9_H_ | |||
#include "basetexture9.h" | |||
#include "surface9.h" | |||
struct NineCubeTexture9 | |||
{ | |||
struct NineBaseTexture9 base; | |||
struct NineSurface9 **surfaces; | |||
struct pipe_box dirty_rect[6]; /* covers all mip levels */ | |||
}; | |||
static INLINE struct NineCubeTexture9 * | |||
NineCubeTexture9( void *data ) | |||
{ | |||
return (struct NineCubeTexture9 *)data; | |||
} | |||
HRESULT | |||
NineCubeTexture9_new( struct NineDevice9 *pDevice, | |||
UINT EdgeLength, UINT Levels, | |||
DWORD Usage, | |||
D3DFORMAT Format, | |||
D3DPOOL Pool, | |||
struct NineCubeTexture9 **ppOut, | |||
HANDLE *pSharedHandle ); | |||
HRESULT WINAPI | |||
NineCubeTexture9_GetLevelDesc( struct NineCubeTexture9 *This, | |||
UINT Level, | |||
D3DSURFACE_DESC *pDesc ); | |||
HRESULT WINAPI | |||
NineCubeTexture9_GetCubeMapSurface( struct NineCubeTexture9 *This, | |||
D3DCUBEMAP_FACES FaceType, | |||
UINT Level, | |||
IDirect3DSurface9 **ppCubeMapSurface ); | |||
HRESULT WINAPI | |||
NineCubeTexture9_LockRect( struct NineCubeTexture9 *This, | |||
D3DCUBEMAP_FACES FaceType, | |||
UINT Level, | |||
D3DLOCKED_RECT *pLockedRect, | |||
const RECT *pRect, | |||
DWORD Flags ); | |||
HRESULT WINAPI | |||
NineCubeTexture9_UnlockRect( struct NineCubeTexture9 *This, | |||
D3DCUBEMAP_FACES FaceType, | |||
UINT Level ); | |||
HRESULT WINAPI | |||
NineCubeTexture9_AddDirtyRect( struct NineCubeTexture9 *This, | |||
D3DCUBEMAP_FACES FaceType, | |||
const RECT *pDirtyRect ); | |||
#endif /* _NINE_CUBETEXTURE9_H_ */ |
@@ -0,0 +1,801 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_DEVICE9_H_ | |||
#define _NINE_DEVICE9_H_ | |||
#include "d3dadapter/d3dadapter9.h" | |||
#include "iunknown.h" | |||
#include "adapter9.h" | |||
#include "nine_helpers.h" | |||
#include "nine_state.h" | |||
struct gen_mipmap_state; | |||
struct util_hash_table; | |||
struct pipe_screen; | |||
struct pipe_context; | |||
struct cso_context; | |||
struct hud_context; | |||
struct u_upload_mgr; | |||
struct NineSwapChain9; | |||
struct NineStateBlock9; | |||
#include "util/u_double_list.h" | |||
struct NineDevice9 | |||
{ | |||
struct NineUnknown base; | |||
boolean ex; | |||
D3DDISPLAYMODEEX *pFullscreenDisplayMode; | |||
/* G3D context */ | |||
struct pipe_screen *screen; | |||
struct pipe_context *pipe; | |||
struct cso_context *cso; | |||
/* creation parameters */ | |||
D3DCAPS9 caps; | |||
D3DDEVICE_CREATION_PARAMETERS params; | |||
IDirect3D9 *d3d9; | |||
/* swapchain stuff */ | |||
ID3DPresentGroup *present; | |||
struct NineSwapChain9 **swapchains; | |||
unsigned nswapchains; | |||
struct NineStateBlock9 *record; | |||
struct nine_state *update; /* state to update (&state / &record->state) */ | |||
struct nine_state state; /* device state */ | |||
struct list_head update_textures; | |||
boolean is_recording; | |||
boolean in_scene; | |||
boolean prefer_user_constbuf; | |||
struct pipe_resource *constbuf_vs; | |||
struct pipe_resource *constbuf_ps; | |||
uint16_t max_vs_const_f; | |||
uint16_t max_ps_const_f; | |||
uint32_t vs_bool_true; | |||
uint32_t ps_bool_true; | |||
struct gen_mipmap_state *gen_mipmap; | |||
struct { | |||
struct util_hash_table *ht_vs; | |||
struct util_hash_table *ht_ps; | |||
struct NineVertexShader9 *vs; | |||
struct NinePixelShader9 *ps; | |||
unsigned num_vs; | |||
unsigned num_ps; | |||
float *vs_const; | |||
float *ps_const; | |||
struct util_hash_table *ht_fvf; | |||
} ff; | |||
struct { | |||
struct pipe_resource *image; | |||
unsigned w; | |||
unsigned h; | |||
POINT hotspot; /* -1, -1 if no cursor image set */ | |||
POINT pos; | |||
BOOL visible; | |||
boolean software; | |||
} cursor; | |||
struct { | |||
boolean user_vbufs; | |||
boolean user_ibufs; | |||
boolean window_space_position_support; | |||
} driver_caps; | |||
struct u_upload_mgr *upload; | |||
struct nine_range_pool range_pool; | |||
struct hud_context *hud; /* NULL if hud is disabled */ | |||
}; | |||
static INLINE struct NineDevice9 * | |||
NineDevice9( void *data ) | |||
{ | |||
return (struct NineDevice9 *)data; | |||
} | |||
HRESULT | |||
NineDevice9_new( struct pipe_screen *pScreen, | |||
D3DDEVICE_CREATION_PARAMETERS *pCreationParameters, | |||
D3DCAPS9 *pCaps, | |||
D3DPRESENT_PARAMETERS *pPresentationParameters, | |||
IDirect3D9 *pD3D9, | |||
ID3DPresentGroup *pPresentationGroup, | |||
struct d3dadapter9_context *pCTX, | |||
struct NineDevice9 **ppOut ); | |||
HRESULT | |||
NineDevice9_ctor( struct NineDevice9 *This, | |||
struct NineUnknownParams *pParams, | |||
struct pipe_screen *pScreen, | |||
D3DDEVICE_CREATION_PARAMETERS *pCreationParameters, | |||
D3DCAPS9 *pCaps, | |||
D3DPRESENT_PARAMETERS *pPresentationParameters, | |||
IDirect3D9 *pD3D9, | |||
ID3DPresentGroup *pPresentationGroup, | |||
struct d3dadapter9_context *pCTX ); | |||
void | |||
NineDevice9_dtor( struct NineDevice9 *This ); | |||
/*** Nine private ***/ | |||
struct pipe_screen * | |||
NineDevice9_GetScreen( struct NineDevice9 *This ); | |||
struct pipe_context * | |||
NineDevice9_GetPipe( struct NineDevice9 *This ); | |||
struct cso_context * | |||
NineDevice9_GetCSO( struct NineDevice9 *This ); | |||
const D3DCAPS9 * | |||
NineDevice9_GetCaps( struct NineDevice9 *This ); | |||
/* Mask: 0x1 = constant buffers, 0x2 = stipple */ | |||
void | |||
NineDevice9_RestoreNonCSOState( struct NineDevice9 *This, unsigned mask ); | |||
/*** Direct3D public ***/ | |||
HRESULT WINAPI | |||
NineDevice9_TestCooperativeLevel( struct NineDevice9 *This ); | |||
UINT WINAPI | |||
NineDevice9_GetAvailableTextureMem( struct NineDevice9 *This ); | |||
HRESULT WINAPI | |||
NineDevice9_EvictManagedResources( struct NineDevice9 *This ); | |||
HRESULT WINAPI | |||
NineDevice9_GetDirect3D( struct NineDevice9 *This, | |||
IDirect3D9 **ppD3D9 ); | |||
HRESULT WINAPI | |||
NineDevice9_GetDeviceCaps( struct NineDevice9 *This, | |||
D3DCAPS9 *pCaps ); | |||
HRESULT WINAPI | |||
NineDevice9_GetDisplayMode( struct NineDevice9 *This, | |||
UINT iSwapChain, | |||
D3DDISPLAYMODE *pMode ); | |||
HRESULT WINAPI | |||
NineDevice9_GetCreationParameters( struct NineDevice9 *This, | |||
D3DDEVICE_CREATION_PARAMETERS *pParameters ); | |||
HRESULT WINAPI | |||
NineDevice9_SetCursorProperties( struct NineDevice9 *This, | |||
UINT XHotSpot, | |||
UINT YHotSpot, | |||
IDirect3DSurface9 *pCursorBitmap ); | |||
void WINAPI | |||
NineDevice9_SetCursorPosition( struct NineDevice9 *This, | |||
int X, | |||
int Y, | |||
DWORD Flags ); | |||
BOOL WINAPI | |||
NineDevice9_ShowCursor( struct NineDevice9 *This, | |||
BOOL bShow ); | |||
HRESULT WINAPI | |||
NineDevice9_CreateAdditionalSwapChain( struct NineDevice9 *This, | |||
D3DPRESENT_PARAMETERS *pPresentationParameters, | |||
IDirect3DSwapChain9 **pSwapChain ); | |||
HRESULT WINAPI | |||
NineDevice9_GetSwapChain( struct NineDevice9 *This, | |||
UINT iSwapChain, | |||
IDirect3DSwapChain9 **pSwapChain ); | |||
UINT WINAPI | |||
NineDevice9_GetNumberOfSwapChains( struct NineDevice9 *This ); | |||
HRESULT WINAPI | |||
NineDevice9_Reset( struct NineDevice9 *This, | |||
D3DPRESENT_PARAMETERS *pPresentationParameters ); | |||
HRESULT WINAPI | |||
NineDevice9_Present( struct NineDevice9 *This, | |||
const RECT *pSourceRect, | |||
const RECT *pDestRect, | |||
HWND hDestWindowOverride, | |||
const RGNDATA *pDirtyRegion ); | |||
HRESULT WINAPI | |||
NineDevice9_GetBackBuffer( struct NineDevice9 *This, | |||
UINT iSwapChain, | |||
UINT iBackBuffer, | |||
D3DBACKBUFFER_TYPE Type, | |||
IDirect3DSurface9 **ppBackBuffer ); | |||
HRESULT WINAPI | |||
NineDevice9_GetRasterStatus( struct NineDevice9 *This, | |||
UINT iSwapChain, | |||
D3DRASTER_STATUS *pRasterStatus ); | |||
HRESULT WINAPI | |||
NineDevice9_SetDialogBoxMode( struct NineDevice9 *This, | |||
BOOL bEnableDialogs ); | |||
void WINAPI | |||
NineDevice9_SetGammaRamp( struct NineDevice9 *This, | |||
UINT iSwapChain, | |||
DWORD Flags, | |||
const D3DGAMMARAMP *pRamp ); | |||
void WINAPI | |||
NineDevice9_GetGammaRamp( struct NineDevice9 *This, | |||
UINT iSwapChain, | |||
D3DGAMMARAMP *pRamp ); | |||
HRESULT WINAPI | |||
NineDevice9_CreateTexture( struct NineDevice9 *This, | |||
UINT Width, | |||
UINT Height, | |||
UINT Levels, | |||
DWORD Usage, | |||
D3DFORMAT Format, | |||
D3DPOOL Pool, | |||
IDirect3DTexture9 **ppTexture, | |||
HANDLE *pSharedHandle ); | |||
HRESULT WINAPI | |||
NineDevice9_CreateVolumeTexture( struct NineDevice9 *This, | |||
UINT Width, | |||
UINT Height, | |||
UINT Depth, | |||
UINT Levels, | |||
DWORD Usage, | |||
D3DFORMAT Format, | |||
D3DPOOL Pool, | |||
IDirect3DVolumeTexture9 **ppVolumeTexture, | |||
HANDLE *pSharedHandle ); | |||
HRESULT WINAPI | |||
NineDevice9_CreateCubeTexture( struct NineDevice9 *This, | |||
UINT EdgeLength, | |||
UINT Levels, | |||
DWORD Usage, | |||
D3DFORMAT Format, | |||
D3DPOOL Pool, | |||
IDirect3DCubeTexture9 **ppCubeTexture, | |||
HANDLE *pSharedHandle ); | |||
HRESULT WINAPI | |||
NineDevice9_CreateVertexBuffer( struct NineDevice9 *This, | |||
UINT Length, | |||
DWORD Usage, | |||
DWORD FVF, | |||
D3DPOOL Pool, | |||
IDirect3DVertexBuffer9 **ppVertexBuffer, | |||
HANDLE *pSharedHandle ); | |||
HRESULT WINAPI | |||
NineDevice9_CreateIndexBuffer( struct NineDevice9 *This, | |||
UINT Length, | |||
DWORD Usage, | |||
D3DFORMAT Format, | |||
D3DPOOL Pool, | |||
IDirect3DIndexBuffer9 **ppIndexBuffer, | |||
HANDLE *pSharedHandle ); | |||
HRESULT WINAPI | |||
NineDevice9_CreateRenderTarget( struct NineDevice9 *This, | |||
UINT Width, | |||
UINT Height, | |||
D3DFORMAT Format, | |||
D3DMULTISAMPLE_TYPE MultiSample, | |||
DWORD MultisampleQuality, | |||
BOOL Lockable, | |||
IDirect3DSurface9 **ppSurface, | |||
HANDLE *pSharedHandle ); | |||
HRESULT WINAPI | |||
NineDevice9_CreateDepthStencilSurface( struct NineDevice9 *This, | |||
UINT Width, | |||
UINT Height, | |||
D3DFORMAT Format, | |||
D3DMULTISAMPLE_TYPE MultiSample, | |||
DWORD MultisampleQuality, | |||
BOOL Discard, | |||
IDirect3DSurface9 **ppSurface, | |||
HANDLE *pSharedHandle ); | |||
HRESULT WINAPI | |||
NineDevice9_UpdateSurface( struct NineDevice9 *This, | |||
IDirect3DSurface9 *pSourceSurface, | |||
const RECT *pSourceRect, | |||
IDirect3DSurface9 *pDestinationSurface, | |||
const POINT *pDestPoint ); | |||
HRESULT WINAPI | |||
NineDevice9_UpdateTexture( struct NineDevice9 *This, | |||
IDirect3DBaseTexture9 *pSourceTexture, | |||
IDirect3DBaseTexture9 *pDestinationTexture ); | |||
HRESULT WINAPI | |||
NineDevice9_GetRenderTargetData( struct NineDevice9 *This, | |||
IDirect3DSurface9 *pRenderTarget, | |||
IDirect3DSurface9 *pDestSurface ); | |||
HRESULT WINAPI | |||
NineDevice9_GetFrontBufferData( struct NineDevice9 *This, | |||
UINT iSwapChain, | |||
IDirect3DSurface9 *pDestSurface ); | |||
HRESULT WINAPI | |||
NineDevice9_StretchRect( struct NineDevice9 *This, | |||
IDirect3DSurface9 *pSourceSurface, | |||
const RECT *pSourceRect, | |||
IDirect3DSurface9 *pDestSurface, | |||
const RECT *pDestRect, | |||
D3DTEXTUREFILTERTYPE Filter ); | |||
HRESULT WINAPI | |||
NineDevice9_ColorFill( struct NineDevice9 *This, | |||
IDirect3DSurface9 *pSurface, | |||
const RECT *pRect, | |||
D3DCOLOR color ); | |||
HRESULT WINAPI | |||
NineDevice9_CreateOffscreenPlainSurface( struct NineDevice9 *This, | |||
UINT Width, | |||
UINT Height, | |||
D3DFORMAT Format, | |||
D3DPOOL Pool, | |||
IDirect3DSurface9 **ppSurface, | |||
HANDLE *pSharedHandle ); | |||
HRESULT WINAPI | |||
NineDevice9_SetRenderTarget( struct NineDevice9 *This, | |||
DWORD RenderTargetIndex, | |||
IDirect3DSurface9 *pRenderTarget ); | |||
HRESULT WINAPI | |||
NineDevice9_GetRenderTarget( struct NineDevice9 *This, | |||
DWORD RenderTargetIndex, | |||
IDirect3DSurface9 **ppRenderTarget ); | |||
HRESULT WINAPI | |||
NineDevice9_SetDepthStencilSurface( struct NineDevice9 *This, | |||
IDirect3DSurface9 *pNewZStencil ); | |||
HRESULT WINAPI | |||
NineDevice9_GetDepthStencilSurface( struct NineDevice9 *This, | |||
IDirect3DSurface9 **ppZStencilSurface ); | |||
HRESULT WINAPI | |||
NineDevice9_BeginScene( struct NineDevice9 *This ); | |||
HRESULT WINAPI | |||
NineDevice9_EndScene( struct NineDevice9 *This ); | |||
HRESULT WINAPI | |||
NineDevice9_Clear( struct NineDevice9 *This, | |||
DWORD Count, | |||
const D3DRECT *pRects, | |||
DWORD Flags, | |||
D3DCOLOR Color, | |||
float Z, | |||
DWORD Stencil ); | |||
HRESULT WINAPI | |||
NineDevice9_SetTransform( struct NineDevice9 *This, | |||
D3DTRANSFORMSTATETYPE State, | |||
const D3DMATRIX *pMatrix ); | |||
HRESULT WINAPI | |||
NineDevice9_GetTransform( struct NineDevice9 *This, | |||
D3DTRANSFORMSTATETYPE State, | |||
D3DMATRIX *pMatrix ); | |||
HRESULT WINAPI | |||
NineDevice9_MultiplyTransform( struct NineDevice9 *This, | |||
D3DTRANSFORMSTATETYPE State, | |||
const D3DMATRIX *pMatrix ); | |||
HRESULT WINAPI | |||
NineDevice9_SetViewport( struct NineDevice9 *This, | |||
const D3DVIEWPORT9 *pViewport ); | |||
HRESULT WINAPI | |||
NineDevice9_GetViewport( struct NineDevice9 *This, | |||
D3DVIEWPORT9 *pViewport ); | |||
HRESULT WINAPI | |||
NineDevice9_SetMaterial( struct NineDevice9 *This, | |||
const D3DMATERIAL9 *pMaterial ); | |||
HRESULT WINAPI | |||
NineDevice9_GetMaterial( struct NineDevice9 *This, | |||
D3DMATERIAL9 *pMaterial ); | |||
HRESULT WINAPI | |||
NineDevice9_SetLight( struct NineDevice9 *This, | |||
DWORD Index, | |||
const D3DLIGHT9 *pLight ); | |||
HRESULT WINAPI | |||
NineDevice9_GetLight( struct NineDevice9 *This, | |||
DWORD Index, | |||
D3DLIGHT9 *pLight ); | |||
HRESULT WINAPI | |||
NineDevice9_LightEnable( struct NineDevice9 *This, | |||
DWORD Index, | |||
BOOL Enable ); | |||
HRESULT WINAPI | |||
NineDevice9_GetLightEnable( struct NineDevice9 *This, | |||
DWORD Index, | |||
BOOL *pEnable ); | |||
HRESULT WINAPI | |||
NineDevice9_SetClipPlane( struct NineDevice9 *This, | |||
DWORD Index, | |||
const float *pPlane ); | |||
HRESULT WINAPI | |||
NineDevice9_GetClipPlane( struct NineDevice9 *This, | |||
DWORD Index, | |||
float *pPlane ); | |||
HRESULT WINAPI | |||
NineDevice9_SetRenderState( struct NineDevice9 *This, | |||
D3DRENDERSTATETYPE State, | |||
DWORD Value ); | |||
HRESULT WINAPI | |||
NineDevice9_GetRenderState( struct NineDevice9 *This, | |||
D3DRENDERSTATETYPE State, | |||
DWORD *pValue ); | |||
HRESULT WINAPI | |||
NineDevice9_CreateStateBlock( struct NineDevice9 *This, | |||
D3DSTATEBLOCKTYPE Type, | |||
IDirect3DStateBlock9 **ppSB ); | |||
HRESULT WINAPI | |||
NineDevice9_BeginStateBlock( struct NineDevice9 *This ); | |||
HRESULT WINAPI | |||
NineDevice9_EndStateBlock( struct NineDevice9 *This, | |||
IDirect3DStateBlock9 **ppSB ); | |||
HRESULT WINAPI | |||
NineDevice9_SetClipStatus( struct NineDevice9 *This, | |||
const D3DCLIPSTATUS9 *pClipStatus ); | |||
HRESULT WINAPI | |||
NineDevice9_GetClipStatus( struct NineDevice9 *This, | |||
D3DCLIPSTATUS9 *pClipStatus ); | |||
HRESULT WINAPI | |||
NineDevice9_GetTexture( struct NineDevice9 *This, | |||
DWORD Stage, | |||
IDirect3DBaseTexture9 **ppTexture ); | |||
HRESULT WINAPI | |||
NineDevice9_SetTexture( struct NineDevice9 *This, | |||
DWORD Stage, | |||
IDirect3DBaseTexture9 *pTexture ); | |||
HRESULT WINAPI | |||
NineDevice9_GetTextureStageState( struct NineDevice9 *This, | |||
DWORD Stage, | |||
D3DTEXTURESTAGESTATETYPE Type, | |||
DWORD *pValue ); | |||
HRESULT WINAPI | |||
NineDevice9_SetTextureStageState( struct NineDevice9 *This, | |||
DWORD Stage, | |||
D3DTEXTURESTAGESTATETYPE Type, | |||
DWORD Value ); | |||
HRESULT WINAPI | |||
NineDevice9_GetSamplerState( struct NineDevice9 *This, | |||
DWORD Sampler, | |||
D3DSAMPLERSTATETYPE Type, | |||
DWORD *pValue ); | |||
HRESULT WINAPI | |||
NineDevice9_SetSamplerState( struct NineDevice9 *This, | |||
DWORD Sampler, | |||
D3DSAMPLERSTATETYPE Type, | |||
DWORD Value ); | |||
HRESULT WINAPI | |||
NineDevice9_ValidateDevice( struct NineDevice9 *This, | |||
DWORD *pNumPasses ); | |||
HRESULT WINAPI | |||
NineDevice9_SetPaletteEntries( struct NineDevice9 *This, | |||
UINT PaletteNumber, | |||
const PALETTEENTRY *pEntries ); | |||
HRESULT WINAPI | |||
NineDevice9_GetPaletteEntries( struct NineDevice9 *This, | |||
UINT PaletteNumber, | |||
PALETTEENTRY *pEntries ); | |||
HRESULT WINAPI | |||
NineDevice9_SetCurrentTexturePalette( struct NineDevice9 *This, | |||
UINT PaletteNumber ); | |||
HRESULT WINAPI | |||
NineDevice9_GetCurrentTexturePalette( struct NineDevice9 *This, | |||
UINT *PaletteNumber ); | |||
HRESULT WINAPI | |||
NineDevice9_SetScissorRect( struct NineDevice9 *This, | |||
const RECT *pRect ); | |||
HRESULT WINAPI | |||
NineDevice9_GetScissorRect( struct NineDevice9 *This, | |||
RECT *pRect ); | |||
HRESULT WINAPI | |||
NineDevice9_SetSoftwareVertexProcessing( struct NineDevice9 *This, | |||
BOOL bSoftware ); | |||
BOOL WINAPI | |||
NineDevice9_GetSoftwareVertexProcessing( struct NineDevice9 *This ); | |||
HRESULT WINAPI | |||
NineDevice9_SetNPatchMode( struct NineDevice9 *This, | |||
float nSegments ); | |||
float WINAPI | |||
NineDevice9_GetNPatchMode( struct NineDevice9 *This ); | |||
HRESULT WINAPI | |||
NineDevice9_DrawPrimitive( struct NineDevice9 *This, | |||
D3DPRIMITIVETYPE PrimitiveType, | |||
UINT StartVertex, | |||
UINT PrimitiveCount ); | |||
HRESULT WINAPI | |||
NineDevice9_DrawIndexedPrimitive( struct NineDevice9 *This, | |||
D3DPRIMITIVETYPE PrimitiveType, | |||
INT BaseVertexIndex, | |||
UINT MinVertexIndex, | |||
UINT NumVertices, | |||
UINT startIndex, | |||
UINT primCount ); | |||
HRESULT WINAPI | |||
NineDevice9_DrawPrimitiveUP( struct NineDevice9 *This, | |||
D3DPRIMITIVETYPE PrimitiveType, | |||
UINT PrimitiveCount, | |||
const void *pVertexStreamZeroData, | |||
UINT VertexStreamZeroStride ); | |||
HRESULT WINAPI | |||
NineDevice9_DrawIndexedPrimitiveUP( struct NineDevice9 *This, | |||
D3DPRIMITIVETYPE PrimitiveType, | |||
UINT MinVertexIndex, | |||
UINT NumVertices, | |||
UINT PrimitiveCount, | |||
const void *pIndexData, | |||
D3DFORMAT IndexDataFormat, | |||
const void *pVertexStreamZeroData, | |||
UINT VertexStreamZeroStride ); | |||
HRESULT WINAPI | |||
NineDevice9_ProcessVertices( struct NineDevice9 *This, | |||
UINT SrcStartIndex, | |||
UINT DestIndex, | |||
UINT VertexCount, | |||
IDirect3DVertexBuffer9 *pDestBuffer, | |||
IDirect3DVertexDeclaration9 *pVertexDecl, | |||
DWORD Flags ); | |||
HRESULT WINAPI | |||
NineDevice9_CreateVertexDeclaration( struct NineDevice9 *This, | |||
const D3DVERTEXELEMENT9 *pVertexElements, | |||
IDirect3DVertexDeclaration9 **ppDecl ); | |||
HRESULT WINAPI | |||
NineDevice9_SetVertexDeclaration( struct NineDevice9 *This, | |||
IDirect3DVertexDeclaration9 *pDecl ); | |||
HRESULT WINAPI | |||
NineDevice9_GetVertexDeclaration( struct NineDevice9 *This, | |||
IDirect3DVertexDeclaration9 **ppDecl ); | |||
HRESULT WINAPI | |||
NineDevice9_SetFVF( struct NineDevice9 *This, | |||
DWORD FVF ); | |||
HRESULT WINAPI | |||
NineDevice9_GetFVF( struct NineDevice9 *This, | |||
DWORD *pFVF ); | |||
HRESULT WINAPI | |||
NineDevice9_CreateVertexShader( struct NineDevice9 *This, | |||
const DWORD *pFunction, | |||
IDirect3DVertexShader9 **ppShader ); | |||
HRESULT WINAPI | |||
NineDevice9_SetVertexShader( struct NineDevice9 *This, | |||
IDirect3DVertexShader9 *pShader ); | |||
HRESULT WINAPI | |||
NineDevice9_GetVertexShader( struct NineDevice9 *This, | |||
IDirect3DVertexShader9 **ppShader ); | |||
HRESULT WINAPI | |||
NineDevice9_SetVertexShaderConstantF( struct NineDevice9 *This, | |||
UINT StartRegister, | |||
const float *pConstantData, | |||
UINT Vector4fCount ); | |||
HRESULT WINAPI | |||
NineDevice9_GetVertexShaderConstantF( struct NineDevice9 *This, | |||
UINT StartRegister, | |||
float *pConstantData, | |||
UINT Vector4fCount ); | |||
HRESULT WINAPI | |||
NineDevice9_SetVertexShaderConstantI( struct NineDevice9 *This, | |||
UINT StartRegister, | |||
const int *pConstantData, | |||
UINT Vector4iCount ); | |||
HRESULT WINAPI | |||
NineDevice9_GetVertexShaderConstantI( struct NineDevice9 *This, | |||
UINT StartRegister, | |||
int *pConstantData, | |||
UINT Vector4iCount ); | |||
HRESULT WINAPI | |||
NineDevice9_SetVertexShaderConstantB( struct NineDevice9 *This, | |||
UINT StartRegister, | |||
const BOOL *pConstantData, | |||
UINT BoolCount ); | |||
HRESULT WINAPI | |||
NineDevice9_GetVertexShaderConstantB( struct NineDevice9 *This, | |||
UINT StartRegister, | |||
BOOL *pConstantData, | |||
UINT BoolCount ); | |||
HRESULT WINAPI | |||
NineDevice9_SetStreamSource( struct NineDevice9 *This, | |||
UINT StreamNumber, | |||
IDirect3DVertexBuffer9 *pStreamData, | |||
UINT OffsetInBytes, | |||
UINT Stride ); | |||
HRESULT WINAPI | |||
NineDevice9_GetStreamSource( struct NineDevice9 *This, | |||
UINT StreamNumber, | |||
IDirect3DVertexBuffer9 **ppStreamData, | |||
UINT *pOffsetInBytes, | |||
UINT *pStride ); | |||
HRESULT WINAPI | |||
NineDevice9_SetStreamSourceFreq( struct NineDevice9 *This, | |||
UINT StreamNumber, | |||
UINT Setting ); | |||
HRESULT WINAPI | |||
NineDevice9_GetStreamSourceFreq( struct NineDevice9 *This, | |||
UINT StreamNumber, | |||
UINT *pSetting ); | |||
HRESULT WINAPI | |||
NineDevice9_SetIndices( struct NineDevice9 *This, | |||
IDirect3DIndexBuffer9 *pIndexData ); | |||
HRESULT WINAPI | |||
NineDevice9_GetIndices( struct NineDevice9 *This, | |||
IDirect3DIndexBuffer9 **ppIndexData /*, | |||
UINT *pBaseVertexIndex */ ); | |||
HRESULT WINAPI | |||
NineDevice9_CreatePixelShader( struct NineDevice9 *This, | |||
const DWORD *pFunction, | |||
IDirect3DPixelShader9 **ppShader ); | |||
HRESULT WINAPI | |||
NineDevice9_SetPixelShader( struct NineDevice9 *This, | |||
IDirect3DPixelShader9 *pShader ); | |||
HRESULT WINAPI | |||
NineDevice9_GetPixelShader( struct NineDevice9 *This, | |||
IDirect3DPixelShader9 **ppShader ); | |||
HRESULT WINAPI | |||
NineDevice9_SetPixelShaderConstantF( struct NineDevice9 *This, | |||
UINT StartRegister, | |||
const float *pConstantData, | |||
UINT Vector4fCount ); | |||
HRESULT WINAPI | |||
NineDevice9_GetPixelShaderConstantF( struct NineDevice9 *This, | |||
UINT StartRegister, | |||
float *pConstantData, | |||
UINT Vector4fCount ); | |||
HRESULT WINAPI | |||
NineDevice9_SetPixelShaderConstantI( struct NineDevice9 *This, | |||
UINT StartRegister, | |||
const int *pConstantData, | |||
UINT Vector4iCount ); | |||
HRESULT WINAPI | |||
NineDevice9_GetPixelShaderConstantI( struct NineDevice9 *This, | |||
UINT StartRegister, | |||
int *pConstantData, | |||
UINT Vector4iCount ); | |||
HRESULT WINAPI | |||
NineDevice9_SetPixelShaderConstantB( struct NineDevice9 *This, | |||
UINT StartRegister, | |||
const BOOL *pConstantData, | |||
UINT BoolCount ); | |||
HRESULT WINAPI | |||
NineDevice9_GetPixelShaderConstantB( struct NineDevice9 *This, | |||
UINT StartRegister, | |||
BOOL *pConstantData, | |||
UINT BoolCount ); | |||
HRESULT WINAPI | |||
NineDevice9_DrawRectPatch( struct NineDevice9 *This, | |||
UINT Handle, | |||
const float *pNumSegs, | |||
const D3DRECTPATCH_INFO *pRectPatchInfo ); | |||
HRESULT WINAPI | |||
NineDevice9_DrawTriPatch( struct NineDevice9 *This, | |||
UINT Handle, | |||
const float *pNumSegs, | |||
const D3DTRIPATCH_INFO *pTriPatchInfo ); | |||
HRESULT WINAPI | |||
NineDevice9_DeletePatch( struct NineDevice9 *This, | |||
UINT Handle ); | |||
HRESULT WINAPI | |||
NineDevice9_CreateQuery( struct NineDevice9 *This, | |||
D3DQUERYTYPE Type, | |||
IDirect3DQuery9 **ppQuery ); | |||
#endif /* _NINE_DEVICE9_H_ */ |
@@ -0,0 +1,400 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "device9ex.h" | |||
#include "swapchain9ex.h" | |||
#include "nine_helpers.h" | |||
#define DBG_CHANNEL DBG_DEVICE | |||
static HRESULT | |||
NineDevice9Ex_ctor( struct NineDevice9Ex *This, | |||
struct NineUnknownParams *pParams, | |||
struct pipe_screen *pScreen, | |||
D3DDEVICE_CREATION_PARAMETERS *pCreationParameters, | |||
D3DCAPS9 *pCaps, | |||
D3DPRESENT_PARAMETERS *pPresentationParameters, | |||
D3DDISPLAYMODEEX *pFullscreenDisplayMode, | |||
IDirect3D9Ex *pD3D9Ex, | |||
ID3DPresentGroup *pPresentationGroup, | |||
struct d3dadapter9_context *pCTX ) | |||
{ | |||
This->base.ex = TRUE; | |||
This->base.pFullscreenDisplayMode = pFullscreenDisplayMode; | |||
return NineDevice9_ctor(&This->base, pParams, | |||
pScreen, pCreationParameters, pCaps, | |||
pPresentationParameters, | |||
(IDirect3D9 *)pD3D9Ex, pPresentationGroup, pCTX); | |||
} | |||
static void | |||
NineDevice9Ex_dtor( struct NineDevice9Ex *This ) | |||
{ | |||
NineDevice9_dtor(&This->base); | |||
} | |||
HRESULT WINAPI | |||
NineDevice9Ex_SetConvolutionMonoKernel( struct NineDevice9Ex *This, | |||
UINT width, | |||
UINT height, | |||
float *rows, | |||
float *columns ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineDevice9Ex_ComposeRects( struct NineDevice9Ex *This, | |||
IDirect3DSurface9 *pSrc, | |||
IDirect3DSurface9 *pDst, | |||
IDirect3DVertexBuffer9 *pSrcRectDescs, | |||
UINT NumRects, | |||
IDirect3DVertexBuffer9 *pDstRectDescs, | |||
D3DCOMPOSERECTSOP Operation, | |||
int Xoffset, | |||
int Yoffset ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineDevice9Ex_PresentEx( struct NineDevice9Ex *This, | |||
const RECT *pSourceRect, | |||
const RECT *pDestRect, | |||
HWND hDestWindowOverride, | |||
const RGNDATA *pDirtyRegion, | |||
DWORD dwFlags ) | |||
{ | |||
unsigned i; | |||
HRESULT hr; | |||
for (i = 0; i < This->base.nswapchains; i++) { | |||
hr = NineSwapChain9_Present(This->base.swapchains[i], pSourceRect, pDestRect, | |||
hDestWindowOverride, pDirtyRegion, dwFlags); | |||
if (FAILED(hr)) { return hr; } | |||
} | |||
return D3D_OK; | |||
} | |||
HRESULT WINAPI | |||
NineDevice9Ex_GetGPUThreadPriority( struct NineDevice9Ex *This, | |||
INT *pPriority ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineDevice9Ex_SetGPUThreadPriority( struct NineDevice9Ex *This, | |||
INT Priority ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineDevice9Ex_WaitForVBlank( struct NineDevice9Ex *This, | |||
UINT iSwapChain ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineDevice9Ex_CheckResourceResidency( struct NineDevice9Ex *This, | |||
IDirect3DResource9 **pResourceArray, | |||
UINT32 NumResources ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineDevice9Ex_SetMaximumFrameLatency( struct NineDevice9Ex *This, | |||
UINT MaxLatency ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineDevice9Ex_GetMaximumFrameLatency( struct NineDevice9Ex *This, | |||
UINT *pMaxLatency ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineDevice9Ex_CheckDeviceState( struct NineDevice9Ex *This, | |||
HWND hDestinationWindow ) | |||
{ | |||
DBG("This=%p hDestinationWindow=%p\n", | |||
This, hDestinationWindow); | |||
/* TODO: handle the other return values */ | |||
return D3D_OK; | |||
} | |||
HRESULT WINAPI | |||
NineDevice9Ex_CreateRenderTargetEx( struct NineDevice9Ex *This, | |||
UINT Width, | |||
UINT Height, | |||
D3DFORMAT Format, | |||
D3DMULTISAMPLE_TYPE MultiSample, | |||
DWORD MultisampleQuality, | |||
BOOL Lockable, | |||
IDirect3DSurface9 **ppSurface, | |||
HANDLE *pSharedHandle, | |||
DWORD Usage ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineDevice9Ex_CreateOffscreenPlainSurfaceEx( struct NineDevice9Ex *This, | |||
UINT Width, | |||
UINT Height, | |||
D3DFORMAT Format, | |||
D3DPOOL Pool, | |||
IDirect3DSurface9 **ppSurface, | |||
HANDLE *pSharedHandle, | |||
DWORD Usage ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineDevice9Ex_CreateDepthStencilSurfaceEx( struct NineDevice9Ex *This, | |||
UINT Width, | |||
UINT Height, | |||
D3DFORMAT Format, | |||
D3DMULTISAMPLE_TYPE MultiSample, | |||
DWORD MultisampleQuality, | |||
BOOL Discard, | |||
IDirect3DSurface9 **ppSurface, | |||
HANDLE *pSharedHandle, | |||
DWORD Usage ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineDevice9Ex_ResetEx( struct NineDevice9Ex *This, | |||
D3DPRESENT_PARAMETERS *pPresentationParameters, | |||
D3DDISPLAYMODEEX *pFullscreenDisplayMode ) | |||
{ | |||
HRESULT hr = D3D_OK; | |||
unsigned i; | |||
DBG("This=%p pPresentationParameters=%p pFullscreenDisplayMode=%p\n", This, pPresentationParameters, pFullscreenDisplayMode); | |||
for (i = 0; i < This->base.nswapchains; ++i) { | |||
D3DDISPLAYMODEEX *mode = NULL; | |||
D3DPRESENT_PARAMETERS *params = &pPresentationParameters[i]; | |||
if (pFullscreenDisplayMode) mode = &(pFullscreenDisplayMode[i]); | |||
hr = NineSwapChain9_Resize(This->base.swapchains[i], params, mode); | |||
if (FAILED(hr)) | |||
return (hr == D3DERR_OUTOFVIDEOMEMORY) ? hr : D3DERR_DEVICELOST; | |||
} | |||
NineDevice9_SetRenderTarget( | |||
(struct NineDevice9 *)This, 0, (IDirect3DSurface9 *)This->base.swapchains[0]->buffers[0]); | |||
return hr; | |||
} | |||
HRESULT WINAPI | |||
NineDevice9Ex_GetDisplayModeEx( struct NineDevice9Ex *This, | |||
UINT iSwapChain, | |||
D3DDISPLAYMODEEX *pMode, | |||
D3DDISPLAYROTATION *pRotation ) | |||
{ | |||
struct NineSwapChain9Ex *swapchain; | |||
user_assert(iSwapChain < This->base.nswapchains, D3DERR_INVALIDCALL); | |||
swapchain = NineSwapChain9Ex(This->base.swapchains[iSwapChain]); | |||
return NineSwapChain9Ex_GetDisplayModeEx(swapchain, pMode, pRotation); | |||
} | |||
IDirect3DDevice9ExVtbl NineDevice9Ex_vtable = { | |||
(void *)NineUnknown_QueryInterface, | |||
(void *)NineUnknown_AddRef, | |||
(void *)NineUnknown_Release, | |||
(void *)NineDevice9_TestCooperativeLevel, | |||
(void *)NineDevice9_GetAvailableTextureMem, | |||
(void *)NineDevice9_EvictManagedResources, | |||
(void *)NineDevice9_GetDirect3D, | |||
(void *)NineDevice9_GetDeviceCaps, | |||
(void *)NineDevice9_GetDisplayMode, | |||
(void *)NineDevice9_GetCreationParameters, | |||
(void *)NineDevice9_SetCursorProperties, | |||
(void *)NineDevice9_SetCursorPosition, | |||
(void *)NineDevice9_ShowCursor, | |||
(void *)NineDevice9_CreateAdditionalSwapChain, | |||
(void *)NineDevice9_GetSwapChain, | |||
(void *)NineDevice9_GetNumberOfSwapChains, | |||
(void *)NineDevice9_Reset, | |||
(void *)NineDevice9_Present, | |||
(void *)NineDevice9_GetBackBuffer, | |||
(void *)NineDevice9_GetRasterStatus, | |||
(void *)NineDevice9_SetDialogBoxMode, | |||
(void *)NineDevice9_SetGammaRamp, | |||
(void *)NineDevice9_GetGammaRamp, | |||
(void *)NineDevice9_CreateTexture, | |||
(void *)NineDevice9_CreateVolumeTexture, | |||
(void *)NineDevice9_CreateCubeTexture, | |||
(void *)NineDevice9_CreateVertexBuffer, | |||
(void *)NineDevice9_CreateIndexBuffer, | |||
(void *)NineDevice9_CreateRenderTarget, | |||
(void *)NineDevice9_CreateDepthStencilSurface, | |||
(void *)NineDevice9_UpdateSurface, | |||
(void *)NineDevice9_UpdateTexture, | |||
(void *)NineDevice9_GetRenderTargetData, | |||
(void *)NineDevice9_GetFrontBufferData, | |||
(void *)NineDevice9_StretchRect, | |||
(void *)NineDevice9_ColorFill, | |||
(void *)NineDevice9_CreateOffscreenPlainSurface, | |||
(void *)NineDevice9_SetRenderTarget, | |||
(void *)NineDevice9_GetRenderTarget, | |||
(void *)NineDevice9_SetDepthStencilSurface, | |||
(void *)NineDevice9_GetDepthStencilSurface, | |||
(void *)NineDevice9_BeginScene, | |||
(void *)NineDevice9_EndScene, | |||
(void *)NineDevice9_Clear, | |||
(void *)NineDevice9_SetTransform, | |||
(void *)NineDevice9_GetTransform, | |||
(void *)NineDevice9_MultiplyTransform, | |||
(void *)NineDevice9_SetViewport, | |||
(void *)NineDevice9_GetViewport, | |||
(void *)NineDevice9_SetMaterial, | |||
(void *)NineDevice9_GetMaterial, | |||
(void *)NineDevice9_SetLight, | |||
(void *)NineDevice9_GetLight, | |||
(void *)NineDevice9_LightEnable, | |||
(void *)NineDevice9_GetLightEnable, | |||
(void *)NineDevice9_SetClipPlane, | |||
(void *)NineDevice9_GetClipPlane, | |||
(void *)NineDevice9_SetRenderState, | |||
(void *)NineDevice9_GetRenderState, | |||
(void *)NineDevice9_CreateStateBlock, | |||
(void *)NineDevice9_BeginStateBlock, | |||
(void *)NineDevice9_EndStateBlock, | |||
(void *)NineDevice9_SetClipStatus, | |||
(void *)NineDevice9_GetClipStatus, | |||
(void *)NineDevice9_GetTexture, | |||
(void *)NineDevice9_SetTexture, | |||
(void *)NineDevice9_GetTextureStageState, | |||
(void *)NineDevice9_SetTextureStageState, | |||
(void *)NineDevice9_GetSamplerState, | |||
(void *)NineDevice9_SetSamplerState, | |||
(void *)NineDevice9_ValidateDevice, | |||
(void *)NineDevice9_SetPaletteEntries, | |||
(void *)NineDevice9_GetPaletteEntries, | |||
(void *)NineDevice9_SetCurrentTexturePalette, | |||
(void *)NineDevice9_GetCurrentTexturePalette, | |||
(void *)NineDevice9_SetScissorRect, | |||
(void *)NineDevice9_GetScissorRect, | |||
(void *)NineDevice9_SetSoftwareVertexProcessing, | |||
(void *)NineDevice9_GetSoftwareVertexProcessing, | |||
(void *)NineDevice9_SetNPatchMode, | |||
(void *)NineDevice9_GetNPatchMode, | |||
(void *)NineDevice9_DrawPrimitive, | |||
(void *)NineDevice9_DrawIndexedPrimitive, | |||
(void *)NineDevice9_DrawPrimitiveUP, | |||
(void *)NineDevice9_DrawIndexedPrimitiveUP, | |||
(void *)NineDevice9_ProcessVertices, | |||
(void *)NineDevice9_CreateVertexDeclaration, | |||
(void *)NineDevice9_SetVertexDeclaration, | |||
(void *)NineDevice9_GetVertexDeclaration, | |||
(void *)NineDevice9_SetFVF, | |||
(void *)NineDevice9_GetFVF, | |||
(void *)NineDevice9_CreateVertexShader, | |||
(void *)NineDevice9_SetVertexShader, | |||
(void *)NineDevice9_GetVertexShader, | |||
(void *)NineDevice9_SetVertexShaderConstantF, | |||
(void *)NineDevice9_GetVertexShaderConstantF, | |||
(void *)NineDevice9_SetVertexShaderConstantI, | |||
(void *)NineDevice9_GetVertexShaderConstantI, | |||
(void *)NineDevice9_SetVertexShaderConstantB, | |||
(void *)NineDevice9_GetVertexShaderConstantB, | |||
(void *)NineDevice9_SetStreamSource, | |||
(void *)NineDevice9_GetStreamSource, | |||
(void *)NineDevice9_SetStreamSourceFreq, | |||
(void *)NineDevice9_GetStreamSourceFreq, | |||
(void *)NineDevice9_SetIndices, | |||
(void *)NineDevice9_GetIndices, | |||
(void *)NineDevice9_CreatePixelShader, | |||
(void *)NineDevice9_SetPixelShader, | |||
(void *)NineDevice9_GetPixelShader, | |||
(void *)NineDevice9_SetPixelShaderConstantF, | |||
(void *)NineDevice9_GetPixelShaderConstantF, | |||
(void *)NineDevice9_SetPixelShaderConstantI, | |||
(void *)NineDevice9_GetPixelShaderConstantI, | |||
(void *)NineDevice9_SetPixelShaderConstantB, | |||
(void *)NineDevice9_GetPixelShaderConstantB, | |||
(void *)NineDevice9_DrawRectPatch, | |||
(void *)NineDevice9_DrawTriPatch, | |||
(void *)NineDevice9_DeletePatch, | |||
(void *)NineDevice9_CreateQuery, | |||
(void *)NineDevice9Ex_SetConvolutionMonoKernel, | |||
(void *)NineDevice9Ex_ComposeRects, | |||
(void *)NineDevice9Ex_PresentEx, | |||
(void *)NineDevice9Ex_GetGPUThreadPriority, | |||
(void *)NineDevice9Ex_SetGPUThreadPriority, | |||
(void *)NineDevice9Ex_WaitForVBlank, | |||
(void *)NineDevice9Ex_CheckResourceResidency, | |||
(void *)NineDevice9Ex_SetMaximumFrameLatency, | |||
(void *)NineDevice9Ex_GetMaximumFrameLatency, | |||
(void *)NineDevice9Ex_CheckDeviceState, | |||
(void *)NineDevice9Ex_CreateRenderTargetEx, | |||
(void *)NineDevice9Ex_CreateOffscreenPlainSurfaceEx, | |||
(void *)NineDevice9Ex_CreateDepthStencilSurfaceEx, | |||
(void *)NineDevice9Ex_ResetEx, | |||
(void *)NineDevice9Ex_GetDisplayModeEx | |||
}; | |||
static const GUID *NineDevice9Ex_IIDs[] = { | |||
&IID_IDirect3DDevice9Ex, | |||
&IID_IDirect3DDevice9, | |||
&IID_IUnknown, | |||
NULL | |||
}; | |||
HRESULT | |||
NineDevice9Ex_new( struct pipe_screen *pScreen, | |||
D3DDEVICE_CREATION_PARAMETERS *pCreationParameters, | |||
D3DCAPS9 *pCaps, | |||
D3DPRESENT_PARAMETERS *pPresentationParameters, | |||
D3DDISPLAYMODEEX *pFullscreenDisplayMode, | |||
IDirect3D9Ex *pD3D9Ex, | |||
ID3DPresentGroup *pPresentationGroup, | |||
struct d3dadapter9_context *pCTX, | |||
struct NineDevice9Ex **ppOut ) | |||
{ | |||
BOOL lock; | |||
lock = !!(pCreationParameters->BehaviorFlags & D3DCREATE_MULTITHREADED); | |||
NINE_NEW(Device9Ex, ppOut, lock, | |||
pScreen, pCreationParameters, pCaps, pPresentationParameters, | |||
pFullscreenDisplayMode, pD3D9Ex, pPresentationGroup, pCTX); | |||
} | |||
@@ -0,0 +1,149 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_DEVICE9EX_H_ | |||
#define _NINE_DEVICE9EX_H_ | |||
#include "device9.h" | |||
struct NineDevice9Ex | |||
{ | |||
struct NineDevice9 base; | |||
}; | |||
static INLINE struct NineDevice9Ex * | |||
NineDevice9Ex( void *data ) | |||
{ | |||
return (struct NineDevice9Ex *)data; | |||
} | |||
HRESULT | |||
NineDevice9Ex_new( struct pipe_screen *pScreen, | |||
D3DDEVICE_CREATION_PARAMETERS *pCreationParameters, | |||
D3DCAPS9 *pCaps, | |||
D3DPRESENT_PARAMETERS *pPresentationParameters, | |||
D3DDISPLAYMODEEX *pFullscreenDisplayMode, | |||
IDirect3D9Ex *pD3D9Ex, | |||
ID3DPresentGroup *pPresentationGroup, | |||
struct d3dadapter9_context *pCTX, | |||
struct NineDevice9Ex **ppOut ); | |||
HRESULT WINAPI | |||
NineDevice9Ex_SetConvolutionMonoKernel( struct NineDevice9Ex *This, | |||
UINT width, | |||
UINT height, | |||
float *rows, | |||
float *columns ); | |||
HRESULT WINAPI | |||
NineDevice9Ex_ComposeRects( struct NineDevice9Ex *This, | |||
IDirect3DSurface9 *pSrc, | |||
IDirect3DSurface9 *pDst, | |||
IDirect3DVertexBuffer9 *pSrcRectDescs, | |||
UINT NumRects, | |||
IDirect3DVertexBuffer9 *pDstRectDescs, | |||
D3DCOMPOSERECTSOP Operation, | |||
int Xoffset, | |||
int Yoffset ); | |||
HRESULT WINAPI | |||
NineDevice9Ex_PresentEx( struct NineDevice9Ex *This, | |||
const RECT *pSourceRect, | |||
const RECT *pDestRect, | |||
HWND hDestWindowOverride, | |||
const RGNDATA *pDirtyRegion, | |||
DWORD dwFlags ); | |||
HRESULT WINAPI | |||
NineDevice9Ex_GetGPUThreadPriority( struct NineDevice9Ex *This, | |||
INT *pPriority ); | |||
HRESULT WINAPI | |||
NineDevice9Ex_SetGPUThreadPriority( struct NineDevice9Ex *This, | |||
INT Priority ); | |||
HRESULT WINAPI | |||
NineDevice9Ex_WaitForVBlank( struct NineDevice9Ex *This, | |||
UINT iSwapChain ); | |||
HRESULT WINAPI | |||
NineDevice9Ex_CheckResourceResidency( struct NineDevice9Ex *This, | |||
IDirect3DResource9 **pResourceArray, | |||
UINT32 NumResources ); | |||
HRESULT WINAPI | |||
NineDevice9Ex_SetMaximumFrameLatency( struct NineDevice9Ex *This, | |||
UINT MaxLatency ); | |||
HRESULT WINAPI | |||
NineDevice9Ex_GetMaximumFrameLatency( struct NineDevice9Ex *This, | |||
UINT *pMaxLatency ); | |||
HRESULT WINAPI | |||
NineDevice9Ex_CheckDeviceState( struct NineDevice9Ex *This, | |||
HWND hDestinationWindow ); | |||
HRESULT WINAPI | |||
NineDevice9Ex_CreateRenderTargetEx( struct NineDevice9Ex *This, | |||
UINT Width, | |||
UINT Height, | |||
D3DFORMAT Format, | |||
D3DMULTISAMPLE_TYPE MultiSample, | |||
DWORD MultisampleQuality, | |||
BOOL Lockable, | |||
IDirect3DSurface9 **ppSurface, | |||
HANDLE *pSharedHandle, | |||
DWORD Usage ); | |||
HRESULT WINAPI | |||
NineDevice9Ex_CreateOffscreenPlainSurfaceEx( struct NineDevice9Ex *This, | |||
UINT Width, | |||
UINT Height, | |||
D3DFORMAT Format, | |||
D3DPOOL Pool, | |||
IDirect3DSurface9 **ppSurface, | |||
HANDLE *pSharedHandle, | |||
DWORD Usage ); | |||
HRESULT WINAPI | |||
NineDevice9Ex_CreateDepthStencilSurfaceEx( struct NineDevice9Ex *This, | |||
UINT Width, | |||
UINT Height, | |||
D3DFORMAT Format, | |||
D3DMULTISAMPLE_TYPE MultiSample, | |||
DWORD MultisampleQuality, | |||
BOOL Discard, | |||
IDirect3DSurface9 **ppSurface, | |||
HANDLE *pSharedHandle, | |||
DWORD Usage ); | |||
HRESULT WINAPI | |||
NineDevice9Ex_ResetEx( struct NineDevice9Ex *This, | |||
D3DPRESENT_PARAMETERS *pPresentationParameters, | |||
D3DDISPLAYMODEEX *pFullscreenDisplayMode ); | |||
HRESULT WINAPI | |||
NineDevice9Ex_GetDisplayModeEx( struct NineDevice9Ex *This, | |||
UINT iSwapChain, | |||
D3DDISPLAYMODEEX *pMode, | |||
D3DDISPLAYROTATION *pRotation ); | |||
#endif /* _NINE_DEVICE9EX_H_ */ |
@@ -0,0 +1,62 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "device9video.h" | |||
#define DBG_CHANNEL DBG_DEVICEVIDEO | |||
HRESULT WINAPI | |||
NineDevice9Video_GetContentProtectionCaps( struct NineDevice9Video *This, | |||
const GUID *pCryptoType, | |||
const GUID *pDecodeProfile, | |||
D3DCONTENTPROTECTIONCAPS *pCaps ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineDevice9Video_CreateAuthenticatedChannel( struct NineDevice9Video *This, | |||
D3DAUTHENTICATEDCHANNELTYPE ChannelType, | |||
IDirect3DAuthenticatedChannel9 **ppAuthenticatedChannel, | |||
HANDLE *pChannelHandle ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineDevice9Video_CreateCryptoSession( struct NineDevice9Video *This, | |||
const GUID *pCryptoType, | |||
const GUID *pDecodeProfile, | |||
IDirect3DCryptoSession9 **ppCryptoSession, | |||
HANDLE *pCryptoHandle ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
IDirect3DDevice9VideoVtbl NineDevice9Video_vtable = { | |||
(void *)NineUnknown_QueryInterface, | |||
(void *)NineUnknown_AddRef, | |||
(void *)NineUnknown_Release, | |||
(void *)NineDevice9Video_GetContentProtectionCaps, | |||
(void *)NineDevice9Video_CreateAuthenticatedChannel, | |||
(void *)NineDevice9Video_CreateCryptoSession | |||
}; |
@@ -0,0 +1,57 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_DEVICE9VIDEO_H_ | |||
#define _NINE_DEVICE9VIDEO_H_ | |||
#include "iunknown.h" | |||
struct NineDevice9Video | |||
{ | |||
struct NineUnknown base; | |||
}; | |||
static INLINE struct NineDevice9Video * | |||
NineDevice9Video( void *data ) | |||
{ | |||
return (struct NineDevice9Video *)data; | |||
} | |||
HRESULT WINAPI | |||
NineDevice9Video_GetContentProtectionCaps( struct NineDevice9Video *This, | |||
const GUID *pCryptoType, | |||
const GUID *pDecodeProfile, | |||
D3DCONTENTPROTECTIONCAPS *pCaps ); | |||
HRESULT WINAPI | |||
NineDevice9Video_CreateAuthenticatedChannel( struct NineDevice9Video *This, | |||
D3DAUTHENTICATEDCHANNELTYPE ChannelType, | |||
IDirect3DAuthenticatedChannel9 **ppAuthenticatedChannel, | |||
HANDLE *pChannelHandle ); | |||
HRESULT WINAPI | |||
NineDevice9Video_CreateCryptoSession( struct NineDevice9Video *This, | |||
const GUID *pCryptoType, | |||
const GUID *pDecodeProfile, | |||
IDirect3DCryptoSession9 **ppCryptoSession, | |||
HANDLE *pCryptoHandle ); | |||
#endif /* _NINE_DEVICE9VIDEO_H_ */ |
@@ -0,0 +1,66 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "guid.h" | |||
const GUID IID_IUnknown = { 0x00000000, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } }; | |||
const GUID IID_ID3D9Adapter = { 0xBF6C7B9A, 0xF0BE, 0x11DF, { 0x81, 0xE3, 0x7F, 0x57, 0xDF, 0xD7, 0x20, 0x85 } }; | |||
const GUID IID_IDirect3D9ExOverlayExtension = { 0x187AEB13, 0xAAF5, 0x4C59, { 0x87, 0x6D, 0xE0, 0x59, 0x08, 0x8C, 0x0D, 0xF8 } }; | |||
const GUID IID_IDirect3DAuthenticatedChannel9 = { 0xFF24BEEE, 0xDA21, 0x4BEB, { 0x98, 0xB5, 0xD2, 0xF8, 0x99, 0xF9, 0x8A, 0xF9 } }; | |||
const GUID IID_IDirect3DBaseTexture9 = { 0x580CA87E, 0x1D3C, 0x4D54, { 0x99, 0x1D, 0xB7, 0xD3, 0xE3, 0xC2, 0x98, 0xCE } }; | |||
const GUID IID_IDirect3DCryptoSession9 = { 0xFA0AB799, 0x7A9C, 0x48CA, { 0x8C, 0x5B, 0x23, 0x7E, 0x71, 0xA5, 0x44, 0x34 } }; | |||
const GUID IID_IDirect3DCubeTexture9 = { 0xFFF32F81, 0xD953, 0x473A, { 0x92, 0x23, 0x93, 0xD6, 0x52, 0xAB, 0xA9, 0x3F } }; | |||
const GUID IID_IDirect3DDevice9 = { 0xD0223B96, 0xBF7A, 0x43FD, { 0x92, 0xBD, 0xA4, 0x3B, 0x0D, 0x82, 0xB9, 0xEB } }; | |||
const GUID IID_IDirect3DDevice9Ex = { 0xB18B10CE, 0x2649, 0x405A, { 0x87, 0x0F, 0x95, 0xF7, 0x77, 0xD4, 0x31, 0x3A } }; | |||
const GUID IID_IDirect3DDevice9Video = { 0x26DC4561, 0xA1EE, 0x4AE7, { 0x96, 0xDA, 0x11, 0x8A, 0x36, 0xC0, 0xEC, 0x95 } }; | |||
const GUID IID_IDirect3DIndexBuffer9 = { 0x7C9DD65E, 0xD3F7, 0x4529, { 0xAC, 0xEE, 0x78, 0x58, 0x30, 0xAC, 0xDE, 0x35 } }; | |||
const GUID IID_IDirect3DPixelShader9 = { 0x6D3BDBDC, 0x5B02, 0x4415, { 0xB8, 0x52, 0xCE, 0x5E, 0x8B, 0xCC, 0xB2, 0x89 } }; | |||
const GUID IID_IDirect3DQuery9 = { 0xD9771460, 0xA695, 0x4F26, { 0xBB, 0xD3, 0x27, 0xB8, 0x40, 0xB5, 0x41, 0xCC } }; | |||
const GUID IID_IDirect3DResource9 = { 0x05EEC05D, 0x8F7D, 0x4362, { 0xB9, 0x99, 0xD1, 0xBA, 0xF3, 0x57, 0xC7, 0x4 } }; | |||
const GUID IID_IDirect3DStateBlock9 = { 0xB07C4FE5, 0x310D, 0x4BA8, { 0xA2, 0x3C, 0x4F, 0x0F, 0x20, 0x6F, 0x21, 0x8B } }; | |||
const GUID IID_IDirect3DSurface9 = { 0x0CFBAF3A, 0x9FF6, 0x429A, { 0x99, 0xB3, 0xA2, 0x79, 0x6A, 0xF8, 0xB8, 0x9B } }; | |||
const GUID IID_IDirect3DSwapChain9 = { 0x794950F2, 0xADFC, 0x458A, { 0x90, 0x5E, 0x10, 0xA1, 0x0B, 0x0B, 0x50, 0x3B } }; | |||
const GUID IID_IDirect3DSwapChain9Ex = { 0x91886CAF, 0x1C3D, 0x4D2E, { 0xA0, 0xAB, 0x3E, 0x4C, 0x7D, 0x8D, 0x33, 0x3 } }; | |||
const GUID IID_IDirect3DTexture9 = { 0x85C31227, 0x3DE5, 0x4F00, { 0x9B, 0x3A, 0xF1, 0x1A, 0xC3, 0x8C, 0x18, 0xB5 } }; | |||
const GUID IID_IDirect3DVertexBuffer9 = { 0xB64BB1B5, 0xFD70, 0x4DF6, { 0xBF, 0x91, 0x19, 0xD0, 0xA1, 0x24, 0x55, 0xE3 } }; | |||
const GUID IID_IDirect3DVertexDeclaration9 = { 0xDD13C59C, 0x36FA, 0x4098, { 0xA8, 0xFB, 0xC7, 0xED, 0x39, 0xDC, 0x85, 0x46 } }; | |||
const GUID IID_IDirect3DVertexShader9 = { 0xEFC5557E, 0x6265, 0x4613, { 0x8A, 0x94, 0x43, 0x85, 0x78, 0x89, 0xEB, 0x36 } }; | |||
const GUID IID_IDirect3DVolume9 = { 0x24F416E6, 0x1F67, 0x4AA7, { 0xB8, 0x8E, 0xD3, 0x3F, 0x6F, 0x31, 0x28, 0xA1 } }; | |||
const GUID IID_IDirect3DVolumeTexture9 = { 0x2518526C, 0xE789, 0x4111, { 0xA7, 0xB9, 0x47, 0xEF, 0x32, 0x8D, 0x13, 0xE6 } }; | |||
boolean | |||
GUID_equal( const GUID *a, | |||
const GUID *b ) | |||
{ | |||
unsigned i; | |||
if (!a || !b) | |||
return FALSE; | |||
if (a->Data1 != b->Data1 || | |||
a->Data2 != b->Data2 || | |||
a->Data3 != b->Data3) { return FALSE; } | |||
for (i = 0; i < 8; i++) { | |||
if (a->Data4[i] != b->Data4[i]) { return FALSE; } | |||
} | |||
return TRUE; | |||
} |
@@ -0,0 +1,36 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_GUID_H_ | |||
#define _NINE_GUID_H_ | |||
#include "pipe/p_compiler.h" | |||
#include "d3d9types.h" | |||
extern const GUID IID_ID3D9Adapter; | |||
boolean | |||
GUID_equal( const GUID *a, | |||
const GUID *b ); | |||
#endif /* _NINE_GUID_H_ */ |
@@ -0,0 +1,218 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "indexbuffer9.h" | |||
#include "device9.h" | |||
#include "nine_helpers.h" | |||
#include "nine_pipe.h" | |||
#include "nine_dump.h" | |||
#include "pipe/p_screen.h" | |||
#include "pipe/p_context.h" | |||
#include "pipe/p_state.h" | |||
#include "pipe/p_defines.h" | |||
#include "pipe/p_format.h" | |||
#include "util/u_box.h" | |||
#define DBG_CHANNEL DBG_INDEXBUFFER | |||
HRESULT | |||
NineIndexBuffer9_ctor( struct NineIndexBuffer9 *This, | |||
struct NineUnknownParams *pParams, | |||
D3DINDEXBUFFER_DESC *pDesc ) | |||
{ | |||
struct pipe_resource *info = &This->base.info; | |||
HRESULT hr; | |||
DBG("This=%p pParams=%p pDesc=%p Usage=%s\n", | |||
This, pParams, pDesc, nine_D3DUSAGE_to_str(pDesc->Usage)); | |||
This->pipe = pParams->device->pipe; | |||
info->screen = pParams->device->screen; | |||
info->target = PIPE_BUFFER; | |||
info->format = PIPE_FORMAT_R8_UNORM; | |||
info->width0 = pDesc->Size; | |||
info->flags = 0; | |||
info->bind = PIPE_BIND_INDEX_BUFFER | PIPE_BIND_TRANSFER_WRITE; | |||
if (!(pDesc->Usage & D3DUSAGE_WRITEONLY)) | |||
info->bind |= PIPE_BIND_TRANSFER_READ; | |||
info->usage = PIPE_USAGE_DEFAULT; | |||
if (pDesc->Usage & D3DUSAGE_DYNAMIC) | |||
info->usage = PIPE_USAGE_STREAM; | |||
if (pDesc->Pool == D3DPOOL_SYSTEMMEM) | |||
info->usage = PIPE_USAGE_STAGING; | |||
/* if (This->desc.Usage & D3DUSAGE_DONOTCLIP) { } */ | |||
/* if (This->desc.Usage & D3DUSAGE_NONSECURE) { } */ | |||
/* if (This->desc.Usage & D3DUSAGE_NPATCHES) { } */ | |||
/* if (This->desc.Usage & D3DUSAGE_POINTS) { } */ | |||
/* if (This->desc.Usage & D3DUSAGE_RTPATCHES) { } */ | |||
/* if (This->desc.Usage & D3DUSAGE_SOFTWAREPROCESSING) { } */ | |||
info->height0 = 1; | |||
info->depth0 = 1; | |||
info->array_size = 1; | |||
info->last_level = 0; | |||
info->nr_samples = 0; | |||
hr = NineResource9_ctor(&This->base, pParams, TRUE, D3DRTYPE_INDEXBUFFER, | |||
pDesc->Pool); | |||
if (FAILED(hr)) | |||
return hr; | |||
This->buffer.buffer = This->base.resource; | |||
This->buffer.offset = 0; | |||
This->map_count = 0; | |||
switch (pDesc->Format) { | |||
case D3DFMT_INDEX16: This->buffer.index_size = 2; break; | |||
case D3DFMT_INDEX32: This->buffer.index_size = 4; break; | |||
default: | |||
user_assert(!"Invalid index format.", D3DERR_INVALIDCALL); | |||
break; | |||
} | |||
This->buffer.user_buffer = NULL; | |||
pDesc->Type = D3DRTYPE_INDEXBUFFER; | |||
This->desc = *pDesc; | |||
return D3D_OK; | |||
} | |||
void | |||
NineIndexBuffer9_dtor( struct NineIndexBuffer9 *This ) | |||
{ | |||
if (This->transfer) { NineIndexBuffer9_Unlock(This); } | |||
NineResource9_dtor(&This->base); | |||
} | |||
const struct pipe_index_buffer * | |||
NineIndexBuffer9_GetBuffer( struct NineIndexBuffer9 *This ) | |||
{ | |||
return &This->buffer; | |||
} | |||
HRESULT WINAPI | |||
NineIndexBuffer9_Lock( struct NineIndexBuffer9 *This, | |||
UINT OffsetToLock, | |||
UINT SizeToLock, | |||
void **ppbData, | |||
DWORD Flags ) | |||
{ | |||
struct pipe_box box; | |||
void *data; | |||
UINT count; | |||
const unsigned usage = d3dlock_buffer_to_pipe_transfer_usage(Flags); | |||
DBG("This=%p OffsetToLock=%u SizeToLock=%u ppbData=%p Flags=%i " | |||
"transfer=%p map_count=%u\n", This, OffsetToLock, | |||
SizeToLock, ppbData, Flags, This->transfer, This->map_count); | |||
count = ++This->map_count; | |||
if (SizeToLock == 0) { | |||
SizeToLock = This->desc.Size - OffsetToLock; | |||
user_warn(OffsetToLock != 0); | |||
} | |||
u_box_1d(OffsetToLock, SizeToLock, &box); | |||
if (unlikely(count != 1)) { | |||
DBG("Lock has been called on already locked buffer." | |||
"Unmapping before mapping again."); | |||
This->pipe->transfer_unmap(This->pipe, This->transfer); | |||
} | |||
data = This->pipe->transfer_map(This->pipe, This->base.resource, 0, | |||
usage, &box, &This->transfer); | |||
if (!This->transfer) { | |||
DBG("pipe::transfer_map failed\n" | |||
" usage = %u\n" | |||
" box.x = %u\n" | |||
" box.width = %u\n", | |||
usage, box.x, box.width); | |||
} | |||
*ppbData = data; | |||
DBG("Returning memory at %p at address %p\n", *ppbData, ppbData); | |||
return D3D_OK; | |||
} | |||
HRESULT WINAPI | |||
NineIndexBuffer9_Unlock( struct NineIndexBuffer9 *This ) | |||
{ | |||
DBG("This=%p\n", This); | |||
if (!This->map_count) { | |||
DBG("Unmap called without a previous map call.\n"); | |||
return D3D_OK; | |||
} | |||
if (--This->map_count) { | |||
DBG("Ignoring unmap.\n"); | |||
return D3D_OK; | |||
} | |||
This->pipe->transfer_unmap(This->pipe, This->transfer); | |||
This->transfer = NULL; | |||
return D3D_OK; | |||
} | |||
HRESULT WINAPI | |||
NineIndexBuffer9_GetDesc( struct NineIndexBuffer9 *This, | |||
D3DINDEXBUFFER_DESC *pDesc ) | |||
{ | |||
user_assert(pDesc, E_POINTER); | |||
*pDesc = This->desc; | |||
return D3D_OK; | |||
} | |||
IDirect3DIndexBuffer9Vtbl NineIndexBuffer9_vtable = { | |||
(void *)NineUnknown_QueryInterface, | |||
(void *)NineUnknown_AddRef, | |||
(void *)NineUnknown_Release, | |||
(void *)NineUnknown_GetDevice, /* actually part of Resource9 iface */ | |||
(void *)NineResource9_SetPrivateData, | |||
(void *)NineResource9_GetPrivateData, | |||
(void *)NineResource9_FreePrivateData, | |||
(void *)NineResource9_SetPriority, | |||
(void *)NineResource9_GetPriority, | |||
(void *)NineResource9_PreLoad, | |||
(void *)NineResource9_GetType, | |||
(void *)NineIndexBuffer9_Lock, | |||
(void *)NineIndexBuffer9_Unlock, | |||
(void *)NineIndexBuffer9_GetDesc | |||
}; | |||
static const GUID *NineIndexBuffer9_IIDs[] = { | |||
&IID_IDirect3DIndexBuffer9, | |||
&IID_IDirect3DResource9, | |||
&IID_IUnknown, | |||
NULL | |||
}; | |||
HRESULT | |||
NineIndexBuffer9_new( struct NineDevice9 *pDevice, | |||
D3DINDEXBUFFER_DESC *pDesc, | |||
struct NineIndexBuffer9 **ppOut ) | |||
{ | |||
NINE_DEVICE_CHILD_NEW(IndexBuffer9, ppOut, /* args */ pDevice, pDesc); | |||
} |
@@ -0,0 +1,88 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_INDEXBUFFER9_H_ | |||
#define _NINE_INDEXBUFFER9_H_ | |||
#include "resource9.h" | |||
#include "pipe/p_state.h" | |||
struct pipe_screen; | |||
struct pipe_context; | |||
struct pipe_index_buffer; | |||
struct pipe_transfer; | |||
struct NineDevice9; | |||
struct NineIndexBuffer9 | |||
{ | |||
struct NineResource9 base; | |||
/* g3d stuff */ | |||
struct pipe_context *pipe; | |||
struct pipe_index_buffer buffer; | |||
struct pipe_transfer *transfer; | |||
UINT map_count; | |||
D3DINDEXBUFFER_DESC desc; | |||
}; | |||
static INLINE struct NineIndexBuffer9 * | |||
NineIndexBuffer9( void *data ) | |||
{ | |||
return (struct NineIndexBuffer9 *)data; | |||
} | |||
HRESULT | |||
NineIndexBuffer9_new( struct NineDevice9 *pDevice, | |||
D3DINDEXBUFFER_DESC *pDesc, | |||
struct NineIndexBuffer9 **ppOut ); | |||
HRESULT | |||
NineIndexBuffer9_ctor( struct NineIndexBuffer9 *This, | |||
struct NineUnknownParams *pParams, | |||
D3DINDEXBUFFER_DESC *pDesc ); | |||
void | |||
NineIndexBuffer9_dtor( struct NineIndexBuffer9 *This ); | |||
/*** Nine private ***/ | |||
const struct pipe_index_buffer * | |||
NineIndexBuffer9_GetBuffer( struct NineIndexBuffer9 *This ); | |||
/*** Direct3D public ***/ | |||
HRESULT WINAPI | |||
NineIndexBuffer9_Lock( struct NineIndexBuffer9 *This, | |||
UINT OffsetToLock, | |||
UINT SizeToLock, | |||
void **ppbData, | |||
DWORD Flags ); | |||
HRESULT WINAPI | |||
NineIndexBuffer9_Unlock( struct NineIndexBuffer9 *This ); | |||
HRESULT WINAPI | |||
NineIndexBuffer9_GetDesc( struct NineIndexBuffer9 *This, | |||
D3DINDEXBUFFER_DESC *pDesc ); | |||
#endif /* _NINE_INDEXBUFFER9_H_ */ |
@@ -0,0 +1,126 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "iunknown.h" | |||
#include "util/u_atomic.h" | |||
#include "nine_helpers.h" | |||
#define DBG_CHANNEL DBG_UNKNOWN | |||
HRESULT | |||
NineUnknown_ctor( struct NineUnknown *This, | |||
struct NineUnknownParams *pParams ) | |||
{ | |||
This->refs = pParams->container ? 0 : 1; | |||
This->bind = 0; | |||
This->forward = !This->refs; | |||
This->container = pParams->container; | |||
This->device = pParams->device; | |||
if (This->refs && This->device) | |||
NineUnknown_AddRef(NineUnknown(This->device)); | |||
This->vtable = pParams->vtable; | |||
This->guids = pParams->guids; | |||
This->dtor = pParams->dtor; | |||
return D3D_OK; | |||
} | |||
void | |||
NineUnknown_dtor( struct NineUnknown *This ) | |||
{ | |||
FREE(This); | |||
} | |||
HRESULT WINAPI | |||
NineUnknown_QueryInterface( struct NineUnknown *This, | |||
REFIID riid, | |||
void **ppvObject ) | |||
{ | |||
unsigned i = 0; | |||
if (!ppvObject) return E_POINTER; | |||
do { | |||
if (GUID_equal(This->guids[i], riid)) { | |||
*ppvObject = This; | |||
assert(This->refs); | |||
NineUnknown_AddRef(This); | |||
return S_OK; | |||
} | |||
} while (This->guids[++i]); | |||
*ppvObject = NULL; | |||
return E_NOINTERFACE; | |||
} | |||
ULONG WINAPI | |||
NineUnknown_AddRef( struct NineUnknown *This ) | |||
{ | |||
ULONG r; | |||
if (This->forward) | |||
return NineUnknown_AddRef(This->container); | |||
else | |||
r = p_atomic_inc_return(&This->refs); | |||
if (r == 1) { | |||
if (This->device) | |||
NineUnknown_AddRef(NineUnknown(This->device)); | |||
/* This shouldn't be necessary: | |||
if (This->container) | |||
NineUnknown_Bind(NineUnknown(This->container)); */ | |||
} | |||
return r; | |||
} | |||
ULONG WINAPI | |||
NineUnknown_Release( struct NineUnknown *This ) | |||
{ | |||
if (This->forward) | |||
return NineUnknown_Release(This->container); | |||
ULONG r = p_atomic_dec_return(&This->refs); | |||
if (r == 0) { | |||
if (This->device) { | |||
if (NineUnknown_Release(NineUnknown(This->device)) == 0) | |||
return r; /* everything's gone */ | |||
} | |||
if (This->container) { | |||
/* NineUnknown_Unbind(NineUnknown(This->container)); */ | |||
} else | |||
if (This->bind == 0) { | |||
This->dtor(This); | |||
} | |||
} | |||
return r; | |||
} | |||
HRESULT WINAPI | |||
NineUnknown_GetDevice( struct NineUnknown *This, | |||
IDirect3DDevice9 **ppDevice ) | |||
{ | |||
user_assert(ppDevice, E_POINTER); | |||
NineUnknown_AddRef(NineUnknown(This->device)); | |||
*ppDevice = (IDirect3DDevice9 *)This->device; | |||
return D3D_OK; | |||
} |
@@ -0,0 +1,153 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_IUNKNOWN_H_ | |||
#define _NINE_IUNKNOWN_H_ | |||
#include "pipe/p_compiler.h" | |||
#include "util/u_memory.h" | |||
#include "guid.h" | |||
#include "nine_debug.h" | |||
#include "nine_quirk.h" | |||
#include "d3d9.h" | |||
struct Nine9; | |||
struct NineDevice9; | |||
struct NineUnknown | |||
{ | |||
/* pointer to vtable */ | |||
void *vtable; | |||
int32_t refs; /* external reference count */ | |||
int32_t bind; /* internal bind count */ | |||
boolean forward; /* whether to forward references to the container */ | |||
struct NineUnknown *container; /* referenced if (refs | bind) */ | |||
struct NineDevice9 *device; /* referenced if (refs) */ | |||
const GUID **guids; /* for QueryInterface */ | |||
void (*dtor)(void *data); /* top-level dtor */ | |||
}; | |||
static INLINE struct NineUnknown * | |||
NineUnknown( void *data ) | |||
{ | |||
return (struct NineUnknown *)data; | |||
} | |||
/* Use this instead of a shitload of arguments: */ | |||
struct NineUnknownParams | |||
{ | |||
void *vtable; | |||
const GUID **guids; | |||
void (*dtor)(void *data); | |||
struct NineUnknown *container; | |||
struct NineDevice9 *device; | |||
}; | |||
HRESULT | |||
NineUnknown_ctor( struct NineUnknown *This, | |||
struct NineUnknownParams *pParams ); | |||
void | |||
NineUnknown_dtor( struct NineUnknown *This ); | |||
/*** Direct3D public methods ***/ | |||
HRESULT WINAPI | |||
NineUnknown_QueryInterface( struct NineUnknown *This, | |||
REFIID riid, | |||
void **ppvObject ); | |||
ULONG WINAPI | |||
NineUnknown_AddRef( struct NineUnknown *This ); | |||
ULONG WINAPI | |||
NineUnknown_Release( struct NineUnknown *This ); | |||
HRESULT WINAPI | |||
NineUnknown_GetDevice( struct NineUnknown *This, | |||
IDirect3DDevice9 **ppDevice ); | |||
/*** Nine private methods ***/ | |||
static INLINE void | |||
NineUnknown_Destroy( struct NineUnknown *This ) | |||
{ | |||
assert(!(This->refs | This->bind)); | |||
This->dtor(This); | |||
} | |||
static INLINE UINT | |||
NineUnknown_Bind( struct NineUnknown *This ) | |||
{ | |||
UINT b = ++This->bind; | |||
assert(b); | |||
if (b == 1 && This->container) { | |||
if (This->container != NineUnknown(This->device)) | |||
NineUnknown_Bind(This->container); | |||
} | |||
return b; | |||
} | |||
static INLINE UINT | |||
NineUnknown_Unbind( struct NineUnknown *This ) | |||
{ | |||
UINT b = --This->bind; | |||
if (!b) { | |||
if (This->container) { | |||
if (This->container != NineUnknown(This->device)) | |||
NineUnknown_Unbind(This->container); | |||
} else | |||
if (This->refs == 0) { | |||
This->dtor(This); | |||
} | |||
} | |||
return b; | |||
} | |||
static INLINE void | |||
NineUnknown_ConvertRefToBind( struct NineUnknown *This ) | |||
{ | |||
NineUnknown_Bind(This); | |||
NineUnknown_Release(This); | |||
} | |||
/* Detach from container. */ | |||
static INLINE void | |||
NineUnknown_Detach( struct NineUnknown *This ) | |||
{ | |||
assert(This->container && !This->forward); | |||
if (This->refs) | |||
NineUnknown_Unbind(This->container); | |||
if (This->bind) | |||
NineUnknown_Unbind(This->container); | |||
This->container = NULL; | |||
if (!(This->refs | This->bind)) | |||
This->dtor(This); | |||
} | |||
#endif /* _NINE_IUNKNOWN_H_ */ |
@@ -0,0 +1,104 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "nine_debug.h" | |||
#include <ctype.h> | |||
static const struct debug_named_value nine_debug_flags[] = { | |||
{ "unknown", DBG_UNKNOWN, "IUnknown implementation." }, | |||
{ "adapter", DBG_ADAPTER, "ID3D9Adapter implementation." }, | |||
{ "overlay", DBG_OVERLAYEXTENSION, "IDirect3D9ExOverlayExtension implementation." }, | |||
{ "auth", DBG_AUTHENTICATEDCHANNEL, "IDirect3DAuthenticatedChannel9 implementation." }, | |||
{ "basetex", DBG_BASETEXTURE, "IDirect3DBaseTexture9 implementation." }, | |||
{ "crypto", DBG_CRYPTOSESSION, "IDirect3DCryptoSession9 implementation." }, | |||
{ "cubetex", DBG_CUBETEXTURE, "IDirect3DCubeTexture9 implementation." }, | |||
{ "device", DBG_DEVICE, "IDirect3DDevice9(Ex) implementation." }, | |||
{ "video", DBG_DEVICEVIDEO, "IDirect3DDeviceVideo9 implementation." }, | |||
{ "ibuf", DBG_INDEXBUFFER, "IDirect3DIndexBuffer9 implementation." }, | |||
{ "ps", DBG_PIXELSHADER, "IDirect3DPixelShader9 implementation." }, | |||
{ "query", DBG_QUERY, "IDirect3DQuery9 implementation." }, | |||
{ "res", DBG_RESOURCE, "IDirect3DResource9 implementation." }, | |||
{ "state", DBG_STATEBLOCK, "IDirect3DStateBlock9 implementation." }, | |||
{ "surf", DBG_SURFACE, "IDirect3DSurface9 implementation." }, | |||
{ "swap", DBG_SWAPCHAIN, "IDirect3DSwapChain9(Ex) implementation." }, | |||
{ "tex", DBG_TEXTURE, "IDirect3DTexture9 implementation." }, | |||
{ "vbuf", DBG_VERTEXBUFFER, "IDirect3DVertexBuffer9 implementation." }, | |||
{ "vdecl", DBG_VERTEXDECLARATION, "IDirect3DVertexDeclaration9 implementation." }, | |||
{ "vs", DBG_VERTEXSHADER, "IDirect3DVertexShader9 implementation." }, | |||
{ "3dsurf", DBG_VOLUME, "IDirect3DVolume9 implementation." }, | |||
{ "3dtex", DBG_VOLUMETEXTURE, "IDirect3DVolumeTexture9 implementation." }, | |||
{ "shader", DBG_SHADER, "Shader token stream translator." }, | |||
{ "ff", DBG_FF, "Fixed function emulation." }, | |||
{ "user", DBG_USER, "User errors, both fixable and unfixable." }, | |||
{ "error", DBG_ERROR, "Driver errors, always visible." }, | |||
{ "warn", DBG_WARN, "Driver warnings, always visible in debug builds." }, | |||
DEBUG_NAMED_VALUE_END | |||
}; | |||
void | |||
_nine_debug_printf( unsigned long flag, | |||
const char *func, | |||
const char *fmt, | |||
... ) | |||
{ | |||
static boolean first = TRUE; | |||
static unsigned long dbg_flags = DBG_ERROR | DBG_WARN; | |||
if (first) { | |||
first = FALSE; | |||
dbg_flags |= debug_get_flags_option("NINE_DEBUG", nine_debug_flags, 0); | |||
} | |||
if (dbg_flags & flag) { | |||
const char *f = func ? strrchr(func, '_') : NULL; | |||
va_list ap; | |||
/* inside a class this will print nine:classinlowercase:func: while | |||
* outside a class (rarely used) it will just print nine:func: | |||
* the reason for lower case is simply to match the filenames, as it | |||
* will also strip off the "Nine" */ | |||
if (f && strncmp(func, "Nine", 4) == 0) { | |||
char klass[96]; /* no class name is this long */ | |||
char *ptr = klass; | |||
for (func += 4; func != f; ++func) { *ptr++ = tolower(*func); } | |||
*ptr = '\0'; | |||
debug_printf("nine:%s:%s: ", klass, ++f); | |||
} else if (func) { | |||
debug_printf("nine:%s: ", func); | |||
} | |||
va_start(ap, fmt); | |||
debug_vprintf(fmt, ap); | |||
va_end(ap); | |||
} | |||
} | |||
void | |||
_nine_stub( const char *file, | |||
const char *func, | |||
unsigned line ) | |||
{ | |||
const char *r = strrchr(file, '/'); | |||
if (r == NULL) { r = strrchr(file, '\\'); } | |||
debug_printf("nine:%s:%d: %s STUB!\n", r ? ++r : file, line, func); | |||
} |
@@ -0,0 +1,135 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_DEBUG_H_ | |||
#define _NINE_DEBUG_H_ | |||
#include "util/u_debug.h" | |||
void | |||
_nine_debug_printf( unsigned long flag, | |||
const char *func, | |||
const char *fmt, | |||
... ) _util_printf_format(3,4); | |||
#define ERR(fmt, ...) _nine_debug_printf(DBG_ERROR, __FUNCTION__, fmt, ## __VA_ARGS__) | |||
#ifdef DEBUG | |||
#define WARN(fmt, ...) _nine_debug_printf(DBG_WARN, __FUNCTION__, fmt, ## __VA_ARGS__) | |||
#define WARN_ONCE(fmt, ...) \ | |||
do { \ | |||
static boolean once = TRUE; \ | |||
if (once) { \ | |||
once = FALSE; \ | |||
_nine_debug_printf(DBG_WARN, __FUNCTION__, fmt, ## __VA_ARGS__); \ | |||
} \ | |||
} while(0) | |||
#else | |||
#define WARN(fmt, ...) | |||
#define WARN_ONCE(fmt, ...) | |||
#endif | |||
#ifdef DEBUG | |||
#define DBG_FLAG(flag, fmt, ...) \ | |||
_nine_debug_printf(flag, __FUNCTION__, fmt, ## __VA_ARGS__) | |||
#else | |||
#define DBG_FLAG(flag, fmt, ...) | |||
#endif | |||
#define DBG(fmt, ...) DBG_FLAG(DBG_CHANNEL, fmt, ## __VA_ARGS__) | |||
#define DBG_UNKNOWN (1<< 0) | |||
#define DBG_ADAPTER (1<< 1) | |||
#define DBG_OVERLAYEXTENSION (1<< 2) | |||
#define DBG_AUTHENTICATEDCHANNEL (1<< 3) | |||
#define DBG_BASETEXTURE (1<< 4) | |||
#define DBG_CRYPTOSESSION (1<< 5) | |||
#define DBG_CUBETEXTURE (1<< 6) | |||
#define DBG_DEVICE (1<< 7) | |||
#define DBG_DEVICEVIDEO (1<< 8) | |||
#define DBG_INDEXBUFFER (1<< 9) | |||
#define DBG_PIXELSHADER (1<<10) | |||
#define DBG_QUERY (1<<11) | |||
#define DBG_RESOURCE (1<<12) | |||
#define DBG_STATEBLOCK (1<<13) | |||
#define DBG_SURFACE (1<<14) | |||
#define DBG_SWAPCHAIN (1<<15) | |||
#define DBG_TEXTURE (1<<16) | |||
#define DBG_VERTEXBUFFER (1<<17) | |||
#define DBG_VERTEXDECLARATION (1<<18) | |||
#define DBG_VERTEXSHADER (1<<19) | |||
#define DBG_VOLUME (1<<20) | |||
#define DBG_VOLUMETEXTURE (1<<21) | |||
#define DBG_SHADER (1<<22) | |||
#define DBG_FF (1<<23) | |||
#define DBG_USER (1<<24) | |||
#define DBG_ERROR (1<<25) | |||
#define DBG_WARN (1<<26) | |||
void | |||
_nine_stub( const char *file, | |||
const char *func, | |||
unsigned line ); | |||
#ifdef DEBUG | |||
#define STUB(ret) \ | |||
do { \ | |||
_nine_stub(__FILE__, __FUNCTION__, __LINE__); \ | |||
return ret; \ | |||
} while (0) | |||
#else | |||
#define STUB(ret) do { return ret; } while (0) | |||
#endif | |||
/* the expression for this macro is equivalent of that to assert, however this | |||
* macro is designed to be used in conditionals ala | |||
* if (user_error(required condition)) { assertion failed } | |||
* It also prints debug message if the assertion fails. */ | |||
#ifdef DEBUG | |||
#define user_error(x) \ | |||
(!(x) ? (DBG_FLAG(DBG_USER, "User assertion failed: `%s'\n", #x), TRUE) \ | |||
: FALSE) | |||
#else | |||
#define user_error(x) (!(x) ? TRUE : FALSE) | |||
#endif | |||
#ifdef DEBUG | |||
#define user_warn(x) \ | |||
if ((x)) { DBG_FLAG(DBG_USER, "User warning: `%s'\n", #x); } | |||
#else | |||
#define user_warn(x) | |||
#endif | |||
/* nonfatal assert */ | |||
#define user_assert(x, r) \ | |||
do { \ | |||
if (user_error(x)) { \ | |||
return r; \ | |||
} \ | |||
} while (0) | |||
#define ret_err(x, r) \ | |||
do { \ | |||
ERR(x); \ | |||
return r; \ | |||
} while(0) | |||
#endif /* _NINE_DEBUG_H_ */ |
@@ -0,0 +1,55 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_DEFINES_H_ | |||
#define _NINE_DEFINES_H_ | |||
#include "pipe/p_defines.h" | |||
#define NINE_RESOURCE_FLAG_LOCKABLE (PIPE_RESOURCE_FLAG_ST_PRIV << 1) | |||
#define NINE_RESOURCE_FLAG_DUMMY (PIPE_RESOURCE_FLAG_ST_PRIV << 2) | |||
/* vertexdeclaration9.c */ | |||
unsigned nine_d3d9_to_nine_declusage(unsigned usage, unsigned index); | |||
#define NINE_DECLUSAGE_POSITION(i) ( 0 + (i)) | |||
#define NINE_DECLUSAGE_BLENDWEIGHT(i) ( 5 + (i)) | |||
#define NINE_DECLUSAGE_BLENDINDICES(i) ( 9 + (i)) | |||
#define NINE_DECLUSAGE_NORMAL(i) (13 + (i)) | |||
#define NINE_DECLUSAGE_PSIZE 15 | |||
#define NINE_DECLUSAGE_TEXCOORD(i) (16 + (i)) | |||
#define NINE_DECLUSAGE_TANGENT(i) (32 + (i)) | |||
#define NINE_DECLUSAGE_BINORMAL(i) (34 + (i)) | |||
#define NINE_DECLUSAGE_TESSFACTOR 36 | |||
#define NINE_DECLUSAGE_POSITIONT 37 | |||
#define NINE_DECLUSAGE_COLOR(i) (38 + (i)) | |||
#define NINE_DECLUSAGE_DEPTH 43 | |||
#define NINE_DECLUSAGE_FOG 44 | |||
#define NINE_DECLUSAGE_SAMPLE 45 | |||
#define NINE_DECLUSAGE_NONE 46 | |||
#define NINE_DECLUSAGE_LAST NINE_DECLUSAGE_NONE | |||
#define NINE_DECLUSAGE_COUNT (NINE_DECLUSAGE_LAST + 1) | |||
#define NINED3DCLEAR_DEPTHSTENCIL (D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL) | |||
#endif /* _NINE_DEFINES_H_ */ |
@@ -0,0 +1,813 @@ | |||
#include "nine_debug.h" | |||
#include "nine_pipe.h" | |||
#include <stdio.h> | |||
#include "util/u_memory.h" | |||
#include "util/u_math.h" | |||
#include "nine_dump.h" | |||
#ifdef DEBUG | |||
static char __thread tls[128]; | |||
const char *nine_D3DDEVTYPE_to_str(D3DDEVTYPE type) | |||
{ | |||
switch (type) { | |||
case D3DDEVTYPE_HAL: return "HAL"; | |||
case D3DDEVTYPE_NULLREF: return "NULLREF"; | |||
case D3DDEVTYPE_REF: return "REF"; | |||
case D3DDEVTYPE_SW: return "SW"; | |||
default: | |||
return "(D3DDEVTYPE_?)"; | |||
} | |||
} | |||
const char *nine_D3DPOOL_to_str(D3DPOOL pool) | |||
{ | |||
switch (pool) { | |||
case D3DPOOL_DEFAULT: return "DEFAULT"; | |||
case D3DPOOL_MANAGED: return "MANAGED"; | |||
case D3DPOOL_SYSTEMMEM: return "SYSTEMMEM"; | |||
case D3DPOOL_SCRATCH: return "SCRATCH"; | |||
default: | |||
return "(D3DPOOL_?)"; | |||
} | |||
} | |||
const char *nine_D3DSAMP_to_str(DWORD samp) | |||
{ | |||
switch (samp) { | |||
case D3DSAMP_ADDRESSU: return "ADDRESSU"; | |||
case D3DSAMP_ADDRESSV: return "ADDRESSV"; | |||
case D3DSAMP_ADDRESSW: return "ADDRESSW"; | |||
case D3DSAMP_BORDERCOLOR: return "BORDERCOLOR"; | |||
case D3DSAMP_MAGFILTER: return "MAGFILTER"; | |||
case D3DSAMP_MINFILTER: return "MINFILTER"; | |||
case D3DSAMP_MIPFILTER: return "MIPFILTER"; | |||
case D3DSAMP_MIPMAPLODBIAS: return "MIPMAPLODBIAS"; | |||
case D3DSAMP_MAXMIPLEVEL: return "MAXMIPLEVEL"; | |||
case D3DSAMP_MAXANISOTROPY: return "MAXANISOTROPY"; | |||
case D3DSAMP_SRGBTEXTURE: return "SRGBTEXTURE"; | |||
case D3DSAMP_ELEMENTINDEX: return "ELEMENTINDEX"; | |||
case D3DSAMP_DMAPOFFSET: return "DMAPOFFSET"; | |||
default: | |||
return "(D3DSAMP_?)"; | |||
} | |||
} | |||
#define C2S(n,s) \ | |||
do { \ | |||
if (usage & D3DUSAGE_##n) p += snprintf(&tls[p], sizeof(tls) - p, s); \ | |||
} while(0) | |||
const char *nine_D3DUSAGE_to_str(DWORD usage) | |||
{ | |||
int p = 0; | |||
tls[0] = 0; | |||
C2S(AUTOGENMIPMAP, "MIPGEN"); | |||
C2S(WRITEONLY, "WO"); | |||
C2S(DYNAMIC, "DYNAMIC"); | |||
C2S(DEPTHSTENCIL, "DS"); | |||
C2S(RENDERTARGET, "RT"); | |||
C2S(SOFTWAREPROCESSING, "SW"); | |||
C2S(DONOTCLIP, "NOCLIP"); | |||
C2S(POINTS, "POINTS"); | |||
C2S(DMAP, "DMAP"); | |||
C2S(NPATCHES, "NPATCHES"); | |||
C2S(RTPATCHES, "RTPATCHES"); | |||
C2S(TEXTAPI, "TEXTAPI"); | |||
C2S(NONSECURE, "NONSECURE"); | |||
C2S(RESTRICTED_CONTENT, "RESTRICTED_CONTENT"); | |||
C2S(RESTRICT_SHARED_RESOURCE, "RESTRICT_SHARED_RESOURCE"); | |||
C2S(RESTRICT_SHARED_RESOURCE_DRIVER, "RESTRICT_SHARED_RESOURCE_DRIVER"); | |||
return tls; | |||
} | |||
#undef C2S | |||
#define C2S(n) \ | |||
do { \ | |||
if (flags & D3DPRESENTFLAG_##n) \ | |||
p += snprintf(&tls[p], sizeof(tls) - p, #n); \ | |||
} while(0) | |||
const char *nine_D3DPRESENTFLAG_to_str(DWORD flags) | |||
{ | |||
int p = 0; | |||
tls[0] = 0; | |||
C2S(DEVICECLIP); | |||
C2S(DISCARD_DEPTHSTENCIL); | |||
C2S(LOCKABLE_BACKBUFFER); | |||
C2S(NOAUTOROTATE); | |||
C2S(UNPRUNEDMODE); | |||
C2S(VIDEO); | |||
C2S(OVERLAY_LIMITEDRGB); | |||
C2S(OVERLAY_YCbCr_BT709); | |||
C2S(OVERLAY_YCbCr_xvYCC); | |||
C2S(RESTRICTED_CONTENT); | |||
C2S(RESTRICT_SHARED_RESOURCE_DRIVER); | |||
return tls; | |||
} | |||
#undef C2S | |||
#define C2S(n) \ | |||
do { \ | |||
if (lock & D3DLOCK_##n) p += snprintf(&tls[p], sizeof(tls) - p, #n"|"); \ | |||
} while(0) | |||
const char *nine_D3DLOCK_to_str(DWORD lock) | |||
{ | |||
int p = 0; | |||
tls[0] = 0; | |||
C2S(DISCARD); | |||
C2S(DONOTWAIT); | |||
C2S(NO_DIRTY_UPDATE); | |||
C2S(NOOVERWRITE); | |||
C2S(NOSYSLOCK); | |||
C2S(READONLY); | |||
return tls; | |||
} | |||
#undef C2S | |||
const char *nine_D3DRTYPE_to_str(D3DRESOURCETYPE type) | |||
{ | |||
switch (type) { | |||
case D3DRTYPE_SURFACE: return "SURFACE"; | |||
case D3DRTYPE_VOLUME: return "VOLUME"; | |||
case D3DRTYPE_TEXTURE: return "TEXTURE"; | |||
case D3DRTYPE_VOLUMETEXTURE: return "VOLUMETEXTURE"; | |||
case D3DRTYPE_CUBETEXTURE: return "CUBETEXTURE"; | |||
case D3DRTYPE_VERTEXBUFFER: return "VERTEXBUFFER"; | |||
case D3DRTYPE_INDEXBUFFER: return "INDEXBUFFER"; | |||
default: | |||
return "(D3DRTYPE_?)"; | |||
} | |||
} | |||
const char *nine_D3DQUERYTYPE_to_str(D3DQUERYTYPE type) | |||
{ | |||
switch (type) { | |||
case D3DQUERYTYPE_VCACHE: return "VCACHE"; | |||
case D3DQUERYTYPE_RESOURCEMANAGER: return "RESOURCEMANAGER"; | |||
case D3DQUERYTYPE_VERTEXSTATS: return "VERTEXSTATS"; | |||
case D3DQUERYTYPE_EVENT: return "EVENT"; | |||
case D3DQUERYTYPE_OCCLUSION: return "OCCLUSION"; | |||
case D3DQUERYTYPE_TIMESTAMP: return "TIMESTAMP"; | |||
case D3DQUERYTYPE_TIMESTAMPDISJOINT: return "TIMESTAMPDISJOINT"; | |||
case D3DQUERYTYPE_TIMESTAMPFREQ: return "TIMESTAMPFREQ"; | |||
case D3DQUERYTYPE_PIPELINETIMINGS: return "PIPELINETIMINGS"; | |||
case D3DQUERYTYPE_INTERFACETIMINGS: return "INTERFACETIMINGS"; | |||
case D3DQUERYTYPE_VERTEXTIMINGS: return "VERTEXTIMINGS"; | |||
case D3DQUERYTYPE_PIXELTIMINGS: return "PIXELTIMINGS"; | |||
case D3DQUERYTYPE_BANDWIDTHTIMINGS: return "BANDWIDTHTIMINGS"; | |||
case D3DQUERYTYPE_CACHEUTILIZATION: return "CACHEUTILIZATION"; | |||
default: | |||
return "(D3DQUERYTYPE_?)"; | |||
} | |||
} | |||
const char *nine_D3DTSS_to_str(D3DTEXTURESTAGESTATETYPE type) | |||
{ | |||
switch (type) { | |||
case D3DTSS_COLOROP: return "COLOROP"; | |||
case D3DTSS_ALPHAOP: return "ALPHAOP"; | |||
case D3DTSS_COLORARG0: return "COLORARG0"; | |||
case D3DTSS_COLORARG1: return "COLORARG1"; | |||
case D3DTSS_COLORARG2: return "COLORARG2"; | |||
case D3DTSS_ALPHAARG0: return "ALPHAARG0"; | |||
case D3DTSS_ALPHAARG1: return "ALPHAARG1"; | |||
case D3DTSS_ALPHAARG2: return "ALPHAARG2"; | |||
case D3DTSS_RESULTARG: return "RESULTARG"; | |||
case D3DTSS_BUMPENVMAT00: return "BUMPENVMAT00"; | |||
case D3DTSS_BUMPENVMAT01: return "BUMPENVMAT01"; | |||
case D3DTSS_BUMPENVMAT10: return "BUMPENVMAT10"; | |||
case D3DTSS_BUMPENVMAT11: return "BUMPENVMAT11"; | |||
case D3DTSS_BUMPENVLSCALE: return "BUMPENVLSCALE"; | |||
case D3DTSS_BUMPENVLOFFSET: return "BUMPENVLOFFSET"; | |||
case D3DTSS_TEXCOORDINDEX: return "TEXCOORDINDEX"; | |||
case D3DTSS_TEXTURETRANSFORMFLAGS: return "TEXTURETRANSFORMFLAGS"; | |||
case D3DTSS_CONSTANT: return "CONSTANT"; | |||
default: | |||
return "(D3DTSS_?)"; | |||
} | |||
} | |||
#define D3DTOP_TO_STR_CASE(n) case D3DTOP_##n: return #n | |||
const char *nine_D3DTOP_to_str(D3DTEXTUREOP top) | |||
{ | |||
switch (top) { | |||
D3DTOP_TO_STR_CASE(DISABLE); | |||
D3DTOP_TO_STR_CASE(SELECTARG1); | |||
D3DTOP_TO_STR_CASE(SELECTARG2); | |||
D3DTOP_TO_STR_CASE(MODULATE); | |||
D3DTOP_TO_STR_CASE(MODULATE2X); | |||
D3DTOP_TO_STR_CASE(MODULATE4X); | |||
D3DTOP_TO_STR_CASE(ADD); | |||
D3DTOP_TO_STR_CASE(ADDSIGNED); | |||
D3DTOP_TO_STR_CASE(ADDSIGNED2X); | |||
D3DTOP_TO_STR_CASE(SUBTRACT); | |||
D3DTOP_TO_STR_CASE(ADDSMOOTH); | |||
D3DTOP_TO_STR_CASE(BLENDDIFFUSEALPHA); | |||
D3DTOP_TO_STR_CASE(BLENDTEXTUREALPHA); | |||
D3DTOP_TO_STR_CASE(BLENDFACTORALPHA); | |||
D3DTOP_TO_STR_CASE(BLENDTEXTUREALPHAPM); | |||
D3DTOP_TO_STR_CASE(BLENDCURRENTALPHA); | |||
D3DTOP_TO_STR_CASE(PREMODULATE); | |||
D3DTOP_TO_STR_CASE(MODULATEALPHA_ADDCOLOR); | |||
D3DTOP_TO_STR_CASE(MODULATECOLOR_ADDALPHA); | |||
D3DTOP_TO_STR_CASE(MODULATEINVALPHA_ADDCOLOR); | |||
D3DTOP_TO_STR_CASE(MODULATEINVCOLOR_ADDALPHA); | |||
D3DTOP_TO_STR_CASE(BUMPENVMAP); | |||
D3DTOP_TO_STR_CASE(BUMPENVMAPLUMINANCE); | |||
D3DTOP_TO_STR_CASE(DOTPRODUCT3); | |||
D3DTOP_TO_STR_CASE(MULTIPLYADD); | |||
D3DTOP_TO_STR_CASE(LERP); | |||
default: | |||
return "(D3DTOP_?)"; | |||
} | |||
} | |||
static const char * | |||
nine_D3DLIGHTTYPE_to_str(D3DLIGHTTYPE type) | |||
{ | |||
switch (type) { | |||
case D3DLIGHT_POINT: return "POINT"; | |||
case D3DLIGHT_SPOT: return "SPOT"; | |||
case D3DLIGHT_DIRECTIONAL: return "DIRECTIONAL"; | |||
default: | |||
return "(D3DLIGHT_?)"; | |||
} | |||
} | |||
static const char * | |||
nine_D3DTA_to_str(DWORD value) | |||
{ | |||
switch (value & D3DTA_SELECTMASK) { | |||
case D3DTA_DIFFUSE: return "DIFFUSE"; | |||
case D3DTA_CURRENT: return "CURRENT"; | |||
case D3DTA_TEXTURE: return "TEXTURE"; | |||
case D3DTA_TFACTOR: return "TFACTOR"; | |||
case D3DTA_SPECULAR: return "SPECULAR"; | |||
case D3DTA_TEMP: return "TEMP"; | |||
case D3DTA_CONSTANT: return "CONSTANT"; | |||
default: | |||
return "(D3DTA_?)"; | |||
} | |||
} | |||
static const char * | |||
nine_D3DTSS_TCI_to_str(DWORD value) | |||
{ | |||
switch (value & 0xf0000) { | |||
case D3DTSS_TCI_PASSTHRU: return "PASSTHRU"; | |||
case D3DTSS_TCI_CAMERASPACENORMAL: return "CAMERASPACENORMAL"; | |||
case D3DTSS_TCI_CAMERASPACEPOSITION: return "CAMERASPACEPOSITION"; | |||
case D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR: | |||
return "CAMERASPACEREFLECTIONVECTOR"; | |||
case D3DTSS_TCI_SPHEREMAP: return "SPHEREMAP"; | |||
default: | |||
return "(D3DTSS_TCI_?)"; | |||
} | |||
} | |||
static const char * | |||
nine_D3DTTFF_to_str(DWORD value) | |||
{ | |||
switch (value) { | |||
case D3DTTFF_DISABLE: return "DISABLE"; | |||
case D3DTTFF_COUNT1: return "COUNT1"; | |||
case D3DTTFF_COUNT2: return "COUNT2"; | |||
case D3DTTFF_COUNT3: return "COUNT3"; | |||
case D3DTTFF_COUNT4: return "COUNT4"; | |||
case D3DTTFF_PROJECTED: return "PROJECTED"; | |||
default: | |||
return "(D3DTTFF_?)"; | |||
} | |||
} | |||
void | |||
nine_dump_D3DLIGHT9(unsigned ch, const D3DLIGHT9 *lit) | |||
{ | |||
DBG_FLAG(ch, "D3DLIGHT9(%p):\n" | |||
"Type: %s\n" | |||
"Diffuse: (%f %f %f %f)\n" | |||
"Specular: (%f %f %f %f)\n" | |||
"Ambient: (%f %f %f %f)\n" | |||
"Position: (%f %f %f)\n" | |||
"Direction: (%f %f %f)\n" | |||
"Range: %f\n" | |||
"Falloff: %f\n" | |||
"Attenuation: %f + %f * d + %f * d^2\n" | |||
"Theta: %f deg\n" | |||
"Phi: %f deg\n", lit, | |||
nine_D3DLIGHTTYPE_to_str(lit->Type), | |||
lit->Diffuse.r,lit->Diffuse.r,lit->Diffuse.g,lit->Diffuse.a, | |||
lit->Specular.r,lit->Specular.r,lit->Specular.g,lit->Specular.a, | |||
lit->Ambient.r,lit->Ambient.r,lit->Ambient.g,lit->Ambient.a, | |||
lit->Position.x,lit->Position.y,lit->Position.z, | |||
lit->Direction.x,lit->Direction.y,lit->Direction.z, | |||
lit->Range,lit->Falloff, | |||
lit->Attenuation0,lit->Attenuation1,lit->Attenuation2, | |||
lit->Theta * 360.0f / M_PI,lit->Phi * 360.0f / M_PI); | |||
} | |||
void | |||
nine_dump_D3DMATERIAL9(unsigned ch, const D3DMATERIAL9 *mat) | |||
{ | |||
DBG_FLAG(ch, "D3DMATERIAL9(%p):\n" | |||
"Diffuse: (%f %f %f %f)\n" | |||
"Specular: (%f %f %f %f)\n" | |||
"Ambient: (%f %f %f %f)\n" | |||
"Emissive: (%f %f %f %f)\n" | |||
"Power: %f\n", mat, | |||
mat->Diffuse.r,mat->Diffuse.r,mat->Diffuse.g,mat->Diffuse.a, | |||
mat->Specular.r,mat->Specular.r,mat->Specular.g,mat->Specular.a, | |||
mat->Ambient.r,mat->Ambient.r,mat->Ambient.g,mat->Ambient.a, | |||
mat->Emissive.r,mat->Emissive.r,mat->Emissive.g,mat->Emissive.a, | |||
mat->Power); | |||
} | |||
void | |||
nine_dump_D3DTSS_value(unsigned ch, D3DTEXTURESTAGESTATETYPE type, DWORD value) | |||
{ | |||
float rgba[4]; | |||
switch (type) { | |||
case D3DTSS_COLOROP: | |||
case D3DTSS_ALPHAOP: | |||
DBG_FLAG(ch, "D3DTSS_%s = %s\n", | |||
nine_D3DTSS_to_str(type), nine_D3DTOP_to_str(value)); | |||
break; | |||
case D3DTSS_COLORARG0: | |||
case D3DTSS_COLORARG1: | |||
case D3DTSS_COLORARG2: | |||
case D3DTSS_ALPHAARG0: | |||
case D3DTSS_ALPHAARG1: | |||
case D3DTSS_ALPHAARG2: | |||
case D3DTSS_RESULTARG: | |||
DBG_FLAG(ch, "D3DTSS_%s = %s%s%s\n", | |||
nine_D3DTSS_to_str(type), | |||
(value & D3DTA_COMPLEMENT) ? "COMPLEMENT " : "", | |||
(value & D3DTA_ALPHAREPLICATE) ? "ALPHAREPLICATE " : "", | |||
nine_D3DTA_to_str(value)); | |||
break; | |||
case D3DTSS_BUMPENVMAT00: | |||
case D3DTSS_BUMPENVMAT01: | |||
case D3DTSS_BUMPENVMAT10: | |||
case D3DTSS_BUMPENVMAT11: | |||
case D3DTSS_BUMPENVLSCALE: | |||
case D3DTSS_BUMPENVLOFFSET: | |||
DBG_FLAG(ch, "D3DTSS_%s = %f\n", | |||
nine_D3DTSS_to_str(type), asfloat(value)); | |||
break; | |||
case D3DTSS_TEXCOORDINDEX: | |||
DBG_FLAG(ch, "D3DTSS_TEXCOORDINDEX = %s %u\n", | |||
nine_D3DTSS_TCI_to_str(value), | |||
value & 0xffff); | |||
break; | |||
case D3DTSS_TEXTURETRANSFORMFLAGS: | |||
DBG_FLAG(ch, "D3DTSS_TEXTURETRANSFORMFLAGS = %s\n", | |||
nine_D3DTTFF_to_str(value)); | |||
break; | |||
case D3DTSS_CONSTANT: | |||
d3dcolor_to_rgba(rgba, value); | |||
DBG_FLAG(ch, "D3DTSS_CONSTANT = %f %f %f %F\n", | |||
rgba[0],rgba[1],rgba[2],rgba[3]); | |||
break; | |||
default: | |||
DBG_FLAG(ch, "D3DTSS_? = 0x%08x\n", value); | |||
break; | |||
} | |||
} | |||
void | |||
nine_dump_D3DADAPTER_IDENTIFIER9(unsigned ch, const D3DADAPTER_IDENTIFIER9 *id) | |||
{ | |||
DBG_FLAG(ch, "D3DADAPTER_IDENTIFIER9(%p):\n" | |||
"Driver: %s\n" | |||
"Description: %s\n" | |||
"DeviceName: %s\n" | |||
"DriverVersion: %08x.%08x\n" | |||
"VendorId: %x\n" | |||
"DeviceId: %x\n" | |||
"SubSysId: %x\n" | |||
"Revision: %u\n" | |||
"GUID: %08x.%04x.%04x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x\n" | |||
"WHQLLevel: %u\n", id, id->Driver, id->Description, | |||
id->DeviceName, | |||
id->DriverVersionLowPart, id->DriverVersionHighPart, | |||
id->VendorId, id->DeviceId, id->SubSysId, | |||
id->Revision, | |||
id->DeviceIdentifier.Data1, | |||
id->DeviceIdentifier.Data2, | |||
id->DeviceIdentifier.Data3, | |||
id->DeviceIdentifier.Data4[0], | |||
id->DeviceIdentifier.Data4[1], | |||
id->DeviceIdentifier.Data4[2], | |||
id->DeviceIdentifier.Data4[3], | |||
id->DeviceIdentifier.Data4[4], | |||
id->DeviceIdentifier.Data4[5], | |||
id->DeviceIdentifier.Data4[6], | |||
id->DeviceIdentifier.Data4[7], | |||
id->WHQLLevel); | |||
} | |||
#define C2S(args...) p += snprintf(&s[p],c-p,args) | |||
#define CAP_CASE(m,p,n) \ | |||
do { \ | |||
if (caps->m & p##_##n) \ | |||
C2S(" "#n); \ | |||
else \ | |||
C2S(" ("#n")"); \ | |||
} while(0) | |||
void | |||
nine_dump_D3DCAPS9(unsigned ch, const D3DCAPS9 *caps) | |||
{ | |||
const int c = 1 << 17; | |||
int p = 0; | |||
char *s = (char *)MALLOC(c); | |||
if (!s) { | |||
DBG_FLAG(ch, "D3DCAPS9(%p): (out of memory)\n", caps); | |||
return; | |||
} | |||
C2S("DeviceType: %s\n", nine_D3DDEVTYPE_to_str(caps->DeviceType)); | |||
C2S("AdapterOrdinal: %u\nCaps:", caps->AdapterOrdinal); | |||
if (caps->Caps & 0x20000) | |||
C2S(" READ_SCANLINE"); | |||
if (caps->Caps & ~0x20000) | |||
C2S(" %x", caps->Caps & ~0x20000); | |||
C2S("\nCaps2:"); | |||
CAP_CASE(Caps2, D3DCAPS2, CANAUTOGENMIPMAP); | |||
CAP_CASE(Caps2, D3DCAPS2, CANCALIBRATEGAMMA); | |||
CAP_CASE(Caps2, D3DCAPS2, CANSHARERESOURCE); | |||
CAP_CASE(Caps2, D3DCAPS2, CANMANAGERESOURCE); | |||
CAP_CASE(Caps2, D3DCAPS2, DYNAMICTEXTURES); | |||
CAP_CASE(Caps2, D3DCAPS2, FULLSCREENGAMMA); | |||
C2S("\nCaps3:"); | |||
CAP_CASE(Caps3, D3DCAPS3, ALPHA_FULLSCREEN_FLIP_OR_DISCARD); | |||
CAP_CASE(Caps3, D3DCAPS3, COPY_TO_VIDMEM); | |||
CAP_CASE(Caps3, D3DCAPS3, COPY_TO_SYSTEMMEM); | |||
CAP_CASE(Caps3, D3DCAPS3, DXVAHD); | |||
CAP_CASE(Caps3, D3DCAPS3, LINEAR_TO_SRGB_PRESENTATION); | |||
C2S("\nPresentationIntervals:"); | |||
CAP_CASE(PresentationIntervals, D3DPRESENT_INTERVAL, ONE); | |||
CAP_CASE(PresentationIntervals, D3DPRESENT_INTERVAL, TWO); | |||
CAP_CASE(PresentationIntervals, D3DPRESENT_INTERVAL, THREE); | |||
CAP_CASE(PresentationIntervals, D3DPRESENT_INTERVAL, FOUR); | |||
CAP_CASE(PresentationIntervals, D3DPRESENT_INTERVAL, IMMEDIATE); | |||
C2S("\nCursorCaps:"); | |||
CAP_CASE(CursorCaps, D3DCURSORCAPS, COLOR); | |||
CAP_CASE(CursorCaps, D3DCURSORCAPS, LOWRES); | |||
C2S("\nDevCaps:"); | |||
CAP_CASE(DevCaps, D3DDEVCAPS, CANBLTSYSTONONLOCAL); | |||
CAP_CASE(DevCaps, D3DDEVCAPS, CANRENDERAFTERFLIP); | |||
CAP_CASE(DevCaps, D3DDEVCAPS, DRAWPRIMITIVES2); | |||
CAP_CASE(DevCaps, D3DDEVCAPS, DRAWPRIMITIVES2EX); | |||
CAP_CASE(DevCaps, D3DDEVCAPS, DRAWPRIMTLVERTEX); | |||
CAP_CASE(DevCaps, D3DDEVCAPS, EXECUTESYSTEMMEMORY); | |||
CAP_CASE(DevCaps, D3DDEVCAPS, EXECUTEVIDEOMEMORY); | |||
CAP_CASE(DevCaps, D3DDEVCAPS, HWRASTERIZATION); | |||
CAP_CASE(DevCaps, D3DDEVCAPS, HWTRANSFORMANDLIGHT); | |||
CAP_CASE(DevCaps, D3DDEVCAPS, NPATCHES); | |||
CAP_CASE(DevCaps, D3DDEVCAPS, PUREDEVICE); | |||
CAP_CASE(DevCaps, D3DDEVCAPS, QUINTICRTPATCHES); | |||
CAP_CASE(DevCaps, D3DDEVCAPS, RTPATCHES); | |||
CAP_CASE(DevCaps, D3DDEVCAPS, RTPATCHHANDLEZERO); | |||
CAP_CASE(DevCaps, D3DDEVCAPS, SEPARATETEXTUREMEMORIES); | |||
CAP_CASE(DevCaps, D3DDEVCAPS, TEXTURENONLOCALVIDMEM); | |||
CAP_CASE(DevCaps, D3DDEVCAPS, TEXTURESYSTEMMEMORY); | |||
CAP_CASE(DevCaps, D3DDEVCAPS, TEXTUREVIDEOMEMORY); | |||
CAP_CASE(DevCaps, D3DDEVCAPS, TLVERTEXSYSTEMMEMORY); | |||
CAP_CASE(DevCaps, D3DDEVCAPS, TLVERTEXVIDEOMEMORY); | |||
C2S("\nPrimitiveMiscCaps:"); | |||
CAP_CASE(PrimitiveMiscCaps, D3DPMISCCAPS, MASKZ); | |||
CAP_CASE(PrimitiveMiscCaps, D3DPMISCCAPS, CULLNONE); | |||
CAP_CASE(PrimitiveMiscCaps, D3DPMISCCAPS, CULLCW); | |||
CAP_CASE(PrimitiveMiscCaps, D3DPMISCCAPS, CULLCCW); | |||
CAP_CASE(PrimitiveMiscCaps, D3DPMISCCAPS, COLORWRITEENABLE); | |||
CAP_CASE(PrimitiveMiscCaps, D3DPMISCCAPS, CLIPPLANESCALEDPOINTS); | |||
CAP_CASE(PrimitiveMiscCaps, D3DPMISCCAPS, CLIPTLVERTS); | |||
CAP_CASE(PrimitiveMiscCaps, D3DPMISCCAPS, TSSARGTEMP); | |||
CAP_CASE(PrimitiveMiscCaps, D3DPMISCCAPS, BLENDOP); | |||
CAP_CASE(PrimitiveMiscCaps, D3DPMISCCAPS, NULLREFERENCE); | |||
CAP_CASE(PrimitiveMiscCaps, D3DPMISCCAPS, INDEPENDENTWRITEMASKS); | |||
CAP_CASE(PrimitiveMiscCaps, D3DPMISCCAPS, PERSTAGECONSTANT); | |||
CAP_CASE(PrimitiveMiscCaps, D3DPMISCCAPS, POSTBLENDSRGBCONVERT); | |||
CAP_CASE(PrimitiveMiscCaps, D3DPMISCCAPS, FOGANDSPECULARALPHA); | |||
CAP_CASE(PrimitiveMiscCaps, D3DPMISCCAPS, SEPARATEALPHABLEND); | |||
CAP_CASE(PrimitiveMiscCaps, D3DPMISCCAPS, MRTINDEPENDENTBITDEPTHS); | |||
CAP_CASE(PrimitiveMiscCaps, D3DPMISCCAPS, MRTPOSTPIXELSHADERBLENDING); | |||
CAP_CASE(PrimitiveMiscCaps, D3DPMISCCAPS, FOGVERTEXCLAMPED); | |||
C2S("\nRasterCaps:"); | |||
CAP_CASE(RasterCaps, D3DPRASTERCAPS, ANISOTROPY); | |||
CAP_CASE(RasterCaps, D3DPRASTERCAPS, COLORPERSPECTIVE); | |||
CAP_CASE(RasterCaps, D3DPRASTERCAPS, DITHER); | |||
CAP_CASE(RasterCaps, D3DPRASTERCAPS, DEPTHBIAS); | |||
CAP_CASE(RasterCaps, D3DPRASTERCAPS, FOGRANGE); | |||
CAP_CASE(RasterCaps, D3DPRASTERCAPS, FOGTABLE); | |||
CAP_CASE(RasterCaps, D3DPRASTERCAPS, FOGVERTEX); | |||
CAP_CASE(RasterCaps, D3DPRASTERCAPS, MIPMAPLODBIAS); | |||
CAP_CASE(RasterCaps, D3DPRASTERCAPS, MULTISAMPLE_TOGGLE); | |||
CAP_CASE(RasterCaps, D3DPRASTERCAPS, SCISSORTEST); | |||
CAP_CASE(RasterCaps, D3DPRASTERCAPS, SLOPESCALEDEPTHBIAS); | |||
CAP_CASE(RasterCaps, D3DPRASTERCAPS, WBUFFER); | |||
CAP_CASE(RasterCaps, D3DPRASTERCAPS, WFOG); | |||
CAP_CASE(RasterCaps, D3DPRASTERCAPS, ZBUFFERLESSHSR); | |||
CAP_CASE(RasterCaps, D3DPRASTERCAPS, ZFOG); | |||
CAP_CASE(RasterCaps, D3DPRASTERCAPS, ZTEST); | |||
C2S("\nZCmpCaps:"); | |||
CAP_CASE(ZCmpCaps, D3DPCMPCAPS, ALWAYS); | |||
CAP_CASE(ZCmpCaps, D3DPCMPCAPS, EQUAL); | |||
CAP_CASE(ZCmpCaps, D3DPCMPCAPS, GREATER); | |||
CAP_CASE(ZCmpCaps, D3DPCMPCAPS, GREATEREQUAL); | |||
CAP_CASE(ZCmpCaps, D3DPCMPCAPS, LESS); | |||
CAP_CASE(ZCmpCaps, D3DPCMPCAPS, LESSEQUAL); | |||
CAP_CASE(ZCmpCaps, D3DPCMPCAPS, NEVER); | |||
CAP_CASE(ZCmpCaps, D3DPCMPCAPS, NOTEQUAL); | |||
C2S("\nSrcBlendCaps"); | |||
CAP_CASE(SrcBlendCaps, D3DPBLENDCAPS, BLENDFACTOR); | |||
CAP_CASE(SrcBlendCaps, D3DPBLENDCAPS, BOTHINVSRCALPHA); | |||
CAP_CASE(SrcBlendCaps, D3DPBLENDCAPS, BOTHSRCALPHA); | |||
CAP_CASE(SrcBlendCaps, D3DPBLENDCAPS, DESTALPHA); | |||
CAP_CASE(SrcBlendCaps, D3DPBLENDCAPS, DESTCOLOR); | |||
CAP_CASE(SrcBlendCaps, D3DPBLENDCAPS, INVDESTALPHA); | |||
CAP_CASE(SrcBlendCaps, D3DPBLENDCAPS, INVDESTCOLOR); | |||
CAP_CASE(SrcBlendCaps, D3DPBLENDCAPS, INVSRCALPHA); | |||
CAP_CASE(SrcBlendCaps, D3DPBLENDCAPS, INVSRCCOLOR); | |||
CAP_CASE(SrcBlendCaps, D3DPBLENDCAPS, INVSRCCOLOR2); | |||
CAP_CASE(SrcBlendCaps, D3DPBLENDCAPS, ONE); | |||
CAP_CASE(SrcBlendCaps, D3DPBLENDCAPS, SRCALPHA); | |||
CAP_CASE(SrcBlendCaps, D3DPBLENDCAPS, SRCALPHASAT); | |||
CAP_CASE(SrcBlendCaps, D3DPBLENDCAPS, SRCCOLOR); | |||
CAP_CASE(SrcBlendCaps, D3DPBLENDCAPS, SRCCOLOR2); | |||
CAP_CASE(SrcBlendCaps, D3DPBLENDCAPS, ZERO); | |||
C2S("\nDestBlendCaps"); | |||
CAP_CASE(DestBlendCaps, D3DPBLENDCAPS, BLENDFACTOR); | |||
CAP_CASE(DestBlendCaps, D3DPBLENDCAPS, BOTHINVSRCALPHA); | |||
CAP_CASE(DestBlendCaps, D3DPBLENDCAPS, BOTHSRCALPHA); | |||
CAP_CASE(DestBlendCaps, D3DPBLENDCAPS, DESTALPHA); | |||
CAP_CASE(DestBlendCaps, D3DPBLENDCAPS, DESTCOLOR); | |||
CAP_CASE(DestBlendCaps, D3DPBLENDCAPS, INVDESTALPHA); | |||
CAP_CASE(DestBlendCaps, D3DPBLENDCAPS, INVDESTCOLOR); | |||
CAP_CASE(DestBlendCaps, D3DPBLENDCAPS, INVSRCALPHA); | |||
CAP_CASE(DestBlendCaps, D3DPBLENDCAPS, INVSRCCOLOR); | |||
CAP_CASE(DestBlendCaps, D3DPBLENDCAPS, INVSRCCOLOR2); | |||
CAP_CASE(DestBlendCaps, D3DPBLENDCAPS, ONE); | |||
CAP_CASE(DestBlendCaps, D3DPBLENDCAPS, SRCALPHA); | |||
CAP_CASE(DestBlendCaps, D3DPBLENDCAPS, SRCALPHASAT); | |||
CAP_CASE(DestBlendCaps, D3DPBLENDCAPS, SRCCOLOR); | |||
CAP_CASE(DestBlendCaps, D3DPBLENDCAPS, SRCCOLOR2); | |||
CAP_CASE(DestBlendCaps, D3DPBLENDCAPS, ZERO); | |||
C2S("\nAlphaCmpCaps:"); | |||
CAP_CASE(AlphaCmpCaps, D3DPCMPCAPS, ALWAYS); | |||
CAP_CASE(AlphaCmpCaps, D3DPCMPCAPS, EQUAL); | |||
CAP_CASE(AlphaCmpCaps, D3DPCMPCAPS, GREATER); | |||
CAP_CASE(AlphaCmpCaps, D3DPCMPCAPS, GREATEREQUAL); | |||
CAP_CASE(AlphaCmpCaps, D3DPCMPCAPS, LESS); | |||
CAP_CASE(AlphaCmpCaps, D3DPCMPCAPS, LESSEQUAL); | |||
CAP_CASE(AlphaCmpCaps, D3DPCMPCAPS, NEVER); | |||
CAP_CASE(AlphaCmpCaps, D3DPCMPCAPS, NOTEQUAL); | |||
C2S("\nShadeCaps:"); | |||
CAP_CASE(ShadeCaps, D3DPSHADECAPS, ALPHAGOURAUDBLEND); | |||
CAP_CASE(ShadeCaps, D3DPSHADECAPS, COLORGOURAUDRGB); | |||
CAP_CASE(ShadeCaps, D3DPSHADECAPS, FOGGOURAUD); | |||
CAP_CASE(ShadeCaps, D3DPSHADECAPS, SPECULARGOURAUDRGB); | |||
C2S("\nTextureCaps:"); | |||
CAP_CASE(TextureCaps, D3DPTEXTURECAPS, ALPHA); | |||
CAP_CASE(TextureCaps, D3DPTEXTURECAPS, ALPHAPALETTE); | |||
CAP_CASE(TextureCaps, D3DPTEXTURECAPS, CUBEMAP); | |||
CAP_CASE(TextureCaps, D3DPTEXTURECAPS, CUBEMAP_POW2); | |||
CAP_CASE(TextureCaps, D3DPTEXTURECAPS, MIPCUBEMAP); | |||
CAP_CASE(TextureCaps, D3DPTEXTURECAPS, MIPMAP); | |||
CAP_CASE(TextureCaps, D3DPTEXTURECAPS, MIPVOLUMEMAP); | |||
CAP_CASE(TextureCaps, D3DPTEXTURECAPS, NONPOW2CONDITIONAL); | |||
CAP_CASE(TextureCaps, D3DPTEXTURECAPS, NOPROJECTEDBUMPENV); | |||
CAP_CASE(TextureCaps, D3DPTEXTURECAPS, PERSPECTIVE); | |||
CAP_CASE(TextureCaps, D3DPTEXTURECAPS, POW2); | |||
CAP_CASE(TextureCaps, D3DPTEXTURECAPS, PROJECTED); | |||
CAP_CASE(TextureCaps, D3DPTEXTURECAPS, SQUAREONLY); | |||
CAP_CASE(TextureCaps, D3DPTEXTURECAPS, TEXREPEATNOTSCALEDBYSIZE); | |||
CAP_CASE(TextureCaps, D3DPTEXTURECAPS, VOLUMEMAP); | |||
CAP_CASE(TextureCaps, D3DPTEXTURECAPS, VOLUMEMAP_POW2); | |||
C2S("\nTextureFilterCaps:"); | |||
/* CAP_CASE(TextureFilterCaps, D3DPTFILTERCAPS, CONVOLUTIONMONO); */ | |||
CAP_CASE(TextureFilterCaps, D3DPTFILTERCAPS, MAGFPOINT); | |||
CAP_CASE(TextureFilterCaps, D3DPTFILTERCAPS, MAGFLINEAR); | |||
CAP_CASE(TextureFilterCaps, D3DPTFILTERCAPS, MAGFANISOTROPIC); | |||
CAP_CASE(TextureFilterCaps, D3DPTFILTERCAPS, MAGFPYRAMIDALQUAD); | |||
CAP_CASE(TextureFilterCaps, D3DPTFILTERCAPS, MAGFGAUSSIANQUAD); | |||
CAP_CASE(TextureFilterCaps, D3DPTFILTERCAPS, MINFPOINT); | |||
CAP_CASE(TextureFilterCaps, D3DPTFILTERCAPS, MINFLINEAR); | |||
CAP_CASE(TextureFilterCaps, D3DPTFILTERCAPS, MINFANISOTROPIC); | |||
CAP_CASE(TextureFilterCaps, D3DPTFILTERCAPS, MINFPYRAMIDALQUAD); | |||
CAP_CASE(TextureFilterCaps, D3DPTFILTERCAPS, MINFGAUSSIANQUAD); | |||
CAP_CASE(TextureFilterCaps, D3DPTFILTERCAPS, MIPFPOINT); | |||
CAP_CASE(TextureFilterCaps, D3DPTFILTERCAPS, MIPFLINEAR); | |||
C2S("\nCubeTextureFilterCaps:"); | |||
/* CAP_CASE(CubeTextureFilterCaps, D3DPTFILTERCAPS, CONVOLUTIONMONO); */ | |||
CAP_CASE(CubeTextureFilterCaps, D3DPTFILTERCAPS, MAGFPOINT); | |||
CAP_CASE(CubeTextureFilterCaps, D3DPTFILTERCAPS, MAGFLINEAR); | |||
CAP_CASE(CubeTextureFilterCaps, D3DPTFILTERCAPS, MAGFANISOTROPIC); | |||
CAP_CASE(CubeTextureFilterCaps, D3DPTFILTERCAPS, MAGFPYRAMIDALQUAD); | |||
CAP_CASE(CubeTextureFilterCaps, D3DPTFILTERCAPS, MAGFGAUSSIANQUAD); | |||
CAP_CASE(CubeTextureFilterCaps, D3DPTFILTERCAPS, MINFPOINT); | |||
CAP_CASE(CubeTextureFilterCaps, D3DPTFILTERCAPS, MINFLINEAR); | |||
CAP_CASE(CubeTextureFilterCaps, D3DPTFILTERCAPS, MINFANISOTROPIC); | |||
CAP_CASE(CubeTextureFilterCaps, D3DPTFILTERCAPS, MINFPYRAMIDALQUAD); | |||
CAP_CASE(CubeTextureFilterCaps, D3DPTFILTERCAPS, MINFGAUSSIANQUAD); | |||
CAP_CASE(CubeTextureFilterCaps, D3DPTFILTERCAPS, MIPFPOINT); | |||
CAP_CASE(CubeTextureFilterCaps, D3DPTFILTERCAPS, MIPFLINEAR); | |||
C2S("\nVolumeTextureFilterCaps:"); | |||
/* CAP_CASE(VolumeTextureFilterCaps, D3DPTFILTERCAPS, CONVOLUTIONMONO); */ | |||
CAP_CASE(VolumeTextureFilterCaps, D3DPTFILTERCAPS, MAGFPOINT); | |||
CAP_CASE(VolumeTextureFilterCaps, D3DPTFILTERCAPS, MAGFLINEAR); | |||
CAP_CASE(VolumeTextureFilterCaps, D3DPTFILTERCAPS, MAGFANISOTROPIC); | |||
CAP_CASE(VolumeTextureFilterCaps, D3DPTFILTERCAPS, MAGFPYRAMIDALQUAD); | |||
CAP_CASE(VolumeTextureFilterCaps, D3DPTFILTERCAPS, MAGFGAUSSIANQUAD); | |||
CAP_CASE(VolumeTextureFilterCaps, D3DPTFILTERCAPS, MINFPOINT); | |||
CAP_CASE(VolumeTextureFilterCaps, D3DPTFILTERCAPS, MINFLINEAR); | |||
CAP_CASE(VolumeTextureFilterCaps, D3DPTFILTERCAPS, MINFANISOTROPIC); | |||
CAP_CASE(VolumeTextureFilterCaps, D3DPTFILTERCAPS, MINFPYRAMIDALQUAD); | |||
CAP_CASE(VolumeTextureFilterCaps, D3DPTFILTERCAPS, MINFGAUSSIANQUAD); | |||
CAP_CASE(VolumeTextureFilterCaps, D3DPTFILTERCAPS, MIPFPOINT); | |||
CAP_CASE(VolumeTextureFilterCaps, D3DPTFILTERCAPS, MIPFLINEAR); | |||
C2S("\nTextureAddressCaps:"); | |||
CAP_CASE(TextureAddressCaps, D3DPTADDRESSCAPS, BORDER); | |||
CAP_CASE(TextureAddressCaps, D3DPTADDRESSCAPS, CLAMP); | |||
CAP_CASE(TextureAddressCaps, D3DPTADDRESSCAPS, INDEPENDENTUV); | |||
CAP_CASE(TextureAddressCaps, D3DPTADDRESSCAPS, MIRROR); | |||
CAP_CASE(TextureAddressCaps, D3DPTADDRESSCAPS, MIRRORONCE); | |||
CAP_CASE(TextureAddressCaps, D3DPTADDRESSCAPS, WRAP); | |||
C2S("\nVolumeTextureAddressCaps:"); | |||
CAP_CASE(VolumeTextureAddressCaps, D3DPTADDRESSCAPS, BORDER); | |||
CAP_CASE(VolumeTextureAddressCaps, D3DPTADDRESSCAPS, CLAMP); | |||
CAP_CASE(VolumeTextureAddressCaps, D3DPTADDRESSCAPS, INDEPENDENTUV); | |||
CAP_CASE(VolumeTextureAddressCaps, D3DPTADDRESSCAPS, MIRROR); | |||
CAP_CASE(VolumeTextureAddressCaps, D3DPTADDRESSCAPS, MIRRORONCE); | |||
CAP_CASE(VolumeTextureAddressCaps, D3DPTADDRESSCAPS, WRAP); | |||
C2S("\nLineCaps:"); | |||
CAP_CASE(LineCaps, D3DLINECAPS, ALPHACMP); | |||
CAP_CASE(LineCaps, D3DLINECAPS, ANTIALIAS); | |||
CAP_CASE(LineCaps, D3DLINECAPS, BLEND); | |||
CAP_CASE(LineCaps, D3DLINECAPS, FOG); | |||
CAP_CASE(LineCaps, D3DLINECAPS, TEXTURE); | |||
CAP_CASE(LineCaps, D3DLINECAPS, ZTEST); | |||
C2S("\nMaxTextureWidth: %u", caps->MaxTextureWidth); | |||
C2S("\nMaxTextureHeight: %u", caps->MaxTextureHeight); | |||
C2S("\nMaxVolumeExtent: %u", caps->MaxVolumeExtent); | |||
C2S("\nMaxTextureRepeat: %u", caps->MaxTextureRepeat); | |||
C2S("\nMaxTextureAspectRatio: %u", caps->MaxTextureAspectRatio); | |||
C2S("\nMaxAnisotropy: %u", caps->MaxAnisotropy); | |||
C2S("\nMaxVertexW: %f", caps->MaxVertexW); | |||
C2S("\nGuardBandLef,Top,Right,Bottom: %f %f %f %f", | |||
caps->GuardBandLeft, caps->GuardBandTop, | |||
caps->GuardBandRight, caps->GuardBandBottom); | |||
C2S("\nExtentsAdjust: %f", caps->ExtentsAdjust); | |||
C2S("\nStencilCaps:"); | |||
CAP_CASE(StencilCaps, D3DSTENCILCAPS, KEEP); | |||
CAP_CASE(StencilCaps, D3DSTENCILCAPS, ZERO); | |||
CAP_CASE(StencilCaps, D3DSTENCILCAPS, REPLACE); | |||
CAP_CASE(StencilCaps, D3DSTENCILCAPS, INCRSAT); | |||
CAP_CASE(StencilCaps, D3DSTENCILCAPS, DECRSAT); | |||
CAP_CASE(StencilCaps, D3DSTENCILCAPS, INVERT); | |||
CAP_CASE(StencilCaps, D3DSTENCILCAPS, INCR); | |||
CAP_CASE(StencilCaps, D3DSTENCILCAPS, DECR); | |||
CAP_CASE(StencilCaps, D3DSTENCILCAPS, TWOSIDED); | |||
C2S("\nFVFCaps:"); | |||
CAP_CASE(FVFCaps, D3DFVFCAPS, DONOTSTRIPELEMENTS); | |||
CAP_CASE(FVFCaps, D3DFVFCAPS, PSIZE); | |||
CAP_CASE(FVFCaps, D3DFVFCAPS, TEXCOORDCOUNTMASK); | |||
C2S("\nTextureOpCaps:"); | |||
CAP_CASE(TextureOpCaps, D3DTEXOPCAPS, ADD); | |||
CAP_CASE(TextureOpCaps, D3DTEXOPCAPS, ADDSIGNED); | |||
C2S(" ..."); | |||
C2S("\nMaxTextureBlendStages: %u", caps->MaxTextureBlendStages); | |||
C2S("\nMaxSimultaneousTextures: %u", caps->MaxTextureBlendStages); | |||
C2S("\nVertexProcessingCaps:"); | |||
CAP_CASE(VertexProcessingCaps, D3DVTXPCAPS, DIRECTIONALLIGHTS); | |||
CAP_CASE(VertexProcessingCaps, D3DVTXPCAPS, LOCALVIEWER); | |||
CAP_CASE(VertexProcessingCaps, D3DVTXPCAPS, MATERIALSOURCE7); | |||
CAP_CASE(VertexProcessingCaps, D3DVTXPCAPS, NO_TEXGEN_NONLOCALVIEWER); | |||
CAP_CASE(VertexProcessingCaps, D3DVTXPCAPS, POSITIONALLIGHTS); | |||
CAP_CASE(VertexProcessingCaps, D3DVTXPCAPS, TEXGEN); | |||
CAP_CASE(VertexProcessingCaps, D3DVTXPCAPS, TEXGEN_SPHEREMAP); | |||
CAP_CASE(VertexProcessingCaps, D3DVTXPCAPS, TWEENING); | |||
C2S("\nMaxActiveLights: %u", caps->MaxActiveLights); | |||
C2S("\nMaxUserClipPlanes: %u", caps->MaxUserClipPlanes); | |||
C2S("\nMaxVertexBlendMatrices: %u", caps->MaxVertexBlendMatrices); | |||
C2S("\nMaxVertexBlendMatrixIndex: %u", caps->MaxVertexBlendMatrixIndex); | |||
C2S("\nMaxPointSize: %f", caps->MaxPointSize); | |||
C2S("\nMaxPrimitiveCount: 0x%x", caps->MaxPrimitiveCount); | |||
C2S("\nMaxVertexIndex: 0x%x", caps->MaxVertexIndex); | |||
C2S("\nMaxStreams: %u", caps->MaxStreams); | |||
C2S("\nMaxStreamStride: 0x%x", caps->MaxStreamStride); | |||
C2S("\nVertexShaderVersion: %08x", caps->VertexShaderVersion); | |||
C2S("\nMaxVertexShaderConst: %u", caps->MaxVertexShaderConst); | |||
C2S("\nPixelShaderVersion: %08x", caps->PixelShaderVersion); | |||
C2S("\nPixelShader1xMaxValue: %f", caps->PixelShader1xMaxValue); | |||
DBG_FLAG(ch, "D3DCAPS9(%p) part 1:\n%s\n", caps, s); | |||
p = 0; | |||
C2S("DevCaps2:"); | |||
CAP_CASE(DevCaps2, D3DDEVCAPS2, ADAPTIVETESSRTPATCH); | |||
CAP_CASE(DevCaps2, D3DDEVCAPS2, ADAPTIVETESSNPATCH); | |||
CAP_CASE(DevCaps2, D3DDEVCAPS2, CAN_STRETCHRECT_FROM_TEXTURES); | |||
CAP_CASE(DevCaps2, D3DDEVCAPS2, DMAPNPATCH); | |||
CAP_CASE(DevCaps2, D3DDEVCAPS2, PRESAMPLEDDMAPNPATCH); | |||
CAP_CASE(DevCaps2, D3DDEVCAPS2, STREAMOFFSET); | |||
CAP_CASE(DevCaps2, D3DDEVCAPS2, VERTEXELEMENTSCANSHARESTREAMOFFSET); | |||
C2S("\nMasterAdapterOrdinal: %u", caps->MasterAdapterOrdinal); | |||
C2S("\nAdapterOrdinalInGroup: %u", caps->AdapterOrdinalInGroup); | |||
C2S("\nNumberOfAdaptersInGroup: %u", caps->NumberOfAdaptersInGroup); | |||
C2S("\nDeclTypes:"); | |||
CAP_CASE(DeclTypes, D3DDTCAPS, UBYTE4); | |||
CAP_CASE(DeclTypes, D3DDTCAPS, UBYTE4N); | |||
CAP_CASE(DeclTypes, D3DDTCAPS, SHORT2N); | |||
CAP_CASE(DeclTypes, D3DDTCAPS, SHORT4N); | |||
CAP_CASE(DeclTypes, D3DDTCAPS, USHORT2N); | |||
CAP_CASE(DeclTypes, D3DDTCAPS, USHORT4N); | |||
CAP_CASE(DeclTypes, D3DDTCAPS, UDEC3); | |||
CAP_CASE(DeclTypes, D3DDTCAPS, DEC3N); | |||
CAP_CASE(DeclTypes, D3DDTCAPS, FLOAT16_2); | |||
CAP_CASE(DeclTypes, D3DDTCAPS, FLOAT16_4); | |||
C2S("\nNumSimultaneousRTs: %u", caps->NumSimultaneousRTs); | |||
C2S("\nStretchRectFilterCaps:"); | |||
CAP_CASE(StretchRectFilterCaps, D3DPTFILTERCAPS, MINFPOINT); | |||
CAP_CASE(StretchRectFilterCaps, D3DPTFILTERCAPS, MINFLINEAR); | |||
CAP_CASE(StretchRectFilterCaps, D3DPTFILTERCAPS, MAGFPOINT); | |||
CAP_CASE(StretchRectFilterCaps, D3DPTFILTERCAPS, MAGFLINEAR); | |||
C2S("\nVS20Caps.Caps: Predication=%s", caps->VS20Caps.Caps ? "yes" : "no"); | |||
C2S("\nVS20Caps.DynamicFlowControlDepth: %u", caps->VS20Caps.DynamicFlowControlDepth); | |||
C2S("\nVS20Caps.NumTemps: %u", caps->VS20Caps.NumTemps); | |||
C2S("\nVS20Caps.StaticFlowControlDepth: %u", caps->VS20Caps.StaticFlowControlDepth); | |||
C2S("\nPS20Caps.Caps: Predication=%s", caps->VS20Caps.Caps ? "yes" : "no"); | |||
C2S("\nPS20Caps.DynamicFlowControlDepth: %u", caps->PS20Caps.DynamicFlowControlDepth); | |||
C2S("\nPS20Caps.NumTemps: %u", caps->PS20Caps.NumTemps); | |||
C2S("\nPS20Caps.StaticFlowControlDepth: %u", caps->PS20Caps.StaticFlowControlDepth); | |||
C2S("\nPS20Caps.NumInstructionSlots: %u", caps->PS20Caps.NumInstructionSlots); | |||
C2S("\nVertexTextureFilterCaps"); | |||
/* CAP_CASE(VertexTextureFilterCaps, D3DPTFILTERCAPS, CONVOLUTIONMONO); */ | |||
CAP_CASE(VertexTextureFilterCaps, D3DPTFILTERCAPS, MAGFPOINT); | |||
CAP_CASE(VertexTextureFilterCaps, D3DPTFILTERCAPS, MAGFLINEAR); | |||
CAP_CASE(VertexTextureFilterCaps, D3DPTFILTERCAPS, MAGFANISOTROPIC); | |||
CAP_CASE(VertexTextureFilterCaps, D3DPTFILTERCAPS, MAGFPYRAMIDALQUAD); | |||
CAP_CASE(VertexTextureFilterCaps, D3DPTFILTERCAPS, MAGFGAUSSIANQUAD); | |||
CAP_CASE(VertexTextureFilterCaps, D3DPTFILTERCAPS, MINFPOINT); | |||
CAP_CASE(VertexTextureFilterCaps, D3DPTFILTERCAPS, MINFLINEAR); | |||
CAP_CASE(VertexTextureFilterCaps, D3DPTFILTERCAPS, MINFANISOTROPIC); | |||
CAP_CASE(VertexTextureFilterCaps, D3DPTFILTERCAPS, MINFPYRAMIDALQUAD); | |||
CAP_CASE(VertexTextureFilterCaps, D3DPTFILTERCAPS, MINFGAUSSIANQUAD); | |||
CAP_CASE(VertexTextureFilterCaps, D3DPTFILTERCAPS, MIPFPOINT); | |||
CAP_CASE(VertexTextureFilterCaps, D3DPTFILTERCAPS, MIPFLINEAR); | |||
C2S("\nMaxVShaderInstructionsExecuted: %u", caps->MaxVShaderInstructionsExecuted); | |||
C2S("\nMaxPShaderInstructionsExecuted: %u", caps->MaxPShaderInstructionsExecuted); | |||
C2S("\nMaxVertexShader30InstructionSlots: %u >= 512", caps->MaxVertexShader30InstructionSlots); | |||
C2S("\nMaxPixelShader30InstructionSlots: %u >= 512", caps->MaxPixelShader30InstructionSlots); | |||
DBG_FLAG(ch, "D3DCAPS9(%p) part 2:\n%s\n", caps, s); | |||
FREE(s); | |||
} | |||
#endif /* DEBUG */ |
@@ -0,0 +1,52 @@ | |||
#ifndef _NINE_DUMP_H_ | |||
#define _NINE_DUMP_H_ | |||
#include "d3d9types.h" | |||
#include "d3d9caps.h" | |||
const char *nine_D3DDEVTYPE_to_str(D3DDEVTYPE); | |||
const char *nine_D3DQUERYTYPE_to_str(D3DQUERYTYPE); | |||
const char *nine_D3DTSS_to_str(D3DTEXTURESTAGESTATETYPE); | |||
const char *nine_D3DTOP_to_str(D3DTEXTUREOP); | |||
const char *nine_D3DPOOL_to_str(D3DPOOL); | |||
const char *nine_D3DRTYPE_to_str(D3DRESOURCETYPE); | |||
const char *nine_D3DUSAGE_to_str(DWORD); | |||
const char *nine_D3DPRESENTFLAG_to_str(DWORD); | |||
const char *nine_D3DLOCK_to_str(DWORD); | |||
const char *nine_D3DSAMP_to_str(DWORD); | |||
#ifdef DEBUG | |||
void | |||
nine_dump_D3DADAPTER_IDENTIFIER9(unsigned, const D3DADAPTER_IDENTIFIER9 *); | |||
void | |||
nine_dump_D3DCAPS9(unsigned, const D3DCAPS9 *); | |||
void | |||
nine_dump_D3DLIGHT9(unsigned, const D3DLIGHT9 *); | |||
void | |||
nine_dump_D3DMATERIAL9(unsigned, const D3DMATERIAL9 *); | |||
void | |||
nine_dump_D3DTSS_value(unsigned, D3DTEXTURESTAGESTATETYPE, DWORD); | |||
#else /* !DEBUG */ | |||
static INLINE void | |||
nine_dump_D3DADAPTER_IDENTIFIER9(unsigned ch, const D3DADAPTER_IDENTIFIER9 *id) | |||
{ } | |||
static INLINE void | |||
nine_dump_D3DCAPS9(unsigned ch, const D3DCAPS9 *caps) | |||
{ } | |||
static INLINE void | |||
nine_dump_D3DLIGHT9(unsigned ch, const D3DLIGHT9 *light) | |||
{ } | |||
static INLINE void | |||
nine_dump_D3DMATERIAL9(unsigned ch, const D3DMATERIAL9 *mat) | |||
{ } | |||
static INLINE void | |||
nine_dump_D3DTSS_value(unsigned ch, D3DTEXTURESTAGESTATETYPE tss, DWORD value) | |||
{ } | |||
#endif /* DEBUG */ | |||
#endif /* _NINE_DUMP_H_H_ */ |
@@ -0,0 +1,32 @@ | |||
#ifndef _NINE_FF_H_ | |||
#define _NINE_FF_H_ | |||
#include "device9.h" | |||
boolean nine_ff_init(struct NineDevice9 *); | |||
void nine_ff_fini(struct NineDevice9 *); | |||
void nine_ff_update(struct NineDevice9 *); | |||
void | |||
nine_d3d_matrix_matrix_mul(D3DMATRIX *, const D3DMATRIX *, const D3DMATRIX *); | |||
void | |||
nine_d3d_vector4_matrix_mul(D3DVECTOR *, const D3DVECTOR *, const D3DMATRIX *); | |||
void | |||
nine_d3d_vector3_matrix_mul(D3DVECTOR *, const D3DVECTOR *, const D3DMATRIX *); | |||
float | |||
nine_d3d_matrix_det(const D3DMATRIX *); | |||
void | |||
nine_d3d_matrix_inverse(D3DMATRIX *, const D3DMATRIX *); | |||
void | |||
nine_d3d_matrix_inverse_3x3(D3DMATRIX *, const D3DMATRIX *); | |||
void | |||
nine_d3d_matrix_transpose(D3DMATRIX *, const D3DMATRIX *); | |||
#endif /* _NINE_FF_H_ */ |
@@ -0,0 +1,100 @@ | |||
/* | |||
* Copyright 2013 Christoph Bumiller | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "nine_helpers.h" | |||
static struct nine_range * | |||
nine_range_pool_more(struct nine_range_pool *pool) | |||
{ | |||
struct nine_range *r = MALLOC(64 * sizeof(struct nine_range)); | |||
int i; | |||
assert(!pool->free); | |||
if (pool->num_slabs == pool->num_slabs_max) { | |||
unsigned p = pool->num_slabs_max; | |||
unsigned n = pool->num_slabs_max * 2; | |||
if (!n) | |||
n = 4; | |||
pool->slabs = REALLOC(pool->slabs, | |||
p * sizeof(struct nine_range *), | |||
n * sizeof(struct nine_range *)); | |||
pool->num_slabs_max = n; | |||
} | |||
pool->free = pool->slabs[pool->num_slabs++] = r; | |||
for (i = 0; i < 63; ++i, r = r->next) | |||
r->next = (struct nine_range *) | |||
((uint8_t *)r + sizeof(struct nine_range)); | |||
r->next = NULL; | |||
return pool->free; | |||
} | |||
static INLINE struct nine_range * | |||
nine_range_pool_get(struct nine_range_pool *pool, int16_t bgn, int16_t end) | |||
{ | |||
struct nine_range *r = pool->free; | |||
if (!r) | |||
r = nine_range_pool_more(pool); | |||
assert(r); | |||
pool->free = r->next; | |||
r->bgn = bgn; | |||
r->end = end; | |||
return r; | |||
} | |||
static INLINE void | |||
nine_ranges_coalesce(struct nine_range *r, struct nine_range_pool *pool) | |||
{ | |||
struct nine_range *n; | |||
while (r->next && r->end >= r->next->bgn) { | |||
n = r->next->next; | |||
r->end = (r->end >= r->next->end) ? r->end : r->next->end; | |||
nine_range_pool_put(pool, r->next); | |||
r->next = n; | |||
} | |||
} | |||
void | |||
nine_ranges_insert(struct nine_range **head, int16_t bgn, int16_t end, | |||
struct nine_range_pool *pool) | |||
{ | |||
struct nine_range *r, **pn = head; | |||
for (r = *head; r && bgn > r->end; pn = &r->next, r = r->next); | |||
if (!r || end < r->bgn) { | |||
*pn = nine_range_pool_get(pool, bgn, end); | |||
(*pn)->next = r; | |||
} else | |||
if (bgn < r->bgn) { | |||
r->bgn = bgn; | |||
if (end > r->end) | |||
r->end = end; | |||
nine_ranges_coalesce(r, pool); | |||
} else | |||
if (end > r->end) { | |||
r->end = end; | |||
nine_ranges_coalesce(r, pool); | |||
} | |||
} |
@@ -0,0 +1,176 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_HELPERS_H_ | |||
#define _NINE_HELPERS_H_ | |||
#include "iunknown.h" | |||
#include "nine_lock.h" | |||
/* | |||
* Note: we use these function rather than the MIN2, MAX2, CLAMP macros to | |||
* avoid evaluating arguments (which are often function calls) more than once. | |||
*/ | |||
static inline unsigned _min(unsigned a, unsigned b) | |||
{ | |||
return (a < b) ? a : b; | |||
} | |||
/* Sshhh ... */ | |||
#define nine_reference(a, b) _nine_reference((void **)(a), (b)) | |||
static inline void _nine_reference(void **ref, void *ptr) | |||
{ | |||
if (*ref != ptr) { | |||
if (*ref) | |||
NineUnknown_Release(*ref); | |||
if (ptr) | |||
NineUnknown_AddRef(ptr); | |||
*ref = ptr; | |||
} | |||
} | |||
#define nine_reference_set(a, b) _nine_reference_set((void **)(a), (b)) | |||
static inline void _nine_reference_set(void **ref, void *ptr) | |||
{ | |||
*ref = ptr; | |||
if (ptr) | |||
NineUnknown_AddRef(ptr); | |||
} | |||
#define nine_bind(a, b) _nine_bind((void **)(a), (b)) | |||
static inline void _nine_bind(void **dst, void *obj) | |||
{ | |||
if (*dst != obj) { | |||
if (*dst) | |||
NineUnknown_Unbind(*dst); | |||
if (obj) | |||
NineUnknown_Bind(obj); | |||
*dst = obj; | |||
} | |||
} | |||
#define NINE_DEVICE_CHILD_NEW(nine, out, dev, ...) \ | |||
{ \ | |||
struct NineUnknownParams __params; \ | |||
struct Nine##nine *__data; \ | |||
\ | |||
__data = CALLOC_STRUCT(Nine##nine); \ | |||
if (!__data) { return E_OUTOFMEMORY; } \ | |||
\ | |||
__params.vtable = ((dev)->params.BehaviorFlags & D3DCREATE_MULTITHREADED) ? &Lock##nine##_vtable : &Nine##nine##_vtable; \ | |||
__params.guids = Nine##nine##_IIDs; \ | |||
__params.dtor = (void *)Nine##nine##_dtor; \ | |||
__params.container = NULL; \ | |||
__params.device = dev; \ | |||
{ \ | |||
HRESULT __hr = Nine##nine##_ctor(__data, &__params, ## __VA_ARGS__); \ | |||
if (FAILED(__hr)) { \ | |||
Nine##nine##_dtor(__data); \ | |||
return __hr; \ | |||
} \ | |||
} \ | |||
\ | |||
*(out) = __data; \ | |||
} \ | |||
return D3D_OK | |||
#define NINE_NEW(nine, out, lock, ...) \ | |||
{ \ | |||
struct NineUnknownParams __params; \ | |||
struct Nine##nine *__data; \ | |||
\ | |||
__data = CALLOC_STRUCT(Nine##nine); \ | |||
if (!__data) { return E_OUTOFMEMORY; } \ | |||
\ | |||
__params.vtable = (lock) ? &Lock##nine##_vtable : &Nine##nine##_vtable; \ | |||
__params.guids = Nine##nine##_IIDs; \ | |||
__params.dtor = (void *)Nine##nine##_dtor; \ | |||
__params.container = NULL; \ | |||
__params.device = NULL; \ | |||
{ \ | |||
HRESULT __hr = Nine##nine##_ctor(__data, &__params, ## __VA_ARGS__); \ | |||
if (FAILED(__hr)) { \ | |||
Nine##nine##_dtor(__data); \ | |||
return __hr; \ | |||
} \ | |||
} \ | |||
\ | |||
*(out) = __data; \ | |||
} \ | |||
return D3D_OK | |||
static INLINE float asfloat(DWORD value) | |||
{ | |||
union { | |||
float f; | |||
DWORD w; | |||
} u; | |||
u.w = value; | |||
return u.f; | |||
} | |||
#define CHECK_PIPE_RESOURCE_TEMPLATE(t) \ | |||
screen->is_format_supported(screen, (t).format, (t).target, (t).nr_samples, (t).bind) | |||
struct nine_range | |||
{ | |||
struct nine_range *next; | |||
int16_t bgn; /* inclusive */ | |||
int16_t end; /* exclusive */ | |||
}; | |||
/* We won't ever need more than 256 ranges, so just allocate once. */ | |||
struct nine_range_pool | |||
{ | |||
struct nine_range *free; | |||
struct nine_range **slabs; | |||
unsigned num_slabs; | |||
unsigned num_slabs_max; | |||
}; | |||
static INLINE void | |||
nine_range_pool_put(struct nine_range_pool *pool, struct nine_range *r) | |||
{ | |||
r->next = pool->free; | |||
pool->free = r; | |||
} | |||
static INLINE void | |||
nine_range_pool_put_chain(struct nine_range_pool *pool, | |||
struct nine_range *head, | |||
struct nine_range *tail) | |||
{ | |||
tail->next = pool->free; | |||
pool->free = head; | |||
} | |||
void | |||
nine_ranges_insert(struct nine_range **head, int16_t bgn, int16_t end, | |||
struct nine_range_pool *pool); | |||
#endif /* _NINE_HELPERS_H_ */ |
@@ -0,0 +1,51 @@ | |||
/* | |||
* Copyright 2013 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_LOCK_H_ | |||
#define _NINE_LOCK_H_ | |||
#include "d3d9.h" | |||
#include "d3dadapter/d3dadapter9.h" | |||
extern IDirect3DAuthenticatedChannel9Vtbl LockAuthenticatedChannel9_vtable; | |||
extern IDirect3DCryptoSession9Vtbl LockCryptoSession9_vtable; | |||
extern IDirect3DCubeTexture9Vtbl LockCubeTexture9_vtable; | |||
extern IDirect3DDevice9Vtbl LockDevice9_vtable; | |||
extern IDirect3DDevice9ExVtbl LockDevice9Ex_vtable; | |||
extern IDirect3DDevice9VideoVtbl LockDevice9Video_vtable; | |||
extern IDirect3DIndexBuffer9Vtbl LockIndexBuffer9_vtable; | |||
extern IDirect3DPixelShader9Vtbl LockPixelShader9_vtable; | |||
extern IDirect3DQuery9Vtbl LockQuery9_vtable; | |||
extern IDirect3DStateBlock9Vtbl LockStateBlock9_vtable; | |||
extern IDirect3DSurface9Vtbl LockSurface9_vtable; | |||
extern IDirect3DSwapChain9Vtbl LockSwapChain9_vtable; | |||
extern IDirect3DSwapChain9ExVtbl LockSwapChain9Ex_vtable; | |||
extern IDirect3DTexture9Vtbl LockTexture9_vtable; | |||
extern IDirect3DVertexBuffer9Vtbl LockVertexBuffer9_vtable; | |||
extern IDirect3DVertexDeclaration9Vtbl LockVertexDeclaration9_vtable; | |||
extern IDirect3DVertexShader9Vtbl LockVertexShader9_vtable; | |||
extern IDirect3DVolume9Vtbl LockVolume9_vtable; | |||
extern IDirect3DVolumeTexture9Vtbl LockVolumeTexture9_vtable; | |||
extern IDirect3DVolumeTexture9Vtbl LockVolumeTexture9_vtable; | |||
extern ID3DAdapter9Vtbl LockAdapter9_vtable; | |||
#endif /* _NINE_LOCK_H_ */ |
@@ -0,0 +1,45 @@ | |||
#ifndef _NINE_PDATA_H_ | |||
#define _NINE_PDATA_H_ | |||
struct pheader | |||
{ | |||
boolean unknown; | |||
DWORD size; | |||
char data[1]; | |||
}; | |||
static int | |||
ht_guid_compare( void *a, | |||
void *b ) | |||
{ | |||
return GUID_equal(a, b) ? 0 : 1; | |||
} | |||
static unsigned | |||
ht_guid_hash( void *key ) | |||
{ | |||
unsigned i, hash = 0; | |||
const unsigned char *str = key; | |||
for (i = 0; i < sizeof(GUID); i++) { | |||
hash = (unsigned)(str[i]) + (hash << 6) + (hash << 16) - hash; | |||
} | |||
return hash; | |||
} | |||
static enum pipe_error | |||
ht_guid_delete( void *key, | |||
void *value, | |||
void *data ) | |||
{ | |||
struct pheader *header = value; | |||
if (header->unknown) { IUnknown_Release(*(IUnknown **)header->data); } | |||
FREE(header); | |||
return PIPE_OK; | |||
} | |||
#endif /* _NINE_PDATA_H_ */ |
@@ -0,0 +1,410 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* Copyright 2013 Christoph Bumiller | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "device9.h" | |||
#include "nine_pipe.h" | |||
#include "cso_cache/cso_context.h" | |||
void | |||
nine_convert_dsa_state(struct cso_context *ctx, const DWORD *rs) | |||
{ | |||
struct pipe_depth_stencil_alpha_state dsa; | |||
memset(&dsa, 0, sizeof(dsa)); /* memcmp safety */ | |||
if (rs[D3DRS_ZENABLE]) { | |||
dsa.depth.enabled = 1; | |||
dsa.depth.writemask = !!rs[D3DRS_ZWRITEENABLE]; | |||
dsa.depth.func = d3dcmpfunc_to_pipe_func(rs[D3DRS_ZFUNC]); | |||
} | |||
if (rs[D3DRS_STENCILENABLE]) { | |||
dsa.stencil[0].enabled = 1; | |||
dsa.stencil[0].func = d3dcmpfunc_to_pipe_func(rs[D3DRS_STENCILFUNC]); | |||
dsa.stencil[0].fail_op = d3dstencilop_to_pipe_stencil_op(rs[D3DRS_STENCILFAIL]); | |||
dsa.stencil[0].zpass_op = d3dstencilop_to_pipe_stencil_op(rs[D3DRS_STENCILPASS]); | |||
dsa.stencil[0].zfail_op = d3dstencilop_to_pipe_stencil_op(rs[D3DRS_STENCILZFAIL]); | |||
dsa.stencil[0].valuemask = rs[D3DRS_STENCILMASK]; | |||
dsa.stencil[0].writemask = rs[D3DRS_STENCILWRITEMASK]; | |||
if (rs[D3DRS_TWOSIDEDSTENCILMODE]) { | |||
dsa.stencil[1].enabled = 1; | |||
dsa.stencil[1].func = d3dcmpfunc_to_pipe_func(rs[D3DRS_CCW_STENCILFUNC]); | |||
dsa.stencil[1].fail_op = d3dstencilop_to_pipe_stencil_op(rs[D3DRS_CCW_STENCILFAIL]); | |||
dsa.stencil[1].zpass_op = d3dstencilop_to_pipe_stencil_op(rs[D3DRS_CCW_STENCILPASS]); | |||
dsa.stencil[1].zfail_op = d3dstencilop_to_pipe_stencil_op(rs[D3DRS_CCW_STENCILZFAIL]); | |||
dsa.stencil[1].valuemask = dsa.stencil[0].valuemask; | |||
dsa.stencil[1].writemask = dsa.stencil[0].writemask; | |||
} | |||
} | |||
if (rs[D3DRS_ALPHATESTENABLE]) { | |||
dsa.alpha.enabled = 1; | |||
dsa.alpha.func = d3dcmpfunc_to_pipe_func(rs[D3DRS_ALPHAFUNC]); | |||
dsa.alpha.ref_value = (float)rs[D3DRS_ALPHAREF] / 255.0f; | |||
} | |||
cso_set_depth_stencil_alpha(ctx, &dsa); | |||
} | |||
/* TODO: Keep a static copy in device so we don't have to memset every time ? */ | |||
void | |||
nine_convert_rasterizer_state(struct cso_context *ctx, const DWORD *rs) | |||
{ | |||
struct pipe_rasterizer_state rast; | |||
memset(&rast, 0, sizeof(rast)); /* memcmp safety */ | |||
rast.flatshade = rs[D3DRS_SHADEMODE] == D3DSHADE_FLAT; | |||
/* rast.light_twoside = 0; */ | |||
/* rast.clamp_fragment_color = 0; */ | |||
/* rast.clamp_vertex_color = 0; */ | |||
/* rast.front_ccw = 0; */ | |||
rast.cull_face = d3dcull_to_pipe_face(rs[D3DRS_CULLMODE]); | |||
rast.fill_front = d3dfillmode_to_pipe_polygon_mode(rs[D3DRS_FILLMODE]); | |||
rast.fill_back = rast.fill_front; | |||
rast.offset_tri = !!(rs[D3DRS_DEPTHBIAS] | rs[D3DRS_SLOPESCALEDEPTHBIAS]); | |||
rast.offset_line = rast.offset_tri; /* triangles in wireframe mode */ | |||
rast.offset_point = 0; /* XXX ? */ | |||
rast.scissor = !!rs[D3DRS_SCISSORTESTENABLE]; | |||
/* rast.poly_smooth = 0; */ | |||
/* rast.poly_stipple_enable = 0; */ | |||
/* rast.point_smooth = 0; */ | |||
rast.sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT; | |||
rast.point_quad_rasterization = !!rs[D3DRS_POINTSPRITEENABLE]; | |||
rast.point_size_per_vertex = rs[NINED3DRS_VSPOINTSIZE]; | |||
rast.multisample = !!rs[D3DRS_MULTISAMPLEANTIALIAS]; | |||
rast.line_smooth = !!rs[D3DRS_ANTIALIASEDLINEENABLE]; | |||
/* rast.line_stipple_enable = 0; */ | |||
rast.line_last_pixel = !!rs[D3DRS_LASTPIXEL]; | |||
rast.flatshade_first = 1; | |||
/* rast.half_pixel_center = 0; */ | |||
/* rast.lower_left_origin = 0; */ | |||
/* rast.bottom_edge_rule = 0; */ | |||
/* rast.rasterizer_discard = 0; */ | |||
rast.depth_clip = 1; | |||
rast.clip_halfz = 1; | |||
rast.clip_plane_enable = rs[D3DRS_CLIPPLANEENABLE]; | |||
/* rast.line_stipple_factor = 0; */ | |||
/* rast.line_stipple_pattern = 0; */ | |||
rast.sprite_coord_enable = rs[D3DRS_POINTSPRITEENABLE] ? 0xff : 0x00; | |||
rast.line_width = 1.0f; | |||
rast.point_size = rs[NINED3DRS_VSPOINTSIZE] ? 1.0f : asfloat(rs[D3DRS_POINTSIZE]); /* XXX: D3DRS_POINTSIZE_MIN/MAX */ | |||
rast.offset_units = asfloat(rs[D3DRS_DEPTHBIAS]) * asfloat(rs[NINED3DRS_ZBIASSCALE]); | |||
rast.offset_scale = asfloat(rs[D3DRS_SLOPESCALEDEPTHBIAS]); | |||
/* rast.offset_clamp = 0.0f; */ | |||
cso_set_rasterizer(ctx, &rast); | |||
} | |||
static INLINE void | |||
nine_convert_blend_state_fixup(struct pipe_blend_state *blend, const DWORD *rs) | |||
{ | |||
if (unlikely(rs[D3DRS_SRCBLEND] == D3DBLEND_BOTHSRCALPHA || | |||
rs[D3DRS_SRCBLEND] == D3DBLEND_BOTHINVSRCALPHA)) { | |||
blend->rt[0].rgb_dst_factor = (rs[D3DRS_SRCBLEND] == D3DBLEND_BOTHSRCALPHA) ? | |||
PIPE_BLENDFACTOR_INV_SRC_ALPHA : PIPE_BLENDFACTOR_SRC_ALPHA; | |||
if (!rs[D3DRS_SEPARATEALPHABLENDENABLE]) | |||
blend->rt[0].alpha_dst_factor = blend->rt[0].rgb_dst_factor; | |||
} else | |||
if (unlikely(rs[D3DRS_SEPARATEALPHABLENDENABLE] && | |||
(rs[D3DRS_SRCBLENDALPHA] == D3DBLEND_BOTHSRCALPHA || | |||
rs[D3DRS_SRCBLENDALPHA] == D3DBLEND_BOTHINVSRCALPHA))) { | |||
blend->rt[0].alpha_dst_factor = (rs[D3DRS_SRCBLENDALPHA] == D3DBLEND_BOTHSRCALPHA) ? | |||
PIPE_BLENDFACTOR_INV_SRC_ALPHA : PIPE_BLENDFACTOR_SRC_ALPHA; | |||
} | |||
} | |||
void | |||
nine_convert_blend_state(struct cso_context *ctx, const DWORD *rs) | |||
{ | |||
struct pipe_blend_state blend; | |||
memset(&blend, 0, sizeof(blend)); /* memcmp safety */ | |||
blend.dither = !!rs[D3DRS_DITHERENABLE]; | |||
/* blend.alpha_to_one = 0; */ | |||
/* blend.alpha_to_coverage = 0; */ /* XXX */ | |||
blend.rt[0].blend_enable = !!rs[D3DRS_ALPHABLENDENABLE]; | |||
if (blend.rt[0].blend_enable) { | |||
blend.rt[0].rgb_func = d3dblendop_to_pipe_blend(rs[D3DRS_BLENDOP]); | |||
blend.rt[0].rgb_src_factor = d3dblend_color_to_pipe_blendfactor(rs[D3DRS_SRCBLEND]); | |||
blend.rt[0].rgb_dst_factor = d3dblend_color_to_pipe_blendfactor(rs[D3DRS_DESTBLEND]); | |||
if (rs[D3DRS_SEPARATEALPHABLENDENABLE]) { | |||
blend.rt[0].alpha_func = d3dblendop_to_pipe_blend(rs[D3DRS_BLENDOPALPHA]); | |||
blend.rt[0].alpha_src_factor = d3dblend_alpha_to_pipe_blendfactor(rs[D3DRS_SRCBLENDALPHA]); | |||
blend.rt[0].alpha_dst_factor = d3dblend_alpha_to_pipe_blendfactor(rs[D3DRS_DESTBLENDALPHA]); | |||
} else { | |||
/* TODO: Just copy the rgb values ? SRC1_x may differ ... */ | |||
blend.rt[0].alpha_func = blend.rt[0].rgb_func; | |||
blend.rt[0].alpha_src_factor = d3dblend_alpha_to_pipe_blendfactor(rs[D3DRS_SRCBLEND]); | |||
blend.rt[0].alpha_dst_factor = d3dblend_alpha_to_pipe_blendfactor(rs[D3DRS_DESTBLEND]); | |||
} | |||
nine_convert_blend_state_fixup(&blend, rs); /* for BOTH[INV]SRCALPHA */ | |||
} | |||
blend.rt[0].colormask = rs[D3DRS_COLORWRITEENABLE]; | |||
if (rs[D3DRS_COLORWRITEENABLE1] != rs[D3DRS_COLORWRITEENABLE] || | |||
rs[D3DRS_COLORWRITEENABLE2] != rs[D3DRS_COLORWRITEENABLE] || | |||
rs[D3DRS_COLORWRITEENABLE3] != rs[D3DRS_COLORWRITEENABLE]) { | |||
unsigned i; | |||
blend.independent_blend_enable = TRUE; | |||
for (i = 1; i < 4; ++i) | |||
blend.rt[i] = blend.rt[0]; | |||
blend.rt[1].colormask = rs[D3DRS_COLORWRITEENABLE1]; | |||
blend.rt[2].colormask = rs[D3DRS_COLORWRITEENABLE2]; | |||
blend.rt[3].colormask = rs[D3DRS_COLORWRITEENABLE3]; | |||
} | |||
/* blend.force_srgb = !!rs[D3DRS_SRGBWRITEENABLE]; */ | |||
cso_set_blend(ctx, &blend); | |||
} | |||
void | |||
nine_convert_sampler_state(struct cso_context *ctx, int idx, const DWORD *ss) | |||
{ | |||
struct pipe_sampler_state samp; | |||
assert(idx >= 0 && | |||
(idx < NINE_MAX_SAMPLERS_PS || idx >= NINE_SAMPLER_VS(0)) && | |||
(idx < NINE_MAX_SAMPLERS)); | |||
memset(&samp, 0, sizeof(samp)); /* memcmp safety */ | |||
if (ss[D3DSAMP_MIPFILTER] != D3DTEXF_NONE) { | |||
samp.lod_bias = asfloat(ss[D3DSAMP_MIPMAPLODBIAS]); | |||
samp.min_lod = ss[NINED3DSAMP_MINLOD]; | |||
samp.min_mip_filter = (ss[D3DSAMP_MIPFILTER] == D3DTEXF_POINT) ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR; | |||
} else { | |||
samp.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; | |||
} | |||
samp.max_lod = 15.0f; | |||
samp.wrap_s = d3dtextureaddress_to_pipe_tex_wrap(ss[D3DSAMP_ADDRESSU]); | |||
samp.wrap_t = d3dtextureaddress_to_pipe_tex_wrap(ss[D3DSAMP_ADDRESSV]); | |||
samp.wrap_r = d3dtextureaddress_to_pipe_tex_wrap(ss[D3DSAMP_ADDRESSW]); | |||
samp.min_img_filter = ss[D3DSAMP_MINFILTER] == D3DTEXF_POINT ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR; | |||
samp.mag_img_filter = ss[D3DSAMP_MAGFILTER] == D3DTEXF_POINT ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR; | |||
if (ss[D3DSAMP_MINFILTER] == D3DTEXF_ANISOTROPIC || | |||
ss[D3DSAMP_MAGFILTER] == D3DTEXF_ANISOTROPIC) | |||
samp.max_anisotropy = ss[D3DSAMP_MAXANISOTROPY]; | |||
samp.compare_mode = ss[NINED3DSAMP_SHADOW] ? PIPE_TEX_COMPARE_R_TO_TEXTURE : PIPE_TEX_COMPARE_NONE; | |||
samp.compare_func = PIPE_FUNC_LEQUAL; | |||
samp.normalized_coords = 1; | |||
samp.seamless_cube_map = 1; | |||
d3dcolor_to_pipe_color_union(&samp.border_color, ss[D3DSAMP_BORDERCOLOR]); | |||
/* see nine_state.h */ | |||
if (idx < NINE_MAX_SAMPLERS_PS) | |||
cso_single_sampler(ctx, PIPE_SHADER_FRAGMENT, idx - NINE_SAMPLER_PS(0), &samp); | |||
else | |||
cso_single_sampler(ctx, PIPE_SHADER_VERTEX, idx - NINE_SAMPLER_VS(0), &samp); | |||
} | |||
void | |||
nine_pipe_context_clear(struct NineDevice9 *This) | |||
{ | |||
struct pipe_context *pipe = This->pipe; | |||
struct cso_context *cso = This->cso; | |||
pipe->bind_vs_state(pipe, NULL); | |||
pipe->bind_fs_state(pipe, NULL); | |||
/* Don't unbind constant buffers, they're device-private and | |||
* do not change on Reset. | |||
*/ | |||
cso_set_samplers(cso, PIPE_SHADER_VERTEX, 0, NULL); | |||
cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, 0, NULL); | |||
pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 0, NULL); | |||
pipe->set_sampler_views(pipe, PIPE_SHADER_VERTEX, 0, 0, NULL); | |||
pipe->set_vertex_buffers(pipe, 0, This->caps.MaxStreams, NULL); | |||
pipe->set_index_buffer(pipe, NULL); | |||
} | |||
const enum pipe_format nine_d3d9_to_pipe_format_map[120] = | |||
{ | |||
[D3DFMT_UNKNOWN] = PIPE_FORMAT_NONE, | |||
[D3DFMT_A8R8G8B8] = PIPE_FORMAT_B8G8R8A8_UNORM, | |||
[D3DFMT_X8R8G8B8] = PIPE_FORMAT_B8G8R8X8_UNORM, | |||
[D3DFMT_R5G6B5] = PIPE_FORMAT_B5G6R5_UNORM, | |||
[D3DFMT_X1R5G5B5] = PIPE_FORMAT_B5G5R5X1_UNORM, | |||
[D3DFMT_A1R5G5B5] = PIPE_FORMAT_B5G5R5A1_UNORM, | |||
[D3DFMT_A4R4G4B4] = PIPE_FORMAT_B4G4R4A4_UNORM, | |||
[D3DFMT_A8] = PIPE_FORMAT_A8_UNORM, | |||
[D3DFMT_X4R4G4B4] = PIPE_FORMAT_B4G4R4X4_UNORM, | |||
[D3DFMT_R3G3B2] = PIPE_FORMAT_B2G3R3_UNORM, | |||
[D3DFMT_A2B10G10R10] = PIPE_FORMAT_R10G10B10A2_UNORM, | |||
[D3DFMT_A8B8G8R8] = PIPE_FORMAT_R8G8B8A8_UNORM, | |||
[D3DFMT_X8B8G8R8] = PIPE_FORMAT_R8G8B8X8_UNORM, | |||
[D3DFMT_G16R16] = PIPE_FORMAT_R16G16_UNORM, | |||
[D3DFMT_A2R10G10B10] = PIPE_FORMAT_B10G10R10A2_UNORM, | |||
[D3DFMT_A16B16G16R16] = PIPE_FORMAT_R16G16B16A16_UNORM, | |||
/* palette texture formats not supported by gallium/hardware, TODO ? */ | |||
[D3DFMT_P8] = PIPE_FORMAT_NONE, | |||
[D3DFMT_A8P8] = PIPE_FORMAT_NONE, | |||
[D3DFMT_L8] = PIPE_FORMAT_L8_UNORM, | |||
[D3DFMT_A8L8] = PIPE_FORMAT_L8A8_UNORM, | |||
[D3DFMT_A4L4] = PIPE_FORMAT_L4A4_UNORM, | |||
[D3DFMT_V8U8] = PIPE_FORMAT_R8G8_SNORM, | |||
[D3DFMT_Q8W8V8U8] = PIPE_FORMAT_R8G8B8A8_SNORM, | |||
[D3DFMT_V16U16] = PIPE_FORMAT_R16G16_SNORM, | |||
[D3DFMT_A2W10V10U10] = PIPE_FORMAT_R10SG10SB10SA2U_NORM, | |||
/* [D3DFMT_UYVY] = PIPE_FORMAT_YUYV, fourcc */ | |||
/* [D3DFMT_YUY2] = PIPE_FORMAT_NONE, fourcc */ | |||
/* XXX: DXT2, DXT4 */ | |||
/* fourcc | |||
[D3DFMT_DXT1] = PIPE_FORMAT_DXT1_RGBA, | |||
[D3DFMT_DXT2] = PIPE_FORMAT_DXT3_RGBA, | |||
[D3DFMT_DXT3] = PIPE_FORMAT_DXT3_RGBA, | |||
[D3DFMT_DXT4] = PIPE_FORMAT_DXT5_RGBA, | |||
[D3DFMT_DXT5] = PIPE_FORMAT_DXT5_RGBA, | |||
*/ | |||
/* XXX: order ? */ | |||
/* fourcc | |||
[D3DFMT_G8R8_G8B8] = PIPE_FORMAT_G8R8_G8B8_UNORM, | |||
[D3DFMT_R8G8_B8G8] = PIPE_FORMAT_R8G8_B8G8_UNORM, | |||
*/ | |||
[D3DFMT_D16_LOCKABLE] = PIPE_FORMAT_Z16_UNORM, | |||
[D3DFMT_D32] = PIPE_FORMAT_Z32_UNORM, | |||
[D3DFMT_D24S8] = PIPE_FORMAT_S8_UINT_Z24_UNORM, | |||
[D3DFMT_D24X8] = PIPE_FORMAT_X8Z24_UNORM, | |||
[D3DFMT_D16] = PIPE_FORMAT_Z16_UNORM, | |||
[D3DFMT_L16] = PIPE_FORMAT_L16_UNORM, | |||
[D3DFMT_D32F_LOCKABLE] = PIPE_FORMAT_Z32_FLOAT, | |||
[D3DFMT_INDEX16] = PIPE_FORMAT_R16_UINT, | |||
[D3DFMT_INDEX32] = PIPE_FORMAT_R32_UINT, | |||
[D3DFMT_Q16W16V16U16] = PIPE_FORMAT_R16G16B16A16_SNORM, | |||
[D3DFMT_R16F] = PIPE_FORMAT_R16_FLOAT, | |||
[D3DFMT_R32F] = PIPE_FORMAT_R32_FLOAT, | |||
[D3DFMT_G16R16F] = PIPE_FORMAT_R16G16_FLOAT, | |||
[D3DFMT_G32R32F] = PIPE_FORMAT_R32G32_FLOAT, | |||
[D3DFMT_A16B16G16R16F] = PIPE_FORMAT_R16G16B16A16_FLOAT, | |||
[D3DFMT_A32B32G32R32F] = PIPE_FORMAT_R32G32B32A32_FLOAT, | |||
/* non-1:1 formats (don't support because we'd have to convert) */ | |||
[D3DFMT_R8G8B8] = PIPE_FORMAT_NONE, /* XXX order */ | |||
[D3DFMT_A8R3G3B2] = PIPE_FORMAT_NONE, /* XXX alpha */ | |||
/* This is ok because they're not lockable: */ | |||
[D3DFMT_D15S1] = PIPE_FORMAT_Z24_UNORM_S8_UINT, | |||
[D3DFMT_D24X4S4] = PIPE_FORMAT_Z24_UNORM_S8_UINT, | |||
[D3DFMT_D24FS8] = PIPE_FORMAT_Z32_FLOAT_S8X24_UINT, | |||
/* not really formats */ | |||
[D3DFMT_VERTEXDATA] = PIPE_FORMAT_NONE, | |||
/* [D3DFMT_BINARYBUFFER] = PIPE_FORMAT_NONE, too large */ | |||
/* unsupported formats */ | |||
[D3DFMT_L6V5U5] = PIPE_FORMAT_NONE, | |||
[D3DFMT_X8L8V8U8] = PIPE_FORMAT_NONE, | |||
/* [D3DFMT_MULTI2_ARGB8] = PIPE_FORMAT_NONE, fourcc, MET */ | |||
[D3DFMT_CxV8U8] = PIPE_FORMAT_NONE, | |||
[D3DFMT_A1] = PIPE_FORMAT_NONE, /* XXX: add this ? */ | |||
[D3DFMT_A2B10G10R10_XR_BIAS] = PIPE_FORMAT_NONE, /* XXX ? */ | |||
}; | |||
const D3DFORMAT nine_pipe_to_d3d9_format_map[PIPE_FORMAT_COUNT] = | |||
{ | |||
[PIPE_FORMAT_NONE] = D3DFMT_UNKNOWN, | |||
/* [PIPE_FORMAT_B8G8R8_UNORM] = D3DFMT_R8G8B8, */ | |||
[PIPE_FORMAT_B8G8R8A8_UNORM] = D3DFMT_A8R8G8B8, | |||
[PIPE_FORMAT_B8G8R8X8_UNORM] = D3DFMT_X8R8G8B8, | |||
[PIPE_FORMAT_B5G6R5_UNORM] = D3DFMT_R5G6B5, | |||
[PIPE_FORMAT_B5G5R5X1_UNORM] = D3DFMT_X1R5G5B5, | |||
[PIPE_FORMAT_B5G5R5A1_UNORM] = D3DFMT_A1R5G5B5, | |||
[PIPE_FORMAT_B4G4R4A4_UNORM] = D3DFMT_A4R4G4B4, | |||
[PIPE_FORMAT_B2G3R3_UNORM] = D3DFMT_R3G3B2, | |||
[PIPE_FORMAT_A8_UNORM] = D3DFMT_A8, | |||
/* [PIPE_FORMAT_B2G3R3A8_UNORM] = D3DFMT_A8R3G3B2, */ | |||
[PIPE_FORMAT_B4G4R4X4_UNORM] = D3DFMT_X4R4G4B4, | |||
[PIPE_FORMAT_R10G10B10A2_UNORM] = D3DFMT_A2B10G10R10, | |||
[PIPE_FORMAT_R8G8B8A8_UNORM] = D3DFMT_A8B8G8R8, | |||
[PIPE_FORMAT_R8G8B8X8_UNORM] = D3DFMT_X8B8G8R8, | |||
[PIPE_FORMAT_R16G16_UNORM] = D3DFMT_G16R16, | |||
[PIPE_FORMAT_B10G10R10A2_UNORM] = D3DFMT_A2R10G10B10, | |||
[PIPE_FORMAT_R16G16B16A16_UNORM] = D3DFMT_A16B16G16R16, | |||
[PIPE_FORMAT_R8_UINT] = D3DFMT_P8, | |||
[PIPE_FORMAT_R8A8_UINT] = D3DFMT_A8P8, | |||
[PIPE_FORMAT_L8_UNORM] = D3DFMT_L8, | |||
[PIPE_FORMAT_L8A8_UNORM] = D3DFMT_A8L8, | |||
[PIPE_FORMAT_L4A4_UNORM] = D3DFMT_A4L4, | |||
[PIPE_FORMAT_R8G8_SNORM] = D3DFMT_V8U8, | |||
/* [PIPE_FORMAT_?] = D3DFMT_L6V5U5, */ | |||
/* [PIPE_FORMAT_?] = D3DFMT_X8L8V8U8, */ | |||
[PIPE_FORMAT_R8G8B8A8_SNORM] = D3DFMT_Q8W8V8U8, | |||
[PIPE_FORMAT_R16G16_SNORM] = D3DFMT_V16U16, | |||
[PIPE_FORMAT_R10SG10SB10SA2U_NORM] = D3DFMT_A2W10V10U10, | |||
[PIPE_FORMAT_YUYV] = D3DFMT_UYVY, | |||
/* [PIPE_FORMAT_YUY2] = D3DFMT_YUY2, */ | |||
[PIPE_FORMAT_DXT1_RGBA] = D3DFMT_DXT1, | |||
/* [PIPE_FORMAT_DXT2_RGBA] = D3DFMT_DXT2, */ | |||
[PIPE_FORMAT_DXT3_RGBA] = D3DFMT_DXT3, | |||
/* [PIPE_FORMAT_DXT4_RGBA] = D3DFMT_DXT4, */ | |||
[PIPE_FORMAT_DXT5_RGBA] = D3DFMT_DXT5, | |||
/* [PIPE_FORMAT_?] = D3DFMT_MULTI2_ARGB8, (MET) */ | |||
[PIPE_FORMAT_R8G8_B8G8_UNORM] = D3DFMT_R8G8_B8G8, /* XXX: order */ | |||
[PIPE_FORMAT_G8R8_G8B8_UNORM] = D3DFMT_G8R8_G8B8, | |||
[PIPE_FORMAT_Z16_UNORM] = D3DFMT_D16_LOCKABLE, | |||
[PIPE_FORMAT_Z32_UNORM] = D3DFMT_D32, | |||
/* [PIPE_FORMAT_Z15_UNORM_S1_UINT] = D3DFMT_D15S1, */ | |||
[PIPE_FORMAT_S8_UINT_Z24_UNORM] = D3DFMT_D24S8, | |||
[PIPE_FORMAT_X8Z24_UNORM] = D3DFMT_D24X8, | |||
[PIPE_FORMAT_L16_UNORM] = D3DFMT_L16, | |||
[PIPE_FORMAT_Z32_FLOAT] = D3DFMT_D32F_LOCKABLE, | |||
/* [PIPE_FORMAT_Z24_FLOAT_S8_UINT] = D3DFMT_D24FS8, */ | |||
[PIPE_FORMAT_R16_UINT] = D3DFMT_INDEX16, | |||
[PIPE_FORMAT_R32_UINT] = D3DFMT_INDEX32, | |||
[PIPE_FORMAT_R16G16B16A16_SNORM] = D3DFMT_Q16W16V16U16, | |||
[PIPE_FORMAT_R16_FLOAT] = D3DFMT_R16F, | |||
[PIPE_FORMAT_R32_FLOAT] = D3DFMT_R32F, | |||
[PIPE_FORMAT_R16G16_FLOAT] = D3DFMT_G16R16F, | |||
[PIPE_FORMAT_R32G32_FLOAT] = D3DFMT_G32R32F, | |||
[PIPE_FORMAT_R16G16B16A16_FLOAT] = D3DFMT_A16B16G16R16F, | |||
[PIPE_FORMAT_R32G32B32A32_FLOAT] = D3DFMT_A32B32G32R32F, | |||
/* [PIPE_FORMAT_?] = D3DFMT_CxV8U8, */ | |||
}; |
@@ -0,0 +1,568 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_PIPE_H_ | |||
#define _NINE_PIPE_H_ | |||
#include "d3d9.h" | |||
#include "pipe/p_format.h" | |||
#include "pipe/p_state.h" /* pipe_box */ | |||
#include "util/u_rect.h" | |||
#include "nine_helpers.h" | |||
struct cso_context; | |||
extern const enum pipe_format nine_d3d9_to_pipe_format_map[120]; | |||
extern const D3DFORMAT nine_pipe_to_d3d9_format_map[PIPE_FORMAT_COUNT]; | |||
void nine_convert_dsa_state(struct cso_context *, const DWORD *); | |||
void nine_convert_rasterizer_state(struct cso_context *, const DWORD *); | |||
void nine_convert_blend_state(struct cso_context *, const DWORD *); | |||
void nine_convert_sampler_state(struct cso_context *, int idx, const DWORD *); | |||
void nine_pipe_context_clear(struct NineDevice9 *); | |||
static INLINE unsigned d3dlock_buffer_to_pipe_transfer_usage(DWORD Flags) | |||
{ | |||
unsigned usage; | |||
if (Flags & D3DLOCK_DISCARD) | |||
usage = PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE; | |||
else | |||
if (Flags & D3DLOCK_READONLY) | |||
usage = PIPE_TRANSFER_READ; | |||
else | |||
usage = PIPE_TRANSFER_READ_WRITE; | |||
if (Flags & D3DLOCK_NOOVERWRITE) | |||
usage = (PIPE_TRANSFER_UNSYNCHRONIZED | | |||
PIPE_TRANSFER_DISCARD_RANGE | usage) & ~PIPE_TRANSFER_READ; | |||
else | |||
if (Flags & D3DLOCK_DONOTWAIT) | |||
usage |= PIPE_TRANSFER_DONTBLOCK; | |||
/* | |||
if (Flags & D3DLOCK_NO_DIRTY_UPDATE) | |||
usage |= PIPE_TRANSFER_FLUSH_EXPLICIT; | |||
*/ | |||
return usage; | |||
} | |||
static INLINE void | |||
rect_to_pipe_box(struct pipe_box *dst, const RECT *src) | |||
{ | |||
dst->x = src->left; | |||
dst->y = src->top; | |||
dst->z = 0; | |||
dst->width = src->right - src->left; | |||
dst->height = src->bottom - src->top; | |||
dst->depth = 1; | |||
} | |||
static INLINE boolean | |||
rect_to_pipe_box_clamp(struct pipe_box *dst, const RECT *src) | |||
{ | |||
rect_to_pipe_box(dst, src); | |||
if (dst->width <= 0 || dst->height <= 0) { | |||
DBG_FLAG(DBG_UNKNOWN, "Warning: NULL box"); | |||
dst->width = MAX2(dst->width, 0); | |||
dst->height = MAX2(dst->height, 0); | |||
return TRUE; | |||
} | |||
return FALSE; | |||
} | |||
static INLINE boolean | |||
rect_to_pipe_box_flip(struct pipe_box *dst, const RECT *src) | |||
{ | |||
rect_to_pipe_box(dst, src); | |||
if (dst->width >= 0 && dst->height >= 0) | |||
return FALSE; | |||
if (dst->width < 0) dst->width = -dst->width; | |||
if (dst->height < 0) dst->height = -dst->height; | |||
return TRUE; | |||
} | |||
static INLINE void | |||
nine_u_rect_to_pipe_box(struct pipe_box *dst, const struct u_rect *rect, int z) | |||
{ | |||
dst->x = rect->x0; | |||
dst->y = rect->y0; | |||
dst->z = z; | |||
dst->width = rect->x1 - rect->x0; | |||
dst->height = rect->y1 - rect->y0; | |||
dst->depth = 1; | |||
} | |||
static INLINE void | |||
rect_to_pipe_box_xy_only(struct pipe_box *dst, const RECT *src) | |||
{ | |||
user_warn(src->left > src->right || src->top > src->bottom); | |||
dst->x = src->left; | |||
dst->y = src->top; | |||
dst->width = src->right - src->left; | |||
dst->height = src->bottom - src->top; | |||
} | |||
static INLINE boolean | |||
rect_to_pipe_box_xy_only_clamp(struct pipe_box *dst, const RECT *src) | |||
{ | |||
rect_to_pipe_box_xy_only(dst, src); | |||
if (dst->width <= 0 || dst->height <= 0) { | |||
DBG_FLAG(DBG_UNKNOWN, "Warning: NULL box"); | |||
dst->width = MAX2(dst->width, 0); | |||
dst->height = MAX2(dst->height, 0); | |||
return TRUE; | |||
} | |||
return FALSE; | |||
} | |||
static INLINE void | |||
rect_to_g3d_u_rect(struct u_rect *dst, const RECT *src) | |||
{ | |||
user_warn(src->left > src->right || src->top > src->bottom); | |||
dst->x0 = src->left; | |||
dst->x1 = src->right; | |||
dst->y0 = src->top; | |||
dst->y1 = src->bottom; | |||
} | |||
static INLINE void | |||
d3dbox_to_pipe_box(struct pipe_box *dst, const D3DBOX *src) | |||
{ | |||
user_warn(src->Left > src->Right); | |||
user_warn(src->Top > src->Bottom); | |||
user_warn(src->Front > src->Back); | |||
dst->x = src->Left; | |||
dst->y = src->Top; | |||
dst->z = src->Front; | |||
dst->width = src->Right - src->Left; | |||
dst->height = src->Bottom - src->Top; | |||
dst->depth = src->Back - src->Front; | |||
} | |||
static INLINE D3DFORMAT | |||
pipe_to_d3d9_format(enum pipe_format format) | |||
{ | |||
return nine_pipe_to_d3d9_format_map[format]; | |||
} | |||
static INLINE enum pipe_format | |||
d3d9_to_pipe_format(D3DFORMAT format) | |||
{ | |||
if (format <= D3DFMT_A2B10G10R10_XR_BIAS) | |||
return nine_d3d9_to_pipe_format_map[format]; | |||
switch (format) { | |||
case D3DFMT_INTZ: return PIPE_FORMAT_Z24_UNORM_S8_UINT; | |||
case D3DFMT_DXT1: return PIPE_FORMAT_DXT1_RGBA; | |||
case D3DFMT_DXT2: return PIPE_FORMAT_DXT3_RGBA; /* XXX */ | |||
case D3DFMT_DXT3: return PIPE_FORMAT_DXT3_RGBA; | |||
case D3DFMT_DXT4: return PIPE_FORMAT_DXT5_RGBA; /* XXX */ | |||
case D3DFMT_DXT5: return PIPE_FORMAT_DXT5_RGBA; | |||
case D3DFMT_UYVY: return PIPE_FORMAT_UYVY; | |||
case D3DFMT_YUY2: return PIPE_FORMAT_YUYV; /* XXX check */ | |||
case D3DFMT_NV12: return PIPE_FORMAT_NV12; | |||
case D3DFMT_G8R8_G8B8: return PIPE_FORMAT_G8R8_G8B8_UNORM; /* XXX order ? */ | |||
case D3DFMT_R8G8_B8G8: return PIPE_FORMAT_R8G8_B8G8_UNORM; /* XXX order ? */ | |||
case D3DFMT_BINARYBUFFER: return PIPE_FORMAT_NONE; /* not a format */ | |||
case D3DFMT_MULTI2_ARGB8: return PIPE_FORMAT_NONE; /* not supported */ | |||
case D3DFMT_Y210: /* XXX */ | |||
case D3DFMT_Y216: | |||
case D3DFMT_NV11: | |||
case D3DFMT_DF16: /* useless, not supported by wine either */ | |||
case D3DFMT_DF24: /* useless, not supported by wine either */ | |||
case D3DFMT_NULL: /* special cased, only for surfaces */ | |||
return PIPE_FORMAT_NONE; | |||
default: | |||
DBG_FLAG(DBG_UNKNOWN, "unknown D3DFORMAT: 0x%x/%c%c%c%c\n", | |||
format, (char)format, (char)(format >> 8), | |||
(char)(format >> 16), (char)(format >> 24)); | |||
return PIPE_FORMAT_NONE; | |||
} | |||
} | |||
static INLINE const char * | |||
d3dformat_to_string(D3DFORMAT fmt) | |||
{ | |||
switch (fmt) { | |||
case D3DFMT_UNKNOWN: return "D3DFMT_UNKNOWN"; | |||
case D3DFMT_R8G8B8: return "D3DFMT_R8G8B8"; | |||
case D3DFMT_A8R8G8B8: return "D3DFMT_A8R8G8B8"; | |||
case D3DFMT_X8R8G8B8: return "D3DFMT_X8R8G8B8"; | |||
case D3DFMT_R5G6B5: return "D3DFMT_R5G6B5"; | |||
case D3DFMT_X1R5G5B5: return "D3DFMT_X1R5G5B5"; | |||
case D3DFMT_A1R5G5B5: return "D3DFMT_A1R5G5B5"; | |||
case D3DFMT_A4R4G4B4: return "D3DFMT_A4R4G4B4"; | |||
case D3DFMT_R3G3B2: return "D3DFMT_R3G3B2"; | |||
case D3DFMT_A8: return "D3DFMT_A8"; | |||
case D3DFMT_A8R3G3B2: return "D3DFMT_A8R3G3B2"; | |||
case D3DFMT_X4R4G4B4: return "D3DFMT_X4R4G4B4"; | |||
case D3DFMT_A2B10G10R10: return "D3DFMT_A2B10G10R10"; | |||
case D3DFMT_A8B8G8R8: return "D3DFMT_A8B8G8R8"; | |||
case D3DFMT_X8B8G8R8: return "D3DFMT_X8B8G8R8"; | |||
case D3DFMT_G16R16: return "D3DFMT_G16R16"; | |||
case D3DFMT_A2R10G10B10: return "D3DFMT_A2R10G10B10"; | |||
case D3DFMT_A16B16G16R16: return "D3DFMT_A16B16G16R16"; | |||
case D3DFMT_A8P8: return "D3DFMT_A8P8"; | |||
case D3DFMT_P8: return "D3DFMT_P8"; | |||
case D3DFMT_L8: return "D3DFMT_L8"; | |||
case D3DFMT_A8L8: return "D3DFMT_A8L8"; | |||
case D3DFMT_A4L4: return "D3DFMT_A4L4"; | |||
case D3DFMT_V8U8: return "D3DFMT_V8U8"; | |||
case D3DFMT_L6V5U5: return "D3DFMT_L6V5U5"; | |||
case D3DFMT_X8L8V8U8: return "D3DFMT_X8L8V8U8"; | |||
case D3DFMT_Q8W8V8U8: return "D3DFMT_Q8W8V8U8"; | |||
case D3DFMT_V16U16: return "D3DFMT_V16U16"; | |||
case D3DFMT_A2W10V10U10: return "D3DFMT_A2W10V10U10"; | |||
case D3DFMT_UYVY: return "D3DFMT_UYVY"; | |||
case D3DFMT_R8G8_B8G8: return "D3DFMT_R8G8_B8G8"; | |||
case D3DFMT_YUY2: return "D3DFMT_YUY2"; | |||
case D3DFMT_G8R8_G8B8: return "D3DFMT_G8R8_G8B8"; | |||
case D3DFMT_DXT1: return "D3DFMT_DXT1"; | |||
case D3DFMT_DXT2: return "D3DFMT_DXT2"; | |||
case D3DFMT_DXT3: return "D3DFMT_DXT3"; | |||
case D3DFMT_DXT4: return "D3DFMT_DXT4"; | |||
case D3DFMT_DXT5: return "D3DFMT_DXT5"; | |||
case D3DFMT_D16_LOCKABLE: return "D3DFMT_D16_LOCKABLE"; | |||
case D3DFMT_D32: return "D3DFMT_D32"; | |||
case D3DFMT_D15S1: return "D3DFMT_D15S1"; | |||
case D3DFMT_D24S8: return "D3DFMT_D24S8"; | |||
case D3DFMT_D24X8: return "D3DFMT_D24X8"; | |||
case D3DFMT_D24X4S4: return "D3DFMT_D24X4S4"; | |||
case D3DFMT_D16: return "D3DFMT_D16"; | |||
case D3DFMT_D32F_LOCKABLE: return "D3DFMT_D32F_LOCKABLE"; | |||
case D3DFMT_D24FS8: return "D3DFMT_D24FS8"; | |||
case D3DFMT_D32_LOCKABLE: return "D3DFMT_D32_LOCKABLE"; | |||
case D3DFMT_S8_LOCKABLE: return "D3DFMT_S8_LOCKABLE"; | |||
case D3DFMT_L16: return "D3DFMT_L16"; | |||
case D3DFMT_VERTEXDATA: return "D3DFMT_VERTEXDATA"; | |||
case D3DFMT_INDEX16: return "D3DFMT_INDEX16"; | |||
case D3DFMT_INDEX32: return "D3DFMT_INDEX32"; | |||
case D3DFMT_Q16W16V16U16: return "D3DFMT_Q16W16V16U16"; | |||
case D3DFMT_MULTI2_ARGB8: return "D3DFMT_MULTI2_ARGB8"; | |||
case D3DFMT_R16F: return "D3DFMT_R16F"; | |||
case D3DFMT_G16R16F: return "D3DFMT_G16R16F"; | |||
case D3DFMT_A16B16G16R16F: return "D3DFMT_A16B16G16R16F"; | |||
case D3DFMT_R32F: return "D3DFMT_R32F"; | |||
case D3DFMT_G32R32F: return "D3DFMT_G32R32F"; | |||
case D3DFMT_A32B32G32R32F: return "D3DFMT_A32B32G32R32F"; | |||
case D3DFMT_CxV8U8: return "D3DFMT_CxV8U8"; | |||
case D3DFMT_A1: return "D3DFMT_A1"; | |||
case D3DFMT_A2B10G10R10_XR_BIAS: return "D3DFMT_A2B10G10R10_XR_BIAS"; | |||
case D3DFMT_BINARYBUFFER: return "D3DFMT_BINARYBUFFER"; | |||
case D3DFMT_DF16: return "D3DFMT_DF16"; | |||
case D3DFMT_DF24: return "D3DFMT_DF24"; | |||
case D3DFMT_INTZ: return "D3DFMT_INTZ"; | |||
case D3DFMT_NULL: return "D3DFMT_NULL"; | |||
default: | |||
break; | |||
} | |||
return "Unknown"; | |||
} | |||
static INLINE unsigned | |||
nine_fvf_stride( DWORD fvf ) | |||
{ | |||
unsigned texcount, i, size = 0; | |||
switch (fvf & D3DFVF_POSITION_MASK) { | |||
case D3DFVF_XYZ: size += 3*4; break; | |||
case D3DFVF_XYZRHW: size += 4*4; break; | |||
case D3DFVF_XYZB1: size += 4*4; break; | |||
case D3DFVF_XYZB2: size += 5*4; break; | |||
case D3DFVF_XYZB3: size += 6*4; break; | |||
case D3DFVF_XYZB4: size += 7*4; break; | |||
case D3DFVF_XYZB5: size += 8*4; break; | |||
case D3DFVF_XYZW: size += 4*4; break; | |||
default: | |||
user_warn("Position doesn't match any known combination."); | |||
break; | |||
} | |||
if (fvf & D3DFVF_NORMAL) { size += 3*4; } | |||
if (fvf & D3DFVF_PSIZE) { size += 1*4; } | |||
if (fvf & D3DFVF_DIFFUSE) { size += 1*4; } | |||
if (fvf & D3DFVF_SPECULAR) { size += 1*4; } | |||
texcount = (fvf >> D3DFVF_TEXCOUNT_SHIFT) & D3DFVF_TEXCOUNT_MASK; | |||
if (user_error(texcount <= 8)) | |||
texcount = 8; | |||
for (i = 0; i < texcount; ++i) { | |||
unsigned texformat = (fvf>>(16+i*2))&0x3; | |||
/* texformats are defined having been shifted around so 1=3,2=0,3=1,4=2 | |||
* meaning we can just do this instead of the switch below */ | |||
size += (((texformat+1)&0x3)+1)*4; | |||
/* | |||
switch (texformat) { | |||
case D3DFVF_TEXTUREFORMAT1: size += 1*4; | |||
case D3DFVF_TEXTUREFORMAT2: size += 2*4; | |||
case D3DFVF_TEXTUREFORMAT3: size += 3*4; | |||
case D3DFVF_TEXTUREFORMAT4: size += 4*4; | |||
} | |||
*/ | |||
} | |||
return size; | |||
} | |||
static INLINE void | |||
d3dcolor_to_rgba(float *rgba, D3DCOLOR color) | |||
{ | |||
rgba[0] = (float)((color >> 16) & 0xFF) / 0xFF; | |||
rgba[1] = (float)((color >> 8) & 0xFF) / 0xFF; | |||
rgba[2] = (float)((color >> 0) & 0xFF) / 0xFF; | |||
rgba[3] = (float)((color >> 24) & 0xFF) / 0xFF; | |||
} | |||
static INLINE void | |||
d3dcolor_to_pipe_color_union(union pipe_color_union *rgba, D3DCOLOR color) | |||
{ | |||
d3dcolor_to_rgba(&rgba->f[0], color); | |||
} | |||
static INLINE unsigned | |||
d3dprimitivetype_to_pipe_prim(D3DPRIMITIVETYPE prim) | |||
{ | |||
switch (prim) { | |||
case D3DPT_POINTLIST: return PIPE_PRIM_POINTS; | |||
case D3DPT_LINELIST: return PIPE_PRIM_LINES; | |||
case D3DPT_LINESTRIP: return PIPE_PRIM_LINE_STRIP; | |||
case D3DPT_TRIANGLELIST: return PIPE_PRIM_TRIANGLES; | |||
case D3DPT_TRIANGLESTRIP: return PIPE_PRIM_TRIANGLE_STRIP; | |||
case D3DPT_TRIANGLEFAN: return PIPE_PRIM_TRIANGLE_FAN; | |||
default: | |||
assert(0); | |||
return PIPE_PRIM_POINTS; | |||
} | |||
} | |||
static INLINE unsigned | |||
prim_count_to_vertex_count(D3DPRIMITIVETYPE prim, UINT count) | |||
{ | |||
switch (prim) { | |||
case D3DPT_POINTLIST: return count; | |||
case D3DPT_LINELIST: return count * 2; | |||
case D3DPT_LINESTRIP: return count + 1; | |||
case D3DPT_TRIANGLELIST: return count * 3; | |||
case D3DPT_TRIANGLESTRIP: return count + 2; | |||
case D3DPT_TRIANGLEFAN: return count + 2; | |||
default: | |||
assert(0); | |||
return 0; | |||
} | |||
} | |||
static INLINE unsigned | |||
d3dcmpfunc_to_pipe_func(D3DCMPFUNC func) | |||
{ | |||
switch (func) { | |||
case D3DCMP_NEVER: return PIPE_FUNC_NEVER; | |||
case D3DCMP_LESS: return PIPE_FUNC_LESS; | |||
case D3DCMP_EQUAL: return PIPE_FUNC_EQUAL; | |||
case D3DCMP_LESSEQUAL: return PIPE_FUNC_LEQUAL; | |||
case D3DCMP_GREATER: return PIPE_FUNC_GREATER; | |||
case D3DCMP_NOTEQUAL: return PIPE_FUNC_NOTEQUAL; | |||
case D3DCMP_GREATEREQUAL: return PIPE_FUNC_GEQUAL; | |||
case D3DCMP_ALWAYS: return PIPE_FUNC_ALWAYS; | |||
default: | |||
assert(0); | |||
return PIPE_FUNC_NEVER; | |||
} | |||
} | |||
static INLINE unsigned | |||
d3dstencilop_to_pipe_stencil_op(D3DSTENCILOP op) | |||
{ | |||
switch (op) { | |||
case D3DSTENCILOP_KEEP: return PIPE_STENCIL_OP_KEEP; | |||
case D3DSTENCILOP_ZERO: return PIPE_STENCIL_OP_ZERO; | |||
case D3DSTENCILOP_REPLACE: return PIPE_STENCIL_OP_REPLACE; | |||
case D3DSTENCILOP_INCRSAT: return PIPE_STENCIL_OP_INCR; | |||
case D3DSTENCILOP_DECRSAT: return PIPE_STENCIL_OP_DECR; | |||
case D3DSTENCILOP_INVERT: return PIPE_STENCIL_OP_INVERT; | |||
case D3DSTENCILOP_INCR: return PIPE_STENCIL_OP_INCR_WRAP; | |||
case D3DSTENCILOP_DECR: return PIPE_STENCIL_OP_DECR_WRAP; | |||
default: | |||
return PIPE_STENCIL_OP_ZERO; | |||
} | |||
} | |||
static INLINE unsigned | |||
d3dcull_to_pipe_face(D3DCULL cull) | |||
{ | |||
switch (cull) { | |||
case D3DCULL_NONE: return PIPE_FACE_NONE; | |||
case D3DCULL_CW: return PIPE_FACE_FRONT; | |||
case D3DCULL_CCW: return PIPE_FACE_BACK; | |||
default: | |||
assert(0); | |||
return PIPE_FACE_NONE; | |||
} | |||
} | |||
static INLINE unsigned | |||
d3dfillmode_to_pipe_polygon_mode(D3DFILLMODE mode) | |||
{ | |||
switch (mode) { | |||
case D3DFILL_POINT: return PIPE_POLYGON_MODE_POINT; | |||
case D3DFILL_WIREFRAME: return PIPE_POLYGON_MODE_LINE; | |||
case D3DFILL_SOLID: return PIPE_POLYGON_MODE_FILL; | |||
default: | |||
assert(0); | |||
return PIPE_POLYGON_MODE_FILL; | |||
} | |||
} | |||
static INLINE unsigned | |||
d3dblendop_to_pipe_blend(D3DBLENDOP op) | |||
{ | |||
switch (op) { | |||
case D3DBLENDOP_ADD: return PIPE_BLEND_ADD; | |||
case D3DBLENDOP_SUBTRACT: return PIPE_BLEND_SUBTRACT; | |||
case D3DBLENDOP_REVSUBTRACT: return PIPE_BLEND_REVERSE_SUBTRACT; | |||
case D3DBLENDOP_MIN: return PIPE_BLEND_MIN; | |||
case D3DBLENDOP_MAX: return PIPE_BLEND_MAX; | |||
default: | |||
assert(0); | |||
return PIPE_BLEND_ADD; | |||
} | |||
} | |||
/* NOTE: The COLOR factors for are equal to the ALPHA ones for alpha. | |||
* Drivers may check RGB and ALPHA factors for equality so we should not | |||
* simply substitute the ALPHA variants. | |||
*/ | |||
static INLINE unsigned | |||
d3dblend_alpha_to_pipe_blendfactor(D3DBLEND b) | |||
{ | |||
switch (b) { | |||
case D3DBLEND_ZERO: return PIPE_BLENDFACTOR_ZERO; | |||
case D3DBLEND_ONE: return PIPE_BLENDFACTOR_ONE; | |||
case D3DBLEND_SRCCOLOR: return PIPE_BLENDFACTOR_SRC_COLOR/*ALPHA*/; | |||
case D3DBLEND_INVSRCCOLOR: return PIPE_BLENDFACTOR_INV_SRC_COLOR/*ALPHA*/; | |||
case D3DBLEND_SRCALPHA: return PIPE_BLENDFACTOR_SRC_ALPHA; | |||
case D3DBLEND_INVSRCALPHA: return PIPE_BLENDFACTOR_INV_SRC_ALPHA; | |||
case D3DBLEND_DESTALPHA: return PIPE_BLENDFACTOR_DST_ALPHA; | |||
case D3DBLEND_INVDESTALPHA: return PIPE_BLENDFACTOR_INV_DST_ALPHA; | |||
case D3DBLEND_DESTCOLOR: return PIPE_BLENDFACTOR_DST_COLOR/*ALPHA*/; | |||
case D3DBLEND_INVDESTCOLOR: return PIPE_BLENDFACTOR_INV_DST_COLOR/*ALPHA*/; | |||
case D3DBLEND_SRCALPHASAT: return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE; | |||
case D3DBLEND_BOTHSRCALPHA: return PIPE_BLENDFACTOR_SRC_ALPHA; | |||
case D3DBLEND_BOTHINVSRCALPHA: return PIPE_BLENDFACTOR_INV_SRC_ALPHA; | |||
case D3DBLEND_BLENDFACTOR: return PIPE_BLENDFACTOR_CONST_COLOR/*ALPHA*/; | |||
case D3DBLEND_INVBLENDFACTOR: return PIPE_BLENDFACTOR_INV_CONST_COLOR/*ALPHA*/; | |||
case D3DBLEND_SRCCOLOR2: return PIPE_BLENDFACTOR_ONE; /* XXX */ | |||
case D3DBLEND_INVSRCCOLOR2: return PIPE_BLENDFACTOR_ZERO; /* XXX */ | |||
default: | |||
DBG_FLAG(DBG_UNKNOWN, "Unhandled blend factor %d\n", b); | |||
return PIPE_BLENDFACTOR_ZERO; | |||
} | |||
} | |||
static INLINE unsigned | |||
d3dblend_color_to_pipe_blendfactor(D3DBLEND b) | |||
{ | |||
switch (b) { | |||
case D3DBLEND_ZERO: return PIPE_BLENDFACTOR_ZERO; | |||
case D3DBLEND_ONE: return PIPE_BLENDFACTOR_ONE; | |||
case D3DBLEND_SRCCOLOR: return PIPE_BLENDFACTOR_SRC_COLOR; | |||
case D3DBLEND_INVSRCCOLOR: return PIPE_BLENDFACTOR_INV_SRC_COLOR; | |||
case D3DBLEND_SRCALPHA: return PIPE_BLENDFACTOR_SRC_ALPHA; | |||
case D3DBLEND_INVSRCALPHA: return PIPE_BLENDFACTOR_INV_SRC_ALPHA; | |||
case D3DBLEND_DESTALPHA: return PIPE_BLENDFACTOR_DST_ALPHA; | |||
case D3DBLEND_INVDESTALPHA: return PIPE_BLENDFACTOR_INV_DST_ALPHA; | |||
case D3DBLEND_DESTCOLOR: return PIPE_BLENDFACTOR_DST_COLOR; | |||
case D3DBLEND_INVDESTCOLOR: return PIPE_BLENDFACTOR_INV_DST_COLOR; | |||
case D3DBLEND_SRCALPHASAT: return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE; | |||
case D3DBLEND_BOTHSRCALPHA: return PIPE_BLENDFACTOR_SRC_ALPHA; | |||
case D3DBLEND_BOTHINVSRCALPHA: return PIPE_BLENDFACTOR_INV_SRC_ALPHA; | |||
case D3DBLEND_BLENDFACTOR: return PIPE_BLENDFACTOR_CONST_COLOR; | |||
case D3DBLEND_INVBLENDFACTOR: return PIPE_BLENDFACTOR_INV_CONST_COLOR; | |||
case D3DBLEND_SRCCOLOR2: return PIPE_BLENDFACTOR_SRC1_COLOR; | |||
case D3DBLEND_INVSRCCOLOR2: return PIPE_BLENDFACTOR_INV_SRC1_COLOR; | |||
default: | |||
DBG_FLAG(DBG_UNKNOWN, "Unhandled blend factor %d\n", b); | |||
return PIPE_BLENDFACTOR_ZERO; | |||
} | |||
} | |||
static INLINE unsigned | |||
d3dtextureaddress_to_pipe_tex_wrap(D3DTEXTUREADDRESS addr) | |||
{ | |||
switch (addr) { | |||
case D3DTADDRESS_WRAP: return PIPE_TEX_WRAP_REPEAT; | |||
case D3DTADDRESS_MIRROR: return PIPE_TEX_WRAP_MIRROR_REPEAT; | |||
case D3DTADDRESS_CLAMP: return PIPE_TEX_WRAP_CLAMP_TO_EDGE; | |||
case D3DTADDRESS_BORDER: return PIPE_TEX_WRAP_CLAMP_TO_BORDER; | |||
case D3DTADDRESS_MIRRORONCE: return PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE; | |||
default: | |||
assert(0); | |||
return PIPE_TEX_WRAP_CLAMP_TO_EDGE; | |||
} | |||
} | |||
static INLINE unsigned | |||
d3dtexturefiltertype_to_pipe_tex_filter(D3DTEXTUREFILTERTYPE filter) | |||
{ | |||
switch (filter) { | |||
case D3DTEXF_POINT: return PIPE_TEX_FILTER_NEAREST; | |||
case D3DTEXF_LINEAR: return PIPE_TEX_FILTER_LINEAR; | |||
case D3DTEXF_ANISOTROPIC: return PIPE_TEX_FILTER_LINEAR; | |||
case D3DTEXF_NONE: | |||
case D3DTEXF_PYRAMIDALQUAD: | |||
case D3DTEXF_GAUSSIANQUAD: | |||
case D3DTEXF_CONVOLUTIONMONO: | |||
default: | |||
assert(0); | |||
return PIPE_TEX_FILTER_NEAREST; | |||
} | |||
} | |||
static INLINE unsigned | |||
d3dtexturefiltertype_to_pipe_tex_mipfilter(D3DTEXTUREFILTERTYPE filter) | |||
{ | |||
switch (filter) { | |||
case D3DTEXF_NONE: return PIPE_TEX_MIPFILTER_NONE; | |||
case D3DTEXF_POINT: return PIPE_TEX_FILTER_NEAREST; | |||
case D3DTEXF_LINEAR: return PIPE_TEX_FILTER_LINEAR; | |||
case D3DTEXF_ANISOTROPIC: return PIPE_TEX_FILTER_LINEAR; | |||
case D3DTEXF_PYRAMIDALQUAD: | |||
case D3DTEXF_GAUSSIANQUAD: | |||
case D3DTEXF_CONVOLUTIONMONO: | |||
default: | |||
assert(0); | |||
return PIPE_TEX_MIPFILTER_NONE; | |||
} | |||
} | |||
#endif /* _NINE_PIPE_H_ */ |
@@ -0,0 +1,49 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "nine_quirk.h" | |||
#include "util/u_debug.h" | |||
static const struct debug_named_value nine_quirk_table[] = { | |||
{ "fakecaps", QUIRK_FAKE_CAPS, | |||
"Fake caps to emulate D3D specs regardless of hardware caps." }, | |||
{ "lenientshader", QUIRK_LENIENT_SHADER, | |||
"Be lenient when translating shaders." }, | |||
{ "all", ~0U, | |||
"Enable all quirks." }, | |||
DEBUG_NAMED_VALUE_END | |||
}; | |||
boolean | |||
_nine_get_quirk( unsigned quirk ) | |||
{ | |||
static boolean first = TRUE; | |||
static unsigned long flags = 0; | |||
if (first) { | |||
first = FALSE; | |||
flags = debug_get_flags_option("NINE_QUIRKS", nine_quirk_table, 0); | |||
} | |||
return !!(flags & quirk); | |||
} |
@@ -0,0 +1,36 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_QUIRK_H_ | |||
#define _NINE_QUIRK_H_ | |||
#include "pipe/p_compiler.h" | |||
boolean | |||
_nine_get_quirk( unsigned quirk ); | |||
#define QUIRK(q) (_nine_get_quirk(QUIRK_##q)) | |||
#define QUIRK_FAKE_CAPS 0x00000001 | |||
#define QUIRK_LENIENT_SHADER 0x00000002 | |||
#endif /* _NINE_QUIRK_H_ */ |
@@ -0,0 +1,142 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_SHADER_H_ | |||
#define _NINE_SHADER_H_ | |||
#include "d3d9types.h" | |||
#include "d3d9caps.h" | |||
#include "nine_defines.h" | |||
#include "pipe/p_state.h" /* PIPE_MAX_ATTRIBS */ | |||
#include "util/u_memory.h" | |||
struct NineDevice9; | |||
struct nine_lconstf /* NOTE: both pointers should be FREE'd by the user */ | |||
{ | |||
struct nine_range *ranges; /* single MALLOC, but next-pointers valid */ | |||
float *data; | |||
}; | |||
struct nine_shader_info | |||
{ | |||
unsigned type; /* in, PIPE_SHADER_x */ | |||
uint8_t version; /* (major << 4) | minor */ | |||
const DWORD *byte_code; /* in, pointer to shader tokens */ | |||
DWORD byte_size; /* out, size of data at byte_code */ | |||
void *cso; /* out, pipe cso for bind_vs,fs_state */ | |||
uint8_t input_map[PIPE_MAX_ATTRIBS]; /* VS input -> NINE_DECLUSAGE_x */ | |||
uint8_t num_inputs; /* there may be unused inputs (NINE_DECLUSAGE_NONE) */ | |||
boolean position_t; /* out, true if VP writes pre-transformed position */ | |||
boolean point_size; /* out, true if VP writes point size */ | |||
uint32_t sampler_ps1xtypes; /* 2 bits per sampler */ | |||
uint16_t sampler_mask; /* out, which samplers are being used */ | |||
uint16_t sampler_mask_shadow; /* in, which samplers use depth compare */ | |||
uint8_t rt_mask; /* out, which render targets are being written */ | |||
unsigned const_i_base; /* in vec4 (16 byte) units */ | |||
unsigned const_b_base; /* in vec4 (16 byte) units */ | |||
unsigned const_used_size; | |||
struct nine_lconstf lconstf; /* out, NOTE: members to be free'd by user */ | |||
}; | |||
static INLINE void | |||
nine_info_mark_const_f_used(struct nine_shader_info *info, int idx) | |||
{ | |||
unsigned size = (idx + 1) * 16; | |||
if (info->const_used_size < size) | |||
info->const_used_size = size; | |||
} | |||
static INLINE void | |||
nine_info_mark_const_i_used(struct nine_shader_info *info, int idx) | |||
{ | |||
unsigned size = (info->const_i_base + (idx + 1)) * 16; | |||
if (info->const_used_size < size) | |||
info->const_used_size = size; | |||
} | |||
static INLINE void | |||
nine_info_mark_const_b_used(struct nine_shader_info *info, int idx) | |||
{ | |||
unsigned size = (info->const_b_base + ((idx + 4) / 4)) * 16; | |||
if (info->const_used_size < size) | |||
info->const_used_size = size; | |||
} | |||
HRESULT | |||
nine_translate_shader(struct NineDevice9 *device, struct nine_shader_info *); | |||
struct nine_shader_variant | |||
{ | |||
struct nine_shader_variant *next; | |||
void *cso; | |||
uint32_t key; | |||
}; | |||
static INLINE void * | |||
nine_shader_variant_get(struct nine_shader_variant *list, uint32_t key) | |||
{ | |||
while (list->key != key && list->next) | |||
list = list->next; | |||
if (list->key == key) | |||
return list->cso; | |||
return NULL; | |||
} | |||
static INLINE boolean | |||
nine_shader_variant_add(struct nine_shader_variant *list, | |||
uint32_t key, void *cso) | |||
{ | |||
while (list->next) { | |||
assert(list->key != key); | |||
list = list->next; | |||
} | |||
list->next = MALLOC_STRUCT(nine_shader_variant); | |||
if (!list->next) | |||
return FALSE; | |||
list->next->next = NULL; | |||
list->next->key = key; | |||
list->next->cso = cso; | |||
return TRUE; | |||
} | |||
static INLINE void | |||
nine_shader_variants_free(struct nine_shader_variant *list) | |||
{ | |||
while (list->next) { | |||
struct nine_shader_variant *ptr = list->next; | |||
list->next = ptr->next; | |||
FREE(ptr); | |||
} | |||
} | |||
#endif /* _NINE_SHADER_H_ */ |
@@ -0,0 +1,234 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_STATE_H_ | |||
#define _NINE_STATE_H_ | |||
#include "d3d9.h" | |||
#include "nine_defines.h" | |||
#include "pipe/p_state.h" | |||
#include "util/u_double_list.h" | |||
#define NINED3DSAMP_MINLOD (D3DSAMP_DMAPOFFSET + 1) | |||
#define NINED3DSAMP_SHADOW (D3DSAMP_DMAPOFFSET + 2) | |||
#define NINED3DRS_VSPOINTSIZE (D3DRS_BLENDOPALPHA + 1) | |||
#define NINED3DRS_RTMASK (D3DRS_BLENDOPALPHA + 2) | |||
#define NINED3DRS_ZBIASSCALE (D3DRS_BLENDOPALPHA + 3) | |||
#define D3DRS_LAST D3DRS_BLENDOPALPHA | |||
#define NINED3DRS_LAST NINED3DRS_ZBIASSCALE /* 212 */ | |||
#define NINED3DSAMP_LAST NINED3DSAMP_SHADOW /* 15 */ | |||
#define NINED3DTSS_LAST D3DTSS_CONSTANT | |||
#define NINED3DTS_LAST D3DTS_WORLDMATRIX(255) | |||
#define D3DRS_COUNT (D3DRS_LAST + 1) | |||
#define NINED3DRS_COUNT (NINED3DRS_LAST + 1) | |||
#define NINED3DSAMP_COUNT (NINED3DSAMP_LAST + 1) | |||
#define NINED3DTSS_COUNT (NINED3DTSS_LAST + 1) | |||
#define NINED3DTS_COUNT (NINED3DTS_LAST + 1) | |||
#define NINE_STATE_FB (1 << 0) | |||
#define NINE_STATE_VIEWPORT (1 << 1) | |||
#define NINE_STATE_SCISSOR (1 << 2) | |||
#define NINE_STATE_RASTERIZER (1 << 3) | |||
#define NINE_STATE_BLEND (1 << 4) | |||
#define NINE_STATE_DSA (1 << 5) | |||
#define NINE_STATE_VS (1 << 6) | |||
#define NINE_STATE_VS_CONST (1 << 7) | |||
#define NINE_STATE_PS (1 << 8) | |||
#define NINE_STATE_PS_CONST (1 << 9) | |||
#define NINE_STATE_TEXTURE (1 << 10) | |||
#define NINE_STATE_SAMPLER (1 << 11) | |||
#define NINE_STATE_VDECL (1 << 12) | |||
#define NINE_STATE_IDXBUF (1 << 13) | |||
#define NINE_STATE_PRIM (1 << 14) | |||
#define NINE_STATE_MATERIAL (1 << 15) | |||
#define NINE_STATE_BLEND_COLOR (1 << 16) | |||
#define NINE_STATE_STENCIL_REF (1 << 17) | |||
#define NINE_STATE_SAMPLE_MASK (1 << 18) | |||
#define NINE_STATE_MISC_CONST (1 << 19) | |||
#define NINE_STATE_FF (0x1f << 20) | |||
#define NINE_STATE_FF_VS (0x17 << 20) | |||
#define NINE_STATE_FF_PS (0x18 << 20) | |||
#define NINE_STATE_FF_LIGHTING (1 << 20) | |||
#define NINE_STATE_FF_MATERIAL (1 << 21) | |||
#define NINE_STATE_FF_VSTRANSF (1 << 22) | |||
#define NINE_STATE_FF_PSSTAGES (1 << 23) | |||
#define NINE_STATE_FF_OTHER (1 << 24) | |||
#define NINE_STATE_ALL 0x1ffffff | |||
#define NINE_STATE_UNHANDLED (1 << 25) | |||
#define NINE_MAX_SIMULTANEOUS_RENDERTARGETS 4 | |||
#define NINE_MAX_CONST_F 256 | |||
#define NINE_MAX_CONST_I 16 | |||
#define NINE_MAX_CONST_B 16 | |||
#define NINE_MAX_CONST_ALL 276 /* B consts count only 1/4 th */ | |||
#define NINE_CONST_I_BASE(nconstf) \ | |||
((nconstf) * 4 * sizeof(float)) | |||
#define NINE_CONST_B_BASE(nconstf) \ | |||
((nconstf) * 4 * sizeof(float) + \ | |||
NINE_MAX_CONST_I * 4 * sizeof(int)) | |||
#define NINE_CONSTBUF_SIZE(nconstf) \ | |||
((nconstf) * 4 * sizeof(float) + \ | |||
NINE_MAX_CONST_I * 4 * sizeof(int) + \ | |||
NINE_MAX_CONST_B * 1 * sizeof(float)) | |||
#define NINE_MAX_LIGHTS 65536 | |||
#define NINE_MAX_LIGHTS_ACTIVE 8 | |||
#define NINED3DLIGHT_INVALID (D3DLIGHT_DIRECTIONAL + 1) | |||
#define NINE_MAX_SAMPLERS_PS 16 | |||
#define NINE_MAX_SAMPLERS_VS 4 | |||
#define NINE_MAX_SAMPLERS 21 /* PS + DMAP + VS */ | |||
#define NINE_SAMPLER_PS(s) ( 0 + (s)) | |||
#define NINE_SAMPLER_DMAP 16 | |||
#define NINE_SAMPLER_VS(s) (17 + (s)) | |||
#define NINE_PS_SAMPLERS_MASK 0x00ffff | |||
#define NINE_VS_SAMPLERS_MASK 0x1e0000 | |||
struct nine_state | |||
{ | |||
struct { | |||
uint32_t group; | |||
uint32_t rs[(NINED3DRS_COUNT + 31) / 32]; | |||
uint32_t vtxbuf; | |||
uint32_t stream_freq; | |||
uint32_t texture; | |||
uint16_t sampler[NINE_MAX_SAMPLERS]; | |||
struct nine_range *vs_const_f; | |||
struct nine_range *ps_const_f; | |||
uint16_t vs_const_i; /* NINE_MAX_CONST_I == 16 */ | |||
uint16_t ps_const_i; | |||
uint16_t vs_const_b; /* NINE_MAX_CONST_B == 16 */ | |||
uint16_t ps_const_b; | |||
uint8_t ucp; | |||
} changed; | |||
struct NineSurface9 *rt[NINE_MAX_SIMULTANEOUS_RENDERTARGETS]; | |||
struct NineSurface9 *ds; | |||
D3DVIEWPORT9 viewport; | |||
struct pipe_scissor_state scissor; | |||
/* NOTE: vs, ps will be NULL for FF and are set in device->ff.vs,ps instead | |||
* (XXX: or is it better to reference FF shaders here, too ?) | |||
* NOTE: const_f contains extra space for const_i,b to use as user constbuf | |||
*/ | |||
struct NineVertexShader9 *vs; | |||
float *vs_const_f; | |||
int vs_const_i[NINE_MAX_CONST_I][4]; | |||
BOOL vs_const_b[NINE_MAX_CONST_B]; | |||
uint32_t vs_key; | |||
struct NinePixelShader9 *ps; | |||
float *ps_const_f; | |||
int ps_const_i[NINE_MAX_CONST_I][4]; | |||
BOOL ps_const_b[NINE_MAX_CONST_B]; | |||
uint32_t ps_key; | |||
struct { | |||
void *vs; | |||
void *ps; | |||
} cso; | |||
struct NineVertexDeclaration9 *vdecl; | |||
struct NineIndexBuffer9 *idxbuf; | |||
struct NineVertexBuffer9 *stream[PIPE_MAX_ATTRIBS]; | |||
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; | |||
UINT stream_freq[PIPE_MAX_ATTRIBS]; | |||
uint32_t stream_instancedata_mask; /* derived from stream_freq */ | |||
uint32_t stream_usage_mask; /* derived from VS and vdecl */ | |||
struct pipe_clip_state clip; | |||
struct pipe_framebuffer_state fb; | |||
uint8_t rt_mask; | |||
DWORD rs[NINED3DRS_COUNT]; | |||
struct NineBaseTexture9 *texture[NINE_MAX_SAMPLERS]; /* PS, DMAP, VS */ | |||
DWORD samp[NINE_MAX_SAMPLERS][NINED3DSAMP_COUNT]; | |||
uint32_t samplers_shadow; | |||
struct { | |||
struct { | |||
uint32_t group; | |||
uint32_t tex_stage[NINE_MAX_SAMPLERS][(NINED3DTSS_COUNT + 31) / 32]; | |||
uint32_t transform[(NINED3DTS_COUNT + 31) / 32]; | |||
} changed; | |||
struct { | |||
boolean vs_const; | |||
boolean ps_const; | |||
} clobber; | |||
D3DMATRIX *transform; /* access only via nine_state_access_transform */ | |||
unsigned num_transforms; | |||
/* XXX: Do state blocks just change the set of active lights or do we | |||
* have to store which lights have been disabled, too ? | |||
*/ | |||
D3DLIGHT9 *light; | |||
uint16_t active_light[NINE_MAX_LIGHTS_ACTIVE]; /* 8 */ | |||
unsigned num_lights; | |||
unsigned num_lights_active; | |||
D3DMATERIAL9 material; | |||
DWORD tex_stage[NINE_MAX_SAMPLERS][NINED3DTSS_COUNT]; | |||
} ff; | |||
}; | |||
/* map D3DRS -> NINE_STATE_x | |||
*/ | |||
extern const uint32_t nine_render_state_group[NINED3DRS_COUNT]; | |||
/* for D3DSBT_PIXEL/VERTEX: | |||
*/ | |||
extern const uint32_t nine_render_states_pixel[(NINED3DRS_COUNT + 31) / 32]; | |||
extern const uint32_t nine_render_states_vertex[(NINED3DRS_COUNT + 31) / 32]; | |||
struct NineDevice9; | |||
boolean nine_update_state(struct NineDevice9 *, uint32_t group_mask); | |||
void nine_state_set_defaults(struct nine_state *, const D3DCAPS9 *, | |||
boolean is_reset); | |||
void nine_state_clear(struct nine_state *, const boolean device); | |||
/* If @alloc is FALSE, the return value may be a const identity matrix. | |||
* Therefore, do not modify if you set alloc to FALSE ! | |||
*/ | |||
D3DMATRIX * | |||
nine_state_access_transform(struct nine_state *, D3DTRANSFORMSTATETYPE, | |||
boolean alloc); | |||
const char *nine_d3drs_to_string(DWORD State); | |||
#endif /* _NINE_STATE_H_ */ |
@@ -0,0 +1,46 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "nineexoverlayextension.h" | |||
#define DBG_CHANNEL DBG_OVERLAYEXTENSION | |||
HRESULT WINAPI | |||
Nine9ExOverlayExtension_CheckDeviceOverlayType( struct Nine9ExOverlayExtension *This, | |||
UINT Adapter, | |||
D3DDEVTYPE DevType, | |||
UINT OverlayWidth, | |||
UINT OverlayHeight, | |||
D3DFORMAT OverlayFormat, | |||
D3DDISPLAYMODEEX *pDisplayMode, | |||
D3DDISPLAYROTATION DisplayRotation, | |||
D3DOVERLAYCAPS *pOverlayCaps ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
IDirect3D9ExOverlayExtensionVtbl Nine9ExOverlayExtension_vtable = { | |||
(void *)NineUnknown_QueryInterface, | |||
(void *)NineUnknown_AddRef, | |||
(void *)NineUnknown_Release, | |||
(void *)Nine9ExOverlayExtension_CheckDeviceOverlayType | |||
}; |
@@ -0,0 +1,49 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_NINEEXOVERLAYEXTENSION_H_ | |||
#define _NINE_NINEEXOVERLAYEXTENSION_H_ | |||
#include "iunknown.h" | |||
struct Nine9ExOverlayExtension | |||
{ | |||
struct NineUnknown base; | |||
}; | |||
static INLINE struct Nine9ExOverlayExtension * | |||
Nine9ExOverlayExtension( void *data ) | |||
{ | |||
return (struct Nine9ExOverlayExtension *)data; | |||
} | |||
HRESULT WINAPI | |||
Nine9ExOverlayExtension_CheckDeviceOverlayType( struct Nine9ExOverlayExtension *This, | |||
UINT Adapter, | |||
D3DDEVTYPE DevType, | |||
UINT OverlayWidth, | |||
UINT OverlayHeight, | |||
D3DFORMAT OverlayFormat, | |||
D3DDISPLAYMODEEX *pDisplayMode, | |||
D3DDISPLAYROTATION DisplayRotation, | |||
D3DOVERLAYCAPS *pOverlayCaps ); | |||
#endif /* _NINE_NINEEXOVERLAYEXTENSION_H_ */ |
@@ -0,0 +1,172 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "nine_helpers.h" | |||
#include "nine_shader.h" | |||
#include "pixelshader9.h" | |||
#include "device9.h" | |||
#include "pipe/p_context.h" | |||
#define DBG_CHANNEL DBG_PIXELSHADER | |||
HRESULT | |||
NinePixelShader9_ctor( struct NinePixelShader9 *This, | |||
struct NineUnknownParams *pParams, | |||
const DWORD *pFunction, void *cso ) | |||
{ | |||
struct NineDevice9 *device; | |||
struct nine_shader_info info; | |||
HRESULT hr; | |||
hr = NineUnknown_ctor(&This->base, pParams); | |||
if (FAILED(hr)) | |||
return hr; | |||
if (cso) { | |||
This->variant.cso = cso; | |||
return D3D_OK; | |||
} | |||
device = This->base.device; | |||
info.type = PIPE_SHADER_FRAGMENT; | |||
info.byte_code = pFunction; | |||
info.const_i_base = NINE_CONST_I_BASE(device->max_ps_const_f) / 16; | |||
info.const_b_base = NINE_CONST_B_BASE(device->max_ps_const_f) / 16; | |||
info.sampler_mask_shadow = 0x0; | |||
info.sampler_ps1xtypes = 0x0; | |||
hr = nine_translate_shader(device, &info); | |||
if (FAILED(hr)) | |||
return hr; | |||
This->byte_code.version = info.version; | |||
This->byte_code.tokens = mem_dup(pFunction, info.byte_size); | |||
if (!This->byte_code.tokens) | |||
return E_OUTOFMEMORY; | |||
This->byte_code.size = info.byte_size; | |||
This->variant.cso = info.cso; | |||
This->sampler_mask = info.sampler_mask; | |||
This->rt_mask = info.rt_mask; | |||
This->const_used_size = info.const_used_size; | |||
if (info.const_used_size == ~0) | |||
This->const_used_size = NINE_CONSTBUF_SIZE(device->max_ps_const_f); | |||
This->lconstf = info.lconstf; | |||
return D3D_OK; | |||
} | |||
void | |||
NinePixelShader9_dtor( struct NinePixelShader9 *This ) | |||
{ | |||
DBG("This=%p cso=%p\n", This, This->variant.cso); | |||
if (This->base.device) { | |||
struct pipe_context *pipe = This->base.device->pipe; | |||
struct nine_shader_variant *var = &This->variant; | |||
do { | |||
if (var->cso) { | |||
if (This->base.device->state.cso.ps == var->cso) | |||
pipe->bind_fs_state(pipe, NULL); | |||
pipe->delete_fs_state(pipe, var->cso); | |||
} | |||
var = var->next; | |||
} while (var); | |||
} | |||
nine_shader_variants_free(&This->variant); | |||
if (This->byte_code.tokens) | |||
FREE((void *)This->byte_code.tokens); /* const_cast */ | |||
FREE(This->lconstf.data); | |||
FREE(This->lconstf.ranges); | |||
NineUnknown_dtor(&This->base); | |||
} | |||
HRESULT WINAPI | |||
NinePixelShader9_GetFunction( struct NinePixelShader9 *This, | |||
void *pData, | |||
UINT *pSizeOfData ) | |||
{ | |||
user_assert(pSizeOfData, D3DERR_INVALIDCALL); | |||
if (!pData) { | |||
*pSizeOfData = This->byte_code.size; | |||
return D3D_OK; | |||
} | |||
user_assert(*pSizeOfData >= This->byte_code.size, D3DERR_INVALIDCALL); | |||
memcpy(pData, This->byte_code.tokens, This->byte_code.size); | |||
return D3D_OK; | |||
} | |||
void * | |||
NinePixelShader9_GetVariant( struct NinePixelShader9 *This, | |||
uint32_t key ) | |||
{ | |||
void *cso = nine_shader_variant_get(&This->variant, key); | |||
if (!cso) { | |||
struct NineDevice9 *device = This->base.device; | |||
struct nine_shader_info info; | |||
HRESULT hr; | |||
info.type = PIPE_SHADER_FRAGMENT; | |||
info.const_i_base = NINE_CONST_I_BASE(device->max_ps_const_f) / 16; | |||
info.const_b_base = NINE_CONST_B_BASE(device->max_ps_const_f) / 16; | |||
info.byte_code = This->byte_code.tokens; | |||
info.sampler_mask_shadow = key & 0xffff; | |||
info.sampler_ps1xtypes = key; | |||
hr = nine_translate_shader(This->base.device, &info); | |||
if (FAILED(hr)) | |||
return NULL; | |||
nine_shader_variant_add(&This->variant, key, info.cso); | |||
cso = info.cso; | |||
} | |||
return cso; | |||
} | |||
IDirect3DPixelShader9Vtbl NinePixelShader9_vtable = { | |||
(void *)NineUnknown_QueryInterface, | |||
(void *)NineUnknown_AddRef, | |||
(void *)NineUnknown_Release, | |||
(void *)NineUnknown_GetDevice, | |||
(void *)NinePixelShader9_GetFunction | |||
}; | |||
static const GUID *NinePixelShader9_IIDs[] = { | |||
&IID_IDirect3DPixelShader9, | |||
&IID_IUnknown, | |||
NULL | |||
}; | |||
HRESULT | |||
NinePixelShader9_new( struct NineDevice9 *pDevice, | |||
struct NinePixelShader9 **ppOut, | |||
const DWORD *pFunction, void *cso ) | |||
{ | |||
NINE_DEVICE_CHILD_NEW(PixelShader9, ppOut, pDevice, pFunction, cso); | |||
} |
@@ -0,0 +1,82 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_PIXELSHADER9_H_ | |||
#define _NINE_PIXELSHADER9_H_ | |||
#include "iunknown.h" | |||
#include "nine_shader.h" | |||
struct nine_lconstf; | |||
struct NinePixelShader9 | |||
{ | |||
struct NineUnknown base; | |||
struct nine_shader_variant variant; | |||
struct { | |||
const DWORD *tokens; | |||
DWORD size; | |||
uint8_t version; /* (major << 4) | minor */ | |||
} byte_code; | |||
unsigned const_used_size; /* in bytes */ | |||
struct nine_lconstf lconstf; | |||
uint16_t sampler_mask; | |||
uint16_t sampler_mask_shadow; | |||
uint8_t rt_mask; | |||
uint64_t ff_key[6]; | |||
}; | |||
static INLINE struct NinePixelShader9 * | |||
NinePixelShader9( void *data ) | |||
{ | |||
return (struct NinePixelShader9 *)data; | |||
} | |||
void * | |||
NinePixelShader9_GetVariant( struct NinePixelShader9 *vs, | |||
uint32_t key ); | |||
/*** public ***/ | |||
HRESULT | |||
NinePixelShader9_new( struct NineDevice9 *pDevice, | |||
struct NinePixelShader9 **ppOut, | |||
const DWORD *pFunction, void *cso ); | |||
HRESULT | |||
NinePixelShader9_ctor( struct NinePixelShader9 *, | |||
struct NineUnknownParams *pParams, | |||
const DWORD *pFunction, void *cso ); | |||
void | |||
NinePixelShader9_dtor( struct NinePixelShader9 * ); | |||
HRESULT WINAPI | |||
NinePixelShader9_GetFunction( struct NinePixelShader9 *This, | |||
void *pData, | |||
UINT *pSizeOfData ); | |||
#endif /* _NINE_PIXELSHADER9_H_ */ |
@@ -0,0 +1,358 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "device9.h" | |||
#include "query9.h" | |||
#include "nine_helpers.h" | |||
#include "pipe/p_context.h" | |||
#include "util/u_math.h" | |||
#include "nine_dump.h" | |||
#define DBG_CHANNEL DBG_QUERY | |||
#define QUERY_TYPE_MAP_CASE(a, b) case D3DQUERYTYPE_##a: return PIPE_QUERY_##b | |||
static inline unsigned | |||
d3dquerytype_to_pipe_query(D3DQUERYTYPE type) | |||
{ | |||
switch (type) { | |||
QUERY_TYPE_MAP_CASE(EVENT, GPU_FINISHED); | |||
QUERY_TYPE_MAP_CASE(OCCLUSION, OCCLUSION_COUNTER); | |||
QUERY_TYPE_MAP_CASE(TIMESTAMP, TIMESTAMP); | |||
QUERY_TYPE_MAP_CASE(TIMESTAMPDISJOINT, TIMESTAMP_DISJOINT); | |||
QUERY_TYPE_MAP_CASE(TIMESTAMPFREQ, TIMESTAMP_DISJOINT); | |||
QUERY_TYPE_MAP_CASE(VERTEXSTATS, PIPELINE_STATISTICS); | |||
case D3DQUERYTYPE_VCACHE: | |||
case D3DQUERYTYPE_RESOURCEMANAGER: | |||
case D3DQUERYTYPE_PIPELINETIMINGS: | |||
case D3DQUERYTYPE_INTERFACETIMINGS: | |||
case D3DQUERYTYPE_VERTEXTIMINGS: | |||
case D3DQUERYTYPE_PIXELTIMINGS: | |||
case D3DQUERYTYPE_BANDWIDTHTIMINGS: | |||
case D3DQUERYTYPE_CACHEUTILIZATION: | |||
return PIPE_QUERY_TYPES; | |||
default: | |||
return ~0; | |||
} | |||
} | |||
#define GET_DATA_SIZE_CASE9(a) case D3DQUERYTYPE_##a: return sizeof(D3DDEVINFO_D3D9##a) | |||
#define GET_DATA_SIZE_CASE1(a) case D3DQUERYTYPE_##a: return sizeof(D3DDEVINFO_##a) | |||
#define GET_DATA_SIZE_CASE2(a, b) case D3DQUERYTYPE_##a: return sizeof(D3DDEVINFO_##b) | |||
#define GET_DATA_SIZE_CASET(a, b) case D3DQUERYTYPE_##a: return sizeof(b) | |||
static INLINE DWORD | |||
nine_query_result_size(D3DQUERYTYPE type) | |||
{ | |||
switch (type) { | |||
GET_DATA_SIZE_CASE1(VCACHE); | |||
GET_DATA_SIZE_CASE1(RESOURCEMANAGER); | |||
GET_DATA_SIZE_CASE2(VERTEXSTATS, D3DVERTEXSTATS); | |||
GET_DATA_SIZE_CASET(EVENT, BOOL); | |||
GET_DATA_SIZE_CASET(OCCLUSION, DWORD); | |||
GET_DATA_SIZE_CASET(TIMESTAMP, UINT64); | |||
GET_DATA_SIZE_CASET(TIMESTAMPDISJOINT, BOOL); | |||
GET_DATA_SIZE_CASET(TIMESTAMPFREQ, UINT64); | |||
GET_DATA_SIZE_CASE9(PIPELINETIMINGS); | |||
GET_DATA_SIZE_CASE9(INTERFACETIMINGS); | |||
GET_DATA_SIZE_CASE2(VERTEXTIMINGS, D3D9STAGETIMINGS); | |||
GET_DATA_SIZE_CASE2(PIXELTIMINGS, D3D9STAGETIMINGS); | |||
GET_DATA_SIZE_CASE9(BANDWIDTHTIMINGS); | |||
GET_DATA_SIZE_CASE9(CACHEUTILIZATION); | |||
/* GET_DATA_SIZE_CASE1(MEMORYPRESSURE); Win7 only */ | |||
default: | |||
assert(0); | |||
return 0; | |||
} | |||
} | |||
HRESULT | |||
nine_is_query_supported(D3DQUERYTYPE type) | |||
{ | |||
const unsigned ptype = d3dquerytype_to_pipe_query(type); | |||
user_assert(ptype != ~0, D3DERR_INVALIDCALL); | |||
if (ptype == PIPE_QUERY_TYPES) { | |||
DBG("Query type %u (%s) not supported.\n", | |||
type, nine_D3DQUERYTYPE_to_str(type)); | |||
return D3DERR_NOTAVAILABLE; | |||
} | |||
return D3D_OK; | |||
} | |||
HRESULT | |||
NineQuery9_ctor( struct NineQuery9 *This, | |||
struct NineUnknownParams *pParams, | |||
D3DQUERYTYPE Type ) | |||
{ | |||
struct pipe_context *pipe = pParams->device->pipe; | |||
const unsigned ptype = d3dquerytype_to_pipe_query(Type); | |||
HRESULT hr; | |||
hr = NineUnknown_ctor(&This->base, pParams); | |||
if (FAILED(hr)) | |||
return hr; | |||
This->state = NINE_QUERY_STATE_FRESH; | |||
This->type = Type; | |||
user_assert(ptype != ~0, D3DERR_INVALIDCALL); | |||
if (ptype < PIPE_QUERY_TYPES) { | |||
This->pq = pipe->create_query(pipe, ptype, 0); | |||
if (!This->pq) | |||
return E_OUTOFMEMORY; | |||
} else { | |||
DBG("Returning dummy NineQuery9 for %s.\n", | |||
nine_D3DQUERYTYPE_to_str(Type)); | |||
} | |||
This->instant = | |||
Type == D3DQUERYTYPE_EVENT || | |||
Type == D3DQUERYTYPE_RESOURCEMANAGER || | |||
Type == D3DQUERYTYPE_TIMESTAMP || | |||
Type == D3DQUERYTYPE_TIMESTAMPFREQ || | |||
Type == D3DQUERYTYPE_VCACHE || | |||
Type == D3DQUERYTYPE_VERTEXSTATS; | |||
This->result_size = nine_query_result_size(Type); | |||
return D3D_OK; | |||
} | |||
void | |||
NineQuery9_dtor( struct NineQuery9 *This ) | |||
{ | |||
struct pipe_context *pipe = This->base.device->pipe; | |||
if (This->pq) { | |||
if (This->state == NINE_QUERY_STATE_RUNNING) | |||
pipe->end_query(pipe, This->pq); | |||
pipe->destroy_query(pipe, This->pq); | |||
} | |||
NineUnknown_dtor(&This->base); | |||
} | |||
D3DQUERYTYPE WINAPI | |||
NineQuery9_GetType( struct NineQuery9 *This ) | |||
{ | |||
return This->type; | |||
} | |||
DWORD WINAPI | |||
NineQuery9_GetDataSize( struct NineQuery9 *This ) | |||
{ | |||
return This->result_size; | |||
} | |||
HRESULT WINAPI | |||
NineQuery9_Issue( struct NineQuery9 *This, | |||
DWORD dwIssueFlags ) | |||
{ | |||
struct pipe_context *pipe = This->base.device->pipe; | |||
user_assert((dwIssueFlags == D3DISSUE_BEGIN && !This->instant) || | |||
(dwIssueFlags == 0) || | |||
(dwIssueFlags == D3DISSUE_END), D3DERR_INVALIDCALL); | |||
if (!This->pq) { | |||
DBG("Issued dummy query.\n"); | |||
return D3D_OK; | |||
} | |||
if (dwIssueFlags == D3DISSUE_BEGIN) { | |||
if (This->state == NINE_QUERY_STATE_RUNNING) { | |||
pipe->end_query(pipe, This->pq); | |||
} | |||
pipe->begin_query(pipe, This->pq); | |||
This->state = NINE_QUERY_STATE_RUNNING; | |||
} else { | |||
if (This->state == NINE_QUERY_STATE_RUNNING) { | |||
pipe->end_query(pipe, This->pq); | |||
This->state = NINE_QUERY_STATE_ENDED; | |||
} | |||
} | |||
return D3D_OK; | |||
} | |||
union nine_query_result | |||
{ | |||
D3DDEVINFO_D3DVERTEXSTATS vertexstats; | |||
D3DDEVINFO_D3D9BANDWIDTHTIMINGS bandwidth; | |||
D3DDEVINFO_VCACHE vcache; | |||
D3DDEVINFO_RESOURCEMANAGER rm; | |||
D3DDEVINFO_D3D9PIPELINETIMINGS pipe; | |||
D3DDEVINFO_D3D9STAGETIMINGS stage; | |||
D3DDEVINFO_D3D9INTERFACETIMINGS iface; | |||
D3DDEVINFO_D3D9CACHEUTILIZATION cacheu; | |||
DWORD dw; | |||
BOOL b; | |||
UINT64 u64; | |||
}; | |||
HRESULT WINAPI | |||
NineQuery9_GetData( struct NineQuery9 *This, | |||
void *pData, | |||
DWORD dwSize, | |||
DWORD dwGetDataFlags ) | |||
{ | |||
struct pipe_context *pipe = This->base.device->pipe; | |||
boolean ok = !This->pq; | |||
unsigned i; | |||
union pipe_query_result presult; | |||
union nine_query_result nresult; | |||
user_assert(This->state != NINE_QUERY_STATE_RUNNING, D3DERR_INVALIDCALL); | |||
user_assert(dwSize == 0 || pData, D3DERR_INVALIDCALL); | |||
user_assert(dwGetDataFlags == 0 || | |||
dwGetDataFlags == D3DGETDATA_FLUSH, D3DERR_INVALIDCALL); | |||
if (!This->pq) { | |||
DBG("No pipe query available.\n"); | |||
if (!dwSize) | |||
return S_OK; | |||
} | |||
if (This->state == NINE_QUERY_STATE_FRESH) | |||
return S_OK; | |||
if (!ok) { | |||
ok = pipe->get_query_result(pipe, This->pq, FALSE, &presult); | |||
if (!ok) { | |||
if (dwGetDataFlags) { | |||
if (This->state != NINE_QUERY_STATE_FLUSHED) | |||
pipe->flush(pipe, NULL, 0); | |||
This->state = NINE_QUERY_STATE_FLUSHED; | |||
} | |||
return S_FALSE; | |||
} | |||
} | |||
if (!dwSize) | |||
return S_OK; | |||
switch (This->type) { | |||
case D3DQUERYTYPE_EVENT: | |||
nresult.b = presult.b; | |||
break; | |||
case D3DQUERYTYPE_OCCLUSION: | |||
nresult.dw = presult.u64; | |||
break; | |||
case D3DQUERYTYPE_TIMESTAMP: | |||
nresult.u64 = presult.u64; | |||
break; | |||
case D3DQUERYTYPE_TIMESTAMPDISJOINT: | |||
nresult.b = presult.timestamp_disjoint.disjoint; | |||
break; | |||
case D3DQUERYTYPE_TIMESTAMPFREQ: | |||
nresult.u64 = presult.timestamp_disjoint.frequency; | |||
break; | |||
case D3DQUERYTYPE_VERTEXSTATS: | |||
nresult.vertexstats.NumRenderedTriangles = | |||
presult.pipeline_statistics.c_invocations; | |||
nresult.vertexstats.NumExtraClippingTriangles = | |||
presult.pipeline_statistics.c_primitives; | |||
break; | |||
/* Thse might be doable with driver-specific queries; dummy for now. */ | |||
case D3DQUERYTYPE_BANDWIDTHTIMINGS: | |||
nresult.bandwidth.MaxBandwidthUtilized = 1.0f; | |||
nresult.bandwidth.FrontEndUploadMemoryUtilizedPercent = 0.5f; | |||
nresult.bandwidth.VertexRateUtilizedPercent = 0.75f; | |||
nresult.bandwidth.TriangleSetupRateUtilizedPercent = 0.75f; | |||
nresult.bandwidth.FillRateUtilizedPercent = 1.0f; | |||
break; | |||
case D3DQUERYTYPE_VERTEXTIMINGS: | |||
case D3DQUERYTYPE_PIXELTIMINGS: | |||
nresult.stage.MemoryProcessingPercent = 0.5f; | |||
nresult.stage.ComputationProcessingPercent = 0.5f; | |||
break; | |||
case D3DQUERYTYPE_VCACHE: | |||
/* Are we supposed to fill this in ? */ | |||
nresult.vcache.Pattern = MAKEFOURCC('C', 'A', 'C', 'H'); | |||
nresult.vcache.OptMethod = 1; | |||
nresult.vcache.CacheSize = 32 << 10; | |||
nresult.vcache.MagicNumber = 0xdeadcafe; | |||
break; | |||
case D3DQUERYTYPE_RESOURCEMANAGER: | |||
/* We could record some of these in the device ... */ | |||
for (i = 0; i < D3DRTYPECOUNT; ++i) { | |||
nresult.rm.stats[i].bThrashing = FALSE; | |||
nresult.rm.stats[i].ApproxBytesDownloaded = 0; | |||
nresult.rm.stats[i].NumEvicts = 0; | |||
nresult.rm.stats[i].NumVidCreates = 0; | |||
nresult.rm.stats[i].LastPri = 0; | |||
nresult.rm.stats[i].NumUsed = 1; | |||
nresult.rm.stats[i].NumUsedInVidMem = 1; | |||
nresult.rm.stats[i].WorkingSet = 1; | |||
nresult.rm.stats[i].WorkingSetBytes = 1 << 20; | |||
nresult.rm.stats[i].TotalManaged = 1; | |||
nresult.rm.stats[i].TotalBytes = 1 << 20; | |||
} | |||
break; | |||
case D3DQUERYTYPE_PIPELINETIMINGS: | |||
nresult.pipe.VertexProcessingTimePercent = 0.4f; | |||
nresult.pipe.PixelProcessingTimePercent = 0.4f; | |||
nresult.pipe.OtherGPUProcessingTimePercent = 0.15f; | |||
nresult.pipe.GPUIdleTimePercent = 0.05f; | |||
break; | |||
case D3DQUERYTYPE_INTERFACETIMINGS: | |||
nresult.iface.WaitingForGPUToUseApplicationResourceTimePercent = 0.0f; | |||
nresult.iface.WaitingForGPUToAcceptMoreCommandsTimePercent = 0.0f; | |||
nresult.iface.WaitingForGPUToStayWithinLatencyTimePercent = 0.0f; | |||
nresult.iface.WaitingForGPUExclusiveResourceTimePercent = 0.0f; | |||
nresult.iface.WaitingForGPUOtherTimePercent = 0.0f; | |||
break; | |||
case D3DQUERYTYPE_CACHEUTILIZATION: | |||
nresult.cacheu.TextureCacheHitRate = 0.9f; | |||
nresult.cacheu.PostTransformVertexCacheHitRate = 0.3f; | |||
break; | |||
default: | |||
assert(0); | |||
break; | |||
} | |||
memcpy(pData, &nresult, MIN2(sizeof(nresult), dwSize)); | |||
return S_OK; | |||
} | |||
IDirect3DQuery9Vtbl NineQuery9_vtable = { | |||
(void *)NineUnknown_QueryInterface, | |||
(void *)NineUnknown_AddRef, | |||
(void *)NineUnknown_Release, | |||
(void *)NineUnknown_GetDevice, /* actually part of Query9 iface */ | |||
(void *)NineQuery9_GetType, | |||
(void *)NineQuery9_GetDataSize, | |||
(void *)NineQuery9_Issue, | |||
(void *)NineQuery9_GetData | |||
}; | |||
static const GUID *NineQuery9_IIDs[] = { | |||
&IID_IDirect3DQuery9, | |||
&IID_IUnknown, | |||
NULL | |||
}; | |||
HRESULT | |||
NineQuery9_new( struct NineDevice9 *pDevice, | |||
struct NineQuery9 **ppOut, | |||
D3DQUERYTYPE Type ) | |||
{ | |||
NINE_DEVICE_CHILD_NEW(Query9, ppOut, pDevice, Type); | |||
} |
@@ -0,0 +1,83 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_QUERY9_H_ | |||
#define _NINE_QUERY9_H_ | |||
#include "iunknown.h" | |||
enum nine_query_state | |||
{ | |||
NINE_QUERY_STATE_FRESH = 0, | |||
NINE_QUERY_STATE_RUNNING, | |||
NINE_QUERY_STATE_ENDED, | |||
NINE_QUERY_STATE_FLUSHED | |||
}; | |||
struct NineQuery9 | |||
{ | |||
struct NineUnknown base; | |||
struct pipe_query *pq; | |||
DWORD result_size; | |||
D3DQUERYTYPE type; | |||
enum nine_query_state state; | |||
boolean instant; /* true if D3DISSUE_BEGIN is not needed / invalid */ | |||
}; | |||
static INLINE struct NineQuery9 * | |||
NineQuery9( void *data ) | |||
{ | |||
return (struct NineQuery9 *)data; | |||
} | |||
HRESULT | |||
nine_is_query_supported(D3DQUERYTYPE); | |||
HRESULT | |||
NineQuery9_new( struct NineDevice9 *Device, | |||
struct NineQuery9 **ppOut, | |||
D3DQUERYTYPE); | |||
HRESULT | |||
NineQuery9_ctor( struct NineQuery9 *, | |||
struct NineUnknownParams *pParams, | |||
D3DQUERYTYPE Type ); | |||
void | |||
NineQuery9_dtor( struct NineQuery9 * ); | |||
D3DQUERYTYPE WINAPI | |||
NineQuery9_GetType( struct NineQuery9 *This ); | |||
DWORD WINAPI | |||
NineQuery9_GetDataSize( struct NineQuery9 *This ); | |||
HRESULT WINAPI | |||
NineQuery9_Issue( struct NineQuery9 *This, | |||
DWORD dwIssueFlags ); | |||
HRESULT WINAPI | |||
NineQuery9_GetData( struct NineQuery9 *This, | |||
void *pData, | |||
DWORD dwSize, | |||
DWORD dwGetDataFlags ); | |||
#endif /* _NINE_QUERY9_H_ */ |
@@ -0,0 +1,230 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "resource9.h" | |||
#include "device9.h" | |||
#include "nine_helpers.h" | |||
#include "nine_defines.h" | |||
#include "pipe/p_screen.h" | |||
#include "util/u_hash_table.h" | |||
#include "util/u_inlines.h" | |||
#include "nine_pdata.h" | |||
#define DBG_CHANNEL DBG_RESOURCE | |||
HRESULT | |||
NineResource9_ctor( struct NineResource9 *This, | |||
struct NineUnknownParams *pParams, | |||
BOOL Allocate, | |||
D3DRESOURCETYPE Type, | |||
D3DPOOL Pool ) | |||
{ | |||
struct pipe_screen *screen; | |||
HRESULT hr; | |||
hr = NineUnknown_ctor(&This->base, pParams); | |||
if (FAILED(hr)) | |||
return hr; | |||
This->info.screen = screen = This->base.device->screen; | |||
if (Allocate) { | |||
DBG("(%p) Creating pipe_resource.\n", This); | |||
This->resource = screen->resource_create(screen, &This->info); | |||
if (!This->resource) | |||
return D3DERR_OUTOFVIDEOMEMORY; | |||
} | |||
This->data = NULL; /* FIXME remove, rather set it to null in surface9.c*/ | |||
This->type = Type; | |||
This->pool = Pool; | |||
This->priority = 0; | |||
This->pdata = util_hash_table_create(ht_guid_hash, ht_guid_compare); | |||
if (!This->pdata) | |||
return E_OUTOFMEMORY; | |||
return D3D_OK; | |||
} | |||
void | |||
NineResource9_dtor( struct NineResource9 *This ) | |||
{ | |||
if (This->pdata) { | |||
util_hash_table_foreach(This->pdata, ht_guid_delete, NULL); | |||
util_hash_table_destroy(This->pdata); | |||
} | |||
/* NOTE: We do have to use refcounting, the driver might | |||
* still hold a reference. */ | |||
pipe_resource_reference(&This->resource, NULL); | |||
/* release allocated system memory for non-D3DPOOL_DEFAULT resources */ | |||
if (This->data) | |||
FREE(This->data); | |||
NineUnknown_dtor(&This->base); | |||
} | |||
struct pipe_resource * | |||
NineResource9_GetResource( struct NineResource9 *This ) | |||
{ | |||
return This->resource; | |||
} | |||
D3DPOOL | |||
NineResource9_GetPool( struct NineResource9 *This ) | |||
{ | |||
return This->pool; | |||
} | |||
HRESULT WINAPI | |||
NineResource9_SetPrivateData( struct NineResource9 *This, | |||
REFGUID refguid, | |||
const void *pData, | |||
DWORD SizeOfData, | |||
DWORD Flags ) | |||
{ | |||
enum pipe_error err; | |||
struct pheader *header; | |||
const void *user_data = pData; | |||
DBG("This=%p refguid=%p pData=%p SizeOfData=%u Flags=%x\n", | |||
This, refguid, pData, SizeOfData, Flags); | |||
if (Flags & D3DSPD_IUNKNOWN) | |||
user_assert(SizeOfData == sizeof(IUnknown *), D3DERR_INVALIDCALL); | |||
/* data consists of a header and the actual data. avoiding 2 mallocs */ | |||
header = CALLOC_VARIANT_LENGTH_STRUCT(pheader, SizeOfData-1); | |||
if (!header) { return E_OUTOFMEMORY; } | |||
header->unknown = (Flags & D3DSPD_IUNKNOWN) ? TRUE : FALSE; | |||
/* if the refguid already exists, delete it */ | |||
NineResource9_FreePrivateData(This, refguid); | |||
/* IUnknown special case */ | |||
if (header->unknown) { | |||
/* here the pointer doesn't point to the data we want, so point at the | |||
* pointer making what we eventually copy is the pointer itself */ | |||
user_data = &pData; | |||
} | |||
header->size = SizeOfData; | |||
memcpy(header->data, user_data, header->size); | |||
err = util_hash_table_set(This->pdata, refguid, header); | |||
if (err == PIPE_OK) { | |||
if (header->unknown) { IUnknown_AddRef(*(IUnknown **)header->data); } | |||
return D3D_OK; | |||
} | |||
FREE(header); | |||
if (err == PIPE_ERROR_OUT_OF_MEMORY) { return E_OUTOFMEMORY; } | |||
return D3DERR_DRIVERINTERNALERROR; | |||
} | |||
HRESULT WINAPI | |||
NineResource9_GetPrivateData( struct NineResource9 *This, | |||
REFGUID refguid, | |||
void *pData, | |||
DWORD *pSizeOfData ) | |||
{ | |||
struct pheader *header; | |||
DBG("This=%p refguid=%p pData=%p pSizeOfData=%p\n", | |||
This, refguid, pData, pSizeOfData); | |||
user_assert(pSizeOfData, E_POINTER); | |||
header = util_hash_table_get(This->pdata, refguid); | |||
if (!header) { return D3DERR_NOTFOUND; } | |||
if (!pData) { | |||
*pSizeOfData = header->size; | |||
return D3D_OK; | |||
} | |||
if (*pSizeOfData < header->size) { | |||
return D3DERR_MOREDATA; | |||
} | |||
if (header->unknown) { IUnknown_AddRef(*(IUnknown **)header->data); } | |||
memcpy(pData, header->data, header->size); | |||
return D3D_OK; | |||
} | |||
HRESULT WINAPI | |||
NineResource9_FreePrivateData( struct NineResource9 *This, | |||
REFGUID refguid ) | |||
{ | |||
struct pheader *header; | |||
DBG("This=%p refguid=%p\n", This, refguid); | |||
header = util_hash_table_get(This->pdata, refguid); | |||
if (!header) | |||
return D3DERR_NOTFOUND; | |||
ht_guid_delete(NULL, header, NULL); | |||
util_hash_table_remove(This->pdata, refguid); | |||
return D3D_OK; | |||
} | |||
DWORD WINAPI | |||
NineResource9_SetPriority( struct NineResource9 *This, | |||
DWORD PriorityNew ) | |||
{ | |||
DWORD prev = This->priority; | |||
This->priority = PriorityNew; | |||
return prev; | |||
} | |||
DWORD WINAPI | |||
NineResource9_GetPriority( struct NineResource9 *This ) | |||
{ | |||
return This->priority; | |||
} | |||
/* NOTE: Don't forget to adjust locked vtable if you change this ! */ | |||
void WINAPI | |||
NineResource9_PreLoad( struct NineResource9 *This ) | |||
{ | |||
if (This->pool != D3DPOOL_MANAGED) | |||
return; | |||
/* We don't treat managed vertex or index buffers different from | |||
* default ones (are managed vertex buffers even allowed ?), and | |||
* the PreLoad for textures is overridden by superclass. | |||
*/ | |||
} | |||
D3DRESOURCETYPE WINAPI | |||
NineResource9_GetType( struct NineResource9 *This ) | |||
{ | |||
return This->type; | |||
} |
@@ -0,0 +1,107 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_RESOURCE9_H_ | |||
#define _NINE_RESOURCE9_H_ | |||
#include "iunknown.h" | |||
#include "pipe/p_state.h" | |||
struct pipe_screen; | |||
struct util_hash_table; | |||
struct NineDevice9; | |||
struct NineResource9 | |||
{ | |||
struct NineUnknown base; | |||
struct pipe_resource *resource; /* device resource */ | |||
uint8_t *data; /* system memory backing */ | |||
D3DRESOURCETYPE type; | |||
D3DPOOL pool; | |||
DWORD priority; | |||
DWORD usage; | |||
struct pipe_resource info; /* resource configuration */ | |||
/* for [GS]etPrivateData/FreePrivateData */ | |||
struct util_hash_table *pdata; | |||
}; | |||
static INLINE struct NineResource9 * | |||
NineResource9( void *data ) | |||
{ | |||
return (struct NineResource9 *)data; | |||
} | |||
HRESULT | |||
NineResource9_ctor( struct NineResource9 *This, | |||
struct NineUnknownParams *pParams, | |||
BOOL Allocate, | |||
D3DRESOURCETYPE Type, | |||
D3DPOOL Pool ); | |||
void | |||
NineResource9_dtor( struct NineResource9 *This ); | |||
/*** Nine private methods ***/ | |||
struct pipe_resource * | |||
NineResource9_GetResource( struct NineResource9 *This ); | |||
D3DPOOL | |||
NineResource9_GetPool( struct NineResource9 *This ); | |||
/*** Direct3D public methods ***/ | |||
HRESULT WINAPI | |||
NineResource9_SetPrivateData( struct NineResource9 *This, | |||
REFGUID refguid, | |||
const void *pData, | |||
DWORD SizeOfData, | |||
DWORD Flags ); | |||
HRESULT WINAPI | |||
NineResource9_GetPrivateData( struct NineResource9 *This, | |||
REFGUID refguid, | |||
void *pData, | |||
DWORD *pSizeOfData ); | |||
HRESULT WINAPI | |||
NineResource9_FreePrivateData( struct NineResource9 *This, | |||
REFGUID refguid ); | |||
DWORD WINAPI | |||
NineResource9_SetPriority( struct NineResource9 *This, | |||
DWORD PriorityNew ); | |||
DWORD WINAPI | |||
NineResource9_GetPriority( struct NineResource9 *This ); | |||
void WINAPI | |||
NineResource9_PreLoad( struct NineResource9 *This ); | |||
D3DRESOURCETYPE WINAPI | |||
NineResource9_GetType( struct NineResource9 *This ); | |||
#endif /* _NINE_RESOURCE9_H_ */ |
@@ -0,0 +1,533 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "stateblock9.h" | |||
#include "device9.h" | |||
#include "basetexture9.h" | |||
#include "nine_helpers.h" | |||
#define DBG_CHANNEL DBG_STATEBLOCK | |||
/* XXX TODO: handling of lights is broken */ | |||
HRESULT | |||
NineStateBlock9_ctor( struct NineStateBlock9 *This, | |||
struct NineUnknownParams *pParams, | |||
enum nine_stateblock_type type ) | |||
{ | |||
HRESULT hr = NineUnknown_ctor(&This->base, pParams); | |||
if (FAILED(hr)) | |||
return hr; | |||
This->type = type; | |||
This->state.vs_const_f = MALLOC(pParams->device->constbuf_vs->width0); | |||
This->state.ps_const_f = MALLOC(pParams->device->constbuf_ps->width0); | |||
if (!This->state.vs_const_f || !This->state.ps_const_f) | |||
return E_OUTOFMEMORY; | |||
return D3D_OK; | |||
} | |||
void | |||
NineStateBlock9_dtor( struct NineStateBlock9 *This ) | |||
{ | |||
struct nine_state *state = &This->state; | |||
struct nine_range *r; | |||
struct nine_range_pool *pool = &This->base.device->range_pool; | |||
nine_state_clear(state, FALSE); | |||
if (state->vs_const_f) FREE(state->vs_const_f); | |||
if (state->ps_const_f) FREE(state->ps_const_f); | |||
if (state->ff.light) FREE(state->ff.light); | |||
if (state->ff.transform) FREE(state->ff.transform); | |||
if (This->state.changed.ps_const_f) { | |||
for (r = This->state.changed.ps_const_f; r->next; r = r->next); | |||
nine_range_pool_put_chain(pool, This->state.changed.ps_const_f, r); | |||
} | |||
if (This->state.changed.vs_const_f) { | |||
for (r = This->state.changed.vs_const_f; r->next; r = r->next); | |||
nine_range_pool_put_chain(pool, This->state.changed.vs_const_f, r); | |||
} | |||
NineUnknown_dtor(&This->base); | |||
} | |||
/* Copy state marked changed in @mask from @src to @dst. | |||
* If @apply is false, updating dst->changed can be omitted. | |||
* TODO: compare ? | |||
*/ | |||
static void | |||
nine_state_copy_common(struct nine_state *dst, | |||
const struct nine_state *src, | |||
struct nine_state *mask, /* aliases either src or dst */ | |||
const boolean apply, | |||
struct nine_range_pool *pool) | |||
{ | |||
unsigned i, s; | |||
if (apply) | |||
dst->changed.group |= mask->changed.group; | |||
if (mask->changed.group & NINE_STATE_VIEWPORT) | |||
dst->viewport = src->viewport; | |||
if (mask->changed.group & NINE_STATE_SCISSOR) | |||
dst->scissor = src->scissor; | |||
if (mask->changed.group & NINE_STATE_VS) | |||
nine_bind(&dst->vs, src->vs); | |||
if (mask->changed.group & NINE_STATE_PS) | |||
nine_bind(&dst->ps, src->ps); | |||
/* Vertex constants. | |||
* | |||
* Various possibilities for optimization here, like creating a per-SB | |||
* constant buffer, or memcmp'ing for changes. | |||
* Will do that later depending on what works best for specific apps. | |||
*/ | |||
if (mask->changed.group & NINE_STATE_VS_CONST) { | |||
struct nine_range *r; | |||
for (r = mask->changed.vs_const_f; r; r = r->next) { | |||
memcpy(&dst->vs_const_f[r->bgn * 4], | |||
&src->vs_const_f[r->bgn * 4], | |||
(r->end - r->bgn) * 4 * sizeof(float)); | |||
if (apply) | |||
nine_ranges_insert(&dst->changed.vs_const_f, r->bgn, r->end, | |||
pool); | |||
} | |||
if (mask->changed.vs_const_i) { | |||
uint16_t m = mask->changed.vs_const_i; | |||
for (i = ffs(m) - 1, m >>= i; m; ++i, m >>= 1) | |||
if (m & 1) | |||
memcpy(dst->vs_const_i[i], src->vs_const_i[i], 4 * sizeof(int)); | |||
if (apply) | |||
dst->changed.vs_const_i |= mask->changed.vs_const_i; | |||
} | |||
if (mask->changed.vs_const_b) { | |||
uint16_t m = mask->changed.vs_const_b; | |||
for (i = ffs(m) - 1, m >>= i; m; ++i, m >>= 1) | |||
if (m & 1) | |||
dst->vs_const_b[i] = src->vs_const_b[i]; | |||
if (apply) | |||
dst->changed.vs_const_b |= mask->changed.vs_const_b; | |||
} | |||
} | |||
/* Pixel constants. */ | |||
if (mask->changed.group & NINE_STATE_PS_CONST) { | |||
struct nine_range *r; | |||
for (r = mask->changed.ps_const_f; r; r = r->next) { | |||
memcpy(&dst->ps_const_f[r->bgn * 4], | |||
&src->ps_const_f[r->bgn * 4], | |||
(r->end - r->bgn) * 4 * sizeof(float)); | |||
if (apply) | |||
nine_ranges_insert(&dst->changed.ps_const_f, r->bgn, r->end, | |||
pool); | |||
} | |||
if (mask->changed.ps_const_i) { | |||
uint16_t m = mask->changed.ps_const_i; | |||
for (i = ffs(m) - 1, m >>= i; m; ++i, m >>= 1) | |||
if (m & 1) | |||
memcpy(dst->ps_const_i[i], src->ps_const_i[i], 4 * sizeof(int)); | |||
if (apply) | |||
dst->changed.ps_const_i |= mask->changed.ps_const_i; | |||
} | |||
if (mask->changed.ps_const_b) { | |||
uint16_t m = mask->changed.ps_const_b; | |||
for (i = ffs(m) - 1, m >>= i; m; ++i, m >>= 1) | |||
if (m & 1) | |||
dst->ps_const_b[i] = src->ps_const_b[i]; | |||
if (apply) | |||
dst->changed.ps_const_b |= mask->changed.ps_const_b; | |||
} | |||
} | |||
/* Render states. | |||
* TODO: Maybe build a list ? | |||
*/ | |||
for (i = 0; i < Elements(dst->changed.rs); ++i) { | |||
uint32_t m = mask->changed.rs[i]; | |||
if (apply) | |||
dst->changed.rs[i] |= m; | |||
while (m) { | |||
const int r = ffs(m) - 1; | |||
m &= ~(1 << r); | |||
dst->rs[i * 32 + r] = src->rs[i * 32 + r]; | |||
} | |||
} | |||
/* Clip planes. */ | |||
if (mask->changed.ucp) { | |||
for (i = 0; i < PIPE_MAX_CLIP_PLANES; ++i) | |||
if (mask->changed.ucp & (1 << i)) | |||
memcpy(dst->clip.ucp[i], | |||
src->clip.ucp[i], sizeof(src->clip.ucp[0])); | |||
if (apply) | |||
dst->changed.ucp |= mask->changed.ucp; | |||
} | |||
/* Sampler state. */ | |||
if (mask->changed.group & NINE_STATE_SAMPLER) { | |||
for (s = 0; s < NINE_MAX_SAMPLERS; ++s) { | |||
if (mask->changed.sampler[s] == 0x3ffe) { | |||
memcpy(&dst->samp[s], &src->samp[s], sizeof(dst->samp[s])); | |||
} else { | |||
uint32_t m = mask->changed.sampler[s]; | |||
while (m) { | |||
const int i = ffs(m) - 1; | |||
m &= ~(1 << i); | |||
dst->samp[s][i] = src->samp[s][i]; | |||
} | |||
} | |||
if (apply) | |||
dst->changed.sampler[s] |= mask->changed.sampler[s]; | |||
} | |||
} | |||
/* Index buffer. */ | |||
if (mask->changed.group & NINE_STATE_IDXBUF) | |||
nine_bind(&dst->idxbuf, src->idxbuf); | |||
/* Vertex streams. */ | |||
if (mask->changed.vtxbuf | mask->changed.stream_freq) { | |||
uint32_t m = mask->changed.vtxbuf | mask->changed.stream_freq; | |||
for (i = 0; m; ++i, m >>= 1) { | |||
if (mask->changed.vtxbuf & (1 << i)) { | |||
nine_bind(&dst->stream[i], src->stream[i]); | |||
if (src->stream[i]) { | |||
dst->vtxbuf[i].buffer_offset = src->vtxbuf[i].buffer_offset; | |||
dst->vtxbuf[i].buffer = src->vtxbuf[i].buffer; | |||
dst->vtxbuf[i].stride = src->vtxbuf[i].stride; | |||
} | |||
} | |||
if (mask->changed.stream_freq & (1 << i)) | |||
dst->stream_freq[i] = src->stream_freq[i]; | |||
} | |||
dst->stream_instancedata_mask &= ~mask->changed.stream_freq; | |||
dst->stream_instancedata_mask |= | |||
src->stream_instancedata_mask & mask->changed.stream_freq; | |||
if (apply) { | |||
dst->changed.vtxbuf |= mask->changed.vtxbuf; | |||
dst->changed.stream_freq |= mask->changed.stream_freq; | |||
} | |||
} | |||
if (!(mask->changed.group & NINE_STATE_FF)) | |||
return; | |||
WARN_ONCE("Fixed function state not handled properly by StateBlocks.\n"); | |||
/* Fixed function state. */ | |||
if (apply) | |||
dst->ff.changed.group |= src->ff.changed.group; | |||
if (mask->changed.group & NINE_STATE_FF_MATERIAL) | |||
dst->ff.material = src->ff.material; | |||
if (mask->changed.group & NINE_STATE_FF_PSSTAGES) { | |||
for (s = 0; s < NINE_MAX_SAMPLERS; ++s) { | |||
for (i = 0; i < NINED3DTSS_COUNT; ++i) | |||
if (mask->ff.changed.tex_stage[s][i / 32] & (1 << (i % 32))) | |||
dst->ff.tex_stage[s][i] = src->ff.tex_stage[s][i]; | |||
if (apply) { | |||
/* TODO: it's 32 exactly, just offset by 1 as 0 is unused */ | |||
dst->ff.changed.tex_stage[s][0] |= | |||
mask->ff.changed.tex_stage[s][0]; | |||
dst->ff.changed.tex_stage[s][1] |= | |||
mask->ff.changed.tex_stage[s][1]; | |||
} | |||
} | |||
} | |||
if (mask->changed.group & NINE_STATE_FF_LIGHTING) { | |||
if (dst->ff.num_lights < mask->ff.num_lights) { | |||
dst->ff.light = REALLOC(dst->ff.light, | |||
dst->ff.num_lights * sizeof(D3DLIGHT9), | |||
mask->ff.num_lights * sizeof(D3DLIGHT9)); | |||
dst->ff.num_lights = mask->ff.num_lights; | |||
} | |||
for (i = 0; i < mask->ff.num_lights; ++i) | |||
if (mask->ff.light[i].Type != NINED3DLIGHT_INVALID) | |||
dst->ff.light[i] = src->ff.light[i]; | |||
DBG("TODO: active lights\n"); | |||
} | |||
if (mask->changed.group & NINE_STATE_FF_VSTRANSF) { | |||
for (i = 0; i < Elements(mask->ff.changed.transform); ++i) { | |||
if (!mask->ff.changed.transform[i]) | |||
continue; | |||
for (s = i * 32; s < (i * 32 + 32); ++s) { | |||
if (!(mask->ff.changed.transform[i] & (1 << (s % 32)))) | |||
continue; | |||
*nine_state_access_transform(dst, s, TRUE) = | |||
*nine_state_access_transform( /* const because !alloc */ | |||
(struct nine_state *)src, s, FALSE); | |||
} | |||
if (apply) | |||
dst->ff.changed.transform[i] |= mask->ff.changed.transform[i]; | |||
} | |||
} | |||
} | |||
static void | |||
nine_state_copy_common_all(struct nine_state *dst, | |||
const struct nine_state *src, | |||
struct nine_state *help, | |||
const boolean apply, | |||
struct nine_range_pool *pool, | |||
const int MaxStreams) | |||
{ | |||
unsigned i; | |||
if (apply) | |||
dst->changed.group |= src->changed.group; | |||
dst->viewport = src->viewport; | |||
dst->scissor = src->scissor; | |||
nine_bind(&dst->vs, src->vs); | |||
nine_bind(&dst->ps, src->ps); | |||
/* Vertex constants. | |||
* | |||
* Various possibilities for optimization here, like creating a per-SB | |||
* constant buffer, or memcmp'ing for changes. | |||
* Will do that later depending on what works best for specific apps. | |||
*/ | |||
if (1) { | |||
struct nine_range *r = help->changed.vs_const_f; | |||
memcpy(&dst->vs_const_f[0], | |||
&src->vs_const_f[0], (r->end - r->bgn) * 4 * sizeof(float)); | |||
if (apply) | |||
nine_ranges_insert(&dst->changed.vs_const_f, r->bgn, r->end, pool); | |||
memcpy(dst->vs_const_i, src->vs_const_i, sizeof(dst->vs_const_i)); | |||
memcpy(dst->vs_const_b, src->vs_const_b, sizeof(dst->vs_const_b)); | |||
if (apply) { | |||
dst->changed.vs_const_i |= src->changed.vs_const_i; | |||
dst->changed.vs_const_b |= src->changed.vs_const_b; | |||
} | |||
} | |||
/* Pixel constants. */ | |||
if (1) { | |||
struct nine_range *r = help->changed.ps_const_f; | |||
memcpy(&dst->ps_const_f[0], | |||
&src->ps_const_f[0], (r->end - r->bgn) * 4 * sizeof(float)); | |||
if (apply) | |||
nine_ranges_insert(&dst->changed.ps_const_f, r->bgn, r->end, pool); | |||
memcpy(dst->ps_const_i, src->ps_const_i, sizeof(dst->ps_const_i)); | |||
memcpy(dst->ps_const_b, src->ps_const_b, sizeof(dst->ps_const_b)); | |||
if (apply) { | |||
dst->changed.ps_const_i |= src->changed.ps_const_i; | |||
dst->changed.ps_const_b |= src->changed.ps_const_b; | |||
} | |||
} | |||
/* Render states. */ | |||
memcpy(dst->rs, src->rs, sizeof(dst->rs)); | |||
if (apply) | |||
memcpy(dst->changed.rs, src->changed.rs, sizeof(dst->changed.rs)); | |||
/* Clip planes. */ | |||
memcpy(&dst->clip, &src->clip, sizeof(dst->clip)); | |||
if (apply) | |||
dst->changed.ucp = src->changed.ucp; | |||
/* Sampler state. */ | |||
memcpy(dst->samp, src->samp, sizeof(dst->samp)); | |||
if (apply) | |||
memcpy(dst->changed.sampler, | |||
src->changed.sampler, sizeof(dst->changed.sampler)); | |||
/* Index buffer. */ | |||
nine_bind(&dst->idxbuf, src->idxbuf); | |||
/* Vertex streams. */ | |||
if (1) { | |||
for (i = 0; i < Elements(dst->stream); ++i) { | |||
nine_bind(&dst->stream[i], src->stream[i]); | |||
if (src->stream[i]) { | |||
dst->vtxbuf[i].buffer_offset = src->vtxbuf[i].buffer_offset; | |||
dst->vtxbuf[i].buffer = src->vtxbuf[i].buffer; | |||
dst->vtxbuf[i].stride = src->vtxbuf[i].stride; | |||
} | |||
dst->stream_freq[i] = src->stream_freq[i]; | |||
} | |||
dst->stream_instancedata_mask = src->stream_instancedata_mask; | |||
if (apply) { | |||
dst->changed.vtxbuf = (1ULL << MaxStreams) - 1; | |||
dst->changed.stream_freq = (1ULL << MaxStreams) - 1; | |||
} | |||
} | |||
/* keep this check in case we want to disable FF */ | |||
if (!(help->changed.group & NINE_STATE_FF)) | |||
return; | |||
WARN_ONCE("Fixed function state not handled properly by StateBlocks.\n"); | |||
/* Fixed function state. */ | |||
if (apply) | |||
dst->ff.changed.group = src->ff.changed.group; | |||
dst->ff.material = src->ff.material; | |||
memcpy(dst->ff.tex_stage, src->ff.tex_stage, sizeof(dst->ff.tex_stage)); | |||
if (apply) /* TODO: memset */ | |||
memcpy(dst->ff.changed.tex_stage, | |||
src->ff.changed.tex_stage, sizeof(dst->ff.changed.tex_stage)); | |||
/* Lights. */ | |||
if (1) { | |||
if (dst->ff.num_lights < src->ff.num_lights) { | |||
dst->ff.light = REALLOC(dst->ff.light, | |||
dst->ff.num_lights * sizeof(D3DLIGHT9), | |||
src->ff.num_lights * sizeof(D3DLIGHT9)); | |||
dst->ff.num_lights = src->ff.num_lights; | |||
} | |||
memcpy(dst->ff.light, | |||
src->ff.light, src->ff.num_lights * sizeof(dst->ff.light[0])); | |||
DBG("TODO: active lights\n"); | |||
} | |||
/* Transforms. */ | |||
if (1) { | |||
if (dst->ff.num_transforms < src->ff.num_transforms) { | |||
dst->ff.transform = REALLOC(dst->ff.transform, | |||
dst->ff.num_transforms * sizeof(dst->ff.transform[0]), | |||
src->ff.num_transforms * sizeof(src->ff.transform[0])); | |||
dst->ff.num_transforms = src->ff.num_transforms; | |||
} | |||
memcpy(dst->ff.transform, | |||
src->ff.transform, src->ff.num_transforms * sizeof(D3DMATRIX)); | |||
if (apply) /* TODO: memset */ | |||
memcpy(dst->ff.changed.transform, | |||
src->ff.changed.transform, sizeof(dst->ff.changed.transform)); | |||
} | |||
} | |||
/* Capture those bits of current device state that have been changed between | |||
* BeginStateBlock and EndStateBlock. | |||
*/ | |||
HRESULT WINAPI | |||
NineStateBlock9_Capture( struct NineStateBlock9 *This ) | |||
{ | |||
struct nine_state *dst = &This->state; | |||
struct nine_state *src = &This->base.device->state; | |||
const int MaxStreams = This->base.device->caps.MaxStreams; | |||
unsigned s; | |||
DBG("This=%p\n", This); | |||
if (This->type == NINESBT_ALL) | |||
nine_state_copy_common_all(dst, src, dst, FALSE, NULL, MaxStreams); | |||
else | |||
nine_state_copy_common(dst, src, dst, FALSE, NULL); | |||
if (dst->changed.group & NINE_STATE_VDECL) | |||
nine_bind(&dst->vdecl, src->vdecl); | |||
/* Textures */ | |||
if (dst->changed.texture) { | |||
uint32_t m = dst->changed.texture; | |||
for (s = 0; m; ++s, m >>= 1) | |||
if (m & 1) | |||
nine_bind(&dst->texture[s], src->texture[s]); | |||
} | |||
return D3D_OK; | |||
} | |||
/* Set state managed by this StateBlock as current device state. */ | |||
HRESULT WINAPI | |||
NineStateBlock9_Apply( struct NineStateBlock9 *This ) | |||
{ | |||
struct nine_state *dst = &This->base.device->state; | |||
struct nine_state *src = &This->state; | |||
struct nine_range_pool *pool = &This->base.device->range_pool; | |||
const int MaxStreams = This->base.device->caps.MaxStreams; | |||
unsigned s; | |||
DBG("This=%p\n", This); | |||
if (This->type == NINESBT_ALL) | |||
nine_state_copy_common_all(dst, src, src, TRUE, pool, MaxStreams); | |||
else | |||
nine_state_copy_common(dst, src, src, TRUE, pool); | |||
if ((src->changed.group & NINE_STATE_VDECL) && src->vdecl) | |||
nine_bind(&dst->vdecl, src->vdecl); | |||
/* Textures */ | |||
if (src->changed.texture) { | |||
uint32_t m = src->changed.texture; | |||
dst->changed.texture |= m; | |||
dst->samplers_shadow &= ~m; | |||
for (s = 0; m; ++s, m >>= 1) { | |||
struct NineBaseTexture9 *tex = src->texture[s]; | |||
if (!(m & 1)) | |||
continue; | |||
if (tex) { | |||
tex->bind_count++; | |||
if ((tex->dirty | tex->dirty_mip) && LIST_IS_EMPTY(&tex->list)) | |||
list_add(&tex->list, &This->base.device->update_textures); | |||
dst->samplers_shadow |= tex->shadow << s; | |||
} | |||
if (src->texture[s]) | |||
src->texture[s]->bind_count--; | |||
nine_bind(&dst->texture[s], src->texture[s]); | |||
} | |||
} | |||
return D3D_OK; | |||
} | |||
IDirect3DStateBlock9Vtbl NineStateBlock9_vtable = { | |||
(void *)NineUnknown_QueryInterface, | |||
(void *)NineUnknown_AddRef, | |||
(void *)NineUnknown_Release, | |||
(void *)NineUnknown_GetDevice, /* actually part of StateBlock9 iface */ | |||
(void *)NineStateBlock9_Capture, | |||
(void *)NineStateBlock9_Apply | |||
}; | |||
static const GUID *NineStateBlock9_IIDs[] = { | |||
&IID_IDirect3DStateBlock9, | |||
&IID_IUnknown, | |||
NULL | |||
}; | |||
HRESULT | |||
NineStateBlock9_new( struct NineDevice9 *pDevice, | |||
struct NineStateBlock9 **ppOut, | |||
enum nine_stateblock_type type) | |||
{ | |||
NINE_DEVICE_CHILD_NEW(StateBlock9, ppOut, pDevice, type); | |||
} |
@@ -0,0 +1,71 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_STATEBLOCK9_H_ | |||
#define _NINE_STATEBLOCK9_H_ | |||
#include "iunknown.h" | |||
#include "nine_state.h" | |||
enum nine_stateblock_type | |||
{ | |||
NINESBT_ALL, | |||
NINESBT_VERTEXSTATE, | |||
NINESBT_PIXELSTATE, | |||
NINESBT_CUSTOM | |||
}; | |||
struct NineStateBlock9 | |||
{ | |||
struct NineUnknown base; | |||
struct nine_state state; | |||
enum nine_stateblock_type type; | |||
}; | |||
static INLINE struct NineStateBlock9 * | |||
NineStateBlock9( void *data ) | |||
{ | |||
return (struct NineStateBlock9 *)data; | |||
} | |||
HRESULT | |||
NineStateBlock9_new( struct NineDevice9 *, | |||
struct NineStateBlock9 **ppOut, | |||
enum nine_stateblock_type); | |||
HRESULT | |||
NineStateBlock9_ctor( struct NineStateBlock9 *, | |||
struct NineUnknownParams *pParams, | |||
enum nine_stateblock_type type ); | |||
void | |||
NineStateBlock9_dtor( struct NineStateBlock9 * ); | |||
HRESULT WINAPI | |||
NineStateBlock9_Capture( struct NineStateBlock9 *This ); | |||
HRESULT WINAPI | |||
NineStateBlock9_Apply( struct NineStateBlock9 *This ); | |||
#endif /* _NINE_STATEBLOCK9_H_ */ |
@@ -0,0 +1,711 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "surface9.h" | |||
#include "device9.h" | |||
#include "basetexture9.h" /* for marking dirty */ | |||
#include "nine_helpers.h" | |||
#include "nine_pipe.h" | |||
#include "nine_dump.h" | |||
#include "pipe/p_context.h" | |||
#include "pipe/p_screen.h" | |||
#include "pipe/p_state.h" | |||
#include "util/u_math.h" | |||
#include "util/u_inlines.h" | |||
#include "util/u_surface.h" | |||
#define DBG_CHANNEL DBG_SURFACE | |||
HRESULT | |||
NineSurface9_ctor( struct NineSurface9 *This, | |||
struct NineUnknownParams *pParams, | |||
struct NineUnknown *pContainer, | |||
struct pipe_resource *pResource, | |||
uint8_t TextureType, | |||
unsigned Level, | |||
unsigned Layer, | |||
D3DSURFACE_DESC *pDesc ) | |||
{ | |||
HRESULT hr; | |||
DBG("This=%p pDevice=%p pResource=%p Level=%u Layer=%u pDesc=%p\n", | |||
This, pParams->device, pResource, Level, Layer, pDesc); | |||
/* Mark this as a special surface held by another internal resource. */ | |||
pParams->container = pContainer; | |||
user_assert(!(pDesc->Usage & D3DUSAGE_DYNAMIC) || | |||
(pDesc->Pool != D3DPOOL_MANAGED), D3DERR_INVALIDCALL); | |||
assert(pResource || | |||
pDesc->Pool != D3DPOOL_DEFAULT || pDesc->Format == D3DFMT_NULL); | |||
This->base.info.screen = pParams->device->screen; | |||
This->base.info.target = PIPE_TEXTURE_2D; | |||
This->base.info.format = d3d9_to_pipe_format(pDesc->Format); | |||
This->base.info.width0 = pDesc->Width; | |||
This->base.info.height0 = pDesc->Height; | |||
This->base.info.depth0 = 1; | |||
This->base.info.last_level = 0; | |||
This->base.info.array_size = 1; | |||
This->base.info.nr_samples = pDesc->MultiSampleType; | |||
This->base.info.usage = PIPE_USAGE_DEFAULT; | |||
This->base.info.bind = PIPE_BIND_SAMPLER_VIEW; | |||
This->base.info.flags = 0; | |||
if (pDesc->Usage & D3DUSAGE_RENDERTARGET) | |||
This->base.info.bind |= PIPE_BIND_RENDER_TARGET; | |||
if (pDesc->Usage & D3DUSAGE_DEPTHSTENCIL) | |||
This->base.info.bind |= PIPE_BIND_DEPTH_STENCIL; | |||
if (pDesc->Pool == D3DPOOL_SYSTEMMEM) { | |||
This->base.info.usage = PIPE_USAGE_STAGING; | |||
if (pResource) | |||
This->base.data = (uint8_t *)pResource; /* this is *pSharedHandle */ | |||
pResource = NULL; | |||
} else { | |||
if (pResource && (pDesc->Usage & D3DUSAGE_DYNAMIC)) | |||
pResource->flags |= NINE_RESOURCE_FLAG_LOCKABLE; | |||
pipe_resource_reference(&This->base.resource, pResource); | |||
} | |||
hr = NineResource9_ctor(&This->base, pParams, FALSE, D3DRTYPE_SURFACE, | |||
pDesc->Pool); | |||
if (FAILED(hr)) | |||
return hr; | |||
This->base.usage = pDesc->Usage; | |||
This->pipe = This->base.base.device->pipe; | |||
This->transfer = NULL; | |||
This->texture = TextureType; | |||
This->level = Level; | |||
This->level_actual = Level; | |||
This->layer = Layer; | |||
This->desc = *pDesc; | |||
This->stride = util_format_get_stride(This->base.info.format, pDesc->Width); | |||
This->stride = align(This->stride, 4); | |||
if (!pResource && !This->base.data) { | |||
hr = NineSurface9_AllocateData(This); | |||
if (FAILED(hr)) | |||
return hr; | |||
} else { | |||
if (pResource && NineSurface9_IsOffscreenPlain(This)) | |||
pResource->flags |= NINE_RESOURCE_FLAG_LOCKABLE; | |||
} | |||
NineSurface9_Dump(This); | |||
return D3D_OK; | |||
} | |||
void | |||
NineSurface9_dtor( struct NineSurface9 *This ) | |||
{ | |||
if (This->transfer) | |||
NineSurface9_UnlockRect(This); | |||
NineSurface9_ClearDirtyRects(This); | |||
pipe_surface_reference(&This->surface[0], NULL); | |||
pipe_surface_reference(&This->surface[1], NULL); | |||
NineResource9_dtor(&This->base); | |||
} | |||
struct pipe_surface * | |||
NineSurface9_CreatePipeSurface( struct NineSurface9 *This, const int sRGB ) | |||
{ | |||
struct pipe_context *pipe = This->pipe; | |||
struct pipe_resource *resource = This->base.resource; | |||
struct pipe_surface templ; | |||
assert(This->desc.Pool == D3DPOOL_DEFAULT || | |||
This->desc.Pool == D3DPOOL_MANAGED); | |||
assert(resource); | |||
templ.format = sRGB ? util_format_srgb(resource->format) : resource->format; | |||
templ.u.tex.level = This->level; | |||
templ.u.tex.first_layer = This->layer; | |||
templ.u.tex.last_layer = This->layer; | |||
This->surface[sRGB] = pipe->create_surface(pipe, resource, &templ); | |||
assert(This->surface[sRGB]); | |||
return This->surface[sRGB]; | |||
} | |||
#ifdef DEBUG | |||
void | |||
NineSurface9_Dump( struct NineSurface9 *This ) | |||
{ | |||
struct NineBaseTexture9 *tex; | |||
GUID id = IID_IDirect3DBaseTexture9; | |||
REFIID ref = &id; | |||
DBG("\nNineSurface9(%p->%p/%p): Pool=%s Type=%s Usage=%s\n" | |||
"Dims=%ux%u Format=%s Stride=%u Lockable=%i\n" | |||
"Level=%u(%u), Layer=%u\n", This, This->base.resource, This->base.data, | |||
nine_D3DPOOL_to_str(This->desc.Pool), | |||
nine_D3DRTYPE_to_str(This->desc.Type), | |||
nine_D3DUSAGE_to_str(This->desc.Usage), | |||
This->desc.Width, This->desc.Height, | |||
d3dformat_to_string(This->desc.Format), This->stride, | |||
This->base.resource && | |||
(This->base.resource->flags & NINE_RESOURCE_FLAG_LOCKABLE), | |||
This->level, This->level_actual, This->layer); | |||
if (!This->base.base.container) | |||
return; | |||
NineUnknown_QueryInterface(This->base.base.container, ref, (void **)&tex); | |||
if (tex) { | |||
NineBaseTexture9_Dump(tex); | |||
NineUnknown_Release(NineUnknown(tex)); | |||
} | |||
} | |||
#endif /* DEBUG */ | |||
HRESULT WINAPI | |||
NineSurface9_GetContainer( struct NineSurface9 *This, | |||
REFIID riid, | |||
void **ppContainer ) | |||
{ | |||
HRESULT hr; | |||
if (!NineUnknown(This)->container) | |||
return E_NOINTERFACE; | |||
hr = NineUnknown_QueryInterface(NineUnknown(This)->container, riid, ppContainer); | |||
if (FAILED(hr)) | |||
DBG("QueryInterface FAILED!\n"); | |||
return hr; | |||
} | |||
static INLINE void | |||
NineSurface9_MarkContainerDirty( struct NineSurface9 *This ) | |||
{ | |||
if (This->texture) { | |||
struct NineBaseTexture9 *tex = | |||
NineBaseTexture9(This->base.base.container); | |||
assert(tex); | |||
assert(This->texture == D3DRTYPE_TEXTURE || | |||
This->texture == D3DRTYPE_CUBETEXTURE); | |||
if (This->base.pool == D3DPOOL_MANAGED) | |||
tex->dirty = TRUE; | |||
else | |||
if (This->base.usage & D3DUSAGE_AUTOGENMIPMAP) | |||
tex->dirty_mip = TRUE; | |||
BASETEX_REGISTER_UPDATE(tex); | |||
} | |||
} | |||
HRESULT WINAPI | |||
NineSurface9_GetDesc( struct NineSurface9 *This, | |||
D3DSURFACE_DESC *pDesc ) | |||
{ | |||
user_assert(pDesc != NULL, E_POINTER); | |||
*pDesc = This->desc; | |||
return D3D_OK; | |||
} | |||
/* Wine just keeps a single directy rect and expands it to cover all | |||
* the dirty rects ever added. | |||
* We'll keep 2, and expand the one that fits better, just for fun. | |||
*/ | |||
INLINE void | |||
NineSurface9_AddDirtyRect( struct NineSurface9 *This, | |||
const struct pipe_box *box ) | |||
{ | |||
float area[2]; | |||
struct u_rect rect, cover_a, cover_b; | |||
if (!box) { | |||
This->dirty_rects[0].x0 = 0; | |||
This->dirty_rects[0].y0 = 0; | |||
This->dirty_rects[0].x1 = This->desc.Width; | |||
This->dirty_rects[0].y1 = This->desc.Height; | |||
memset(&This->dirty_rects[1], 0, sizeof(This->dirty_rects[1])); | |||
return; | |||
} | |||
rect.x0 = box->x; | |||
rect.y0 = box->y; | |||
rect.x1 = box->x + box->width; | |||
rect.y1 = box->y + box->height; | |||
if (This->dirty_rects[0].x1 == 0) { | |||
This->dirty_rects[0] = rect; | |||
return; | |||
} | |||
u_rect_union(&cover_a, &This->dirty_rects[0], &rect); | |||
area[0] = u_rect_area(&cover_a); | |||
if (This->dirty_rects[1].x1 == 0) { | |||
area[1] = u_rect_area(&This->dirty_rects[0]); | |||
if (area[0] > (area[1] * 1.25f)) | |||
This->dirty_rects[1] = rect; | |||
else | |||
This->dirty_rects[0] = cover_a; | |||
} else { | |||
u_rect_union(&cover_b, &This->dirty_rects[1], &rect); | |||
area[1] = u_rect_area(&cover_b); | |||
if (area[0] > area[1]) | |||
This->dirty_rects[1] = cover_b; | |||
else | |||
This->dirty_rects[0] = cover_a; | |||
} | |||
} | |||
static INLINE uint8_t * | |||
NineSurface9_GetSystemMemPointer(struct NineSurface9 *This, int x, int y) | |||
{ | |||
unsigned x_offset = util_format_get_stride(This->base.info.format, x); | |||
y = util_format_get_nblocksy(This->base.info.format, y); | |||
assert(This->base.data); | |||
return This->base.data + (y * This->stride + x_offset); | |||
} | |||
HRESULT WINAPI | |||
NineSurface9_LockRect( struct NineSurface9 *This, | |||
D3DLOCKED_RECT *pLockedRect, | |||
const RECT *pRect, | |||
DWORD Flags ) | |||
{ | |||
struct pipe_resource *resource = This->base.resource; | |||
struct pipe_box box; | |||
unsigned usage; | |||
DBG("This=%p pLockedRect=%p pRect=%p[%u..%u,%u..%u] Flags=%s\n", This, | |||
pLockedRect, pRect, | |||
pRect ? pRect->left : 0, pRect ? pRect->right : 0, | |||
pRect ? pRect->top : 0, pRect ? pRect->bottom : 0, | |||
nine_D3DLOCK_to_str(Flags)); | |||
NineSurface9_Dump(This); | |||
#ifdef NINE_STRICT | |||
user_assert(This->base.pool != D3DPOOL_DEFAULT || | |||
(resource && (resource->flags & NINE_RESOURCE_FLAG_LOCKABLE)), | |||
D3DERR_INVALIDCALL); | |||
#endif | |||
user_assert(!(Flags & ~(D3DLOCK_DISCARD | | |||
D3DLOCK_DONOTWAIT | | |||
D3DLOCK_NO_DIRTY_UPDATE | | |||
D3DLOCK_NOOVERWRITE | | |||
D3DLOCK_NOSYSLOCK | /* ignored */ | |||
D3DLOCK_READONLY)), D3DERR_INVALIDCALL); | |||
user_assert(!((Flags & D3DLOCK_DISCARD) && (Flags & D3DLOCK_READONLY)), | |||
D3DERR_INVALIDCALL); | |||
/* check if it's already locked */ | |||
user_assert(This->lock_count == 0, D3DERR_INVALIDCALL); | |||
user_assert(pLockedRect, E_POINTER); | |||
user_assert(This->desc.MultiSampleType == D3DMULTISAMPLE_NONE, | |||
D3DERR_INVALIDCALL); | |||
if (pRect && This->base.pool == D3DPOOL_DEFAULT && | |||
util_format_is_compressed(This->base.info.format)) { | |||
const unsigned w = util_format_get_blockwidth(This->base.info.format); | |||
const unsigned h = util_format_get_blockheight(This->base.info.format); | |||
user_assert(!(pRect->left % w) && !(pRect->right % w) && | |||
!(pRect->top % h) && !(pRect->bottom % h), | |||
D3DERR_INVALIDCALL); | |||
} | |||
if (Flags & D3DLOCK_DISCARD) { | |||
usage = PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE; | |||
} else { | |||
usage = (Flags & D3DLOCK_READONLY) ? | |||
PIPE_TRANSFER_READ : PIPE_TRANSFER_READ_WRITE; | |||
} | |||
if (Flags & D3DLOCK_DONOTWAIT) | |||
usage |= PIPE_TRANSFER_DONTBLOCK; | |||
if (pRect) { | |||
rect_to_pipe_box(&box, pRect); | |||
if (u_box_clip_2d(&box, &box, This->desc.Width, | |||
This->desc.Height) < 0) { | |||
DBG("pRect clipped by Width=%u Height=%u\n", | |||
This->desc.Width, This->desc.Height); | |||
return D3DERR_INVALIDCALL; | |||
} | |||
} else { | |||
u_box_origin_2d(This->desc.Width, This->desc.Height, &box); | |||
} | |||
user_warn(This->desc.Format == D3DFMT_NULL); | |||
if (This->base.data) { | |||
DBG("returning system memory\n"); | |||
pLockedRect->Pitch = This->stride; | |||
pLockedRect->pBits = NineSurface9_GetSystemMemPointer(This, | |||
box.x, box.y); | |||
} else { | |||
DBG("mapping pipe_resource %p (level=%u usage=%x)\n", | |||
resource, This->level, usage); | |||
pLockedRect->pBits = This->pipe->transfer_map(This->pipe, resource, | |||
This->level, usage, &box, | |||
&This->transfer); | |||
if (!This->transfer) { | |||
DBG("transfer_map failed\n"); | |||
if (Flags & D3DLOCK_DONOTWAIT) | |||
return D3DERR_WASSTILLDRAWING; | |||
return D3DERR_INVALIDCALL; | |||
} | |||
pLockedRect->Pitch = This->transfer->stride; | |||
} | |||
if (!(Flags & (D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_READONLY))) { | |||
NineSurface9_MarkContainerDirty(This); | |||
if (This->base.pool == D3DPOOL_MANAGED) | |||
NineSurface9_AddDirtyRect(This, &box); | |||
} | |||
++This->lock_count; | |||
return D3D_OK; | |||
} | |||
HRESULT WINAPI | |||
NineSurface9_UnlockRect( struct NineSurface9 *This ) | |||
{ | |||
DBG("This=%p lock_count=%u\n", This, This->lock_count); | |||
user_assert(This->lock_count, D3DERR_INVALIDCALL); | |||
if (This->transfer) { | |||
This->pipe->transfer_unmap(This->pipe, This->transfer); | |||
This->transfer = NULL; | |||
} | |||
--This->lock_count; | |||
return D3D_OK; | |||
} | |||
HRESULT WINAPI | |||
NineSurface9_GetDC( struct NineSurface9 *This, | |||
HDC *phdc ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineSurface9_ReleaseDC( struct NineSurface9 *This, | |||
HDC hdc ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
/* nine private */ | |||
HRESULT | |||
NineSurface9_AllocateData( struct NineSurface9 *This ) | |||
{ | |||
#if 0 | |||
struct pipe_screen *screen = This->base.info.screen; | |||
/* XXX: Can't use staging resource because apparently apps expect | |||
* memory offsets to be the same across locks. | |||
* NV50 doesn't support direct mapping yet so only enable this if | |||
* everything else works. | |||
*/ | |||
if (This->base.pool == D3DPOOL_SYSTEMMEM) { | |||
/* Allocate a staging resource to save a copy: | |||
* user -> staging resource | |||
* staging resource -> (blit) -> video memory | |||
* | |||
* Instead of: | |||
* user -> system memory | |||
* system memory -> transfer staging area | |||
* transfer -> video memory | |||
* | |||
* Does this work if we "lose" the device ? | |||
*/ | |||
struct pipe_resource *resource; | |||
struct pipe_resource templ; | |||
templ.target = PIPE_TEXTURE_2D; | |||
templ.format = This->base.info.format; | |||
templ.width0 = This->desc.Width; | |||
templ.height0 = This->desc.Height; | |||
templ.depth0 = 1; | |||
templ.array_size = 1; | |||
templ.last_level = 0; | |||
templ.nr_samples = 0; | |||
templ.usage = PIPE_USAGE_STAGING; | |||
templ.bind = | |||
PIPE_BIND_SAMPLER_VIEW | | |||
PIPE_BIND_TRANSFER_WRITE | | |||
PIPE_BIND_TRANSFER_READ; | |||
templ.flags = 0; | |||
DBG("(%p(This=%p),level=%u) Allocating staging resource.\n", | |||
This->base.base.container, This, This->level); | |||
resource = screen->resource_create(screen, &templ); | |||
if (!resource) | |||
DBG("Failed to allocate staging resource.\n"); | |||
/* Also deallocate old staging resource. */ | |||
pipe_resource_reference(&This->base.resource, resource); | |||
} | |||
#endif | |||
if (!This->base.resource) { | |||
const unsigned size = This->stride * | |||
util_format_get_nblocksy(This->base.info.format, This->desc.Height); | |||
DBG("(%p(This=%p),level=%u) Allocating 0x%x bytes of system memory.\n", | |||
This->base.base.container, This, This->level, size); | |||
This->base.data = (uint8_t *)MALLOC(size); | |||
if (!This->base.data) | |||
return E_OUTOFMEMORY; | |||
} | |||
return D3D_OK; | |||
} | |||
IDirect3DSurface9Vtbl NineSurface9_vtable = { | |||
(void *)NineUnknown_QueryInterface, | |||
(void *)NineUnknown_AddRef, | |||
(void *)NineUnknown_Release, | |||
(void *)NineUnknown_GetDevice, /* actually part of Resource9 iface */ | |||
(void *)NineResource9_SetPrivateData, | |||
(void *)NineResource9_GetPrivateData, | |||
(void *)NineResource9_FreePrivateData, | |||
(void *)NineResource9_SetPriority, | |||
(void *)NineResource9_GetPriority, | |||
(void *)NineResource9_PreLoad, | |||
(void *)NineResource9_GetType, | |||
(void *)NineSurface9_GetContainer, | |||
(void *)NineSurface9_GetDesc, | |||
(void *)NineSurface9_LockRect, | |||
(void *)NineSurface9_UnlockRect, | |||
(void *)NineSurface9_GetDC, | |||
(void *)NineSurface9_ReleaseDC | |||
}; | |||
static INLINE boolean | |||
NineSurface9_IsDirty(struct NineSurface9 *This) | |||
{ | |||
return This->dirty_rects[0].x1 != 0; | |||
} | |||
HRESULT | |||
NineSurface9_CopySurface( struct NineSurface9 *This, | |||
struct NineSurface9 *From, | |||
const POINT *pDestPoint, | |||
const RECT *pSourceRect ) | |||
{ | |||
struct pipe_context *pipe = This->pipe; | |||
struct pipe_resource *r_dst = This->base.resource; | |||
struct pipe_resource *r_src = From->base.resource; | |||
struct pipe_transfer *transfer; | |||
struct pipe_box src_box; | |||
struct pipe_box dst_box; | |||
uint8_t *p_dst; | |||
const uint8_t *p_src; | |||
user_assert(This->desc.Format == From->desc.Format, D3DERR_INVALIDCALL); | |||
dst_box.x = pDestPoint ? pDestPoint->x : 0; | |||
dst_box.y = pDestPoint ? pDestPoint->y : 0; | |||
user_assert(dst_box.x >= 0 && | |||
dst_box.y >= 0, D3DERR_INVALIDCALL); | |||
dst_box.z = This->layer; | |||
src_box.z = From->layer; | |||
dst_box.depth = 1; | |||
src_box.depth = 1; | |||
if (pSourceRect) { | |||
/* make sure it doesn't range outside the source surface */ | |||
user_assert(pSourceRect->left >= 0 && | |||
pSourceRect->right <= From->desc.Width && | |||
pSourceRect->top >= 0 && | |||
pSourceRect->bottom <= From->desc.Height, | |||
D3DERR_INVALIDCALL); | |||
if (rect_to_pipe_box_xy_only_clamp(&src_box, pSourceRect)) | |||
return D3D_OK; | |||
} else { | |||
src_box.x = 0; | |||
src_box.y = 0; | |||
src_box.width = From->desc.Width; | |||
src_box.height = From->desc.Height; | |||
} | |||
/* limits */ | |||
dst_box.width = This->desc.Width - dst_box.x; | |||
dst_box.height = This->desc.Height - dst_box.y; | |||
user_assert(src_box.width <= dst_box.width && | |||
src_box.height <= dst_box.height, D3DERR_INVALIDCALL); | |||
dst_box.width = src_box.width; | |||
dst_box.height = src_box.height; | |||
/* Don't copy to device memory of managed resources. | |||
* We don't want to download it back again later. | |||
*/ | |||
if (This->base.pool == D3DPOOL_MANAGED) | |||
r_dst = NULL; | |||
/* Don't copy from stale device memory of managed resources. | |||
* Also, don't copy between system and device if we don't have to. | |||
*/ | |||
if (From->base.pool == D3DPOOL_MANAGED) { | |||
if (!r_dst || NineSurface9_IsDirty(From)) | |||
r_src = NULL; | |||
} | |||
if (r_dst && r_src) { | |||
pipe->resource_copy_region(pipe, | |||
r_dst, This->level, | |||
dst_box.x, dst_box.y, dst_box.z, | |||
r_src, From->level, | |||
&src_box); | |||
} else | |||
if (r_dst) { | |||
p_src = NineSurface9_GetSystemMemPointer(From, src_box.x, src_box.y); | |||
pipe->transfer_inline_write(pipe, r_dst, This->level, | |||
0, /* WRITE|DISCARD are implicit */ | |||
&dst_box, p_src, From->stride, 0); | |||
} else | |||
if (r_src) { | |||
p_dst = NineSurface9_GetSystemMemPointer(This, 0, 0); | |||
p_src = pipe->transfer_map(pipe, r_src, From->level, | |||
PIPE_TRANSFER_READ, | |||
&src_box, &transfer); | |||
if (!p_src) | |||
return D3DERR_DRIVERINTERNALERROR; | |||
util_copy_rect(p_dst, This->base.info.format, | |||
This->stride, dst_box.x, dst_box.y, | |||
dst_box.width, dst_box.height, | |||
p_src, | |||
transfer->stride, src_box.x, src_box.y); | |||
pipe->transfer_unmap(pipe, transfer); | |||
} else { | |||
p_dst = NineSurface9_GetSystemMemPointer(This, 0, 0); | |||
p_src = NineSurface9_GetSystemMemPointer(From, 0, 0); | |||
util_copy_rect(p_dst, This->base.info.format, | |||
This->stride, dst_box.x, dst_box.y, | |||
dst_box.width, dst_box.height, | |||
p_src, | |||
From->stride, src_box.x, src_box.y); | |||
} | |||
if (This->base.pool == D3DPOOL_DEFAULT || | |||
This->base.pool == D3DPOOL_MANAGED) | |||
NineSurface9_MarkContainerDirty(This); | |||
if (!r_dst && This->base.resource) | |||
NineSurface9_AddDirtyRect(This, &dst_box); | |||
return D3D_OK; | |||
} | |||
/* Gladly, rendering to a MANAGED surface is not permitted, so we will | |||
* never have to do the reverse, i.e. download the surface. | |||
*/ | |||
HRESULT | |||
NineSurface9_UploadSelf( struct NineSurface9 *This ) | |||
{ | |||
struct pipe_context *pipe = This->pipe; | |||
struct pipe_resource *res = This->base.resource; | |||
uint8_t *ptr; | |||
unsigned i; | |||
assert(This->base.pool == D3DPOOL_MANAGED); | |||
if (!NineSurface9_IsDirty(This)) | |||
return D3D_OK; | |||
for (i = 0; i < Elements(This->dirty_rects); ++i) { | |||
struct pipe_box box; | |||
nine_u_rect_to_pipe_box(&box, &This->dirty_rects[i], This->layer); | |||
if (box.width == 0) | |||
break; | |||
ptr = NineSurface9_GetSystemMemPointer(This, box.x, box.y); | |||
pipe->transfer_inline_write(pipe, res, This->level, | |||
0, | |||
&box, ptr, This->stride, 0); | |||
} | |||
NineSurface9_ClearDirtyRects(This); | |||
return D3D_OK; | |||
} | |||
void | |||
NineSurface9_SetResourceResize( struct NineSurface9 *This, | |||
struct pipe_resource *resource ) | |||
{ | |||
assert(This->level == 0 && This->level_actual == 0); | |||
assert(!This->lock_count); | |||
assert(This->desc.Pool == D3DPOOL_DEFAULT); | |||
assert(!This->texture); | |||
pipe_resource_reference(&This->base.resource, resource); | |||
This->desc.Width = This->base.info.width0 = resource->width0; | |||
This->desc.Height = This->base.info.height0 = resource->height0; | |||
This->stride = util_format_get_stride(This->base.info.format, | |||
This->desc.Width); | |||
This->stride = align(This->stride, 4); | |||
pipe_surface_reference(&This->surface[0], NULL); | |||
pipe_surface_reference(&This->surface[1], NULL); | |||
} | |||
static const GUID *NineSurface9_IIDs[] = { | |||
&IID_IDirect3DSurface9, | |||
&IID_IDirect3DResource9, | |||
&IID_IUnknown, | |||
NULL | |||
}; | |||
HRESULT | |||
NineSurface9_new( struct NineDevice9 *pDevice, | |||
struct NineUnknown *pContainer, | |||
struct pipe_resource *pResource, | |||
uint8_t TextureType, | |||
unsigned Level, | |||
unsigned Layer, | |||
D3DSURFACE_DESC *pDesc, | |||
struct NineSurface9 **ppOut ) | |||
{ | |||
NINE_DEVICE_CHILD_NEW(Surface9, ppOut, pDevice, /* args */ | |||
pContainer, pResource, | |||
TextureType, Level, Layer, pDesc); | |||
} |
@@ -0,0 +1,181 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_SURFACE9_H_ | |||
#define _NINE_SURFACE9_H_ | |||
#include "resource9.h" | |||
#include "pipe/p_state.h" | |||
#include "util/u_double_list.h" | |||
#include "util/u_rect.h" | |||
#include "util/u_inlines.h" | |||
struct NineSurface9 | |||
{ | |||
struct NineResource9 base; | |||
/* G3D state */ | |||
struct pipe_context *pipe; | |||
struct pipe_transfer *transfer; | |||
struct pipe_surface *surface[2]; /* created on-demand (linear, sRGB) */ | |||
int lock_count; | |||
uint8_t texture; /* rtype of container BaseTex or 0 */ | |||
/* resource description */ | |||
unsigned level; /* refers to the pipe_resource (SetLOD !) */ | |||
unsigned level_actual; /* refers to the NineTexture */ | |||
unsigned layer; | |||
D3DSURFACE_DESC desc; | |||
unsigned stride; /* for system memory backing */ | |||
/* wine doesn't even use these, 2 will be enough */ | |||
struct u_rect dirty_rects[2]; | |||
}; | |||
static INLINE struct NineSurface9 * | |||
NineSurface9( void *data ) | |||
{ | |||
return (struct NineSurface9 *)data; | |||
} | |||
HRESULT | |||
NineSurface9_new( struct NineDevice9 *pDevice, | |||
struct NineUnknown *pContainer, | |||
struct pipe_resource *pResource, | |||
uint8_t TextureType, /* 0 if pContainer isn't BaseTexure9 */ | |||
unsigned Level, | |||
unsigned Layer, | |||
D3DSURFACE_DESC *pDesc, | |||
struct NineSurface9 **ppOut ); | |||
HRESULT | |||
NineSurface9_ctor( struct NineSurface9 *This, | |||
struct NineUnknownParams *pParams, | |||
struct NineUnknown *pContainer, | |||
struct pipe_resource *pResource, | |||
uint8_t TextureType, | |||
unsigned Level, | |||
unsigned Layer, | |||
D3DSURFACE_DESC *pDesc ); | |||
void | |||
NineSurface9_dtor( struct NineSurface9 *This ); | |||
/*** Nine private ***/ | |||
struct pipe_surface * | |||
NineSurface9_CreatePipeSurface( struct NineSurface9 *This, const int sRGB ); | |||
static INLINE struct pipe_surface * | |||
NineSurface9_GetSurface( struct NineSurface9 *This, int sRGB ) | |||
{ | |||
if (This->surface[sRGB]) | |||
return This->surface[sRGB]; | |||
return NineSurface9_CreatePipeSurface(This, sRGB); | |||
} | |||
static INLINE struct pipe_resource * | |||
NineSurface9_GetResource( struct NineSurface9 *This ) | |||
{ | |||
return This->base.resource; | |||
} | |||
static INLINE void | |||
NineSurface9_SetResource( struct NineSurface9 *This, | |||
struct pipe_resource *resource, unsigned level ) | |||
{ | |||
This->level = level; | |||
pipe_resource_reference(&This->base.resource, resource); | |||
pipe_surface_reference(&This->surface[0], NULL); | |||
pipe_surface_reference(&This->surface[1], NULL); | |||
} | |||
void | |||
NineSurface9_SetResourceResize( struct NineSurface9 *This, | |||
struct pipe_resource *resource ); | |||
void | |||
NineSurface9_AddDirtyRect( struct NineSurface9 *This, | |||
const struct pipe_box *box ); | |||
static INLINE void | |||
NineSurface9_ClearDirtyRects( struct NineSurface9 *This ) | |||
{ | |||
memset(&This->dirty_rects, 0, sizeof(This->dirty_rects)); | |||
} | |||
HRESULT | |||
NineSurface9_AllocateData( struct NineSurface9 *This ); | |||
HRESULT | |||
NineSurface9_UploadSelf( struct NineSurface9 *This ); | |||
HRESULT | |||
NineSurface9_CopySurface( struct NineSurface9 *This, | |||
struct NineSurface9 *From, | |||
const POINT *pDestPoint, | |||
const RECT *pSourceRect ); | |||
static INLINE boolean | |||
NineSurface9_IsOffscreenPlain (struct NineSurface9 *This ) | |||
{ | |||
return This->base.usage == 0 && !This->texture; | |||
} | |||
#ifdef DEBUG | |||
void | |||
NineSurface9_Dump( struct NineSurface9 *This ); | |||
#else | |||
static INLINE void | |||
NineSurface9_Dump( struct NineSurface9 *This ) { } | |||
#endif | |||
/*** Direct3D public ***/ | |||
HRESULT WINAPI | |||
NineSurface9_GetContainer( struct NineSurface9 *This, | |||
REFIID riid, | |||
void **ppContainer ); | |||
HRESULT WINAPI | |||
NineSurface9_GetDesc( struct NineSurface9 *This, | |||
D3DSURFACE_DESC *pDesc ); | |||
HRESULT WINAPI | |||
NineSurface9_LockRect( struct NineSurface9 *This, | |||
D3DLOCKED_RECT *pLockedRect, | |||
const RECT *pRect, | |||
DWORD Flags ); | |||
HRESULT WINAPI | |||
NineSurface9_UnlockRect( struct NineSurface9 *This ); | |||
HRESULT WINAPI | |||
NineSurface9_GetDC( struct NineSurface9 *This, | |||
HDC *phdc ); | |||
HRESULT WINAPI | |||
NineSurface9_ReleaseDC( struct NineSurface9 *This, | |||
HDC hdc ); | |||
#endif /* _NINE_SURFACE9_H_ */ |
@@ -0,0 +1,871 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "swapchain9.h" | |||
#include "surface9.h" | |||
#include "device9.h" | |||
#include "nine_helpers.h" | |||
#include "nine_pipe.h" | |||
#include "nine_dump.h" | |||
#include "util/u_inlines.h" | |||
#include "util/u_surface.h" | |||
#include "hud/hud_context.h" | |||
#include "state_tracker/drm_driver.h" | |||
#define DBG_CHANNEL DBG_SWAPCHAIN | |||
#define UNTESTED(n) DBG("UNTESTED point %d. Please tell if it worked\n", n) | |||
HRESULT | |||
NineSwapChain9_ctor( struct NineSwapChain9 *This, | |||
struct NineUnknownParams *pParams, | |||
BOOL implicit, | |||
ID3DPresent *pPresent, | |||
D3DPRESENT_PARAMETERS *pPresentationParameters, | |||
struct d3dadapter9_context *pCTX, | |||
HWND hFocusWindow, | |||
D3DDISPLAYMODEEX *mode ) | |||
{ | |||
HRESULT hr; | |||
DBG("This=%p pDevice=%p pPresent=%p pCTX=%p hFocusWindow=%p\n", | |||
This, pParams->device, pPresent, pCTX, hFocusWindow); | |||
hr = NineUnknown_ctor(&This->base, pParams); | |||
if (FAILED(hr)) | |||
return hr; | |||
This->screen = NineDevice9_GetScreen(This->base.device); | |||
This->pipe = NineDevice9_GetPipe(This->base.device); | |||
This->cso = NineDevice9_GetCSO(This->base.device); | |||
This->implicit = implicit; | |||
This->actx = pCTX; | |||
This->present = pPresent; | |||
This->mode = NULL; | |||
ID3DPresent_AddRef(pPresent); | |||
if (!pPresentationParameters->hDeviceWindow) | |||
pPresentationParameters->hDeviceWindow = hFocusWindow; | |||
This->rendering_done = FALSE; | |||
return NineSwapChain9_Resize(This, pPresentationParameters, mode); | |||
} | |||
static D3DWindowBuffer * | |||
D3DWindowBuffer_create(struct NineSwapChain9 *This, | |||
struct pipe_resource *resource, | |||
int depth) | |||
{ | |||
D3DWindowBuffer *ret; | |||
struct winsys_handle whandle; | |||
int stride, dmaBufFd; | |||
memset(&whandle, 0, sizeof(whandle)); | |||
whandle.type = DRM_API_HANDLE_TYPE_FD; | |||
This->screen->resource_get_handle(This->screen, resource, &whandle); | |||
stride = whandle.stride; | |||
dmaBufFd = whandle.handle; | |||
ID3DPresent_NewD3DWindowBufferFromDmaBuf(This->present, | |||
dmaBufFd, | |||
resource->width0, | |||
resource->height0, | |||
stride, | |||
depth, | |||
32, | |||
&ret); | |||
return ret; | |||
} | |||
HRESULT | |||
NineSwapChain9_Resize( struct NineSwapChain9 *This, | |||
D3DPRESENT_PARAMETERS *pParams, | |||
D3DDISPLAYMODEEX *mode ) | |||
{ | |||
struct NineDevice9 *pDevice = This->base.device; | |||
struct NineSurface9 **bufs; | |||
D3DSURFACE_DESC desc; | |||
HRESULT hr; | |||
struct pipe_resource *resource, tmplt; | |||
enum pipe_format pf; | |||
BOOL has_present_buffers = FALSE; | |||
int depth; | |||
unsigned i, oldBufferCount, newBufferCount; | |||
DBG("This=%p pParams=%p\n", This, pParams); | |||
user_assert(pParams != NULL, E_POINTER); | |||
DBG("pParams(%p):\n" | |||
"BackBufferWidth: %u\n" | |||
"BackBufferHeight: %u\n" | |||
"BackBufferFormat: %s\n" | |||
"BackBufferCount: %u\n" | |||
"MultiSampleType: %u\n" | |||
"MultiSampleQuality: %u\n" | |||
"SwapEffect: %u\n" | |||
"hDeviceWindow: %p\n" | |||
"Windowed: %i\n" | |||
"EnableAutoDepthStencil: %i\n" | |||
"AutoDepthStencilFormat: %s\n" | |||
"Flags: %s\n" | |||
"FullScreen_RefreshRateInHz: %u\n" | |||
"PresentationInterval: %x\n", pParams, | |||
pParams->BackBufferWidth, pParams->BackBufferHeight, | |||
d3dformat_to_string(pParams->BackBufferFormat), | |||
pParams->BackBufferCount, | |||
pParams->MultiSampleType, pParams->MultiSampleQuality, | |||
pParams->SwapEffect, pParams->hDeviceWindow, pParams->Windowed, | |||
pParams->EnableAutoDepthStencil, | |||
d3dformat_to_string(pParams->AutoDepthStencilFormat), | |||
nine_D3DPRESENTFLAG_to_str(pParams->Flags), | |||
pParams->FullScreen_RefreshRateInHz, | |||
pParams->PresentationInterval); | |||
if (pParams->SwapEffect == D3DSWAPEFFECT_COPY && | |||
pParams->BackBufferCount > 1) { | |||
pParams->BackBufferCount = 1; | |||
} | |||
if (pParams->BackBufferCount > 3) { | |||
pParams->BackBufferCount = 3; | |||
} | |||
if (pParams->BackBufferCount == 0) { | |||
pParams->BackBufferCount = 1; | |||
} | |||
if (pParams->BackBufferFormat == D3DFMT_UNKNOWN) { | |||
pParams->BackBufferFormat = D3DFMT_A8R8G8B8; | |||
} | |||
This->desired_fences = This->actx->throttling ? This->actx->throttling_value + 1 : 0; | |||
/* +1 because we add the fence of the current buffer before popping an old one */ | |||
if (This->desired_fences > DRI_SWAP_FENCES_MAX) | |||
This->desired_fences = DRI_SWAP_FENCES_MAX; | |||
if (mode && This->mode) { | |||
*(This->mode) = *mode; | |||
} else if (mode) { | |||
This->mode = malloc(sizeof(D3DDISPLAYMODEEX)); | |||
memcpy(This->mode, mode, sizeof(D3DDISPLAYMODEEX)); | |||
} else if (This->mode) { | |||
free(This->mode); | |||
This->mode = NULL; | |||
} | |||
/* Note: It is the role of the backend to fill if neccessary | |||
* BackBufferWidth and BackBufferHeight */ | |||
ID3DPresent_SetPresentParameters(This->present, pParams, This->mode); | |||
/* When we have flip behaviour, d3d9 expects we get back the screen buffer when we flip. | |||
* Here we don't get back the initial content of the screen. To emulate the behaviour | |||
* we allocate an additional buffer */ | |||
oldBufferCount = This->params.BackBufferCount ? | |||
(This->params.BackBufferCount + | |||
(This->params.SwapEffect != D3DSWAPEFFECT_COPY)) : 0; | |||
newBufferCount = pParams->BackBufferCount + | |||
(pParams->SwapEffect != D3DSWAPEFFECT_COPY); | |||
pf = d3d9_to_pipe_format(pParams->BackBufferFormat); | |||
if (This->actx->linear_framebuffer || | |||
(pf != PIPE_FORMAT_B8G8R8X8_UNORM && | |||
pf != PIPE_FORMAT_B8G8R8A8_UNORM) || | |||
pParams->SwapEffect != D3DSWAPEFFECT_DISCARD || | |||
pParams->MultiSampleType >= 2 || | |||
(This->actx->ref && This->actx->ref == This->screen)) | |||
has_present_buffers = TRUE; | |||
/* Note: the buffer depth has to match the window depth. | |||
* In practice, ARGB buffers can be used with windows | |||
* of depth 24. Windows of depth 32 are extremely rare. | |||
* So even if the buffer is ARGB, say it is depth 24. | |||
* It is common practice, for example that's how | |||
* glamor implements depth 24. | |||
* TODO: handle windows with other depths. Not possible in the short term. | |||
* For example 16 bits.*/ | |||
depth = 24; | |||
tmplt.target = PIPE_TEXTURE_2D; | |||
tmplt.width0 = pParams->BackBufferWidth; | |||
tmplt.height0 = pParams->BackBufferHeight; | |||
tmplt.depth0 = 1; | |||
tmplt.last_level = 0; | |||
tmplt.array_size = 1; | |||
tmplt.usage = PIPE_USAGE_DEFAULT; | |||
tmplt.flags = 0; | |||
desc.Type = D3DRTYPE_SURFACE; | |||
desc.Pool = D3DPOOL_DEFAULT; | |||
desc.MultiSampleType = pParams->MultiSampleType; | |||
desc.MultiSampleQuality = 0; | |||
desc.Width = pParams->BackBufferWidth; | |||
desc.Height = pParams->BackBufferHeight; | |||
for (i = 0; i < oldBufferCount; i++) { | |||
ID3DPresent_DestroyD3DWindowBuffer(This->present, This->present_handles[i]); | |||
This->present_handles[i] = NULL; | |||
if (This->present_buffers) | |||
pipe_resource_reference(&(This->present_buffers[i]), NULL); | |||
} | |||
if (!has_present_buffers && This->present_buffers) { | |||
FREE(This->present_buffers); | |||
This->present_buffers = NULL; | |||
} | |||
if (newBufferCount != oldBufferCount) { | |||
for (i = newBufferCount; i < oldBufferCount; | |||
++i) | |||
NineUnknown_Detach(NineUnknown(This->buffers[i])); | |||
bufs = REALLOC(This->buffers, | |||
oldBufferCount * sizeof(This->buffers[0]), | |||
newBufferCount * sizeof(This->buffers[0])); | |||
if (!bufs) | |||
return E_OUTOFMEMORY; | |||
This->buffers = bufs; | |||
if (has_present_buffers) { | |||
This->present_buffers = REALLOC(This->present_buffers, | |||
This->present_buffers == NULL ? 0 : oldBufferCount * sizeof(struct pipe_resource *), | |||
newBufferCount * sizeof(struct pipe_resource *)); | |||
memset(This->present_buffers, 0, newBufferCount * sizeof(struct pipe_resource *)); | |||
} | |||
This->present_handles = REALLOC(This->present_handles, | |||
oldBufferCount * sizeof(D3DWindowBuffer *), | |||
newBufferCount * sizeof(D3DWindowBuffer *)); | |||
for (i = oldBufferCount; i < newBufferCount; ++i) { | |||
This->buffers[i] = NULL; | |||
This->present_handles[i] = NULL; | |||
} | |||
} | |||
for (i = 0; i < newBufferCount; ++i) { | |||
tmplt.format = d3d9_to_pipe_format(pParams->BackBufferFormat); | |||
tmplt.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_TRANSFER_READ | | |||
PIPE_BIND_TRANSFER_WRITE | PIPE_BIND_RENDER_TARGET; | |||
tmplt.nr_samples = pParams->MultiSampleType; | |||
if (!has_present_buffers) | |||
tmplt.bind |= PIPE_BIND_SHARED | PIPE_BIND_SCANOUT | PIPE_BIND_DISPLAY_TARGET; | |||
resource = This->screen->resource_create(This->screen, &tmplt); | |||
if (!resource) { | |||
DBG("Failed to create pipe_resource.\n"); | |||
return D3DERR_OUTOFVIDEOMEMORY; | |||
} | |||
if (pParams->Flags & D3DPRESENTFLAG_LOCKABLE_BACKBUFFER) | |||
resource->flags |= NINE_RESOURCE_FLAG_LOCKABLE; | |||
if (This->buffers[i]) { | |||
NineSurface9_SetResourceResize(This->buffers[i], resource); | |||
if (has_present_buffers) | |||
pipe_resource_reference(&resource, NULL); | |||
} else { | |||
desc.Format = pParams->BackBufferFormat; | |||
desc.Usage = D3DUSAGE_RENDERTARGET; | |||
hr = NineSurface9_new(pDevice, NineUnknown(This), resource, 0, | |||
0, 0, &desc, &This->buffers[i]); | |||
if (has_present_buffers) | |||
pipe_resource_reference(&resource, NULL); | |||
if (FAILED(hr)) { | |||
DBG("Failed to create RT surface.\n"); | |||
return hr; | |||
} | |||
This->buffers[i]->base.base.forward = FALSE; | |||
} | |||
if (has_present_buffers) { | |||
tmplt.format = PIPE_FORMAT_B8G8R8X8_UNORM; | |||
tmplt.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_SHARED | PIPE_BIND_SCANOUT | PIPE_BIND_DISPLAY_TARGET; | |||
tmplt.nr_samples = 0; | |||
if (This->actx->linear_framebuffer) | |||
tmplt.bind |= PIPE_BIND_LINEAR; | |||
if (pParams->SwapEffect != D3DSWAPEFFECT_DISCARD) | |||
tmplt.bind |= PIPE_BIND_RENDER_TARGET; | |||
resource = This->screen->resource_create(This->screen, &tmplt); | |||
pipe_resource_reference(&(This->present_buffers[i]), resource); | |||
} | |||
This->present_handles[i] = D3DWindowBuffer_create(This, resource, depth); | |||
if (!has_present_buffers) | |||
pipe_resource_reference(&resource, NULL); | |||
} | |||
if (pParams->EnableAutoDepthStencil) { | |||
tmplt.format = d3d9_to_pipe_format(pParams->AutoDepthStencilFormat); | |||
tmplt.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_TRANSFER_READ | | |||
PIPE_BIND_TRANSFER_WRITE | PIPE_BIND_DEPTH_STENCIL; | |||
tmplt.nr_samples = pParams->MultiSampleType; | |||
resource = This->screen->resource_create(This->screen, &tmplt); | |||
if (!resource) { | |||
DBG("Failed to create pipe_resource for depth buffer.\n"); | |||
return D3DERR_OUTOFVIDEOMEMORY; | |||
} | |||
if (This->zsbuf) { | |||
NineSurface9_SetResourceResize(This->zsbuf, resource); | |||
pipe_resource_reference(&resource, NULL); | |||
} else { | |||
/* XXX wine thinks the container of this should be the device */ | |||
desc.Format = pParams->AutoDepthStencilFormat; | |||
desc.Usage = D3DUSAGE_DEPTHSTENCIL; | |||
hr = NineSurface9_new(pDevice, NineUnknown(pDevice), resource, 0, | |||
0, 0, &desc, &This->zsbuf); | |||
pipe_resource_reference(&resource, NULL); | |||
if (FAILED(hr)) { | |||
DBG("Failed to create ZS surface.\n"); | |||
return hr; | |||
} | |||
This->zsbuf->base.base.forward = FALSE; | |||
} | |||
} | |||
This->params = *pParams; | |||
return D3D_OK; | |||
} | |||
/* Throttling: code adapted from the dri state tracker */ | |||
/** | |||
* swap_fences_pop_front - pull a fence from the throttle queue | |||
* | |||
* If the throttle queue is filled to the desired number of fences, | |||
* pull fences off the queue until the number is less than the desired | |||
* number of fences, and return the last fence pulled. | |||
*/ | |||
static struct pipe_fence_handle * | |||
swap_fences_pop_front(struct NineSwapChain9 *This) | |||
{ | |||
struct pipe_screen *screen = This->screen; | |||
struct pipe_fence_handle *fence = NULL; | |||
if (This->desired_fences == 0) | |||
return NULL; | |||
if (This->cur_fences >= This->desired_fences) { | |||
screen->fence_reference(screen, &fence, This->swap_fences[This->tail]); | |||
screen->fence_reference(screen, &This->swap_fences[This->tail++], NULL); | |||
This->tail &= DRI_SWAP_FENCES_MASK; | |||
--This->cur_fences; | |||
} | |||
return fence; | |||
} | |||
/** | |||
* swap_fences_see_front - same than swap_fences_pop_front without | |||
* pulling | |||
* | |||
*/ | |||
static struct pipe_fence_handle * | |||
swap_fences_see_front(struct NineSwapChain9 *This) | |||
{ | |||
struct pipe_screen *screen = This->screen; | |||
struct pipe_fence_handle *fence = NULL; | |||
if (This->desired_fences == 0) | |||
return NULL; | |||
if (This->cur_fences >= This->desired_fences) { | |||
screen->fence_reference(screen, &fence, This->swap_fences[This->tail]); | |||
} | |||
return fence; | |||
} | |||
/** | |||
* swap_fences_push_back - push a fence onto the throttle queue at the back | |||
* | |||
* push a fence onto the throttle queue and pull fences of the queue | |||
* so that the desired number of fences are on the queue. | |||
*/ | |||
static void | |||
swap_fences_push_back(struct NineSwapChain9 *This, | |||
struct pipe_fence_handle *fence) | |||
{ | |||
struct pipe_screen *screen = This->screen; | |||
if (!fence || This->desired_fences == 0) | |||
return; | |||
while(This->cur_fences == This->desired_fences) | |||
swap_fences_pop_front(This); | |||
This->cur_fences++; | |||
screen->fence_reference(screen, &This->swap_fences[This->head++], | |||
fence); | |||
This->head &= DRI_SWAP_FENCES_MASK; | |||
} | |||
/** | |||
* swap_fences_unref - empty the throttle queue | |||
* | |||
* pulls fences of the throttle queue until it is empty. | |||
*/ | |||
static void | |||
swap_fences_unref(struct NineSwapChain9 *This) | |||
{ | |||
struct pipe_screen *screen = This->screen; | |||
while(This->cur_fences) { | |||
screen->fence_reference(screen, &This->swap_fences[This->tail++], NULL); | |||
This->tail &= DRI_SWAP_FENCES_MASK; | |||
--This->cur_fences; | |||
} | |||
} | |||
void | |||
NineSwapChain9_dtor( struct NineSwapChain9 *This ) | |||
{ | |||
unsigned i; | |||
DBG("This=%p\n", This); | |||
if (This->buffers) { | |||
for (i = 0; i < This->params.BackBufferCount; i++) { | |||
NineUnknown_Destroy(NineUnknown(This->buffers[i])); | |||
ID3DPresent_DestroyD3DWindowBuffer(This->present, This->present_handles[i]); | |||
if (This->present_buffers) | |||
pipe_resource_reference(&(This->present_buffers[i]), NULL); | |||
} | |||
FREE(This->buffers); | |||
FREE(This->present_buffers); | |||
} | |||
if (This->zsbuf) | |||
NineUnknown_Destroy(NineUnknown(This->zsbuf)); | |||
if (This->present) | |||
ID3DPresent_Release(This->present); | |||
swap_fences_unref(This); | |||
NineUnknown_dtor(&This->base); | |||
} | |||
static void | |||
create_present_buffer( struct NineSwapChain9 *This, | |||
unsigned int width, unsigned int height, | |||
struct pipe_resource **resource, | |||
D3DWindowBuffer **present_handle) | |||
{ | |||
struct pipe_resource tmplt; | |||
tmplt.target = PIPE_TEXTURE_2D; | |||
tmplt.width0 = width; | |||
tmplt.height0 = height; | |||
tmplt.depth0 = 1; | |||
tmplt.last_level = 0; | |||
tmplt.array_size = 1; | |||
tmplt.usage = PIPE_USAGE_DEFAULT; | |||
tmplt.flags = 0; | |||
tmplt.format = PIPE_FORMAT_B8G8R8X8_UNORM; | |||
tmplt.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_TRANSFER_READ | | |||
PIPE_BIND_TRANSFER_WRITE | PIPE_BIND_RENDER_TARGET | | |||
PIPE_BIND_SHARED | PIPE_BIND_SCANOUT | PIPE_BIND_DISPLAY_TARGET; | |||
tmplt.nr_samples = 0; | |||
if (This->actx->linear_framebuffer) | |||
tmplt.bind |= PIPE_BIND_LINEAR; | |||
*resource = This->screen->resource_create(This->screen, &tmplt); | |||
*present_handle = D3DWindowBuffer_create(This, *resource, 24); | |||
} | |||
static void | |||
handle_draw_cursor_and_hud( struct NineSwapChain9 *This, struct pipe_resource *resource) | |||
{ | |||
struct NineDevice9 *device = This->base.device; | |||
struct pipe_blit_info blit; | |||
if (device->cursor.software && device->cursor.visible && device->cursor.w) { | |||
blit.src.resource = device->cursor.image; | |||
blit.src.level = 0; | |||
blit.src.format = device->cursor.image->format; | |||
blit.src.box.x = 0; | |||
blit.src.box.y = 0; | |||
blit.src.box.z = 0; | |||
blit.src.box.depth = 1; | |||
blit.src.box.width = device->cursor.w; | |||
blit.src.box.height = device->cursor.h; | |||
blit.dst.resource = resource; | |||
blit.dst.level = 0; | |||
blit.dst.format = resource->format; | |||
blit.dst.box.z = 0; | |||
blit.dst.box.depth = 1; | |||
blit.mask = PIPE_MASK_RGBA; | |||
blit.filter = PIPE_TEX_FILTER_NEAREST; | |||
blit.scissor_enable = FALSE; | |||
ID3DPresent_GetCursorPos(This->present, &device->cursor.pos); | |||
/* NOTE: blit messes up when box.x + box.width < 0, fix driver */ | |||
blit.dst.box.x = MAX2(device->cursor.pos.x, 0) - device->cursor.hotspot.x; | |||
blit.dst.box.y = MAX2(device->cursor.pos.y, 0) - device->cursor.hotspot.y; | |||
blit.dst.box.width = blit.src.box.width; | |||
blit.dst.box.height = blit.src.box.height; | |||
DBG("Blitting cursor(%ux%u) to (%i,%i).\n", | |||
blit.src.box.width, blit.src.box.height, | |||
blit.dst.box.x, blit.dst.box.y); | |||
This->pipe->blit(This->pipe, &blit); | |||
} | |||
if (device->hud && resource) { | |||
hud_draw(device->hud, resource); /* XXX: no offset */ | |||
/* HUD doesn't clobber stipple */ | |||
NineDevice9_RestoreNonCSOState(device, ~0x2); | |||
} | |||
} | |||
static INLINE HRESULT | |||
present( struct NineSwapChain9 *This, | |||
const RECT *pSourceRect, | |||
const RECT *pDestRect, | |||
HWND hDestWindowOverride, | |||
const RGNDATA *pDirtyRegion, | |||
DWORD dwFlags ) | |||
{ | |||
struct pipe_resource *resource; | |||
struct pipe_fence_handle *fence; | |||
HRESULT hr; | |||
struct pipe_blit_info blit; | |||
DBG("present: This=%p pSourceRect=%p pDestRect=%p " | |||
"pDirtyRegion=%p hDestWindowOverride=%p" | |||
"dwFlags=%d resource=%p\n", | |||
This, pSourceRect, pDestRect, pDirtyRegion, | |||
hDestWindowOverride, (int)dwFlags, This->buffers[0]->base.resource); | |||
if (pSourceRect) | |||
DBG("pSourceRect = (%u..%u)x(%u..%u)\n", | |||
pSourceRect->left, pSourceRect->right, | |||
pSourceRect->top, pSourceRect->bottom); | |||
if (pDestRect) | |||
DBG("pDestRect = (%u..%u)x(%u..%u)\n", | |||
pDestRect->left, pDestRect->right, | |||
pDestRect->top, pDestRect->bottom); | |||
/* TODO: in the case the source and destination rect have different size: | |||
* We need to allocate a new buffer, and do a blit to it to resize. | |||
* We can't use the present_buffer for that since when we created it, | |||
* we couldn't guess which size would have been needed. | |||
* If pDestRect or pSourceRect is null, we have to check the sizes | |||
* from the source size, and the destination window size. | |||
* In this case, either resize rngdata, or pass NULL instead | |||
*/ | |||
/* Note: This->buffers[0]->level should always be 0 */ | |||
if (This->rendering_done) | |||
goto bypass_rendering; | |||
resource = This->buffers[0]->base.resource; | |||
if (This->params.SwapEffect == D3DSWAPEFFECT_DISCARD) | |||
handle_draw_cursor_and_hud(This, resource); | |||
if (This->present_buffers) { | |||
blit.src.resource = resource; | |||
blit.src.level = 0; | |||
blit.src.format = resource->format; | |||
blit.src.box.z = 0; | |||
blit.src.box.depth = 1; | |||
blit.src.box.x = 0; | |||
blit.src.box.y = 0; | |||
blit.src.box.width = resource->width0; | |||
blit.src.box.height = resource->height0; | |||
resource = This->present_buffers[0]; | |||
blit.dst.resource = resource; | |||
blit.dst.level = 0; | |||
blit.dst.format = resource->format; | |||
blit.dst.box.z = 0; | |||
blit.dst.box.depth = 1; | |||
blit.dst.box.x = 0; | |||
blit.dst.box.y = 0; | |||
blit.dst.box.width = resource->width0; | |||
blit.dst.box.height = resource->height0; | |||
blit.mask = PIPE_MASK_RGBA; | |||
blit.filter = PIPE_TEX_FILTER_NEAREST; | |||
blit.scissor_enable = FALSE; | |||
This->pipe->blit(This->pipe, &blit); | |||
} | |||
if (This->params.SwapEffect != D3DSWAPEFFECT_DISCARD) | |||
handle_draw_cursor_and_hud(This, resource); | |||
fence = NULL; | |||
This->pipe->flush(This->pipe, &fence, PIPE_FLUSH_END_OF_FRAME); | |||
if (fence) { | |||
swap_fences_push_back(This, fence); | |||
This->screen->fence_reference(This->screen, &fence, NULL); | |||
} | |||
This->rendering_done = TRUE; | |||
bypass_rendering: | |||
if (dwFlags & D3DPRESENT_DONOTWAIT) { | |||
UNTESTED(2); | |||
BOOL still_draw = FALSE; | |||
fence = swap_fences_see_front(This); | |||
if (fence) { | |||
still_draw = !This->screen->fence_signalled(This->screen, fence); | |||
This->screen->fence_reference(This->screen, &fence, NULL); | |||
} | |||
if (still_draw) | |||
return D3DERR_WASSTILLDRAWING; | |||
} | |||
fence = swap_fences_pop_front(This); | |||
if (fence) { | |||
(void) This->screen->fence_finish(This->screen, fence, PIPE_TIMEOUT_INFINITE); | |||
This->screen->fence_reference(This->screen, &fence, NULL); | |||
} | |||
if (This->present_buffers) | |||
resource = This->present_buffers[0]; | |||
else | |||
resource = This->buffers[0]->base.resource; | |||
This->pipe->flush_resource(This->pipe, resource); | |||
hr = ID3DPresent_PresentBuffer(This->present, This->present_handles[0], hDestWindowOverride, pSourceRect, pDestRect, pDirtyRegion, dwFlags); | |||
if (FAILED(hr)) { UNTESTED(3);return hr; } | |||
This->rendering_done = FALSE; | |||
return D3D_OK; | |||
} | |||
HRESULT WINAPI | |||
NineSwapChain9_Present( struct NineSwapChain9 *This, | |||
const RECT *pSourceRect, | |||
const RECT *pDestRect, | |||
HWND hDestWindowOverride, | |||
const RGNDATA *pDirtyRegion, | |||
DWORD dwFlags ) | |||
{ | |||
struct pipe_resource *res = NULL; | |||
D3DWindowBuffer *handle_temp; | |||
int i; | |||
BOOL released; | |||
HRESULT hr = present(This, pSourceRect, pDestRect, | |||
hDestWindowOverride, pDirtyRegion, dwFlags); | |||
if (hr == D3DERR_WASSTILLDRAWING) | |||
return hr; | |||
switch (This->params.SwapEffect) { | |||
case D3DSWAPEFFECT_FLIP: | |||
UNTESTED(4); | |||
case D3DSWAPEFFECT_DISCARD: | |||
/* rotate the queue */; | |||
pipe_resource_reference(&res, This->buffers[0]->base.resource); | |||
for (i = 1; i <= This->params.BackBufferCount; i++) { | |||
NineSurface9_SetResourceResize(This->buffers[i - 1], | |||
This->buffers[i]->base.resource); | |||
} | |||
NineSurface9_SetResourceResize( | |||
This->buffers[This->params.BackBufferCount], res); | |||
pipe_resource_reference(&res, NULL); | |||
if (This->present_buffers) { | |||
pipe_resource_reference(&res, This->present_buffers[0]); | |||
for (i = 1; i <= This->params.BackBufferCount; i++) | |||
pipe_resource_reference(&(This->present_buffers[i-1]), This->present_buffers[i]); | |||
pipe_resource_reference(&(This->present_buffers[This->params.BackBufferCount]), res); | |||
pipe_resource_reference(&res, NULL); | |||
} | |||
handle_temp = This->present_handles[0]; | |||
for (i = 1; i <= This->params.BackBufferCount; i++) { | |||
This->present_handles[i-1] = This->present_handles[i]; | |||
} | |||
This->present_handles[This->params.BackBufferCount] = handle_temp; | |||
break; | |||
case D3DSWAPEFFECT_COPY: | |||
UNTESTED(5); | |||
/* do nothing */ | |||
break; | |||
case D3DSWAPEFFECT_OVERLAY: | |||
/* XXX not implemented */ | |||
break; | |||
case D3DSWAPEFFECT_FLIPEX: | |||
/* XXX not implemented */ | |||
break; | |||
} | |||
ID3DPresent_WaitBufferReleased(This->present, This->present_handles[0]); | |||
This->base.device->state.changed.group |= NINE_STATE_FB; | |||
nine_update_state(This->base.device, NINE_STATE_FB); | |||
return hr; | |||
} | |||
HRESULT WINAPI | |||
NineSwapChain9_GetFrontBufferData( struct NineSwapChain9 *This, | |||
IDirect3DSurface9 *pDestSurface ) | |||
{ | |||
struct NineSurface9 *dest_surface = NineSurface9(pDestSurface); | |||
struct NineDevice9 *pDevice = This->base.device; | |||
unsigned int width, height; | |||
struct pipe_resource *temp_resource; | |||
struct NineSurface9 *temp_surface; | |||
D3DWindowBuffer *temp_handle; | |||
D3DSURFACE_DESC desc; | |||
HRESULT hr; | |||
DBG("GetFrontBufferData: This=%p pDestSurface=%p\n", | |||
This, pDestSurface); | |||
width = dest_surface->desc.Width; | |||
height = dest_surface->desc.Height; | |||
/* Note: front window size and destination size are supposed | |||
* to match. However it's not very clear what should get taken in Windowed | |||
* mode. It may need a fix */ | |||
create_present_buffer(This, width, height, &temp_resource, &temp_handle); | |||
desc.Type = D3DRTYPE_SURFACE; | |||
desc.Pool = D3DPOOL_DEFAULT; | |||
desc.MultiSampleType = D3DMULTISAMPLE_NONE; | |||
desc.MultiSampleQuality = 0; | |||
desc.Width = width; | |||
desc.Height = height; | |||
/* NineSurface9_CopySurface needs same format. */ | |||
desc.Format = dest_surface->desc.Format; | |||
desc.Usage = D3DUSAGE_RENDERTARGET; | |||
hr = NineSurface9_new(pDevice, NineUnknown(This), temp_resource, 0, | |||
0, 0, &desc, &temp_surface); | |||
pipe_resource_reference(&temp_resource, NULL); | |||
if (FAILED(hr)) { | |||
DBG("Failed to create temp FrontBuffer surface.\n"); | |||
return hr; | |||
} | |||
ID3DPresent_FrontBufferCopy(This->present, temp_handle); | |||
NineSurface9_CopySurface(dest_surface, temp_surface, NULL, NULL); | |||
ID3DPresent_DestroyD3DWindowBuffer(This->present, temp_handle); | |||
NineUnknown_Destroy(NineUnknown(temp_surface)); | |||
return D3D_OK; | |||
} | |||
HRESULT WINAPI | |||
NineSwapChain9_GetBackBuffer( struct NineSwapChain9 *This, | |||
UINT iBackBuffer, | |||
D3DBACKBUFFER_TYPE Type, | |||
IDirect3DSurface9 **ppBackBuffer ) | |||
{ | |||
DBG("GetBackBuffer: This=%p iBackBuffer=%d Type=%d ppBackBuffer=%p\n", | |||
This, iBackBuffer, Type, ppBackBuffer); | |||
(void)user_error(Type == D3DBACKBUFFER_TYPE_MONO); | |||
user_assert(iBackBuffer < This->params.BackBufferCount, D3DERR_INVALIDCALL); | |||
user_assert(ppBackBuffer != NULL, E_POINTER); | |||
NineUnknown_AddRef(NineUnknown(This->buffers[iBackBuffer])); | |||
*ppBackBuffer = (IDirect3DSurface9 *)This->buffers[iBackBuffer]; | |||
return D3D_OK; | |||
} | |||
HRESULT WINAPI | |||
NineSwapChain9_GetRasterStatus( struct NineSwapChain9 *This, | |||
D3DRASTER_STATUS *pRasterStatus ) | |||
{ | |||
DBG("GetRasterStatus: This=%p pRasterStatus=%p\n", | |||
This, pRasterStatus); | |||
user_assert(pRasterStatus != NULL, E_POINTER); | |||
return ID3DPresent_GetRasterStatus(This->present, pRasterStatus); | |||
} | |||
HRESULT WINAPI | |||
NineSwapChain9_GetDisplayMode( struct NineSwapChain9 *This, | |||
D3DDISPLAYMODE *pMode ) | |||
{ | |||
D3DDISPLAYMODEEX mode; | |||
D3DDISPLAYROTATION rot; | |||
HRESULT hr; | |||
DBG("GetDisplayMode: This=%p pMode=%p\n", | |||
This, pMode); | |||
user_assert(pMode != NULL, E_POINTER); | |||
hr = ID3DPresent_GetDisplayMode(This->present, &mode, &rot); | |||
if (SUCCEEDED(hr)) { | |||
pMode->Width = mode.Width; | |||
pMode->Height = mode.Height; | |||
pMode->RefreshRate = mode.RefreshRate; | |||
pMode->Format = mode.Format; | |||
} | |||
return hr; | |||
} | |||
HRESULT WINAPI | |||
NineSwapChain9_GetPresentParameters( struct NineSwapChain9 *This, | |||
D3DPRESENT_PARAMETERS *pPresentationParameters ) | |||
{ | |||
DBG("GetPresentParameters: This=%p pPresentationParameters=%p\n", | |||
This, pPresentationParameters); | |||
user_assert(pPresentationParameters != NULL, E_POINTER); | |||
*pPresentationParameters = This->params; | |||
return D3D_OK; | |||
} | |||
IDirect3DSwapChain9Vtbl NineSwapChain9_vtable = { | |||
(void *)NineUnknown_QueryInterface, | |||
(void *)NineUnknown_AddRef, | |||
(void *)NineUnknown_Release, | |||
(void *)NineSwapChain9_Present, | |||
(void *)NineSwapChain9_GetFrontBufferData, | |||
(void *)NineSwapChain9_GetBackBuffer, | |||
(void *)NineSwapChain9_GetRasterStatus, | |||
(void *)NineSwapChain9_GetDisplayMode, | |||
(void *)NineUnknown_GetDevice, /* actually part of SwapChain9 iface */ | |||
(void *)NineSwapChain9_GetPresentParameters | |||
}; | |||
static const GUID *NineSwapChain9_IIDs[] = { | |||
&IID_IDirect3DSwapChain9, | |||
&IID_IUnknown, | |||
NULL | |||
}; | |||
HRESULT | |||
NineSwapChain9_new( struct NineDevice9 *pDevice, | |||
BOOL implicit, | |||
ID3DPresent *pPresent, | |||
D3DPRESENT_PARAMETERS *pPresentationParameters, | |||
struct d3dadapter9_context *pCTX, | |||
HWND hFocusWindow, | |||
struct NineSwapChain9 **ppOut ) | |||
{ | |||
NINE_DEVICE_CHILD_NEW(SwapChain9, ppOut, pDevice, /* args */ | |||
implicit, pPresent, pPresentationParameters, | |||
pCTX, hFocusWindow, NULL); | |||
} |
@@ -0,0 +1,135 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_SWAPCHAIN9_H_ | |||
#define _NINE_SWAPCHAIN9_H_ | |||
#include "iunknown.h" | |||
#include "adapter9.h" | |||
#include "d3dadapter/d3dadapter9.h" | |||
struct NineDevice9; | |||
struct NineSurface9; | |||
struct nine_winsys_swapchain; | |||
struct blit_state; | |||
#define DRI_SWAP_FENCES_MAX 4 | |||
#define DRI_SWAP_FENCES_MASK 3 | |||
struct NineSwapChain9 | |||
{ | |||
struct NineUnknown base; | |||
/* G3D stuff */ | |||
struct pipe_screen *screen; | |||
struct pipe_context *pipe; | |||
struct cso_context *cso; | |||
/* presentation backend */ | |||
ID3DPresent *present; | |||
D3DPRESENT_PARAMETERS params; | |||
D3DDISPLAYMODEEX *mode; | |||
struct d3dadapter9_context *actx; | |||
BOOL implicit; | |||
/* buffer handles */ | |||
struct NineSurface9 **buffers; /* 0 to BackBufferCount-1 : the back buffers. BackBufferCount : additional buffer */ | |||
struct pipe_resource **present_buffers; | |||
D3DWindowBuffer **present_handles; | |||
struct pipe_fence_handle *swap_fences[DRI_SWAP_FENCES_MAX]; | |||
unsigned int cur_fences; | |||
unsigned int head; | |||
unsigned int tail; | |||
unsigned int desired_fences; | |||
BOOL rendering_done; | |||
struct NineSurface9 *zsbuf; | |||
D3DGAMMARAMP gamma; | |||
}; | |||
static INLINE struct NineSwapChain9 * | |||
NineSwapChain9( void *data ) | |||
{ | |||
return (struct NineSwapChain9 *)data; | |||
} | |||
HRESULT | |||
NineSwapChain9_new( struct NineDevice9 *pDevice, | |||
BOOL implicit, | |||
ID3DPresent *pPresent, | |||
D3DPRESENT_PARAMETERS *pPresentationParameters, | |||
struct d3dadapter9_context *pCTX, | |||
HWND hFocusWindow, | |||
struct NineSwapChain9 **ppOut ); | |||
HRESULT | |||
NineSwapChain9_ctor( struct NineSwapChain9 *This, | |||
struct NineUnknownParams *pParams, | |||
BOOL implicit, | |||
ID3DPresent *pPresent, | |||
D3DPRESENT_PARAMETERS *pPresentationParameters, | |||
struct d3dadapter9_context *pCTX, | |||
HWND hFocusWindow, | |||
D3DDISPLAYMODEEX *mode ); | |||
void | |||
NineSwapChain9_dtor( struct NineSwapChain9 *This ); | |||
HRESULT | |||
NineSwapChain9_Resize( struct NineSwapChain9 *This, | |||
D3DPRESENT_PARAMETERS *pParams, | |||
D3DDISPLAYMODEEX *mode ); | |||
HRESULT WINAPI | |||
NineSwapChain9_Present( struct NineSwapChain9 *This, | |||
const RECT *pSourceRect, | |||
const RECT *pDestRect, | |||
HWND hDestWindowOverride, | |||
const RGNDATA *pDirtyRegion, | |||
DWORD dwFlags ); | |||
HRESULT WINAPI | |||
NineSwapChain9_GetFrontBufferData( struct NineSwapChain9 *This, | |||
IDirect3DSurface9 *pDestSurface ); | |||
HRESULT WINAPI | |||
NineSwapChain9_GetBackBuffer( struct NineSwapChain9 *This, | |||
UINT iBackBuffer, | |||
D3DBACKBUFFER_TYPE Type, | |||
IDirect3DSurface9 **ppBackBuffer ); | |||
HRESULT WINAPI | |||
NineSwapChain9_GetRasterStatus( struct NineSwapChain9 *This, | |||
D3DRASTER_STATUS *pRasterStatus ); | |||
HRESULT WINAPI | |||
NineSwapChain9_GetDisplayMode( struct NineSwapChain9 *This, | |||
D3DDISPLAYMODE *pMode ); | |||
HRESULT WINAPI | |||
NineSwapChain9_GetPresentParameters( struct NineSwapChain9 *This, | |||
D3DPRESENT_PARAMETERS *pPresentationParameters ); | |||
#endif /* _NINE_SWAPCHAIN9_H_ */ |
@@ -0,0 +1,113 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "swapchain9ex.h" | |||
#include "device9.h" | |||
#include "nine_helpers.h" | |||
#define DBG_CHANNEL DBG_SWAPCHAIN | |||
static HRESULT | |||
NineSwapChain9Ex_ctor( struct NineSwapChain9Ex *This, | |||
struct NineUnknownParams *pParams, | |||
BOOL implicit, | |||
ID3DPresent *pPresent, | |||
D3DPRESENT_PARAMETERS *pPresentationParameters, | |||
struct d3dadapter9_context *pCTX, | |||
HWND hFocusWindow, | |||
D3DDISPLAYMODEEX *mode ) | |||
{ | |||
return NineSwapChain9_ctor(&This->base, pParams, implicit, pPresent, | |||
pPresentationParameters, pCTX, hFocusWindow, mode); | |||
} | |||
static void | |||
NineSwapChain9Ex_dtor( struct NineSwapChain9Ex *This ) | |||
{ | |||
NineSwapChain9_dtor(&This->base); | |||
} | |||
HRESULT WINAPI | |||
NineSwapChain9Ex_GetLastPresentCount( struct NineSwapChain9Ex *This, | |||
UINT *pLastPresentCount ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineSwapChain9Ex_GetPresentStats( struct NineSwapChain9Ex *This, | |||
D3DPRESENTSTATS *pPresentationStatistics ) | |||
{ | |||
STUB(D3DERR_INVALIDCALL); | |||
} | |||
HRESULT WINAPI | |||
NineSwapChain9Ex_GetDisplayModeEx( struct NineSwapChain9Ex *This, | |||
D3DDISPLAYMODEEX *pMode, | |||
D3DDISPLAYROTATION *pRotation ) | |||
{ | |||
D3DDISPLAYROTATION rot; | |||
user_assert(pMode != NULL, E_POINTER); | |||
if (!pRotation) { pRotation = &rot; } | |||
return ID3DPresent_GetDisplayMode(This->base.present, pMode, pRotation); | |||
} | |||
IDirect3DSwapChain9ExVtbl NineSwapChain9Ex_vtable = { | |||
(void *)NineUnknown_QueryInterface, | |||
(void *)NineUnknown_AddRef, | |||
(void *)NineUnknown_Release, | |||
(void *)NineSwapChain9_Present, | |||
(void *)NineSwapChain9_GetFrontBufferData, | |||
(void *)NineSwapChain9_GetBackBuffer, | |||
(void *)NineSwapChain9_GetRasterStatus, | |||
(void *)NineSwapChain9_GetDisplayMode, | |||
(void *)NineUnknown_GetDevice, /* actually part of NineSwapChain9 iface */ | |||
(void *)NineSwapChain9_GetPresentParameters, | |||
(void *)NineSwapChain9Ex_GetLastPresentCount, | |||
(void *)NineSwapChain9Ex_GetPresentStats, | |||
(void *)NineSwapChain9Ex_GetDisplayModeEx | |||
}; | |||
static const GUID *NineSwapChain9Ex_IIDs[] = { | |||
&IID_IDirect3DSwapChain9Ex, | |||
&IID_IDirect3DSwapChain9, | |||
&IID_IUnknown, | |||
NULL | |||
}; | |||
HRESULT | |||
NineSwapChain9Ex_new( struct NineDevice9 *pDevice, | |||
BOOL implicit, | |||
ID3DPresent *pPresent, | |||
D3DPRESENT_PARAMETERS *pPresentationParameters, | |||
struct d3dadapter9_context *pCTX, | |||
HWND hFocusWindow, | |||
D3DDISPLAYMODEEX *mode, | |||
struct NineSwapChain9Ex **ppOut ) | |||
{ | |||
NINE_DEVICE_CHILD_NEW(SwapChain9Ex, ppOut, pDevice, /* args */ | |||
implicit, pPresent, pPresentationParameters, | |||
pCTX, hFocusWindow, mode); | |||
} |
@@ -0,0 +1,61 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_SWAPCHAIN9EX_H_ | |||
#define _NINE_SWAPCHAIN9EX_H_ | |||
#include "swapchain9.h" | |||
struct NineSwapChain9Ex | |||
{ | |||
struct NineSwapChain9 base; | |||
}; | |||
static INLINE struct NineSwapChain9Ex * | |||
NineSwapChain9Ex( void *data ) | |||
{ | |||
return (struct NineSwapChain9Ex *)data; | |||
} | |||
HRESULT | |||
NineSwapChain9Ex_new( struct NineDevice9 *pDevice, | |||
BOOL implicit, | |||
ID3DPresent *pPresent, | |||
D3DPRESENT_PARAMETERS *pPresentationParameters, | |||
struct d3dadapter9_context *pCTX, | |||
HWND hFocusWindow, | |||
D3DDISPLAYMODEEX *mode, | |||
struct NineSwapChain9Ex **ppOut ); | |||
HRESULT WINAPI | |||
NineSwapChain9Ex_GetLastPresentCount( struct NineSwapChain9Ex *This, | |||
UINT *pLastPresentCount ); | |||
HRESULT WINAPI | |||
NineSwapChain9Ex_GetPresentStats( struct NineSwapChain9Ex *This, | |||
D3DPRESENTSTATS *pPresentationStatistics ); | |||
HRESULT WINAPI | |||
NineSwapChain9Ex_GetDisplayModeEx( struct NineSwapChain9Ex *This, | |||
D3DDISPLAYMODEEX *pMode, | |||
D3DDISPLAYROTATION *pRotation ); | |||
#endif /* _NINE_SWAPCHAIN9EX_H_ */ |
@@ -0,0 +1,342 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "device9.h" | |||
#include "surface9.h" | |||
#include "texture9.h" | |||
#include "nine_helpers.h" | |||
#include "nine_pipe.h" | |||
#include "nine_dump.h" | |||
#include "pipe/p_state.h" | |||
#include "pipe/p_context.h" | |||
#include "pipe/p_screen.h" | |||
#include "util/u_inlines.h" | |||
#include "util/u_resource.h" | |||
#define DBG_CHANNEL DBG_TEXTURE | |||
static HRESULT | |||
NineTexture9_ctor( struct NineTexture9 *This, | |||
struct NineUnknownParams *pParams, | |||
UINT Width, UINT Height, UINT Levels, | |||
DWORD Usage, | |||
D3DFORMAT Format, | |||
D3DPOOL Pool, | |||
HANDLE *pSharedHandle ) | |||
{ | |||
struct pipe_screen *screen = pParams->device->screen; | |||
struct pipe_resource *info = &This->base.base.info; | |||
unsigned l; | |||
D3DSURFACE_DESC sfdesc; | |||
HRESULT hr; | |||
const boolean shared_create = pSharedHandle && !*pSharedHandle; | |||
DBG("(%p) Width=%u Height=%u Levels=%u Usage=%s Format=%s Pool=%s " | |||
"pSharedHandle=%p\n", This, Width, Height, Levels, | |||
nine_D3DUSAGE_to_str(Usage), | |||
d3dformat_to_string(Format), nine_D3DPOOL_to_str(Pool), pSharedHandle); | |||
user_assert(!(Usage & D3DUSAGE_AUTOGENMIPMAP) || | |||
(Pool != D3DPOOL_SYSTEMMEM && Levels <= 1), D3DERR_INVALIDCALL); | |||
/* TODO: implement buffer sharing (should work with cross process too) | |||
* | |||
* Gem names may have fit but they're depreciated and won't work on render-nodes. | |||
* One solution is to use shm buffers. We would use a /dev/shm file, fill the first | |||
* values to tell it is a nine buffer, the size, which function created it, etc, | |||
* and then it would contain the data. The handle would be a number, corresponding to | |||
* the file to read (/dev/shm/nine-share-4 for example would be 4). | |||
* | |||
* Wine just ignores the argument, which works only if the app creates the handle | |||
* and won't use it. Instead of failing, we support that situation by putting an | |||
* invalid handle, that we would fail to import. Please note that we don't advertise | |||
* the flag indicating the support for that feature, but apps seem to not care. | |||
*/ | |||
user_assert(!pSharedHandle || | |||
Pool == D3DPOOL_SYSTEMMEM || | |||
Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); | |||
if (pSharedHandle && Pool == D3DPOOL_DEFAULT) { | |||
/* Note: Below there is some implementation to support buffer sharing in | |||
* this case, but it won't work for cross-process. Thus just ignore | |||
* that code. */ | |||
if (shared_create) { | |||
DBG("Creating Texture with invalid handle. Importing will fail\n."); | |||
*pSharedHandle = (HANDLE)1; /* Wine would keep it NULL */ | |||
pSharedHandle = NULL; | |||
} else { | |||
ERR("Application tries to use cross-process sharing feature. Nine " | |||
"doesn't support it"); | |||
return D3DERR_INVALIDCALL; | |||
} | |||
} | |||
if (Usage & D3DUSAGE_AUTOGENMIPMAP) | |||
Levels = 0; | |||
This->base.format = Format; | |||
This->base.base.usage = Usage; | |||
info->screen = screen; | |||
info->target = PIPE_TEXTURE_2D; | |||
info->format = d3d9_to_pipe_format(Format); | |||
info->width0 = Width; | |||
info->height0 = Height; | |||
info->depth0 = 1; | |||
if (Levels) | |||
info->last_level = Levels - 1; | |||
else | |||
info->last_level = util_logbase2(MAX2(Width, Height)); | |||
info->array_size = 1; | |||
info->nr_samples = 0; | |||
info->bind = PIPE_BIND_SAMPLER_VIEW; | |||
info->usage = PIPE_USAGE_DEFAULT; | |||
info->flags = 0; | |||
if (Usage & D3DUSAGE_RENDERTARGET) | |||
info->bind |= PIPE_BIND_RENDER_TARGET; | |||
if (Usage & D3DUSAGE_DEPTHSTENCIL) | |||
info->bind |= PIPE_BIND_DEPTH_STENCIL; | |||
if (Usage & D3DUSAGE_DYNAMIC) { | |||
info->usage = PIPE_USAGE_DYNAMIC; | |||
info->bind |= | |||
PIPE_BIND_TRANSFER_READ | | |||
PIPE_BIND_TRANSFER_WRITE; | |||
} | |||
if (pSharedHandle) | |||
info->bind |= PIPE_BIND_SHARED; | |||
if (Pool == D3DPOOL_SYSTEMMEM) | |||
info->usage = PIPE_USAGE_STAGING; | |||
if (pSharedHandle && !shared_create) { | |||
if (Pool == D3DPOOL_SYSTEMMEM) { | |||
/* Hack for surface creation. */ | |||
This->base.base.resource = (struct pipe_resource *)*pSharedHandle; | |||
} else { | |||
struct pipe_resource *res; | |||
res = screen->resource_from_handle(screen, info, | |||
(struct winsys_handle *)pSharedHandle); | |||
if (!res) | |||
return D3DERR_NOTFOUND; | |||
This->base.base.resource = res; | |||
} | |||
} | |||
This->surfaces = CALLOC(info->last_level + 1, sizeof(*This->surfaces)); | |||
if (!This->surfaces) | |||
return E_OUTOFMEMORY; | |||
hr = NineBaseTexture9_ctor(&This->base, pParams, D3DRTYPE_TEXTURE, Pool); | |||
if (FAILED(hr)) | |||
return hr; | |||
This->base.pstype = (Height == 1) ? 1 : 0; | |||
/* Create all the surfaces right away. | |||
* They manage backing storage, and transfers (LockRect) are deferred | |||
* to them. | |||
*/ | |||
sfdesc.Format = Format; | |||
sfdesc.Type = D3DRTYPE_SURFACE; | |||
sfdesc.Usage = Usage; | |||
sfdesc.Pool = Pool; | |||
sfdesc.MultiSampleType = D3DMULTISAMPLE_NONE; | |||
sfdesc.MultiSampleQuality = 0; | |||
for (l = 0; l <= info->last_level; ++l) { | |||
sfdesc.Width = u_minify(Width, l); | |||
sfdesc.Height = u_minify(Height, l); | |||
hr = NineSurface9_new(This->base.base.base.device, NineUnknown(This), | |||
This->base.base.resource, D3DRTYPE_TEXTURE, l, 0, | |||
&sfdesc, &This->surfaces[l]); | |||
if (FAILED(hr)) | |||
return hr; | |||
} | |||
This->dirty_rect.depth = 1; /* widht == 0 means empty, depth stays 1 */ | |||
if (pSharedHandle) { | |||
if (Pool == D3DPOOL_SYSTEMMEM) { | |||
This->base.base.resource = NULL; | |||
if (shared_create) | |||
*pSharedHandle = This->surfaces[0]->base.data; | |||
} else | |||
if (shared_create) { | |||
boolean ok; | |||
ok = screen->resource_get_handle(screen, This->base.base.resource, | |||
(struct winsys_handle *)pSharedHandle); | |||
if (!ok) | |||
return D3DERR_DRIVERINTERNALERROR; | |||
} | |||
} | |||
return D3D_OK; | |||
} | |||
static void | |||
NineTexture9_dtor( struct NineTexture9 *This ) | |||
{ | |||
unsigned l; | |||
if (This->surfaces) { | |||
/* The surfaces should have 0 references and be unbound now. */ | |||
for (l = 0; l <= This->base.base.info.last_level; ++l) | |||
NineUnknown_Destroy(&This->surfaces[l]->base.base); | |||
FREE(This->surfaces); | |||
} | |||
NineBaseTexture9_dtor(&This->base); | |||
} | |||
HRESULT WINAPI | |||
NineTexture9_GetLevelDesc( struct NineTexture9 *This, | |||
UINT Level, | |||
D3DSURFACE_DESC *pDesc ) | |||
{ | |||
user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL); | |||
user_assert(Level == 0 || !(This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP), | |||
D3DERR_INVALIDCALL); | |||
*pDesc = This->surfaces[Level]->desc; | |||
return D3D_OK; | |||
} | |||
HRESULT WINAPI | |||
NineTexture9_GetSurfaceLevel( struct NineTexture9 *This, | |||
UINT Level, | |||
IDirect3DSurface9 **ppSurfaceLevel ) | |||
{ | |||
user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL); | |||
user_assert(Level == 0 || !(This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP), | |||
D3DERR_INVALIDCALL); | |||
NineUnknown_AddRef(NineUnknown(This->surfaces[Level])); | |||
*ppSurfaceLevel = (IDirect3DSurface9 *)This->surfaces[Level]; | |||
return D3D_OK; | |||
} | |||
HRESULT WINAPI | |||
NineTexture9_LockRect( struct NineTexture9 *This, | |||
UINT Level, | |||
D3DLOCKED_RECT *pLockedRect, | |||
const RECT *pRect, | |||
DWORD Flags ) | |||
{ | |||
user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL); | |||
user_assert(Level == 0 || !(This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP), | |||
D3DERR_INVALIDCALL); | |||
return NineSurface9_LockRect(This->surfaces[Level], pLockedRect, | |||
pRect, Flags); | |||
} | |||
HRESULT WINAPI | |||
NineTexture9_UnlockRect( struct NineTexture9 *This, | |||
UINT Level ) | |||
{ | |||
user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL); | |||
return NineSurface9_UnlockRect(This->surfaces[Level]); | |||
} | |||
HRESULT WINAPI | |||
NineTexture9_AddDirtyRect( struct NineTexture9 *This, | |||
const RECT *pDirtyRect ) | |||
{ | |||
DBG("This=%p pDirtyRect=%p[(%u,%u)-(%u,%u)]\n", This, pDirtyRect, | |||
pDirtyRect ? pDirtyRect->left : 0, pDirtyRect ? pDirtyRect->top : 0, | |||
pDirtyRect ? pDirtyRect->right : 0, pDirtyRect ? pDirtyRect->bottom : 0); | |||
/* Tracking dirty regions on DEFAULT or SYSTEMMEM resources is pointless, | |||
* because we always write to the final storage. Just marked it dirty in | |||
* case we need to generate mip maps. | |||
*/ | |||
if (This->base.base.pool != D3DPOOL_MANAGED) { | |||
if (This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP) | |||
This->base.dirty_mip = TRUE; | |||
return D3D_OK; | |||
} | |||
This->base.dirty = TRUE; | |||
BASETEX_REGISTER_UPDATE(&This->base); | |||
if (!pDirtyRect) { | |||
u_box_origin_2d(This->base.base.info.width0, | |||
This->base.base.info.height0, &This->dirty_rect); | |||
} else { | |||
struct pipe_box box; | |||
rect_to_pipe_box_clamp(&box, pDirtyRect); | |||
u_box_union_2d(&This->dirty_rect, &This->dirty_rect, &box); | |||
} | |||
return D3D_OK; | |||
} | |||
IDirect3DTexture9Vtbl NineTexture9_vtable = { | |||
(void *)NineUnknown_QueryInterface, | |||
(void *)NineUnknown_AddRef, | |||
(void *)NineUnknown_Release, | |||
(void *)NineUnknown_GetDevice, /* actually part of Resource9 iface */ | |||
(void *)NineResource9_SetPrivateData, | |||
(void *)NineResource9_GetPrivateData, | |||
(void *)NineResource9_FreePrivateData, | |||
(void *)NineResource9_SetPriority, | |||
(void *)NineResource9_GetPriority, | |||
(void *)NineBaseTexture9_PreLoad, | |||
(void *)NineResource9_GetType, | |||
(void *)NineBaseTexture9_SetLOD, | |||
(void *)NineBaseTexture9_GetLOD, | |||
(void *)NineBaseTexture9_GetLevelCount, | |||
(void *)NineBaseTexture9_SetAutoGenFilterType, | |||
(void *)NineBaseTexture9_GetAutoGenFilterType, | |||
(void *)NineBaseTexture9_GenerateMipSubLevels, | |||
(void *)NineTexture9_GetLevelDesc, | |||
(void *)NineTexture9_GetSurfaceLevel, | |||
(void *)NineTexture9_LockRect, | |||
(void *)NineTexture9_UnlockRect, | |||
(void *)NineTexture9_AddDirtyRect | |||
}; | |||
static const GUID *NineTexture9_IIDs[] = { | |||
&IID_IDirect3DTexture9, | |||
&IID_IDirect3DBaseTexture9, | |||
&IID_IDirect3DResource9, | |||
&IID_IUnknown, | |||
NULL | |||
}; | |||
HRESULT | |||
NineTexture9_new( struct NineDevice9 *pDevice, | |||
UINT Width, UINT Height, UINT Levels, | |||
DWORD Usage, | |||
D3DFORMAT Format, | |||
D3DPOOL Pool, | |||
struct NineTexture9 **ppOut, | |||
HANDLE *pSharedHandle ) | |||
{ | |||
NINE_DEVICE_CHILD_NEW(Texture9, ppOut, pDevice, | |||
Width, Height, Levels, | |||
Usage, Format, Pool, pSharedHandle); | |||
} |
@@ -0,0 +1,75 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_TEXTURE9_H_ | |||
#define _NINE_TEXTURE9_H_ | |||
#include "basetexture9.h" | |||
#include "surface9.h" | |||
struct NineTexture9 | |||
{ | |||
struct NineBaseTexture9 base; | |||
struct NineSurface9 **surfaces; | |||
struct pipe_box dirty_rect; /* covers all mip levels */ | |||
}; | |||
static INLINE struct NineTexture9 * | |||
NineTexture9( void *data ) | |||
{ | |||
return (struct NineTexture9 *)data; | |||
} | |||
HRESULT | |||
NineTexture9_new( struct NineDevice9 *pDevice, | |||
UINT Width, UINT Height, UINT Levels, | |||
DWORD Usage, | |||
D3DFORMAT Format, | |||
D3DPOOL Pool, | |||
struct NineTexture9 **ppOut, | |||
HANDLE *pSharedHandle ); | |||
HRESULT WINAPI | |||
NineTexture9_GetLevelDesc( struct NineTexture9 *This, | |||
UINT Level, | |||
D3DSURFACE_DESC *pDesc ); | |||
HRESULT WINAPI | |||
NineTexture9_GetSurfaceLevel( struct NineTexture9 *This, | |||
UINT Level, | |||
IDirect3DSurface9 **ppSurfaceLevel ); | |||
HRESULT WINAPI | |||
NineTexture9_LockRect( struct NineTexture9 *This, | |||
UINT Level, | |||
D3DLOCKED_RECT *pLockedRect, | |||
const RECT *pRect, | |||
DWORD Flags ); | |||
HRESULT WINAPI | |||
NineTexture9_UnlockRect( struct NineTexture9 *This, | |||
UINT Level ); | |||
HRESULT WINAPI | |||
NineTexture9_AddDirtyRect( struct NineTexture9 *This, | |||
const RECT *pDirtyRect ); | |||
#endif /* _NINE_TEXTURE9_H_ */ |
@@ -0,0 +1,223 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "vertexbuffer9.h" | |||
#include "device9.h" | |||
#include "nine_helpers.h" | |||
#include "nine_pipe.h" | |||
#include "pipe/p_screen.h" | |||
#include "pipe/p_context.h" | |||
#include "pipe/p_state.h" | |||
#include "pipe/p_defines.h" | |||
#include "pipe/p_format.h" | |||
#include "util/u_box.h" | |||
#define DBG_CHANNEL DBG_VERTEXBUFFER | |||
HRESULT | |||
NineVertexBuffer9_ctor( struct NineVertexBuffer9 *This, | |||
struct NineUnknownParams *pParams, | |||
D3DVERTEXBUFFER_DESC *pDesc ) | |||
{ | |||
struct pipe_resource *info = &This->base.info; | |||
HRESULT hr; | |||
DBG("This=%p Size=0x%x Usage=%x Pool=%u\n", This, | |||
pDesc->Size, pDesc->Usage, pDesc->Pool); | |||
user_assert(pDesc->Pool != D3DPOOL_SCRATCH, D3DERR_INVALIDCALL); | |||
This->maps = MALLOC(sizeof(struct pipe_transfer *)); | |||
if (!This->maps) | |||
return E_OUTOFMEMORY; | |||
This->nmaps = 0; | |||
This->maxmaps = 1; | |||
This->pipe = pParams->device->pipe; | |||
info->screen = pParams->device->screen; | |||
info->target = PIPE_BUFFER; | |||
info->format = PIPE_FORMAT_R8_UNORM; | |||
info->width0 = pDesc->Size; | |||
info->flags = 0; | |||
info->bind = PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_TRANSFER_WRITE; | |||
if (!(pDesc->Usage & D3DUSAGE_WRITEONLY)) | |||
info->bind |= PIPE_BIND_TRANSFER_READ; | |||
info->usage = PIPE_USAGE_DEFAULT; | |||
if (pDesc->Usage & D3DUSAGE_DYNAMIC) | |||
info->usage = PIPE_USAGE_STREAM; | |||
if (pDesc->Pool == D3DPOOL_SYSTEMMEM) | |||
info->usage = PIPE_USAGE_STAGING; | |||
/* if (pDesc->Usage & D3DUSAGE_DONOTCLIP) { } */ | |||
/* if (pDesc->Usage & D3DUSAGE_NONSECURE) { } */ | |||
/* if (pDesc->Usage & D3DUSAGE_NPATCHES) { } */ | |||
/* if (pDesc->Usage & D3DUSAGE_POINTS) { } */ | |||
/* if (pDesc->Usage & D3DUSAGE_RTPATCHES) { } */ | |||
/* if (pDesc->Usage & D3DUSAGE_SOFTWAREPROCESSING) { } */ | |||
/* if (pDesc->Usage & D3DUSAGE_TEXTAPI) { } */ | |||
info->height0 = 1; | |||
info->depth0 = 1; | |||
info->array_size = 1; | |||
info->last_level = 0; | |||
info->nr_samples = 0; | |||
hr = NineResource9_ctor(&This->base, pParams, TRUE, D3DRTYPE_VERTEXBUFFER, | |||
pDesc->Pool); | |||
if (FAILED(hr)) | |||
return hr; | |||
pDesc->Type = D3DRTYPE_VERTEXBUFFER; | |||
pDesc->Format = D3DFMT_VERTEXDATA; | |||
This->desc = *pDesc; | |||
return D3D_OK; | |||
} | |||
void | |||
NineVertexBuffer9_dtor( struct NineVertexBuffer9 *This ) | |||
{ | |||
if (This->maps) { | |||
while (This->nmaps) { | |||
NineVertexBuffer9_Unlock(This); | |||
} | |||
FREE(This->maps); | |||
} | |||
NineResource9_dtor(&This->base); | |||
} | |||
HRESULT WINAPI | |||
NineVertexBuffer9_Lock( struct NineVertexBuffer9 *This, | |||
UINT OffsetToLock, | |||
UINT SizeToLock, | |||
void **ppbData, | |||
DWORD Flags ) | |||
{ | |||
struct pipe_box box; | |||
void *data; | |||
const unsigned usage = d3dlock_buffer_to_pipe_transfer_usage(Flags); | |||
DBG("This=%p(pipe=%p) OffsetToLock=0x%x, SizeToLock=0x%x, Flags=0x%x\n", | |||
This, This->base.resource, | |||
OffsetToLock, SizeToLock, Flags); | |||
user_assert(ppbData, E_POINTER); | |||
user_assert(!(Flags & ~(D3DLOCK_DISCARD | | |||
D3DLOCK_DONOTWAIT | | |||
D3DLOCK_NO_DIRTY_UPDATE | | |||
D3DLOCK_NOSYSLOCK | | |||
D3DLOCK_READONLY | | |||
D3DLOCK_NOOVERWRITE)), D3DERR_INVALIDCALL); | |||
if (This->nmaps == This->maxmaps) { | |||
struct pipe_transfer **newmaps = | |||
REALLOC(This->maps, sizeof(struct pipe_transfer *)*This->maxmaps, | |||
sizeof(struct pipe_transfer *)*(This->maxmaps << 1)); | |||
if (newmaps == NULL) | |||
return E_OUTOFMEMORY; | |||
This->maxmaps <<= 1; | |||
This->maps = newmaps; | |||
} | |||
if (SizeToLock == 0) { | |||
SizeToLock = This->desc.Size - OffsetToLock; | |||
user_warn(OffsetToLock != 0); | |||
} | |||
u_box_1d(OffsetToLock, SizeToLock, &box); | |||
data = This->pipe->transfer_map(This->pipe, This->base.resource, 0, | |||
usage, &box, &This->maps[This->nmaps]); | |||
if (!data) { | |||
DBG("pipe::transfer_map failed\n" | |||
" usage = %x\n" | |||
" box.x = %u\n" | |||
" box.width = %u\n", | |||
usage, box.x, box.width); | |||
/* not sure what to return, msdn suggests this */ | |||
if (Flags & D3DLOCK_DONOTWAIT) | |||
return D3DERR_WASSTILLDRAWING; | |||
return D3DERR_INVALIDCALL; | |||
} | |||
This->nmaps++; | |||
*ppbData = data; | |||
return D3D_OK; | |||
} | |||
HRESULT WINAPI | |||
NineVertexBuffer9_Unlock( struct NineVertexBuffer9 *This ) | |||
{ | |||
DBG("This=%p\n", This); | |||
user_assert(This->nmaps > 0, D3DERR_INVALIDCALL); | |||
This->pipe->transfer_unmap(This->pipe, This->maps[--(This->nmaps)]); | |||
return D3D_OK; | |||
} | |||
HRESULT WINAPI | |||
NineVertexBuffer9_GetDesc( struct NineVertexBuffer9 *This, | |||
D3DVERTEXBUFFER_DESC *pDesc ) | |||
{ | |||
user_assert(pDesc, E_POINTER); | |||
*pDesc = This->desc; | |||
return D3D_OK; | |||
} | |||
IDirect3DVertexBuffer9Vtbl NineVertexBuffer9_vtable = { | |||
(void *)NineUnknown_QueryInterface, | |||
(void *)NineUnknown_AddRef, | |||
(void *)NineUnknown_Release, | |||
(void *)NineUnknown_GetDevice, /* actually part of Resource9 iface */ | |||
(void *)NineResource9_SetPrivateData, | |||
(void *)NineResource9_GetPrivateData, | |||
(void *)NineResource9_FreePrivateData, | |||
(void *)NineResource9_SetPriority, | |||
(void *)NineResource9_GetPriority, | |||
(void *)NineResource9_PreLoad, | |||
(void *)NineResource9_GetType, | |||
(void *)NineVertexBuffer9_Lock, | |||
(void *)NineVertexBuffer9_Unlock, | |||
(void *)NineVertexBuffer9_GetDesc | |||
}; | |||
static const GUID *NineVertexBuffer9_IIDs[] = { | |||
&IID_IDirect3DVertexBuffer9, | |||
&IID_IDirect3DResource9, | |||
&IID_IUnknown, | |||
NULL | |||
}; | |||
HRESULT | |||
NineVertexBuffer9_new( struct NineDevice9 *pDevice, | |||
D3DVERTEXBUFFER_DESC *pDesc, | |||
struct NineVertexBuffer9 **ppOut ) | |||
{ | |||
NINE_DEVICE_CHILD_NEW(VertexBuffer9, ppOut, /* args */ pDevice, pDesc); | |||
} |
@@ -0,0 +1,76 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_VERTEXBUFFER9_H_ | |||
#define _NINE_VERTEXBUFFER9_H_ | |||
#include "resource9.h" | |||
struct pipe_screen; | |||
struct pipe_context; | |||
struct pipe_transfer; | |||
struct NineVertexBuffer9 | |||
{ | |||
struct NineResource9 base; | |||
/* G3D */ | |||
struct pipe_context *pipe; | |||
struct pipe_transfer **maps; | |||
int nmaps, maxmaps; | |||
D3DVERTEXBUFFER_DESC desc; | |||
}; | |||
static INLINE struct NineVertexBuffer9 * | |||
NineVertexBuffer9( void *data ) | |||
{ | |||
return (struct NineVertexBuffer9 *)data; | |||
} | |||
HRESULT | |||
NineVertexBuffer9_new( struct NineDevice9 *pDevice, | |||
D3DVERTEXBUFFER_DESC *pDesc, | |||
struct NineVertexBuffer9 **ppOut ); | |||
HRESULT | |||
NineVertexBuffer9_ctor( struct NineVertexBuffer9 *This, | |||
struct NineUnknownParams *pParams, | |||
D3DVERTEXBUFFER_DESC *pDesc ); | |||
void | |||
NineVertexBuffer9_dtor( struct NineVertexBuffer9 *This ); | |||
HRESULT WINAPI | |||
NineVertexBuffer9_Lock( struct NineVertexBuffer9 *This, | |||
UINT OffsetToLock, | |||
UINT SizeToLock, | |||
void **ppbData, | |||
DWORD Flags ); | |||
HRESULT WINAPI | |||
NineVertexBuffer9_Unlock( struct NineVertexBuffer9 *This ); | |||
HRESULT WINAPI | |||
NineVertexBuffer9_GetDesc( struct NineVertexBuffer9 *This, | |||
D3DVERTEXBUFFER_DESC *pDesc ); | |||
#endif /* _NINE_VERTEXBUFFER9_H_ */ |
@@ -0,0 +1,518 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "vertexdeclaration9.h" | |||
#include "vertexbuffer9.h" | |||
#include "device9.h" | |||
#include "nine_helpers.h" | |||
#include "pipe/p_format.h" | |||
#include "pipe/p_context.h" | |||
#include "util/u_math.h" | |||
#include "util/u_format.h" | |||
#include "util/u_box.h" | |||
#include "translate/translate.h" | |||
#define DBG_CHANNEL DBG_VERTEXDECLARATION | |||
static INLINE enum pipe_format decltype_format(BYTE type) | |||
{ | |||
switch (type) { | |||
case D3DDECLTYPE_FLOAT1: return PIPE_FORMAT_R32_FLOAT; | |||
case D3DDECLTYPE_FLOAT2: return PIPE_FORMAT_R32G32_FLOAT; | |||
case D3DDECLTYPE_FLOAT3: return PIPE_FORMAT_R32G32B32_FLOAT; | |||
case D3DDECLTYPE_FLOAT4: return PIPE_FORMAT_R32G32B32A32_FLOAT; | |||
case D3DDECLTYPE_D3DCOLOR: return PIPE_FORMAT_B8G8R8A8_UNORM; | |||
case D3DDECLTYPE_UBYTE4: return PIPE_FORMAT_R8G8B8A8_USCALED; | |||
case D3DDECLTYPE_SHORT2: return PIPE_FORMAT_R16G16_SSCALED; | |||
case D3DDECLTYPE_SHORT4: return PIPE_FORMAT_R16G16B16A16_SSCALED; | |||
case D3DDECLTYPE_UBYTE4N: return PIPE_FORMAT_R8G8B8A8_UNORM; | |||
case D3DDECLTYPE_SHORT2N: return PIPE_FORMAT_R16G16_SNORM; | |||
case D3DDECLTYPE_SHORT4N: return PIPE_FORMAT_R16G16B16A16_SNORM; | |||
case D3DDECLTYPE_USHORT2N: return PIPE_FORMAT_R16G16_UNORM; | |||
case D3DDECLTYPE_USHORT4N: return PIPE_FORMAT_R16G16B16A16_UNORM; | |||
case D3DDECLTYPE_UDEC3: return PIPE_FORMAT_R10G10B10X2_USCALED; | |||
case D3DDECLTYPE_DEC3N: return PIPE_FORMAT_R10G10B10X2_SNORM; | |||
case D3DDECLTYPE_FLOAT16_2: return PIPE_FORMAT_R16G16_FLOAT; | |||
case D3DDECLTYPE_FLOAT16_4: return PIPE_FORMAT_R16G16B16A16_FLOAT; | |||
default: | |||
assert(!"Implementation error !"); | |||
} | |||
return PIPE_FORMAT_NONE; | |||
} | |||
static INLINE unsigned decltype_size(BYTE type) | |||
{ | |||
switch (type) { | |||
case D3DDECLTYPE_FLOAT1: return 1 * sizeof(float); | |||
case D3DDECLTYPE_FLOAT2: return 2 * sizeof(float); | |||
case D3DDECLTYPE_FLOAT3: return 3 * sizeof(float); | |||
case D3DDECLTYPE_FLOAT4: return 4 * sizeof(float); | |||
case D3DDECLTYPE_D3DCOLOR: return 1 * sizeof(DWORD); | |||
case D3DDECLTYPE_UBYTE4: return 4 * sizeof(BYTE); | |||
case D3DDECLTYPE_SHORT2: return 2 * sizeof(short); | |||
case D3DDECLTYPE_SHORT4: return 4 * sizeof(short); | |||
case D3DDECLTYPE_UBYTE4N: return 4 * sizeof(BYTE); | |||
case D3DDECLTYPE_SHORT2N: return 2 * sizeof(short); | |||
case D3DDECLTYPE_SHORT4N: return 4 * sizeof(short); | |||
case D3DDECLTYPE_USHORT2N: return 2 * sizeof(short); | |||
case D3DDECLTYPE_USHORT4N: return 4 * sizeof(short); | |||
case D3DDECLTYPE_UDEC3: return 4; | |||
case D3DDECLTYPE_DEC3N: return 4; | |||
case D3DDECLTYPE_FLOAT16_2: return 2 * 2; | |||
case D3DDECLTYPE_FLOAT16_4: return 4 * 2; | |||
default: | |||
assert(!"Implementation error !"); | |||
} | |||
return 0; | |||
} | |||
/* Actually, arbitrary usage index values are permitted, but a | |||
* simple lookup table won't work in that case. Let's just wait | |||
* with making this more generic until we need it. | |||
*/ | |||
static INLINE boolean | |||
nine_d3ddeclusage_check(unsigned usage, unsigned usage_idx) | |||
{ | |||
switch (usage) { | |||
case D3DDECLUSAGE_POSITIONT: | |||
case D3DDECLUSAGE_PSIZE: | |||
case D3DDECLUSAGE_TESSFACTOR: | |||
case D3DDECLUSAGE_DEPTH: | |||
case D3DDECLUSAGE_FOG: | |||
case D3DDECLUSAGE_SAMPLE: | |||
return usage_idx <= 0; | |||
case D3DDECLUSAGE_NORMAL: | |||
case D3DDECLUSAGE_TANGENT: | |||
case D3DDECLUSAGE_BINORMAL: | |||
return usage_idx <= 1; | |||
case D3DDECLUSAGE_POSITION: | |||
case D3DDECLUSAGE_BLENDWEIGHT: | |||
case D3DDECLUSAGE_BLENDINDICES: | |||
case D3DDECLUSAGE_COLOR: | |||
return usage_idx <= 4; | |||
case D3DDECLUSAGE_TEXCOORD: | |||
return usage_idx <= 15; | |||
default: | |||
return FALSE; | |||
} | |||
} | |||
#define NINE_DECLUSAGE_CASE0(n) case D3DDECLUSAGE_##n: return NINE_DECLUSAGE_##n | |||
#define NINE_DECLUSAGE_CASEi(n) case D3DDECLUSAGE_##n: return NINE_DECLUSAGE_##n(usage_idx) | |||
INLINE unsigned | |||
nine_d3d9_to_nine_declusage(unsigned usage, unsigned usage_idx) | |||
{ | |||
if (!nine_d3ddeclusage_check(usage, usage_idx)) | |||
ERR("D3DDECLUSAGE_%u[%u]\n",usage,usage_idx); | |||
assert(nine_d3ddeclusage_check(usage, usage_idx)); | |||
switch (usage) { | |||
NINE_DECLUSAGE_CASEi(POSITION); | |||
NINE_DECLUSAGE_CASEi(BLENDWEIGHT); | |||
NINE_DECLUSAGE_CASEi(BLENDINDICES); | |||
NINE_DECLUSAGE_CASEi(NORMAL); | |||
NINE_DECLUSAGE_CASE0(PSIZE); | |||
NINE_DECLUSAGE_CASEi(TEXCOORD); | |||
NINE_DECLUSAGE_CASEi(TANGENT); | |||
NINE_DECLUSAGE_CASEi(BINORMAL); | |||
NINE_DECLUSAGE_CASE0(TESSFACTOR); | |||
NINE_DECLUSAGE_CASE0(POSITIONT); | |||
NINE_DECLUSAGE_CASEi(COLOR); | |||
NINE_DECLUSAGE_CASE0(DEPTH); | |||
NINE_DECLUSAGE_CASE0(FOG); | |||
NINE_DECLUSAGE_CASE0(SAMPLE); | |||
default: | |||
assert(!"Invalid DECLUSAGE."); | |||
return NINE_DECLUSAGE_NONE; | |||
} | |||
} | |||
static const char *nine_declusage_names[] = | |||
{ | |||
[NINE_DECLUSAGE_POSITION(0)] = "POSITION", | |||
[NINE_DECLUSAGE_POSITION(1)] = "POSITION1", | |||
[NINE_DECLUSAGE_POSITION(2)] = "POSITION2", | |||
[NINE_DECLUSAGE_POSITION(3)] = "POSITION3", | |||
[NINE_DECLUSAGE_POSITION(4)] = "POSITION4", | |||
[NINE_DECLUSAGE_BLENDWEIGHT(0)] = "BLENDWEIGHT", | |||
[NINE_DECLUSAGE_BLENDWEIGHT(1)] = "BLENDWEIGHT1", | |||
[NINE_DECLUSAGE_BLENDWEIGHT(2)] = "BLENDWEIGHT2", | |||
[NINE_DECLUSAGE_BLENDWEIGHT(3)] = "BLENDWEIGHT3", | |||
[NINE_DECLUSAGE_BLENDINDICES(0)] = "BLENDINDICES", | |||
[NINE_DECLUSAGE_BLENDINDICES(1)] = "BLENDINDICES1", | |||
[NINE_DECLUSAGE_BLENDINDICES(2)] = "BLENDINDICES2", | |||
[NINE_DECLUSAGE_BLENDINDICES(3)] = "BLENDINDICES3", | |||
[NINE_DECLUSAGE_NORMAL(0)] = "NORMAL", | |||
[NINE_DECLUSAGE_NORMAL(1)] = "NORMAL1", | |||
[NINE_DECLUSAGE_PSIZE] = "PSIZE", | |||
[NINE_DECLUSAGE_TEXCOORD(0)] = "TEXCOORD0", | |||
[NINE_DECLUSAGE_TEXCOORD(1)] = "TEXCOORD1", | |||
[NINE_DECLUSAGE_TEXCOORD(2)] = "TEXCOORD2", | |||
[NINE_DECLUSAGE_TEXCOORD(3)] = "TEXCOORD3", | |||
[NINE_DECLUSAGE_TEXCOORD(4)] = "TEXCOORD4", | |||
[NINE_DECLUSAGE_TEXCOORD(5)] = "TEXCOORD5", | |||
[NINE_DECLUSAGE_TEXCOORD(6)] = "TEXCOORD6", | |||
[NINE_DECLUSAGE_TEXCOORD(7)] = "TEXCOORD7", | |||
[NINE_DECLUSAGE_TEXCOORD(8)] = "TEXCOORD8", | |||
[NINE_DECLUSAGE_TEXCOORD(9)] = "TEXCOORD9", | |||
[NINE_DECLUSAGE_TEXCOORD(10)] = "TEXCOORD10", | |||
[NINE_DECLUSAGE_TEXCOORD(11)] = "TEXCOORD11", | |||
[NINE_DECLUSAGE_TEXCOORD(12)] = "TEXCOORD12", | |||
[NINE_DECLUSAGE_TEXCOORD(13)] = "TEXCOORD13", | |||
[NINE_DECLUSAGE_TEXCOORD(14)] = "TEXCOORD14", | |||
[NINE_DECLUSAGE_TEXCOORD(15)] = "TEXCOORD15", | |||
[NINE_DECLUSAGE_TANGENT(0)] = "TANGENT", | |||
[NINE_DECLUSAGE_TANGENT(1)] = "TANGENT1", | |||
[NINE_DECLUSAGE_BINORMAL(0)] = "BINORMAL", | |||
[NINE_DECLUSAGE_BINORMAL(1)] = "BINORMAL1", | |||
[NINE_DECLUSAGE_TESSFACTOR] = "TESSFACTOR", | |||
[NINE_DECLUSAGE_POSITIONT] = "POSITIONT", | |||
[NINE_DECLUSAGE_COLOR(0)] = "DIFFUSE", | |||
[NINE_DECLUSAGE_COLOR(1)] = "SPECULAR", | |||
[NINE_DECLUSAGE_COLOR(2)] = "COLOR2", | |||
[NINE_DECLUSAGE_COLOR(3)] = "COLOR3", | |||
[NINE_DECLUSAGE_COLOR(4)] = "COLOR4", | |||
[NINE_DECLUSAGE_DEPTH] = "DEPTH", | |||
[NINE_DECLUSAGE_FOG] = "FOG", | |||
[NINE_DECLUSAGE_NONE] = "(NONE)", | |||
[NINE_DECLUSAGE_COUNT] = "(OOB)" | |||
}; | |||
static INLINE const char * | |||
nine_declusage_name(unsigned ndcl) | |||
{ | |||
return nine_declusage_names[MIN2(ndcl, Elements(nine_declusage_names) - 1)]; | |||
} | |||
HRESULT | |||
NineVertexDeclaration9_ctor( struct NineVertexDeclaration9 *This, | |||
struct NineUnknownParams *pParams, | |||
const D3DVERTEXELEMENT9 *pElements ) | |||
{ | |||
const D3DCAPS9 *caps; | |||
unsigned i; | |||
HRESULT hr = NineUnknown_ctor(&This->base, pParams); | |||
if (FAILED(hr)) { return hr; } | |||
for (This->nelems = 0; | |||
pElements[This->nelems].Type != D3DDECLTYPE_UNUSED && | |||
pElements[This->nelems].Stream != 0xFF; /* wine */ | |||
++This->nelems); | |||
caps = NineDevice9_GetCaps(This->base.device); | |||
user_assert(This->nelems <= caps->MaxStreams, D3DERR_INVALIDCALL); | |||
This->decls = CALLOC(This->nelems+1, sizeof(D3DVERTEXELEMENT9)); | |||
This->elems = CALLOC(This->nelems, sizeof(struct pipe_vertex_element)); | |||
if (!This->decls || !This->elems) { return E_OUTOFMEMORY; } | |||
memcpy(This->decls, pElements, sizeof(D3DVERTEXELEMENT9)*(This->nelems+1)); | |||
memset(This->usage_map, 0xff, sizeof(This->usage_map)); | |||
for (i = 0; i < This->nelems; ++i) { | |||
uint8_t usage = nine_d3d9_to_nine_declusage(This->decls[i].Usage, | |||
This->decls[i].UsageIndex); | |||
This->usage_map[usage] = i; | |||
This->elems[i].src_offset = This->decls[i].Offset; | |||
This->elems[i].instance_divisor = 0; | |||
This->elems[i].vertex_buffer_index = This->decls[i].Stream; | |||
This->elems[i].src_format = decltype_format(This->decls[i].Type); | |||
/* XXX Remember Method (tesselation), Usage, UsageIndex */ | |||
DBG("VERTEXELEMENT[%u]: Stream=%u Offset=%u Type=%s DeclUsage=%s\n", i, | |||
This->decls[i].Stream, | |||
This->decls[i].Offset, | |||
util_format_name(This->elems[i].src_format), | |||
nine_declusage_name(usage)); | |||
} | |||
return D3D_OK; | |||
} | |||
void | |||
NineVertexDeclaration9_dtor( struct NineVertexDeclaration9 *This ) | |||
{ | |||
if (This->decls) | |||
FREE(This->decls); | |||
if (This->elems) | |||
FREE(This->elems); | |||
NineUnknown_dtor(&This->base); | |||
} | |||
HRESULT WINAPI | |||
NineVertexDeclaration9_GetDeclaration( struct NineVertexDeclaration9 *This, | |||
D3DVERTEXELEMENT9 *pElement, | |||
UINT *pNumElements ) | |||
{ | |||
if (!pElement) { | |||
user_assert(pNumElements, D3DERR_INVALIDCALL); | |||
*pNumElements = This->nelems+1; | |||
return D3D_OK; | |||
} | |||
if (pNumElements) { *pNumElements = This->nelems+1; } | |||
memcpy(pElement, This->decls, sizeof(D3DVERTEXELEMENT9)*(This->nelems+1)); | |||
return D3D_OK; | |||
} | |||
IDirect3DVertexDeclaration9Vtbl NineVertexDeclaration9_vtable = { | |||
(void *)NineUnknown_QueryInterface, | |||
(void *)NineUnknown_AddRef, | |||
(void *)NineUnknown_Release, | |||
(void *)NineUnknown_GetDevice, /* actually part of VertexDecl9 iface */ | |||
(void *)NineVertexDeclaration9_GetDeclaration | |||
}; | |||
static const GUID *NineVertexDeclaration9_IIDs[] = { | |||
&IID_IDirect3DVertexDeclaration9, | |||
&IID_IUnknown, | |||
NULL | |||
}; | |||
HRESULT | |||
NineVertexDeclaration9_new( struct NineDevice9 *pDevice, | |||
const D3DVERTEXELEMENT9 *pElements, | |||
struct NineVertexDeclaration9 **ppOut ) | |||
{ | |||
NINE_DEVICE_CHILD_NEW(VertexDeclaration9, ppOut, /* args */ pDevice, pElements); | |||
} | |||
HRESULT | |||
NineVertexDeclaration9_new_from_fvf( struct NineDevice9 *pDevice, | |||
DWORD FVF, | |||
struct NineVertexDeclaration9 **ppOut ) | |||
{ | |||
D3DVERTEXELEMENT9 elems[16], decl_end = D3DDECL_END(); | |||
unsigned texcount, i, betas, nelems = 0; | |||
BYTE beta_index = 0xFF; | |||
switch (FVF & D3DFVF_POSITION_MASK) { | |||
case D3DFVF_XYZ: /* simple XYZ */ | |||
case D3DFVF_XYZB1: | |||
case D3DFVF_XYZB2: | |||
case D3DFVF_XYZB3: | |||
case D3DFVF_XYZB4: | |||
case D3DFVF_XYZB5: /* XYZ with beta values */ | |||
elems[nelems].Type = D3DDECLTYPE_FLOAT3; | |||
elems[nelems].Usage = D3DDECLUSAGE_POSITION; | |||
elems[nelems].UsageIndex = 0; | |||
++nelems; | |||
/* simple XYZ has no beta values. break. */ | |||
if ((FVF & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) { break; } | |||
betas = (((FVF & D3DFVF_XYZB5)-D3DFVF_XYZB1)>>1)+1; | |||
if (FVF & D3DFVF_LASTBETA_D3DCOLOR) { | |||
beta_index = D3DDECLTYPE_D3DCOLOR; | |||
} else if (FVF & D3DFVF_LASTBETA_UBYTE4) { | |||
beta_index = D3DDECLTYPE_UBYTE4; | |||
} else if ((FVF & D3DFVF_XYZB5) == D3DFVF_XYZB5) { | |||
beta_index = D3DDECLTYPE_FLOAT1; | |||
} | |||
if (beta_index != 0xFF) { --betas; } | |||
if (betas > 0) { | |||
switch (betas) { | |||
case 1: elems[nelems].Type = D3DDECLTYPE_FLOAT1; break; | |||
case 2: elems[nelems].Type = D3DDECLTYPE_FLOAT2; break; | |||
case 3: elems[nelems].Type = D3DDECLTYPE_FLOAT3; break; | |||
case 4: elems[nelems].Type = D3DDECLTYPE_FLOAT4; break; | |||
default: | |||
assert(!"Implementation error!"); | |||
} | |||
elems[nelems].Usage = D3DDECLUSAGE_BLENDWEIGHT; | |||
elems[nelems].UsageIndex = 0; | |||
++nelems; | |||
} | |||
if (beta_index != 0xFF) { | |||
elems[nelems].Type = beta_index; | |||
elems[nelems].Usage = D3DDECLUSAGE_BLENDINDICES; | |||
elems[nelems].UsageIndex = 0; | |||
++nelems; | |||
} | |||
break; | |||
case D3DFVF_XYZW: /* simple XYZW */ | |||
case D3DFVF_XYZRHW: /* pretransformed XYZW */ | |||
elems[nelems].Type = D3DDECLTYPE_FLOAT4; | |||
elems[nelems].Usage = | |||
((FVF & D3DFVF_POSITION_MASK) == D3DFVF_XYZW) ? | |||
D3DDECLUSAGE_POSITION : D3DDECLUSAGE_POSITIONT; | |||
elems[nelems].UsageIndex = 0; | |||
++nelems; | |||
break; | |||
default: | |||
(void)user_error(!"Position doesn't match any known combination"); | |||
} | |||
/* normals, psize and colors */ | |||
if (FVF & D3DFVF_NORMAL) { | |||
elems[nelems].Type = D3DDECLTYPE_FLOAT3; | |||
elems[nelems].Usage = D3DDECLUSAGE_NORMAL; | |||
elems[nelems].UsageIndex = 0; | |||
++nelems; | |||
} | |||
if (FVF & D3DFVF_PSIZE) { | |||
elems[nelems].Type = D3DDECLTYPE_FLOAT1; | |||
elems[nelems].Usage = D3DDECLUSAGE_PSIZE; | |||
elems[nelems].UsageIndex = 0; | |||
++nelems; | |||
} | |||
if (FVF & D3DFVF_DIFFUSE) { | |||
elems[nelems].Type = D3DDECLTYPE_D3DCOLOR; | |||
elems[nelems].Usage = D3DDECLUSAGE_COLOR; | |||
elems[nelems].UsageIndex = 0; | |||
++nelems; | |||
} | |||
if (FVF & D3DFVF_SPECULAR) { | |||
elems[nelems].Type = D3DDECLTYPE_D3DCOLOR; | |||
elems[nelems].Usage = D3DDECLUSAGE_COLOR; | |||
elems[nelems].UsageIndex = 1; | |||
++nelems; | |||
} | |||
/* textures */ | |||
texcount = (FVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT; | |||
if (user_error(texcount <= 8)) { texcount = 8; } | |||
for (i = 0; i < texcount; ++i) { | |||
switch ((FVF >> (16+i*2)) & 0x3) { | |||
case D3DFVF_TEXTUREFORMAT1: | |||
elems[nelems].Type = D3DDECLTYPE_FLOAT1; | |||
break; | |||
case D3DFVF_TEXTUREFORMAT2: | |||
elems[nelems].Type = D3DDECLTYPE_FLOAT2; | |||
break; | |||
case D3DFVF_TEXTUREFORMAT3: | |||
elems[nelems].Type = D3DDECLTYPE_FLOAT3; | |||
break; | |||
case D3DFVF_TEXTUREFORMAT4: | |||
elems[nelems].Type = D3DDECLTYPE_FLOAT4; | |||
break; | |||
default: | |||
assert(!"Implementation error!"); | |||
} | |||
elems[nelems].Usage = D3DDECLUSAGE_TEXCOORD; | |||
elems[nelems].UsageIndex = i; | |||
++nelems; | |||
} | |||
/* fill out remaining data */ | |||
for (i = 0; i < nelems; ++i) { | |||
elems[i].Stream = 0; | |||
elems[i].Offset = (i == 0) ? 0 : (elems[i-1].Offset + | |||
decltype_size(elems[i-1].Type)); | |||
elems[i].Method = D3DDECLMETHOD_DEFAULT; | |||
} | |||
elems[nelems++] = decl_end; | |||
NINE_DEVICE_CHILD_NEW(VertexDeclaration9, ppOut, /* args */ pDevice, elems); | |||
} | |||
/* ProcessVertices runs stream output into a temporary buffer to capture | |||
* all outputs. | |||
* Now we have to convert them to the format and order set by the vertex | |||
* declaration, for which we use u_translate. | |||
* This is necessary if the vertex declaration contains elements using a | |||
* non float32 format, because stream output only supports f32/u32/s32. | |||
*/ | |||
HRESULT | |||
NineVertexDeclaration9_ConvertStreamOutput( | |||
struct NineVertexDeclaration9 *This, | |||
struct NineVertexBuffer9 *pDstBuf, | |||
UINT DestIndex, | |||
UINT VertexCount, | |||
struct pipe_resource *pSrcBuf, | |||
const struct pipe_stream_output_info *so ) | |||
{ | |||
struct pipe_context *pipe = This->base.device->pipe; | |||
struct pipe_transfer *transfer = NULL; | |||
struct translate *translate; | |||
struct translate_key transkey; | |||
struct pipe_box box; | |||
HRESULT hr; | |||
unsigned i; | |||
void *src_map; | |||
void *dst_map; | |||
transkey.output_stride = 0; | |||
for (i = 0; i < This->nelems; ++i) { | |||
enum pipe_format format; | |||
switch (so->output[i].num_components) { | |||
case 1: format = PIPE_FORMAT_R32_FLOAT; break; | |||
case 2: format = PIPE_FORMAT_R32G32_FLOAT; break; | |||
case 3: format = PIPE_FORMAT_R32G32B32_FLOAT; break; | |||
default: | |||
assert(so->output[i].num_components == 4); | |||
format = PIPE_FORMAT_R32G32B32A32_FLOAT; | |||
break; | |||
} | |||
transkey.element[i].type = TRANSLATE_ELEMENT_NORMAL; | |||
transkey.element[i].input_format = format; | |||
transkey.element[i].input_buffer = 0; | |||
transkey.element[i].input_offset = so->output[i].dst_offset * 4; | |||
transkey.element[i].instance_divisor = 0; | |||
transkey.element[i].output_format = This->elems[i].src_format; | |||
transkey.element[i].output_offset = This->elems[i].src_offset; | |||
transkey.output_stride += | |||
util_format_get_blocksize(This->elems[i].src_format); | |||
assert(!(transkey.output_stride & 3)); | |||
} | |||
transkey.nr_elements = This->nelems; | |||
translate = translate_create(&transkey); | |||
if (!translate) | |||
return E_OUTOFMEMORY; | |||
hr = NineVertexBuffer9_Lock(pDstBuf, | |||
transkey.output_stride * DestIndex, | |||
transkey.output_stride * VertexCount, | |||
&dst_map, D3DLOCK_DISCARD); | |||
if (FAILED(hr)) | |||
goto out; | |||
src_map = pipe->transfer_map(pipe, pSrcBuf, 0, PIPE_TRANSFER_READ, &box, | |||
&transfer); | |||
if (!src_map) { | |||
hr = D3DERR_DRIVERINTERNALERROR; | |||
goto out; | |||
} | |||
translate->set_buffer(translate, 0, src_map, so->stride[0], ~0); | |||
translate->run(translate, 0, VertexCount, 0, 0, dst_map); | |||
NineVertexBuffer9_Unlock(pDstBuf); | |||
out: | |||
if (transfer) | |||
pipe->transfer_unmap(pipe, transfer); | |||
translate->release(translate); /* TODO: cache these */ | |||
return hr; | |||
} |
@@ -0,0 +1,89 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_VERTEXDECLARATION9_H_ | |||
#define _NINE_VERTEXDECLARATION9_H_ | |||
#include "nine_defines.h" | |||
#include "iunknown.h" | |||
struct pipe_resource; | |||
struct pipe_vertex_element; | |||
struct pipe_stream_output_info; | |||
struct NineDevice9; | |||
struct NineVertexBuffer9; | |||
struct NineVertexDeclaration9 | |||
{ | |||
struct NineUnknown base; | |||
/* G3D state */ | |||
struct pipe_vertex_element *elems; | |||
unsigned nelems; | |||
/* DECLUSAGE -> element index, for selecting the vertex element | |||
* for each VS input */ | |||
uint8_t usage_map[NINE_DECLUSAGE_COUNT]; | |||
D3DVERTEXELEMENT9 *decls; | |||
DWORD fvf; | |||
}; | |||
static INLINE struct NineVertexDeclaration9 * | |||
NineVertexDeclaration9( void *data ) | |||
{ | |||
return (struct NineVertexDeclaration9 *)data; | |||
} | |||
HRESULT | |||
NineVertexDeclaration9_new( struct NineDevice9 *pDevice, | |||
const D3DVERTEXELEMENT9 *pElements, | |||
struct NineVertexDeclaration9 **ppOut ); | |||
HRESULT | |||
NineVertexDeclaration9_new_from_fvf( struct NineDevice9 *pDevice, | |||
DWORD FVF, | |||
struct NineVertexDeclaration9 **ppOut ); | |||
HRESULT | |||
NineVertexDeclaration9_ctor( struct NineVertexDeclaration9 *This, | |||
struct NineUnknownParams *pParams, | |||
const D3DVERTEXELEMENT9 *pElements ); | |||
void | |||
NineVertexDeclaration9_dtor( struct NineVertexDeclaration9 *This ); | |||
HRESULT WINAPI | |||
NineVertexDeclaration9_GetDeclaration( struct NineVertexDeclaration9 *This, | |||
D3DVERTEXELEMENT9 *pElement, | |||
UINT *pNumElements ); | |||
/* Convert stream output data to the vertex declaration's format. */ | |||
HRESULT | |||
NineVertexDeclaration9_ConvertStreamOutput( | |||
struct NineVertexDeclaration9 *This, | |||
struct NineVertexBuffer9 *pDstBuf, | |||
UINT DestIndex, | |||
UINT VertexCount, | |||
struct pipe_resource *pSrcBuf, | |||
const struct pipe_stream_output_info *so ); | |||
#endif /* _NINE_VERTEXDECLARATION9_H_ */ |
@@ -0,0 +1,177 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "nine_helpers.h" | |||
#include "nine_shader.h" | |||
#include "vertexshader9.h" | |||
#include "device9.h" | |||
#include "pipe/p_context.h" | |||
#define DBG_CHANNEL DBG_VERTEXSHADER | |||
HRESULT | |||
NineVertexShader9_ctor( struct NineVertexShader9 *This, | |||
struct NineUnknownParams *pParams, | |||
const DWORD *pFunction, void *cso ) | |||
{ | |||
struct NineDevice9 *device; | |||
struct nine_shader_info info; | |||
HRESULT hr; | |||
unsigned i; | |||
hr = NineUnknown_ctor(&This->base, pParams); | |||
if (FAILED(hr)) | |||
return hr; | |||
if (cso) { | |||
This->variant.cso = cso; | |||
return D3D_OK; | |||
} | |||
device = This->base.device; | |||
info.type = PIPE_SHADER_VERTEX; | |||
info.byte_code = pFunction; | |||
info.const_i_base = NINE_CONST_I_BASE(device->max_vs_const_f) / 16; | |||
info.const_b_base = NINE_CONST_B_BASE(device->max_vs_const_f) / 16; | |||
info.sampler_mask_shadow = 0x0; | |||
info.sampler_ps1xtypes = 0x0; | |||
hr = nine_translate_shader(device, &info); | |||
if (FAILED(hr)) | |||
return hr; | |||
This->byte_code.version = info.version; | |||
This->byte_code.tokens = mem_dup(pFunction, info.byte_size); | |||
if (!This->byte_code.tokens) | |||
return E_OUTOFMEMORY; | |||
This->byte_code.size = info.byte_size; | |||
This->variant.cso = info.cso; | |||
This->const_used_size = info.const_used_size; | |||
if (info.const_used_size == ~0) | |||
This->const_used_size = NINE_CONSTBUF_SIZE(device->max_vs_const_f); | |||
This->lconstf = info.lconstf; | |||
This->sampler_mask = info.sampler_mask; | |||
This->position_t = info.position_t; | |||
This->point_size = info.point_size; | |||
for (i = 0; i < info.num_inputs && i < Elements(This->input_map); ++i) | |||
This->input_map[i].ndecl = info.input_map[i]; | |||
This->num_inputs = i; | |||
return D3D_OK; | |||
} | |||
void | |||
NineVertexShader9_dtor( struct NineVertexShader9 *This ) | |||
{ | |||
DBG("This=%p cso=%p\n", This, This->variant.cso); | |||
if (This->base.device) { | |||
struct pipe_context *pipe = This->base.device->pipe; | |||
struct nine_shader_variant *var = &This->variant; | |||
do { | |||
if (var->cso) { | |||
if (This->base.device->state.cso.vs == var->cso) | |||
pipe->bind_vs_state(pipe, NULL); | |||
pipe->delete_vs_state(pipe, var->cso); | |||
} | |||
var = var->next; | |||
} while (var); | |||
} | |||
nine_shader_variants_free(&This->variant); | |||
if (This->byte_code.tokens) | |||
FREE((void *)This->byte_code.tokens); /* const_cast */ | |||
FREE(This->lconstf.data); | |||
FREE(This->lconstf.ranges); | |||
NineUnknown_dtor(&This->base); | |||
} | |||
HRESULT WINAPI | |||
NineVertexShader9_GetFunction( struct NineVertexShader9 *This, | |||
void *pData, | |||
UINT *pSizeOfData ) | |||
{ | |||
user_assert(pSizeOfData, D3DERR_INVALIDCALL); | |||
if (!pData) { | |||
*pSizeOfData = This->byte_code.size; | |||
return D3D_OK; | |||
} | |||
user_assert(*pSizeOfData >= This->byte_code.size, D3DERR_INVALIDCALL); | |||
memcpy(pData, This->byte_code.tokens, This->byte_code.size); | |||
return D3D_OK; | |||
} | |||
void * | |||
NineVertexShader9_GetVariant( struct NineVertexShader9 *This, | |||
uint32_t key ) | |||
{ | |||
void *cso = nine_shader_variant_get(&This->variant, key); | |||
if (!cso) { | |||
struct NineDevice9 *device = This->base.device; | |||
struct nine_shader_info info; | |||
HRESULT hr; | |||
info.type = PIPE_SHADER_VERTEX; | |||
info.const_i_base = NINE_CONST_I_BASE(device->max_vs_const_f) / 16; | |||
info.const_b_base = NINE_CONST_B_BASE(device->max_vs_const_f) / 16; | |||
info.byte_code = This->byte_code.tokens; | |||
info.sampler_mask_shadow = key & 0xf; | |||
hr = nine_translate_shader(This->base.device, &info); | |||
if (FAILED(hr)) | |||
return NULL; | |||
nine_shader_variant_add(&This->variant, key, info.cso); | |||
cso = info.cso; | |||
} | |||
return cso; | |||
} | |||
IDirect3DVertexShader9Vtbl NineVertexShader9_vtable = { | |||
(void *)NineUnknown_QueryInterface, | |||
(void *)NineUnknown_AddRef, | |||
(void *)NineUnknown_Release, | |||
(void *)NineUnknown_GetDevice, | |||
(void *)NineVertexShader9_GetFunction | |||
}; | |||
static const GUID *NineVertexShader9_IIDs[] = { | |||
&IID_IDirect3DVertexShader9, | |||
&IID_IUnknown, | |||
NULL | |||
}; | |||
HRESULT | |||
NineVertexShader9_new( struct NineDevice9 *pDevice, | |||
struct NineVertexShader9 **ppOut, | |||
const DWORD *pFunction, void *cso ) | |||
{ | |||
NINE_DEVICE_CHILD_NEW(VertexShader9, ppOut, pDevice, pFunction, cso); | |||
} |
@@ -0,0 +1,89 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_VERTEXSHADER9_H_ | |||
#define _NINE_VERTEXSHADER9_H_ | |||
#include "iunknown.h" | |||
#include "nine_shader.h" | |||
struct NineVertexShader9 | |||
{ | |||
struct NineUnknown base; | |||
struct nine_shader_variant variant; | |||
struct { | |||
uint8_t ndecl; /* NINE_DECLUSAGE_x */ | |||
} input_map[PIPE_MAX_ATTRIBS]; | |||
unsigned num_inputs; | |||
struct { | |||
const DWORD *tokens; | |||
DWORD size; | |||
uint8_t version; /* (major << 4) | minor */ | |||
} byte_code; | |||
uint8_t sampler_mask; | |||
uint8_t sampler_mask_shadow; | |||
boolean position_t; /* if true, disable vport transform */ | |||
boolean point_size; /* if true, set rasterizer.point_size_per_vertex to 1 */ | |||
unsigned const_used_size; /* in bytes */ | |||
struct nine_lconstf lconstf; | |||
const struct pipe_stream_output_info *so; | |||
uint64_t ff_key[2]; | |||
}; | |||
static INLINE struct NineVertexShader9 * | |||
NineVertexShader9( void *data ) | |||
{ | |||
return (struct NineVertexShader9 *)data; | |||
} | |||
void * | |||
NineVertexShader9_GetVariant( struct NineVertexShader9 *vs, | |||
uint32_t key ); | |||
/*** public ***/ | |||
HRESULT | |||
NineVertexShader9_new( struct NineDevice9 *pDevice, | |||
struct NineVertexShader9 **ppOut, | |||
const DWORD *pFunction, void *cso ); | |||
HRESULT | |||
NineVertexShader9_ctor( struct NineVertexShader9 *, | |||
struct NineUnknownParams *pParams, | |||
const DWORD *pFunction, void *cso ); | |||
void | |||
NineVertexShader9_dtor( struct NineVertexShader9 * ); | |||
HRESULT WINAPI | |||
NineVertexShader9_GetFunction( struct NineVertexShader9 *This, | |||
void *pData, | |||
UINT *pSizeOfData ); | |||
#endif /* _NINE_VERTEXSHADER9_H_ */ |
@@ -0,0 +1,604 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "device9.h" | |||
#include "volume9.h" | |||
#include "basetexture9.h" /* for marking dirty */ | |||
#include "nine_helpers.h" | |||
#include "nine_pipe.h" | |||
#include "nine_dump.h" | |||
#include "util/u_hash_table.h" | |||
#include "util/u_format.h" | |||
#include "util/u_surface.h" | |||
#include "nine_pdata.h" | |||
#define DBG_CHANNEL DBG_VOLUME | |||
static HRESULT | |||
NineVolume9_AllocateData( struct NineVolume9 *This ) | |||
{ | |||
unsigned size = This->layer_stride * This->desc.Depth; | |||
DBG("(%p(This=%p),level=%u) Allocating 0x%x bytes of system memory.\n", | |||
This->base.container, This, This->level, size); | |||
This->data = (uint8_t *)MALLOC(size); | |||
if (!This->data) | |||
return E_OUTOFMEMORY; | |||
return D3D_OK; | |||
} | |||
static HRESULT | |||
NineVolume9_ctor( struct NineVolume9 *This, | |||
struct NineUnknownParams *pParams, | |||
struct NineUnknown *pContainer, | |||
struct pipe_resource *pResource, | |||
unsigned Level, | |||
D3DVOLUME_DESC *pDesc ) | |||
{ | |||
HRESULT hr; | |||
assert(pContainer); /* stand-alone volumes can't be created */ | |||
DBG("This=%p pContainer=%p pDevice=%p pResource=%p Level=%u pDesc=%p\n", | |||
This, pContainer, pParams->device, pResource, Level, pDesc); | |||
/* Mark this as a special surface held by another internal resource. */ | |||
pParams->container = pContainer; | |||
user_assert(!(pDesc->Usage & D3DUSAGE_DYNAMIC) || | |||
(pDesc->Pool != D3DPOOL_MANAGED), D3DERR_INVALIDCALL); | |||
assert(pResource || pDesc->Pool != D3DPOOL_DEFAULT); | |||
hr = NineUnknown_ctor(&This->base, pParams); | |||
if (FAILED(hr)) | |||
return hr; | |||
This->pdata = util_hash_table_create(ht_guid_hash, ht_guid_compare); | |||
if (!This->pdata) | |||
return E_OUTOFMEMORY; | |||
pipe_resource_reference(&This->resource, pResource); | |||
This->pipe = pParams->device->pipe; | |||
This->transfer = NULL; | |||
This->lock_count = 0; | |||
This->level = Level; | |||
This->level_actual = Level; | |||
This->desc = *pDesc; | |||
This->info.screen = pParams->device->screen; | |||
This->info.target = PIPE_TEXTURE_3D; | |||
This->info.format = d3d9_to_pipe_format(pDesc->Format); | |||
This->info.width0 = pDesc->Width; | |||
This->info.height0 = pDesc->Height; | |||
This->info.depth0 = pDesc->Depth; | |||
This->info.last_level = 0; | |||
This->info.array_size = 1; | |||
This->info.nr_samples = 0; | |||
This->info.usage = PIPE_USAGE_DEFAULT; | |||
This->info.bind = PIPE_BIND_SAMPLER_VIEW; | |||
This->info.flags = 0; | |||
This->stride = util_format_get_stride(This->info.format, pDesc->Width); | |||
This->stride = align(This->stride, 4); | |||
This->layer_stride = util_format_get_2d_size(This->info.format, | |||
This->stride, pDesc->Height); | |||
if (pDesc->Pool == D3DPOOL_SYSTEMMEM) | |||
This->info.usage = PIPE_USAGE_STAGING; | |||
if (!This->resource) { | |||
hr = NineVolume9_AllocateData(This); | |||
if (FAILED(hr)) | |||
return hr; | |||
} | |||
return D3D_OK; | |||
} | |||
static void | |||
NineVolume9_dtor( struct NineVolume9 *This ) | |||
{ | |||
DBG("This=%p\n", This); | |||
if (This->transfer) | |||
NineVolume9_UnlockBox(This); | |||
pipe_resource_reference(&This->resource, NULL); | |||
NineUnknown_dtor(&This->base); | |||
} | |||
HRESULT WINAPI | |||
NineVolume9_GetContainer( struct NineVolume9 *This, | |||
REFIID riid, | |||
void **ppContainer ) | |||
{ | |||
if (!NineUnknown(This)->container) | |||
return E_NOINTERFACE; | |||
return NineUnknown_QueryInterface(NineUnknown(This)->container, riid, ppContainer); | |||
} | |||
static INLINE void | |||
NineVolume9_MarkContainerDirty( struct NineVolume9 *This ) | |||
{ | |||
struct NineBaseTexture9 *tex; | |||
#ifdef DEBUG | |||
/* This is always contained by a NineVolumeTexture9. */ | |||
GUID id = IID_IDirect3DVolumeTexture9; | |||
REFIID ref = &id; | |||
assert(NineUnknown_QueryInterface(This->base.container, ref, (void **)&tex) | |||
== S_OK); | |||
assert(NineUnknown_Release(NineUnknown(tex)) != 0); | |||
#endif | |||
tex = NineBaseTexture9(This->base.container); | |||
assert(tex); | |||
if (This->desc.Pool == D3DPOOL_MANAGED) | |||
tex->dirty = TRUE; | |||
else | |||
if (This->desc.Usage & D3DUSAGE_AUTOGENMIPMAP) | |||
tex->dirty_mip = TRUE; | |||
BASETEX_REGISTER_UPDATE(tex); | |||
} | |||
HRESULT WINAPI | |||
NineVolume9_GetDesc( struct NineVolume9 *This, | |||
D3DVOLUME_DESC *pDesc ) | |||
{ | |||
user_assert(pDesc != NULL, E_POINTER); | |||
*pDesc = This->desc; | |||
return D3D_OK; | |||
} | |||
static INLINE boolean | |||
NineVolume9_IsDirty(struct NineVolume9 *This) | |||
{ | |||
return This->dirty_box[0].width != 0; | |||
} | |||
INLINE void | |||
NineVolume9_AddDirtyRegion( struct NineVolume9 *This, | |||
const struct pipe_box *box ) | |||
{ | |||
struct pipe_box cover_a, cover_b; | |||
float vol[2]; | |||
if (!box) { | |||
u_box_3d(0, 0, 0, This->desc.Width, This->desc.Height, | |||
This->desc.Depth, &This->dirty_box[0]); | |||
memset(&This->dirty_box[1], 0, sizeof(This->dirty_box[1])); | |||
return; | |||
} | |||
if (!This->dirty_box[0].width) { | |||
This->dirty_box[0] = *box; | |||
return; | |||
} | |||
u_box_union_3d(&cover_a, &This->dirty_box[0], box); | |||
vol[0] = u_box_volume_3d(&cover_a); | |||
if (This->dirty_box[1].width == 0) { | |||
vol[1] = u_box_volume_3d(&This->dirty_box[0]); | |||
if (vol[0] > (vol[1] * 1.5f)) | |||
This->dirty_box[1] = *box; | |||
else | |||
This->dirty_box[0] = cover_a; | |||
} else { | |||
u_box_union_3d(&cover_b, &This->dirty_box[1], box); | |||
vol[1] = u_box_volume_3d(&cover_b); | |||
if (vol[0] > vol[1]) | |||
This->dirty_box[1] = cover_b; | |||
else | |||
This->dirty_box[0] = cover_a; | |||
} | |||
} | |||
static INLINE uint8_t * | |||
NineVolume9_GetSystemMemPointer(struct NineVolume9 *This, int x, int y, int z) | |||
{ | |||
unsigned x_offset = util_format_get_stride(This->info.format, x); | |||
y = util_format_get_nblocksy(This->info.format, y); | |||
assert(This->data); | |||
return This->data + (z * This->layer_stride + y * This->stride + x_offset); | |||
} | |||
HRESULT WINAPI | |||
NineVolume9_LockBox( struct NineVolume9 *This, | |||
D3DLOCKED_BOX *pLockedVolume, | |||
const D3DBOX *pBox, | |||
DWORD Flags ) | |||
{ | |||
struct pipe_resource *resource = This->resource; | |||
struct pipe_box box; | |||
unsigned usage; | |||
DBG("This=%p(%p) pLockedVolume=%p pBox=%p[%u..%u,%u..%u,%u..%u] Flags=%s\n", | |||
This, This->base.container, pLockedVolume, pBox, | |||
pBox ? pBox->Left : 0, pBox ? pBox->Right : 0, | |||
pBox ? pBox->Top : 0, pBox ? pBox->Bottom : 0, | |||
pBox ? pBox->Front : 0, pBox ? pBox->Back : 0, | |||
nine_D3DLOCK_to_str(Flags)); | |||
user_assert(This->desc.Pool != D3DPOOL_DEFAULT || | |||
(This->desc.Usage & D3DUSAGE_DYNAMIC), D3DERR_INVALIDCALL); | |||
user_assert(!((Flags & D3DLOCK_DISCARD) && (Flags & D3DLOCK_READONLY)), | |||
D3DERR_INVALIDCALL); | |||
user_assert(This->lock_count == 0, D3DERR_INVALIDCALL); | |||
user_assert(pLockedVolume, E_POINTER); | |||
if (pBox && This->desc.Pool == D3DPOOL_DEFAULT && | |||
util_format_is_compressed(This->info.format)) { | |||
const unsigned w = util_format_get_blockwidth(This->info.format); | |||
const unsigned h = util_format_get_blockheight(This->info.format); | |||
user_assert(!(pBox->Left % w) && !(pBox->Right % w) && | |||
!(pBox->Top % h) && !(pBox->Bottom % h), | |||
D3DERR_INVALIDCALL); | |||
} | |||
if (Flags & D3DLOCK_DISCARD) { | |||
usage = PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE; | |||
} else { | |||
usage = (Flags & D3DLOCK_READONLY) ? | |||
PIPE_TRANSFER_READ : PIPE_TRANSFER_READ_WRITE; | |||
} | |||
if (Flags & D3DLOCK_DONOTWAIT) | |||
usage |= PIPE_TRANSFER_DONTBLOCK; | |||
if (pBox) { | |||
d3dbox_to_pipe_box(&box, pBox); | |||
if (u_box_clip_2d(&box, &box, This->desc.Width, This->desc.Height) < 0) { | |||
DBG("Locked volume intersection empty.\n"); | |||
return D3DERR_INVALIDCALL; | |||
} | |||
} else { | |||
u_box_3d(0, 0, 0, This->desc.Width, This->desc.Height, This->desc.Depth, | |||
&box); | |||
} | |||
if (This->data) { | |||
pLockedVolume->RowPitch = This->stride; | |||
pLockedVolume->SlicePitch = This->layer_stride; | |||
pLockedVolume->pBits = | |||
NineVolume9_GetSystemMemPointer(This, box.x, box.y, box.z); | |||
} else { | |||
pLockedVolume->pBits = | |||
This->pipe->transfer_map(This->pipe, resource, This->level, usage, | |||
&box, &This->transfer); | |||
if (!This->transfer) { | |||
if (Flags & D3DLOCK_DONOTWAIT) | |||
return D3DERR_WASSTILLDRAWING; | |||
return D3DERR_DRIVERINTERNALERROR; | |||
} | |||
pLockedVolume->RowPitch = This->transfer->stride; | |||
pLockedVolume->SlicePitch = This->transfer->layer_stride; | |||
} | |||
if (!(Flags & (D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_READONLY))) { | |||
NineVolume9_MarkContainerDirty(This); | |||
if (This->desc.Pool == D3DPOOL_MANAGED) | |||
NineVolume9_AddDirtyRegion(This, &box); | |||
} | |||
++This->lock_count; | |||
return D3D_OK; | |||
} | |||
HRESULT WINAPI | |||
NineVolume9_UnlockBox( struct NineVolume9 *This ) | |||
{ | |||
DBG("This=%p lock_count=%u\n", This, This->lock_count); | |||
user_assert(This->lock_count, D3DERR_INVALIDCALL); | |||
if (This->transfer) { | |||
This->pipe->transfer_unmap(This->pipe, This->transfer); | |||
This->transfer = NULL; | |||
} | |||
--This->lock_count; | |||
return D3D_OK; | |||
} | |||
HRESULT | |||
NineVolume9_CopyVolume( struct NineVolume9 *This, | |||
struct NineVolume9 *From, | |||
unsigned dstx, unsigned dsty, unsigned dstz, | |||
struct pipe_box *pSrcBox ) | |||
{ | |||
struct pipe_context *pipe = This->pipe; | |||
struct pipe_resource *r_dst = This->resource; | |||
struct pipe_resource *r_src = From->resource; | |||
struct pipe_transfer *transfer; | |||
struct pipe_box src_box; | |||
struct pipe_box dst_box; | |||
uint8_t *p_dst; | |||
const uint8_t *p_src; | |||
user_assert(This->desc.Format == From->desc.Format, D3DERR_INVALIDCALL); | |||
dst_box.x = dstx; | |||
dst_box.y = dsty; | |||
dst_box.z = dstz; | |||
if (pSrcBox) { | |||
/* make sure it doesn't range outside the source volume */ | |||
user_assert(pSrcBox->x >= 0 && | |||
(pSrcBox->width - pSrcBox->x) <= From->desc.Width && | |||
pSrcBox->y >= 0 && | |||
(pSrcBox->height - pSrcBox->y) <= From->desc.Height && | |||
pSrcBox->z >= 0 && | |||
(pSrcBox->depth - pSrcBox->z) <= From->desc.Depth, | |||
D3DERR_INVALIDCALL); | |||
src_box = *pSrcBox; | |||
} else { | |||
src_box.x = 0; | |||
src_box.y = 0; | |||
src_box.z = 0; | |||
src_box.width = From->desc.Width; | |||
src_box.height = From->desc.Height; | |||
src_box.depth = From->desc.Depth; | |||
} | |||
/* limits */ | |||
dst_box.width = This->desc.Width - dst_box.x; | |||
dst_box.height = This->desc.Height - dst_box.y; | |||
dst_box.depth = This->desc.Depth - dst_box.z; | |||
user_assert(src_box.width <= dst_box.width && | |||
src_box.height <= dst_box.height && | |||
src_box.depth <= dst_box.depth, D3DERR_INVALIDCALL); | |||
dst_box.width = src_box.width; | |||
dst_box.height = src_box.height; | |||
dst_box.depth = src_box.depth; | |||
/* Don't copy to device memory of managed resources. | |||
* We don't want to download it back again later. | |||
*/ | |||
if (This->desc.Pool == D3DPOOL_MANAGED) | |||
r_dst = NULL; | |||
/* Don't copy from stale device memory of managed resources. | |||
* Also, don't copy between system and device if we don't have to. | |||
*/ | |||
if (From->desc.Pool == D3DPOOL_MANAGED) { | |||
if (!r_dst || NineVolume9_IsDirty(From)) | |||
r_src = NULL; | |||
} | |||
if (r_dst && r_src) { | |||
pipe->resource_copy_region(pipe, | |||
r_dst, This->level, | |||
dst_box.x, dst_box.y, dst_box.z, | |||
r_src, From->level, | |||
&src_box); | |||
} else | |||
if (r_dst) { | |||
p_src = NineVolume9_GetSystemMemPointer(From, | |||
src_box.x, src_box.y, src_box.z); | |||
pipe->transfer_inline_write(pipe, r_dst, This->level, | |||
0, /* WRITE|DISCARD are implicit */ | |||
&dst_box, p_src, | |||
From->stride, From->layer_stride); | |||
} else | |||
if (r_src) { | |||
p_dst = NineVolume9_GetSystemMemPointer(This, 0, 0, 0); | |||
p_src = pipe->transfer_map(pipe, r_src, From->level, | |||
PIPE_TRANSFER_READ, | |||
&src_box, &transfer); | |||
if (!p_src) | |||
return D3DERR_DRIVERINTERNALERROR; | |||
util_copy_box(p_dst, This->info.format, | |||
This->stride, This->layer_stride, | |||
dst_box.x, dst_box.y, dst_box.z, | |||
dst_box.width, dst_box.height, dst_box.depth, | |||
p_src, | |||
transfer->stride, transfer->layer_stride, | |||
src_box.x, src_box.y, src_box.z); | |||
pipe->transfer_unmap(pipe, transfer); | |||
} else { | |||
p_dst = NineVolume9_GetSystemMemPointer(This, 0, 0, 0); | |||
p_src = NineVolume9_GetSystemMemPointer(From, 0, 0, 0); | |||
util_copy_box(p_dst, This->info.format, | |||
This->stride, This->layer_stride, | |||
dst_box.x, dst_box.y, dst_box.z, | |||
dst_box.width, dst_box.height, dst_box.depth, | |||
p_src, | |||
From->stride, From->layer_stride, | |||
src_box.x, src_box.y, src_box.z); | |||
} | |||
if (This->desc.Pool == D3DPOOL_DEFAULT || | |||
This->desc.Pool == D3DPOOL_MANAGED) | |||
NineVolume9_MarkContainerDirty(This); | |||
if (!r_dst && This->resource) | |||
NineVolume9_AddDirtyRegion(This, &dst_box); | |||
return D3D_OK; | |||
} | |||
HRESULT | |||
NineVolume9_UploadSelf( struct NineVolume9 *This ) | |||
{ | |||
struct pipe_context *pipe = This->pipe; | |||
struct pipe_resource *res = This->resource; | |||
uint8_t *ptr; | |||
unsigned i; | |||
DBG("This=%p dirty=%i data=%p res=%p\n", This, NineVolume9_IsDirty(This), | |||
This->data, res); | |||
assert(This->desc.Pool == D3DPOOL_MANAGED); | |||
if (!NineVolume9_IsDirty(This)) | |||
return D3D_OK; | |||
assert(res); | |||
for (i = 0; i < Elements(This->dirty_box); ++i) { | |||
const struct pipe_box *box = &This->dirty_box[i]; | |||
if (box->width == 0) | |||
break; | |||
ptr = NineVolume9_GetSystemMemPointer(This, box->x, box->y, box->z); | |||
pipe->transfer_inline_write(pipe, res, This->level, | |||
0, | |||
box, ptr, This->stride, This->layer_stride); | |||
} | |||
NineVolume9_ClearDirtyRegion(This); | |||
return D3D_OK; | |||
} | |||
IDirect3DVolume9Vtbl NineVolume9_vtable = { | |||
(void *)NineUnknown_QueryInterface, | |||
(void *)NineUnknown_AddRef, | |||
(void *)NineUnknown_Release, | |||
(void *)NineUnknown_GetDevice, /* actually part of Volume9 iface */ | |||
(void *)NineVolume9_SetPrivateData, | |||
(void *)NineVolume9_GetPrivateData, | |||
(void *)NineVolume9_FreePrivateData, | |||
(void *)NineVolume9_GetContainer, | |||
(void *)NineVolume9_GetDesc, | |||
(void *)NineVolume9_LockBox, | |||
(void *)NineVolume9_UnlockBox | |||
}; | |||
static const GUID *NineVolume9_IIDs[] = { | |||
&IID_IDirect3DVolume9, | |||
&IID_IUnknown, | |||
NULL | |||
}; | |||
HRESULT | |||
NineVolume9_new( struct NineDevice9 *pDevice, | |||
struct NineUnknown *pContainer, | |||
struct pipe_resource *pResource, | |||
unsigned Level, | |||
D3DVOLUME_DESC *pDesc, | |||
struct NineVolume9 **ppOut ) | |||
{ | |||
NINE_DEVICE_CHILD_NEW(Volume9, ppOut, pDevice, /* args */ | |||
pContainer, pResource, Level, pDesc); | |||
} | |||
/*** The boring stuff. TODO: Unify with Resource. ***/ | |||
HRESULT WINAPI | |||
NineVolume9_SetPrivateData( struct NineVolume9 *This, | |||
REFGUID refguid, | |||
const void *pData, | |||
DWORD SizeOfData, | |||
DWORD Flags ) | |||
{ | |||
enum pipe_error err; | |||
struct pheader *header; | |||
const void *user_data = pData; | |||
if (Flags & D3DSPD_IUNKNOWN) | |||
user_assert(SizeOfData == sizeof(IUnknown *), D3DERR_INVALIDCALL); | |||
/* data consists of a header and the actual data. avoiding 2 mallocs */ | |||
header = CALLOC_VARIANT_LENGTH_STRUCT(pheader, SizeOfData-1); | |||
if (!header) { return E_OUTOFMEMORY; } | |||
header->unknown = (Flags & D3DSPD_IUNKNOWN) ? TRUE : FALSE; | |||
/* if the refguid already exists, delete it */ | |||
NineVolume9_FreePrivateData(This, refguid); | |||
/* IUnknown special case */ | |||
if (header->unknown) { | |||
/* here the pointer doesn't point to the data we want, so point at the | |||
* pointer making what we eventually copy is the pointer itself */ | |||
user_data = &pData; | |||
} | |||
header->size = SizeOfData; | |||
memcpy(header->data, user_data, header->size); | |||
err = util_hash_table_set(This->pdata, refguid, header); | |||
if (err == PIPE_OK) { | |||
if (header->unknown) { IUnknown_AddRef(*(IUnknown **)header->data); } | |||
return D3D_OK; | |||
} | |||
FREE(header); | |||
if (err == PIPE_ERROR_OUT_OF_MEMORY) { return E_OUTOFMEMORY; } | |||
return D3DERR_DRIVERINTERNALERROR; | |||
} | |||
HRESULT WINAPI | |||
NineVolume9_GetPrivateData( struct NineVolume9 *This, | |||
REFGUID refguid, | |||
void *pData, | |||
DWORD *pSizeOfData ) | |||
{ | |||
struct pheader *header; | |||
user_assert(pSizeOfData, E_POINTER); | |||
header = util_hash_table_get(This->pdata, refguid); | |||
if (!header) { return D3DERR_NOTFOUND; } | |||
if (!pData) { | |||
*pSizeOfData = header->size; | |||
return D3D_OK; | |||
} | |||
if (*pSizeOfData < header->size) { | |||
return D3DERR_MOREDATA; | |||
} | |||
if (header->unknown) { IUnknown_AddRef(*(IUnknown **)header->data); } | |||
memcpy(pData, header->data, header->size); | |||
return D3D_OK; | |||
} | |||
HRESULT WINAPI | |||
NineVolume9_FreePrivateData( struct NineVolume9 *This, | |||
REFGUID refguid ) | |||
{ | |||
struct pheader *header; | |||
header = util_hash_table_get(This->pdata, refguid); | |||
if (!header) { return D3DERR_NOTFOUND; } | |||
ht_guid_delete(NULL, header, NULL); | |||
util_hash_table_remove(This->pdata, refguid); | |||
return D3D_OK; | |||
} | |||
@@ -0,0 +1,141 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_VOLUME9_H_ | |||
#define _NINE_VOLUME9_H_ | |||
#include "iunknown.h" | |||
#include "pipe/p_state.h" | |||
#include "util/u_inlines.h" | |||
struct util_hash_table; | |||
struct NineDevice9; | |||
struct NineVolume9 | |||
{ | |||
struct NineUnknown base; | |||
struct pipe_resource *resource; | |||
unsigned level; | |||
unsigned level_actual; | |||
uint8_t *data; /* system memory backing */ | |||
D3DVOLUME_DESC desc; | |||
struct pipe_resource info; | |||
unsigned stride; | |||
unsigned layer_stride; | |||
struct pipe_transfer *transfer; | |||
unsigned lock_count; | |||
struct pipe_box dirty_box[2]; | |||
struct pipe_context *pipe; | |||
/* for [GS]etPrivateData/FreePrivateData */ | |||
struct util_hash_table *pdata; | |||
}; | |||
static INLINE struct NineVolume9 * | |||
NineVolume9( void *data ) | |||
{ | |||
return (struct NineVolume9 *)data; | |||
} | |||
HRESULT | |||
NineVolume9_new( struct NineDevice9 *pDevice, | |||
struct NineUnknown *pContainer, | |||
struct pipe_resource *pResource, | |||
unsigned Level, | |||
D3DVOLUME_DESC *pDesc, | |||
struct NineVolume9 **ppOut ); | |||
/*** Nine private ***/ | |||
static INLINE void | |||
NineVolume9_SetResource( struct NineVolume9 *This, | |||
struct pipe_resource *resource, unsigned level ) | |||
{ | |||
This->level = level; | |||
pipe_resource_reference(&This->resource, resource); | |||
} | |||
void | |||
NineVolume9_AddDirtyRegion( struct NineVolume9 *This, | |||
const struct pipe_box *box ); | |||
static INLINE void | |||
NineVolume9_ClearDirtyRegion( struct NineVolume9 *This ) | |||
{ | |||
memset(&This->dirty_box, 0, sizeof(This->dirty_box)); | |||
} | |||
HRESULT | |||
NineVolume9_CopyVolume( struct NineVolume9 *This, | |||
struct NineVolume9 *From, | |||
unsigned dstx, unsigned dsty, unsigned dstz, | |||
struct pipe_box *pSrcBox ); | |||
HRESULT | |||
NineVolume9_UploadSelf( struct NineVolume9 *This ); | |||
/*** Direct3D public ***/ | |||
HRESULT WINAPI | |||
NineVolume9_SetPrivateData( struct NineVolume9 *This, | |||
REFGUID refguid, | |||
const void *pData, | |||
DWORD SizeOfData, | |||
DWORD Flags ); | |||
HRESULT WINAPI | |||
NineVolume9_GetPrivateData( struct NineVolume9 *This, | |||
REFGUID refguid, | |||
void *pData, | |||
DWORD *pSizeOfData ); | |||
HRESULT WINAPI | |||
NineVolume9_FreePrivateData( struct NineVolume9 *This, | |||
REFGUID refguid ); | |||
HRESULT WINAPI | |||
NineVolume9_GetContainer( struct NineVolume9 *This, | |||
REFIID riid, | |||
void **ppContainer ); | |||
HRESULT WINAPI | |||
NineVolume9_GetDesc( struct NineVolume9 *This, | |||
D3DVOLUME_DESC *pDesc ); | |||
HRESULT WINAPI | |||
NineVolume9_LockBox( struct NineVolume9 *This, | |||
D3DLOCKED_BOX *pLockedVolume, | |||
const D3DBOX *pBox, | |||
DWORD Flags ); | |||
HRESULT WINAPI | |||
NineVolume9_UnlockBox( struct NineVolume9 *This ); | |||
#endif /* _NINE_VOLUME9_H_ */ |
@@ -0,0 +1,253 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "device9.h" | |||
#include "volumetexture9.h" | |||
#include "nine_helpers.h" | |||
#include "nine_pipe.h" | |||
#define DBG_CHANNEL DBG_VOLUMETEXTURE | |||
static HRESULT | |||
NineVolumeTexture9_ctor( struct NineVolumeTexture9 *This, | |||
struct NineUnknownParams *pParams, | |||
UINT Width, UINT Height, UINT Depth, UINT Levels, | |||
DWORD Usage, | |||
D3DFORMAT Format, | |||
D3DPOOL Pool, | |||
HANDLE *pSharedHandle ) | |||
{ | |||
struct pipe_resource *info = &This->base.base.info; | |||
unsigned l; | |||
D3DVOLUME_DESC voldesc; | |||
HRESULT hr; | |||
/* An IDirect3DVolume9 cannot be bound as a render target can it ? */ | |||
user_assert(!(Usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)), | |||
D3DERR_INVALIDCALL); | |||
user_assert(!(Usage & D3DUSAGE_AUTOGENMIPMAP) || | |||
(Pool != D3DPOOL_SYSTEMMEM && Levels <= 1), D3DERR_INVALIDCALL); | |||
user_assert(!pSharedHandle, D3DERR_INVALIDCALL); /* TODO */ | |||
if (Usage & D3DUSAGE_AUTOGENMIPMAP) | |||
Levels = 0; | |||
This->base.format = Format; | |||
This->base.base.usage = Usage; | |||
info->screen = pParams->device->screen; | |||
info->target = PIPE_TEXTURE_3D; | |||
info->format = d3d9_to_pipe_format(Format); | |||
info->width0 = Width; | |||
info->height0 = Height; | |||
info->depth0 = Depth; | |||
if (Levels) | |||
info->last_level = Levels - 1; | |||
else | |||
info->last_level = util_logbase2(MAX2(MAX2(Width, Height), Depth)); | |||
info->array_size = 1; | |||
info->nr_samples = 0; | |||
info->bind = PIPE_BIND_SAMPLER_VIEW; | |||
info->usage = PIPE_USAGE_DEFAULT; | |||
info->flags = 0; | |||
if (Usage & D3DUSAGE_DYNAMIC) { | |||
info->usage = PIPE_USAGE_DYNAMIC; | |||
info->bind |= | |||
PIPE_BIND_TRANSFER_READ | | |||
PIPE_BIND_TRANSFER_WRITE; | |||
} | |||
This->volumes = CALLOC(info->last_level + 1, sizeof(*This->volumes)); | |||
if (!This->volumes) | |||
return E_OUTOFMEMORY; | |||
This->base.pstype = 3; | |||
hr = NineBaseTexture9_ctor(&This->base, pParams, | |||
D3DRTYPE_VOLUMETEXTURE, Pool); | |||
if (FAILED(hr)) | |||
return hr; | |||
voldesc.Format = Format; | |||
voldesc.Type = D3DRTYPE_VOLUME; | |||
voldesc.Usage = Usage; | |||
voldesc.Pool = Pool; | |||
for (l = 0; l <= info->last_level; ++l) { | |||
voldesc.Width = u_minify(Width, l); | |||
voldesc.Height = u_minify(Height, l); | |||
voldesc.Depth = u_minify(Depth, l); | |||
hr = NineVolume9_new(This->base.base.base.device, NineUnknown(This), | |||
This->base.base.resource, l, | |||
&voldesc, &This->volumes[l]); | |||
if (FAILED(hr)) | |||
return hr; | |||
} | |||
return D3D_OK; | |||
} | |||
static void | |||
NineVolumeTexture9_dtor( struct NineVolumeTexture9 *This ) | |||
{ | |||
unsigned l; | |||
DBG("This=%p\n", This); | |||
if (This->volumes) { | |||
for (l = 0; l < This->base.base.info.last_level; ++l) | |||
NineUnknown_Destroy(&This->volumes[l]->base); | |||
FREE(This->volumes); | |||
} | |||
NineBaseTexture9_dtor(&This->base); | |||
} | |||
HRESULT WINAPI | |||
NineVolumeTexture9_GetLevelDesc( struct NineVolumeTexture9 *This, | |||
UINT Level, | |||
D3DVOLUME_DESC *pDesc ) | |||
{ | |||
user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL); | |||
user_assert(Level == 0 || !(This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP), | |||
D3DERR_INVALIDCALL); | |||
*pDesc = This->volumes[Level]->desc; | |||
return D3D_OK; | |||
} | |||
HRESULT WINAPI | |||
NineVolumeTexture9_GetVolumeLevel( struct NineVolumeTexture9 *This, | |||
UINT Level, | |||
IDirect3DVolume9 **ppVolumeLevel ) | |||
{ | |||
user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL); | |||
user_assert(Level == 0 || !(This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP), | |||
D3DERR_INVALIDCALL); | |||
NineUnknown_AddRef(NineUnknown(This->volumes[Level])); | |||
*ppVolumeLevel = (IDirect3DVolume9 *)This->volumes[Level]; | |||
return D3D_OK; | |||
} | |||
HRESULT WINAPI | |||
NineVolumeTexture9_LockBox( struct NineVolumeTexture9 *This, | |||
UINT Level, | |||
D3DLOCKED_BOX *pLockedVolume, | |||
const D3DBOX *pBox, | |||
DWORD Flags ) | |||
{ | |||
user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL); | |||
user_assert(Level == 0 || !(This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP), | |||
D3DERR_INVALIDCALL); | |||
return NineVolume9_LockBox(This->volumes[Level], pLockedVolume, pBox, | |||
Flags); | |||
} | |||
HRESULT WINAPI | |||
NineVolumeTexture9_UnlockBox( struct NineVolumeTexture9 *This, | |||
UINT Level ) | |||
{ | |||
user_assert(Level <= This->base.base.info.last_level, D3DERR_INVALIDCALL); | |||
return NineVolume9_UnlockBox(This->volumes[Level]); | |||
} | |||
HRESULT WINAPI | |||
NineVolumeTexture9_AddDirtyBox( struct NineVolumeTexture9 *This, | |||
const D3DBOX *pDirtyBox ) | |||
{ | |||
if (This->base.base.pool != D3DPOOL_MANAGED) { | |||
if (This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP) | |||
This->base.dirty_mip = TRUE; | |||
return D3D_OK; | |||
} | |||
This->base.dirty = TRUE; | |||
BASETEX_REGISTER_UPDATE(&This->base); | |||
if (!pDirtyBox) { | |||
This->dirty_box.x = 0; | |||
This->dirty_box.y = 0; | |||
This->dirty_box.z = 0; | |||
This->dirty_box.width = This->base.base.info.width0; | |||
This->dirty_box.height = This->base.base.info.height0; | |||
This->dirty_box.depth = This->base.base.info.depth0; | |||
} else { | |||
struct pipe_box box; | |||
d3dbox_to_pipe_box(&box, pDirtyBox); | |||
u_box_union_3d(&This->dirty_box, &This->dirty_box, &box); | |||
} | |||
return D3D_OK; | |||
} | |||
IDirect3DVolumeTexture9Vtbl NineVolumeTexture9_vtable = { | |||
(void *)NineUnknown_QueryInterface, | |||
(void *)NineUnknown_AddRef, | |||
(void *)NineUnknown_Release, | |||
(void *)NineUnknown_GetDevice, /* actually part of Resource9 iface */ | |||
(void *)NineResource9_SetPrivateData, | |||
(void *)NineResource9_GetPrivateData, | |||
(void *)NineResource9_FreePrivateData, | |||
(void *)NineResource9_SetPriority, | |||
(void *)NineResource9_GetPriority, | |||
(void *)NineBaseTexture9_PreLoad, | |||
(void *)NineResource9_GetType, | |||
(void *)NineBaseTexture9_SetLOD, | |||
(void *)NineBaseTexture9_GetLOD, | |||
(void *)NineBaseTexture9_GetLevelCount, | |||
(void *)NineBaseTexture9_SetAutoGenFilterType, | |||
(void *)NineBaseTexture9_GetAutoGenFilterType, | |||
(void *)NineBaseTexture9_GenerateMipSubLevels, | |||
(void *)NineVolumeTexture9_GetLevelDesc, | |||
(void *)NineVolumeTexture9_GetVolumeLevel, | |||
(void *)NineVolumeTexture9_LockBox, | |||
(void *)NineVolumeTexture9_UnlockBox, | |||
(void *)NineVolumeTexture9_AddDirtyBox | |||
}; | |||
static const GUID *NineVolumeTexture9_IIDs[] = { | |||
&IID_IDirect3DVolumeTexture9, | |||
&IID_IDirect3DBaseTexture9, | |||
&IID_IDirect3DResource9, | |||
&IID_IUnknown, | |||
NULL | |||
}; | |||
HRESULT | |||
NineVolumeTexture9_new( struct NineDevice9 *pDevice, | |||
UINT Width, UINT Height, UINT Depth, UINT Levels, | |||
DWORD Usage, | |||
D3DFORMAT Format, | |||
D3DPOOL Pool, | |||
struct NineVolumeTexture9 **ppOut, | |||
HANDLE *pSharedHandle ) | |||
{ | |||
NINE_DEVICE_CHILD_NEW(VolumeTexture9, ppOut, pDevice, | |||
Width, Height, Depth, Levels, | |||
Usage, Format, Pool, pSharedHandle); | |||
} | |||
@@ -0,0 +1,75 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef _NINE_VOLUMETEXTURE9_H_ | |||
#define _NINE_VOLUMETEXTURE9_H_ | |||
#include "basetexture9.h" | |||
#include "volume9.h" | |||
struct NineVolumeTexture9 | |||
{ | |||
struct NineBaseTexture9 base; | |||
struct NineVolume9 **volumes; | |||
struct pipe_box dirty_box; | |||
}; | |||
static INLINE struct NineVolumeTexture9 * | |||
NineVolumeTexture9( void *data ) | |||
{ | |||
return (struct NineVolumeTexture9 *)data; | |||
} | |||
HRESULT | |||
NineVolumeTexture9_new( struct NineDevice9 *pDevice, | |||
UINT Width, UINT Height, UINT Depth, UINT Levels, | |||
DWORD Usage, | |||
D3DFORMAT Format, | |||
D3DPOOL Pool, | |||
struct NineVolumeTexture9 **ppOut, | |||
HANDLE *pSharedHandle ); | |||
HRESULT WINAPI | |||
NineVolumeTexture9_GetLevelDesc( struct NineVolumeTexture9 *This, | |||
UINT Level, | |||
D3DVOLUME_DESC *pDesc ); | |||
HRESULT WINAPI | |||
NineVolumeTexture9_GetVolumeLevel( struct NineVolumeTexture9 *This, | |||
UINT Level, | |||
IDirect3DVolume9 **ppVolumeLevel ); | |||
HRESULT WINAPI | |||
NineVolumeTexture9_LockBox( struct NineVolumeTexture9 *This, | |||
UINT Level, | |||
D3DLOCKED_BOX *pLockedVolume, | |||
const D3DBOX *pBox, | |||
DWORD Flags ); | |||
HRESULT WINAPI | |||
NineVolumeTexture9_UnlockBox( struct NineVolumeTexture9 *This, | |||
UINT Level ); | |||
HRESULT WINAPI | |||
NineVolumeTexture9_AddDirtyBox( struct NineVolumeTexture9 *This, | |||
const D3DBOX *pDirtyBox ); | |||
#endif /* _NINE_VOLUMETEXTURE9_H_ */ |
@@ -0,0 +1,131 @@ | |||
# Copyright © 2012 Intel Corporation | |||
# | |||
# Permission is hereby granted, free of charge, to any person obtaining a | |||
# copy of this software and associated documentation files (the "Software"), | |||
# to deal in the Software without restriction, including without limitation | |||
# the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
# and/or sell copies of the Software, and to permit persons to whom the | |||
# Software is furnished to do so, subject to the following conditions: | |||
# | |||
# The above copyright notice and this permission notice (including the next | |||
# paragraph) shall be included in all copies or substantial portions of the | |||
# Software. | |||
# | |||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |||
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |||
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
# DEALINGS IN THE SOFTWARE. | |||
include $(top_srcdir)/src/gallium/Automake.inc | |||
AM_CFLAGS = \ | |||
-I$(top_srcdir)/include/D3D9 \ | |||
-I$(top_srcdir)/src/loader \ | |||
-I$(top_srcdir)/src/mapi/ \ | |||
-I$(top_srcdir)/src/mesa/ \ | |||
-I$(top_srcdir)/src/mesa/drivers/dri/common/ \ | |||
-I$(top_builddir)/src/mesa/drivers/dri/common/ \ | |||
-I$(top_srcdir)/src/gallium/winsys \ | |||
-I$(top_srcdir)/src/gallium/state_trackers/nine \ | |||
$(GALLIUM_TARGET_CFLAGS) \ | |||
$(VISIBILITY_CFLAGS) | |||
if HAVE_GALLIUM_STATIC_TARGETS | |||
AM_CPPFLAGS = \ | |||
-DNINE_TARGET \ | |||
-DGALLIUM_STATIC_TARGETS=1 | |||
else | |||
AM_CPPFLAGS = \ | |||
-DPIPE_SEARCH_DIR=\"$(libdir)/gallium-pipe\" \ | |||
$(GALLIUM_PIPE_LOADER_DEFINES) | |||
endif | |||
ninedir = $(D3D_DRIVER_INSTALL_DIR) | |||
nine_LTLIBRARIES = d3dadapter9.la | |||
pkgconfigdir = $(libdir)/pkgconfig | |||
pkgconfig_DATA = d3d.pc | |||
d3dadapter9_la_SOURCES = \ | |||
getproc.c \ | |||
drm.c | |||
d3dadapter9_la_LDFLAGS = \ | |||
-shared \ | |||
-shrext .so \ | |||
-module \ | |||
-no-undefined \ | |||
-version-number $(NINE_MAJOR):$(NINE_MINOR) \ | |||
$(GC_SECTIONS) \ | |||
$(LD_NO_UNDEFINED) | |||
if HAVE_LD_VERSION_SCRIPT | |||
d3dadapter9_la_LDFLAGS += \ | |||
-Wl,--version-script=$(top_srcdir)/src/gallium/targets/d3dadapter9/d3dadapter9.sym | |||
endif # HAVE_LD_VERSION_SCRIPT | |||
d3dadapter9_la_LIBADD = \ | |||
$(top_builddir)/src/gallium/auxiliary/libgallium.la \ | |||
$(top_builddir)/src/gallium/state_trackers/nine/libninetracker.la \ | |||
$(top_builddir)/src/util/libmesautil.la \ | |||
$(top_builddir)/src/gallium/winsys/sw/wrapper/libwsw.la \ | |||
$(EXPAT_LIBS) \ | |||
$(GALLIUM_COMMON_LIB_DEPS) | |||
TARGET_DRIVERS = | |||
TARGET_CPPFLAGS = | |||
TARGET_LIB_DEPS = $(top_builddir)/src/loader/libloader.la | |||
include $(top_srcdir)/src/gallium/drivers/i915/Automake.inc | |||
include $(top_srcdir)/src/gallium/drivers/ilo/Automake.inc | |||
include $(top_srcdir)/src/gallium/drivers/nouveau/Automake.inc | |||
include $(top_srcdir)/src/gallium/drivers/r300/Automake.inc | |||
include $(top_srcdir)/src/gallium/drivers/r600/Automake.inc | |||
include $(top_srcdir)/src/gallium/drivers/radeonsi/Automake.inc | |||
include $(top_srcdir)/src/gallium/drivers/svga/Automake.inc | |||
include $(top_srcdir)/src/gallium/drivers/freedreno/Automake.inc | |||
include $(top_srcdir)/src/gallium/drivers/vc4/Automake.inc | |||
include $(top_srcdir)/src/gallium/drivers/softpipe/Automake.inc | |||
include $(top_srcdir)/src/gallium/drivers/llvmpipe/Automake.inc | |||
if HAVE_GALLIUM_STATIC_TARGETS | |||
d3dadapter9_la_CPPFLAGS = $(AM_CPPFLAGS) $(TARGET_CPPFLAGS) | |||
d3dadapter9_la_LIBADD += $(TARGET_LIB_DEPS) \ | |||
$(TARGET_RADEON_WINSYS) $(TARGET_RADEON_COMMON) | |||
else # HAVE_GALLIUM_STATIC_TARGETS | |||
d3dadapter9_la_LIBADD += \ | |||
$(top_builddir)/src/gallium/auxiliary/pipe-loader/libpipe_loader.la \ | |||
$(GALLIUM_PIPE_LOADER_WINSYS_LIBS) \ | |||
$(GALLIUM_PIPE_LOADER_LIBS) | |||
endif # HAVE_GALLIUM_STATIC_TARGETS | |||
if HAVE_MESA_LLVM | |||
nodist_EXTRA_d3dadapter9_la_SOURCES = dummy.cpp | |||
d3dadapter9_la_LDFLAGS += $(LLVM_LDFLAGS) | |||
d3dadapter9_la_LIBADD += $(LLVM_LIBS) | |||
endif | |||
d3dadapterdir = $(includedir)/d3dadapter | |||
d3dadapter_HEADERS = \ | |||
$(top_srcdir)/include/d3dadapter/d3dadapter9.h \ | |||
$(top_srcdir)/include/d3dadapter/drm.h \ | |||
$(top_srcdir)/include/d3dadapter/present.h |
@@ -0,0 +1,11 @@ | |||
prefix=@prefix@ | |||
exec_prefix=@exec_prefix@ | |||
libdir=@libdir@ | |||
includedir=@includedir@ | |||
moduledir=@D3D_DRIVER_INSTALL_DIR@ | |||
Name: d3d | |||
Description: Native D3D driver modules | |||
Version: @VERSION@ | |||
Requires.private: @DRI_PC_REQ_PRIV@ | |||
Cflags: -I${includedir} |
@@ -0,0 +1,6 @@ | |||
{ | |||
global: | |||
D3DAdapter9GetProc; | |||
local: | |||
*; | |||
}; |
@@ -0,0 +1,327 @@ | |||
/* | |||
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "loader.h" | |||
#include "adapter9.h" | |||
#include "pipe-loader/pipe_loader.h" | |||
#include "pipe/p_screen.h" | |||
#include "pipe/p_state.h" | |||
#include "target-helpers/inline_drm_helper.h" | |||
#include "target-helpers/inline_sw_helper.h" | |||
#include "state_tracker/drm_driver.h" | |||
#include "d3dadapter/d3dadapter9.h" | |||
#include "d3dadapter/drm.h" | |||
#include <libdrm/drm.h> | |||
#include <sys/ioctl.h> | |||
#include <fcntl.h> | |||
#include <stdio.h> | |||
#define DBG_CHANNEL DBG_ADAPTER | |||
#define VERSION_DWORD(hi, lo) \ | |||
((DWORD)( \ | |||
((DWORD)((hi) & 0xFFFF) << 16) | \ | |||
(DWORD)((lo) & 0xFFFF) \ | |||
)) | |||
/* Regarding os versions, we should not define our own as that would simply be | |||
* weird. Defaulting to Win2k/XP seems sane considering the origin of D3D9. The | |||
* driver also defaults to being a generic D3D9 driver, which of course only | |||
* matters if you're actually using the DDI. */ | |||
#define VERSION_HIGH VERSION_DWORD(0x0006, 0x000E) /* winxp, d3d9 */ | |||
#define VERSION_LOW VERSION_DWORD(0x0000, 0x0001) /* version, build */ | |||
struct d3dadapter9drm_context | |||
{ | |||
struct d3dadapter9_context base; | |||
struct pipe_loader_device *dev, *swdev; | |||
}; | |||
static void | |||
drm_destroy( struct d3dadapter9_context *ctx ) | |||
{ | |||
#if !GALLIUM_STATIC_TARGETS | |||
struct d3dadapter9drm_context *drm = (struct d3dadapter9drm_context *)ctx; | |||
/* pipe_loader_sw destroys the context */ | |||
if (drm->swdev) | |||
pipe_loader_release(&drm->swdev, 1); | |||
if (drm->dev) | |||
pipe_loader_release(&drm->dev, 1); | |||
#endif | |||
FREE(ctx); | |||
} | |||
/* read a DWORD in the form 0xnnnnnnnn, which is how sysfs pci id stuff is | |||
* formatted. */ | |||
static INLINE DWORD | |||
read_file_dword( const char *name ) | |||
{ | |||
char buf[32]; | |||
int fd, r; | |||
fd = open(name, O_RDONLY); | |||
if (fd < 0) { | |||
DBG("Unable to get PCI information from `%s'\n", name); | |||
return 0; | |||
} | |||
r = read(fd, buf, 32); | |||
close(fd); | |||
return (r > 0) ? (DWORD)strtol(buf, NULL, 0) : 0; | |||
} | |||
/* sysfs doesn't expose the revision as its own file, so this function grabs a | |||
* dword at an offset in the raw PCI header. The reason this isn't used for all | |||
* data is that the kernel will make corrections but not expose them in the raw | |||
* header bytes. */ | |||
static INLINE DWORD | |||
read_config_dword( int fd, | |||
unsigned offset ) | |||
{ | |||
DWORD r = 0; | |||
if (lseek(fd, offset, SEEK_SET) != offset) { return 0; } | |||
if (read(fd, &r, 4) != 4) { return 0; } | |||
return r; | |||
} | |||
static INLINE void | |||
get_bus_info( int fd, | |||
DWORD *vendorid, | |||
DWORD *deviceid, | |||
DWORD *subsysid, | |||
DWORD *revision ) | |||
{ | |||
drm_unique_t u; | |||
u.unique_len = 0; | |||
u.unique = NULL; | |||
if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) { return; } | |||
u.unique = CALLOC(u.unique_len+1, 1); | |||
if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) { return; } | |||
u.unique[u.unique_len] = '\0'; | |||
DBG("DRM Device BusID: %s\n", u.unique); | |||
if (strncmp("pci:", u.unique, 4) == 0) { | |||
char fname[512]; /* this ought to be enough */ | |||
int l = snprintf(fname, 512, "/sys/bus/pci/devices/%s/", u.unique+4); | |||
/* VendorId */ | |||
snprintf(fname+l, 512-l, "vendor"); | |||
*vendorid = read_file_dword(fname); | |||
/* DeviceId */ | |||
snprintf(fname+l, 512-l, "device"); | |||
*deviceid = read_file_dword(fname); | |||
/* SubSysId */ | |||
snprintf(fname+l, 512-l, "subsystem_device"); | |||
*subsysid = (read_file_dword(fname) << 16) & 0xFFFF0000; | |||
snprintf(fname+l, 512-l, "subsystem_vendor"); | |||
*subsysid |= read_file_dword(fname) & 0x0000FFFF; | |||
/* Revision */ | |||
{ | |||
int cfgfd; | |||
snprintf(fname+l, 512-l, "config"); | |||
cfgfd = open(fname, O_RDONLY); | |||
if (cfgfd >= 0) { | |||
*revision = read_config_dword(cfgfd, 0x8) & 0x000000FF; | |||
close(cfgfd); | |||
} else { | |||
DBG("Unable to get raw PCI information from `%s'\n", fname); | |||
} | |||
} | |||
DBG("PCI info: vendor=0x%04x, device=0x%04x, subsys=0x%08x, rev=%d\n", | |||
*vendorid, *deviceid, *subsysid, *revision); | |||
} else { | |||
DBG("Unsupported BusID type.\n"); | |||
} | |||
FREE(u.unique); | |||
} | |||
static INLINE void | |||
read_descriptor( struct d3dadapter9_context *ctx, | |||
int fd ) | |||
{ | |||
D3DADAPTER_IDENTIFIER9 *drvid = &ctx->identifier; | |||
memset(drvid, 0, sizeof(*drvid)); | |||
get_bus_info(fd, &drvid->VendorId, &drvid->DeviceId, | |||
&drvid->SubSysId, &drvid->Revision); | |||
strncpy(drvid->Driver, "libd3dadapter9.so", sizeof(drvid->Driver)); | |||
strncpy(drvid->DeviceName, ctx->hal->get_name(ctx->hal), 32); | |||
snprintf(drvid->Description, sizeof(drvid->Description), | |||
"Gallium 0.4 with %s", ctx->hal->get_vendor(ctx->hal)); | |||
drvid->DriverVersionLowPart = VERSION_LOW; | |||
drvid->DriverVersionHighPart = VERSION_HIGH; | |||
/* To make a pseudo-real GUID we use the PCI bus data and some string */ | |||
drvid->DeviceIdentifier.Data1 = drvid->VendorId; | |||
drvid->DeviceIdentifier.Data2 = drvid->DeviceId; | |||
drvid->DeviceIdentifier.Data3 = drvid->SubSysId; | |||
memcpy(drvid->DeviceIdentifier.Data4, "Gallium3D", 8); | |||
drvid->WHQLLevel = 1; /* This fakes WHQL validaion */ | |||
/* XXX Fake NVIDIA binary driver on Windows. | |||
* | |||
* OS version: 4=95/98/NT4, 5=2000, 6=2000/XP, 7=Vista, 8=Win7 | |||
*/ | |||
strncpy(drvid->Driver, "nvd3dum.dll", sizeof(drvid->Driver)); | |||
strncpy(drvid->Description, "NVIDIA GeForce GTX 680", sizeof(drvid->Description)); | |||
drvid->DriverVersionLowPart = VERSION_DWORD(12, 6658); /* minor, build */ | |||
drvid->DriverVersionHighPart = VERSION_DWORD(6, 15); /* OS, major */ | |||
drvid->SubSysId = 0; | |||
drvid->Revision = 0; | |||
drvid->DeviceIdentifier.Data1 = 0xaeb2cdd4; | |||
drvid->DeviceIdentifier.Data2 = 0x6e41; | |||
drvid->DeviceIdentifier.Data3 = 0x43ea; | |||
drvid->DeviceIdentifier.Data4[0] = 0x94; | |||
drvid->DeviceIdentifier.Data4[1] = 0x1c; | |||
drvid->DeviceIdentifier.Data4[2] = 0x83; | |||
drvid->DeviceIdentifier.Data4[3] = 0x61; | |||
drvid->DeviceIdentifier.Data4[4] = 0xcc; | |||
drvid->DeviceIdentifier.Data4[5] = 0x76; | |||
drvid->DeviceIdentifier.Data4[6] = 0x07; | |||
drvid->DeviceIdentifier.Data4[7] = 0x81; | |||
drvid->WHQLLevel = 0; | |||
} | |||
static HRESULT WINAPI | |||
drm_create_adapter( int fd, | |||
ID3DAdapter9 **ppAdapter ) | |||
{ | |||
struct d3dadapter9drm_context *ctx = CALLOC_STRUCT(d3dadapter9drm_context); | |||
HRESULT hr; | |||
int i, different_device; | |||
const struct drm_conf_ret *throttle_ret = NULL; | |||
const struct drm_conf_ret *dmabuf_ret = NULL; | |||
#if !GALLIUM_STATIC_TARGETS | |||
const char *paths[] = { | |||
getenv("D3D9_DRIVERS_PATH"), | |||
getenv("D3D9_DRIVERS_DIR"), | |||
PIPE_SEARCH_DIR | |||
}; | |||
#endif | |||
if (!ctx) { return E_OUTOFMEMORY; } | |||
ctx->base.destroy = drm_destroy; | |||
fd = loader_get_user_preferred_fd(fd, &different_device); | |||
ctx->base.linear_framebuffer = !!different_device; | |||
#if GALLIUM_STATIC_TARGETS | |||
ctx->base.hal = dd_create_screen(fd); | |||
#else | |||
/* use pipe-loader to dlopen appropriate drm driver */ | |||
if (!pipe_loader_drm_probe_fd(&ctx->dev, fd, FALSE)) { | |||
ERR("Failed to probe drm fd %d.\n", fd); | |||
FREE(ctx); | |||
close(fd); | |||
return D3DERR_DRIVERINTERNALERROR; | |||
} | |||
/* use pipe-loader to create a drm screen (hal) */ | |||
ctx->base.hal = NULL; | |||
for (i = 0; !ctx->base.hal && i < Elements(paths); ++i) { | |||
if (!paths[i]) { continue; } | |||
ctx->base.hal = pipe_loader_create_screen(ctx->dev, paths[i]); | |||
} | |||
#endif | |||
if (!ctx->base.hal) { | |||
ERR("Unable to load requested driver.\n"); | |||
drm_destroy(&ctx->base); | |||
return D3DERR_DRIVERINTERNALERROR; | |||
} | |||
#if GALLIUM_STATIC_TARGETS | |||
dmabuf_ret = dd_configuration(DRM_CONF_SHARE_FD); | |||
throttle_ret = dd_configuration(DRM_CONF_THROTTLE); | |||
#else | |||
dmabuf_ret = pipe_loader_configuration(ctx->dev, DRM_CONF_SHARE_FD); | |||
throttle_ret = pipe_loader_configuration(ctx->dev, DRM_CONF_THROTTLE); | |||
#endif // GALLIUM_STATIC_TARGETS | |||
if (!dmabuf_ret || !dmabuf_ret->val.val_bool) { | |||
ERR("The driver is not capable of dma-buf sharing." | |||
"Abandon to load nine state tracker\n"); | |||
drm_destroy(&ctx->base); | |||
return D3DERR_DRIVERINTERNALERROR; | |||
} | |||
if (throttle_ret && throttle_ret->val.val_int != -1) { | |||
ctx->base.throttling = TRUE; | |||
ctx->base.throttling_value = throttle_ret->val.val_int; | |||
} else | |||
ctx->base.throttling = FALSE; | |||
#if GALLIUM_STATIC_TARGETS | |||
ctx->base.ref = ninesw_create_screen(ctx->base.hal); | |||
#else | |||
/* wrap it to create a software screen that can share resources */ | |||
if (pipe_loader_sw_probe_wrapped(&ctx->swdev, ctx->base.hal)) { | |||
ctx->base.ref = NULL; | |||
for (i = 0; !ctx->base.ref && i < Elements(paths); ++i) { | |||
if (!paths[i]) { continue; } | |||
ctx->base.ref = pipe_loader_create_screen(ctx->swdev, paths[i]); | |||
} | |||
} | |||
#endif | |||
if (!ctx->base.ref) { | |||
ERR("Couldn't wrap drm screen to swrast screen. Software devices " | |||
"will be unavailable.\n"); | |||
} | |||
/* read out PCI info */ | |||
read_descriptor(&ctx->base, fd); | |||
/* create and return new ID3DAdapter9 */ | |||
hr = NineAdapter9_new(&ctx->base, (struct NineAdapter9 **)ppAdapter); | |||
if (FAILED(hr)) { | |||
drm_destroy(&ctx->base); | |||
return hr; | |||
} | |||
return D3D_OK; | |||
} | |||
const struct D3DAdapter9DRM drm9_desc = { | |||
.major_version = D3DADAPTER9DRM_MAJOR, | |||
.minor_version = D3DADAPTER9DRM_MINOR, | |||
.create_adapter = drm_create_adapter | |||
}; |
@@ -0,0 +1,47 @@ | |||
/* | |||
* Copyright 2013 Joakim Sindholt <opensource@zhasha.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include <string.h> | |||
#include "util/u_memory.h" | |||
#include "d3dadapter/drm.h" | |||
extern const struct D3DAdapter9DRM drm9_desc; | |||
struct { | |||
const char *name; | |||
const void *desc; | |||
} drivers[] = { | |||
{ D3DADAPTER9DRM_NAME, &drm9_desc }, | |||
}; | |||
PUBLIC const void * WINAPI | |||
D3DAdapter9GetProc( const char *name ) | |||
{ | |||
int i; | |||
for (i = 0; i < Elements(drivers); ++i) { | |||
if (strcmp(name, drivers[i].name) == 0) { | |||
return drivers[i].desc; | |||
} | |||
} | |||
return NULL; | |||
} |