nine: Add state tracker nine for Direct3D9 (v3)

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>
This commit is contained in:
Joakim Sindholt 2011-08-04 15:14:06 +02:00 committed by Emil Velikov
parent 7d2573b537
commit fdd96578ef
87 changed files with 32748 additions and 0 deletions

View File

@ -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

1858
include/D3D9/d3d9.h Normal file

File diff suppressed because it is too large Load Diff

387
include/D3D9/d3d9caps.h Normal file
View File

@ -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_ */

1797
include/D3D9/d3d9types.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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_ */

44
include/d3dadapter/drm.h Normal file
View File

@ -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_ */

View File

@ -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_ */

View File

@ -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
##

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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!

File diff suppressed because it is too large Load Diff

View File

@ -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_ */

View File

@ -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
};

View File

@ -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_ */

View File

@ -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 */

View File

@ -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_ */

View File

@ -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
};

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_ */

File diff suppressed because it is too large Load Diff

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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
};

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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 */

View File

@ -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_ */

File diff suppressed because it is too large Load Diff

View File

@ -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_ */

View File

@ -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);
}
}

View File

@ -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_ */

File diff suppressed because it is too large Load Diff

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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, */
};

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_ */

File diff suppressed because it is too large Load Diff

View File

@ -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_ */

File diff suppressed because it is too large Load Diff

View File

@ -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_ */

View File

@ -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
};

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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

View File

@ -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}

View File

@ -0,0 +1,6 @@
{
global:
D3DAdapter9GetProc;
local:
*;
};

View File

@ -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
};

View File

@ -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;
}