delete gallium-nine
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

farewell, old friend

Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Acked-by: Marek Olšák <marek.olsak@amd.com>
Acked-by: Axel Davy <davyaxel0@gmail.com>
Acked-by: David Heidelberg <david@ixit.cz>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34887>
This commit is contained in:
Mike Blumenkrantz 2025-05-08 15:05:25 -04:00
parent 3be2c47db2
commit 00aaef9f12
110 changed files with 0 additions and 39143 deletions

View file

@ -97,7 +97,6 @@ debian-testing:
-D glx=dri
-D platforms=x11,wayland
GALLIUM_ST: >
-D gallium-nine=false
-D gallium-rusticl=true
-D gallium-va=enabled
GALLIUM_DRIVERS: "llvmpipe,softpipe,virgl,radeonsi,zink,iris,svga"
@ -128,7 +127,6 @@ debian-testing-asan:
EXTRA_OPTION: >
-D b_sanitize=address
-D gallium-va=false
-D gallium-nine=false
-D gallium-rusticl=false
-D mesa-clc=system
-D tools=dlclose-skip
@ -142,7 +140,6 @@ debian-testing-asan:
-D build-tests=false
-D enable-glcpp-tests=false
-D gallium-rusticl=false
-D gallium-nine=false
-D gallium-drivers=
-D glx=disabled
-D install-mesa-clc=true
@ -228,7 +225,6 @@ debian-testing-ubsan:
-D mesa-clc=system
-D gallium-rusticl=false
-D gallium-va=false
-D gallium-nine=false
S3_ARTIFACT_NAME: ""
ARTIFACTS_DEBUG_SYMBOLS: 1
RUN_MESON_TESTS: "false" # just too slow
@ -265,7 +261,6 @@ debian-build-testing:
-D gallium-extra-hud=true
-D gallium-vdpau=enabled
-D gallium-va=enabled
-D gallium-nine=true
-D gallium-rusticl=false
GALLIUM_DRIVERS: "i915,iris,nouveau,r300,r600,freedreno,llvmpipe,softpipe,svga,v3d,vc4,virgl,etnaviv,panfrost,lima,zink,d3d12,asahi,crocus"
VULKAN_DRIVERS: "intel_hasvk,imagination-experimental,microsoft-experimental,nouveau,swrast"
@ -298,7 +293,6 @@ debian-release:
-D gallium-extra-hud=true
-D gallium-vdpau=enabled
-D gallium-va=enabled
-D gallium-nine=false
-D gallium-rusticl=false
-D llvm=enabled
GALLIUM_DRIVERS: "i915,iris,nouveau,r300,freedreno,llvmpipe,softpipe,svga,v3d,vc4,virgl,etnaviv,panfrost,lima,zink,d3d12,asahi,crocus"
@ -339,7 +333,6 @@ alpine-build-testing:
-D gallium-extra-hud=true
-D gallium-vdpau=disabled
-D gallium-va=enabled
-D gallium-nine=true
-D gallium-rusticl=false
-D gles1=disabled
-D gles2=enabled
@ -390,7 +383,6 @@ fedora-release:
-D gallium-extra-hud=true
-D gallium-vdpau=enabled
-D gallium-va=enabled
-D gallium-nine=false
-D gallium-rusticl=true
-D gles1=disabled
-D gles2=enabled
@ -441,7 +433,6 @@ debian-android:
GALLIUM_ST: >
-D gallium-vdpau=disabled
-D gallium-va=disabled
-D gallium-nine=false
-D gallium-rusticl=false
PKG_CONFIG_LIBDIR: "/disable/non/android/system/pc/files"
HOST_BUILD_OPTIONS: >
@ -493,7 +484,6 @@ debian-android:
GALLIUM_ST: >
-D gallium-vdpau=disabled
-D gallium-va=disabled
-D gallium-nine=false
.meson-arm:
extends:
@ -707,7 +697,6 @@ debian-clang:
-D gallium-extra-hud=true
-D gallium-vdpau=enabled
-D gallium-va=enabled
-D gallium-nine=true
-D gles1=enabled
-D gles2=enabled
-D llvm=enabled
@ -757,7 +746,6 @@ debian-clang-release:
-D gallium-extra-hud=true
-D gallium-vdpau=enabled
-D gallium-va=enabled
-D gallium-nine=true
-D gles1=disabled
-D gles2=disabled
-D llvm=enabled
@ -796,7 +784,6 @@ debian-vulkan:
GALLIUM_ST: >
-D gallium-vdpau=disabled
-D gallium-va=disabled
-D gallium-nine=false
-D gallium-rusticl=false
-D b_sanitize=undefined
-D c_args=-fno-sanitize-recover=all

View file

@ -1,29 +0,0 @@
#!/usr/bin/env bash
# When changing this file, you need to bump the following
# .gitlab-ci/image-tags.yml tags:
# DEBIAN_TEST_GL_TAG
set -ex -o pipefail
uncollapsed_section_start ninetests "Building Nine tests"
### Careful editing anything below this line
git config --global user.email "mesa@example.com"
git config --global user.name "Mesa CI"
git clone https://github.com/axeldavy/Xnine.git /Xnine
mkdir /Xnine/build
pushd /Xnine/build
git checkout c64753d224c08006bcdcfa7880ada826f27164b1
cmake .. -DBUILD_TESTS=1 -DWITH_DRI3=1 -DD3DADAPTER9_LOCATION=/install/lib/d3d/d3dadapter9.so
make
mkdir -p /NineTests/
mv NineTests/NineTests /NineTests/
popd
rm -rf /Xnine
section_end ninetests

View file

@ -31,7 +31,6 @@ EPHEMERAL=(
libgl-dev
libgles2-mesa-dev
libglu1-mesa-dev
libgtest-dev
libglx-dev
libpciaccess-dev
libpng-dev
@ -40,9 +39,6 @@ EPHEMERAL=(
libwayland-dev
libx11-xcb-dev
libxcb-dri2-0-dev
libxcb-dri3-dev
libxcb-present-dev
libxfixes-dev
libxkbcommon-dev
libxrandr-dev
libxrender-dev
@ -126,10 +122,6 @@ if [ "$DEBIAN_ARCH" != "armhf" ]; then
. .gitlab-ci/container/build-skqp.sh
fi
############### Build nine tests
. .gitlab-ci/container/build-ninetests.sh
############### Uninstall the build software
uncollapsed_section_switch debian_cleanup "Cleaning up base Debian system"

View file

@ -1,47 +0,0 @@
Gallium Nine
============
The Gallium frontend, which implements Direct3D 9.
Nine implements the full IDirect3DDevice9 COM interface and a custom COM interface called ID3DAdapter9, which is used to implement the final IDirect3D9Ex COM interface.
ID3DAdapter9 is completely agnostic regarding the window system code, meaning this can be provided by wine, Xlib, Wayland, etc.
Gallium Nine is commonly used in conjunction with `Wine <https://www.winehq.org/>`__.
`Gallium Nine Standalone <https://github.com/iXit/wine-nine-standalone>`__ is the standalone version of the Wine parts of Gallium Nine which makes it possible to use it with any stock Wine version. It's simple to install through `Winetricks <https://github.com/Winetricks/winetricks>`__ with ``winetricks galliumnine``.
Aside from Wine, Gallium Nine works well with `Box86 <https://ptitseb.github.io/box86/>`__.
Can be used via `Zink <https://www.supergoodcode.com/to-the-nines/>`__ even on the `Vulkan API <https://en.wikipedia.org/wiki/Vulkan>`__.
In the majority of cases this implementation has better performance than Wine doing the translation from D3D9 to OpenGL itself.
It's also possible to use D3D9 directly from the Linux environment. For tests, demos, and more details, you can see `this repository <https://github.com/iXit/nine-tests>`__.
Build
-----
Beware: Most Direct3D games are 32-bit, and thus need a 32-bit version of Mesa.
.. code-block:: sh
$ meson configure \
-D gallium-nine=true \
...
Paths
-----
You need to point wine-nine-standalone to the location of ``d3dadapter9.so``.
If you use distribution packaged Mesa, it should work out of the box.
There are three options (sorted from permanent to temporary):
- compile Wine Nine Standalone with ``D3D9NINE_MODULEPATH`` pointing to your local library
- set ModulePath of Software\Wine\Direct3DNine in the wine registers
- ``$ D3D_MODULE_PATH="$MESA_INSTALLDIR/lib/d3d/d3dadapter9.so" wine ...``
Run
---
Before running your application in Wine, verify that everything works as expected by running:
.. code-block:: sh
$ wine ninewinecfg

View file

@ -71,7 +71,6 @@ Linux, FreeBSD, and other operating systems.
gpu-perf-tracing
extensions
application-issues
gallium-nine
viewperf
xlibdriver
teflon

View file

@ -137,7 +137,6 @@ each directory.
- **glx** - Meta frontend for GLX
- **hgl** - Haiku OpenGL
- **lavapipe** - Vulkan frontend, software Vulkan rasterizer using LLVMpipe.
- **nine** - D3D9 frontend, see targets/d3dadapter9
- **va** - VA-API frontend
- **vdpau** - VDPAU frontend
- **wgl** - Windows WGL frontend

View file

@ -1,3 +0,0 @@
[*.h]
indent_style = space
indent_size = 4

View file

@ -1,101 +0,0 @@
/*
* 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_ */

View file

@ -1,51 +0,0 @@
/*
* 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 2
/* version 0.0: Initial release
* 0.1: All IDirect3D objects can be assumed to have a pointer to the
* internal vtable in second position of the structure
* 0.2: IDirect3DDevice9_SetCursorPosition always calls
* ID3DPresent_SetCursorPos for hardware cursors
*/
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

@ -1,173 +0,0 @@
/*
* 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;
/* Available since version 1.3 */
typedef struct _D3DPRESENT_PARAMETERS2_ {
/* Whether D3DSWAPEFFECT_DISCARD is allowed to release the
* D3DWindowBuffers in any order, and eventually with a delay.
* FALSE (Default): buffers should be released as soon as possible.
* TRUE: it is allowed to release some buffers with a delay, and in
* a random order. */
BOOL AllowDISCARDDelayedRelease;
/* User preference for D3DSWAPEFFECT_DISCARD with D3DPRESENT_INTERVAL_IMMEDIATE.
* FALSE (Default): User prefers presentation to occur as soon as possible,
* with potential tearings.
* TRUE: User prefers presentation to be tear free. Requires
* AllowDISCARDDelayedRelease to have any effect. */
BOOL TearFreeDISCARD;
} D3DPRESENT_PARAMETERS2, *PD3DPRESENT_PARAMETERS2, *LPD3DPRESENT_PARAMETERS2;
/* 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.
* Note: This function waits as well that the buffer content was displayed (this
* can be after the release of the buffer if the window system decided to make
* an internal copy and release early. */
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);
/* Available since version 1.1 */
BOOL (WINAPI *GetWindowOccluded)(ID3DPresent *This);
/* Available since version 1.2 */
BOOL (WINAPI *ResolutionMismatch)(ID3DPresent *This);
HANDLE (WINAPI *CreateThread)(ID3DPresent *This, void *pThreadfunc, void *pParam);
BOOL (WINAPI *WaitForThread)(ID3DPresent *This, HANDLE thread);
/* Available since version 1.3 */
HRESULT (WINAPI *SetPresentParameters2)(ID3DPresent *This, D3DPRESENT_PARAMETERS2 *pParameters);
BOOL (WINAPI *IsBufferReleased)(ID3DPresent *This, D3DWindowBuffer *buffer);
/* Wait a buffer gets released. */
HRESULT (WINAPI *WaitBufferReleaseEvent)(ID3DPresent *This);
} 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->GetWindowInfo(p,a,b,c,d)
#define ID3DPresent_GetWindowOccluded(p) (p)->lpVtbl->GetWindowOccluded(p)
#define ID3DPresent_ResolutionMismatch(p) (p)->lpVtbl->ResolutionMismatch(p)
#define ID3DPresent_CreateThread(p,a,b) (p)->lpVtbl->CreateThread(p,a,b)
#define ID3DPresent_WaitForThread(p,a) (p)->lpVtbl->WaitForThread(p,a)
#define ID3DPresent_SetPresentParameters2(p,a) (p)->lpVtbl->SetPresentParameters2(p,a)
#define ID3DPresent_IsBufferReleased(p,a) (p)->lpVtbl->IsBufferReleased(p,a)
#define ID3DPresent_WaitBufferReleaseEvent(p) (p)->lpVtbl->WaitBufferReleaseEvent(p)
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

@ -83,13 +83,6 @@ if with_dri
install_headers('GL/internal/dri_interface.h', subdir : 'GL/internal')
endif
if with_gallium_st_nine
install_headers(
'd3dadapter/d3dadapter9.h', 'd3dadapter/drm.h', 'd3dadapter/present.h',
subdir : 'd3dadapter',
)
endif
opencl_headers = files(
'CL/cl.h',
'CL/cl.hpp',

View file

@ -716,27 +716,6 @@ if d3d_drivers_path == ''
d3d_drivers_path = join_paths(get_option('prefix'), get_option('libdir'), 'd3d')
endif
with_gallium_st_nine = get_option('gallium-nine')
if with_gallium_st_nine
warning('The nine state tracker will be removed in Mesa 25.2')
if not with_gallium_swrast
error('The nine state tracker requires gallium softpipe/llvmpipe.')
elif not [
with_gallium_crocus,
with_gallium_freedreno,
with_gallium_i915,
with_gallium_iris,
with_gallium_nouveau,
with_gallium_panfrost,
with_gallium_r300,
with_gallium_r600,
with_gallium_radeonsi,
with_gallium_svga,
with_gallium_zink,
].contains(true)
error('The nine state tracker requires at least one non-swrast gallium driver.')
endif
endif
with_gallium_st_d3d10umd = get_option('gallium-d3d10umd')
if with_gallium_st_d3d10umd
if not with_gallium_swrast
@ -2419,9 +2398,6 @@ if with_gallium
if with_gallium_mediafoundation
gallium_frontends += 'mediafoundation'
endif
if with_gallium_st_nine
gallium_frontends += 'nine'
endif
if with_gallium_rusticl
gallium_frontends += 'rusticl'
endif

View file

@ -138,14 +138,6 @@ option(
description : 'path to put va libraries. defaults to $libdir/dri.'
)
option(
'gallium-nine',
type : 'boolean',
value : false,
description : 'build gallium "nine" Direct3D 9.x frontend.',
deprecated: true,
)
option(
'gallium-d3d10umd',
type : 'boolean',

View file

@ -84,7 +84,6 @@ with_nir_headers_only = (
with_gallium_va,
with_any_vk,
with_gallium_xa,
with_gallium_st_nine,
with_gallium_st_d3d10umd,
with_gallium_rusticl,
with_microsoft_clc,

View file

@ -27,20 +27,3 @@
*r300_file_list
when: manual
.r300-nine-rules:
stage: amd
rules:
- !reference [.test, rules]
- !reference [.r300-rules, rules]
- changes: &nine_file_list
- src/gallium/frontends/nine/*
when: on_success
.r300-nine-manual-rules:
stage: amd-nightly
extends: .no-auto-retry
rules:
- !reference [.test, rules]
- !reference [.r300-manual-rules, rules]
- changes: *nine_file_list
when: manual

View file

@ -36,17 +36,6 @@ r300-rv530-deqp-gles2:
# see https://gitlab.freedesktop.org/mesa/mesa/-/issues/8093
RADEON_DEBUG: nohiz
r300-rv530-nine:
extends:
- .ondracka-rv530
- .r300-nine-manual-rules
variables:
GTEST: "/NineTests/NineTests"
HWCI_TEST_SCRIPT: "/install/gtest-runner.sh"
HWCI_START_WESTON: 1
GPU_VERSION: r300-rv530-nohiz
FDO_CI_CONCURRENT: 1
r300-rv380-deqp-gles2:
extends:
- .ondracka-rv380

View file

@ -801,29 +801,7 @@ spec@oes_texture_float@oes_texture_float,Fail
spec@oes_texture_float@oes_texture_float half,Fail
# Xnine tests
Xnine.clip_planes,Fail
Xnine.depth_clamp,Fail
Xnine.depthbias,Fail
Xnine.dsy,Fail
Xnine.fp_special,Fail
Xnine.fragment_coords,Fail
Xnine.mvp_software_vertex_shaders,Fail
Xnine.negative_fixedfunction_fog,Fail
Xnine.pixelshader_blending,Fail
Xnine.pretransformed_varying,Fail
Xnine.srgbwrite_format,Fail
Xnine.stream,Fail
Xnine.texture_transform_flags,Fail
Xnine.zenable,Fail
# https://gitlab.freedesktop.org/mesa/mesa/-/issues/10557
Xnine.drawindexedprimitiveup,Crash
Xnine.fog,Crash
Xnine.lighting,Crash
Xnine.specular_lighting,Crash
Xnine.stencil_cull,Crash
dEQP-GLES2.functional.texture.mipmap.2d.projected.nearest_nearest_mirror,Fail
dEQP-GLES2.functional.texture.mipmap.2d.projected.nearest_nearest_repeat,Fail
dEQP-GLES2.functional.texture.mipmap.2d.projected.nearest_nearest_clamp,Fail

View file

@ -1,3 +0,0 @@
[*.{c,h}]
indent_style = space
indent_size = 4

File diff suppressed because it is too large Load diff

View file

@ -1,130 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#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;
int vblank_mode;
BOOL thread_submit;
BOOL discard_delayed_release;
BOOL tearfree_discard;
int csmt_force;
BOOL dynamic_texture_workaround;
BOOL shader_inline_constants;
int memfd_virtualsizelimit;
int override_vram_size;
BOOL force_emulation;
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 NINE_WINAPI
NineAdapter9_GetAdapterIdentifier( struct NineAdapter9 *This,
DWORD Flags,
D3DADAPTER_IDENTIFIER9 *pIdentifier );
HRESULT NINE_WINAPI
NineAdapter9_CheckDeviceType( struct NineAdapter9 *This,
D3DDEVTYPE DevType,
D3DFORMAT AdapterFormat,
D3DFORMAT BackBufferFormat,
BOOL bWindowed );
HRESULT NINE_WINAPI
NineAdapter9_CheckDeviceFormat( struct NineAdapter9 *This,
D3DDEVTYPE DeviceType,
D3DFORMAT AdapterFormat,
DWORD Usage,
D3DRESOURCETYPE RType,
D3DFORMAT CheckFormat );
HRESULT NINE_WINAPI
NineAdapter9_CheckDeviceMultiSampleType( struct NineAdapter9 *This,
D3DDEVTYPE DeviceType,
D3DFORMAT SurfaceFormat,
BOOL Windowed,
D3DMULTISAMPLE_TYPE MultiSampleType,
DWORD *pQualityLevels );
HRESULT NINE_WINAPI
NineAdapter9_CheckDepthStencilMatch( struct NineAdapter9 *This,
D3DDEVTYPE DeviceType,
D3DFORMAT AdapterFormat,
D3DFORMAT RenderTargetFormat,
D3DFORMAT DepthStencilFormat );
HRESULT NINE_WINAPI
NineAdapter9_CheckDeviceFormatConversion( struct NineAdapter9 *This,
D3DDEVTYPE DeviceType,
D3DFORMAT SourceFormat,
D3DFORMAT TargetFormat );
HRESULT NINE_WINAPI
NineAdapter9_GetDeviceCaps( struct NineAdapter9 *This,
D3DDEVTYPE DeviceType,
D3DCAPS9 *pCaps );
HRESULT NINE_WINAPI
NineAdapter9_CreateDevice( struct NineAdapter9 *This,
UINT RealAdapter,
D3DDEVTYPE DeviceType,
HWND hFocusWindow,
DWORD BehaviorFlags,
D3DPRESENT_PARAMETERS *pPresentationParameters,
IDirect3D9 *pD3D9,
ID3DPresentGroup *pPresentationGroup,
IDirect3DDevice9 **ppReturnedDeviceInterface );
HRESULT NINE_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

@ -1,61 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#include "authenticatedchannel9.h"
#define DBG_CHANNEL DBG_AUTHENTICATEDCHANNEL
HRESULT NINE_WINAPI
NineAuthenticatedChannel9_GetCertificateSize( struct NineAuthenticatedChannel9 *This,
UINT *pCertificateSize )
{
STUB(D3DERR_INVALIDCALL);
}
HRESULT NINE_WINAPI
NineAuthenticatedChannel9_GetCertificate( struct NineAuthenticatedChannel9 *This,
UINT CertifacteSize,
BYTE *ppCertificate )
{
STUB(D3DERR_INVALIDCALL);
}
HRESULT NINE_WINAPI
NineAuthenticatedChannel9_NegotiateKeyExchange( struct NineAuthenticatedChannel9 *This,
UINT DataSize,
void *pData )
{
STUB(D3DERR_INVALIDCALL);
}
HRESULT NINE_WINAPI
NineAuthenticatedChannel9_Query( struct NineAuthenticatedChannel9 *This,
UINT InputSize,
const void *pInput,
UINT OutputSize,
void *pOutput )
{
STUB(D3DERR_INVALIDCALL);
}
HRESULT NINE_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

@ -1,48 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#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 NINE_WINAPI
NineAuthenticatedChannel9_GetCertificateSize( struct NineAuthenticatedChannel9 *This,
UINT *pCertificateSize );
HRESULT NINE_WINAPI
NineAuthenticatedChannel9_GetCertificate( struct NineAuthenticatedChannel9 *This,
UINT CertifacteSize,
BYTE *ppCertificate );
HRESULT NINE_WINAPI
NineAuthenticatedChannel9_NegotiateKeyExchange( struct NineAuthenticatedChannel9 *This,
UINT DataSize,
void *pData );
HRESULT NINE_WINAPI
NineAuthenticatedChannel9_Query( struct NineAuthenticatedChannel9 *This,
UINT InputSize,
const void *pInput,
UINT OutputSize,
void *pOutput );
HRESULT NINE_WINAPI
NineAuthenticatedChannel9_Configure( struct NineAuthenticatedChannel9 *This,
UINT InputSize,
const void *pInput,
D3DAUTHENTICATEDCHANNEL_CONFIGURE_OUTPUT *pOutput );
#endif /* _NINE_AUTHENTICATEDCHANNEL9_H_ */

View file

@ -1,612 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#include "basetexture9.h"
#include "device9.h"
/* For UploadSelf: */
#include "texture9.h"
#include "cubetexture9.h"
#include "volumetexture9.h"
#include "nine_pipe.h"
#if MESA_DEBUG || !defined(NDEBUG)
#include "nine_dump.h"
#endif
#include "util/format/u_format.h"
#define DBG_CHANNEL DBG_BASETEXTURE
HRESULT
NineBaseTexture9_ctor( struct NineBaseTexture9 *This,
struct NineUnknownParams *pParams,
struct pipe_resource *initResource,
D3DRESOURCETYPE Type,
D3DFORMAT format,
D3DPOOL Pool,
DWORD Usage)
{
BOOL alloc = (Pool == D3DPOOL_DEFAULT) && !initResource &&
(format != D3DFMT_NULL);
HRESULT hr;
DBG("This=%p, pParams=%p initResource=%p Type=%d format=%d Pool=%d Usage=%d\n",
This, pParams, initResource, Type, format, Pool, Usage);
user_assert(!(Usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) ||
Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL);
user_assert(!(Usage & D3DUSAGE_DYNAMIC) ||
!(Pool == D3DPOOL_MANAGED ||
Pool == D3DPOOL_SCRATCH), D3DERR_INVALIDCALL);
hr = NineResource9_ctor(&This->base, pParams, initResource, alloc, Type, Pool, Usage);
if (FAILED(hr))
return hr;
This->format = format;
This->mipfilter = (Usage & D3DUSAGE_AUTOGENMIPMAP) ?
D3DTEXF_LINEAR : D3DTEXF_NONE;
/* In the case of D3DUSAGE_AUTOGENMIPMAP, only the first level is accessible,
* and thus needs a surface created. */
This->level_count = (Usage & D3DUSAGE_AUTOGENMIPMAP) ? 1 : (This->base.info.last_level+1);
This->managed.lod = 0;
This->managed.lod_resident = -1;
/* Mark the texture as dirty to trigger first upload when we need the texture,
* even if it wasn't set by the application */
if (Pool == D3DPOOL_MANAGED)
This->managed.dirty = true;
/* When a depth buffer is sampled, it is for shadow mapping, except for
* D3DFMT_INTZ, D3DFMT_DF16 and D3DFMT_DF24.
* In addition D3DFMT_INTZ can be used for both texturing and depth buffering
* if z write is disabled. This particular feature may not work for us in
* practice because OGL doesn't have that. However apparently it is known
* some cards have performance issues with this feature, so real apps
* shouldn't use it. */
This->shadow = (This->format != D3DFMT_INTZ && This->format != D3DFMT_DF16 &&
This->format != D3DFMT_DF24) &&
util_format_has_depth(util_format_description(This->base.info.format));
This->fetch4_compatible = fetch4_compatible_format(This->format);
list_inithead(&This->list);
list_inithead(&This->list2);
if (Pool == D3DPOOL_MANAGED)
list_add(&This->list2, &This->base.base.device->managed_textures);
return D3D_OK;
}
void
NineBaseTexture9_dtor( struct NineBaseTexture9 *This )
{
DBG("This=%p\n", This);
nine_context_get_pipe_acquire(This->base.base.device);
pipe_sampler_view_release_ptr(&This->view[0]);
pipe_sampler_view_release_ptr(&This->view[1]);
nine_context_get_pipe_release(This->base.base.device);
if (list_is_linked(&This->list))
list_del(&This->list);
if (list_is_linked(&This->list2))
list_del(&This->list2);
NineResource9_dtor(&This->base);
}
DWORD NINE_WINAPI
NineBaseTexture9_SetLOD( struct NineBaseTexture9 *This,
DWORD LODNew )
{
DWORD old = This->managed.lod;
DBG("This=%p LODNew=%d\n", This, LODNew);
user_assert(This->base.pool == D3DPOOL_MANAGED, 0);
This->managed.lod = MIN2(LODNew, This->level_count-1);
if (This->managed.lod != old && This->bind_count && list_is_empty(&This->list))
list_add(&This->list, &This->base.base.device->update_textures);
return old;
}
DWORD NINE_WINAPI
NineBaseTexture9_GetLOD( struct NineBaseTexture9 *This )
{
DBG("This=%p\n", This);
return This->managed.lod;
}
DWORD NINE_WINAPI
NineBaseTexture9_GetLevelCount( struct NineBaseTexture9 *This )
{
DBG("This=%p\n", This);
return This->level_count;
}
HRESULT NINE_WINAPI
NineBaseTexture9_SetAutoGenFilterType( struct NineBaseTexture9 *This,
D3DTEXTUREFILTERTYPE FilterType )
{
DBG("This=%p FilterType=%d\n", This, FilterType);
if (!(This->base.usage & D3DUSAGE_AUTOGENMIPMAP))
return D3D_OK;
user_assert(FilterType != D3DTEXF_NONE, D3DERR_INVALIDCALL);
This->mipfilter = FilterType;
This->dirty_mip = true;
NineBaseTexture9_GenerateMipSubLevels(This);
return D3D_OK;
}
D3DTEXTUREFILTERTYPE NINE_WINAPI
NineBaseTexture9_GetAutoGenFilterType( struct NineBaseTexture9 *This )
{
DBG("This=%p\n", This);
return This->mipfilter;
}
HRESULT
NineBaseTexture9_UploadSelf( struct NineBaseTexture9 *This )
{
HRESULT hr;
unsigned l, min_level_dirty = This->managed.lod;
BOOL update_lod;
DBG("This=%p dirty=%i type=%s\n", This, This->managed.dirty,
nine_D3DRTYPE_to_str(This->base.type));
assert(This->base.pool == D3DPOOL_MANAGED);
update_lod = This->managed.lod_resident != This->managed.lod;
if (!update_lod && !This->managed.dirty)
return D3D_OK;
/* Allocate a new resource with the correct number of levels,
* Mark states for update, and tell the nine surfaces/volumes
* their new resource. */
if (update_lod) {
struct pipe_resource *res;
DBG("updating LOD from %u to %u ...\n", This->managed.lod_resident, This->managed.lod);
nine_context_get_pipe_acquire(This->base.base.device);
pipe_sampler_view_release_ptr(&This->view[0]);
pipe_sampler_view_release_ptr(&This->view[1]);
nine_context_get_pipe_release(This->base.base.device);
/* Allocate a new resource */
hr = NineBaseTexture9_CreatePipeResource(This, This->managed.lod_resident != -1);
if (FAILED(hr))
return hr;
res = This->base.resource;
if (This->managed.lod_resident == -1) {/* no levels were resident */
This->managed.dirty = false; /* We are going to upload everything. */
This->managed.lod_resident = This->level_count;
}
if (This->base.type == D3DRTYPE_TEXTURE) {
struct NineTexture9 *tex = NineTexture9(This);
/* last content (if apply) has been copied to the new resource.
* Note: We cannot render to surfaces of managed textures.
* Note2: the level argument passed is to get the level offset
* right when the texture is uploaded (the texture first level
* corresponds to This->managed.lod).
* Note3: We don't care about the value passed for the surfaces
* before This->managed.lod, negative with this implementation. */
for (l = 0; l < This->level_count; ++l)
NineSurface9_SetResource(tex->surfaces[l], res, l - This->managed.lod);
} else
if (This->base.type == D3DRTYPE_CUBETEXTURE) {
struct NineCubeTexture9 *tex = NineCubeTexture9(This);
unsigned z;
for (l = 0; l < This->level_count; ++l) {
for (z = 0; z < 6; ++z)
NineSurface9_SetResource(tex->surfaces[l * 6 + z],
res, l - This->managed.lod);
}
} else
if (This->base.type == D3DRTYPE_VOLUMETEXTURE) {
struct NineVolumeTexture9 *tex = NineVolumeTexture9(This);
for (l = 0; l < This->level_count; ++l)
NineVolume9_SetResource(tex->volumes[l], res, l - This->managed.lod);
} else {
assert(!"invalid texture type");
}
/* We are going to fully upload the new levels,
* no need to update dirty parts of the texture for these */
min_level_dirty = MAX2(This->managed.lod, This->managed.lod_resident);
}
/* Update dirty parts of the texture */
if (This->managed.dirty) {
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);
/* Note: for l < min_level_dirty, the resource is
* either non-existing (and thus will be entirely re-uploaded
* if the lod changes) or going to have a full upload */
if (tex->dirty_rect.width) {
for (l = min_level_dirty; l < This->level_count; ++l) {
u_box_minify_2d(&box, &tex->dirty_rect, l);
NineSurface9_UploadSelf(tex->surfaces[l], &box);
}
memset(&tex->dirty_rect, 0, sizeof(tex->dirty_rect));
tex->dirty_rect.depth = 1;
}
} 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 = min_level_dirty; l < This->level_count; ++l) {
u_box_minify_2d(&box, &tex->dirty_rect[z], l);
NineSurface9_UploadSelf(tex->surfaces[l * 6 + z], &box);
}
memset(&tex->dirty_rect[z], 0, sizeof(tex->dirty_rect[z]));
tex->dirty_rect[z].depth = 1;
}
}
} 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 = min_level_dirty; l < This->level_count; ++l) {
u_box_minify_3d(&box, &tex->dirty_box, l);
NineVolume9_UploadSelf(tex->volumes[l], &box);
}
memset(&tex->dirty_box, 0, sizeof(tex->dirty_box));
}
} else {
assert(!"invalid texture type");
}
This->managed.dirty = false;
}
/* Upload the new levels */
if (update_lod) {
if (This->base.type == D3DRTYPE_TEXTURE) {
struct NineTexture9 *tex = NineTexture9(This);
struct pipe_box box;
box.x = box.y = box.z = 0;
box.depth = 1;
for (l = This->managed.lod; l < This->managed.lod_resident; ++l) {
box.width = u_minify(This->base.info.width0, l);
box.height = u_minify(This->base.info.height0, l);
NineSurface9_UploadSelf(tex->surfaces[l], &box);
}
} else
if (This->base.type == D3DRTYPE_CUBETEXTURE) {
struct NineCubeTexture9 *tex = NineCubeTexture9(This);
struct pipe_box box;
unsigned z;
box.x = box.y = box.z = 0;
box.depth = 1;
for (l = This->managed.lod; l < This->managed.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_UploadSelf(tex->surfaces[l * 6 + z], &box);
}
} else
if (This->base.type == D3DRTYPE_VOLUMETEXTURE) {
struct NineVolumeTexture9 *tex = NineVolumeTexture9(This);
struct pipe_box box;
box.x = box.y = box.z = 0;
for (l = This->managed.lod; l < This->managed.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_UploadSelf(tex->volumes[l], &box);
}
} else {
assert(!"invalid texture type");
}
This->managed.lod_resident = This->managed.lod;
}
if (This->base.usage & D3DUSAGE_AUTOGENMIPMAP)
This->dirty_mip = true;
/* Set again the textures currently bound to update the texture data */
if (This->bind_count) {
struct nine_state *state = &This->base.base.device->state;
unsigned s;
for (s = 0; s < NINE_MAX_SAMPLERS; ++s)
/* Dirty tracking is done in device9 state, not nine_context. */
if (state->texture[s] == This)
nine_context_set_texture(This->base.base.device, s, This);
}
DBG("DONE, generate mip maps = %i\n", This->dirty_mip);
return D3D_OK;
}
void NINE_WINAPI
NineBaseTexture9_GenerateMipSubLevels( struct NineBaseTexture9 *This )
{
unsigned base_level = 0;
unsigned last_level = This->base.info.last_level - This->managed.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->managed.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);
nine_context_gen_mipmap(This->base.base.device, (struct NineUnknown *)This,
This->base.resource,
base_level, last_level,
first_layer, last_layer, filter);
This->dirty_mip = false;
}
HRESULT
NineBaseTexture9_CreatePipeResource( struct NineBaseTexture9 *This,
BOOL CopyData )
{
struct pipe_context *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->managed.lod, This->base.info.last_level);
assert(This->base.pool == D3DPOOL_MANAGED);
templ = This->base.info;
if (This->managed.lod) {
templ.width0 = u_minify(templ.width0, This->managed.lod);
templ.height0 = u_minify(templ.height0, This->managed.lod);
templ.depth0 = u_minify(templ.depth0, This->managed.lod);
}
templ.last_level = This->base.info.last_level - This->managed.lod;
if (old) {
/* LOD might have changed. */
if (old->width0 == templ.width0 &&
old->height0 == templ.height0 &&
old->depth0 == templ.depth0)
return D3D_OK;
}
res = nine_resource_create_with_retry(This->base.base.device, 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->managed.lod < This->managed.lod_resident) ? This->managed.lod_resident - This->managed.lod : 0;
m = (This->managed.lod < This->managed.lod_resident) ? 0 : This->managed.lod - This->managed.lod_resident;
box.width = u_minify(templ.width0, l);
box.height = u_minify(templ.height0, l);
box.depth = u_minify(templ.depth0, l);
pipe = nine_context_get_pipe_acquire(This->base.base.device);
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);
}
nine_context_get_pipe_release(This->base.base.device);
}
pipe_resource_reference(&old, NULL);
return D3D_OK;
}
#define SWIZZLE_TO_REPLACE(s) (s == PIPE_SWIZZLE_0 || \
s == PIPE_SWIZZLE_1 || \
s == PIPE_SWIZZLE_NONE)
HRESULT
NineBaseTexture9_UpdateSamplerView( struct NineBaseTexture9 *This,
const int sRGB )
{
const struct util_format_description *desc;
struct pipe_context *pipe;
struct pipe_screen *screen = NineDevice9_GetScreen(This->base.base.device);
struct pipe_resource *resource = This->base.resource;
struct pipe_sampler_view templ;
enum pipe_format srgb_format;
unsigned i;
uint8_t swizzle[4];
memset(&templ, 0, sizeof(templ));
DBG("This=%p sRGB=%d\n", This, sRGB);
if (unlikely(!resource)) {
if (unlikely(This->format == D3DFMT_NULL))
return D3D_OK;
NineBaseTexture9_Dump(This);
}
assert(resource);
pipe = nine_context_get_pipe_acquire(This->base.base.device);
pipe->sampler_view_release(pipe, This->view[sRGB]);
This->view[sRGB] = NULL;
nine_context_get_pipe_release(This->base.base.device);
swizzle[0] = PIPE_SWIZZLE_X;
swizzle[1] = PIPE_SWIZZLE_Y;
swizzle[2] = PIPE_SWIZZLE_Z;
swizzle[3] = PIPE_SWIZZLE_W;
desc = util_format_description(resource->format);
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
/* msdn doc is incomplete here and wrong.
* The only formats that can be read directly here
* are DF16, DF24 and INTZ.
* Tested on win the swizzle is
* R = depth, G = B = 0, A = 1 for DF16 and DF24
* R = G = B = A = depth for INTZ
* For the other ZS formats that can't be read directly
* but can be used as shadow map, the result is duplicated on
* all channel */
if (This->format == D3DFMT_DF16 ||
This->format == D3DFMT_DF24) {
swizzle[1] = PIPE_SWIZZLE_0;
swizzle[2] = PIPE_SWIZZLE_0;
swizzle[3] = PIPE_SWIZZLE_1;
} else {
swizzle[1] = PIPE_SWIZZLE_X;
swizzle[2] = PIPE_SWIZZLE_X;
swizzle[3] = PIPE_SWIZZLE_X;
}
} else if (resource->format == PIPE_FORMAT_RGTC2_UNORM) {
swizzle[0] = PIPE_SWIZZLE_Y;
swizzle[1] = PIPE_SWIZZLE_X;
swizzle[2] = PIPE_SWIZZLE_1;
swizzle[3] = PIPE_SWIZZLE_1;
} else if (resource->format != PIPE_FORMAT_A8_UNORM &&
resource->format != PIPE_FORMAT_RGTC1_UNORM) {
/* exceptions:
* A8 should have 0.0 as default values for RGB.
* ATI1/RGTC1 should be r 0 0 1 (tested on windows).
* It is already what gallium does. All the other ones
* should have 1.0 for non-defined values */
for (i = 0; i < 4; i++) {
if (SWIZZLE_TO_REPLACE(desc->swizzle[i]))
swizzle[i] = PIPE_SWIZZLE_1;
}
}
/* if requested and supported, convert to the sRGB format */
srgb_format = util_format_srgb(resource->format);
if (sRGB && srgb_format != PIPE_FORMAT_NONE &&
screen->is_format_supported(screen, srgb_format,
resource->target, 0, 0, resource->bind))
templ.format = srgb_format;
else
templ.format = resource->format;
templ.u.tex.first_layer = 0;
templ.u.tex.last_layer = resource->target == PIPE_TEXTURE_3D ?
0 : resource->array_size - 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;
pipe = nine_context_get_pipe_acquire(This->base.base.device);
This->view[sRGB] = pipe->create_sampler_view(pipe, resource, &templ);
nine_context_get_pipe_release(This->base.base.device);
DBG("sampler view = %p(resource = %p)\n", This->view[sRGB], resource);
return This->view[sRGB] ? D3D_OK : D3DERR_DRIVERINTERNALERROR;
}
void NINE_WINAPI
NineBaseTexture9_PreLoad( struct NineBaseTexture9 *This )
{
DBG("This=%p\n", This);
if (This->base.pool == D3DPOOL_MANAGED)
NineBaseTexture9_UploadSelf(This);
}
void
NineBaseTexture9_UnLoad( struct NineBaseTexture9 *This )
{
DBG("This=%p\n", This);
if (This->base.pool != D3DPOOL_MANAGED ||
This->managed.lod_resident == -1)
return;
DBG("This=%p, releasing resource\n", This);
pipe_resource_reference(&This->base.resource, NULL);
This->managed.lod_resident = -1;
This->managed.dirty = true;
/* If the texture is bound, we have to re-upload it */
BASETEX_REGISTER_UPDATE(This);
}
#if MESA_DEBUG || !defined(NDEBUG)
void
NineBaseTexture9_Dump( struct NineBaseTexture9 *This )
{
DBG("\nNineBaseTexture9(%p->NULL/%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,
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->managed.lod, This->managed.lod_resident);
}
#endif /* MESA_DEBUG || !NDEBUG */

View file

@ -1,156 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_BASETEXTURE9_H_
#define _NINE_BASETEXTURE9_H_
#include "device9.h"
#include "resource9.h"
#include "util/u_inlines.h"
#include "util/list.h"
struct NineBaseTexture9
{
struct NineResource9 base;
struct list_head list; /* for update_textures */
struct list_head list2; /* for managed_textures */
/* g3d */
struct pipe_sampler_view *view[2]; /* linear and sRGB */
D3DFORMAT format;
int16_t bind_count; /* to Device9->state.texture */
bool shadow;
bool fetch4_compatible;
uint8_t pstype; /* 0: 2D, 1: 1D, 2: CUBE, 3: 3D */
bool dirty_mip;
D3DTEXTUREFILTERTYPE mipfilter;
unsigned level_count;
/* Specific to managed textures */
struct {
bool dirty;
DWORD lod;
DWORD lod_resident;
} managed;
};
static inline struct NineBaseTexture9 *
NineBaseTexture9( void *data )
{
return (struct NineBaseTexture9 *)data;
}
HRESULT
NineBaseTexture9_ctor( struct NineBaseTexture9 *This,
struct NineUnknownParams *pParams,
struct pipe_resource *initResource,
D3DRESOURCETYPE Type,
D3DFORMAT format,
D3DPOOL Pool,
DWORD Usage);
void
NineBaseTexture9_dtor( struct NineBaseTexture9 *This );
DWORD NINE_WINAPI
NineBaseTexture9_SetLOD( struct NineBaseTexture9 *This,
DWORD LODNew );
DWORD NINE_WINAPI
NineBaseTexture9_GetLOD( struct NineBaseTexture9 *This );
DWORD NINE_WINAPI
NineBaseTexture9_GetLevelCount( struct NineBaseTexture9 *This );
HRESULT NINE_WINAPI
NineBaseTexture9_SetAutoGenFilterType( struct NineBaseTexture9 *This,
D3DTEXTUREFILTERTYPE FilterType );
D3DTEXTUREFILTERTYPE NINE_WINAPI
NineBaseTexture9_GetAutoGenFilterType( struct NineBaseTexture9 *This );
void NINE_WINAPI
NineBaseTexture9_GenerateMipSubLevels( struct NineBaseTexture9 *This );
void NINE_WINAPI
NineBaseTexture9_PreLoad( struct NineBaseTexture9 *This );
void
NineBaseTexture9_UnLoad( 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->managed.dirty, This->dirty_mip, This->managed.lod, This->managed.lod_resident);
if ((This->base.pool == D3DPOOL_MANAGED) &&
(This->managed.dirty || This->managed.lod != This->managed.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];
}
static void inline
NineBindTextureToDevice( struct NineDevice9 *device,
struct NineBaseTexture9 **slot,
struct NineBaseTexture9 *tex )
{
struct NineBaseTexture9 *old = *slot;
if (tex) {
if ((tex->managed.dirty | tex->dirty_mip) && list_is_empty(&tex->list))
list_add(&tex->list, &device->update_textures);
tex->bind_count++;
}
if (old) {
old->bind_count--;
if (!old->bind_count)
list_delinit(&old->list);
}
nine_bind(slot, tex);
}
#if MESA_DEBUG || !defined(NDEBUG)
void
NineBaseTexture9_Dump( struct NineBaseTexture9 *This );
#else
static inline void
NineBaseTexture9_Dump( struct NineBaseTexture9 *This ) { }
#endif
#define BASETEX_REGISTER_UPDATE(t) do { \
if (((t)->managed.dirty | ((t)->dirty_mip)) && (t)->bind_count) \
if (list_is_empty(&(t)->list)) \
list_add(&(t)->list, &(t)->base.base.device->update_textures); \
} while(0)
#endif /* _NINE_BASETEXTURE9_H_ */

View file

@ -1,699 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* Copyright 2015 Patrick Rudolph <siro@das-labor.org>
* SPDX-License-Identifier: MIT
*/
#include "buffer9.h"
#include "device9.h"
#include "indexbuffer9.h"
#include "nine_buffer_upload.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 "util/format/u_formats.h"
#include "util/box.h"
#include "util/u_inlines.h"
#define DBG_CHANNEL (DBG_INDEXBUFFER|DBG_VERTEXBUFFER)
HRESULT
NineBuffer9_ctor( struct NineBuffer9 *This,
struct NineUnknownParams *pParams,
D3DRESOURCETYPE Type,
DWORD Usage,
UINT Size,
D3DPOOL Pool )
{
struct pipe_resource *info = &This->base.info;
HRESULT hr;
DBG("This=%p Size=0x%x Usage=%x Pool=%u\n", This, Size, Usage, Pool);
user_assert(Pool != D3DPOOL_SCRATCH, D3DERR_INVALIDCALL);
This->maps = MALLOC(sizeof(struct NineTransfer));
if (!This->maps)
return E_OUTOFMEMORY;
This->nlocks = 0;
This->nmaps = 0;
This->maxmaps = 1;
This->size = Size;
info->screen = pParams->device->screen;
info->target = PIPE_BUFFER;
info->format = PIPE_FORMAT_R8_UNORM;
info->width0 = Size;
info->flags = 0;
/* Note: WRITEONLY is just tip for resource placement, the resource
* can still be read (but slower). */
info->bind = (Type == D3DRTYPE_INDEXBUFFER) ? PIPE_BIND_INDEX_BUFFER : PIPE_BIND_VERTEX_BUFFER;
/* Software vertex processing:
* If the device is full software vertex processing,
* then the buffer is supposed to be used only for sw processing.
* For mixed vertex processing, buffers with D3DUSAGE_SOFTWAREPROCESSING
* can be used for both sw and hw processing.
* These buffers are expected to be stored in RAM.
* Apps expect locking the full buffer with no flags, then
* render a a few primitive, then locking again, etc
* to be a fast pattern. Only the SYSTEMMEM DYNAMIC path
* will give that pattern ok performance in our case.
* An alternative would be when sw processing is detected to
* convert Draw* calls to Draw*Up calls. */
if (Usage & D3DUSAGE_SOFTWAREPROCESSING ||
pParams->device->params.BehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) {
Pool = D3DPOOL_SYSTEMMEM;
Usage |= D3DUSAGE_DYNAMIC;
/* Note: the application cannot retrieve Pool and Usage */
}
/* Always use the DYNAMIC path for SYSTEMMEM.
* If the app uses the vertex buffer is a dynamic fashion,
* this is going to be very significantly faster that way.
* If the app uses the vertex buffer in a static fashion,
* instead of being filled all at once, the buffer will be filled
* little per little, until it is fully filled, thus the perf hit
* will be very small. */
if (Pool == D3DPOOL_SYSTEMMEM)
Usage |= D3DUSAGE_DYNAMIC;
/* It is hard to find clear information on where to place the buffer in
* memory depending on the flag.
* MSDN: resources are static, except for those with DYNAMIC, thus why you
* can only use DISCARD on them.
* ATI doc: The driver has the liberty it wants for having things static
* or not.
* MANAGED: Ram + uploads to Vram copy at unlock (msdn and nvidia doc say
* at first draw call using the buffer)
* DEFAULT + Usage = 0 => System memory backing for easy read access
* (That doc is very unclear on the details, like whether some copies to
* vram copy are involved or not).
* DEFAULT + WRITEONLY => Vram
* DEFAULT + WRITEONLY + DYNAMIC => Either Vram buffer or GTT_WC, depending on what the driver wants.
* SYSTEMMEM: Same as MANAGED, but handled by the driver instead of the runtime (which means
* some small behavior differences between vendors). Implementing exactly as MANAGED should
* be fine.
*/
if (Pool == D3DPOOL_SYSTEMMEM && Usage & D3DUSAGE_DYNAMIC)
info->usage = PIPE_USAGE_STREAM;
else if (Pool != D3DPOOL_DEFAULT)
info->usage = PIPE_USAGE_DEFAULT;
else if (Usage & D3DUSAGE_DYNAMIC && Usage & D3DUSAGE_WRITEONLY)
info->usage = PIPE_USAGE_STREAM;
else if (Usage & D3DUSAGE_WRITEONLY)
info->usage = PIPE_USAGE_DEFAULT;
/* For the remaining two, PIPE_USAGE_STAGING would probably be
* a good fit according to the doc. However it seems rather a mistake
* from apps to use these (mistakes that do really happen). Try
* to put the flags that are the best compromise between the real
* behaviour and what buggy apps should get for better performance. */
else if (Usage & D3DUSAGE_DYNAMIC)
info->usage = PIPE_USAGE_STREAM;
else
info->usage = PIPE_USAGE_DYNAMIC;
/* When Writeonly is not set, we don't want to enable the
* optimizations */
This->discard_nooverwrite_only = !!(Usage & D3DUSAGE_WRITEONLY) &&
pParams->device->buffer_upload;
/* 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_TEXTAPI) { } */
info->height0 = 1;
info->depth0 = 1;
info->array_size = 1;
info->last_level = 0;
info->nr_samples = 0;
info->nr_storage_samples = 0;
hr = NineResource9_ctor(&This->base, pParams, NULL, true,
Type, Pool, Usage);
if (FAILED(hr))
return hr;
if (Pool != D3DPOOL_DEFAULT) {
This->managed.data = align_calloc(
nine_format_get_level_alloc_size(This->base.info.format,
Size, 1, 0), 32);
if (!This->managed.data)
return E_OUTOFMEMORY;
This->managed.dirty = true;
u_box_1d(0, Size, &This->managed.dirty_box);
u_box_1d(0, 0, &This->managed.valid_region);
u_box_1d(0, 0, &This->managed.required_valid_region);
u_box_1d(0, 0, &This->managed.filled_region);
This->managed.can_unsynchronized = true;
This->managed.num_worker_thread_syncs = 0;
list_inithead(&This->managed.list);
list_inithead(&This->managed.list2);
list_add(&This->managed.list2, &pParams->device->managed_buffers);
}
return D3D_OK;
}
void
NineBuffer9_dtor( struct NineBuffer9 *This )
{
DBG("This=%p\n", This);
if (This->maps) {
while (This->nlocks) {
NineBuffer9_Unlock(This);
}
assert(!This->nmaps);
FREE(This->maps);
}
if (This->base.pool != D3DPOOL_DEFAULT) {
if (This->managed.data)
align_free(This->managed.data);
if (list_is_linked(&This->managed.list))
list_del(&This->managed.list);
if (list_is_linked(&This->managed.list2))
list_del(&This->managed.list2);
}
if (This->buf)
nine_upload_release_buffer(This->base.base.device->buffer_upload, This->buf);
NineResource9_dtor(&This->base);
}
struct pipe_resource *
NineBuffer9_GetResource( struct NineBuffer9 *This, unsigned *offset )
{
if (This->buf)
return nine_upload_buffer_resource_and_offset(This->buf, offset);
*offset = 0;
return NineResource9_GetResource(&This->base);
}
static void
NineBuffer9_RebindIfRequired( struct NineBuffer9 *This,
struct NineDevice9 *device,
struct pipe_resource *resource,
unsigned offset )
{
int i;
if (!This->bind_count)
return;
for (i = 0; i < device->caps.MaxStreams; i++) {
if (device->state.stream[i] == (struct NineVertexBuffer9 *)This)
nine_context_set_stream_source_apply(device, i,
resource,
device->state.vtxbuf[i].buffer_offset + offset,
device->state.vtxstride[i]);
}
if (device->state.idxbuf == (struct NineIndexBuffer9 *)This)
nine_context_set_indices_apply(device, resource,
((struct NineIndexBuffer9 *)This)->index_size,
offset);
}
HRESULT NINE_WINAPI
NineBuffer9_Lock( struct NineBuffer9 *This,
UINT OffsetToLock,
UINT SizeToLock,
void **ppbData,
DWORD Flags )
{
struct NineDevice9 *device = This->base.base.device;
struct pipe_box box;
struct pipe_context *pipe;
void *data;
unsigned usage;
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);
if (SizeToLock == 0) {
SizeToLock = This->size - OffsetToLock;
user_warn(OffsetToLock != 0);
}
/* Write out of bound seems to have to be taken into account for these.
* TODO: Do more tests (is it only at buffer first lock ? etc).
* Since these buffers are supposed to be locked once and never
* written again (MANAGED or DYNAMIC is used for the other uses cases),
* performance should be unaffected. */
if (!(This->base.usage & D3DUSAGE_DYNAMIC) && This->base.pool == D3DPOOL_DEFAULT)
SizeToLock = This->size - OffsetToLock;
SizeToLock = MIN2(SizeToLock, This->size - OffsetToLock); /* Do not read or track out of the buffer */
u_box_1d(OffsetToLock, SizeToLock, &box);
if (This->base.pool != D3DPOOL_DEFAULT) {
/* MANAGED: READONLY doesn't dirty the buffer, nor
* wait the upload in the worker thread
* SYSTEMMEM: AMD/NVidia: All locks dirty the full buffer. Not on Intel
* For Nvidia, SYSTEMMEM behaves are if there is no worker thread.
* On AMD, READONLY and NOOVERWRITE do dirty the buffer, but do not sync the previous uploads
* in the worker thread. On Intel only NOOVERWRITE has that effect.
* We implement the AMD behaviour. */
if (This->base.pool == D3DPOOL_MANAGED) {
if (!(Flags & D3DLOCK_READONLY)) {
if (!This->managed.dirty) {
assert(list_is_empty(&This->managed.list));
This->managed.dirty = true;
This->managed.dirty_box = box;
/* Flush if regions pending to be uploaded would be dirtied */
if (p_atomic_read(&This->managed.pending_upload)) {
u_box_intersect_1d(&box, &box, &This->managed.upload_pending_regions);
if (box.width != 0)
nine_csmt_process(This->base.base.device);
}
} else
u_box_union_1d(&This->managed.dirty_box, &This->managed.dirty_box, &box);
/* Tests trying to draw while the buffer is locked show that
* SYSTEMMEM/MANAGED buffers are made dirty at Lock time */
BASEBUF_REGISTER_UPDATE(This);
}
} else {
if (!(Flags & (D3DLOCK_READONLY|D3DLOCK_NOOVERWRITE)) &&
p_atomic_read(&This->managed.pending_upload)) {
This->managed.num_worker_thread_syncs++;
/* If we sync too often, pick the vertex_uploader path */
if (This->managed.num_worker_thread_syncs >= 3)
This->managed.can_unsynchronized = false;
nine_csmt_process(This->base.base.device);
/* Note: AS DISCARD is not relevant for SYSTEMMEM,
* NOOVERWRITE might have a similar meaning as what is
* in D3D7 doc. Basically that data from previous draws
* OF THIS FRAME are unaffected. As we flush csmt in Present(),
* we should be correct. In some parts of the doc, the notion
* of frame is implied to be related to Begin/EndScene(),
* but tests show NOOVERWRITE after EndScene() doesn't flush
* the csmt thread. */
}
This->managed.dirty = true;
u_box_1d(0, This->size, &This->managed.dirty_box); /* systemmem non-dynamic */
u_box_1d(0, 0, &This->managed.valid_region); /* systemmem dynamic */
BASEBUF_REGISTER_UPDATE(This);
}
*ppbData = (int8_t *)This->managed.data + OffsetToLock;
DBG("returning pointer %p\n", *ppbData);
This->nlocks++;
return D3D_OK;
}
/* Driver ddi doc: READONLY is never passed to the device. So it can only
* have effect on things handled by the driver (MANAGED pool for example).
* Msdn doc: DISCARD and NOOVERWRITE are only for DYNAMIC.
* ATI doc: You can use DISCARD and NOOVERWRITE without DYNAMIC.
* Msdn doc: D3DLOCK_DONOTWAIT is not among the valid flags for buffers.
* Our tests: On win 7 nvidia, D3DLOCK_DONOTWAIT does return
* D3DERR_WASSTILLDRAWING if the resource is in use, except for DYNAMIC.
* Our tests: some apps do use both DISCARD and NOOVERWRITE at the same
* time. On windows it seems to return different pointer in some conditions,
* creation flags and drivers. However these tests indicate having
* NOOVERWRITE win is a valid behaviour (NVidia).
*/
/* Have NOOVERWRITE win over DISCARD. This is allowed (see above) and
* it prevents overconsuming buffers if apps do use both at the same time. */
if ((Flags & (D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE)) == (D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE))
Flags &= ~D3DLOCK_DISCARD;
if (Flags & D3DLOCK_DISCARD)
usage = PIPE_MAP_WRITE | PIPE_MAP_DISCARD_WHOLE_RESOURCE;
else if (Flags & D3DLOCK_NOOVERWRITE)
usage = PIPE_MAP_WRITE | PIPE_MAP_UNSYNCHRONIZED;
else
/* Do not ask for READ if writeonly and default pool (should be safe enough,
* as the doc says app shouldn't expect reading to work with writeonly). */
usage = (This->base.usage & D3DUSAGE_WRITEONLY) ?
PIPE_MAP_WRITE :
PIPE_MAP_READ_WRITE;
if (Flags & D3DLOCK_DONOTWAIT && !(This->base.usage & D3DUSAGE_DYNAMIC))
usage |= PIPE_MAP_DONTBLOCK;
This->discard_nooverwrite_only &= !!(Flags & (D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE));
if (This->nmaps == This->maxmaps) {
struct NineTransfer *newmaps =
REALLOC(This->maps, sizeof(struct NineTransfer)*This->maxmaps,
sizeof(struct NineTransfer)*(This->maxmaps << 1));
if (newmaps == NULL)
return E_OUTOFMEMORY;
This->maxmaps <<= 1;
This->maps = newmaps;
}
if (This->buf && !This->discard_nooverwrite_only) {
struct pipe_box src_box;
unsigned offset;
struct pipe_resource *src_res;
DBG("Disabling nine_subbuffer for a buffer having"
"used a nine_subbuffer buffer\n");
/* Copy buffer content to the buffer resource, which
* we will now use.
* Note: The behaviour may be different from what is expected
* with double lock. However applications can't really make expectations
* about double locks, and don't really use them, so that's ok. */
src_res = nine_upload_buffer_resource_and_offset(This->buf, &offset);
u_box_1d(offset, This->size, &src_box);
pipe = NineDevice9_GetPipe(device);
pipe->resource_copy_region(pipe, This->base.resource, 0, 0, 0, 0,
src_res, 0, &src_box);
/* Release previous resource */
if (This->nmaps >= 1)
This->maps[This->nmaps-1].should_destroy_buf = true;
else
nine_upload_release_buffer(device->buffer_upload, This->buf);
This->buf = NULL;
/* Rebind buffer */
NineBuffer9_RebindIfRequired(This, device, This->base.resource, 0);
}
This->maps[This->nmaps].transfer = NULL;
This->maps[This->nmaps].is_pipe_secondary = false;
This->maps[This->nmaps].buf = NULL;
This->maps[This->nmaps].should_destroy_buf = false;
if (This->discard_nooverwrite_only) {
if (This->buf && (Flags & D3DLOCK_DISCARD)) {
/* Release previous buffer */
if (This->nmaps >= 1)
This->maps[This->nmaps-1].should_destroy_buf = true;
else
nine_upload_release_buffer(device->buffer_upload, This->buf);
This->buf = NULL;
}
if (!This->buf) {
unsigned offset;
struct pipe_resource *res;
This->buf = nine_upload_create_buffer(device->buffer_upload, This->base.info.width0);
res = nine_upload_buffer_resource_and_offset(This->buf, &offset);
NineBuffer9_RebindIfRequired(This, device, res, offset);
}
if (This->buf) {
This->maps[This->nmaps].buf = This->buf;
This->nmaps++;
This->nlocks++;
DBG("Returning %p\n", nine_upload_buffer_get_map(This->buf) + OffsetToLock);
*ppbData = nine_upload_buffer_get_map(This->buf) + OffsetToLock;
return D3D_OK;
} else {
/* Fallback to normal path, and don't try again */
This->discard_nooverwrite_only = false;
}
}
/* Previous mappings may need pending commands to write to the
* buffer (staging buffer for example). Before a NOOVERWRITE,
* we thus need a finish, to guarantee any upload is finished.
* Note for discard_nooverwrite_only we don't need to do this
* check as neither discard nor nooverwrite have issues there */
if (This->need_sync_if_nooverwrite && !(Flags & D3DLOCK_DISCARD) &&
(Flags & D3DLOCK_NOOVERWRITE)) {
struct pipe_screen *screen = NineDevice9_GetScreen(device);
struct pipe_fence_handle *fence = NULL;
pipe = NineDevice9_GetPipe(device);
pipe->flush(pipe, &fence, 0);
(void) screen->fence_finish(screen, NULL, fence, OS_TIMEOUT_INFINITE);
screen->fence_reference(screen, &fence, NULL);
}
This->need_sync_if_nooverwrite = !(Flags & (D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE));
/* When csmt is active, we want to avoid stalls as much as possible,
* and thus we want to create a new resource on discard and map it
* with the secondary pipe, instead of waiting on the main pipe. */
if (Flags & D3DLOCK_DISCARD && device->csmt_active) {
struct pipe_screen *screen = NineDevice9_GetScreen(device);
struct pipe_resource *new_res = nine_resource_create_with_retry(device, screen, &This->base.info);
if (new_res) {
/* Use the new resource */
pipe_resource_reference(&This->base.resource, new_res);
pipe_resource_reference(&new_res, NULL);
usage = PIPE_MAP_WRITE | PIPE_MAP_UNSYNCHRONIZED;
NineBuffer9_RebindIfRequired(This, device, This->base.resource, 0);
This->maps[This->nmaps].is_pipe_secondary = true;
}
} else if (Flags & D3DLOCK_NOOVERWRITE && device->csmt_active)
This->maps[This->nmaps].is_pipe_secondary = true;
if (This->maps[This->nmaps].is_pipe_secondary)
pipe = device->pipe_secondary;
else
pipe = NineDevice9_GetPipe(device);
data = pipe->buffer_map(pipe, This->base.resource, 0,
usage, &box, &This->maps[This->nmaps].transfer);
if (!data) {
DBG("pipe::buffer_map failed\n"
" usage = %x\n"
" box.x = %u\n"
" box.width = %u\n",
usage, box.x, box.width);
if (Flags & D3DLOCK_DONOTWAIT)
return D3DERR_WASSTILLDRAWING;
return D3DERR_INVALIDCALL;
}
DBG("returning pointer %p\n", data);
This->nmaps++;
This->nlocks++;
*ppbData = data;
return D3D_OK;
}
HRESULT NINE_WINAPI
NineBuffer9_Unlock( struct NineBuffer9 *This )
{
struct NineDevice9 *device = This->base.base.device;
struct pipe_context *pipe;
int i;
DBG("This=%p\n", This);
user_assert(This->nlocks > 0, D3DERR_INVALIDCALL);
This->nlocks--;
if (This->nlocks > 0)
return D3D_OK; /* Pending unlocks. Wait all unlocks before unmapping */
if (This->base.pool == D3DPOOL_DEFAULT) {
for (i = 0; i < This->nmaps; i++) {
if (!This->maps[i].buf) {
pipe = This->maps[i].is_pipe_secondary ?
device->pipe_secondary :
nine_context_get_pipe_acquire(device);
pipe->buffer_unmap(pipe, This->maps[i].transfer);
/* We need to flush in case the driver does implicit copies */
if (This->maps[i].is_pipe_secondary)
pipe->flush(pipe, NULL, 0);
else
nine_context_get_pipe_release(device);
} else if (This->maps[i].should_destroy_buf)
nine_upload_release_buffer(device->buffer_upload, This->maps[i].buf);
}
This->nmaps = 0;
}
return D3D_OK;
}
void
NineBuffer9_SetDirty( struct NineBuffer9 *This )
{
assert(This->base.pool != D3DPOOL_DEFAULT);
This->managed.dirty = true;
u_box_1d(0, This->size, &This->managed.dirty_box);
BASEBUF_REGISTER_UPDATE(This);
}
/* Try to remove b from a, supposed to include b */
static void u_box_try_remove_region_1d(struct pipe_box *dst,
const struct pipe_box *a,
const struct pipe_box *b)
{
int x, width;
if (a->x == b->x) {
x = a->x + b->width;
width = a->width - b->width;
} else if ((a->x + a->width) == (b->x + b->width)) {
x = a->x;
width = a->width - b->width;
} else {
x = a->x;
width = a->width;
}
dst->x = x;
dst->width = width;
}
void
NineBuffer9_Upload( struct NineBuffer9 *This )
{
struct NineDevice9 *device = This->base.base.device;
unsigned upload_flags = 0;
struct pipe_box box_upload;
assert(This->base.pool != D3DPOOL_DEFAULT && This->managed.dirty);
if (This->base.pool == D3DPOOL_SYSTEMMEM && This->base.usage & D3DUSAGE_DYNAMIC) {
struct pipe_box region_already_valid;
struct pipe_box conflicting_region;
struct pipe_box *valid_region = &This->managed.valid_region;
struct pipe_box *required_valid_region = &This->managed.required_valid_region;
struct pipe_box *filled_region = &This->managed.filled_region;
/* Try to upload SYSTEMMEM DYNAMIC in an efficient fashion.
* Unlike non-dynamic for which we upload the whole dirty region, try to
* only upload the data needed for the draw. The draw call preparation
* fills This->managed.required_valid_region for that */
u_box_intersect_1d(&region_already_valid,
valid_region,
required_valid_region);
/* If the required valid region is already valid, nothing to do */
if (region_already_valid.x == required_valid_region->x &&
region_already_valid.width == required_valid_region->width) {
/* Rebind if the region happens to be valid in the original buffer
* but we have since used vertex_uploader */
if (!This->managed.can_unsynchronized)
NineBuffer9_RebindIfRequired(This, device, This->base.resource, 0);
u_box_1d(0, 0, required_valid_region);
return;
}
/* (Try to) Remove valid areas from the region to upload */
u_box_try_remove_region_1d(&box_upload,
required_valid_region,
&region_already_valid);
assert(box_upload.width > 0);
/* To maintain correctly the valid region, as we will do union later with
* box_upload, we must ensure box_upload is consecutive with valid_region */
if (box_upload.x > valid_region->x + valid_region->width && valid_region->width > 0) {
box_upload.width = box_upload.x + box_upload.width - (valid_region->x + valid_region->width);
box_upload.x = valid_region->x + valid_region->width;
} else if (box_upload.x + box_upload.width < valid_region->x && valid_region->width > 0) {
box_upload.width = valid_region->x - box_upload.x;
}
/* There is conflict if some areas, that are not valid but are filled for previous draw calls,
* intersect with the region we plan to upload. Note by construction valid_region IS
* included in filled_region, thus so is region_already_valid. */
u_box_intersect_1d(&conflicting_region, &box_upload, filled_region);
/* As box_upload could still contain region_already_valid, check the intersection
* doesn't happen to be exactly region_already_valid (it cannot be smaller, see above) */
if (This->managed.can_unsynchronized && (conflicting_region.width == 0 ||
(conflicting_region.x == region_already_valid.x &&
conflicting_region.width == region_already_valid.width))) {
/* No conflicts. */
upload_flags |= PIPE_MAP_UNSYNCHRONIZED;
} else {
/* We cannot use PIPE_MAP_UNSYNCHRONIZED. We must choose between no flag and DISCARD.
* Criteria to discard:
* . Most of the resource was filled (but some apps do allocate a big buffer
* to only use a small part in a round fashion)
* . The region to upload is very small compared to the filled region and
* at the start of the buffer (hints at round usage starting again)
* . The region to upload is very big compared to the required region
* . We have not discarded yet this frame
* If the buffer use pattern seems to sync the worker thread too often,
* revert to the vertex_uploader */
if (This->managed.num_worker_thread_syncs < 3 &&
(filled_region->width > (This->size / 2) ||
(10 * box_upload.width < filled_region->width &&
box_upload.x < (filled_region->x + filled_region->width)/2) ||
box_upload.width > 2 * required_valid_region->width ||
This->managed.frame_count_last_discard != device->frame_count)) {
/* Avoid DISCARDING too much by discarding only if most of the buffer
* has been used */
DBG_FLAG(DBG_INDEXBUFFER|DBG_VERTEXBUFFER,
"Uploading %p DISCARD: valid %d %d, filled %d %d, required %d %d, box_upload %d %d, required already_valid %d %d, conflicting %d %d\n",
This, valid_region->x, valid_region->width, filled_region->x, filled_region->width,
required_valid_region->x, required_valid_region->width, box_upload.x, box_upload.width,
region_already_valid.x, region_already_valid.width, conflicting_region.x, conflicting_region.width
);
upload_flags |= PIPE_MAP_DISCARD_WHOLE_RESOURCE;
u_box_1d(0, 0, filled_region);
u_box_1d(0, 0, valid_region);
box_upload = This->managed.required_valid_region;
/* Rebind the buffer if we used intermediate alternative buffer */
if (!This->managed.can_unsynchronized)
NineBuffer9_RebindIfRequired(This, device, This->base.resource, 0);
This->managed.can_unsynchronized = true;
This->managed.frame_count_last_discard = device->frame_count;
} else {
/* Once we use without UNSYNCHRONIZED, we cannot use it anymore.
* Use a different buffer. */
unsigned buffer_offset = 0;
struct pipe_resource *resource = NULL;
This->managed.can_unsynchronized = false;
u_upload_data(device->vertex_uploader,
required_valid_region->x,
required_valid_region->width,
64,
This->managed.data + required_valid_region->x,
&buffer_offset,
&resource);
buffer_offset -= required_valid_region->x;
u_upload_unmap(device->vertex_uploader);
if (resource) {
NineBuffer9_RebindIfRequired(This, device, resource, buffer_offset);
/* Note: This only works because for these types of buffers this function
* is called before every draw call. Else it wouldn't work when the app
* rebinds buffers. In addition it needs this function to be called only
* once per buffers even if bound several times, which we do. */
u_box_1d(0, 0, required_valid_region);
pipe_resource_reference(&resource, NULL);
return;
}
}
}
u_box_union_1d(filled_region,
filled_region,
&box_upload);
u_box_union_1d(valid_region,
valid_region,
&box_upload);
u_box_1d(0, 0, required_valid_region);
} else
box_upload = This->managed.dirty_box;
if (box_upload.x == 0 && box_upload.width == This->size) {
upload_flags |= PIPE_MAP_DISCARD_WHOLE_RESOURCE;
}
if (This->managed.pending_upload) {
u_box_union_1d(&This->managed.upload_pending_regions,
&This->managed.upload_pending_regions,
&box_upload);
} else {
This->managed.upload_pending_regions = box_upload;
}
DBG_FLAG(DBG_INDEXBUFFER|DBG_VERTEXBUFFER,
"Uploading %p, offset=%d, size=%d, Flags=0x%x\n",
This, box_upload.x, box_upload.width, upload_flags);
nine_context_range_upload(device, &This->managed.pending_upload,
(struct NineUnknown *)This,
This->base.resource,
box_upload.x,
box_upload.width,
upload_flags,
(int8_t *)This->managed.data + box_upload.x);
This->managed.dirty = false;
}

View file

@ -1,129 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* Copyright 2015 Patrick Rudolph <siro@das-labor.org>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_BUFFER9_H_
#define _NINE_BUFFER9_H_
#include "device9.h"
#include "nine_buffer_upload.h"
#include "nine_state.h"
#include "resource9.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_state.h"
#include "util/list.h"
#include "util/box.h"
#include "util/u_upload_mgr.h"
struct pipe_screen;
struct pipe_context;
struct pipe_transfer;
struct NineTransfer {
struct pipe_transfer *transfer;
bool is_pipe_secondary;
struct nine_subbuffer *buf; /* NULL unless subbuffer are used */
bool should_destroy_buf; /* If the subbuffer should be destroyed */
};
struct NineBuffer9
{
struct NineResource9 base;
/* G3D */
struct NineTransfer *maps;
int nlocks, nmaps, maxmaps;
UINT size;
int16_t bind_count; /* to Device9->state.stream */
/* Whether only discard and nooverwrite were used so far
* for this buffer. Allows some optimization. */
bool discard_nooverwrite_only;
bool need_sync_if_nooverwrite;
struct nine_subbuffer *buf;
/* Specific to managed buffers */
struct {
void *data;
bool dirty;
struct pipe_box dirty_box; /* region in the resource to update */
struct pipe_box upload_pending_regions; /* region with uploads pending */
struct list_head list; /* for update_buffers */
struct list_head list2; /* for managed_buffers */
unsigned pending_upload; /* for uploads */
/* SYSTEMMEM DYNAMIC */
bool can_unsynchronized; /* Whether the upload can use nooverwrite */
struct pipe_box valid_region; /* Region in the GPU buffer with valid content */
struct pipe_box required_valid_region; /* Region that needs to be valid right now. */
struct pipe_box filled_region; /* Region in the GPU buffer filled since last discard */
unsigned num_worker_thread_syncs;
unsigned frame_count_last_discard;
} managed;
};
static inline struct NineBuffer9 *
NineBuffer9( void *data )
{
return (struct NineBuffer9 *)data;
}
HRESULT
NineBuffer9_ctor( struct NineBuffer9 *This,
struct NineUnknownParams *pParams,
D3DRESOURCETYPE Type,
DWORD Usage,
UINT Size,
D3DPOOL Pool );
void
NineBuffer9_dtor( struct NineBuffer9 *This );
struct pipe_resource *
NineBuffer9_GetResource( struct NineBuffer9 *This, unsigned *offset );
HRESULT NINE_WINAPI
NineBuffer9_Lock( struct NineBuffer9 *This,
UINT OffsetToLock,
UINT SizeToLock,
void **ppbData,
DWORD Flags );
HRESULT NINE_WINAPI
NineBuffer9_Unlock( struct NineBuffer9 *This );
void
NineBuffer9_Upload( struct NineBuffer9 *This );
static void inline
NineBindBufferToDevice( struct NineDevice9 *device,
struct NineBuffer9 **slot,
struct NineBuffer9 *buf )
{
struct NineBuffer9 *old = *slot;
if (buf) {
if ((buf->managed.dirty) && list_is_empty(&buf->managed.list))
list_add(&buf->managed.list, &device->update_buffers);
buf->bind_count++;
}
if (old) {
old->bind_count--;
if (!old->bind_count && old->managed.dirty)
list_delinit(&old->managed.list);
}
nine_bind(slot, buf);
}
void
NineBuffer9_SetDirty( struct NineBuffer9 *This );
#define BASEBUF_REGISTER_UPDATE(b) { \
if ((b)->managed.dirty && (b)->bind_count) \
if (list_is_empty(&(b)->managed.list)) \
list_add(&(b)->managed.list, &(b)->base.base.device->update_buffers); \
}
#endif /* _NINE_BUFFER9_H_ */

View file

@ -1,98 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#include "cryptosession9.h"
#define DBG_CHANNEL DBG_CRYPTOSESSION
HRESULT NINE_WINAPI
NineCryptoSession9_GetCertificateSize( struct NineCryptoSession9 *This,
UINT *pCertificateSize )
{
STUB(D3DERR_INVALIDCALL);
}
HRESULT NINE_WINAPI
NineCryptoSession9_GetCertificate( struct NineCryptoSession9 *This,
UINT CertifacteSize,
BYTE *ppCertificate )
{
STUB(D3DERR_INVALIDCALL);
}
HRESULT NINE_WINAPI
NineCryptoSession9_NegotiateKeyExchange( struct NineCryptoSession9 *This,
UINT DataSize,
void *pData )
{
STUB(D3DERR_INVALIDCALL);
}
HRESULT NINE_WINAPI
NineCryptoSession9_EncryptionBlt( struct NineCryptoSession9 *This,
IDirect3DSurface9 *pSrcSurface,
IDirect3DSurface9 *pDstSurface,
UINT DstSurfaceSize,
void *pIV )
{
STUB(D3DERR_INVALIDCALL);
}
HRESULT NINE_WINAPI
NineCryptoSession9_DecryptionBlt( struct NineCryptoSession9 *This,
IDirect3DSurface9 *pSrcSurface,
IDirect3DSurface9 *pDstSurface,
UINT SrcSurfaceSize,
D3DENCRYPTED_BLOCK_INFO *pEncryptedBlockInfo,
void *pContentKey,
void *pIV )
{
STUB(D3DERR_INVALIDCALL);
}
HRESULT NINE_WINAPI
NineCryptoSession9_GetSurfacePitch( struct NineCryptoSession9 *This,
IDirect3DSurface9 *pSrcSurface,
UINT *pSurfacePitch )
{
STUB(D3DERR_INVALIDCALL);
}
HRESULT NINE_WINAPI
NineCryptoSession9_StartSessionKeyRefresh( struct NineCryptoSession9 *This,
void *pRandomNumber,
UINT RandomNumberSize )
{
STUB(D3DERR_INVALIDCALL);
}
HRESULT NINE_WINAPI
NineCryptoSession9_FinishSessionKeyRefresh( struct NineCryptoSession9 *This )
{
STUB(D3DERR_INVALIDCALL);
}
HRESULT NINE_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

@ -1,69 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#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 NINE_WINAPI
NineCryptoSession9_GetCertificateSize( struct NineCryptoSession9 *This,
UINT *pCertificateSize );
HRESULT NINE_WINAPI
NineCryptoSession9_GetCertificate( struct NineCryptoSession9 *This,
UINT CertifacteSize,
BYTE *ppCertificate );
HRESULT NINE_WINAPI
NineCryptoSession9_NegotiateKeyExchange( struct NineCryptoSession9 *This,
UINT DataSize,
void *pData );
HRESULT NINE_WINAPI
NineCryptoSession9_EncryptionBlt( struct NineCryptoSession9 *This,
IDirect3DSurface9 *pSrcSurface,
IDirect3DSurface9 *pDstSurface,
UINT DstSurfaceSize,
void *pIV );
HRESULT NINE_WINAPI
NineCryptoSession9_DecryptionBlt( struct NineCryptoSession9 *This,
IDirect3DSurface9 *pSrcSurface,
IDirect3DSurface9 *pDstSurface,
UINT SrcSurfaceSize,
D3DENCRYPTED_BLOCK_INFO *pEncryptedBlockInfo,
void *pContentKey,
void *pIV );
HRESULT NINE_WINAPI
NineCryptoSession9_GetSurfacePitch( struct NineCryptoSession9 *This,
IDirect3DSurface9 *pSrcSurface,
UINT *pSurfacePitch );
HRESULT NINE_WINAPI
NineCryptoSession9_StartSessionKeyRefresh( struct NineCryptoSession9 *This,
void *pRandomNumber,
UINT RandomNumberSize );
HRESULT NINE_WINAPI
NineCryptoSession9_FinishSessionKeyRefresh( struct NineCryptoSession9 *This );
HRESULT NINE_WINAPI
NineCryptoSession9_GetEncryptionBltKey( struct NineCryptoSession9 *This,
void *pReadbackKey,
UINT KeySize );
#endif /* _NINE_CRYPTOSESSION9_H_ */

View file

@ -1,336 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#include "c99_alloca.h"
#include "device9.h"
#include "cubetexture9.h"
#include "nine_memory_helper.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;
struct pipe_screen *screen = pParams->device->screen;
enum pipe_format pf;
unsigned i, l, f, offset, face_size = 0;
unsigned *level_offsets = NULL;
D3DSURFACE_DESC sfdesc;
struct nine_allocation *p;
HRESULT hr;
DBG("This=%p pParams=%p EdgeLength=%u Levels=%u Usage=%d "
"Format=%d Pool=%d pSharedHandle=%p\n",
This, pParams, EdgeLength, Levels, Usage,
Format, Pool, pSharedHandle);
This->base.base.base.device = pParams->device; /* Early fill this field in case of failure */
user_assert(EdgeLength, D3DERR_INVALIDCALL);
/* user_assert(!pSharedHandle || Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL); */
user_assert(!pSharedHandle, D3DERR_INVALIDCALL); /* TODO */
user_assert(!(Usage & D3DUSAGE_AUTOGENMIPMAP) ||
(Pool != D3DPOOL_SYSTEMMEM && Levels <= 1), D3DERR_INVALIDCALL);
if (Usage & D3DUSAGE_AUTOGENMIPMAP)
Levels = 0;
pf = d3d9_to_pipe_format_checked(screen, Format, PIPE_TEXTURE_CUBE, 0,
PIPE_BIND_SAMPLER_VIEW, false,
Pool == D3DPOOL_SCRATCH);
if (pf == PIPE_FORMAT_NONE)
return D3DERR_INVALIDCALL;
if (compressed_format(Format)) {
const unsigned w = util_format_get_blockwidth(pf);
const unsigned h = util_format_get_blockheight(pf);
user_assert(!(EdgeLength % w) && !(EdgeLength % h), D3DERR_INVALIDCALL);
}
info->screen = pParams->device->screen;
info->target = PIPE_TEXTURE_CUBE;
info->format = pf;
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->nr_storage_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;
}
if (Usage & D3DUSAGE_SOFTWAREPROCESSING)
DBG("Application asked for Software Vertex Processing, "
"but this is unimplemented\n");
hr = NineBaseTexture9_ctor(&This->base, pParams, NULL, D3DRTYPE_CUBETEXTURE,
Format, Pool, Usage);
if (FAILED(hr))
return hr;
This->base.pstype = 2;
if (Pool != D3DPOOL_DEFAULT) {
level_offsets = alloca(sizeof(unsigned) * This->base.level_count);
face_size = nine_format_get_size_and_offsets(pf, level_offsets,
EdgeLength, EdgeLength,
This->base.level_count-1);
This->managed_buffer = nine_allocate(pParams->device->allocator, 6 * face_size);
if (!This->managed_buffer)
return E_OUTOFMEMORY;
}
This->surfaces = CALLOC(6 * This->base.level_count, sizeof(*This->surfaces));
if (!This->surfaces)
return E_OUTOFMEMORY;
/* 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;
/* We allocate the memory for the surfaces as continuous blocks.
* This is the expected behaviour, however we haven't tested for
* cube textures in which order the faces/levels should be in memory
*/
for (f = 0; f < 6; f++) {
offset = f * face_size;
for (l = 0; l < This->base.level_count; l++) {
sfdesc.Width = sfdesc.Height = u_minify(EdgeLength, l);
p = This->managed_buffer ?
nine_suballocate(pParams->device->allocator, This->managed_buffer, offset + level_offsets[l]) : NULL;
hr = NineSurface9_new(This->base.base.base.device, NineUnknown(This),
This->base.base.resource, p, D3DRTYPE_CUBETEXTURE,
l, f, &sfdesc, &This->surfaces[f + 6 * l]);
if (FAILED(hr))
return hr;
}
}
for (i = 0; i < 6; ++i) {
/* Textures start initially dirty */
This->dirty_rect[i].width = EdgeLength;
This->dirty_rect[i].height = EdgeLength;
This->dirty_rect[i].depth = 1;
}
return D3D_OK;
}
static void
NineCubeTexture9_dtor( struct NineCubeTexture9 *This )
{
unsigned i;
bool is_worker = nine_context_is_worker(This->base.base.base.device);
DBG("This=%p\n", This);
if (This->surfaces) {
for (i = 0; i < This->base.level_count * 6; ++i)
if (This->surfaces[i])
NineUnknown_Destroy(&This->surfaces[i]->base.base);
FREE(This->surfaces);
}
if (This->managed_buffer) {
if (is_worker)
nine_free_worker(This->base.base.base.device->allocator, This->managed_buffer);
else
nine_free(This->base.base.base.device->allocator, This->managed_buffer);
}
NineBaseTexture9_dtor(&This->base);
}
HRESULT NINE_WINAPI
NineCubeTexture9_GetLevelDesc( struct NineCubeTexture9 *This,
UINT Level,
D3DSURFACE_DESC *pDesc )
{
DBG("This=%p Level=%u pDesc=%p\n", This, Level, pDesc);
user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
*pDesc = This->surfaces[Level * 6]->desc;
return D3D_OK;
}
HRESULT NINE_WINAPI
NineCubeTexture9_GetCubeMapSurface( struct NineCubeTexture9 *This,
D3DCUBEMAP_FACES FaceType,
UINT Level,
IDirect3DSurface9 **ppCubeMapSurface )
{
const unsigned s = Level * 6 + FaceType;
DBG("This=%p FaceType=%d Level=%u ppCubeMapSurface=%p\n",
This, FaceType, Level, ppCubeMapSurface);
user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
user_assert(FaceType < 6, D3DERR_INVALIDCALL);
NineUnknown_AddRef(NineUnknown(This->surfaces[s]));
*ppCubeMapSurface = (IDirect3DSurface9 *)This->surfaces[s];
return D3D_OK;
}
HRESULT NINE_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;
DBG("This=%p FaceType=%d Level=%u pLockedRect=%p pRect=%p Flags=%d\n",
This, FaceType, Level, pLockedRect, pRect, Flags);
user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
user_assert(FaceType < 6, D3DERR_INVALIDCALL);
return NineSurface9_LockRect(This->surfaces[s], pLockedRect, pRect, Flags);
}
HRESULT NINE_WINAPI
NineCubeTexture9_UnlockRect( struct NineCubeTexture9 *This,
D3DCUBEMAP_FACES FaceType,
UINT Level )
{
const unsigned s = Level * 6 + FaceType;
DBG("This=%p FaceType=%d Level=%u\n", This, FaceType, Level);
user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
user_assert(FaceType < 6, D3DERR_INVALIDCALL);
return NineSurface9_UnlockRect(This->surfaces[s]);
}
HRESULT NINE_WINAPI
NineCubeTexture9_AddDirtyRect( struct NineCubeTexture9 *This,
D3DCUBEMAP_FACES FaceType,
const RECT *pDirtyRect )
{
DBG("This=%p FaceType=%d pDirtyRect=%p\n", This, FaceType, 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;
BASETEX_REGISTER_UPDATE(&This->base);
}
return D3D_OK;
}
if (This->base.base.pool == D3DPOOL_MANAGED) {
This->base.managed.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 {
if (This->dirty_rect[FaceType].width == 0) {
rect_to_pipe_box_clamp(&This->dirty_rect[FaceType], pDirtyRect);
} 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);
}
(void) u_box_clip_2d(&This->dirty_rect[FaceType],
&This->dirty_rect[FaceType],
This->base.base.info.width0,
This->base.base.info.height0);
}
return D3D_OK;
}
IDirect3DCubeTexture9Vtbl NineCubeTexture9_vtable = {
(void *)NineUnknown_QueryInterface,
(void *)NineUnknown_AddRef,
(void *)NineUnknown_Release,
(void *)NineUnknown_GetDevice, /* actually part of Resource9 iface */
(void *)NineUnknown_SetPrivateData,
(void *)NineUnknown_GetPrivateData,
(void *)NineUnknown_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

@ -1,64 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_CUBETEXTURE9_H_
#define _NINE_CUBETEXTURE9_H_
#include "basetexture9.h"
#include "nine_memory_helper.h"
#include "surface9.h"
struct NineCubeTexture9
{
struct NineBaseTexture9 base;
struct NineSurface9 **surfaces;
struct pipe_box dirty_rect[6]; /* covers all mip levels */
struct nine_allocation *managed_buffer;
};
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 NINE_WINAPI
NineCubeTexture9_GetLevelDesc( struct NineCubeTexture9 *This,
UINT Level,
D3DSURFACE_DESC *pDesc );
HRESULT NINE_WINAPI
NineCubeTexture9_GetCubeMapSurface( struct NineCubeTexture9 *This,
D3DCUBEMAP_FACES FaceType,
UINT Level,
IDirect3DSurface9 **ppCubeMapSurface );
HRESULT NINE_WINAPI
NineCubeTexture9_LockRect( struct NineCubeTexture9 *This,
D3DCUBEMAP_FACES FaceType,
UINT Level,
D3DLOCKED_RECT *pLockedRect,
const RECT *pRect,
DWORD Flags );
HRESULT NINE_WINAPI
NineCubeTexture9_UnlockRect( struct NineCubeTexture9 *This,
D3DCUBEMAP_FACES FaceType,
UINT Level );
HRESULT NINE_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

@ -1,848 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_DEVICE9_H_
#define _NINE_DEVICE9_H_
#include "d3dadapter/d3dadapter9.h"
#include "iunknown.h"
#include "adapter9.h"
#include "nine_helpers.h"
#include "nine_memory_helper.h"
#include "nine_state.h"
struct gen_mipmap_state;
struct hash_table;
struct pipe_screen;
struct pipe_context;
struct cso_context;
struct hud_context;
struct u_upload_mgr;
struct csmt_context;
struct NineSwapChain9;
struct NineStateBlock9;
#include "util/list.h"
struct NineDevice9
{
struct NineUnknown base;
bool ex;
bool may_swvp;
/* G3D context */
struct pipe_screen *screen;
/* For first time upload. No Sync with rendering thread */
struct pipe_context *pipe_secondary;
struct pipe_screen *screen_sw;
struct pipe_context *pipe_sw;
struct cso_context *cso_sw;
/* CSMT context */
struct csmt_context *csmt_ctx;
BOOL csmt_active;
/* For DISCARD/NOOVERWRITE */
struct nine_buffer_upload *buffer_upload;
/* 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 nine_context context;
struct nine_state_sw_internal state_sw_internal;
struct list_head update_buffers;
struct list_head update_textures;
struct list_head managed_buffers;
struct list_head managed_textures;
bool is_recording;
bool in_scene;
unsigned end_scene_since_present;
uint16_t vs_const_size;
uint16_t ps_const_size;
uint16_t max_vs_const_f;
struct pipe_resource *dummy_texture;
struct pipe_sampler_view *dummy_sampler_view;
struct pipe_sampler_state dummy_sampler_state;
struct gen_mipmap_state *gen_mipmap;
struct {
struct hash_table *ht_vs;
struct hash_table *ht_ps;
struct NineVertexShader9 *vs;
struct NinePixelShader9 *ps;
unsigned num_vs;
unsigned num_ps;
float *vs_const;
float *ps_const;
struct 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;
bool software;
void *hw_upload_temp;
} cursor;
struct {
bool user_sw_vbufs;
bool window_space_position_support;
bool disabling_depth_clipping_support;
bool vs_integer;
bool ps_integer;
bool offset_units_unscaled;
bool alpha_test_emulation;
bool always_output_pointsize;
bool emulate_ucp;
bool shader_emulate_features;
} driver_caps;
struct {
bool buggy_barycentrics;
} driver_bugs;
struct {
bool dynamic_texture_workaround;
} workarounds;
struct u_upload_mgr *vertex_uploader;
struct nine_range_pool range_pool;
struct hud_context *hud; /* NULL if hud is disabled */
struct nine_allocator *allocator;
/* dummy vbo (containing 0 0 0 0) to bind if vertex shader input
* is not bound to anything by the vertex declaration */
struct pipe_resource *dummy_vbo;
struct pipe_resource *dummy_vbo_sw;
BOOL device_needs_reset;
int minor_version_num;
long long available_texture_mem;
long long available_texture_limit;
/* software vertex processing */
bool swvp;
/* pure device */
bool pure;
unsigned frame_count; /* It's ok if we overflow */
/* Ex */
int gpu_priority;
unsigned max_frame_latency;
};
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,
bool ex,
D3DDISPLAYMODEEX *pFullscreenDisplayMode,
struct NineDevice9 **ppOut,
int minorVersionNum );
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,
bool ex,
D3DDISPLAYMODEEX *pFullscreenDisplayMode,
int minorVersionNum );
void
NineDevice9_dtor( struct NineDevice9 *This );
/*** Nine private ***/
struct pipe_resource *
nine_resource_create_with_retry( struct NineDevice9 *This,
struct pipe_screen *screen,
const struct pipe_resource *templat );
void
NineDevice9_SetDefaultState( struct NineDevice9 *This, bool is_reset );
struct pipe_screen *
NineDevice9_GetScreen( struct NineDevice9 *This );
struct pipe_context *
NineDevice9_GetPipe( struct NineDevice9 *This );
const D3DCAPS9 *
NineDevice9_GetCaps( struct NineDevice9 *This );
void
NineDevice9_EvictManagedResourcesInternal( struct NineDevice9 *This );
/*** Direct3D public ***/
HRESULT NINE_WINAPI
NineDevice9_TestCooperativeLevel( struct NineDevice9 *This );
UINT NINE_WINAPI
NineDevice9_GetAvailableTextureMem( struct NineDevice9 *This );
HRESULT NINE_WINAPI
NineDevice9_EvictManagedResources( struct NineDevice9 *This );
HRESULT NINE_WINAPI
NineDevice9_GetDirect3D( struct NineDevice9 *This,
IDirect3D9 **ppD3D9 );
HRESULT NINE_WINAPI
NineDevice9_GetDeviceCaps( struct NineDevice9 *This,
D3DCAPS9 *pCaps );
HRESULT NINE_WINAPI
NineDevice9_GetDisplayMode( struct NineDevice9 *This,
UINT iSwapChain,
D3DDISPLAYMODE *pMode );
HRESULT NINE_WINAPI
NineDevice9_GetCreationParameters( struct NineDevice9 *This,
D3DDEVICE_CREATION_PARAMETERS *pParameters );
HRESULT NINE_WINAPI
NineDevice9_SetCursorProperties( struct NineDevice9 *This,
UINT XHotSpot,
UINT YHotSpot,
IDirect3DSurface9 *pCursorBitmap );
void NINE_WINAPI
NineDevice9_SetCursorPosition( struct NineDevice9 *This,
int X,
int Y,
DWORD Flags );
BOOL NINE_WINAPI
NineDevice9_ShowCursor( struct NineDevice9 *This,
BOOL bShow );
HRESULT NINE_WINAPI
NineDevice9_CreateAdditionalSwapChain( struct NineDevice9 *This,
D3DPRESENT_PARAMETERS *pPresentationParameters,
IDirect3DSwapChain9 **pSwapChain );
HRESULT NINE_WINAPI
NineDevice9_GetSwapChain( struct NineDevice9 *This,
UINT iSwapChain,
IDirect3DSwapChain9 **pSwapChain );
UINT NINE_WINAPI
NineDevice9_GetNumberOfSwapChains( struct NineDevice9 *This );
HRESULT NINE_WINAPI
NineDevice9_Reset( struct NineDevice9 *This,
D3DPRESENT_PARAMETERS *pPresentationParameters );
HRESULT NINE_WINAPI
NineDevice9_Present( struct NineDevice9 *This,
const RECT *pSourceRect,
const RECT *pDestRect,
HWND hDestWindowOverride,
const RGNDATA *pDirtyRegion );
HRESULT NINE_WINAPI
NineDevice9_GetBackBuffer( struct NineDevice9 *This,
UINT iSwapChain,
UINT iBackBuffer,
D3DBACKBUFFER_TYPE Type,
IDirect3DSurface9 **ppBackBuffer );
HRESULT NINE_WINAPI
NineDevice9_GetRasterStatus( struct NineDevice9 *This,
UINT iSwapChain,
D3DRASTER_STATUS *pRasterStatus );
HRESULT NINE_WINAPI
NineDevice9_SetDialogBoxMode( struct NineDevice9 *This,
BOOL bEnableDialogs );
void NINE_WINAPI
NineDevice9_SetGammaRamp( struct NineDevice9 *This,
UINT iSwapChain,
DWORD Flags,
const D3DGAMMARAMP *pRamp );
void NINE_WINAPI
NineDevice9_GetGammaRamp( struct NineDevice9 *This,
UINT iSwapChain,
D3DGAMMARAMP *pRamp );
HRESULT NINE_WINAPI
NineDevice9_CreateTexture( struct NineDevice9 *This,
UINT Width,
UINT Height,
UINT Levels,
DWORD Usage,
D3DFORMAT Format,
D3DPOOL Pool,
IDirect3DTexture9 **ppTexture,
HANDLE *pSharedHandle );
HRESULT NINE_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 NINE_WINAPI
NineDevice9_CreateCubeTexture( struct NineDevice9 *This,
UINT EdgeLength,
UINT Levels,
DWORD Usage,
D3DFORMAT Format,
D3DPOOL Pool,
IDirect3DCubeTexture9 **ppCubeTexture,
HANDLE *pSharedHandle );
HRESULT NINE_WINAPI
NineDevice9_CreateVertexBuffer( struct NineDevice9 *This,
UINT Length,
DWORD Usage,
DWORD FVF,
D3DPOOL Pool,
IDirect3DVertexBuffer9 **ppVertexBuffer,
HANDLE *pSharedHandle );
HRESULT NINE_WINAPI
NineDevice9_CreateIndexBuffer( struct NineDevice9 *This,
UINT Length,
DWORD Usage,
D3DFORMAT Format,
D3DPOOL Pool,
IDirect3DIndexBuffer9 **ppIndexBuffer,
HANDLE *pSharedHandle );
HRESULT NINE_WINAPI
NineDevice9_CreateRenderTarget( struct NineDevice9 *This,
UINT Width,
UINT Height,
D3DFORMAT Format,
D3DMULTISAMPLE_TYPE MultiSample,
DWORD MultisampleQuality,
BOOL Lockable,
IDirect3DSurface9 **ppSurface,
HANDLE *pSharedHandle );
HRESULT NINE_WINAPI
NineDevice9_CreateDepthStencilSurface( struct NineDevice9 *This,
UINT Width,
UINT Height,
D3DFORMAT Format,
D3DMULTISAMPLE_TYPE MultiSample,
DWORD MultisampleQuality,
BOOL Discard,
IDirect3DSurface9 **ppSurface,
HANDLE *pSharedHandle );
HRESULT NINE_WINAPI
NineDevice9_UpdateSurface( struct NineDevice9 *This,
IDirect3DSurface9 *pSourceSurface,
const RECT *pSourceRect,
IDirect3DSurface9 *pDestinationSurface,
const POINT *pDestPoint );
HRESULT NINE_WINAPI
NineDevice9_UpdateTexture( struct NineDevice9 *This,
IDirect3DBaseTexture9 *pSourceTexture,
IDirect3DBaseTexture9 *pDestinationTexture );
HRESULT NINE_WINAPI
NineDevice9_GetRenderTargetData( struct NineDevice9 *This,
IDirect3DSurface9 *pRenderTarget,
IDirect3DSurface9 *pDestSurface );
HRESULT NINE_WINAPI
NineDevice9_GetFrontBufferData( struct NineDevice9 *This,
UINT iSwapChain,
IDirect3DSurface9 *pDestSurface );
HRESULT NINE_WINAPI
NineDevice9_StretchRect( struct NineDevice9 *This,
IDirect3DSurface9 *pSourceSurface,
const RECT *pSourceRect,
IDirect3DSurface9 *pDestSurface,
const RECT *pDestRect,
D3DTEXTUREFILTERTYPE Filter );
HRESULT NINE_WINAPI
NineDevice9_ColorFill( struct NineDevice9 *This,
IDirect3DSurface9 *pSurface,
const RECT *pRect,
D3DCOLOR color );
HRESULT NINE_WINAPI
NineDevice9_CreateOffscreenPlainSurface( struct NineDevice9 *This,
UINT Width,
UINT Height,
D3DFORMAT Format,
D3DPOOL Pool,
IDirect3DSurface9 **ppSurface,
HANDLE *pSharedHandle );
HRESULT NINE_WINAPI
NineDevice9_SetRenderTarget( struct NineDevice9 *This,
DWORD RenderTargetIndex,
IDirect3DSurface9 *pRenderTarget );
HRESULT NINE_WINAPI
NineDevice9_GetRenderTarget( struct NineDevice9 *This,
DWORD RenderTargetIndex,
IDirect3DSurface9 **ppRenderTarget );
HRESULT NINE_WINAPI
NineDevice9_SetDepthStencilSurface( struct NineDevice9 *This,
IDirect3DSurface9 *pNewZStencil );
HRESULT NINE_WINAPI
NineDevice9_GetDepthStencilSurface( struct NineDevice9 *This,
IDirect3DSurface9 **ppZStencilSurface );
HRESULT NINE_WINAPI
NineDevice9_BeginScene( struct NineDevice9 *This );
HRESULT NINE_WINAPI
NineDevice9_EndScene( struct NineDevice9 *This );
HRESULT NINE_WINAPI
NineDevice9_Clear( struct NineDevice9 *This,
DWORD Count,
const D3DRECT *pRects,
DWORD Flags,
D3DCOLOR Color,
float Z,
DWORD Stencil );
HRESULT NINE_WINAPI
NineDevice9_SetTransform( struct NineDevice9 *This,
D3DTRANSFORMSTATETYPE State,
const D3DMATRIX *pMatrix );
HRESULT NINE_WINAPI
NineDevice9_GetTransform( struct NineDevice9 *This,
D3DTRANSFORMSTATETYPE State,
D3DMATRIX *pMatrix );
HRESULT NINE_WINAPI
NineDevice9_MultiplyTransform( struct NineDevice9 *This,
D3DTRANSFORMSTATETYPE State,
const D3DMATRIX *pMatrix );
HRESULT NINE_WINAPI
NineDevice9_SetViewport( struct NineDevice9 *This,
const D3DVIEWPORT9 *pViewport );
HRESULT NINE_WINAPI
NineDevice9_GetViewport( struct NineDevice9 *This,
D3DVIEWPORT9 *pViewport );
HRESULT NINE_WINAPI
NineDevice9_SetMaterial( struct NineDevice9 *This,
const D3DMATERIAL9 *pMaterial );
HRESULT NINE_WINAPI
NineDevice9_GetMaterial( struct NineDevice9 *This,
D3DMATERIAL9 *pMaterial );
HRESULT NINE_WINAPI
NineDevice9_SetLight( struct NineDevice9 *This,
DWORD Index,
const D3DLIGHT9 *pLight );
HRESULT NINE_WINAPI
NineDevice9_GetLight( struct NineDevice9 *This,
DWORD Index,
D3DLIGHT9 *pLight );
HRESULT NINE_WINAPI
NineDevice9_LightEnable( struct NineDevice9 *This,
DWORD Index,
BOOL Enable );
HRESULT NINE_WINAPI
NineDevice9_GetLightEnable( struct NineDevice9 *This,
DWORD Index,
BOOL *pEnable );
HRESULT NINE_WINAPI
NineDevice9_SetClipPlane( struct NineDevice9 *This,
DWORD Index,
const float *pPlane );
HRESULT NINE_WINAPI
NineDevice9_GetClipPlane( struct NineDevice9 *This,
DWORD Index,
float *pPlane );
HRESULT NINE_WINAPI
NineDevice9_SetRenderState( struct NineDevice9 *This,
D3DRENDERSTATETYPE State,
DWORD Value );
HRESULT NINE_WINAPI
NineDevice9_GetRenderState( struct NineDevice9 *This,
D3DRENDERSTATETYPE State,
DWORD *pValue );
HRESULT NINE_WINAPI
NineDevice9_CreateStateBlock( struct NineDevice9 *This,
D3DSTATEBLOCKTYPE Type,
IDirect3DStateBlock9 **ppSB );
HRESULT NINE_WINAPI
NineDevice9_BeginStateBlock( struct NineDevice9 *This );
HRESULT NINE_WINAPI
NineDevice9_EndStateBlock( struct NineDevice9 *This,
IDirect3DStateBlock9 **ppSB );
HRESULT NINE_WINAPI
NineDevice9_SetClipStatus( struct NineDevice9 *This,
const D3DCLIPSTATUS9 *pClipStatus );
HRESULT NINE_WINAPI
NineDevice9_GetClipStatus( struct NineDevice9 *This,
D3DCLIPSTATUS9 *pClipStatus );
HRESULT NINE_WINAPI
NineDevice9_GetTexture( struct NineDevice9 *This,
DWORD Stage,
IDirect3DBaseTexture9 **ppTexture );
HRESULT NINE_WINAPI
NineDevice9_SetTexture( struct NineDevice9 *This,
DWORD Stage,
IDirect3DBaseTexture9 *pTexture );
HRESULT NINE_WINAPI
NineDevice9_GetTextureStageState( struct NineDevice9 *This,
DWORD Stage,
D3DTEXTURESTAGESTATETYPE Type,
DWORD *pValue );
HRESULT NINE_WINAPI
NineDevice9_SetTextureStageState( struct NineDevice9 *This,
DWORD Stage,
D3DTEXTURESTAGESTATETYPE Type,
DWORD Value );
HRESULT NINE_WINAPI
NineDevice9_GetSamplerState( struct NineDevice9 *This,
DWORD Sampler,
D3DSAMPLERSTATETYPE Type,
DWORD *pValue );
HRESULT NINE_WINAPI
NineDevice9_SetSamplerState( struct NineDevice9 *This,
DWORD Sampler,
D3DSAMPLERSTATETYPE Type,
DWORD Value );
HRESULT NINE_WINAPI
NineDevice9_ValidateDevice( struct NineDevice9 *This,
DWORD *pNumPasses );
HRESULT NINE_WINAPI
NineDevice9_SetPaletteEntries( struct NineDevice9 *This,
UINT PaletteNumber,
const PALETTEENTRY *pEntries );
HRESULT NINE_WINAPI
NineDevice9_GetPaletteEntries( struct NineDevice9 *This,
UINT PaletteNumber,
PALETTEENTRY *pEntries );
HRESULT NINE_WINAPI
NineDevice9_SetCurrentTexturePalette( struct NineDevice9 *This,
UINT PaletteNumber );
HRESULT NINE_WINAPI
NineDevice9_GetCurrentTexturePalette( struct NineDevice9 *This,
UINT *PaletteNumber );
HRESULT NINE_WINAPI
NineDevice9_SetScissorRect( struct NineDevice9 *This,
const RECT *pRect );
HRESULT NINE_WINAPI
NineDevice9_GetScissorRect( struct NineDevice9 *This,
RECT *pRect );
HRESULT NINE_WINAPI
NineDevice9_SetSoftwareVertexProcessing( struct NineDevice9 *This,
BOOL bSoftware );
BOOL NINE_WINAPI
NineDevice9_GetSoftwareVertexProcessing( struct NineDevice9 *This );
HRESULT NINE_WINAPI
NineDevice9_SetNPatchMode( struct NineDevice9 *This,
float nSegments );
float NINE_WINAPI
NineDevice9_GetNPatchMode( struct NineDevice9 *This );
HRESULT NINE_WINAPI
NineDevice9_DrawPrimitive( struct NineDevice9 *This,
D3DPRIMITIVETYPE PrimitiveType,
UINT StartVertex,
UINT PrimitiveCount );
HRESULT NINE_WINAPI
NineDevice9_DrawIndexedPrimitive( struct NineDevice9 *This,
D3DPRIMITIVETYPE PrimitiveType,
INT BaseVertexIndex,
UINT MinVertexIndex,
UINT NumVertices,
UINT startIndex,
UINT primCount );
HRESULT NINE_WINAPI
NineDevice9_DrawPrimitiveUP( struct NineDevice9 *This,
D3DPRIMITIVETYPE PrimitiveType,
UINT PrimitiveCount,
const void *pVertexStreamZeroData,
UINT VertexStreamZeroStride );
HRESULT NINE_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 NINE_WINAPI
NineDevice9_ProcessVertices( struct NineDevice9 *This,
UINT SrcStartIndex,
UINT DestIndex,
UINT VertexCount,
IDirect3DVertexBuffer9 *pDestBuffer,
IDirect3DVertexDeclaration9 *pVertexDecl,
DWORD Flags );
HRESULT NINE_WINAPI
NineDevice9_CreateVertexDeclaration( struct NineDevice9 *This,
const D3DVERTEXELEMENT9 *pVertexElements,
IDirect3DVertexDeclaration9 **ppDecl );
HRESULT NINE_WINAPI
NineDevice9_SetVertexDeclaration( struct NineDevice9 *This,
IDirect3DVertexDeclaration9 *pDecl );
HRESULT NINE_WINAPI
NineDevice9_GetVertexDeclaration( struct NineDevice9 *This,
IDirect3DVertexDeclaration9 **ppDecl );
HRESULT NINE_WINAPI
NineDevice9_SetFVF( struct NineDevice9 *This,
DWORD FVF );
HRESULT NINE_WINAPI
NineDevice9_GetFVF( struct NineDevice9 *This,
DWORD *pFVF );
HRESULT NINE_WINAPI
NineDevice9_CreateVertexShader( struct NineDevice9 *This,
const DWORD *pFunction,
IDirect3DVertexShader9 **ppShader );
HRESULT NINE_WINAPI
NineDevice9_SetVertexShader( struct NineDevice9 *This,
IDirect3DVertexShader9 *pShader );
HRESULT NINE_WINAPI
NineDevice9_GetVertexShader( struct NineDevice9 *This,
IDirect3DVertexShader9 **ppShader );
HRESULT NINE_WINAPI
NineDevice9_SetVertexShaderConstantF( struct NineDevice9 *This,
UINT StartRegister,
const float *pConstantData,
UINT Vector4fCount );
HRESULT NINE_WINAPI
NineDevice9_GetVertexShaderConstantF( struct NineDevice9 *This,
UINT StartRegister,
float *pConstantData,
UINT Vector4fCount );
HRESULT NINE_WINAPI
NineDevice9_SetVertexShaderConstantI( struct NineDevice9 *This,
UINT StartRegister,
const int *pConstantData,
UINT Vector4iCount );
HRESULT NINE_WINAPI
NineDevice9_GetVertexShaderConstantI( struct NineDevice9 *This,
UINT StartRegister,
int *pConstantData,
UINT Vector4iCount );
HRESULT NINE_WINAPI
NineDevice9_SetVertexShaderConstantB( struct NineDevice9 *This,
UINT StartRegister,
const BOOL *pConstantData,
UINT BoolCount );
HRESULT NINE_WINAPI
NineDevice9_GetVertexShaderConstantB( struct NineDevice9 *This,
UINT StartRegister,
BOOL *pConstantData,
UINT BoolCount );
HRESULT NINE_WINAPI
NineDevice9_SetStreamSource( struct NineDevice9 *This,
UINT StreamNumber,
IDirect3DVertexBuffer9 *pStreamData,
UINT OffsetInBytes,
UINT Stride );
HRESULT NINE_WINAPI
NineDevice9_GetStreamSource( struct NineDevice9 *This,
UINT StreamNumber,
IDirect3DVertexBuffer9 **ppStreamData,
UINT *pOffsetInBytes,
UINT *pStride );
HRESULT NINE_WINAPI
NineDevice9_SetStreamSourceFreq( struct NineDevice9 *This,
UINT StreamNumber,
UINT Setting );
HRESULT NINE_WINAPI
NineDevice9_GetStreamSourceFreq( struct NineDevice9 *This,
UINT StreamNumber,
UINT *pSetting );
HRESULT NINE_WINAPI
NineDevice9_SetIndices( struct NineDevice9 *This,
IDirect3DIndexBuffer9 *pIndexData );
HRESULT NINE_WINAPI
NineDevice9_GetIndices( struct NineDevice9 *This,
IDirect3DIndexBuffer9 **ppIndexData /*,
UINT *pBaseVertexIndex */ );
HRESULT NINE_WINAPI
NineDevice9_CreatePixelShader( struct NineDevice9 *This,
const DWORD *pFunction,
IDirect3DPixelShader9 **ppShader );
HRESULT NINE_WINAPI
NineDevice9_SetPixelShader( struct NineDevice9 *This,
IDirect3DPixelShader9 *pShader );
HRESULT NINE_WINAPI
NineDevice9_GetPixelShader( struct NineDevice9 *This,
IDirect3DPixelShader9 **ppShader );
HRESULT NINE_WINAPI
NineDevice9_SetPixelShaderConstantF( struct NineDevice9 *This,
UINT StartRegister,
const float *pConstantData,
UINT Vector4fCount );
HRESULT NINE_WINAPI
NineDevice9_GetPixelShaderConstantF( struct NineDevice9 *This,
UINT StartRegister,
float *pConstantData,
UINT Vector4fCount );
HRESULT NINE_WINAPI
NineDevice9_SetPixelShaderConstantI( struct NineDevice9 *This,
UINT StartRegister,
const int *pConstantData,
UINT Vector4iCount );
HRESULT NINE_WINAPI
NineDevice9_GetPixelShaderConstantI( struct NineDevice9 *This,
UINT StartRegister,
int *pConstantData,
UINT Vector4iCount );
HRESULT NINE_WINAPI
NineDevice9_SetPixelShaderConstantB( struct NineDevice9 *This,
UINT StartRegister,
const BOOL *pConstantData,
UINT BoolCount );
HRESULT NINE_WINAPI
NineDevice9_GetPixelShaderConstantB( struct NineDevice9 *This,
UINT StartRegister,
BOOL *pConstantData,
UINT BoolCount );
HRESULT NINE_WINAPI
NineDevice9_DrawRectPatch( struct NineDevice9 *This,
UINT Handle,
const float *pNumSegs,
const D3DRECTPATCH_INFO *pRectPatchInfo );
HRESULT NINE_WINAPI
NineDevice9_DrawTriPatch( struct NineDevice9 *This,
UINT Handle,
const float *pNumSegs,
const D3DTRIPATCH_INFO *pTriPatchInfo );
HRESULT NINE_WINAPI
NineDevice9_DeletePatch( struct NineDevice9 *This,
UINT Handle );
HRESULT NINE_WINAPI
NineDevice9_CreateQuery( struct NineDevice9 *This,
D3DQUERYTYPE Type,
IDirect3DQuery9 **ppQuery );
#endif /* _NINE_DEVICE9_H_ */

View file

@ -1,517 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#include "device9.h"
#include "device9ex.h"
#include "nine_pipe.h"
#include "swapchain9ex.h"
#include "nine_helpers.h"
#include "util/macros.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,
int minorVersionNum )
{
DBG("This=%p pParams=%p pScreen=%p pCreationParameters=%p pCaps=%p "
"pPresentationParameters=%p pFullscreenDisplayMode=%p "
"pD3D9Ex=%p pPresentationGroup=%p pCTX=%p\n",
This, pParams, pScreen, pCreationParameters, pCaps,
pPresentationParameters, pFullscreenDisplayMode,
pD3D9Ex, pPresentationGroup, pCTX);
return NineDevice9_ctor(&This->base, pParams,
pScreen, pCreationParameters, pCaps,
pPresentationParameters,
(IDirect3D9 *)pD3D9Ex, pPresentationGroup, pCTX,
true, pFullscreenDisplayMode, minorVersionNum);
}
static void
NineDevice9Ex_dtor( struct NineDevice9Ex *This )
{
NineDevice9_dtor(&This->base);
}
HRESULT NINE_WINAPI
NineDevice9Ex_SetConvolutionMonoKernel( UNUSED struct NineDevice9Ex *This,
UNUSED UINT width,
UNUSED UINT height,
UNUSED float *rows,
UNUSED float *columns )
{
DBG("This\n");
STUB(D3D_OK);
}
HRESULT NINE_WINAPI
NineDevice9Ex_ComposeRects( UNUSED struct NineDevice9Ex *This,
UNUSED IDirect3DSurface9 *pSrc,
UNUSED IDirect3DSurface9 *pDst,
UNUSED IDirect3DVertexBuffer9 *pSrcRectDescs,
UNUSED UINT NumRects,
UNUSED IDirect3DVertexBuffer9 *pDstRectDescs,
UNUSED D3DCOMPOSERECTSOP Operation,
UNUSED int Xoffset,
UNUSED int Yoffset )
{
DBG("This\n");
STUB(D3D_OK);
}
HRESULT NINE_WINAPI
NineDevice9Ex_PresentEx( struct NineDevice9Ex *This,
const RECT *pSourceRect,
const RECT *pDestRect,
HWND hDestWindowOverride,
const RGNDATA *pDirtyRegion,
DWORD dwFlags )
{
unsigned i;
HRESULT hr;
DBG("This=%p pSourceRect=%p pDestRect=%p hDestWindowOverride=%p "
"pDirtyRegion=%p dwFlags=%d\n",
This, pSourceRect, pDestRect, hDestWindowOverride,
pDirtyRegion, dwFlags);
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 NINE_WINAPI
NineDevice9Ex_GetGPUThreadPriority( struct NineDevice9Ex *This,
INT *pPriority )
{
DBG("This\n");
user_assert(pPriority != NULL, D3DERR_INVALIDCALL);
*pPriority = This->base.gpu_priority;
return D3D_OK;
}
HRESULT NINE_WINAPI
NineDevice9Ex_SetGPUThreadPriority( struct NineDevice9Ex *This,
INT Priority )
{
DBG("This\n");
user_assert(Priority >= -7 && Priority <= 7, D3DERR_INVALIDCALL);
This->base.gpu_priority = Priority;
return D3D_OK;
}
HRESULT NINE_WINAPI
NineDevice9Ex_WaitForVBlank( UNUSED struct NineDevice9Ex *This,
UNUSED UINT iSwapChain )
{
DBG("This\n");
STUB(D3D_OK);
}
HRESULT NINE_WINAPI
NineDevice9Ex_CheckResourceResidency( UNUSED struct NineDevice9Ex *This,
UNUSED IDirect3DResource9 **pResourceArray,
UNUSED UINT32 NumResources )
{
DBG("This\n");
STUB(D3D_OK);
}
HRESULT NINE_WINAPI
NineDevice9Ex_SetMaximumFrameLatency( struct NineDevice9Ex *This,
UINT MaxLatency )
{
DBG("This\n");
This->base.max_frame_latency = MaxLatency;
return D3D_OK;
}
HRESULT NINE_WINAPI
NineDevice9Ex_GetMaximumFrameLatency( struct NineDevice9Ex *This,
UINT *pMaxLatency )
{
DBG("This\n");
user_assert(pMaxLatency != NULL, D3DERR_INVALIDCALL);
*pMaxLatency = This->base.max_frame_latency;
return D3D_OK;
}
HRESULT NINE_WINAPI
NineDevice9Ex_CheckDeviceState( struct NineDevice9Ex *This,
HWND hDestinationWindow )
{
DBG("This=%p hDestinationWindow=%p\n",
This, hDestinationWindow);
user_assert(!This->base.swapchains[0]->params.Windowed, D3D_OK);
if (This->base.params.hFocusWindow == hDestinationWindow) {
if (NineSwapChain9_GetOccluded(This->base.swapchains[0]))
return S_PRESENT_OCCLUDED;
} else if(!NineSwapChain9_GetOccluded(This->base.swapchains[0])) {
return S_PRESENT_OCCLUDED;
}
/* TODO: handle the other return values */
return D3D_OK;
}
HRESULT NINE_WINAPI
NineDevice9Ex_CreateRenderTargetEx( struct NineDevice9Ex *This,
UINT Width,
UINT Height,
D3DFORMAT Format,
D3DMULTISAMPLE_TYPE MultiSample,
DWORD MultisampleQuality,
BOOL Lockable,
IDirect3DSurface9 **ppSurface,
HANDLE *pSharedHandle,
UNUSED DWORD Usage )
{
DBG("This\n");
/* The Create*Ex functions only purpose seem to introduce the
* Usage field, to pass the new d3d9ex flags on secure/restricted
* content.
* TODO: Return error on invalid Usage.
* TODO: Store Usage in the surface descriptor, in case the
* app checks */
return NineDevice9_CreateRenderTarget(&This->base,
Width,
Height,
Format,
MultiSample,
MultisampleQuality,
Lockable,
ppSurface,
pSharedHandle);
}
HRESULT NINE_WINAPI
NineDevice9Ex_CreateOffscreenPlainSurfaceEx( struct NineDevice9Ex *This,
UINT Width,
UINT Height,
D3DFORMAT Format,
D3DPOOL Pool,
IDirect3DSurface9 **ppSurface,
HANDLE *pSharedHandle,
UNUSED DWORD Usage )
{
DBG("This\n");
/* The Create*Ex functions only purpose seem to introduce the
* Usage field, to pass the new d3d9ex flags on secure/restricted
* content.
* TODO: Return error on invalid Usage.
* TODO: Store Usage in the surface descriptor, in case the
* app checks */
return NineDevice9_CreateOffscreenPlainSurface(&This->base,
Width,
Height,
Format,
Pool,
ppSurface,
pSharedHandle);
}
HRESULT NINE_WINAPI
NineDevice9Ex_CreateDepthStencilSurfaceEx( struct NineDevice9Ex *This,
UINT Width,
UINT Height,
D3DFORMAT Format,
D3DMULTISAMPLE_TYPE MultiSample,
DWORD MultisampleQuality,
BOOL Discard,
IDirect3DSurface9 **ppSurface,
HANDLE *pSharedHandle,
UNUSED DWORD Usage )
{
DBG("This\n");
/* The Create*Ex functions only purpose seem to introduce the
* Usage field, to pass the new d3d9ex flags on secure/restricted
* content.
* TODO: Return error on invalid Usage.
* TODO: Store Usage in the surface descriptor, in case the
* app checks */
return NineDevice9_CreateDepthStencilSurface(&This->base,
Width,
Height,
Format,
MultiSample,
MultisampleQuality,
Discard,
ppSurface,
pSharedHandle);
}
HRESULT NINE_WINAPI
NineDevice9Ex_ResetEx( struct NineDevice9Ex *This,
D3DPRESENT_PARAMETERS *pPresentationParameters,
D3DDISPLAYMODEEX *pFullscreenDisplayMode )
{
HRESULT hr = D3D_OK;
float MinZ, MaxZ;
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))
break;
}
MinZ = This->base.state.viewport.MinZ; /* These are preserved */
MaxZ = This->base.state.viewport.MaxZ;
NineDevice9_SetRenderTarget(
(struct NineDevice9 *)This, 0, (IDirect3DSurface9 *)This->base.swapchains[0]->buffers[0]);
This->base.state.viewport.MinZ = MinZ;
This->base.state.viewport.MaxZ = MaxZ;
nine_context_set_viewport(&This->base, &This->base.state.viewport);
if (This->base.nswapchains && This->base.swapchains[0]->params.EnableAutoDepthStencil)
NineDevice9_SetDepthStencilSurface(
&This->base, (IDirect3DSurface9 *)This->base.swapchains[0]->zsbuf);
return hr;
}
HRESULT NINE_WINAPI
NineDevice9Ex_Reset( struct NineDevice9Ex *This,
D3DPRESENT_PARAMETERS *pPresentationParameters )
{
HRESULT hr = D3D_OK;
float MinZ, MaxZ;
unsigned i;
DBG("This=%p pPresentationParameters=%p\n", This, pPresentationParameters);
for (i = 0; i < This->base.nswapchains; ++i) {
D3DPRESENT_PARAMETERS *params = &pPresentationParameters[i];
hr = NineSwapChain9_Resize(This->base.swapchains[i], params, NULL);
if (FAILED(hr))
break;
}
MinZ = This->base.state.viewport.MinZ; /* These are preserved */
MaxZ = This->base.state.viewport.MaxZ;
NineDevice9_SetRenderTarget(
(struct NineDevice9 *)This, 0, (IDirect3DSurface9 *)This->base.swapchains[0]->buffers[0]);
This->base.state.viewport.MinZ = MinZ;
This->base.state.viewport.MaxZ = MaxZ;
nine_context_set_viewport(&This->base, &This->base.state.viewport);
if (This->base.nswapchains && This->base.swapchains[0]->params.EnableAutoDepthStencil)
NineDevice9_SetDepthStencilSurface(
&This->base, (IDirect3DSurface9 *)This->base.swapchains[0]->zsbuf);
return hr;
}
HRESULT NINE_WINAPI
NineDevice9Ex_GetDisplayModeEx( struct NineDevice9Ex *This,
UINT iSwapChain,
D3DDISPLAYMODEEX *pMode,
D3DDISPLAYROTATION *pRotation )
{
struct NineSwapChain9Ex *swapchain;
DBG("This=%p iSwapChain=%u pMode=%p pRotation=%p\n",
This, iSwapChain, pMode, pRotation);
user_assert(iSwapChain < This->base.nswapchains, D3DERR_INVALIDCALL);
swapchain = NineSwapChain9Ex(This->base.swapchains[iSwapChain]);
return NineSwapChain9Ex_GetDisplayModeEx(swapchain, pMode, pRotation);
}
HRESULT NINE_WINAPI
NineDevice9Ex_TestCooperativeLevel( UNUSED struct NineDevice9Ex *This )
{
DBG("This\n");
return D3D_OK;
}
IDirect3DDevice9ExVtbl NineDevice9Ex_vtable = {
(void *)NineUnknown_QueryInterface,
(void *)NineUnknown_AddRef,
(void *)NineUnknown_Release,
(void *)NineDevice9Ex_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 *)NineDevice9Ex_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,
int minorVersionNum )
{
BOOL lock;
lock = !!(pCreationParameters->BehaviorFlags & D3DCREATE_MULTITHREADED);
NINE_NEW(Device9Ex, ppOut, lock,
pScreen, pCreationParameters, pCaps, pPresentationParameters,
pFullscreenDisplayMode, pD3D9Ex, pPresentationGroup, pCTX, minorVersionNum );
}

View file

@ -1,147 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#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,
int minorVersionNum );
HRESULT NINE_WINAPI
NineDevice9Ex_SetConvolutionMonoKernel( struct NineDevice9Ex *This,
UINT width,
UINT height,
float *rows,
float *columns );
HRESULT NINE_WINAPI
NineDevice9Ex_ComposeRects( struct NineDevice9Ex *This,
IDirect3DSurface9 *pSrc,
IDirect3DSurface9 *pDst,
IDirect3DVertexBuffer9 *pSrcRectDescs,
UINT NumRects,
IDirect3DVertexBuffer9 *pDstRectDescs,
D3DCOMPOSERECTSOP Operation,
int Xoffset,
int Yoffset );
HRESULT NINE_WINAPI
NineDevice9Ex_PresentEx( struct NineDevice9Ex *This,
const RECT *pSourceRect,
const RECT *pDestRect,
HWND hDestWindowOverride,
const RGNDATA *pDirtyRegion,
DWORD dwFlags );
HRESULT NINE_WINAPI
NineDevice9Ex_Present( struct NineDevice9Ex *This,
const RECT *pSourceRect,
const RECT *pDestRect,
HWND hDestWindowOverride,
const RGNDATA *pDirtyRegion );
HRESULT NINE_WINAPI
NineDevice9Ex_GetGPUThreadPriority( struct NineDevice9Ex *This,
INT *pPriority );
HRESULT NINE_WINAPI
NineDevice9Ex_SetGPUThreadPriority( struct NineDevice9Ex *This,
INT Priority );
HRESULT NINE_WINAPI
NineDevice9Ex_WaitForVBlank( struct NineDevice9Ex *This,
UINT iSwapChain );
HRESULT NINE_WINAPI
NineDevice9Ex_CheckResourceResidency( struct NineDevice9Ex *This,
IDirect3DResource9 **pResourceArray,
UINT32 NumResources );
HRESULT NINE_WINAPI
NineDevice9Ex_SetMaximumFrameLatency( struct NineDevice9Ex *This,
UINT MaxLatency );
HRESULT NINE_WINAPI
NineDevice9Ex_GetMaximumFrameLatency( struct NineDevice9Ex *This,
UINT *pMaxLatency );
HRESULT NINE_WINAPI
NineDevice9Ex_CheckDeviceState( struct NineDevice9Ex *This,
HWND hDestinationWindow );
HRESULT NINE_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 NINE_WINAPI
NineDevice9Ex_CreateOffscreenPlainSurfaceEx( struct NineDevice9Ex *This,
UINT Width,
UINT Height,
D3DFORMAT Format,
D3DPOOL Pool,
IDirect3DSurface9 **ppSurface,
HANDLE *pSharedHandle,
DWORD Usage );
HRESULT NINE_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 NINE_WINAPI
NineDevice9Ex_ResetEx( struct NineDevice9Ex *This,
D3DPRESENT_PARAMETERS *pPresentationParameters,
D3DDISPLAYMODEEX *pFullscreenDisplayMode );
HRESULT NINE_WINAPI
NineDevice9Ex_Reset( struct NineDevice9Ex *This,
D3DPRESENT_PARAMETERS *pPresentationParameters );
HRESULT NINE_WINAPI
NineDevice9Ex_GetDisplayModeEx( struct NineDevice9Ex *This,
UINT iSwapChain,
D3DDISPLAYMODEEX *pMode,
D3DDISPLAYROTATION *pRotation );
HRESULT NINE_WINAPI
NineDevice9Ex_TestCooperativeLevel( struct NineDevice9Ex *This );
#endif /* _NINE_DEVICE9EX_H_ */

View file

@ -1,45 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#include "device9video.h"
#define DBG_CHANNEL DBG_DEVICEVIDEO
HRESULT NINE_WINAPI
NineDevice9Video_GetContentProtectionCaps( struct NineDevice9Video *This,
const GUID *pCryptoType,
const GUID *pDecodeProfile,
D3DCONTENTPROTECTIONCAPS *pCaps )
{
STUB(D3DERR_INVALIDCALL);
}
HRESULT NINE_WINAPI
NineDevice9Video_CreateAuthenticatedChannel( struct NineDevice9Video *This,
D3DAUTHENTICATEDCHANNELTYPE ChannelType,
IDirect3DAuthenticatedChannel9 **ppAuthenticatedChannel,
HANDLE *pChannelHandle )
{
STUB(D3DERR_INVALIDCALL);
}
HRESULT NINE_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

@ -1,40 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#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 NINE_WINAPI
NineDevice9Video_GetContentProtectionCaps( struct NineDevice9Video *This,
const GUID *pCryptoType,
const GUID *pDecodeProfile,
D3DCONTENTPROTECTIONCAPS *pCaps );
HRESULT NINE_WINAPI
NineDevice9Video_CreateAuthenticatedChannel( struct NineDevice9Video *This,
D3DAUTHENTICATEDCHANNELTYPE ChannelType,
IDirect3DAuthenticatedChannel9 **ppAuthenticatedChannel,
HANDLE *pChannelHandle );
HRESULT NINE_WINAPI
NineDevice9Video_CreateCryptoSession( struct NineDevice9Video *This,
const GUID *pCryptoType,
const GUID *pDecodeProfile,
IDirect3DCryptoSession9 **ppCryptoSession,
HANDLE *pCryptoHandle );
#endif /* _NINE_DEVICE9VIDEO_H_ */

View file

@ -1,67 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#include <stdio.h>
#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 } };
bool
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;
}
char* GUID_sprintf(char *guid_str, REFGUID id) {
sprintf( guid_str,
"{%08X,%04X,%04X,%02X%02X%02X%02X%02X%02X%02X%02X}",
id->Data1,
id->Data2,
id->Data3,
id->Data4[0],
id->Data4[1],
id->Data4[2],
id->Data4[3],
id->Data4[4],
id->Data4[5],
id->Data4[6],
id->Data4[7]);
return guid_str;
}

View file

@ -1,23 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_GUID_H_
#define _NINE_GUID_H_
#include "util/compiler.h"
#include "d3d9types.h"
extern const GUID IID_ID3D9Adapter;
bool
GUID_equal( const GUID *a,
const GUID *b );
char*
GUID_sprintf( char *guid_str,
REFGUID id );
#endif /* _NINE_GUID_H_ */

View file

@ -1,117 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#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 "util/format/u_formats.h"
#include "util/box.h"
#define DBG_CHANNEL DBG_INDEXBUFFER
HRESULT
NineIndexBuffer9_ctor( struct NineIndexBuffer9 *This,
struct NineUnknownParams *pParams,
D3DINDEXBUFFER_DESC *pDesc )
{
HRESULT hr;
DBG("This=%p pParams=%p pDesc=%p Usage=%s\n",
This, pParams, pDesc, nine_D3DUSAGE_to_str(pDesc->Usage));
hr = NineBuffer9_ctor(&This->base, pParams, D3DRTYPE_INDEXBUFFER,
pDesc->Usage, pDesc->Size, pDesc->Pool);
if (FAILED(hr))
return hr;
switch (pDesc->Format) {
case D3DFMT_INDEX16: This->index_size = 2; break;
case D3DFMT_INDEX32: This->index_size = 4; break;
default:
user_assert(!"Invalid index format.", D3DERR_INVALIDCALL);
break;
}
pDesc->Type = D3DRTYPE_INDEXBUFFER;
This->desc = *pDesc;
return D3D_OK;
}
void
NineIndexBuffer9_dtor( struct NineIndexBuffer9 *This )
{
NineBuffer9_dtor(&This->base);
}
struct pipe_resource *
NineIndexBuffer9_GetBuffer( struct NineIndexBuffer9 *This, unsigned *offset )
{
/* The resource may change */
return NineBuffer9_GetResource(&This->base, offset);
}
HRESULT NINE_WINAPI
NineIndexBuffer9_Lock( struct NineIndexBuffer9 *This,
UINT OffsetToLock,
UINT SizeToLock,
void **ppbData,
DWORD Flags )
{
return NineBuffer9_Lock(&This->base, OffsetToLock, SizeToLock, ppbData, Flags);
}
HRESULT NINE_WINAPI
NineIndexBuffer9_Unlock( struct NineIndexBuffer9 *This )
{
return NineBuffer9_Unlock(&This->base);
}
HRESULT NINE_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 *)NineUnknown_SetPrivateData,
(void *)NineUnknown_GetPrivateData,
(void *)NineUnknown_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

@ -1,68 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_INDEXBUFFER9_H_
#define _NINE_INDEXBUFFER9_H_
#include "resource9.h"
#include "buffer9.h"
#include "pipe/p_state.h"
struct pipe_screen;
struct pipe_context;
struct pipe_transfer;
struct NineDevice9;
struct NineIndexBuffer9
{
struct NineBuffer9 base;
/* g3d stuff */
unsigned index_size;
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 ***/
struct pipe_resource *
NineIndexBuffer9_GetBuffer( struct NineIndexBuffer9 *This,
unsigned *offset );
/*** Direct3D public ***/
HRESULT NINE_WINAPI
NineIndexBuffer9_Lock( struct NineIndexBuffer9 *This,
UINT OffsetToLock,
UINT SizeToLock,
void **ppbData,
DWORD Flags );
HRESULT NINE_WINAPI
NineIndexBuffer9_Unlock( struct NineIndexBuffer9 *This );
HRESULT NINE_WINAPI
NineIndexBuffer9_GetDesc( struct NineIndexBuffer9 *This,
D3DINDEXBUFFER_DESC *pDesc );
#endif /* _NINE_INDEXBUFFER9_H_ */

View file

@ -1,293 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#include "iunknown.h"
#include "util/u_atomic.h"
#include "util/hash_table.h"
#include "nine_helpers.h"
#include "nine_pdata.h"
#include "nine_lock.h"
#define DBG_CHANNEL DBG_UNKNOWN
HRESULT
NineUnknown_ctor( struct NineUnknown *This,
struct NineUnknownParams *pParams )
{
if (pParams->container) {
This->refs = 0;
This->forward = true;
This->bind = 0;
assert(!pParams->start_with_bind_not_ref);
} else if (pParams->start_with_bind_not_ref) {
This->refs = 0;
This->forward = false;
This->bind = 1;
} else {
This->refs = 1;
This->forward = false;
This->bind = 0;
}
This->has_bind_or_refs = This->bind + 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->vtable_internal = pParams->vtable;
This->guids = pParams->guids;
This->dtor = pParams->dtor;
This->pdata = _mesa_hash_table_create(NULL, ht_guid_hash, ht_guid_compare);
if (!This->pdata)
return E_OUTOFMEMORY;
return D3D_OK;
}
void
NineUnknown_dtor( struct NineUnknown *This )
{
if (This->refs && This->device) /* Possible only if early exit after a ctor failed */
(void) NineUnknown_Release(NineUnknown(This->device));
if (This->pdata)
_mesa_hash_table_destroy(This->pdata, ht_guid_delete);
FREE(This);
}
HRESULT NINE_WINAPI
NineUnknown_QueryInterface( struct NineUnknown *This,
REFIID riid,
void **ppvObject )
{
unsigned i = 0;
char guid_str[64];
DBG("This=%p riid=%p id=%s ppvObject=%p\n",
This, riid, riid ? GUID_sprintf(guid_str, riid) : "", ppvObject);
(void)guid_str;
if (!ppvObject) return E_POINTER;
do {
if (GUID_equal(This->guids[i], riid)) {
*ppvObject = This;
/* Tests showed that this call succeeds even on objects with
* zero refcount. This can happen if the app released all references
* but the resource is still bound.
*/
NineUnknown_AddRef(This);
return S_OK;
}
} while (This->guids[++i]);
*ppvObject = NULL;
return E_NOINTERFACE;
}
ULONG NINE_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) {
p_atomic_inc(&This->has_bind_or_refs);
if (This->device)
NineUnknown_AddRef(NineUnknown(This->device));
}
return r;
}
ULONG NINE_WINAPI
NineUnknown_Release( struct NineUnknown *This )
{
if (This->forward)
return NineUnknown_Release(This->container);
/* Cannot decrease lower than 0. This is a thing
* according to wine tests. It's not just clamping
* the result as AddRef after Release while refs is 0
* will give 1 */
if (!p_atomic_read(&This->refs))
return 0;
ULONG r = p_atomic_dec_return(&This->refs);
if (r == 0) {
struct NineDevice9 *device = This->device;
UINT b_or_ref = p_atomic_dec_return(&This->has_bind_or_refs);
/* Containers (here with !forward) take care of item destruction */
if (!This->container && b_or_ref == 0) {
assert(p_atomic_read(&This->bind) == 0);
This->dtor(This);
}
if (device) {
NineUnknown_Release(NineUnknown(device));
}
}
return r;
}
/* No need to lock the mutex protecting nine (when D3DCREATE_MULTITHREADED)
* for AddRef and Release, except for dtor as some of the dtors require it. */
ULONG NINE_WINAPI
NineUnknown_ReleaseWithDtorLock( struct NineUnknown *This )
{
if (This->forward)
return NineUnknown_ReleaseWithDtorLock(This->container);
ULONG r = p_atomic_dec_return(&This->refs);
if (r == 0) {
struct NineDevice9 *device = This->device;
UINT b_or_ref = p_atomic_dec_return(&This->has_bind_or_refs);
/* Containers (here with !forward) take care of item destruction */
if (!This->container && b_or_ref == 0) {
assert(p_atomic_read(&This->bind) == 0);
NineLockGlobalMutex();
This->dtor(This);
NineUnlockGlobalMutex();
}
if (device) {
NineUnknown_ReleaseWithDtorLock(NineUnknown(device));
}
}
return r;
}
HRESULT NINE_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;
}
HRESULT NINE_WINAPI
NineUnknown_SetPrivateData( struct NineUnknown *This,
REFGUID refguid,
const void *pData,
DWORD SizeOfData,
DWORD Flags )
{
struct pheader *header;
const void *user_data = pData;
char guid_str[64];
void *header_data;
DBG("This=%p GUID=%s pData=%p SizeOfData=%u Flags=%x\n",
This, GUID_sprintf(guid_str, refguid), pData, SizeOfData, Flags);
(void)guid_str;
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);
if (!header) { DBG("Returning E_OUTOFMEMORY\n"); return E_OUTOFMEMORY; }
header->unknown = (Flags & D3DSPD_IUNKNOWN) ? true : false;
/* if the refguid already exists, delete it */
NineUnknown_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;
header_data = (void *)header + sizeof(*header);
memcpy(header_data, user_data, header->size);
memcpy(&header->guid, refguid, sizeof(header->guid));
DBG("New header %p, size %d\n", header, (int)header->size);
_mesa_hash_table_insert(This->pdata, &header->guid, header);
if (header->unknown) { IUnknown_AddRef(*(IUnknown **)header_data); }
return D3D_OK;
}
HRESULT NINE_WINAPI
NineUnknown_GetPrivateData( struct NineUnknown *This,
REFGUID refguid,
void *pData,
DWORD *pSizeOfData )
{
struct hash_entry *entry;
struct pheader *header;
DWORD sizeofdata;
char guid_str[64];
void *header_data;
DBG("This=%p GUID=%s pData=%p pSizeOfData=%p\n",
This, GUID_sprintf(guid_str, refguid), pData, pSizeOfData);
(void)guid_str;
entry = _mesa_hash_table_search(This->pdata, refguid);
if (!entry) { DBG("Returning D3DERR_NOTFOUND\n"); return D3DERR_NOTFOUND; }
header = entry->data;
user_assert(pSizeOfData, E_POINTER);
sizeofdata = *pSizeOfData;
*pSizeOfData = header->size;
DBG("Found header %p, size %d. Requested max %d\n", header, (int)header->size, (int)sizeofdata);
if (!pData) {
DBG("Returning early D3D_OK\n");
return D3D_OK;
}
if (sizeofdata < header->size) {
DBG("Returning D3DERR_MOREDATA\n");
return D3DERR_MOREDATA;
}
header_data = (void *)header + sizeof(*header);
if (header->unknown) { IUnknown_AddRef(*(IUnknown **)header_data); }
memcpy(pData, header_data, header->size);
DBG("Returning D3D_OK\n");
return D3D_OK;
}
HRESULT NINE_WINAPI
NineUnknown_FreePrivateData( struct NineUnknown *This,
REFGUID refguid )
{
struct hash_entry *entry;
char guid_str[64];
DBG("This=%p GUID=%s\n", This, GUID_sprintf(guid_str, refguid));
(void)guid_str;
entry = _mesa_hash_table_search(This->pdata, refguid);
if (!entry) {
DBG("Nothing to free\n");
return D3DERR_NOTFOUND;
}
DBG("Freeing %p\n", entry->data);
ht_guid_delete(entry);
_mesa_hash_table_remove(This->pdata, entry);
return D3D_OK;
}

View file

@ -1,169 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_IUNKNOWN_H_
#define _NINE_IUNKNOWN_H_
#include "util/compiler.h"
#include "util/u_atomic.h"
#include "util/u_memory.h"
#include "guid.h"
#include "nine_flags.h"
#include "nine_debug.h"
#include "nine_quirk.h"
#include "d3d9.h"
struct Nine9;
struct NineDevice9;
struct NineUnknown
{
/* pointer to vtable (can be overridden outside gallium nine) */
void *vtable;
/* pointer to internal vtable */
void *vtable_internal;
int32_t refs; /* external reference count */
int32_t bind; /* internal bind count */
int32_t has_bind_or_refs; /* 0 if no ref, 1 if bind or ref, 2 if both */
bool forward; /* whether to forward references to the container */
/* container: for surfaces and volumes only.
* Can be a texture, a volume texture or a swapchain.
* forward is set to false for the swapchain case.
* If forward is set, refs are passed to the container if forward is set
* and the container has bind increased if the object has non null bind. */
struct NineUnknown *container;
struct NineDevice9 *device; /* referenced if (refs) */
const GUID **guids; /* for QueryInterface */
/* for [GS]etPrivateData/FreePrivateData */
struct hash_table *pdata;
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;
bool start_with_bind_not_ref;
};
HRESULT
NineUnknown_ctor( struct NineUnknown *This,
struct NineUnknownParams *pParams );
void
NineUnknown_dtor( struct NineUnknown *This );
/*** Direct3D public methods ***/
HRESULT NINE_WINAPI
NineUnknown_QueryInterface( struct NineUnknown *This,
REFIID riid,
void **ppvObject );
ULONG NINE_WINAPI
NineUnknown_AddRef( struct NineUnknown *This );
ULONG NINE_WINAPI
NineUnknown_Release( struct NineUnknown *This );
ULONG NINE_WINAPI
NineUnknown_ReleaseWithDtorLock( struct NineUnknown *This );
HRESULT NINE_WINAPI
NineUnknown_GetDevice( struct NineUnknown *This,
IDirect3DDevice9 **ppDevice );
HRESULT NINE_WINAPI
NineUnknown_SetPrivateData( struct NineUnknown *This,
REFGUID refguid,
const void *pData,
DWORD SizeOfData,
DWORD Flags );
HRESULT NINE_WINAPI
NineUnknown_GetPrivateData( struct NineUnknown *This,
REFGUID refguid,
void *pData,
DWORD *pSizeOfData );
HRESULT NINE_WINAPI
NineUnknown_FreePrivateData( struct NineUnknown *This,
REFGUID refguid );
/*** Nine private methods ***/
static inline void
NineUnknown_Destroy( struct NineUnknown *This )
{
assert(!(This->refs | This->bind) && !This->has_bind_or_refs);
This->dtor(This);
}
static inline UINT
NineUnknown_Bind( struct NineUnknown *This )
{
UINT b = p_atomic_inc_return(&This->bind);
assert(b);
if (b == 1)
p_atomic_inc(&This->has_bind_or_refs);
if (b == 1 && This->forward)
NineUnknown_Bind(This->container);
return b;
}
static inline UINT
NineUnknown_Unbind( struct NineUnknown *This )
{
UINT b = p_atomic_dec_return(&This->bind);
UINT b_or_ref = 1;
if (b == 0)
b_or_ref = p_atomic_dec_return(&This->has_bind_or_refs);
if (b == 0 && This->forward)
NineUnknown_Unbind(This->container);
else if (b_or_ref == 0 && !This->container)
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);
This->container = NULL;
if (!(This->has_bind_or_refs))
This->dtor(This);
}
#endif /* _NINE_IUNKNOWN_H_ */

View file

@ -1,59 +0,0 @@
# Copyright © 2017 Intel Corporation
# SPDX-License-Identifier: MIT
nine_st_files = files(
'adapter9.c',
'authenticatedchannel9.c',
'basetexture9.c',
'buffer9.c',
'cryptosession9.c',
'cubetexture9.c',
'device9.c',
'device9ex.c',
'device9video.c',
'guid.c',
'indexbuffer9.c',
'iunknown.c',
'nine_buffer_upload.c',
'nine_debug.c',
'nine_dump.c',
'nineexoverlayextension.c',
'nine_ff.c',
'nine_helpers.c',
'nine_lock.c',
'nine_memory_helper.c',
'nine_pipe.c',
'nine_quirk.c',
'nine_queue.c',
'nine_shader.c',
'nine_state.c',
'pixelshader9.c',
'query9.c',
'resource9.c',
'stateblock9.c',
'surface9.c',
'swapchain9.c',
'swapchain9ex.c',
'texture9.c',
'threadpool.c',
'vertexbuffer9.c',
'vertexdeclaration9.c',
'vertexshader9.c',
'volume9.c',
'volumetexture9.c',
)
libnine_st = static_library(
'nine_st',
nine_st_files,
gnu_symbol_visibility : 'hidden',
include_directories : [
inc_d3d9, inc_gallium, inc_include, inc_src, inc_gallium_aux,
],
dependencies : [
dep_thread, idep_nir, idep_nir_headers
],
link_with : [
libmesa
]
)

View file

@ -1,284 +0,0 @@
/*
*
* Copyright 2009 VMware, Inc.
* Copyright 2016 Axel Davy <axel.davy@ens.fr>
* All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*/
/* Adapted from u_upload_mgr.
* Makes suballocations from bigger allocations,
* while enabling fast mapping. */
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
#include "pipe/p_context.h"
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/slab.h"
#include "nine_buffer_upload.h"
#include "nine_debug.h"
#define DBG_CHANNEL (DBG_INDEXBUFFER|DBG_VERTEXBUFFER)
struct nine_buffer_group {
unsigned refcount; /* How many sub-buffers live inside the buffer */
struct pipe_resource *resource;
struct pipe_transfer *transfer;
uint8_t *map;
unsigned free_offset; /* Aligned offset to the upload buffer, pointing
* at the first unused byte. */
};
struct nine_subbuffer {
struct nine_buffer_group *parent; /* Can be NULL */
struct pipe_resource *resource; /* The parent resource if apply */
unsigned offset; /* Offset inside the resource */
/* If there is no parent, the resource map. Else NULL. */
struct pipe_transfer *transfer;
uint8_t *map;
};
struct nine_buffer_upload {
struct pipe_context *pipe;
struct slab_mempool buffer_pool;
unsigned buffers_size; /* Size of the big allocated buffers */
unsigned num_buffers;
struct nine_buffer_group *buffers;
};
static void
nine_upload_create_buffer_group(struct nine_buffer_upload *upload,
struct nine_buffer_group *group)
{
struct pipe_resource resource;
struct pipe_screen *screen = upload->pipe->screen;
DBG("Allocating %p %p\n", upload, group);
memset(&resource, 0, sizeof(resource));
resource.target = PIPE_BUFFER;
resource.format = PIPE_FORMAT_R8_UNORM;
resource.bind = PIPE_BIND_VERTEX_BUFFER;
resource.usage = PIPE_USAGE_STREAM;
resource.width0 = upload->buffers_size;
resource.height0 = 1;
resource.depth0 = 1;
resource.array_size = 1;
resource.flags = PIPE_RESOURCE_FLAG_MAP_PERSISTENT |
PIPE_RESOURCE_FLAG_MAP_COHERENT;
group->refcount = 0;
group->resource = screen->resource_create(screen, &resource);
if (group->resource == NULL)
return;
group->map = pipe_buffer_map_range(upload->pipe, group->resource,
0, upload->buffers_size,
PIPE_MAP_WRITE |
#if DETECT_ARCH_X86
PIPE_MAP_ONCE |
#endif
PIPE_MAP_PERSISTENT |
PIPE_MAP_COHERENT,
&group->transfer);
if (group->map == NULL) {
group->transfer = NULL;
pipe_resource_reference(&group->resource, NULL);
return;
}
group->free_offset = 0;
DBG("Success: %p %p\n", group->map, group->map+upload->buffers_size);
}
static void
nine_upload_destroy_buffer_group(struct nine_buffer_upload *upload,
struct nine_buffer_group *group)
{
DBG("%p %p\n", upload, group);
DBG("Release: %p %p\n", group->map, group->map+upload->buffers_size);
assert(group->refcount == 0);
if (group->transfer)
pipe_buffer_unmap(upload->pipe, group->transfer);
if (group->resource)
pipe_resource_reference(&group->resource, NULL);
group->transfer = NULL;
group->map = NULL;
}
struct nine_buffer_upload *
nine_upload_create(struct pipe_context *pipe, unsigned buffers_size,
unsigned num_buffers)
{
struct nine_buffer_upload *upload;
int i;
DBG("\n");
if (!pipe->screen->caps.buffer_map_persistent_coherent)
return NULL;
upload = CALLOC_STRUCT(nine_buffer_upload);
if (!upload)
return NULL;
slab_create(&upload->buffer_pool, sizeof(struct nine_subbuffer), 4096);
upload->pipe = pipe;
upload->buffers_size = align(buffers_size, 4096);
upload->num_buffers = num_buffers;
upload->buffers = CALLOC(num_buffers, sizeof(struct nine_buffer_group));
if (!upload->buffers)
goto buffers_fail;
for (i = 0; i < num_buffers; i++)
nine_upload_create_buffer_group(upload, &upload->buffers[i]);
return upload;
buffers_fail:
slab_destroy(&upload->buffer_pool);
FREE(upload);
return NULL;
}
void
nine_upload_destroy(struct nine_buffer_upload *upload)
{
int i;
DBG("%p\n", upload);
for (i = 0; i < upload->num_buffers; i++)
nine_upload_destroy_buffer_group(upload, &upload->buffers[i]);
slab_destroy(&upload->buffer_pool);
FREE(upload);
}
struct nine_subbuffer *
nine_upload_create_buffer(struct nine_buffer_upload *upload,
unsigned buffer_size)
{
struct nine_subbuffer *buf = slab_alloc_st(&upload->buffer_pool);
struct nine_buffer_group *group = NULL;
unsigned size = align(buffer_size, 4096);
int i = 0;
DBG("%p %d\n", upload, buffer_size);
if (!buf)
return NULL;
for (i = 0; i < upload->num_buffers; i++) {
group = &upload->buffers[i];
if (group->resource &&
group->free_offset + size <= upload->buffers_size)
break;
}
if (i == upload->num_buffers) {
/* Allocate lonely buffer */
struct pipe_resource resource;
struct pipe_screen *screen = upload->pipe->screen;
DBG("Allocating buffer\n");
buf->parent = NULL;
memset(&resource, 0, sizeof(resource));
resource.target = PIPE_BUFFER;
resource.format = PIPE_FORMAT_R8_UNORM;
resource.bind = PIPE_BIND_VERTEX_BUFFER;
resource.usage = PIPE_USAGE_STREAM;
resource.width0 = buffer_size;
resource.height0 = 1;
resource.depth0 = 1;
resource.array_size = 1;
resource.flags = PIPE_RESOURCE_FLAG_MAP_PERSISTENT |
PIPE_RESOURCE_FLAG_MAP_COHERENT;
buf->resource = screen->resource_create(screen, &resource);
if (buf->resource == NULL) {
slab_free_st(&upload->buffer_pool, buf);
return NULL;
}
buf->map = pipe_buffer_map_range(upload->pipe, buf->resource,
0, buffer_size,
PIPE_MAP_WRITE |
#if DETECT_ARCH_X86
PIPE_MAP_ONCE |
#endif
PIPE_MAP_PERSISTENT |
PIPE_MAP_COHERENT,
&buf->transfer);
if (buf->map == NULL) {
pipe_resource_reference(&buf->resource, NULL);
slab_free_st(&upload->buffer_pool, buf);
return NULL;
}
buf->offset = 0;
return buf;
}
DBG("Using buffer group %d\n", i);
buf->parent = group;
buf->resource = NULL;
pipe_resource_reference(&buf->resource, group->resource);
buf->offset = group->free_offset;
group->free_offset += size;
group->refcount += 1;
return buf;
}
void
nine_upload_release_buffer(struct nine_buffer_upload *upload,
struct nine_subbuffer *buf)
{
DBG("%p %p %p\n", upload, buf, buf->parent);
if (buf->parent) {
pipe_resource_reference(&buf->resource, NULL);
buf->parent->refcount--;
if (buf->parent->refcount == 0) {
/* Allocate new buffer */
nine_upload_destroy_buffer_group(upload, buf->parent);
nine_upload_create_buffer_group(upload, buf->parent);
}
} else {
/* lonely buffer */
if (buf->transfer)
pipe_buffer_unmap(upload->pipe, buf->transfer);
pipe_resource_reference(&buf->resource, NULL);
}
slab_free_st(&upload->buffer_pool, buf);
}
uint8_t *
nine_upload_buffer_get_map(struct nine_subbuffer *buf)
{
if (buf->parent) {
DBG("%d\n", buf->parent->refcount);
return buf->parent->map + buf->offset;
}
/* lonely buffer */
return buf->map;
}
struct pipe_resource *
nine_upload_buffer_resource_and_offset(struct nine_subbuffer *buf,
unsigned *offset)
{
*offset = buf->offset;
return buf->resource;
}

View file

@ -1,39 +0,0 @@
/*
* Copyright 2009 VMware, Inc.
* Copyright 2016 Axel Davy <axel.davy@ens.fr>
* All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_BUFFER_UPLOAD_H_
#define _NINE_BUFFER_UPLOAD_H_
#include "pipe/p_defines.h"
struct nine_buffer_upload;
struct nine_subbuffer;
struct nine_buffer_upload *
nine_upload_create(struct pipe_context *pipe, unsigned buffers_size,
unsigned num_buffers);
void
nine_upload_destroy(struct nine_buffer_upload *upload);
struct nine_subbuffer *
nine_upload_create_buffer(struct nine_buffer_upload *upload,
unsigned buffer_size);
void
nine_upload_release_buffer(struct nine_buffer_upload *upload,
struct nine_subbuffer *buf);
uint8_t *
nine_upload_buffer_get_map(struct nine_subbuffer *buf);
struct pipe_resource *
nine_upload_buffer_resource_and_offset(struct nine_subbuffer *buf,
unsigned *offset);
#endif /* _NINE_BUFFER_UPLOAD_H_ */

View file

@ -1,427 +0,0 @@
/*
* Copyright 2016 Patrick Rudolph <siro@das-labor.org>
* SPDX-License-Identifier: MIT
*/
/* get number of arguments with __NARG__ */
#define __NARG__(...) __NARG_I_(__VA_ARGS__,__RSEQ_N())
#define __NARG_I_(...) __ARG_N(__VA_ARGS__)
#define __ARG_N( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63,_64,_65,_66,_67,_68,_69,_70,N,...) N
#define __RSEQ_N() \
70,69,68,67,66,65,64,63,62,61,60, \
59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40, \
39,38,37,36,35,34,33,32,31,30, \
29,28,27,26,25,24,23,22,21,20, \
19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0
#define _args_for_bypass_1(a) a
#define _args_for_bypass_7(a, b, c, d, e, f, g) ,g
#define _args_for_bypass_14(a, b, c, d, e, f, g, ...) ,g _args_for_bypass_7(__VA_ARGS__)
#define _args_for_bypass_21(a, b, c, d, e, f, g, ...) ,g _args_for_bypass_14(__VA_ARGS__)
#define _args_for_bypass_28(a, b, c, d, e, f, g, ...) ,g _args_for_bypass_21(__VA_ARGS__)
#define _args_for_bypass_35(a, b, c, d, e, f, g, ...) ,g _args_for_bypass_28(__VA_ARGS__)
#define _args_for_bypass_42(a, b, c, d, e, f, g, ...) ,g _args_for_bypass_35(__VA_ARGS__)
#define _args_for_bypass_49(a, b, c, d, e, f, g, ...) ,g _args_for_bypass_42(__VA_ARGS__)
#define _args_for_bypass_56(a, b, c, d, e, f, g, ...) ,g _args_for_bypass_49(__VA_ARGS__)
#define _args_for_bypass_63(a, b, c, d, e, f, g, ...) ,g _args_for_bypass_56(__VA_ARGS__)
#define _args_for_bypass_70(a, b, c, d, e, f, g, ...) ,g _args_for_bypass_63(__VA_ARGS__)
#define _args_for_bypass_77(a, b, c, d, e, f, g, ...) ,g _args_for_bypass_70(__VA_ARGS__)
#define _GFUNC_(n) _args_for_bypass_##n
#define _GFUNC(n) _GFUNC_(n)
#define ARGS_FOR_BYPASS(...) _GFUNC(__NARG__(__VA_ARGS__)) (__VA_ARGS__)
#define _args_for_mem_1(a) a;
#define _args_for_mem_7(a, b, c, d, e, f, g) f;
#define _args_for_mem_14(a, b, c, d, e, f, g, ...) f; _args_for_mem_7(__VA_ARGS__)
#define _args_for_mem_21(a, b, c, d, e, f, g, ...) f; _args_for_mem_14(__VA_ARGS__)
#define _args_for_mem_28(a, b, c, d, e, f, g, ...) f; _args_for_mem_21(__VA_ARGS__)
#define _args_for_mem_35(a, b, c, d, e, f, g, ...) f; _args_for_mem_28(__VA_ARGS__)
#define _args_for_mem_42(a, b, c, d, e, f, g, ...) f; _args_for_mem_35(__VA_ARGS__)
#define _args_for_mem_49(a, b, c, d, e, f, g, ...) f; _args_for_mem_42(__VA_ARGS__)
#define _args_for_mem_56(a, b, c, d, e, f, g, ...) f; _args_for_mem_49(__VA_ARGS__)
#define _args_for_mem_63(a, b, c, d, e, f, g, ...) f; _args_for_mem_56(__VA_ARGS__)
#define _args_for_mem_70(a, b, c, d, e, f, g, ...) f; _args_for_mem_63(__VA_ARGS__)
#define _args_for_mem_77(a, b, c, d, e, f, g, ...) f; _args_for_mem_70(__VA_ARGS__)
#define _FFUNC_(n) _args_for_mem_##n
#define _FFUNC(n) _FFUNC_(n)
#define ARGS_FOR_MEM(...) _FFUNC(__NARG__(__VA_ARGS__)) (__VA_ARGS__)
#define _args_for_unbind_1(a) a;
#define _args_for_unbind_7(a, b, c, d, e, f, g) e;
#define _args_for_unbind_14(a, b, c, d, e, f, g, ...) e; _args_for_unbind_7(__VA_ARGS__)
#define _args_for_unbind_21(a, b, c, d, e, f, g, ...) e; _args_for_unbind_14(__VA_ARGS__)
#define _args_for_unbind_28(a, b, c, d, e, f, g, ...) e; _args_for_unbind_21(__VA_ARGS__)
#define _args_for_unbind_35(a, b, c, d, e, f, g, ...) e; _args_for_unbind_28(__VA_ARGS__)
#define _args_for_unbind_42(a, b, c, d, e, f, g, ...) e; _args_for_unbind_35(__VA_ARGS__)
#define _args_for_unbind_49(a, b, c, d, e, f, g, ...) e; _args_for_unbind_42(__VA_ARGS__)
#define _args_for_unbind_56(a, b, c, d, e, f, g, ...) e; _args_for_unbind_49(__VA_ARGS__)
#define _args_for_unbind_63(a, b, c, d, e, f, g, ...) e; _args_for_unbind_56(__VA_ARGS__)
#define _args_for_unbind_70(a, b, c, d, e, f, g, ...) e; _args_for_unbind_63(__VA_ARGS__)
#define _args_for_unbind_77(a, b, c, d, e, f, g, ...) e; _args_for_unbind_70(__VA_ARGS__)
#define _EFUNC_(n) _args_for_unbind_##n
#define _EFUNC(n) _EFUNC_(n)
#define ARGS_FOR_UNBIND(...) _EFUNC(__NARG__(__VA_ARGS__)) (__VA_ARGS__)
#define _args_for_call_1(a) a
#define _args_for_call_7(a, b, c, d, e, f, g) ,d
#define _args_for_call_14(a, b, c, d, e, f, g, ...) ,d _args_for_call_7(__VA_ARGS__)
#define _args_for_call_21(a, b, c, d, e, f, g, ...) ,d _args_for_call_14(__VA_ARGS__)
#define _args_for_call_28(a, b, c, d, e, f, g, ...) ,d _args_for_call_21(__VA_ARGS__)
#define _args_for_call_35(a, b, c, d, e, f, g, ...) ,d _args_for_call_28(__VA_ARGS__)
#define _args_for_call_42(a, b, c, d, e, f, g, ...) ,d _args_for_call_35(__VA_ARGS__)
#define _args_for_call_49(a, b, c, d, e, f, g, ...) ,d _args_for_call_42(__VA_ARGS__)
#define _args_for_call_56(a, b, c, d, e, f, g, ...) ,d _args_for_call_49(__VA_ARGS__)
#define _args_for_call_63(a, b, c, d, e, f, g, ...) ,d _args_for_call_56(__VA_ARGS__)
#define _args_for_call_70(a, b, c, d, e, f, g, ...) ,d _args_for_call_63(__VA_ARGS__)
#define _args_for_call_77(a, b, c, d, e, f, g, ...) ,d _args_for_call_70(__VA_ARGS__)
#define _DFUNC_(n) _args_for_call_##n
#define _DFUNC(n) _DFUNC_(n)
#define ARGS_FOR_CALL(...) _DFUNC(__NARG__(__VA_ARGS__)) (__VA_ARGS__)
#define _args_for_decl_1(a) a
#define _args_for_decl_7(a, b, c, d, e, f, g) ,c
#define _args_for_decl_14(a, b, c, d, e, f, g, ...) ,c _args_for_decl_7(__VA_ARGS__)
#define _args_for_decl_21(a, b, c, d, e, f, g, ...) ,c _args_for_decl_14(__VA_ARGS__)
#define _args_for_decl_28(a, b, c, d, e, f, g, ...) ,c _args_for_decl_21(__VA_ARGS__)
#define _args_for_decl_35(a, b, c, d, e, f, g, ...) ,c _args_for_decl_28(__VA_ARGS__)
#define _args_for_decl_42(a, b, c, d, e, f, g, ...) ,c _args_for_decl_35(__VA_ARGS__)
#define _args_for_decl_49(a, b, c, d, e, f, g, ...) ,c _args_for_decl_42(__VA_ARGS__)
#define _args_for_decl_56(a, b, c, d, e, f, g, ...) ,c _args_for_decl_49(__VA_ARGS__)
#define _args_for_decl_63(a, b, c, d, e, f, g, ...) ,c _args_for_decl_56(__VA_ARGS__)
#define _args_for_decl_70(a, b, c, d, e, f, g, ...) ,c _args_for_decl_63(__VA_ARGS__)
#define _args_for_decl_77(a, b, c, d, e, f, g, ...) ,c _args_for_decl_70(__VA_ARGS__)
#define _CFUNC_(n) _args_for_decl_##n
#define _CFUNC(n) _CFUNC_(n)
#define ARGS_FOR_DECLARATION(...) _CFUNC(__NARG__(__VA_ARGS__)) (__VA_ARGS__)
#define _args_for_assign_1(a) a
#define _args_for_assign_7(a, b, c, d, e, f, g) b;
#define _args_for_assign_14(a, b, c, d, e, f, g, ...) b; _args_for_assign_7(__VA_ARGS__)
#define _args_for_assign_21(a, b, c, d, e, f, g, ...) b; _args_for_assign_14(__VA_ARGS__)
#define _args_for_assign_28(a, b, c, d, e, f, g, ...) b; _args_for_assign_21(__VA_ARGS__)
#define _args_for_assign_35(a, b, c, d, e, f, g, ...) b; _args_for_assign_28(__VA_ARGS__)
#define _args_for_assign_42(a, b, c, d, e, f, g, ...) b; _args_for_assign_35(__VA_ARGS__)
#define _args_for_assign_49(a, b, c, d, e, f, g, ...) b; _args_for_assign_42(__VA_ARGS__)
#define _args_for_assign_56(a, b, c, d, e, f, g, ...) b; _args_for_assign_49(__VA_ARGS__)
#define _args_for_assign_63(a, b, c, d, e, f, g, ...) b; _args_for_assign_56(__VA_ARGS__)
#define _args_for_assign_70(a, b, c, d, e, f, g, ...) b; _args_for_assign_63(__VA_ARGS__)
#define _args_for_assign_77(a, b, c, d, e, f, g, ...) b; _args_for_assign_70(__VA_ARGS__)
#define _BFUNC_(n) _args_for_assign_##n
#define _BFUNC(n) _BFUNC_(n)
#define ARGS_FOR_ASSIGN(...) _BFUNC(__NARG__(__VA_ARGS__)) (__VA_ARGS__)
#define _args_for_struct_1(a) a;
#define _args_for_struct_7(a, b, c, d, e, f, g) a;
#define _args_for_struct_14(a, b, c, d, e, f, g, ...) a; _args_for_struct_7(__VA_ARGS__)
#define _args_for_struct_21(a, b, c, d, e, f, g, ...) a; _args_for_struct_14(__VA_ARGS__)
#define _args_for_struct_28(a, b, c, d, e, f, g, ...) a; _args_for_struct_21(__VA_ARGS__)
#define _args_for_struct_35(a, b, c, d, e, f, g, ...) a; _args_for_struct_28(__VA_ARGS__)
#define _args_for_struct_42(a, b, c, d, e, f, g, ...) a; _args_for_struct_35(__VA_ARGS__)
#define _args_for_struct_49(a, b, c, d, e, f, g, ...) a; _args_for_struct_42(__VA_ARGS__)
#define _args_for_struct_56(a, b, c, d, e, f, g, ...) a; _args_for_struct_49(__VA_ARGS__)
#define _args_for_struct_63(a, b, c, d, e, f, g, ...) a; _args_for_struct_56(__VA_ARGS__)
#define _args_for_struct_70(a, b, c, d, e, f, g, ...) a; _args_for_struct_63(__VA_ARGS__)
#define _args_for_struct_77(a, b, c, d, e, f, g, ...) a; _args_for_struct_70(__VA_ARGS__)
#define _AFUNC_(n) _args_for_struct_##n
#define _AFUNC(n) _AFUNC_(n)
#define ARGS_FOR_STRUCT(...) _AFUNC(__NARG__(__VA_ARGS__)) (__VA_ARGS__)
/* Serialization and deserialization */
#define CSMT_ITEM_NO_WAIT(name, ...) \
\
struct s_##name##_private { \
struct csmt_instruction instr; \
ARGS_FOR_STRUCT( __VA_ARGS__ ) \
}; \
\
static void \
name##_priv( struct NineDevice9 *device ARGS_FOR_DECLARATION( __VA_ARGS__ ) ); \
\
static int \
name##_rx( struct NineDevice9 *device, struct csmt_instruction *instr ) \
{ \
struct csmt_context *ctx = device->csmt_ctx; \
struct s_##name##_private *args = (struct s_##name##_private *)instr; \
\
(void) args; \
(void) ctx; \
name##_priv( \
device ARGS_FOR_CALL( __VA_ARGS__ ) \
); \
ARGS_FOR_UNBIND( __VA_ARGS__ ) \
return 0; \
} \
\
void \
name( struct NineDevice9 *device ARGS_FOR_DECLARATION( __VA_ARGS__ ) ) \
{ \
struct csmt_context *ctx = device->csmt_ctx; \
struct s_##name##_private *args; \
unsigned memsize = sizeof(struct s_##name##_private); \
unsigned memsize2 = 0; \
\
if (!device->csmt_active) { \
name##_priv( \
device ARGS_FOR_BYPASS( __VA_ARGS__ ) \
); \
return; \
} \
ARGS_FOR_MEM ( __VA_ARGS__ ) \
args = nine_queue_alloc(ctx->pool, memsize + memsize2); \
assert(args); \
args->instr.func = &name##_rx; \
ARGS_FOR_ASSIGN( __VA_ARGS__ ) \
} \
\
static void \
name##_priv( struct NineDevice9 *device ARGS_FOR_DECLARATION( __VA_ARGS__ ) )
#define CSMT_ITEM_NO_WAIT_WITH_COUNTER(name, ...) \
\
struct s_##name##_private { \
struct csmt_instruction instr; \
unsigned *counter; \
ARGS_FOR_STRUCT( __VA_ARGS__ ) \
}; \
\
static void \
name##_priv( struct NineDevice9 *device ARGS_FOR_DECLARATION( __VA_ARGS__ ) ); \
\
static int \
name##_rx( struct NineDevice9 *device, struct csmt_instruction *instr ) \
{ \
struct csmt_context *ctx = device->csmt_ctx; \
struct s_##name##_private *args = (struct s_##name##_private *)instr; \
\
(void) args; \
(void) ctx; \
name##_priv( \
device ARGS_FOR_CALL( __VA_ARGS__ ) \
); \
p_atomic_dec(args->counter); \
ARGS_FOR_UNBIND( __VA_ARGS__ ) \
return 0; \
} \
\
void \
name( struct NineDevice9 *device, unsigned *counter ARGS_FOR_DECLARATION( __VA_ARGS__ ) ) \
{ \
struct csmt_context *ctx = device->csmt_ctx; \
struct s_##name##_private *args; \
unsigned memsize = sizeof(struct s_##name##_private); \
unsigned memsize2 = 0; \
\
if (!device->csmt_active) { \
name##_priv( \
device ARGS_FOR_BYPASS( __VA_ARGS__ ) \
); \
return; \
} \
assert(counter); \
p_atomic_inc(counter); \
ARGS_FOR_MEM ( __VA_ARGS__ ) \
args = nine_queue_alloc(ctx->pool, memsize + memsize2); \
assert(args); \
args->instr.func = &name##_rx; \
args->counter = counter; \
ARGS_FOR_ASSIGN( __VA_ARGS__ ) \
} \
\
static void \
name##_priv( struct NineDevice9 *device ARGS_FOR_DECLARATION( __VA_ARGS__ ) )
#define CSMT_ITEM_DO_WAIT(name, ...) \
\
struct s_##name##_private { \
struct csmt_instruction instr; \
ARGS_FOR_STRUCT( __VA_ARGS__ ) \
}; \
static void \
name##_priv( struct NineDevice9 *device ARGS_FOR_DECLARATION( __VA_ARGS__ ) ); \
\
static int \
name##_rx( struct NineDevice9 *device, struct csmt_instruction *instr) \
{ \
struct csmt_context *ctx = device->csmt_ctx; \
struct s_##name##_private *args = (struct s_##name##_private *)instr; \
\
(void) args; \
(void) ctx; \
name##_priv( \
device ARGS_FOR_CALL( __VA_ARGS__ ) \
); \
ARGS_FOR_UNBIND( __VA_ARGS__ ) \
return 1; \
} \
\
void \
name( struct NineDevice9 *device ARGS_FOR_DECLARATION( __VA_ARGS__ ) ) \
{ \
struct csmt_context *ctx = device->csmt_ctx; \
struct s_##name##_private *args; \
unsigned memsize = sizeof(struct s_##name##_private); \
unsigned memsize2 = 0; \
\
if (!device->csmt_active) { \
name##_priv( \
device ARGS_FOR_BYPASS( __VA_ARGS__ ) \
); \
return; \
} \
ARGS_FOR_MEM ( __VA_ARGS__ ) \
args = nine_queue_alloc(ctx->pool, memsize + memsize2); \
assert(args); \
args->instr.func = &name##_rx; \
ARGS_FOR_ASSIGN( __VA_ARGS__ ) \
ctx->processed = false; \
nine_queue_flush(ctx->pool); \
nine_csmt_wait_processed(ctx); \
} \
\
static void \
name##_priv( struct NineDevice9 *device ARGS_FOR_DECLARATION( __VA_ARGS__ ) )
/* ARGS_FOR_STRUCT, ARGS_FOR_ASSIGN, ARGS_FOR_DECLARATION, ARGS_FOR_CALL, ARGS_FOR_UNBIND, ARGS_FOR_MEM, ARGS_FOR_BYPASS */
#define ARG_VAL(x, y) \
x _##y ; ,\
args->_##y = y ; ,\
x y ,\
args->_##y ,\
,\
,\
y
#define ARG_REF(x, y) \
x* _##y ; ,\
args->_##y = y; ,\
x *y ,\
args->_##y ,\
,\
,\
y
#define ARG_COPY_REF(x, y) \
x * _##y ; x __##y ; ,\
if ( y ) { args->_##y = &args->__##y ; args->__##y = *y ; } else { args->_##y = NULL; } ,\
const x *y ,\
(const x *)args->_##y ,\
,\
,\
(const x *)y
#define ARG_BIND_REF(x, y) \
x * _##y ,\
if ( y ) \
NineUnknown_Bind( (void *)y ); \
args->_##y = y ; ,\
x *y ,\
args->_##y,\
if (args->_##y) \
NineUnknown_Unbind((void *)(args->_##y)); \
args->_##y = NULL; ,\
,\
y
#define ARG_BIND_RES(x, y) \
x * _##y ,\
args->_##y = NULL; \
if (y) \
pipe_resource_reference(&args->_##y, y); ,\
x *y ,\
args->_##y ,\
if (args->_##y) \
pipe_resource_reference(&args->_##y, NULL); ,\
,\
y
#define ARG_MEM(x, y) \
x * _##y ,\
args->_##y = (void *)args + memsize;\
memcpy(args->_##y, y, memsize2); ,\
const x *y ,\
(const x *)args->_##y ,\
,\
,\
(const x *)y
#define ARG_MEM_SIZE(x, y) \
x _##y ,\
args->_##y = y; ,\
x y ,\
args->_##y ,\
,\
memsize2 = y, \
y
#define ARG_BIND_BLIT(x, y) \
x _##y ,\
memcpy(&args->_##y , y, sizeof(x)); \
args->_##y.src.resource = NULL; \
args->_##y.dst.resource = NULL; \
pipe_resource_reference(&args->_##y.src.resource, y->src.resource); \
pipe_resource_reference(&args->_##y.dst.resource, y->dst.resource);,\
x *y ,\
&args->_##y ,\
pipe_resource_reference(&args->_##y.src.resource, NULL); \
pipe_resource_reference(&args->_##y.dst.resource, NULL);,\
,\
y
#define ARG_BIND_VBUF(x, y) \
x _##y ,\
memcpy(&args->_##y , y, sizeof(x)); \
args->_##y.buffer.resource = NULL; \
pipe_resource_reference(&args->_##y.buffer.resource, y->buffer.resource); ,\
x *y ,\
&args->_##y ,\
pipe_resource_reference(&args->_##y.buffer.resource, NULL); ,\
,\
y
#define ARG_BIND_IBUF(x, y) \
x _##y ,\
memcpy(&args->_##y , y, sizeof(x)); \
args->_##y.buffer = NULL; \
pipe_resource_reference(&args->_##y.buffer, y->buffer); ,\
x *y ,\
&args->_##y ,\
pipe_resource_reference(&args->_##y.buffer, NULL); ,\
,\
y
#define ARG_BIND_VIEW(x, y) \
x * _##y ,\
args->_##y = NULL; \
if (y) \
args->_##y = y;,\
x *y ,\
args->_##y ,\
if (args->_##y) \
args->_##y = NULL;,\
,\
y

View file

@ -1,100 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#include "nine_debug.h"
#include <ctype.h>
#include "c11/threads.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." },
{ "tid", DBG_TID, "Display thread-ids." },
DEBUG_NAMED_VALUE_END
};
void
_nine_debug_printf( unsigned long flag,
const char *func,
const char *fmt,
... )
{
static bool first = true;
static unsigned long dbg_flags = DBG_ERROR | DBG_WARN;
unsigned long tid = 0;
if (first) {
first = false;
dbg_flags |= debug_get_flags_option("NINE_DEBUG", nine_debug_flags, 0);
}
#if defined(HAVE_PTHREAD)
if (dbg_flags & DBG_TID)
tid = (unsigned long)pthread_self();
#endif
if (dbg_flags & flag) {
const char *f = func ? strrchr(func, '_') : NULL;
va_list ap;
/* inside a class this will print nine:tid:classinlowercase:func: while
* outside a class (rarely used) it will just print nine:tid: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';
if (tid)
_debug_printf("nine:0x%08lx:%s:%s: ", tid, klass, ++f);
else
_debug_printf("nine:%s:%s: ", klass, ++f);
} else if (func) {
if (tid)
_debug_printf("nine:0x%08lx:%s ", tid, func);
else
_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

@ -1,120 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_DEBUG_H_
#define _NINE_DEBUG_H_
#include "util/u_debug.h"
#include "util/compiler.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, __func__, fmt, ## __VA_ARGS__)
#if MESA_DEBUG || !defined(NDEBUG)
#define WARN(fmt, ...) _nine_debug_printf(DBG_WARN, __func__, fmt, ## __VA_ARGS__)
#define WARN_ONCE(fmt, ...) \
do { \
static bool once = true; \
if (once) { \
once = false; \
_nine_debug_printf(DBG_WARN, __func__, fmt, ## __VA_ARGS__); \
} \
} while(0)
#else
#define WARN(fmt, ...) do {} while(0)
#define WARN_ONCE(fmt, ...) do {} while(0)
#endif
#if MESA_DEBUG || !defined(NDEBUG)
#define DBG_FLAG(flag, fmt, ...) \
_nine_debug_printf(flag, __func__, fmt, ## __VA_ARGS__)
#else
#define DBG_FLAG(flag, fmt, ...) do {} while(0)
#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)
#define DBG_TID (1<<27)
void
_nine_stub( const char *file,
const char *func,
unsigned line );
#if MESA_DEBUG || !defined(NDEBUG)
#define STUB(ret) \
do { \
_nine_stub(__FILE__, __func__, __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. */
#if MESA_DEBUG || !defined(NDEBUG)
#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
#if MESA_DEBUG || !defined(NDEBUG)
#define user_warn(x) \
if ((x)) { DBG_FLAG(DBG_USER, "User warning: `%s'\n", #x); }
#else
#define user_warn(x) do {} while(0)
#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

@ -1,48 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_DEFINES_H_
#define _NINE_DEFINES_H_
#include "pipe/p_defines.h"
#define NINE_RESOURCE_FLAG_LOCKABLE (PIPE_RESOURCE_FLAG_FRONTEND_PRIV << 1)
#define NINE_RESOURCE_FLAG_DUMMY (PIPE_RESOURCE_FLAG_FRONTEND_PRIV << 2)
/* vertexdeclaration9.c */
uint16_t nine_d3d9_to_nine_declusage(unsigned usage, unsigned index);
#define NINE_DECLUSAGE_POSITION 0
#define NINE_DECLUSAGE_BLENDWEIGHT 1
#define NINE_DECLUSAGE_BLENDINDICES 2
#define NINE_DECLUSAGE_NORMAL 3
#define NINE_DECLUSAGE_TEXCOORD 4
#define NINE_DECLUSAGE_TANGENT 5
#define NINE_DECLUSAGE_BINORMAL 6
#define NINE_DECLUSAGE_COLOR 7
#define NINE_DECLUSAGE_POSITIONT 8
#define NINE_DECLUSAGE_PSIZE 9
#define NINE_DECLUSAGE_TESSFACTOR 10
#define NINE_DECLUSAGE_DEPTH 11
#define NINE_DECLUSAGE_FOG 12
#define NINE_DECLUSAGE_SAMPLE 13
#define NINE_DECLUSAGE_NONE 14
#define NINE_DECLUSAGE_COUNT (NINE_DECLUSAGE_NONE + 1)
#define NINE_DECLUSAGE_i(declusage, n) NINE_DECLUSAGE_##declusage + n * NINE_DECLUSAGE_COUNT
#define NINED3DCLEAR_DEPTHSTENCIL (D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL)
#define NINE_BIND_BACKBUFFER_FLAGS (PIPE_BIND_RENDER_TARGET |\
PIPE_BIND_SAMPLER_VIEW)
#define NINE_BIND_PRESENTBUFFER_FLAGS (PIPE_BIND_RENDER_TARGET |\
PIPE_BIND_DISPLAY_TARGET |\
PIPE_BIND_SCANOUT |\
PIPE_BIND_SHARED)
#endif /* _NINE_DEFINES_H_ */

View file

@ -1,818 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#include "nine_debug.h"
#include "nine_pipe.h"
#include <stdio.h>
#include "c11/threads.h"
#include "util/u_memory.h"
#include "util/u_math.h"
#include "nine_dump.h"
#if MESA_DEBUG || !defined(NDEBUG)
static char thread_local 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 /* MESA_DEBUG || !NDEBUG */

View file

@ -1,56 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#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);
#if MESA_DEBUG || !defined(NDEBUG)
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 /* !(MESA_DEBUG || !NDEBUG) */
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 /* MESA_DEBUG || !NDEBUG */
#endif /* _NINE_DUMP_H_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,132 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* Copyright Axel Davy <davyaxel0@gmail.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_FF_H_
#define _NINE_FF_H_
#include "device9.h"
#include "vertexdeclaration9.h"
bool 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_transpose(D3DMATRIX *, const D3DMATRIX *);
#define NINED3DTSS_TCI_DISABLE 0
#define NINED3DTSS_TCI_PASSTHRU 1
#define NINED3DTSS_TCI_CAMERASPACENORMAL 2
#define NINED3DTSS_TCI_CAMERASPACEPOSITION 3
#define NINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR 4
#define NINED3DTSS_TCI_SPHEREMAP 5
static inline unsigned
nine_decltype_get_dim(BYTE type)
{
switch (type) {
case D3DDECLTYPE_FLOAT1: return 1;
case D3DDECLTYPE_FLOAT2: return 2;
case D3DDECLTYPE_FLOAT3: return 3;
case D3DDECLTYPE_FLOAT4: return 4;
case D3DDECLTYPE_D3DCOLOR: return 1;
case D3DDECLTYPE_UBYTE4: return 4;
case D3DDECLTYPE_SHORT2: return 2;
case D3DDECLTYPE_SHORT4: return 4;
case D3DDECLTYPE_UBYTE4N: return 4;
case D3DDECLTYPE_SHORT2N: return 2;
case D3DDECLTYPE_SHORT4N: return 4;
case D3DDECLTYPE_USHORT2N: return 2;
case D3DDECLTYPE_USHORT4N: return 4;
case D3DDECLTYPE_UDEC3: return 3;
case D3DDECLTYPE_DEC3N: return 3;
case D3DDECLTYPE_FLOAT16_2: return 2;
case D3DDECLTYPE_FLOAT16_4: return 4;
default:
assert(!"Implementation error !");
}
return 0;
}
static inline uint16_t
nine_ff_get_projected_key(struct nine_context *context, unsigned num_stages)
{
unsigned s, i;
uint16_t projected = 0;
int8_t input_texture_coord[num_stages];
memset(&input_texture_coord, 0, sizeof(input_texture_coord));
if (context->vdecl) {
for (i = 0; i < context->vdecl->nelems; i++) {
uint16_t usage = context->vdecl->usage_map[i];
if (usage % NINE_DECLUSAGE_COUNT == NINE_DECLUSAGE_TEXCOORD) {
s = usage / NINE_DECLUSAGE_COUNT;
if (s < num_stages)
input_texture_coord[s] = nine_decltype_get_dim(context->vdecl->decls[i].Type);
}
}
}
for (s = 0; s < num_stages; ++s) {
unsigned gen = (context->ff.tex_stage[s][D3DTSS_TEXCOORDINDEX] >> 16) + 1;
unsigned dim = context->ff.tex_stage[s][D3DTSS_TEXTURETRANSFORMFLAGS] & 0x7;
unsigned idx = context->ff.tex_stage[s][D3DTSS_TEXCOORDINDEX] & 7;
unsigned proj = !!(context->ff.tex_stage[s][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED);
if (!context->programmable_vs) {
if (dim > 4)
dim = input_texture_coord[idx];
if (!dim && gen == NINED3DTSS_TCI_PASSTHRU)
dim = input_texture_coord[idx];
else if (!dim)
dim = 4;
if (dim == 1) /* NV behaviour */
proj = 0;
if (dim > input_texture_coord[idx] && gen == NINED3DTSS_TCI_PASSTHRU)
proj = 0;
} else {
dim = 4;
}
if (proj)
projected |= (dim-1) << (2 * s);
}
return projected;
}
static inline uint16_t
nine_ff_get_projected_key_ff(struct nine_context *context)
{
/* 8 stages */
return nine_ff_get_projected_key(context, 8);
}
static inline uint8_t
nine_ff_get_projected_key_programmable(struct nine_context *context)
{
/* We only look at the 4 stages because this function
* is used only for ps 1.1-3, where only the first four
* slots are available */
return (uint8_t)nine_ff_get_projected_key(context, 4);
}
#endif /* _NINE_FF_H_ */

View file

@ -1,17 +0,0 @@
/*
* Copyright Axel Davy <davyaxel0@gmail.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_FLAGS_H_
#define _NINE_FLAGS_H_
#include "util/compiler.h"
/* Incoming 32 bits calls are 4-byte aligned.
* We need to realign them to be able to use
* SSE and to work with other libraries (llvm, etc)
*/
#define NINE_WINAPI WINAPI UTIL_ALIGN_STACK
#endif /* _NINE_FLAGS_H_ */

View file

@ -1,83 +0,0 @@
/*
* Copyright 2013 Christoph Bumiller
* SPDX-License-Identifier: MIT
*/
#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

@ -1,183 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#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; \
__params.start_with_bind_not_ref = false; \
{ \
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_DEVICE_CHILD_BIND_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; \
__params.start_with_bind_not_ref = true; \
{ \
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; \
__params.start_with_bind_not_ref = false; \
{ \
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;
}
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_ */

View file

@ -1,230 +0,0 @@
/*
* Copyright 2015 Axel Davy <axel.davy@ens.fr>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_LIMITS_H_
#define _NINE_LIMITS_H_
#include "assert.h"
#include "d3d9types.h"
// state can be any value
#define NINE_STATE_NO_LIMIT 0
// value is clamped if below min or max
#define NINE_STATE_CLAMP 1
// boolean: 0 -> false; any other value -> true
#define NINE_STATE_BOOL 2
// a mask is applied on the value
#define NINE_STATE_MASK 3
// if outside a range, state value is changed to a default value
#define NINE_STATE_RANGE_DEF_VAL 4
struct nine_state_behaviour {
unsigned state_value_behaviour;
union {
struct {
unsigned min;
unsigned max;
} clamp;
unsigned mask;
struct {
unsigned min;
unsigned max;
unsigned default_val;
} range_def_val;
} u;
};
#define __NO_LIMIT_RS(o) \
[D3DRS_##o] = {NINE_STATE_NO_LIMIT}
#define __CLAMP_RS(o, m, M) \
[D3DRS_##o] = {NINE_STATE_CLAMP, {.clamp = {m, M}}}
#define __BOOLEAN_RS(o) \
[D3DRS_##o] = {NINE_STATE_BOOL}
#define __MASK_RS(o, m) \
[D3DRS_##o] = {NINE_STATE_MASK, {.mask = m}}
#define __RANGE_DEF_VAL_RS(o, m, M, d) \
[D3DRS_##o] = {NINE_STATE_RANGE_DEF_VAL, {.range_def_val = {m, M, d}}}
#define __TO_DETERMINE_RS(o, m, M) \
[D3DRS_##o] = {NINE_STATE_NO_LIMIT}
static const struct nine_state_behaviour
render_state_limits_table[D3DRS_BLENDOPALPHA + 1] = {
__TO_DETERMINE_RS(ZENABLE, 0, 3),
__TO_DETERMINE_RS(FILLMODE, 1, 3),
__CLAMP_RS(SHADEMODE, 1, 3),
__BOOLEAN_RS(ZWRITEENABLE),
__BOOLEAN_RS(ALPHATESTENABLE),
__BOOLEAN_RS(LASTPIXEL),
__RANGE_DEF_VAL_RS(SRCBLEND, 1, 17, D3DBLEND_ZERO),
__RANGE_DEF_VAL_RS(DESTBLEND, 1, 17, D3DBLEND_ZERO),
__CLAMP_RS(CULLMODE, 1, 3),
__CLAMP_RS(ZFUNC, 1, 8),
__MASK_RS(ALPHAREF, 0x000000FF),
__CLAMP_RS(ALPHAFUNC, 1, 8),
__BOOLEAN_RS(DITHERENABLE),
__BOOLEAN_RS(ALPHABLENDENABLE),
__BOOLEAN_RS(FOGENABLE),
__BOOLEAN_RS(SPECULARENABLE),
__NO_LIMIT_RS(FOGCOLOR),
__MASK_RS(FOGTABLEMODE, 0x00000003),
__NO_LIMIT_RS(FOGSTART), /* a bit more complex than that, lets ignore */
__NO_LIMIT_RS(FOGEND),
__NO_LIMIT_RS(FOGDENSITY), /* actually should be between 0.0 and 1.0 */
__BOOLEAN_RS(RANGEFOGENABLE),
__BOOLEAN_RS(STENCILENABLE),
__CLAMP_RS(STENCILFAIL, 1, 8),
__CLAMP_RS(STENCILZFAIL, 1, 8),
__CLAMP_RS(STENCILPASS, 1, 8),
__CLAMP_RS(STENCILFUNC, 1, 8),
__NO_LIMIT_RS(STENCILREF),
__NO_LIMIT_RS(STENCILMASK),
__NO_LIMIT_RS(STENCILWRITEMASK),
__NO_LIMIT_RS(TEXTUREFACTOR),
__TO_DETERMINE_RS(WRAP0, 0, 15),
__TO_DETERMINE_RS(WRAP1, 0, 15),
__TO_DETERMINE_RS(WRAP2, 0, 15),
__TO_DETERMINE_RS(WRAP3, 0, 15),
__TO_DETERMINE_RS(WRAP4, 0, 15),
__TO_DETERMINE_RS(WRAP5, 0, 15),
__TO_DETERMINE_RS(WRAP6, 0, 15),
__TO_DETERMINE_RS(WRAP7, 0, 15),
__BOOLEAN_RS(CLIPPING),
__BOOLEAN_RS(LIGHTING),
__NO_LIMIT_RS(AMBIENT),
__MASK_RS(FOGVERTEXMODE, 0x00000003),
__BOOLEAN_RS(COLORVERTEX),
__BOOLEAN_RS(LOCALVIEWER),
__BOOLEAN_RS(NORMALIZENORMALS),
__TO_DETERMINE_RS(DIFFUSEMATERIALSOURCE, 0, 2),
__TO_DETERMINE_RS(SPECULARMATERIALSOURCE, 0, 2),
__TO_DETERMINE_RS(AMBIENTMATERIALSOURCE, 0, 2),
__TO_DETERMINE_RS(EMISSIVEMATERIALSOURCE, 0, 2),
__TO_DETERMINE_RS(VERTEXBLEND, 0, 256), /* values between 4 and 254 -both included- are forbidden too */
__NO_LIMIT_RS(CLIPPLANEENABLE), /* expected check seems complex */
__TO_DETERMINE_RS(POINTSIZE, 0, 0xFFFFFFFF),
__TO_DETERMINE_RS(POINTSIZE_MIN, 0, 0x7FFFFFFF), /* float >= 0.0 */
__BOOLEAN_RS(POINTSPRITEENABLE),
__BOOLEAN_RS(POINTSCALEENABLE),
__TO_DETERMINE_RS(POINTSCALE_A, 0, 0x7FFFFFFF), /* float >= 0.0 */
__TO_DETERMINE_RS(POINTSCALE_B, 0, 0x7FFFFFFF), /* float >= 0.0 */
__TO_DETERMINE_RS(POINTSCALE_C, 0, 0x7FFFFFFF), /* float >= 0.0 */
__BOOLEAN_RS(MULTISAMPLEANTIALIAS),
__NO_LIMIT_RS(MULTISAMPLEMASK),
__TO_DETERMINE_RS(PATCHEDGESTYLE, 0, 1),
__TO_DETERMINE_RS(DEBUGMONITORTOKEN, 0, 1),
__TO_DETERMINE_RS(POINTSIZE_MAX, 0, 0x7FFFFFFF), /* check more complex than that */
__BOOLEAN_RS(INDEXEDVERTEXBLENDENABLE),
__TO_DETERMINE_RS(COLORWRITEENABLE, 0, 15),
__NO_LIMIT_RS(TWEENFACTOR),
__CLAMP_RS(BLENDOP, 1, 5),
__TO_DETERMINE_RS(POSITIONDEGREE, 1, 5), /* can actually be only 1 or 5 */
__TO_DETERMINE_RS(NORMALDEGREE, 1, 2),
__BOOLEAN_RS(SCISSORTESTENABLE),
__NO_LIMIT_RS(SLOPESCALEDEPTHBIAS),
__BOOLEAN_RS(ANTIALIASEDLINEENABLE),
__NO_LIMIT_RS(MINTESSELLATIONLEVEL),
__NO_LIMIT_RS(MAXTESSELLATIONLEVEL),
__NO_LIMIT_RS(ADAPTIVETESS_X),
__NO_LIMIT_RS(ADAPTIVETESS_Y),
__NO_LIMIT_RS(ADAPTIVETESS_Z),
__NO_LIMIT_RS(ADAPTIVETESS_W),
__BOOLEAN_RS(ENABLEADAPTIVETESSELLATION),
__BOOLEAN_RS(TWOSIDEDSTENCILMODE),
__CLAMP_RS(CCW_STENCILFAIL, 1, 8),
__CLAMP_RS(CCW_STENCILZFAIL, 1, 8),
__CLAMP_RS(CCW_STENCILPASS, 1, 8),
__CLAMP_RS(CCW_STENCILFUNC, 1, 8),
__TO_DETERMINE_RS(COLORWRITEENABLE1, 0, 15),
__TO_DETERMINE_RS(COLORWRITEENABLE2, 0, 15),
__TO_DETERMINE_RS(COLORWRITEENABLE3, 0, 15),
__NO_LIMIT_RS(BLENDFACTOR),
__BOOLEAN_RS(SRGBWRITEENABLE),
__NO_LIMIT_RS(DEPTHBIAS),
__TO_DETERMINE_RS(WRAP8, 0, 15),
__TO_DETERMINE_RS(WRAP9, 0, 15),
__TO_DETERMINE_RS(WRAP10, 0, 15),
__TO_DETERMINE_RS(WRAP11, 0, 15),
__TO_DETERMINE_RS(WRAP12, 0, 15),
__TO_DETERMINE_RS(WRAP13, 0, 15),
__TO_DETERMINE_RS(WRAP14, 0, 15),
__TO_DETERMINE_RS(WRAP15, 0, 15),
__BOOLEAN_RS(SEPARATEALPHABLENDENABLE),
__RANGE_DEF_VAL_RS(SRCBLENDALPHA, 1, 17, D3DBLEND_ZERO),
__RANGE_DEF_VAL_RS(DESTBLENDALPHA, 1, 17, D3DBLEND_ZERO),
__CLAMP_RS(BLENDOPALPHA, 1, 5)
};
static DWORD inline
nine_fix_render_state_value(D3DRENDERSTATETYPE State,
DWORD Value)
{
struct nine_state_behaviour behaviour = render_state_limits_table[State];
switch (behaviour.state_value_behaviour) {
case NINE_STATE_NO_LIMIT:
break;
case NINE_STATE_CLAMP:
if (Value < behaviour.u.clamp.min)
Value = behaviour.u.clamp.min;
else if (Value > behaviour.u.clamp.max)
Value = behaviour.u.clamp.max;
break;
case NINE_STATE_BOOL:
Value = Value ? 1 : 0;
break;
case NINE_STATE_MASK:
Value = Value & behaviour.u.mask;
break;
case NINE_STATE_RANGE_DEF_VAL:
if (Value < behaviour.u.range_def_val.min || Value > behaviour.u.range_def_val.max)
Value = behaviour.u.range_def_val.default_val;
break;
}
return Value;
}
struct nine_limits
{
unsigned min;
unsigned max;
};
#define __VALUE_SAMP(o, m, M) \
[D3DSAMP_##o] = {m, M}
static const struct nine_limits
sampler_state_limits_table[D3DRS_BLENDOPALPHA + 1] = {
__VALUE_SAMP(ADDRESSU, 1, 5),
__VALUE_SAMP(ADDRESSV, 1, 5),
__VALUE_SAMP(ADDRESSW, 1, 5),
__VALUE_SAMP(BORDERCOLOR, 0, 0xFFFFFFFF),
__VALUE_SAMP(MAGFILTER, 0, 8), /* 4-5 should be forbidden */
__VALUE_SAMP(MINFILTER, 0, 8), /* same */
__VALUE_SAMP(MIPFILTER, 0, 8), /* same */
__VALUE_SAMP(MIPMAPLODBIAS, 0, 0xFFFFFFFF),
__VALUE_SAMP(MAXMIPLEVEL, 0, 0xFFFFFFFF),
__VALUE_SAMP(MAXANISOTROPY, 1, 0xFFFFFFFF), /* Max value should be pCaps->MaxAnisotropy */
__VALUE_SAMP(SRGBTEXTURE, 0, 1),
__VALUE_SAMP(ELEMENTINDEX, 0, 0xFFFFFFFF),
__VALUE_SAMP(DMAPOFFSET, 0, 0xFFFFFFFF)
};
static BOOL inline
nine_check_sampler_state_value(D3DSAMPLERSTATETYPE State,
DWORD Value)
{
struct nine_limits limit;
limit = sampler_state_limits_table[State];
return (limit.min <= Value && Value <= limit.max);
}
#endif /* _NINE_HELPERS_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,37 +0,0 @@
/*
* Copyright 2013 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#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;
void NineLockGlobalMutex(void);
void NineUnlockGlobalMutex(void);
#endif /* _NINE_LOCK_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,58 +0,0 @@
/*
* Copyright 2020 Axel Davy <davyaxel0@gmail.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_MEMORY_HELPER_H_
#define _NINE_MEMORY_HELPER_H_
struct NineDevice9;
struct nine_allocator;
struct nine_allocation;
/* Note: None of these functions are thread safe, thus the worker thread is disallowed
* to call any of them. Only exception is nine_free_worker reserved for it. */
struct nine_allocation *
nine_allocate(struct nine_allocator *allocator, unsigned size);
/* Note: Suballocations MUST be freed before their parent */
void nine_free(struct nine_allocator *allocator, struct nine_allocation *allocation);
void nine_free_worker(struct nine_allocator *allocator, struct nine_allocation *allocation);
void *nine_get_pointer(struct nine_allocator *allocator, struct nine_allocation *allocation);
/* We don't need the pointer anymore, but we are likely to need it again soon */
void nine_pointer_weakrelease(struct nine_allocator *allocator, struct nine_allocation *allocation);
/* We don't need the pointer anymore, probably for a long time */
void nine_pointer_strongrelease(struct nine_allocator *allocator, struct nine_allocation *allocation);
/* You can strong release when counter becomes 0.
* Once a counter is used for a given allocation, the same must keep being used */
void nine_pointer_delayedstrongrelease(struct nine_allocator *allocator,
struct nine_allocation *allocation,
unsigned *counter);
/* Note: It is disallowed to release a suballocation before its parent.
* It is disallowed to suballocate on a suballocation. */
struct nine_allocation *
nine_suballocate(struct nine_allocator* allocator, struct nine_allocation *allocation, int offset);
/* Won't be freed - but at least we can use the same interface */
struct nine_allocation *
nine_wrap_external_pointer(struct nine_allocator* allocator, void* data);
/* memfd_virtualsizelimit: Limit for the virtual memory usage (in MB)
* above which memfd files are unmapped (to reduce virtual memory usage).
* If negative, disables memfd usage. */
struct nine_allocator *
nine_allocator_create(struct NineDevice9 *device, int memfd_virtualsizelimit);
void
nine_allocator_destroy(struct nine_allocator *allocator);
#endif /* _NINE_MEMORY_HELPER_H_ */

View file

@ -1,48 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_PDATA_H_
#define _NINE_PDATA_H_
#include "util/hash_table.h"
struct pheader
{
bool unknown;
GUID guid;
DWORD size;
};
static bool
ht_guid_compare( const void *a,
const void *b )
{
return GUID_equal(a, b);
}
static uint32_t
ht_guid_hash( const 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 void
ht_guid_delete( struct hash_entry *entry )
{
struct pheader *header = entry->data;
void *header_data = (void *)header + sizeof(*header);
if (header->unknown) { IUnknown_Release(*(IUnknown **)header_data); }
FREE(header);
}
#endif /* _NINE_PDATA_H_ */

View file

@ -1,382 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* Copyright 2013 Christoph Bumiller
* SPDX-License-Identifier: MIT
*/
#include "device9.h"
#include "nine_pipe.h"
#include "cso_cache/cso_context.h"
void
nine_convert_dsa_state(struct pipe_depth_stencil_alpha_state *dsa_state,
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_func = d3dcmpfunc_to_pipe_func(rs[D3DRS_ZFUNC]);
/* Disable depth write if no change can occur */
dsa.depth_writemask = !!rs[D3DRS_ZWRITEENABLE] &&
dsa.depth_func != PIPE_FUNC_EQUAL &&
dsa.depth_func != PIPE_FUNC_NEVER;
}
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] && rs[NINED3DRS_EMULATED_ALPHATEST] == 7 && rs[D3DRS_ALPHAFUNC] != D3DCMP_ALWAYS) {
dsa.alpha_enabled = 1;
dsa.alpha_func = d3dcmpfunc_to_pipe_func(rs[D3DRS_ALPHAFUNC]);
dsa.alpha_ref_value = (float)rs[D3DRS_ALPHAREF] / 255.0f;
}
*dsa_state = dsa;
}
void
nine_convert_rasterizer_state(struct NineDevice9 *device,
struct pipe_rasterizer_state *rast_state,
const DWORD *rs)
{
struct pipe_rasterizer_state rast;
memset(&rast, 0, sizeof(rast));
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 = 1;
rast.point_size_per_vertex = rs[NINED3DRS_VSPOINTSIZE];
rast.multisample = rs[NINED3DRS_MULTISAMPLE];
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; */
if (rs[NINED3DRS_POSITIONT] &&
!device->driver_caps.window_space_position_support &&
device->driver_caps.disabling_depth_clipping_support) {
/* rast.depth_clip_near = 0; */
/* rast.depth_clip_far = 0; */
rast.depth_clamp = 1;
} else {
rast.depth_clip_near = 1;
rast.depth_clip_far = 1;
/* rast.depth_clamp = 0; */
}
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.line_rectangular = 0;
if (rs[NINED3DRS_VSPOINTSIZE]) {
rast.point_size = 1.0f;
} else {
rast.point_size = CLAMP(asfloat(rs[D3DRS_POINTSIZE]),
asfloat(rs[D3DRS_POINTSIZE_MIN]),
asfloat(rs[D3DRS_POINTSIZE_MAX]));
}
/* offset_units has the ogl/d3d11 meaning.
* d3d9: offset = scale * dz + bias
* ogl/d3d11: offset = scale * dz + r * bias
* with r implementation dependent (+ different formula for float depth
* buffers). r=2^-23 is often the right value for gallium drivers.
* If possible, use offset_units_unscaled, which gives the d3d9
* behaviour, else scale by 1 << 23 */
rast.offset_units = asfloat(rs[D3DRS_DEPTHBIAS]) * (device->driver_caps.offset_units_unscaled ? 1.0f : (float)(1 << 23));
rast.offset_units_unscaled = device->driver_caps.offset_units_unscaled;
rast.offset_scale = asfloat(rs[D3DRS_SLOPESCALEDEPTHBIAS]);
/* rast.offset_clamp = 0.0f; */
*rast_state = 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 pipe_blend_state *blend_state, 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 = !!(rs[NINED3DRS_ALPHACOVERAGE] & 5);
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.max_rt = 3; /* Upper bound. Could be optimized to fb->nr_cbufs for example */
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]; */
*blend_state = 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));
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_lod = 0.0;
samp.lod_bias = 0.0;
samp.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
}
samp.max_lod = 15.0f;
if (ss[NINED3DSAMP_CUBETEX]) {
/* Cube textures are always clamped to edge on D3D */
samp.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
samp.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
samp.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
} else {
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 && !ss[NINED3DSAMP_SHADOW]) ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR;
samp.mag_img_filter = (ss[D3DSAMP_MAGFILTER] == D3DTEXF_POINT && !ss[NINED3DSAMP_SHADOW]) ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR;
if (ss[D3DSAMP_MINFILTER] == D3DTEXF_ANISOTROPIC ||
ss[D3DSAMP_MAGFILTER] == D3DTEXF_ANISOTROPIC)
samp.max_anisotropy = MIN2(16, ss[D3DSAMP_MAXANISOTROPY]);
else
samp.max_anisotropy = 0;
samp.compare_mode = ss[NINED3DSAMP_SHADOW] ? PIPE_TEX_COMPARE_R_TO_TEXTURE : PIPE_TEX_COMPARE_NONE;
samp.compare_func = PIPE_FUNC_LEQUAL;
samp.unnormalized_coords = 0;
samp.seamless_cube_map = 0;
samp.border_color_is_integer = 0;
samp.reduction_mode = 0;
samp.pad = 0;
samp.border_color_format = PIPE_FORMAT_NONE;
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);
}
const enum pipe_format nine_d3d9_to_pipe_format_map[120] =
{
[D3DFMT_UNKNOWN] = PIPE_FORMAT_NONE,
[D3DFMT_R8G8B8] = PIPE_FORMAT_R8G8B8_UNORM,
[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_R3G3B2] = PIPE_FORMAT_B2G3R3_UNORM,
[D3DFMT_A8] = PIPE_FORMAT_A8_UNORM,
[D3DFMT_A8R3G3B2] = PIPE_FORMAT_NONE,
[D3DFMT_X4R4G4B4] = PIPE_FORMAT_B4G4R4X4_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,
[D3DFMT_A8P8] = PIPE_FORMAT_NONE,
[D3DFMT_P8] = 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_L6V5U5] = PIPE_FORMAT_NONE, /* Should be PIPE_FORMAT_R5SG5SB6U_NORM, but interpretation of the data differs a bit. */
[D3DFMT_X8L8V8U8] = PIPE_FORMAT_R8SG8SB8UX8U_NORM,
[D3DFMT_Q8W8V8U8] = PIPE_FORMAT_R8G8B8A8_SNORM,
[D3DFMT_V16U16] = PIPE_FORMAT_R16G16_SNORM,
[D3DFMT_A2W10V10U10] = PIPE_FORMAT_R10SG10SB10SA2U_NORM,
[D3DFMT_D16_LOCKABLE] = PIPE_FORMAT_Z16_UNORM,
[D3DFMT_D32] = PIPE_FORMAT_Z32_UNORM,
[D3DFMT_D15S1] = PIPE_FORMAT_NONE,
[D3DFMT_D24S8] = PIPE_FORMAT_S8_UINT_Z24_UNORM,
[D3DFMT_D24X8] = PIPE_FORMAT_X8Z24_UNORM,
[D3DFMT_D24X4S4] = PIPE_FORMAT_NONE,
[D3DFMT_D16] = PIPE_FORMAT_Z16_UNORM,
[D3DFMT_D32F_LOCKABLE] = PIPE_FORMAT_Z32_FLOAT,
[D3DFMT_D24FS8] = PIPE_FORMAT_Z32_FLOAT_S8X24_UINT,
[D3DFMT_D32_LOCKABLE] = PIPE_FORMAT_NONE,
[D3DFMT_S8_LOCKABLE] = PIPE_FORMAT_NONE,
[D3DFMT_L16] = PIPE_FORMAT_L16_UNORM,
[D3DFMT_VERTEXDATA] = PIPE_FORMAT_NONE,
[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_G16R16F] = PIPE_FORMAT_R16G16_FLOAT,
[D3DFMT_A16B16G16R16F] = PIPE_FORMAT_R16G16B16A16_FLOAT,
[D3DFMT_R32F] = PIPE_FORMAT_R32_FLOAT,
[D3DFMT_G32R32F] = PIPE_FORMAT_R32G32_FLOAT,
[D3DFMT_A32B32G32R32F] = PIPE_FORMAT_R32G32B32A32_FLOAT,
[D3DFMT_CxV8U8] = PIPE_FORMAT_NONE,
[D3DFMT_A1] = PIPE_FORMAT_NONE,
[D3DFMT_A2B10G10R10_XR_BIAS] = PIPE_FORMAT_NONE,
};
const D3DFORMAT nine_pipe_to_d3d9_format_map[PIPE_FORMAT_COUNT] =
{
[PIPE_FORMAT_NONE] = D3DFMT_UNKNOWN,
/* TODO: rename PIPE_FORMAT_R8G8B8_UNORM to PIPE_FORMAT_B8G8R8_UNORM */
[PIPE_FORMAT_R8G8B8_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

@ -1,853 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_PIPE_H_
#define _NINE_PIPE_H_
#include "d3d9.h"
#include "util/format/u_formats.h"
#include "pipe/p_screen.h"
#include "pipe/p_state.h" /* pipe_box */
#include "util/macros.h"
#include "util/u_rect.h"
#include "util/format/u_format.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 pipe_depth_stencil_alpha_state *, const DWORD *);
void nine_convert_rasterizer_state(struct NineDevice9 *, struct pipe_rasterizer_state *, const DWORD *);
void nine_convert_blend_state(struct pipe_blend_state *, const DWORD *);
void nine_convert_sampler_state(struct cso_context *, int idx, const DWORD *);
#define is_ATI1_ATI2(format) (format == PIPE_FORMAT_RGTC1_UNORM || format == PIPE_FORMAT_RGTC2_UNORM)
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 void
pipe_box_to_rect(RECT *dst, const struct pipe_box *src)
{
dst->left = src->x;
dst->right = src->x + src->width;
dst->top = src->y;
dst->bottom = src->y + src->height;
}
static inline void
rect_minify_inclusive(RECT *rect)
{
rect->left = rect->left >> 2;
rect->top = rect->top >> 2;
rect->right = DIV_ROUND_UP(rect->right, 2);
rect->bottom = DIV_ROUND_UP(rect->bottom, 2);
}
/* We suppose:
* 0 <= rect->left < rect->right
* 0 <= rect->top < rect->bottom
*/
static inline void
fit_rect_format_inclusive(enum pipe_format format, RECT *rect, int width, int height)
{
const unsigned w = util_format_get_blockwidth(format);
const unsigned h = util_format_get_blockheight(format);
if (util_format_is_compressed(format)) {
rect->left = rect->left - rect->left % w;
rect->top = rect->top - rect->top % h;
rect->right = (rect->right % w) == 0 ?
rect->right :
rect->right - (rect->right % w) + w;
rect->bottom = (rect->bottom % h) == 0 ?
rect->bottom :
rect->bottom - (rect->bottom % h) + h;
}
rect->right = MIN2(rect->right, width);
rect->bottom = MIN2(rect->bottom, height);
}
static inline bool
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 bool
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
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 bool
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 bool
fetch4_compatible_format( D3DFORMAT fmt )
{
/* Basically formats with only red channel are allowed (with some exceptions) */
static const D3DFORMAT allowed[] = { /* TODO: list incomplete */
D3DFMT_L8,
D3DFMT_L16,
D3DFMT_R16F,
D3DFMT_R32F,
D3DFMT_A8,
D3DFMT_DF16,
D3DFMT_DF24,
D3DFMT_INTZ
};
unsigned i;
for (i = 0; i < sizeof(allowed)/sizeof(D3DFORMAT); i++) {
if (fmt == allowed[i]) { return true; }
}
return false;
}
/* ATI1 and ATI2 are not officially compressed in d3d9 */
static inline bool
compressed_format( D3DFORMAT fmt )
{
switch (fmt) {
case D3DFMT_DXT1:
case D3DFMT_DXT2:
case D3DFMT_DXT3:
case D3DFMT_DXT4:
case D3DFMT_DXT5:
return true;
default:
break;
}
return false;
}
static inline bool
depth_stencil_format( D3DFORMAT fmt )
{
static const D3DFORMAT allowed[] = {
D3DFMT_D16_LOCKABLE,
D3DFMT_D32,
D3DFMT_D15S1,
D3DFMT_D24S8,
D3DFMT_D24X8,
D3DFMT_D24X4S4,
D3DFMT_D16,
D3DFMT_D32F_LOCKABLE,
D3DFMT_D24FS8,
D3DFMT_D32_LOCKABLE,
D3DFMT_DF16,
D3DFMT_DF24,
D3DFMT_INTZ
};
unsigned i;
for (i = 0; i < sizeof(allowed)/sizeof(D3DFORMAT); i++) {
if (fmt == allowed[i]) { return true; }
}
return false;
}
static inline unsigned
d3d9_get_pipe_depth_format_bindings(D3DFORMAT format)
{
switch (format) {
case D3DFMT_D32:
case D3DFMT_D15S1:
case D3DFMT_D24S8:
case D3DFMT_D24X8:
case D3DFMT_D24X4S4:
case D3DFMT_D16:
case D3DFMT_D24FS8:
return PIPE_BIND_DEPTH_STENCIL;
case D3DFMT_D32F_LOCKABLE:
case D3DFMT_D16_LOCKABLE:
case D3DFMT_D32_LOCKABLE:
return PIPE_BIND_DEPTH_STENCIL;
case D3DFMT_DF16:
case D3DFMT_DF24:
case D3DFMT_INTZ:
return PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_SAMPLER_VIEW;
default: unreachable("Unexpected format");
}
}
static inline enum pipe_format
d3d9_to_pipe_format_internal(D3DFORMAT format)
{
if (format <= D3DFMT_A2B10G10R10_XR_BIAS)
return nine_d3d9_to_pipe_format_map[format];
switch (format) {
case D3DFMT_INTZ: return PIPE_FORMAT_S8_UINT_Z24_UNORM;
case D3DFMT_DF16: return PIPE_FORMAT_Z16_UNORM;
case D3DFMT_DF24: return PIPE_FORMAT_X8Z24_UNORM;
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_ATI1: return PIPE_FORMAT_RGTC1_UNORM;
case D3DFMT_ATI2: return PIPE_FORMAT_RGTC2_UNORM;
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_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;
}
}
#define format_check_internal(pipe_format) \
screen->is_format_supported(screen, pipe_format, target, \
sample_count, sample_count, bindings)
static inline enum pipe_format
d3d9_to_pipe_format_checked(struct pipe_screen *screen,
D3DFORMAT format,
enum pipe_texture_target target,
unsigned sample_count,
unsigned bindings,
bool srgb,
bool bypass_check)
{
enum pipe_format result;
/* We cannot render to depth textures as a render target */
if (depth_stencil_format(format) && (bindings & PIPE_BIND_RENDER_TARGET))
return PIPE_FORMAT_NONE;
result = d3d9_to_pipe_format_internal(format);
if (result == PIPE_FORMAT_NONE)
return PIPE_FORMAT_NONE;
if (srgb)
result = util_format_srgb(result);
/* bypass_check: Used for D3DPOOL_SCRATCH, which
* isn't limited to the formats supported by the
* device, and to check we are not using a format
* fallback. */
if (bypass_check || format_check_internal(result))
return result;
/* fallback to another format for formats
* that match several pipe_format */
switch(format) {
/* depth buffer formats are not lockable (except those for which it
* is precised in the name), so it is ok to match to another similar
* format. In all cases, if the app reads the texture with a shader,
* it gets depth on r and doesn't get stencil.*/
case D3DFMT_D16:
/* D16 support is a requirement, but as it cannot be locked,
* it is ok to revert to D24 */
if (format_check_internal(PIPE_FORMAT_Z24X8_UNORM))
return PIPE_FORMAT_Z24X8_UNORM;
if (format_check_internal(PIPE_FORMAT_X8Z24_UNORM))
return PIPE_FORMAT_X8Z24_UNORM;
break;
case D3DFMT_INTZ:
case D3DFMT_D24S8:
if (format_check_internal(PIPE_FORMAT_Z24_UNORM_S8_UINT))
return PIPE_FORMAT_Z24_UNORM_S8_UINT;
break;
case D3DFMT_DF24:
case D3DFMT_D24X8:
if (format_check_internal(PIPE_FORMAT_Z24X8_UNORM))
return PIPE_FORMAT_Z24X8_UNORM;
break;
/* Support for X8L8V8U8 bumpenvmap format with lighting bits.
* X8L8V8U8 is commonly supported among dx9 cards.
* To avoid precision loss, we use PIPE_FORMAT_R32G32B32X32_FLOAT,
* however using PIPE_FORMAT_R8G8B8A8_SNORM should be ok */
case D3DFMT_X8L8V8U8:
if (bindings & PIPE_BIND_RENDER_TARGET)
return PIPE_FORMAT_NONE;
if (format_check_internal(PIPE_FORMAT_R32G32B32X32_FLOAT))
return PIPE_FORMAT_R32G32B32X32_FLOAT;
break;
/* Fallback for YUV formats */
case D3DFMT_UYVY:
case D3DFMT_YUY2:
case D3DFMT_NV12:
if (bindings & PIPE_BIND_RENDER_TARGET)
return PIPE_FORMAT_NONE;
if (format_check_internal(PIPE_FORMAT_R8G8B8X8_UNORM))
return PIPE_FORMAT_R8G8B8X8_UNORM;
break;
default:
break;
}
return PIPE_FORMAT_NONE;
}
/* The quality levels are vendor dependent, so we set our own.
* Every quality level has its own sample count and sample
* position matrix.
* The exact mapping might differ from system to system but that's OK,
* as there's no way to gather more information about quality levels
* in D3D9.
* In case of NONMASKABLE multisample map every quality-level
* to a MASKABLE MultiSampleType:
* 0: no MSAA
* 1: 2x MSAA
* 2: 4x MSAA
* ...
* If the requested quality level is not available to nearest
* matching quality level is used.
* If no multisample is available the function sets
* multisample to D3DMULTISAMPLE_NONE and returns zero.
*/
static inline HRESULT
d3dmultisample_type_check(struct pipe_screen *screen,
D3DFORMAT format,
D3DMULTISAMPLE_TYPE *multisample,
DWORD multisamplequality,
DWORD *levels)
{
unsigned bind, i;
assert(multisample);
if (levels)
*levels = 1;
/* Ignores multisamplequality */
if (*multisample == D3DMULTISAMPLE_NONE)
return D3D_OK;
if (*multisample == D3DMULTISAMPLE_NONMASKABLE) {
if (depth_stencil_format(format))
bind = d3d9_get_pipe_depth_format_bindings(format);
else /* render-target */
bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
*multisample = 0;
for (i = D3DMULTISAMPLE_2_SAMPLES; i < D3DMULTISAMPLE_16_SAMPLES &&
multisamplequality; ++i) {
if (d3d9_to_pipe_format_checked(screen, format, PIPE_TEXTURE_2D,
i, bind, false, false) != PIPE_FORMAT_NONE) {
multisamplequality--;
if (levels)
(*levels)++;
*multisample = i;
}
}
}
/* Make sure to get an exact match */
if (multisamplequality)
return D3DERR_INVALIDCALL;
return D3D_OK;
}
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_ATI1: return "D3DFMT_ATI1";
case D3DFMT_ATI2: return "D3DFMT_ATI2";
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_NVDB: return "D3DFMT_NVDB";
case D3DFMT_RESZ: return "D3DFMT_RESZ";
case D3DFMT_NULL: return "D3DFMT_NULL";
case D3DFMT_ATOC: return "D3DFMT_ATOC";
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 MESA_PRIM_POINTS;
case D3DPT_LINELIST: return MESA_PRIM_LINES;
case D3DPT_LINESTRIP: return MESA_PRIM_LINE_STRIP;
case D3DPT_TRIANGLELIST: return MESA_PRIM_TRIANGLES;
case D3DPT_TRIANGLESTRIP: return MESA_PRIM_TRIANGLE_STRIP;
case D3DPT_TRIANGLEFAN: return MESA_PRIM_TRIANGLE_FAN;
default:
assert(0);
return MESA_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;
case D3DCMP_NEVER_ZERO: return PIPE_FUNC_NEVER; // Tested on windows + ATI HD5770
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;
case D3DFILL_SOLID_ZERO: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;
}
}
static inline unsigned nine_format_get_stride(enum pipe_format format,
unsigned width)
{
unsigned stride = util_format_get_stride(format, width);
return align(stride, 4);
}
static inline unsigned nine_format_get_level_alloc_size(enum pipe_format format,
unsigned width,
unsigned height,
unsigned level)
{
unsigned w, h, size;
w = u_minify(width, level);
h = u_minify(height, level);
if (is_ATI1_ATI2(format)) {
/* For "unknown" formats like ATIx use width * height bytes */
size = w * h;
} else if (format == PIPE_FORMAT_NONE) { /* D3DFMT_NULL */
size = w * h * 4;
} else {
size = nine_format_get_stride(format, w) *
util_format_get_nblocksy(format, h);
}
return size;
}
static inline unsigned nine_format_get_size_and_offsets(enum pipe_format format,
unsigned *offsets,
unsigned width,
unsigned height,
unsigned last_level)
{
unsigned l, w, h, size = 0;
for (l = 0; l <= last_level; ++l) {
w = u_minify(width, l);
h = u_minify(height, l);
offsets[l] = size;
if (is_ATI1_ATI2(format)) {
/* For "unknown" formats like ATIx use width * height bytes */
size += w * h;
} else {
size += nine_format_get_stride(format, w) *
util_format_get_nblocksy(format, h);
}
}
return size;
}
#endif /* _NINE_PIPE_H_ */

View file

@ -1,262 +0,0 @@
/*
* Copyright 2016 Patrick Rudolph <siro@das-labor.org>
* SPDX-License-Identifier: MIT
*/
#include "nine_queue.h"
#include "util/u_thread.h"
#include "util/macros.h"
#include "nine_helpers.h"
#define NINE_CMD_BUF_INSTR (256)
#define NINE_CMD_BUFS (32)
#define NINE_CMD_BUFS_MASK (NINE_CMD_BUFS - 1)
#define NINE_QUEUE_SIZE (8192 * 16 + 128)
#define DBG_CHANNEL DBG_DEVICE
/*
* Single producer - single consumer pool queue
*
* Producer:
* Calls nine_queue_alloc to get a slice of memory in current cmdbuf.
* Calls nine_queue_flush to flush the queue by request.
* The queue is flushed automatically on insufficient space or once the
* cmdbuf contains NINE_CMD_BUF_INSTR instructions.
*
* nine_queue_flush does block, while nine_queue_alloc doesn't block.
*
* nine_queue_alloc returns NULL on insufficient space.
*
* Consumer:
* Calls nine_queue_wait_flush to wait for a cmdbuf.
* After waiting for a cmdbuf it calls nine_queue_get until NULL is returned.
*
* nine_queue_wait_flush does block, while nine_queue_get doesn't block.
*
* Constrains:
* Only a single consumer and a single producer are supported.
*
*/
struct nine_cmdbuf {
unsigned instr_size[NINE_CMD_BUF_INSTR];
unsigned num_instr;
unsigned offset;
void *mem_pool;
BOOL full;
};
struct nine_queue_pool {
struct nine_cmdbuf pool[NINE_CMD_BUFS];
unsigned head;
unsigned tail;
unsigned cur_instr;
BOOL worker_wait;
cnd_t event_pop;
cnd_t event_push;
mtx_t mutex_pop;
mtx_t mutex_push;
};
/* Consumer functions: */
void
nine_queue_wait_flush(struct nine_queue_pool* ctx)
{
struct nine_cmdbuf *cmdbuf = &ctx->pool[ctx->tail];
/* wait for cmdbuf full */
mtx_lock(&ctx->mutex_push);
while (!cmdbuf->full)
{
DBG("waiting for full cmdbuf\n");
cnd_wait(&ctx->event_push, &ctx->mutex_push);
}
DBG("got cmdbuf=%p\n", cmdbuf);
mtx_unlock(&ctx->mutex_push);
cmdbuf->offset = 0;
ctx->cur_instr = 0;
}
/* Gets a pointer to the next memory slice.
* Does not block.
* Returns NULL on empty cmdbuf. */
void *
nine_queue_get(struct nine_queue_pool* ctx)
{
struct nine_cmdbuf *cmdbuf = &ctx->pool[ctx->tail];
unsigned offset;
/* At this pointer there's always a cmdbuf. */
if (ctx->cur_instr == cmdbuf->num_instr) {
/* signal waiting producer */
mtx_lock(&ctx->mutex_pop);
DBG("freeing cmdbuf=%p\n", cmdbuf);
cmdbuf->full = 0;
cnd_signal(&ctx->event_pop);
mtx_unlock(&ctx->mutex_pop);
ctx->tail = (ctx->tail + 1) & NINE_CMD_BUFS_MASK;
return NULL;
}
/* At this pointer there's always a cmdbuf with instruction to process. */
offset = cmdbuf->offset;
cmdbuf->offset += cmdbuf->instr_size[ctx->cur_instr];
ctx->cur_instr ++;
return cmdbuf->mem_pool + offset;
}
/* Producer functions: */
/* Flushes the queue.
* Moves the current cmdbuf to worker thread.
* Blocks until next cmdbuf is free. */
void
nine_queue_flush(struct nine_queue_pool* ctx)
{
struct nine_cmdbuf *cmdbuf = &ctx->pool[ctx->head];
DBG("flushing cmdbuf=%p instr=%d size=%d\n",
cmdbuf, cmdbuf->num_instr, cmdbuf->offset);
/* Nothing to flush */
if (!cmdbuf->num_instr)
return;
/* signal waiting worker */
mtx_lock(&ctx->mutex_push);
cmdbuf->full = 1;
cnd_signal(&ctx->event_push);
mtx_unlock(&ctx->mutex_push);
ctx->head = (ctx->head + 1) & NINE_CMD_BUFS_MASK;
cmdbuf = &ctx->pool[ctx->head];
/* wait for queue empty */
mtx_lock(&ctx->mutex_pop);
while (cmdbuf->full)
{
DBG("waiting for empty cmdbuf\n");
cnd_wait(&ctx->event_pop, &ctx->mutex_pop);
}
DBG("got empty cmdbuf=%p\n", cmdbuf);
mtx_unlock(&ctx->mutex_pop);
cmdbuf->offset = 0;
cmdbuf->num_instr = 0;
}
/* Gets a a pointer to slice of memory with size @space.
* Does block if queue is full.
* Returns NULL on @space > NINE_QUEUE_SIZE. */
void *
nine_queue_alloc(struct nine_queue_pool* ctx, unsigned space)
{
unsigned offset;
struct nine_cmdbuf *cmdbuf = &ctx->pool[ctx->head];
if (space > NINE_QUEUE_SIZE)
return NULL;
/* at this pointer there's always a free queue available */
if ((cmdbuf->offset + space > NINE_QUEUE_SIZE) ||
(cmdbuf->num_instr == NINE_CMD_BUF_INSTR)) {
nine_queue_flush(ctx);
cmdbuf = &ctx->pool[ctx->head];
}
DBG("cmdbuf=%p space=%d\n", cmdbuf, space);
/* at this pointer there's always a free queue with sufficient space available */
offset = cmdbuf->offset;
cmdbuf->offset += space;
cmdbuf->instr_size[cmdbuf->num_instr] = space;
cmdbuf->num_instr ++;
return cmdbuf->mem_pool + offset;
}
/* Returns the current queue flush state.
* TRUE nothing flushed
* FALSE one or more instructions queued flushed. */
bool
nine_queue_no_flushed_work(struct nine_queue_pool* ctx)
{
return (ctx->tail == ctx->head);
}
/* Returns the current queue empty state.
* TRUE no instructions queued.
* FALSE one or more instructions queued. */
bool
nine_queue_isempty(struct nine_queue_pool* ctx)
{
struct nine_cmdbuf *cmdbuf = &ctx->pool[ctx->head];
return (ctx->tail == ctx->head) && !cmdbuf->num_instr;
}
struct nine_queue_pool*
nine_queue_create(void)
{
unsigned i;
struct nine_queue_pool *ctx;
ctx = CALLOC_STRUCT(nine_queue_pool);
if (!ctx)
goto failed;
for (i = 0; i < NINE_CMD_BUFS; i++) {
ctx->pool[i].mem_pool = MALLOC(NINE_QUEUE_SIZE);
if (!ctx->pool[i].mem_pool)
goto failed;
}
cnd_init(&ctx->event_pop);
(void) mtx_init(&ctx->mutex_pop, mtx_plain);
cnd_init(&ctx->event_push);
(void) mtx_init(&ctx->mutex_push, mtx_plain);
/* Block until first cmdbuf has been flushed. */
ctx->worker_wait = true;
return ctx;
failed:
if (ctx) {
for (i = 0; i < NINE_CMD_BUFS; i++) {
if (ctx->pool[i].mem_pool)
FREE(ctx->pool[i].mem_pool);
}
FREE(ctx);
}
return NULL;
}
void
nine_queue_delete(struct nine_queue_pool *ctx)
{
unsigned i;
mtx_destroy(&ctx->mutex_pop);
cnd_destroy(&ctx->event_pop);
mtx_destroy(&ctx->mutex_push);
cnd_destroy(&ctx->event_push);
for (i = 0; i < NINE_CMD_BUFS; i++)
FREE(ctx->pool[i].mem_pool);
FREE(ctx);
}

View file

@ -1,37 +0,0 @@
/*
* Copyright 2016 Patrick Rudolph <siro@das-labor.org>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_QUEUE_H_
#define _NINE_QUEUE_H_
#include "util/compiler.h"
struct nine_queue_pool;
void
nine_queue_wait_flush(struct nine_queue_pool* ctx);
void *
nine_queue_get(struct nine_queue_pool* ctx);
void
nine_queue_flush(struct nine_queue_pool* ctx);
void *
nine_queue_alloc(struct nine_queue_pool* ctx, unsigned space);
bool
nine_queue_no_flushed_work(struct nine_queue_pool* ctx);
bool
nine_queue_isempty(struct nine_queue_pool* ctx);
struct nine_queue_pool*
nine_queue_create(void);
void
nine_queue_delete(struct nine_queue_pool *ctx);
#endif /* _NINE_QUEUE_H_ */

View file

@ -1,32 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#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
};
bool
_nine_get_quirk( unsigned quirk )
{
static bool 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

@ -1,19 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_QUIRK_H_
#define _NINE_QUIRK_H_
#include "util/compiler.h"
bool
_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

@ -1,334 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_SHADER_H_
#define _NINE_SHADER_H_
#include "d3d9types.h"
#include "d3d9caps.h"
#include "nine_defines.h"
#include "nine_helpers.h"
#include "nine_state.h"
#include "pipe/p_state.h" /* PIPE_MAX_ATTRIBS */
#include "util/u_memory.h"
#include "tgsi/tgsi_ureg.h"
struct NineDevice9;
struct NineVertexDeclaration9;
struct ureg_program;
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_constant_combination;
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 */
uint16_t input_map[PIPE_MAX_ATTRIBS]; /* VS input -> NINE_DECLUSAGE_x */
uint8_t num_inputs; /* there may be unused inputs (NINE_DECLUSAGE_NONE) */
bool position_t; /* out, true if VP writes pre-transformed position */
bool point_size; /* out, true if VP writes point size */
float point_size_min;
float point_size_max;
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 */
uint8_t fog_enable;
uint8_t fog_mode;
uint8_t zfog;
uint8_t force_color_in_centroid;
uint8_t color_flatshade;
uint8_t projected; /* ps 1.1 to 1.3 */
uint16_t fetch4;
uint8_t alpha_test_emulation;
uint8_t clip_plane_emulation;
bool emulate_features;
unsigned const_i_base; /* in vec4 (16 byte) units */
unsigned const_b_base; /* in vec4 (16 byte) units */
unsigned const_used_size;
bool int_slots_used[NINE_MAX_CONST_I];
bool bool_slots_used[NINE_MAX_CONST_B];
unsigned const_float_slots;
unsigned const_int_slots;
unsigned const_bool_slots;
unsigned *const_ranges;
struct nine_lconstf lconstf; /* out, NOTE: members to be free'd by user */
uint8_t bumpenvmat_needed;
struct {
struct nine_shader_constant_combination* c_combination;
bool (*int_const_added)[NINE_MAX_CONST_I];
bool (*bool_const_added)[NINE_MAX_CONST_B];
} add_constants_defs;
bool swvp_on;
bool process_vertices;
struct NineVertexDeclaration9 *vdecl_out;
struct pipe_stream_output_info so;
};
struct nine_vs_output_info
{
BYTE output_semantic;
int output_semantic_index;
int mask;
int output_index;
};
void *
nine_create_shader_with_so_and_destroy(struct ureg_program *p,
struct pipe_context *pipe,
const struct pipe_stream_output_info *so);
HRESULT
nine_translate_shader(struct NineDevice9 *device,
struct nine_shader_info *,
struct pipe_context *);
struct nine_shader_variant
{
struct nine_shader_variant *next;
void *cso;
unsigned *const_ranges;
unsigned const_used_size;
uint64_t key;
};
static inline void *
nine_shader_variant_get(struct nine_shader_variant *list,
unsigned **const_ranges,
unsigned *const_used_size,
uint64_t key)
{
while (list->key != key && list->next)
list = list->next;
if (list->key == key) {
*const_ranges = list->const_ranges;
*const_used_size = list->const_used_size;
return list->cso;
}
return NULL;
}
static inline bool
nine_shader_variant_add(struct nine_shader_variant *list,
uint64_t key, void *cso,
unsigned *const_ranges,
unsigned const_used_size)
{
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;
list->next->const_ranges = const_ranges;
list->next->const_used_size = const_used_size;
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);
}
}
struct nine_shader_variant_so
{
struct nine_shader_variant_so *next;
struct NineVertexDeclaration9 *vdecl;
struct pipe_stream_output_info so;
void *cso;
};
static inline void *
nine_shader_variant_so_get(struct nine_shader_variant_so *list,
struct NineVertexDeclaration9 *vdecl,
struct pipe_stream_output_info *so)
{
while (list->vdecl != vdecl && list->next)
list = list->next;
if (list->vdecl == vdecl) {
*so = list->so;
return list->cso;
}
return NULL;
}
static inline bool
nine_shader_variant_so_add(struct nine_shader_variant_so *list,
struct NineVertexDeclaration9 *vdecl,
struct pipe_stream_output_info *so, void *cso)
{
if (list->vdecl == NULL) { /* first shader */
list->next = NULL;
nine_bind(&list->vdecl, vdecl);
list->so = *so;
list->cso = cso;
return true;
}
while (list->next) {
assert(list->vdecl != vdecl);
list = list->next;
}
list->next = MALLOC_STRUCT(nine_shader_variant_so);
if (!list->next)
return false;
list->next->next = NULL;
nine_bind(&list->vdecl, vdecl);
list->next->so = *so;
list->next->cso = cso;
return true;
}
static inline void
nine_shader_variants_so_free(struct nine_shader_variant_so *list)
{
while (list->next) {
struct nine_shader_variant_so *ptr = list->next;
list->next = ptr->next;
nine_bind(&ptr->vdecl, NULL);
FREE(ptr);
}
if (list->vdecl)
nine_bind(&list->vdecl, NULL);
}
struct nine_shader_constant_combination
{
struct nine_shader_constant_combination *next;
int const_i[NINE_MAX_CONST_I][4];
BOOL const_b[NINE_MAX_CONST_B];
};
#define NINE_MAX_CONSTANT_COMBINATION_VARIANTS 32
static inline uint8_t
nine_shader_constant_combination_key(struct nine_shader_constant_combination **list,
bool *int_slots_used,
bool *bool_slots_used,
int *const_i,
BOOL *const_b)
{
int i;
uint8_t index = 0;
bool match;
struct nine_shader_constant_combination **next_allocate = list, *current = *list;
assert(int_slots_used);
assert(bool_slots_used);
assert(const_i);
assert(const_b);
while (current) {
index++; /* start at 1. 0 is for the variant without constant replacement */
match = true;
for (i = 0; i < NINE_MAX_CONST_I; ++i) {
if (int_slots_used[i])
match &= !memcmp(const_i + 4*i, current->const_i[i], sizeof(current->const_i[0]));
}
for (i = 0; i < NINE_MAX_CONST_B; ++i) {
if (bool_slots_used[i])
match &= const_b[i] == current->const_b[i];
}
if (match)
return index;
next_allocate = &current->next;
current = current->next;
}
if (index < NINE_MAX_CONSTANT_COMBINATION_VARIANTS) {
*next_allocate = MALLOC_STRUCT(nine_shader_constant_combination);
current = *next_allocate;
index++;
current->next = NULL;
memcpy(current->const_i, const_i, sizeof(current->const_i));
memcpy(current->const_b, const_b, sizeof(current->const_b));
return index;
}
return 0; /* Too many variants, revert to no replacement */
}
static inline struct nine_shader_constant_combination *
nine_shader_constant_combination_get(struct nine_shader_constant_combination *list, uint8_t index)
{
if (index == 0)
return NULL;
while (index) {
assert(list != NULL);
index--;
if (index == 0)
return list;
list = list->next;
}
assert(false);
return NULL;
}
static inline void
nine_shader_constant_combination_free(struct nine_shader_constant_combination *list)
{
if (!list)
return;
while (list->next) {
struct nine_shader_constant_combination *ptr = list->next;
list->next = ptr->next;
FREE(ptr);
}
FREE(list);
}
/* Returns corresponding opposite test */
static inline unsigned
pipe_comp_to_tgsi_opposite(BYTE flags)
{
switch (flags) {
case PIPE_FUNC_GREATER: return TGSI_OPCODE_SLE;
case PIPE_FUNC_EQUAL: return TGSI_OPCODE_SNE;
case PIPE_FUNC_GEQUAL: return TGSI_OPCODE_SLT;
case PIPE_FUNC_LESS: return TGSI_OPCODE_SGE;
case PIPE_FUNC_NOTEQUAL: return TGSI_OPCODE_SEQ;
case PIPE_FUNC_LEQUAL: return TGSI_OPCODE_SGT;
default:
assert(!"invalid comparison flags");
return TGSI_OPCODE_SGT;
}
}
#endif /* _NINE_SHADER_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,696 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_STATE_H_
#define _NINE_STATE_H_
#include "d3d9.h"
#include "iunknown.h"
#include "nine_defines.h"
#include "pipe/p_state.h"
#include "util/list.h"
#define NINED3DSAMP_MINLOD (D3DSAMP_DMAPOFFSET + 1)
#define NINED3DSAMP_SHADOW (D3DSAMP_DMAPOFFSET + 2)
#define NINED3DSAMP_CUBETEX (D3DSAMP_DMAPOFFSET + 3)
#define NINED3DRS_VSPOINTSIZE (D3DRS_BLENDOPALPHA + 1)
#define NINED3DRS_RTMASK (D3DRS_BLENDOPALPHA + 2)
/* ALPHACOVERAGE:
* bit 0: enable alpha coverage
* bit 1: ATOC is on
*/
#define NINED3DRS_ALPHACOVERAGE (D3DRS_BLENDOPALPHA + 3)
#define NINED3DRS_MULTISAMPLE (D3DRS_BLENDOPALPHA + 4)
#define NINED3DRS_FETCH4 (D3DRS_BLENDOPALPHA + 5)
#define NINED3DRS_EMULATED_ALPHATEST (D3DRS_BLENDOPALPHA + 6)
#define NINED3DRS_POSITIONT (D3DRS_BLENDOPALPHA + 7)
#define D3DRS_LAST D3DRS_BLENDOPALPHA
#define D3DSAMP_LAST D3DSAMP_DMAPOFFSET
#define NINED3DRS_LAST NINED3DRS_POSITIONT /* 217 */
#define NINED3DSAMP_LAST NINED3DSAMP_CUBETEX /* 16 */
#define NINED3DTSS_LAST D3DTSS_CONSTANT
#define NINED3DTS_LAST D3DTS_WORLDMATRIX(255)
#define D3DRS_COUNT (D3DRS_LAST + 1)
#define D3DSAMP_COUNT (D3DSAMP_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_STREAMFREQ (1 << 14)
#define NINE_STATE_BLEND_COLOR (1 << 17)
#define NINE_STATE_STENCIL_REF (1 << 18)
#define NINE_STATE_SAMPLE_MASK (1 << 19)
#define NINE_STATE_FF (0x1f << 20)
#define NINE_STATE_FF_VS (0x17 << 20)
#define NINE_STATE_FF_PS (0x08 << 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_PS_CONSTS (1 << 23)
#define NINE_STATE_FF_VS_OTHER (1 << 24)
#define NINE_STATE_VS_PARAMS_MISC (1 << 25)
#define NINE_STATE_PS_PARAMS_MISC (1 << 26)
#define NINE_STATE_MULTISAMPLE (1 << 27)
#define NINE_STATE_SWVP (1 << 28)
#define NINE_STATE_ALL 0x1fffffff
#define NINE_STATE_UNHANDLED (1 << 29)
/* These states affect the ff shader key,
* which we recompute every time. */
#define NINE_STATE_FF_SHADER 0
#define NINE_STATE_COMMIT_DSA (1 << 0)
#define NINE_STATE_COMMIT_RASTERIZER (1 << 1)
#define NINE_STATE_COMMIT_BLEND (1 << 2)
#define NINE_STATE_COMMIT_CONST_VS (1 << 3)
#define NINE_STATE_COMMIT_CONST_PS (1 << 4)
#define NINE_STATE_COMMIT_VS (1 << 5)
#define NINE_STATE_COMMIT_PS (1 << 6)
#define NINE_MAX_SIMULTANEOUS_RENDERTARGETS 4
#define NINE_MAX_CONST_F_PS3 224
#define NINE_MAX_CONST_F 256
#define NINE_MAX_CONST_I 16
#define NINE_MAX_CONST_B 16
#define NINE_MAX_CONST_F_SWVP 8192
#define NINE_MAX_CONST_I_SWVP 2048
#define NINE_MAX_CONST_B_SWVP 2048
#define NINE_MAX_CONST_VS_SPE_OFFSET (NINE_MAX_CONST_F + (NINE_MAX_CONST_I + NINE_MAX_CONST_B / 4)) /* B consts count only 1/4 th */
#define NINE_MAX_CONST_SWVP_SPE_OFFSET 3564 /* No app will read that far */
#define NINE_MAX_CONST_VS_SPE 9
#define NINE_MAX_CONST_ALL_VS (NINE_MAX_CONST_VS_SPE_OFFSET + NINE_MAX_CONST_VS_SPE)
#define NINE_MAX_CONST_PS_SPE_OFFSET (NINE_MAX_CONST_F_PS3 + (NINE_MAX_CONST_I + NINE_MAX_CONST_B / 4))
/* bumpmap_vars (12), fog (2), D3DRS_ALPHAREF (1) */
#define NINE_MAX_CONST_PS_SPE 15
#define NINE_MAX_CONST_ALL_PS (NINE_MAX_CONST_PS_SPE_OFFSET + NINE_MAX_CONST_PS_SPE)
#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 VS_CONST_F_SIZE(device) (device->may_swvp ? (NINE_MAX_CONST_F_SWVP * sizeof(float[4])) : (NINE_MAX_CONST_F * sizeof(float[4])))
#define VS_CONST_I_SIZE(device) (device->may_swvp ? (NINE_MAX_CONST_I_SWVP * sizeof(int[4])) : (NINE_MAX_CONST_I * sizeof(int[4])))
#define VS_CONST_B_SIZE(device) (device->may_swvp ? (NINE_MAX_CONST_B_SWVP * sizeof(BOOL)) : (NINE_MAX_CONST_B * sizeof(BOOL)))
#define NINE_MAX_TEXTURE_STAGES 8
#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_ff_state {
struct {
uint32_t tex_stage[NINE_MAX_TEXTURE_STAGES][(NINED3DTSS_COUNT + 31) / 32]; /* stateblocks only */
uint32_t transform[(NINED3DTS_COUNT + 31) / 32];
} changed;
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_TEXTURE_STAGES][NINED3DTSS_COUNT];
};
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;
struct nine_range *vs_const_i;
uint16_t ps_const_i; /* NINE_MAX_CONST_I == 16 */
struct nine_range *vs_const_b;
uint16_t ps_const_b; /* NINE_MAX_CONST_B == 16 */
uint8_t ucp;
} changed; /* stateblocks only */
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;
BOOL *vs_const_b;
float *vs_lconstf_temp; /* ProcessVertices */
struct NinePixelShader9 *ps;
float *ps_const_f;
int ps_const_i[NINE_MAX_CONST_I][4];
BOOL ps_const_b[NINE_MAX_CONST_B];
struct NineVertexDeclaration9 *vdecl;
struct NineIndexBuffer9 *idxbuf;
struct NineVertexBuffer9 *stream[PIPE_MAX_ATTRIBS];
uint32_t stream_mask; /* i bit set for *stream[i] not NULL */
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; /* vtxbuf.buffer unused */
unsigned last_vtxbuf_count;
uint16_t vtxstride[PIPE_MAX_ATTRIBS];
UINT stream_freq[PIPE_MAX_ATTRIBS];
struct pipe_clip_state clip;
DWORD rs_advertised[NINED3DRS_COUNT]; /* the ones apps get with GetRenderState */
struct NineBaseTexture9 *texture[NINE_MAX_SAMPLERS]; /* PS, DMAP, VS */
DWORD samp_advertised[NINE_MAX_SAMPLERS][D3DSAMP_COUNT];
struct nine_ff_state ff;
};
struct nine_context {
struct {
uint32_t group;
uint16_t sampler[NINE_MAX_SAMPLERS];
bool vtxbuf_dirty;
BOOL vs_const_f;
BOOL vs_const_i;
BOOL vs_const_b;
BOOL ps_const_f;
BOOL ps_const_i;
BOOL ps_const_b;
BOOL ucp;
} changed;
uint32_t bumpmap_vars[6 * NINE_MAX_TEXTURE_STAGES];
struct NineSurface9 *rt[NINE_MAX_SIMULTANEOUS_RENDERTARGETS];
struct NineSurface9 *ds;
struct {
void *vs;
unsigned *vs_const_ranges;
unsigned vs_const_used_size;
void *ps;
unsigned *ps_const_ranges;
unsigned ps_const_used_size;
} cso_shader;
struct pipe_context *pipe;
struct cso_context *cso;
uint8_t rt_mask;
D3DVIEWPORT9 viewport;
struct pipe_scissor_state scissor;
struct NineVertexShader9 *vs;
BOOL programmable_vs;
float *vs_const_f;
float *vs_const_f_swvp;
int *vs_const_i;
BOOL *vs_const_b;
float *vs_lconstf_temp;
struct NinePixelShader9 *ps;
float *ps_const_f;
int ps_const_i[NINE_MAX_CONST_I][4];
BOOL ps_const_b[NINE_MAX_CONST_B];
BOOL zfog;
struct NineVertexDeclaration9 *vdecl;
unsigned num_vertex_buffers;
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
uint32_t vtxbuf_mask; /* i bit set for context->vtxbuf[i].buffer.resource not NULL */
uint16_t vtxstride[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_resource *idxbuf;
unsigned index_offset;
unsigned index_size;
struct pipe_clip_state clip;
DWORD rs[NINED3DRS_COUNT];
struct {
BOOL enabled;
BOOL shadow;
DWORD lod;
D3DRESOURCETYPE type;
struct pipe_resource *resource;
struct pipe_sampler_view *view[2];
uint8_t pstype;
} texture[NINE_MAX_SAMPLERS];
DWORD samp[NINE_MAX_SAMPLERS][NINED3DSAMP_COUNT];
uint32_t samplers_shadow;
uint32_t samplers_fetch4;
uint8_t bound_samplers_mask_vs;
uint8_t enabled_samplers_mask_vs;
uint8_t enabled_sampler_count_vs;
uint8_t enabled_sampler_count_ps;
uint16_t bound_samplers_mask_ps;
uint16_t enabled_samplers_mask_ps;
int dummy_vbo_bound_at; /* -1 = not bound , >= 0 = bound index */
bool inline_constants;
struct nine_ff_state ff;
/* software vertex processing */
bool swvp;
uint32_t commit;
struct {
struct pipe_framebuffer_state fb;
struct pipe_depth_stencil_alpha_state dsa;
struct pipe_rasterizer_state rast;
struct pipe_blend_state blend;
struct pipe_constant_buffer cb_vs;
struct pipe_constant_buffer cb0_swvp;
struct pipe_constant_buffer cb1_swvp;
struct pipe_constant_buffer cb2_swvp;
struct pipe_constant_buffer cb3_swvp;
struct pipe_constant_buffer cb_ps;
struct pipe_constant_buffer cb_vs_ff;
struct pipe_constant_buffer cb_ps_ff;
} pipe_data;
};
struct nine_state_sw_internal {
struct pipe_transfer *transfers_so[4];
};
struct nine_clipplane {
float plane[4];
};
/* 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;
/* Internal multithreading: When enabled, the nine_context functions
* will append work to a worker thread when possible. Only the worker
* thread can access struct nine_context. */
void
nine_context_set_stream_source_apply(struct NineDevice9 *device,
UINT StreamNumber,
struct pipe_resource *res,
UINT OffsetInBytes,
UINT Stride);
void
nine_context_set_indices_apply(struct NineDevice9 *device,
struct pipe_resource *res,
UINT IndexSize,
UINT OffsetInBytes);
void
nine_context_set_render_state(struct NineDevice9 *device,
D3DRENDERSTATETYPE State,
DWORD Value);
void
nine_context_set_texture(struct NineDevice9 *device,
DWORD Stage,
struct NineBaseTexture9 *tex);
void
nine_context_set_sampler_state(struct NineDevice9 *device,
DWORD Sampler,
D3DSAMPLERSTATETYPE Type,
DWORD Value);
void
nine_context_set_stream_source(struct NineDevice9 *device,
UINT StreamNumber,
struct NineVertexBuffer9 *pVBuf9,
UINT OffsetInBytes,
UINT Stride);
void
nine_context_set_stream_source_freq(struct NineDevice9 *device,
UINT StreamNumber,
UINT Setting);
void
nine_context_set_indices(struct NineDevice9 *device,
struct NineIndexBuffer9 *idxbuf);
void
nine_context_set_vertex_declaration(struct NineDevice9 *device,
struct NineVertexDeclaration9 *vdecl);
void
nine_context_set_vertex_shader(struct NineDevice9 *device,
struct NineVertexShader9 *pShader);
void
nine_context_set_vertex_shader_constant_f(struct NineDevice9 *device,
UINT StartRegister,
const float *pConstantData,
const unsigned pConstantData_size,
UINT Vector4fCount);
void
nine_context_set_vertex_shader_constant_i(struct NineDevice9 *device,
UINT StartRegister,
const int *pConstantData,
const unsigned pConstantData_size,
UINT Vector4iCount);
void
nine_context_set_vertex_shader_constant_b(struct NineDevice9 *device,
UINT StartRegister,
const BOOL *pConstantData,
const unsigned pConstantData_size,
UINT BoolCount);
void
nine_context_set_pixel_shader(struct NineDevice9 *device,
struct NinePixelShader9* ps);
void
nine_context_set_pixel_shader_constant_f(struct NineDevice9 *device,
UINT StartRegister,
const float *pConstantData,
const unsigned pConstantData_size,
UINT Vector4fCount);
void
nine_context_set_pixel_shader_constant_i(struct NineDevice9 *device,
UINT StartRegister,
const int *pConstantData,
const unsigned pConstantData_size,
UINT Vector4iCount);
void
nine_context_set_pixel_shader_constant_b(struct NineDevice9 *device,
UINT StartRegister,
const BOOL *pConstantData,
const unsigned pConstantData_size,
UINT BoolCount);
void
nine_context_set_viewport(struct NineDevice9 *device,
const D3DVIEWPORT9 *viewport);
void
nine_context_set_scissor(struct NineDevice9 *device,
const struct pipe_scissor_state *scissor);
void
nine_context_set_transform(struct NineDevice9 *device,
D3DTRANSFORMSTATETYPE State,
const D3DMATRIX *pMatrix);
void
nine_context_set_material(struct NineDevice9 *device,
const D3DMATERIAL9 *pMaterial);
void
nine_context_set_light(struct NineDevice9 *device,
DWORD Index,
const D3DLIGHT9 *pLight);
void
nine_context_light_enable(struct NineDevice9 *device,
DWORD Index,
BOOL Enable);
void
nine_context_set_texture_stage_state(struct NineDevice9 *device,
DWORD Stage,
D3DTEXTURESTAGESTATETYPE Type,
DWORD Value);
void
nine_context_set_render_target(struct NineDevice9 *device,
DWORD RenderTargetIndex,
struct NineSurface9 *rt);
void
nine_context_set_depth_stencil(struct NineDevice9 *device,
struct NineSurface9 *ds);
void
nine_context_set_clip_plane(struct NineDevice9 *device,
DWORD Index,
const struct nine_clipplane *pPlane);
void
nine_context_set_swvp(struct NineDevice9 *device,
bool swvp);
void
nine_context_apply_stateblock(struct NineDevice9 *device,
const struct nine_state *src);
void
nine_context_clear_fb(struct NineDevice9 *device, DWORD Count,
const D3DRECT *pRects, DWORD Flags,
D3DCOLOR Color, float Z, DWORD Stencil);
void
nine_context_draw_primitive(struct NineDevice9 *device,
D3DPRIMITIVETYPE PrimitiveType,
UINT StartVertex,
UINT PrimitiveCount);
void
nine_context_draw_indexed_primitive(struct NineDevice9 *device,
D3DPRIMITIVETYPE PrimitiveType,
INT BaseVertexIndex,
UINT MinVertexIndex,
UINT NumVertices,
UINT StartIndex,
UINT PrimitiveCount);
void
nine_context_draw_indexed_primitive_from_vtxbuf_idxbuf(struct NineDevice9 *device,
D3DPRIMITIVETYPE PrimitiveType,
UINT MinVertexIndex,
UINT NumVertices,
UINT PrimitiveCount,
unsigned vbuf_stride,
struct pipe_vertex_buffer *vbuf,
struct pipe_resource *ibuf,
void *user_ibuf,
unsigned index_offset,
unsigned index_size);
void
nine_context_resource_copy_region(struct NineDevice9 *device,
struct NineUnknown *dst,
struct NineUnknown *src,
struct pipe_resource* dst_res,
unsigned dst_level,
const struct pipe_box *dst_box,
struct pipe_resource* src_res,
unsigned src_level,
const struct pipe_box *src_box);
void
nine_context_blit(struct NineDevice9 *device,
struct NineUnknown *dst,
struct NineUnknown *src,
struct pipe_blit_info *blit);
void
nine_context_clear_render_target(struct NineDevice9 *device,
struct NineSurface9 *surface,
D3DCOLOR color,
UINT x,
UINT y,
UINT width,
UINT height);
void
nine_context_gen_mipmap(struct NineDevice9 *device,
struct NineUnknown *dst,
struct pipe_resource *res,
UINT base_level, UINT last_level,
UINT first_layer, UINT last_layer,
UINT filter);
void
nine_context_range_upload(struct NineDevice9 *device,
unsigned *counter,
struct NineUnknown *src_ref,
struct pipe_resource *res,
unsigned offset,
unsigned size,
unsigned usage,
const void *data);
void
nine_context_box_upload(struct NineDevice9 *device,
unsigned *counter,
struct NineUnknown *src_ref,
struct pipe_resource *res,
unsigned level,
const struct pipe_box *dst_box,
enum pipe_format src_format,
const void *src, unsigned src_stride,
unsigned src_layer_stride,
const struct pipe_box *src_box);
struct pipe_query *
nine_context_create_query(struct NineDevice9 *device, unsigned query_type);
void
nine_context_destroy_query(struct NineDevice9 *device, struct pipe_query *query);
void
nine_context_begin_query(struct NineDevice9 *device, unsigned *counter, struct pipe_query *query);
void
nine_context_end_query(struct NineDevice9 *device, unsigned *counter, struct pipe_query *query);
bool
nine_context_get_query_result(struct NineDevice9 *device, struct pipe_query *query,
unsigned *counter, bool flush, bool wait,
union pipe_query_result *result);
void
nine_context_pipe_flush(struct NineDevice9 *device);
void nine_state_restore_non_cso(struct NineDevice9 *device);
void nine_state_set_defaults(struct NineDevice9 *, const D3DCAPS9 *,
bool is_reset);
void nine_device_state_clear(struct NineDevice9 *);
void nine_context_clear(struct NineDevice9 *);
void nine_context_update_state(struct NineDevice9 *);
void nine_state_init_sw(struct NineDevice9 *device);
void nine_state_prepare_draw_sw(struct NineDevice9 *device,
struct NineVertexDeclaration9 *vdecl_out,
int start_vertice,
int num_vertices,
struct pipe_stream_output_info *so);
void nine_state_after_draw_sw(struct NineDevice9 *device);
void nine_state_destroy_sw(struct NineDevice9 *device);
void
nine_state_resize_transform(struct nine_ff_state *ff_state, unsigned N);
/* 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_ff_state *, D3DTRANSFORMSTATETYPE,
bool alloc);
HRESULT
nine_state_set_light(struct nine_ff_state *, DWORD, const D3DLIGHT9 *);
HRESULT
nine_state_light_enable(struct nine_ff_state *,
DWORD, BOOL);
const char *nine_d3drs_to_string(DWORD State);
/* CSMT functions */
struct csmt_context;
struct csmt_context *
nine_csmt_create( struct NineDevice9 *This );
void
nine_csmt_destroy( struct NineDevice9 *This, struct csmt_context *ctx );
/* Flushes and waits everything is executed */
void
nine_csmt_process( struct NineDevice9 *This );
/* Flushes and doesn't wait */
void
nine_csmt_flush( struct NineDevice9 *This );
/* Get the pipe_context (should not be called from the worker thread).
* All the work in the worker thread is finished before returning. */
struct pipe_context *
nine_context_get_pipe( struct NineDevice9 *device );
/* Can be called from all threads */
struct pipe_context *
nine_context_get_pipe_multithread( struct NineDevice9 *device );
/* Get the pipe_context (should not be called from the worker thread).
* All the work in the worker thread is paused before returning.
* It is necessary to release in order to restart the thread.
* This is intended for use of the nine_context pipe_context that don't
* need the worker thread to finish all queued job. */
struct pipe_context *
nine_context_get_pipe_acquire( struct NineDevice9 *device );
void
nine_context_get_pipe_release( struct NineDevice9 *device );
bool
nine_context_is_worker( struct NineDevice9 *device );
#endif /* _NINE_STATE_H_ */

View file

@ -1,29 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#include "nineexoverlayextension.h"
#define DBG_CHANNEL DBG_OVERLAYEXTENSION
HRESULT NINE_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

@ -1,32 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#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 NINE_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

@ -1,255 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#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;
struct pipe_context *pipe;
HRESULT hr;
DBG("This=%p pParams=%p pFunction=%p cso=%p\n", This, pParams, pFunction, cso);
hr = NineUnknown_ctor(&This->base, pParams);
if (FAILED(hr))
return hr;
if (cso) {
This->ff_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(NINE_MAX_CONST_F_PS3) / 16;
info.const_b_base = NINE_CONST_B_BASE(NINE_MAX_CONST_F_PS3) / 16;
info.sampler_mask_shadow = 0x0;
info.fetch4 = 0x0;
info.force_color_in_centroid = 0;
info.sampler_ps1xtypes = 0x0;
info.fog_enable = 0;
info.projected = 0;
info.alpha_test_emulation = 0;
info.color_flatshade = 0;
info.add_constants_defs.c_combination = NULL;
info.add_constants_defs.int_const_added = NULL;
info.add_constants_defs.bool_const_added = NULL;
info.process_vertices = false;
info.swvp_on = false;
pipe = nine_context_get_pipe_acquire(device);
hr = nine_translate_shader(device, &info, pipe);
nine_context_get_pipe_release(device);
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->variant.const_ranges = info.const_ranges;
This->variant.const_used_size = info.const_used_size;
This->last_cso = info.cso;
This->last_const_ranges = info.const_ranges;
This->last_const_used_size = info.const_used_size;
This->last_key = 0;
This->sampler_mask = info.sampler_mask;
This->rt_mask = info.rt_mask;
This->bumpenvmat_needed = info.bumpenvmat_needed;
memcpy(This->int_slots_used, info.int_slots_used, sizeof(This->int_slots_used));
memcpy(This->bool_slots_used, info.bool_slots_used, sizeof(This->bool_slots_used));
This->const_int_slots = info.const_int_slots;
This->const_bool_slots = info.const_bool_slots;
This->c_combinations = NULL;
/* no constant relative addressing for ps */
assert(info.lconstf.data == NULL);
assert(info.lconstf.ranges == NULL);
return D3D_OK;
}
void
NinePixelShader9_dtor( struct NinePixelShader9 *This )
{
DBG("This=%p\n", This);
if (This->base.device) {
struct pipe_context *pipe = nine_context_get_pipe_multithread(This->base.device);
struct nine_shader_variant *var = &This->variant;
do {
if (var->cso) {
if (This->base.device->context.cso_shader.ps == var->cso) {
/* unbind because it is illegal to delete something bound */
pipe->bind_fs_state(pipe, NULL);
/* This will rebind cso_shader.ps in case somehow actually
* an identical shader with same cso is bound */
This->base.device->context.commit |= NINE_STATE_COMMIT_PS;
}
pipe->delete_fs_state(pipe, var->cso);
FREE(var->const_ranges);
}
var = var->next;
} while (var);
if (This->ff_cso) {
if (This->ff_cso == This->base.device->context.cso_shader.ps) {
pipe->bind_fs_state(pipe, NULL);
This->base.device->context.commit |= NINE_STATE_COMMIT_PS;
}
pipe->delete_fs_state(pipe, This->ff_cso);
}
}
nine_shader_variants_free(&This->variant);
nine_shader_constant_combination_free(This->c_combinations);
FREE((void *)This->byte_code.tokens); /* const_cast */
NineUnknown_dtor(&This->base);
}
HRESULT NINE_WINAPI
NinePixelShader9_GetFunction( struct NinePixelShader9 *This,
void *pData,
UINT *pSizeOfData )
{
DBG("This=%p pData=%p pSizeOfData=%p\n", This, pData, 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,
unsigned **const_ranges,
unsigned *const_used_size )
{
/* GetVariant is called from nine_context, thus we can
* get pipe directly */
struct pipe_context *pipe = This->base.device->context.pipe;
void *cso;
uint64_t key;
key = This->next_key;
if (key == This->last_key) {
*const_ranges = This->last_const_ranges;
*const_used_size = This->last_const_used_size;
return This->last_cso;
}
cso = nine_shader_variant_get(&This->variant, const_ranges, const_used_size, 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(NINE_MAX_CONST_F_PS3) / 16;
info.const_b_base = NINE_CONST_B_BASE(NINE_MAX_CONST_F_PS3) / 16;
info.byte_code = This->byte_code.tokens;
info.sampler_mask_shadow = key & 0xffff;
/* intended overlap with sampler_mask_shadow */
if (unlikely(This->byte_code.version < 0x20)) {
if (This->byte_code.version < 0x14) {
info.sampler_ps1xtypes = (key >> 4) & 0xff;
info.projected = (key >> 12) & 0xff;
} else {
info.sampler_ps1xtypes = (key >> 6) & 0xfff;
info.projected = 0;
}
} else {
info.sampler_ps1xtypes = 0;
info.projected = 0;
}
info.fog_enable = device->context.rs[D3DRS_FOGENABLE];
info.fog_mode = device->context.rs[D3DRS_FOGTABLEMODE];
info.zfog = device->context.zfog;
info.add_constants_defs.c_combination =
nine_shader_constant_combination_get(This->c_combinations, (key >> 24) & 0xff);
info.add_constants_defs.int_const_added = &This->int_slots_used;
info.add_constants_defs.bool_const_added = &This->bool_slots_used;
info.fetch4 = (key >> 32) & 0xffff;
info.force_color_in_centroid = (key >> 48) & 1;
info.alpha_test_emulation = (key >> 49) & 0x7;
info.color_flatshade = (key >> 52) & 1;
info.force_color_in_centroid &= !info.color_flatshade; /* centroid doesn't make sense with flatshade */
info.process_vertices = false;
info.swvp_on = false;
hr = nine_translate_shader(This->base.device, &info, pipe);
if (FAILED(hr))
return NULL;
nine_shader_variant_add(&This->variant, key, info.cso,
info.const_ranges, info.const_used_size);
cso = info.cso;
*const_ranges = info.const_ranges;
*const_used_size = info.const_used_size;
}
This->last_key = key;
This->last_cso = cso;
This->last_const_ranges = *const_ranges;
This->last_const_used_size = *const_used_size;
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 )
{
if (cso) { /* ff shader. Needs to start with bind count */
NINE_DEVICE_CHILD_BIND_NEW(PixelShader9, ppOut, pDevice, pFunction, cso);
} else {
NINE_DEVICE_CHILD_NEW(PixelShader9, ppOut, pDevice, pFunction, cso);
}
}

View file

@ -1,150 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_PIXELSHADER9_H_
#define _NINE_PIXELSHADER9_H_
#include "iunknown.h"
#include "nine_shader.h"
#include "nine_state.h"
#include "basetexture9.h"
#include "nine_ff.h"
#include "surface9.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;
uint8_t bumpenvmat_needed;
uint16_t sampler_mask;
uint8_t rt_mask;
bool int_slots_used[NINE_MAX_CONST_I];
bool bool_slots_used[NINE_MAX_CONST_B];
unsigned const_int_slots;
unsigned const_bool_slots;
struct nine_shader_constant_combination *c_combinations;
uint64_t ff_key[6];
void *ff_cso;
uint64_t last_key;
void *last_cso;
unsigned *last_const_ranges;
unsigned last_const_used_size; /* in bytes */
uint64_t next_key;
};
static inline struct NinePixelShader9 *
NinePixelShader9( void *data )
{
return (struct NinePixelShader9 *)data;
}
static inline BOOL
NinePixelShader9_UpdateKey( struct NinePixelShader9 *ps,
struct nine_context *context )
{
uint16_t samplers_shadow;
uint16_t samplers_fetch4;
uint16_t samplers_ps1_types;
uint8_t projected;
uint64_t key;
BOOL res;
samplers_shadow = (uint16_t)((context->samplers_shadow & NINE_PS_SAMPLERS_MASK) >> NINE_SAMPLER_PS(0));
samplers_fetch4 = (uint16_t)((context->samplers_fetch4 & NINE_PS_SAMPLERS_MASK) >> NINE_SAMPLER_PS(0));
key = samplers_shadow & ps->sampler_mask;
samplers_fetch4 &= ps->sampler_mask;
if (unlikely(ps->byte_code.version < 0x20)) {
/* variable targets */
uint32_t m = ps->sampler_mask;
samplers_ps1_types = 0;
while (m) {
int s = ffs(m) - 1;
m &= ~(1 << s);
samplers_ps1_types |= (context->texture[s].enabled ? context->texture[s].pstype : 1) << (s * 2);
}
/* Note: For ps 1.X, only samplers 0 1 2 and 3 are available (except 1.4 where 4 and 5 are available).
* ps < 1.4: samplers_shadow 4b, samplers_ps1_types 8b, projected 8b
* ps 1.4: samplers_shadow 6b, samplers_ps1_types 12b
* Tot ps X.X samplers_shadow + extra: 20b */
assert((ps->byte_code.version < 0x14 && !(ps->sampler_mask & 0xFFF0)) || !(ps->sampler_mask & 0xFFC0));
if (unlikely(ps->byte_code.version < 0x14)) {
key |= samplers_ps1_types << 4;
projected = nine_ff_get_projected_key_programmable(context);
key |= ((uint64_t) projected) << 12;
} else {
key |= samplers_ps1_types << 6;
}
}
if (ps->byte_code.version < 0x30 && context->rs[D3DRS_FOGENABLE]) {
key |= 1 << 20;
key |= ((uint64_t)context->rs[D3DRS_FOGTABLEMODE]) << 21; /* 2 bits */
key |= ((uint64_t)context->zfog) << 23;
}
if ((ps->const_int_slots > 0 || ps->const_bool_slots > 0) && context->inline_constants)
key |= ((uint64_t)nine_shader_constant_combination_key(&ps->c_combinations,
ps->int_slots_used,
ps->bool_slots_used,
(void *)context->ps_const_i,
context->ps_const_b)) << 24;
key |= ((uint64_t)(context->rs[NINED3DRS_FETCH4] & samplers_fetch4)) << 32; /* 16 bits */
/* centroid interpolation automatically used for color ps inputs */
if (context->rt[0]->base.info.nr_samples)
key |= ((uint64_t)1) << 48;
key |= ((uint64_t)(context->rs[NINED3DRS_EMULATED_ALPHATEST] & 0x7)) << 49; /* 3 bits */
if (context->rs[D3DRS_SHADEMODE] == D3DSHADE_FLAT)
key |= ((uint64_t)1) << 52;
res = ps->last_key != key;
if (res)
ps->next_key = key;
return res;
}
void *
NinePixelShader9_GetVariant( struct NinePixelShader9 *ps,
unsigned **const_ranges,
unsigned *const_used_size );
/*** 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 NINE_WINAPI
NinePixelShader9_GetFunction( struct NinePixelShader9 *This,
void *pData,
UINT *pSizeOfData );
#endif /* _NINE_PIXELSHADER9_H_ */

View file

@ -1,296 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#include "device9.h"
#include "nine_state.h"
#include "query9.h"
#include "nine_helpers.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
#include "util/u_math.h"
#include "nine_dump.h"
#define DBG_CHANNEL DBG_QUERY
static inline unsigned
d3dquerytype_to_pipe_query(struct pipe_screen *screen, D3DQUERYTYPE type)
{
switch (type) {
case D3DQUERYTYPE_EVENT:
return PIPE_QUERY_GPU_FINISHED;
case D3DQUERYTYPE_OCCLUSION:
return screen->caps.occlusion_query ?
PIPE_QUERY_OCCLUSION_COUNTER : PIPE_QUERY_TYPES;
case D3DQUERYTYPE_TIMESTAMP:
return screen->caps.query_timestamp ?
PIPE_QUERY_TIMESTAMP : PIPE_QUERY_TYPES;
case D3DQUERYTYPE_TIMESTAMPDISJOINT:
case D3DQUERYTYPE_TIMESTAMPFREQ:
return screen->caps.query_timestamp ?
PIPE_QUERY_TIMESTAMP_DISJOINT : PIPE_QUERY_TYPES;
case D3DQUERYTYPE_VERTEXSTATS:
return screen->caps.query_pipeline_statistics ?
PIPE_QUERY_PIPELINE_STATISTICS : PIPE_QUERY_TYPES;
default:
return PIPE_QUERY_TYPES; /* Query not supported */
}
}
#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_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);
default:
assert(0);
return 0;
}
}
HRESULT
nine_is_query_supported(struct pipe_screen *screen, D3DQUERYTYPE type)
{
const unsigned ptype = d3dquerytype_to_pipe_query(screen, 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 NineDevice9 *device = pParams->device;
const unsigned ptype = d3dquerytype_to_pipe_query(device->screen, Type);
HRESULT hr;
DBG("This=%p pParams=%p Type=%d\n", This, pParams, Type);
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 = nine_context_create_query(device, ptype);
if (!This->pq)
return E_OUTOFMEMORY;
} else {
assert(0); /* we have checked this case before */
}
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 NineDevice9 *device = This->base.device;
DBG("This=%p\n", This);
if (This->pq) {
if (This->state == NINE_QUERY_STATE_RUNNING)
nine_context_end_query(device, &This->counter, This->pq);
nine_context_destroy_query(device, This->pq);
}
NineUnknown_dtor(&This->base);
}
D3DQUERYTYPE NINE_WINAPI
NineQuery9_GetType( struct NineQuery9 *This )
{
return This->type;
}
DWORD NINE_WINAPI
NineQuery9_GetDataSize( struct NineQuery9 *This )
{
return This->result_size;
}
HRESULT NINE_WINAPI
NineQuery9_Issue( struct NineQuery9 *This,
DWORD dwIssueFlags )
{
struct NineDevice9 *device = This->base.device;
DBG("This=%p dwIssueFlags=%d\n", This, dwIssueFlags);
user_assert((dwIssueFlags == D3DISSUE_BEGIN) ||
(dwIssueFlags == 0) ||
(dwIssueFlags == D3DISSUE_END), D3DERR_INVALIDCALL);
/* Wine tests: always return D3D_OK on D3DISSUE_BEGIN
* even when the call is supposed to be forbidden */
if (dwIssueFlags == D3DISSUE_BEGIN && This->instant)
return D3D_OK;
if (dwIssueFlags == D3DISSUE_BEGIN) {
if (This->state == NINE_QUERY_STATE_RUNNING)
nine_context_end_query(device, &This->counter, This->pq);
nine_context_begin_query(device, &This->counter, This->pq);
This->state = NINE_QUERY_STATE_RUNNING;
} else {
if (This->state != NINE_QUERY_STATE_RUNNING &&
This->type != D3DQUERYTYPE_EVENT &&
This->type != D3DQUERYTYPE_TIMESTAMP)
nine_context_begin_query(device, &This->counter, This->pq);
nine_context_end_query(device, &This->counter, This->pq);
This->state = NINE_QUERY_STATE_ENDED;
}
return D3D_OK;
}
union nine_query_result
{
D3DDEVINFO_D3DVERTEXSTATS vertexstats;
DWORD dw;
BOOL b;
UINT64 u64;
};
HRESULT NINE_WINAPI
NineQuery9_GetData( struct NineQuery9 *This,
void *pData,
DWORD dwSize,
DWORD dwGetDataFlags )
{
struct NineDevice9 *device = This->base.device;
bool ok, wait_query_result = false;
union pipe_query_result presult;
union nine_query_result nresult;
DBG("This=%p pData=%p dwSize=%d dwGetDataFlags=%d\n",
This, pData, dwSize, dwGetDataFlags);
/* according to spec we should return D3DERR_INVALIDCALL here, but
* wine returns S_FALSE because it is apparently the behaviour
* on windows */
user_assert(This->state != NINE_QUERY_STATE_RUNNING, S_FALSE);
user_assert(dwSize == 0 || pData, D3DERR_INVALIDCALL);
user_assert(dwGetDataFlags == 0 ||
dwGetDataFlags == D3DGETDATA_FLUSH, D3DERR_INVALIDCALL);
if (This->state == NINE_QUERY_STATE_FRESH) {
/* App forgot calling Issue. call it for it.
* However Wine states that return value should
* be S_OK, so wait for the result to return S_OK. */
NineQuery9_Issue(This, D3DISSUE_END);
wait_query_result = true;
}
/* The documentation mentions no special case for D3DQUERYTYPE_TIMESTAMP.
* However Windows tests show that the query always succeeds when
* D3DGETDATA_FLUSH is specified. */
if (This->type == D3DQUERYTYPE_TIMESTAMP &&
(dwGetDataFlags & D3DGETDATA_FLUSH))
wait_query_result = true;
/* Note: We ignore dwGetDataFlags, because get_query_result will
* flush automatically if needed */
ok = nine_context_get_query_result(device, This->pq, &This->counter,
!!(dwGetDataFlags & D3DGETDATA_FLUSH),
wait_query_result, &presult);
if (!ok) 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:
/* Applications use it to convert the TIMESTAMP value to time.
AMD drivers on win seem to return the actual hardware clock
resolution and corresponding values in TIMESTAMP.
However, this behaviour is not easy to replicate here.
So instead we do what wine and opengl do, and use
nanoseconds TIMESTAMPs.
(Which is also the unit used by PIPE_QUERY_TIMESTAMP.)
*/
nresult.u64 = 1000000000;
break;
case D3DQUERYTYPE_VERTEXSTATS:
nresult.vertexstats.NumRenderedTriangles =
presult.pipeline_statistics.c_invocations;
nresult.vertexstats.NumExtraClippingTriangles =
presult.pipeline_statistics.c_primitives;
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

@ -1,66 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#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,
};
struct NineQuery9
{
struct NineUnknown base;
struct pipe_query *pq;
DWORD result_size;
D3DQUERYTYPE type;
enum nine_query_state state;
bool instant; /* true if D3DISSUE_BEGIN is not needed / invalid */
unsigned counter; /* Number of pending Begin/End (0 if internal multithreading off) */
};
static inline struct NineQuery9 *
NineQuery9( void *data )
{
return (struct NineQuery9 *)data;
}
HRESULT
nine_is_query_supported(struct pipe_screen *screen, 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 NINE_WINAPI
NineQuery9_GetType( struct NineQuery9 *This );
DWORD NINE_WINAPI
NineQuery9_GetDataSize( struct NineQuery9 *This );
HRESULT NINE_WINAPI
NineQuery9_Issue( struct NineQuery9 *This,
DWORD dwIssueFlags );
HRESULT NINE_WINAPI
NineQuery9_GetData( struct NineQuery9 *This,
void *pData,
DWORD dwSize,
DWORD dwGetDataFlags );
#endif /* _NINE_QUERY9_H_ */

View file

@ -1,164 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#include "resource9.h"
#include "device9.h"
#include "nine_helpers.h"
#include "nine_defines.h"
#include "util/u_inlines.h"
#include "util/u_resource.h"
#include "pipe/p_screen.h"
#define DBG_CHANNEL DBG_RESOURCE
HRESULT
NineResource9_ctor( struct NineResource9 *This,
struct NineUnknownParams *pParams,
struct pipe_resource *initResource,
BOOL Allocate,
D3DRESOURCETYPE Type,
D3DPOOL Pool,
DWORD Usage)
{
struct pipe_screen *screen;
HRESULT hr;
DBG("This=%p pParams=%p initResource=%p Allocate=%d "
"Type=%d Pool=%d Usage=%d\n",
This, pParams, initResource, (int) Allocate,
Type, Pool, Usage);
hr = NineUnknown_ctor(&This->base, pParams);
if (FAILED(hr))
return hr;
This->info.screen = screen = This->base.device->screen;
if (initResource)
pipe_resource_reference(&This->resource, initResource);
if (Allocate) {
assert(!initResource);
/* On Windows it is possible allocation fails when
* IDirect3DDevice9::GetAvailableTextureMem() still reports
* enough free space.
*
* Some games allocate surfaces
* in a loop until they receive D3DERR_OUTOFVIDEOMEMORY to measure
* the available texture memory size.
*
* We are not using the drivers VRAM statistics because:
* * This would add overhead to each resource allocation.
* * Freeing memory is lazy and takes some time, but applications
* expects the memory counter to change immediately after allocating
* or freeing memory.
*
* Vertexbuffers and indexbuffers are not accounted !
*/
if (This->info.target != PIPE_BUFFER) {
This->size = util_resource_size(&This->info);
p_atomic_add(&This->base.device->available_texture_mem, -This->size);
/* Before failing allocation, evict MANAGED memory */
if (This->base.device &&
p_atomic_read(&This->base.device->available_texture_mem) <=
This->base.device->available_texture_limit)
NineDevice9_EvictManagedResourcesInternal(This->base.device);
if (p_atomic_read(&This->base.device->available_texture_mem) <=
This->base.device->available_texture_limit) {
DBG("Memory allocation failure: software limit\n");
return D3DERR_OUTOFVIDEOMEMORY;
}
}
DBG("(%p) Creating pipe_resource.\n", This);
This->resource = nine_resource_create_with_retry(This->base.device, screen, &This->info);
if (!This->resource)
return D3DERR_OUTOFVIDEOMEMORY;
}
DBG("Current texture memory count: (%d/%d)KB\n",
(int)(This->base.device->available_texture_mem >> 10),
(int)(This->base.device->available_texture_limit >> 10));
This->type = Type;
This->pool = Pool;
This->usage = Usage;
This->priority = 0;
return D3D_OK;
}
void
NineResource9_dtor( struct NineResource9 *This )
{
DBG("This=%p\n", This);
/* NOTE: We do have to use refcounting, the driver might
* still hold a reference. */
pipe_resource_reference(&This->resource, NULL);
/* NOTE: size is 0, unless something has actually been allocated */
if (This->base.device)
p_atomic_add(&This->base.device->available_texture_mem, This->size);
NineUnknown_dtor(&This->base);
}
struct pipe_resource *
NineResource9_GetResource( struct NineResource9 *This )
{
return This->resource;
}
D3DPOOL
NineResource9_GetPool( struct NineResource9 *This )
{
return This->pool;
}
DWORD NINE_WINAPI
NineResource9_SetPriority( struct NineResource9 *This,
DWORD PriorityNew )
{
DWORD prev;
DBG("This=%p, PriorityNew=%d\n", This, PriorityNew);
if (This->pool != D3DPOOL_MANAGED || This->type == D3DRTYPE_SURFACE)
return 0;
prev = This->priority;
This->priority = PriorityNew;
return prev;
}
DWORD NINE_WINAPI
NineResource9_GetPriority( struct NineResource9 *This )
{
if (This->pool != D3DPOOL_MANAGED || This->type == D3DRTYPE_SURFACE)
return 0;
return This->priority;
}
/* NOTE: Don't forget to adjust locked vtable if you change this ! */
void NINE_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 NINE_WINAPI
NineResource9_GetType( struct NineResource9 *This )
{
return This->type;
}

View file

@ -1,72 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_RESOURCE9_H_
#define _NINE_RESOURCE9_H_
#include "iunknown.h"
#include "pipe/p_state.h"
struct pipe_screen;
struct hash_table;
struct NineDevice9;
struct NineResource9
{
struct NineUnknown base;
struct pipe_resource *resource; /* device resource */
D3DRESOURCETYPE type;
D3DPOOL pool;
DWORD priority;
DWORD usage;
struct pipe_resource info; /* resource configuration */
long long size;
};
static inline struct NineResource9 *
NineResource9( void *data )
{
return (struct NineResource9 *)data;
}
HRESULT
NineResource9_ctor( struct NineResource9 *This,
struct NineUnknownParams *pParams,
struct pipe_resource *initResource,
BOOL Allocate,
D3DRESOURCETYPE Type,
D3DPOOL Pool,
DWORD Usage);
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 ***/
DWORD NINE_WINAPI
NineResource9_SetPriority( struct NineResource9 *This,
DWORD PriorityNew );
DWORD NINE_WINAPI
NineResource9_GetPriority( struct NineResource9 *This );
void NINE_WINAPI
NineResource9_PreLoad( struct NineResource9 *This );
D3DRESOURCETYPE NINE_WINAPI
NineResource9_GetType( struct NineResource9 *This );
#endif /* _NINE_RESOURCE9_H_ */

View file

@ -1,585 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#include "stateblock9.h"
#include "device9.h"
#include "basetexture9.h"
#include "nine_helpers.h"
#include "vertexdeclaration9.h"
#include "vertexbuffer9.h"
#include "indexbuffer9.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);
DBG("This=%p pParams=%p type=%d\n", This, pParams, type);
if (FAILED(hr))
return hr;
This->type = type;
This->state.vs_const_f = MALLOC(VS_CONST_F_SIZE(This->base.device));
This->state.ps_const_f = MALLOC(This->base.device->ps_const_size);
This->state.vs_const_i = MALLOC(VS_CONST_I_SIZE(This->base.device));
This->state.vs_const_b = MALLOC(VS_CONST_B_SIZE(This->base.device));
if (!This->state.vs_const_f || !This->state.ps_const_f ||
!This->state.vs_const_i || !This->state.vs_const_b)
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;
unsigned i;
for (i = 0; i < ARRAY_SIZE(state->rt); ++i)
nine_bind(&state->rt[i], NULL);
nine_bind(&state->ds, NULL);
nine_bind(&state->vs, NULL);
nine_bind(&state->ps, NULL);
nine_bind(&state->vdecl, NULL);
for (i = 0; i < PIPE_MAX_ATTRIBS; ++i)
nine_bind(&state->stream[i], NULL);
nine_bind(&state->idxbuf, NULL);
for (i = 0; i < NINE_MAX_SAMPLERS; ++i)
nine_bind(&state->texture[i], NULL);
FREE(state->vs_const_f);
FREE(state->ps_const_f);
FREE(state->vs_const_i);
FREE(state->vs_const_b);
FREE(state->ff.light);
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);
}
if (This->state.changed.vs_const_i) {
for (r = This->state.changed.vs_const_i; r->next; r = r->next);
nine_range_pool_put_chain(pool, This->state.changed.vs_const_i, r);
}
if (This->state.changed.vs_const_b) {
for (r = This->state.changed.vs_const_b; r->next; r = r->next);
nine_range_pool_put_chain(pool, This->state.changed.vs_const_b, r);
}
NineUnknown_dtor(&This->base);
}
static void
NineStateBlock9_BindBuffer( struct NineDevice9 *device,
bool applyToDevice,
struct NineBuffer9 **slot,
struct NineBuffer9 *buf )
{
if (applyToDevice)
NineBindBufferToDevice(device, slot, buf);
else
nine_bind(slot, buf);
}
static void
NineStateBlock9_BindTexture( struct NineDevice9 *device,
bool applyToDevice,
struct NineBaseTexture9 **slot,
struct NineBaseTexture9 *tex )
{
if (applyToDevice)
NineBindTextureToDevice(device, slot, tex);
else
nine_bind(slot, tex);
}
/* 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 NineDevice9 *device,
struct nine_state *dst,
struct nine_state *src,
struct nine_state *mask, /* aliases either src or dst */
const bool apply,
struct nine_range_pool *pool)
{
unsigned i, s;
DBG("apply:%d changed.group: %x\n", (int)apply, (int)mask->changed.group );
/* device changed.* are unused.
* Instead nine_context_apply_stateblock is used and will
* internally set the right context->changed fields.
* Uncomment these only if we want to apply a stateblock onto a stateblock.
*
* 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.
*
* Note: Currently when we apply stateblocks, it's always on the device state.
* Should it affect recording stateblocks ? Since it's on device state, there
* is no need to copy which ranges are dirty. If it turns out we should affect
* recording stateblocks, the info should be copied.
*/
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));
}
for (r = mask->changed.vs_const_i; r; r = r->next) {
memcpy(&dst->vs_const_i[r->bgn * 4],
&src->vs_const_i[r->bgn * 4],
(r->end - r->bgn) * 4 * sizeof(int));
}
for (r = mask->changed.vs_const_b; r; r = r->next) {
memcpy(&dst->vs_const_b[r->bgn],
&src->vs_const_b[r->bgn],
(r->end - r->bgn) * sizeof(int));
}
}
/* 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 (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 (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];
}
}
/* Render states.
* TODO: Maybe build a list ?
*/
for (i = 0; i < ARRAY_SIZE(mask->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);
DBG("State %d %s = %d\n", i * 32 + r, nine_d3drs_to_string(i * 32 + r), (int)src->rs_advertised[i * 32 + r]);
dst->rs_advertised[i * 32 + r] = src->rs_advertised[i * 32 + r];
}
}
/* Clip planes. */
if (mask->changed.ucp) {
DBG("ucp: %x\n", 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_advertised[s], &src->samp_advertised[s], sizeof(dst->samp_advertised[s]));
} else {
uint32_t m = mask->changed.sampler[s];
DBG("samp %d: changed = %x\n", i, (int)m);
while (m) {
const int i = ffs(m) - 1;
m &= ~(1 << i);
dst->samp_advertised[s][i] = src->samp_advertised[s][i];
}
}
/* if (apply)
* dst->changed.sampler[s] |= mask->changed.sampler[s];*/
}
}
/* Index buffer. */
if (mask->changed.group & NINE_STATE_IDXBUF)
NineStateBlock9_BindBuffer(device,
apply,
(struct NineBuffer9 **)&dst->idxbuf,
(struct NineBuffer9 *)src->idxbuf);
/* Vertex streams. */
if (mask->changed.vtxbuf | mask->changed.stream_freq) {
DBG("vtxbuf/stream_freq: %x/%x\n", 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)) {
NineStateBlock9_BindBuffer(device,
apply,
(struct NineBuffer9 **)&dst->stream[i],
(struct NineBuffer9 *)src->stream[i]);
if (src->stream[i]) {
dst->vtxbuf[i].buffer_offset = src->vtxbuf[i].buffer_offset;
dst->vtxstride[i] = src->vtxstride[i];
}
}
if (mask->changed.stream_freq & (1 << i))
dst->stream_freq[i] = src->stream_freq[i];
}
/*
* if (apply) {
* dst->changed.vtxbuf |= mask->changed.vtxbuf;
* dst->changed.stream_freq |= mask->changed.stream_freq;
* }*/
}
/* Textures */
if (mask->changed.texture) {
uint32_t m = mask->changed.texture;
for (s = 0; m; ++s, m >>= 1)
if (m & 1)
NineStateBlock9_BindTexture(device, apply, &dst->texture[s], src->texture[s]);
}
if (!(mask->changed.group & NINE_STATE_FF))
return;
WARN_ONCE("Fixed function state not handled properly by StateBlocks.\n");
/* Fixed function state. */
if (mask->changed.group & NINE_STATE_FF_MATERIAL)
dst->ff.material = src->ff.material;
if (mask->changed.group & NINE_STATE_FF_PS_CONSTS) {
for (s = 0; s < NINE_MAX_TEXTURE_STAGES; ++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) {
unsigned num_lights = MAX2(dst->ff.num_lights, src->ff.num_lights);
/* Can happen in Capture() if device state has created new lights after
* the stateblock was created.
* Can happen in Apply() if the stateblock had recorded the creation of
* new lights. */
if (dst->ff.num_lights < num_lights) {
dst->ff.light = REALLOC(dst->ff.light,
dst->ff.num_lights * sizeof(D3DLIGHT9),
num_lights * sizeof(D3DLIGHT9));
memset(&dst->ff.light[dst->ff.num_lights], 0, (num_lights - dst->ff.num_lights) * sizeof(D3DLIGHT9));
/* if mask == dst, a Type of 0 will trigger
* "dst->ff.light[i] = src->ff.light[i];" later,
* which is what we want in that case. */
if (mask != dst) {
for (i = dst->ff.num_lights; i < num_lights; ++i)
dst->ff.light[i].Type = (D3DLIGHTTYPE)NINED3DLIGHT_INVALID;
}
dst->ff.num_lights = num_lights;
}
/* Can happen in Capture() if the stateblock had recorded the creation of
* new lights.
* Can happen in Apply() if device state has created new lights after
* the stateblock was created. */
if (src->ff.num_lights < num_lights) {
src->ff.light = REALLOC(src->ff.light,
src->ff.num_lights * sizeof(D3DLIGHT9),
num_lights * sizeof(D3DLIGHT9));
memset(&src->ff.light[src->ff.num_lights], 0, (num_lights - src->ff.num_lights) * sizeof(D3DLIGHT9));
for (i = src->ff.num_lights; i < num_lights; ++i)
src->ff.light[i].Type = (D3DLIGHTTYPE)NINED3DLIGHT_INVALID;
src->ff.num_lights = num_lights;
}
/* Note: mask is either src or dst, so at this point src, dst and mask
* have num_lights lights. */
for (i = 0; i < num_lights; ++i)
if (mask->ff.light[i].Type != NINED3DLIGHT_INVALID)
dst->ff.light[i] = src->ff.light[i];
memcpy(dst->ff.active_light, src->ff.active_light, sizeof(src->ff.active_light) );
dst->ff.num_lights_active = src->ff.num_lights_active;
}
if (mask->changed.group & NINE_STATE_FF_VSTRANSF) {
for (i = 0; i < ARRAY_SIZE(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->ff, s, true) =
*nine_state_access_transform(&src->ff, s, false);
}
/* if (apply)
* dst->ff.changed.transform[i] |= mask->ff.changed.transform[i];*/
}
}
}
static void
nine_state_copy_common_all(struct NineDevice9 *device,
struct nine_state *dst,
struct nine_state *src,
struct nine_state *help,
const bool 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) {
memcpy(&dst->vs_const_f[0],
&src->vs_const_f[0], VS_CONST_F_SIZE(device));
memcpy(dst->vs_const_i, src->vs_const_i, VS_CONST_I_SIZE(device));
memcpy(dst->vs_const_b, src->vs_const_b, VS_CONST_B_SIZE(device));
}
/* 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));
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));
}
/* Render states. */
memcpy(dst->rs_advertised, src->rs_advertised, sizeof(dst->rs_advertised));
/* 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_advertised, src->samp_advertised, sizeof(dst->samp_advertised));
/* if (apply)
* memcpy(dst->changed.sampler,
* src->changed.sampler, sizeof(dst->changed.sampler));*/
/* Index buffer. */
NineStateBlock9_BindBuffer(device,
apply,
(struct NineBuffer9 **)&dst->idxbuf,
(struct NineBuffer9 *)src->idxbuf);
/* Vertex streams. */
if (1) {
for (i = 0; i < ARRAY_SIZE(dst->stream); ++i) {
NineStateBlock9_BindBuffer(device,
apply,
(struct NineBuffer9 **)&dst->stream[i],
(struct NineBuffer9 *)src->stream[i]);
if (src->stream[i]) {
dst->vtxbuf[i].buffer_offset = src->vtxbuf[i].buffer_offset;
dst->vtxstride[i] = src->vtxstride[i];
}
dst->stream_freq[i] = src->stream_freq[i];
}
/* if (apply) {
* dst->changed.vtxbuf = (1ULL << MaxStreams) - 1;
* dst->changed.stream_freq = (1ULL << MaxStreams) - 1;
* }*/
}
/* Textures */
if (1) {
for (i = 0; i < NINE_MAX_SAMPLERS; i++)
NineStateBlock9_BindTexture(device, apply, &dst->texture[i], src->texture[i]);
}
/* 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. */
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]));
memcpy(dst->ff.active_light, src->ff.active_light, sizeof(src->ff.active_light) );
dst->ff.num_lights_active = src->ff.num_lights_active;
}
/* Transforms. */
if (1) {
/* Increase dst size if required (to copy the new states).
* Increase src size if required (to initialize missing transforms).
*/
if (dst->ff.num_transforms != src->ff.num_transforms) {
int num_transforms = MAX2(src->ff.num_transforms, dst->ff.num_transforms);
nine_state_resize_transform(&src->ff, num_transforms);
nine_state_resize_transform(&dst->ff, num_transforms);
}
memcpy(dst->ff.transform,
src->ff.transform, dst->ff.num_transforms * sizeof(D3DMATRIX));
/* Apply is always used on device state.
* src is then the D3DSBT_ALL stateblock which
* ff.changed.transform indicates all matrices are dirty.
*
* if (apply)
* 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 NINE_WINAPI
NineStateBlock9_Capture( struct NineStateBlock9 *This )
{
struct NineDevice9 *device = This->base.device;
struct nine_state *dst = &This->state;
struct nine_state *src = &device->state;
const int MaxStreams = device->caps.MaxStreams;
DBG("This=%p\n", This);
if (This->type == NINESBT_ALL)
nine_state_copy_common_all(device, dst, src, dst, false, NULL, MaxStreams);
else
nine_state_copy_common(device, dst, src, dst, false, NULL);
if (dst->changed.group & NINE_STATE_VDECL)
nine_bind(&dst->vdecl, src->vdecl);
return D3D_OK;
}
/* Set state managed by this StateBlock as current device state. */
HRESULT NINE_WINAPI
NineStateBlock9_Apply( struct NineStateBlock9 *This )
{
struct NineDevice9 *device = This->base.device;
struct nine_state *dst = &device->state;
struct nine_state *src = &This->state;
struct nine_range_pool *pool = &device->range_pool;
const int MaxStreams = device->caps.MaxStreams;
DBG("This=%p\n", This);
if (This->type == NINESBT_ALL)
nine_state_copy_common_all(device, dst, src, src, true, pool, MaxStreams);
else
nine_state_copy_common(device, dst, src, src, true, pool);
nine_context_apply_stateblock(device, src);
if ((src->changed.group & NINE_STATE_VDECL) && src->vdecl)
nine_bind(&dst->vdecl, src->vdecl);
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

@ -1,54 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#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 NINE_WINAPI
NineStateBlock9_Capture( struct NineStateBlock9 *This );
HRESULT NINE_WINAPI
NineStateBlock9_Apply( struct NineStateBlock9 *This );
#endif /* _NINE_STATEBLOCK9_H_ */

View file

@ -1,853 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#include "iunknown.h"
#include "surface9.h"
#include "device9.h"
/* for marking dirty */
#include "basetexture9.h"
#include "texture9.h"
#include "cubetexture9.h"
#include "nine_helpers.h"
#include "nine_pipe.h"
#include "nine_dump.h"
#include "nine_memory_helper.h"
#include "nine_state.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
static void
NineSurface9_CreatePipeSurfaces( struct NineSurface9 *This );
HRESULT
NineSurface9_ctor( struct NineSurface9 *This,
struct NineUnknownParams *pParams,
struct NineUnknown *pContainer,
struct pipe_resource *pResource,
struct nine_allocation *user_buffer,
uint8_t TextureType,
unsigned Level,
unsigned Layer,
D3DSURFACE_DESC *pDesc )
{
HRESULT hr;
bool allocate = !pContainer && pDesc->Format != D3DFMT_NULL;
D3DMULTISAMPLE_TYPE multisample_type;
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;
This->base.base.device = pParams->device; /* Early fill this field in case of failure */
/* Make sure there's a Desc */
assert(pDesc);
assert(allocate || pResource || user_buffer ||
pDesc->Format == D3DFMT_NULL);
assert(!allocate || (!pResource && !user_buffer));
assert(!pResource || !user_buffer);
assert(!user_buffer || pDesc->Pool != D3DPOOL_DEFAULT);
assert(!pResource || pDesc->Pool == D3DPOOL_DEFAULT);
/* Allocation only from create_zs_or_rt_surface with params 0 0 0 */
assert(!allocate || (Level == 0 && Layer == 0 && TextureType == 0));
This->data = user_buffer;
multisample_type = pDesc->MultiSampleType;
/* Map MultiSampleQuality to MultiSampleType */
hr = d3dmultisample_type_check(pParams->device->screen,
pDesc->Format,
&multisample_type,
pDesc->MultiSampleQuality,
NULL);
if (FAILED(hr)) {
return hr;
}
/* TODO: this is (except width and height) duplicate from
* container info (in the pContainer case). Some refactoring is
* needed to avoid duplication */
This->base.info.screen = pParams->device->screen;
This->base.info.target = PIPE_TEXTURE_2D;
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 = multisample_type;
This->base.info.nr_storage_samples = multisample_type;
This->base.info.usage = PIPE_USAGE_DEFAULT;
This->base.info.bind = PIPE_BIND_SAMPLER_VIEW; /* StretchRect */
if (pDesc->Usage & D3DUSAGE_RENDERTARGET) {
This->base.info.bind |= PIPE_BIND_RENDER_TARGET;
} else if (pDesc->Usage & D3DUSAGE_DEPTHSTENCIL) {
if (!depth_stencil_format(pDesc->Format))
return D3DERR_INVALIDCALL;
This->base.info.bind = d3d9_get_pipe_depth_format_bindings(pDesc->Format);
if (TextureType)
This->base.info.bind |= PIPE_BIND_SAMPLER_VIEW;
}
This->base.info.flags = 0;
This->base.info.format = d3d9_to_pipe_format_checked(This->base.info.screen,
pDesc->Format,
This->base.info.target,
This->base.info.nr_samples,
This->base.info.bind,
false,
pDesc->Pool == D3DPOOL_SCRATCH);
if (This->base.info.format == PIPE_FORMAT_NONE && pDesc->Format != D3DFMT_NULL)
return D3DERR_INVALIDCALL;
if (allocate && compressed_format(pDesc->Format)) {
const unsigned w = util_format_get_blockwidth(This->base.info.format);
const unsigned h = util_format_get_blockheight(This->base.info.format);
/* Note: In the !allocate case, the test could fail (lower levels of a texture) */
user_assert(!(pDesc->Width % w) && !(pDesc->Height % h), D3DERR_INVALIDCALL);
}
/* Get true format */
This->format_internal = d3d9_to_pipe_format_checked(This->base.info.screen,
pDesc->Format,
This->base.info.target,
This->base.info.nr_samples,
This->base.info.bind,
false,
true);
if (This->base.info.format != This->format_internal ||
/* DYNAMIC Textures requires same stride as ram buffers.
* The workaround stores a copy in RAM for locks. It eats more virtual space,
* but that is compensated by the use of shmem */
(pParams->device->workarounds.dynamic_texture_workaround &&
pDesc->Pool == D3DPOOL_DEFAULT && pDesc->Usage & D3DUSAGE_DYNAMIC)) {
This->data_internal = nine_allocate(pParams->device->allocator,
nine_format_get_level_alloc_size(This->format_internal,
pDesc->Width,
pDesc->Height,
0));
if (!This->data_internal)
return E_OUTOFMEMORY;
This->stride_internal = nine_format_get_stride(This->format_internal,
pDesc->Width);
}
if ((allocate && pDesc->Pool != D3DPOOL_DEFAULT) || pDesc->Format == D3DFMT_NULL) {
/* Ram buffer with no parent. Has to allocate the resource itself */
assert(!user_buffer);
This->data = nine_allocate(pParams->device->allocator,
nine_format_get_level_alloc_size(This->base.info.format,
pDesc->Width,
pDesc->Height,
0));
if (!This->data)
return E_OUTOFMEMORY;
}
hr = NineResource9_ctor(&This->base, pParams, pResource,
allocate && (pDesc->Pool == D3DPOOL_DEFAULT),
D3DRTYPE_SURFACE, pDesc->Pool, pDesc->Usage);
if (FAILED(hr))
return hr;
This->transfer = NULL;
This->texture = TextureType;
This->level = Level;
This->level_actual = Level;
This->layer = Layer;
This->desc = *pDesc;
This->stride = nine_format_get_stride(This->base.info.format, pDesc->Width);
if (This->base.resource && (pDesc->Usage & D3DUSAGE_DYNAMIC))
This->base.resource->flags |= NINE_RESOURCE_FLAG_LOCKABLE;
if (This->base.resource && (pDesc->Usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)))
NineSurface9_CreatePipeSurfaces(This);
/* TODO: investigate what else exactly needs to be cleared */
if (This->base.resource && (pDesc->Usage & D3DUSAGE_RENDERTARGET))
nine_context_clear_render_target(pParams->device, This, 0, 0, 0, pDesc->Width, pDesc->Height);
NineSurface9_Dump(This);
return D3D_OK;
}
void
NineSurface9_dtor( struct NineSurface9 *This )
{
bool is_worker = nine_context_is_worker(This->base.base.device);
DBG("This=%p\n", This);
if (This->transfer) {
struct pipe_context *pipe = nine_context_get_pipe_multithread(This->base.base.device);
pipe->texture_unmap(pipe, This->transfer);
This->transfer = NULL;
}
/* Note: Following condition cannot happen currently, since we
* refcount the surface in the functions increasing
* pending_uploads_counter. */
if (p_atomic_read(&This->pending_uploads_counter))
nine_csmt_process(This->base.base.device);
if (!is_worker && This->lock_count && (This->data_internal || This->data)) {
/* For is_worker nine_free_worker will handle it */
nine_pointer_strongrelease(This->base.base.device->allocator,
This->data_internal ? This->data_internal : This->data);
}
/* Release system memory when we have to manage it (no parent) */
if (This->data) {
if (is_worker)
nine_free_worker(This->base.base.device->allocator, This->data);
else
nine_free(This->base.base.device->allocator, This->data);
}
if (This->data_internal) {
if (is_worker)
nine_free_worker(This->base.base.device->allocator, This->data_internal);
else
nine_free(This->base.base.device->allocator, This->data_internal);
}
NineResource9_dtor(&This->base);
}
static void
NineSurface9_CreatePipeSurfaces( struct NineSurface9 *This )
{
struct pipe_screen *screen = NineDevice9_GetScreen(This->base.base.device);
struct pipe_resource *resource = This->base.resource;
struct pipe_surface templ;
enum pipe_format srgb_format;
assert(This->desc.Pool == D3DPOOL_DEFAULT);
assert(resource);
srgb_format = util_format_srgb(resource->format);
if (srgb_format == PIPE_FORMAT_NONE ||
!screen->is_format_supported(screen, srgb_format,
resource->target, 0, 0, resource->bind))
srgb_format = resource->format;
u_surface_default_template(&templ, resource);
templ.u.tex.level = This->level;
templ.u.tex.first_layer = This->layer;
templ.u.tex.last_layer = This->layer;
This->surface[0] = templ;
templ.format = srgb_format;
This->surface[1] = templ;
}
#if MESA_DEBUG || !defined(NDEBUG)
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->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 /* MESA_DEBUG || !NDEBUG */
HRESULT NINE_WINAPI
NineSurface9_GetContainer( struct NineSurface9 *This,
REFIID riid,
void **ppContainer )
{
HRESULT hr;
char guid_str[64];
DBG("This=%p riid=%p id=%s ppContainer=%p\n",
This, riid, riid ? GUID_sprintf(guid_str, riid) : "", ppContainer);
(void)guid_str;
if (!ppContainer) return E_POINTER;
/* Use device for OffscreenPlainSurface, DepthStencilSurface and RenderTarget */
hr = NineUnknown_QueryInterface(NineUnknown(This)->container ?
NineUnknown(This)->container : &NineUnknown(This)->device->base,
riid, ppContainer);
if (FAILED(hr))
DBG("QueryInterface FAILED!\n");
return hr;
}
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->managed.dirty = true;
else
if (This->base.usage & D3DUSAGE_AUTOGENMIPMAP)
tex->dirty_mip = true;
BASETEX_REGISTER_UPDATE(tex);
}
}
HRESULT NINE_WINAPI
NineSurface9_GetDesc( struct NineSurface9 *This,
D3DSURFACE_DESC *pDesc )
{
user_assert(pDesc != NULL, E_POINTER);
DBG("This=%p pDesc=%p\n", This, pDesc);
*pDesc = This->desc;
return D3D_OK;
}
/* Add the dirty rects to the source texture */
inline void
NineSurface9_AddDirtyRect( struct NineSurface9 *This,
const struct pipe_box *box )
{
RECT dirty_rect;
DBG("This=%p box=%p\n", This, box);
assert (This->base.pool != D3DPOOL_MANAGED ||
This->texture == D3DRTYPE_CUBETEXTURE ||
This->texture == D3DRTYPE_TEXTURE);
if (This->base.pool == D3DPOOL_DEFAULT)
return;
/* Add a dirty rect to level 0 of the parent texture */
dirty_rect.left = box->x << This->level_actual;
dirty_rect.right = dirty_rect.left + (box->width << This->level_actual);
dirty_rect.top = box->y << This->level_actual;
dirty_rect.bottom = dirty_rect.top + (box->height << This->level_actual);
if (This->texture == D3DRTYPE_TEXTURE) {
struct NineTexture9 *tex =
NineTexture9(This->base.base.container);
NineTexture9_AddDirtyRect(tex, &dirty_rect);
} else if (This->texture == D3DRTYPE_CUBETEXTURE) {
struct NineCubeTexture9 *ctex =
NineCubeTexture9(This->base.base.container);
NineCubeTexture9_AddDirtyRect(ctex, This->layer, &dirty_rect);
}
}
static inline unsigned
NineSurface9_GetSystemMemOffset(enum pipe_format format, unsigned stride,
int x, int y)
{
unsigned x_offset = util_format_get_stride(format, x);
y = util_format_get_nblocksy(format, y);
return y * stride + x_offset;
}
HRESULT NINE_WINAPI
NineSurface9_LockRect( struct NineSurface9 *This,
D3DLOCKED_RECT *pLockedRect,
const RECT *pRect,
DWORD Flags )
{
struct pipe_resource *resource = This->base.resource;
struct pipe_context *pipe;
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);
/* check if it's already locked */
user_assert(This->lock_count == 0, D3DERR_INVALIDCALL);
/* set pBits to NULL after lock_count check */
user_assert(pLockedRect, E_POINTER);
pLockedRect->pBits = NULL;
#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) && (Flags & D3DLOCK_READONLY)),
D3DERR_INVALIDCALL);
user_assert(This->desc.MultiSampleType == D3DMULTISAMPLE_NONE,
D3DERR_INVALIDCALL);
if (pRect && This->desc.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 == 0 && pRect->right == This->desc.Width &&
pRect->top == 0 && pRect->bottom == This->desc.Height) ||
(!(pRect->left % w) && !(pRect->right % w) &&
!(pRect->top % h) && !(pRect->bottom % h)),
D3DERR_INVALIDCALL);
}
if (Flags & D3DLOCK_DISCARD) {
usage = PIPE_MAP_WRITE | PIPE_MAP_DISCARD_RANGE;
} else {
usage = (Flags & D3DLOCK_READONLY) ?
PIPE_MAP_READ : PIPE_MAP_READ_WRITE;
}
if (Flags & D3DLOCK_DONOTWAIT)
usage |= PIPE_MAP_DONTBLOCK;
if (pRect) {
/* Windows XP accepts invalid locking rectangles, Windows 7 rejects
* them. Use Windows XP behaviour for now. */
rect_to_pipe_box(&box, pRect);
} else {
u_box_origin_2d(This->desc.Width, This->desc.Height, &box);
}
box.z = This->layer;
user_warn(This->desc.Format == D3DFMT_NULL);
if (p_atomic_read(&This->pending_uploads_counter))
nine_csmt_process(This->base.base.device);
if (This->data_internal || This->data) {
enum pipe_format format = This->base.info.format;
unsigned stride = This->stride;
uint8_t *data = nine_get_pointer(This->base.base.device->allocator, This->data_internal ? This->data_internal : This->data);
if (This->data_internal) {
format = This->format_internal;
stride = This->stride_internal;
}
/* ATI1 and ATI2 need special handling, because of d3d9 bug.
* We must advertise to the application as if it is uncompressed
* and bpp 8, and the app has a workaround to work with the fact
* that it is actually compressed. */
if (is_ATI1_ATI2(format)) {
pLockedRect->Pitch = This->desc.Width;
pLockedRect->pBits = data + box.y * This->desc.Width + box.x;
} else {
pLockedRect->Pitch = stride;
pLockedRect->pBits = data +
NineSurface9_GetSystemMemOffset(format,
stride,
box.x,
box.y);
}
DBG("returning system memory %p\n", pLockedRect->pBits);
} else {
bool no_refs = !p_atomic_read(&This->base.base.bind) &&
!(This->base.base.container && p_atomic_read(&This->base.base.container->bind));
DBG("mapping pipe_resource %p (level=%u usage=%x)\n",
resource, This->level, usage);
/* if the object is not bound internally, there can't be any pending
* operation with the surface in the queue */
if (no_refs)
pipe = nine_context_get_pipe_acquire(This->base.base.device);
else
pipe = NineDevice9_GetPipe(This->base.base.device);
pLockedRect->pBits = pipe->texture_map(pipe, resource,
This->level, usage, &box,
&This->transfer);
if (no_refs)
nine_context_get_pipe_release(This->base.base.device);
if (!This->transfer) {
DBG("texture_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);
NineSurface9_AddDirtyRect(This, &box);
}
++This->lock_count;
return D3D_OK;
}
HRESULT NINE_WINAPI
NineSurface9_UnlockRect( struct NineSurface9 *This )
{
struct pipe_box dst_box, src_box;
struct pipe_context *pipe;
DBG("This=%p lock_count=%u\n", This, This->lock_count);
user_assert(This->lock_count, D3DERR_INVALIDCALL);
if (This->transfer) {
pipe = nine_context_get_pipe_acquire(This->base.base.device);
pipe->texture_unmap(pipe, This->transfer);
nine_context_get_pipe_release(This->base.base.device);
This->transfer = NULL;
}
--This->lock_count;
if (This->data_internal) {
nine_pointer_weakrelease(This->base.base.device->allocator, This->data_internal);
if (This->data) {
(void) util_format_translate(This->base.info.format,
nine_get_pointer(This->base.base.device->allocator, This->data),
This->stride,
0, 0,
This->format_internal,
nine_get_pointer(This->base.base.device->allocator, This->data_internal),
This->stride_internal,
0, 0,
This->desc.Width, This->desc.Height);
nine_pointer_weakrelease(This->base.base.device->allocator, This->data);
nine_pointer_strongrelease(This->base.base.device->allocator, This->data_internal);
} else {
u_box_2d_zslice(0, 0, This->layer,
This->desc.Width, This->desc.Height, &dst_box);
u_box_2d_zslice(0, 0, 0,
This->desc.Width, This->desc.Height, &src_box);
nine_context_box_upload(This->base.base.device,
&This->pending_uploads_counter,
(struct NineUnknown *)This,
This->base.resource,
This->level,
&dst_box,
This->format_internal,
nine_get_pointer(This->base.base.device->allocator, This->data_internal),
This->stride_internal,
0, /* depth = 1 */
&src_box);
nine_pointer_delayedstrongrelease(This->base.base.device->allocator, This->data_internal, &This->pending_uploads_counter);
}
} else if (This->data) {
nine_pointer_weakrelease(This->base.base.device->allocator, This->data);
}
return D3D_OK;
}
HRESULT NINE_WINAPI
NineSurface9_GetDC( struct NineSurface9 *This,
HDC *phdc )
{
STUB(D3DERR_INVALIDCALL);
}
HRESULT NINE_WINAPI
NineSurface9_ReleaseDC( struct NineSurface9 *This,
HDC hdc )
{
STUB(D3DERR_INVALIDCALL);
}
IDirect3DSurface9Vtbl NineSurface9_vtable = {
(void *)NineUnknown_QueryInterface,
(void *)NineUnknown_AddRef,
(void *)NineUnknown_Release,
(void *)NineUnknown_GetDevice, /* actually part of Resource9 iface */
(void *)NineUnknown_SetPrivateData,
(void *)NineUnknown_GetPrivateData,
(void *)NineUnknown_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
};
/* When this function is called, we have already checked
* The copy regions fit the surfaces */
void
NineSurface9_CopyMemToDefault( struct NineSurface9 *This,
struct NineSurface9 *From,
const POINT *pDestPoint,
const RECT *pSourceRect )
{
struct pipe_resource *r_dst = This->base.resource;
struct pipe_box dst_box, src_box;
int src_x, src_y, dst_x, dst_y, copy_width, copy_height;
assert(This->base.pool == D3DPOOL_DEFAULT &&
From->base.pool == D3DPOOL_SYSTEMMEM);
if (pDestPoint) {
dst_x = pDestPoint->x;
dst_y = pDestPoint->y;
} else {
dst_x = 0;
dst_y = 0;
}
if (pSourceRect) {
src_x = pSourceRect->left;
src_y = pSourceRect->top;
copy_width = pSourceRect->right - pSourceRect->left;
copy_height = pSourceRect->bottom - pSourceRect->top;
} else {
src_x = 0;
src_y = 0;
copy_width = From->desc.Width;
copy_height = From->desc.Height;
}
u_box_2d_zslice(dst_x, dst_y, This->layer,
copy_width, copy_height, &dst_box);
u_box_2d_zslice(src_x, src_y, 0,
copy_width, copy_height, &src_box);
if (This->data_internal) {
(void) util_format_translate(This->format_internal,
nine_get_pointer(This->base.base.device->allocator, This->data_internal),
This->stride_internal,
dst_x, dst_y,
From->base.info.format,
nine_get_pointer(This->base.base.device->allocator, From->data),
From->stride,
src_x, src_y,
copy_width, copy_height);
nine_pointer_weakrelease(This->base.base.device->allocator, From->data);
nine_pointer_strongrelease(This->base.base.device->allocator, This->data_internal);
}
nine_context_box_upload(This->base.base.device,
&From->pending_uploads_counter,
(struct NineUnknown *)From,
r_dst,
This->level,
&dst_box,
From->base.info.format,
nine_get_pointer(This->base.base.device->allocator, From->data),
From->stride,
0, /* depth = 1 */
&src_box);
nine_pointer_delayedstrongrelease(This->base.base.device->allocator, From->data, &From->pending_uploads_counter);
if (From->texture == D3DRTYPE_TEXTURE) {
struct NineTexture9 *tex =
NineTexture9(From->base.base.container);
/* D3DPOOL_SYSTEMMEM with buffer content passed
* from the user: execute the upload right now.
* It is possible it is enough to delay upload
* until the surface refcount is 0, but the
* bind refcount may not be 0, and thus the dtor
* is not executed (and doesn't trigger the
* pending_uploads_counter check). */
if (!tex->managed_buffer)
nine_csmt_process(This->base.base.device);
}
NineSurface9_MarkContainerDirty(This);
}
void
NineSurface9_CopyDefaultToMem( struct NineSurface9 *This,
struct NineSurface9 *From )
{
struct pipe_context *pipe;
struct pipe_resource *r_src = From->base.resource;
struct pipe_transfer *transfer;
struct pipe_box src_box;
uint8_t *p_dst;
const uint8_t *p_src;
assert(This->base.pool == D3DPOOL_SYSTEMMEM &&
From->base.pool == D3DPOOL_DEFAULT);
assert(This->desc.Width == From->desc.Width);
assert(This->desc.Height == From->desc.Height);
u_box_origin_2d(This->desc.Width, This->desc.Height, &src_box);
src_box.z = From->layer;
if (p_atomic_read(&This->pending_uploads_counter))
nine_csmt_process(This->base.base.device);
pipe = NineDevice9_GetPipe(This->base.base.device);
p_src = pipe->texture_map(pipe, r_src, From->level,
PIPE_MAP_READ,
&src_box, &transfer);
p_dst = nine_get_pointer(This->base.base.device->allocator, This->data);
assert (p_src && p_dst);
util_copy_rect(p_dst, This->base.info.format,
This->stride, 0, 0,
This->desc.Width, This->desc.Height,
p_src,
transfer->stride, 0, 0);
pipe->texture_unmap(pipe, transfer);
nine_pointer_weakrelease(This->base.base.device->allocator, This->data);
}
/* 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,
const struct pipe_box *damaged )
{
struct pipe_resource *res = This->base.resource;
struct pipe_box box;
DBG("This=%p damaged=%p\n", This, damaged);
assert(This->base.pool == D3DPOOL_MANAGED);
if (damaged) {
box = *damaged;
box.z = This->layer;
box.depth = 1;
} else {
box.x = 0;
box.y = 0;
box.z = This->layer;
box.width = This->desc.Width;
box.height = This->desc.Height;
box.depth = 1;
}
nine_context_box_upload(This->base.base.device,
&This->pending_uploads_counter,
(struct NineUnknown *)This,
res,
This->level,
&box,
res->format,
nine_get_pointer(This->base.base.device->allocator, This->data),
This->stride,
0, /* depth = 1 */
&box);
nine_pointer_delayedstrongrelease(This->base.base.device->allocator, This->data, &This->pending_uploads_counter);
return D3D_OK;
}
/* Currently nine_context uses the NineSurface9
* fields when it is render target. Any modification requires
* pending commands with the surface to be executed. If the bind
* count is 0, there is no pending commands. */
#define PROCESS_IF_BOUND(surf) \
if (surf->base.base.bind) \
nine_csmt_process(surf->base.base.device);
void
NineSurface9_SetResource( struct NineSurface9 *This,
struct pipe_resource *resource, unsigned level )
{
/* No need to call PROCESS_IF_BOUND, because SetResource is used only
* for MANAGED textures, and they are not render targets. */
assert(This->base.pool == D3DPOOL_MANAGED);
This->level = level;
pipe_resource_reference(&This->base.resource, resource);
}
void
NineSurface9_SetMultiSampleType( struct NineSurface9 *This,
D3DMULTISAMPLE_TYPE mst )
{
PROCESS_IF_BOUND(This);
This->desc.MultiSampleType = mst;
}
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);
PROCESS_IF_BOUND(This);
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->base.info.nr_samples = resource->nr_samples;
This->base.info.nr_storage_samples = resource->nr_storage_samples;
This->stride = nine_format_get_stride(This->base.info.format,
This->desc.Width);
NineSurface9_CreatePipeSurfaces(This);
}
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,
struct nine_allocation *user_buffer,
uint8_t TextureType,
unsigned Level,
unsigned Layer,
D3DSURFACE_DESC *pDesc,
struct NineSurface9 **ppOut )
{
NINE_DEVICE_CHILD_NEW(Surface9, ppOut, pDevice, /* args */
pContainer, pResource, user_buffer,
TextureType, Level, Layer, pDesc);
}

View file

@ -1,161 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_SURFACE9_H_
#define _NINE_SURFACE9_H_
#include "nine_memory_helper.h"
#include "resource9.h"
#include "pipe/p_state.h"
#include "util/list.h"
#include "util/u_rect.h"
#include "util/u_inlines.h"
struct NineSurface9
{
struct NineResource9 base;
/* G3D state */
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;
struct nine_allocation *data; /* system memory backing */
struct nine_allocation *data_internal; /* for conversions */
enum pipe_format format_internal;
unsigned stride; /* for system memory backing */
unsigned stride_internal;
unsigned pending_uploads_counter; /* pending uploads */
};
static inline struct NineSurface9 *
NineSurface9( void *data )
{
return (struct NineSurface9 *)data;
}
HRESULT
NineSurface9_new( struct NineDevice9 *pDevice,
struct NineUnknown *pContainer,
struct pipe_resource *pResource,
struct nine_allocation *user_buffer,
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,
struct nine_allocation *user_buffer,
uint8_t TextureType,
unsigned Level,
unsigned Layer,
D3DSURFACE_DESC *pDesc );
void
NineSurface9_dtor( struct NineSurface9 *This );
/*** Nine private ***/
void
NineSurface9_MarkContainerDirty( struct NineSurface9 *This );
static inline struct pipe_surface *
NineSurface9_GetSurface( struct NineSurface9 *This, int sRGB )
{
return &This->surface[sRGB];
}
static inline struct pipe_resource *
NineSurface9_GetResource( struct NineSurface9 *This )
{
return This->base.resource;
}
void
NineSurface9_SetResource( struct NineSurface9 *This,
struct pipe_resource *resource, unsigned level );
void
NineSurface9_SetMultiSampleType( struct NineSurface9 *This,
D3DMULTISAMPLE_TYPE mst );
void
NineSurface9_SetResourceResize( struct NineSurface9 *This,
struct pipe_resource *resource );
void
NineSurface9_AddDirtyRect( struct NineSurface9 *This,
const struct pipe_box *box );
HRESULT
NineSurface9_UploadSelf( struct NineSurface9 *This,
const struct pipe_box *damaged );
void
NineSurface9_CopyMemToDefault( struct NineSurface9 *This,
struct NineSurface9 *From,
const POINT *pDestPoint,
const RECT *pSourceRect );
void
NineSurface9_CopyDefaultToMem( struct NineSurface9 *This,
struct NineSurface9 *From );
static inline bool
NineSurface9_IsOffscreenPlain (struct NineSurface9 *This )
{
return This->base.usage == 0 && !This->texture;
}
#if MESA_DEBUG || !defined(NDEBUG)
void
NineSurface9_Dump( struct NineSurface9 *This );
#else
static inline void
NineSurface9_Dump( struct NineSurface9 *This ) { }
#endif
/*** Direct3D public ***/
HRESULT NINE_WINAPI
NineSurface9_GetContainer( struct NineSurface9 *This,
REFIID riid,
void **ppContainer );
HRESULT NINE_WINAPI
NineSurface9_GetDesc( struct NineSurface9 *This,
D3DSURFACE_DESC *pDesc );
HRESULT NINE_WINAPI
NineSurface9_LockRect( struct NineSurface9 *This,
D3DLOCKED_RECT *pLockedRect,
const RECT *pRect,
DWORD Flags );
HRESULT NINE_WINAPI
NineSurface9_UnlockRect( struct NineSurface9 *This );
HRESULT NINE_WINAPI
NineSurface9_GetDC( struct NineSurface9 *This,
HDC *phdc );
HRESULT NINE_WINAPI
NineSurface9_ReleaseDC( struct NineSurface9 *This,
HDC hdc );
#endif /* _NINE_SURFACE9_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,141 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_SWAPCHAIN9_H_
#define _NINE_SWAPCHAIN9_H_
#include "iunknown.h"
#include "adapter9.h"
#include "d3dadapter/d3dadapter9.h"
#include "threadpool.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;
/* presentation backend */
ID3DPresent *present;
D3DPRESENT_PARAMETERS params;
D3DDISPLAYMODEEX *mode;
struct d3dadapter9_context *actx;
BOOL implicit;
unsigned num_back_buffers;
/* buffer handles */
struct NineSurface9 *buffers[D3DPRESENT_BACK_BUFFERS_MAX_EX + 1]; /* 0 to BackBufferCount-1 : the back buffers. BackBufferCount : additional buffer */
struct pipe_resource *present_buffers[D3DPRESENT_BACK_BUFFERS_MAX_EX + 1];
D3DWindowBuffer *present_handles[D3DPRESENT_BACK_BUFFERS_MAX_EX + 1];
D3DWindowBuffer *present_handles_pending_release[D3DPRESENT_BACK_BUFFERS_MAX_EX + 1];
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;
struct threadpool *pool;
struct threadpool_task *tasks[D3DPRESENT_BACK_BUFFERS_MAX_EX + 1];
BOOL *pending_presentation[D3DPRESENT_BACK_BUFFERS_MAX_EX + 1];
BOOL enable_threadpool;
};
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 NINE_WINAPI
NineSwapChain9_Present( struct NineSwapChain9 *This,
const RECT *pSourceRect,
const RECT *pDestRect,
HWND hDestWindowOverride,
const RGNDATA *pDirtyRegion,
DWORD dwFlags );
HRESULT NINE_WINAPI
NineSwapChain9_GetFrontBufferData( struct NineSwapChain9 *This,
IDirect3DSurface9 *pDestSurface );
HRESULT NINE_WINAPI
NineSwapChain9_GetBackBuffer( struct NineSwapChain9 *This,
UINT iBackBuffer,
D3DBACKBUFFER_TYPE Type,
IDirect3DSurface9 **ppBackBuffer );
HRESULT NINE_WINAPI
NineSwapChain9_GetRasterStatus( struct NineSwapChain9 *This,
D3DRASTER_STATUS *pRasterStatus );
HRESULT NINE_WINAPI
NineSwapChain9_GetDisplayMode( struct NineSwapChain9 *This,
D3DDISPLAYMODE *pMode );
HRESULT NINE_WINAPI
NineSwapChain9_GetPresentParameters( struct NineSwapChain9 *This,
D3DPRESENT_PARAMETERS *pPresentationParameters );
BOOL
NineSwapChain9_GetOccluded( struct NineSwapChain9 *This );
BOOL
NineSwapChain9_ResolutionMismatch( struct NineSwapChain9 *This );
HANDLE
NineSwapChain9_CreateThread( struct NineSwapChain9 *This,
void *pFuncAddress,
void *pParam );
void
NineSwapChain9_WaitForThread( struct NineSwapChain9 *This,
HANDLE thread );
#endif /* _NINE_SWAPCHAIN9_H_ */

View file

@ -1,100 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#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 )
{
DBG("This=%p pParams=%p implicit=%d pPresent=%p pPresentationParameters=%p "
"pCTX=%p hFocusWindow=%p mode=%p",
This, pParams, (int) implicit, pPresent, pPresentationParameters, pCTX, hFocusWindow, 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 NINE_WINAPI
NineSwapChain9Ex_GetLastPresentCount( struct NineSwapChain9Ex *This,
UINT *pLastPresentCount )
{
STUB(D3DERR_INVALIDCALL);
}
HRESULT NINE_WINAPI
NineSwapChain9Ex_GetPresentStats( struct NineSwapChain9Ex *This,
D3DPRESENTSTATS *pPresentationStatistics )
{
STUB(D3DERR_INVALIDCALL);
}
HRESULT NINE_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

@ -1,44 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#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 NINE_WINAPI
NineSwapChain9Ex_GetLastPresentCount( struct NineSwapChain9Ex *This,
UINT *pLastPresentCount );
HRESULT NINE_WINAPI
NineSwapChain9Ex_GetPresentStats( struct NineSwapChain9Ex *This,
D3DPRESENTSTATS *pPresentationStatistics );
HRESULT NINE_WINAPI
NineSwapChain9Ex_GetDisplayModeEx( struct NineSwapChain9Ex *This,
D3DDISPLAYMODEEX *pMode,
D3DDISPLAYROTATION *pRotation );
#endif /* _NINE_SWAPCHAIN9EX_H_ */

View file

@ -1,375 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#include "c99_alloca.h"
#include "device9.h"
#include "surface9.h"
#include "texture9.h"
#include "nine_helpers.h"
#include "nine_memory_helper.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;
enum pipe_format pf;
unsigned *level_offsets = NULL;
unsigned l;
D3DSURFACE_DESC sfdesc;
HRESULT hr;
struct nine_allocation *user_buffer = NULL, *user_buffer_for_level;
This->base.base.base.device = pParams->device; /* Early fill this field in case of failure */
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(Width && Height, D3DERR_INVALIDCALL);
/* pSharedHandle: can be non-null for ex only.
* D3DPOOL_SYSTEMMEM: Levels must be 1
* D3DPOOL_DEFAULT: no restriction for Levels
* Other Pools are forbidden. */
user_assert(!pSharedHandle || pParams->device->ex, D3DERR_INVALIDCALL);
user_assert(!pSharedHandle ||
(Pool == D3DPOOL_SYSTEMMEM && Levels == 1) ||
Pool == D3DPOOL_DEFAULT, D3DERR_INVALIDCALL);
user_assert(!(Usage & D3DUSAGE_AUTOGENMIPMAP) ||
(Pool != D3DPOOL_SYSTEMMEM && Pool != D3DPOOL_SCRATCH && Levels <= 1),
D3DERR_INVALIDCALL);
/* TODO: implement pSharedHandle for D3DPOOL_DEFAULT (cross process
* buffer sharing).
*
* 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.
*/
if (pSharedHandle && Pool == D3DPOOL_DEFAULT) {
if (!*pSharedHandle) {
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;
pf = d3d9_to_pipe_format_checked(screen, Format, PIPE_TEXTURE_2D, 0,
PIPE_BIND_SAMPLER_VIEW, false,
Pool == D3DPOOL_SCRATCH);
if (Format != D3DFMT_NULL && pf == PIPE_FORMAT_NONE)
return D3DERR_INVALIDCALL;
if (compressed_format(Format)) {
const unsigned w = util_format_get_blockwidth(pf);
const unsigned h = util_format_get_blockheight(pf);
user_assert(!(Width % w) && !(Height % h), D3DERR_INVALIDCALL);
}
info->screen = screen;
info->target = PIPE_TEXTURE_2D;
info->format = pf;
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->nr_storage_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;
}
if (Usage & D3DUSAGE_SOFTWAREPROCESSING)
DBG("Application asked for Software Vertex Processing, "
"but this is unimplemented\n");
hr = NineBaseTexture9_ctor(&This->base, pParams, NULL, D3DRTYPE_TEXTURE, Format, Pool, Usage);
if (FAILED(hr))
return hr;
This->base.pstype = (Height == 1) ? 1 : 0;
if (pSharedHandle && *pSharedHandle) { /* Pool == D3DPOOL_SYSTEMMEM */
user_buffer = nine_wrap_external_pointer(pParams->device->allocator, (void *)*pSharedHandle);
level_offsets = alloca(sizeof(unsigned) * This->base.level_count);
(void) nine_format_get_size_and_offsets(pf, level_offsets,
Width, Height,
This->base.level_count-1);
} else if (Pool != D3DPOOL_DEFAULT) {
level_offsets = alloca(sizeof(unsigned) * This->base.level_count);
user_buffer = nine_allocate(pParams->device->allocator,
nine_format_get_size_and_offsets(pf, level_offsets,
Width, Height,
This->base.level_count-1));
This->managed_buffer = user_buffer;
if (!This->managed_buffer)
return E_OUTOFMEMORY;
}
This->surfaces = CALLOC(This->base.level_count, sizeof(*This->surfaces));
if (!This->surfaces)
return E_OUTOFMEMORY;
/* 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 < This->base.level_count; ++l) {
sfdesc.Width = u_minify(Width, l);
sfdesc.Height = u_minify(Height, l);
/* Some apps expect the memory to be allocated in
* continuous blocks */
user_buffer_for_level = user_buffer ?
nine_suballocate(pParams->device->allocator, user_buffer, level_offsets[l]) : NULL;
hr = NineSurface9_new(This->base.base.base.device, NineUnknown(This),
This->base.base.resource, user_buffer_for_level,
D3DRTYPE_TEXTURE, l, 0,
&sfdesc, &This->surfaces[l]);
if (FAILED(hr))
return hr;
}
/* Textures start initially dirty */
This->dirty_rect.width = Width;
This->dirty_rect.height = Height;
This->dirty_rect.depth = 1; /* width == 0 means empty, depth stays 1 */
if (pSharedHandle && !*pSharedHandle) {/* Pool == D3DPOOL_SYSTEMMEM */
*pSharedHandle = This->surfaces[0]->data;
}
return D3D_OK;
}
static void
NineTexture9_dtor( struct NineTexture9 *This )
{
bool is_worker = nine_context_is_worker(This->base.base.base.device);
unsigned l;
DBG("This=%p\n", This);
if (This->surfaces) {
/* The surfaces should have 0 references and be unbound now. */
for (l = 0; l < This->base.level_count; ++l)
if (This->surfaces[l])
NineUnknown_Destroy(&This->surfaces[l]->base.base);
FREE(This->surfaces);
}
if (This->managed_buffer) {
if (is_worker)
nine_free_worker(This->base.base.base.device->allocator, This->managed_buffer);
else
nine_free(This->base.base.base.device->allocator, This->managed_buffer);
}
NineBaseTexture9_dtor(&This->base);
}
HRESULT NINE_WINAPI
NineTexture9_GetLevelDesc( struct NineTexture9 *This,
UINT Level,
D3DSURFACE_DESC *pDesc )
{
DBG("This=%p Level=%d pDesc=%p\n", This, Level, pDesc);
user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
user_assert(pDesc, D3DERR_INVALIDCALL);
*pDesc = This->surfaces[Level]->desc;
return D3D_OK;
}
HRESULT NINE_WINAPI
NineTexture9_GetSurfaceLevel( struct NineTexture9 *This,
UINT Level,
IDirect3DSurface9 **ppSurfaceLevel )
{
DBG("This=%p Level=%d ppSurfaceLevel=%p\n", This, Level, ppSurfaceLevel);
user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
user_assert(ppSurfaceLevel, D3DERR_INVALIDCALL);
NineUnknown_AddRef(NineUnknown(This->surfaces[Level]));
*ppSurfaceLevel = (IDirect3DSurface9 *)This->surfaces[Level];
return D3D_OK;
}
HRESULT NINE_WINAPI
NineTexture9_LockRect( struct NineTexture9 *This,
UINT Level,
D3DLOCKED_RECT *pLockedRect,
const RECT *pRect,
DWORD Flags )
{
DBG("This=%p Level=%u pLockedRect=%p pRect=%p Flags=%d\n",
This, Level, pLockedRect, pRect, Flags);
user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
return NineSurface9_LockRect(This->surfaces[Level], pLockedRect,
pRect, Flags);
}
HRESULT NINE_WINAPI
NineTexture9_UnlockRect( struct NineTexture9 *This,
UINT Level )
{
DBG("This=%p Level=%u\n", This, Level);
user_assert(Level < This->base.level_count, D3DERR_INVALIDCALL);
return NineSurface9_UnlockRect(This->surfaces[Level]);
}
HRESULT NINE_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 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_DEFAULT) {
if (This->base.base.usage & D3DUSAGE_AUTOGENMIPMAP) {
This->base.dirty_mip = true;
BASETEX_REGISTER_UPDATE(&This->base);
}
return D3D_OK;
}
if (This->base.base.pool == D3DPOOL_MANAGED) {
This->base.managed.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 {
if (This->dirty_rect.width == 0) {
rect_to_pipe_box_clamp(&This->dirty_rect, pDirtyRect);
} else {
struct pipe_box box;
rect_to_pipe_box_clamp(&box, pDirtyRect);
u_box_union_2d(&This->dirty_rect, &This->dirty_rect, &box);
}
(void) u_box_clip_2d(&This->dirty_rect, &This->dirty_rect,
This->base.base.info.width0,
This->base.base.info.height0);
}
return D3D_OK;
}
IDirect3DTexture9Vtbl NineTexture9_vtable = {
(void *)NineUnknown_QueryInterface,
(void *)NineUnknown_AddRef,
(void *)NineUnknown_Release,
(void *)NineUnknown_GetDevice, /* actually part of Resource9 iface */
(void *)NineUnknown_SetPrivateData,
(void *)NineUnknown_GetPrivateData,
(void *)NineUnknown_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

@ -1,60 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_TEXTURE9_H_
#define _NINE_TEXTURE9_H_
#include "basetexture9.h"
#include "nine_memory_helper.h"
#include "surface9.h"
struct NineTexture9
{
struct NineBaseTexture9 base;
struct NineSurface9 **surfaces;
struct pipe_box dirty_rect; /* covers all mip levels */
struct nine_allocation *managed_buffer;
};
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 NINE_WINAPI
NineTexture9_GetLevelDesc( struct NineTexture9 *This,
UINT Level,
D3DSURFACE_DESC *pDesc );
HRESULT NINE_WINAPI
NineTexture9_GetSurfaceLevel( struct NineTexture9 *This,
UINT Level,
IDirect3DSurface9 **ppSurfaceLevel );
HRESULT NINE_WINAPI
NineTexture9_LockRect( struct NineTexture9 *This,
UINT Level,
D3DLOCKED_RECT *pLockedRect,
const RECT *pRect,
DWORD Flags );
HRESULT NINE_WINAPI
NineTexture9_UnlockRect( struct NineTexture9 *This,
UINT Level );
HRESULT NINE_WINAPI
NineTexture9_AddDirtyRect( struct NineTexture9 *This,
const RECT *pDirtyRect );
#endif /* _NINE_TEXTURE9_H_ */

View file

@ -1,182 +0,0 @@
/*
* Copyright © 2012 Intel Corporation
* SPDX-License-Identifier: MIT
*/
#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 "frontend/drm_driver.h"
#include "util/u_thread.h"
#include "threadpool.h"
/* POSIX thread function */
static void *
threadpool_worker(void *data)
{
struct threadpool *pool = data;
pthread_mutex_lock(&pool->m);
while (!pool->shutdown) {
struct threadpool_task *task;
/* Block (dropping the lock) until new work arrives for us. */
while (!pool->workqueue && !pool->shutdown)
pthread_cond_wait(&pool->new_work, &pool->m);
if (pool->shutdown)
break;
/* Pull the first task from the list. We don't free it -- it now lacks
* a reference other than the worker creator's, whose responsibility it
* is to call threadpool_wait_for_work() to free it.
*/
task = pool->workqueue;
pool->workqueue = task->next;
/* Call the task's work func. */
pthread_mutex_unlock(&pool->m);
task->work(task->data);
pthread_mutex_lock(&pool->m);
task->finished = true;
pthread_cond_broadcast(&task->finish);
}
pthread_mutex_unlock(&pool->m);
return NULL;
}
/* Windows thread function */
static DWORD NINE_WINAPI
wthreadpool_worker(void *data)
{
threadpool_worker(data);
return 0;
}
struct threadpool *
_mesa_threadpool_create(struct NineSwapChain9 *swapchain)
{
struct threadpool *pool = calloc(1, sizeof(*pool));
if (!pool)
return NULL;
pthread_mutex_init(&pool->m, NULL);
pthread_cond_init(&pool->new_work, NULL);
/* This uses WINE's CreateThread, so the thread function needs to use
* the Windows ABI */
pool->wthread = NineSwapChain9_CreateThread(swapchain, wthreadpool_worker, pool);
if (!pool->wthread) {
/* using pthread as fallback */
pthread_create(&pool->pthread, NULL, threadpool_worker, pool);
}
return pool;
}
void
_mesa_threadpool_destroy(struct NineSwapChain9 *swapchain, struct threadpool *pool)
{
if (!pool)
return;
pthread_mutex_lock(&pool->m);
pool->shutdown = true;
pthread_cond_broadcast(&pool->new_work);
pthread_mutex_unlock(&pool->m);
if (pool->wthread) {
NineSwapChain9_WaitForThread(swapchain, pool->wthread);
} else {
pthread_join(pool->pthread, NULL);
}
pthread_cond_destroy(&pool->new_work);
pthread_mutex_destroy(&pool->m);
free(pool);
}
/**
* Queues a request for the work function to be asynchronously executed by the
* thread pool.
*
* The work func will get the "data" argument as its parameter -- any
* communication between the caller and the work function will occur through
* that.
*
* If there is an error, the work function is called immediately and NULL is
* returned.
*/
struct threadpool_task *
_mesa_threadpool_queue_task(struct threadpool *pool,
threadpool_task_func work, void *data)
{
struct threadpool_task *task, *previous;
if (!pool) {
work(data);
return NULL;
}
task = calloc(1, sizeof(*task));
if (!task) {
work(data);
return NULL;
}
task->work = work;
task->data = data;
task->next = NULL;
pthread_cond_init(&task->finish, NULL);
pthread_mutex_lock(&pool->m);
if (!pool->workqueue) {
pool->workqueue = task;
} else {
previous = pool->workqueue;
while (previous && previous->next)
previous = previous->next;
previous->next = task;
}
pthread_cond_signal(&pool->new_work);
pthread_mutex_unlock(&pool->m);
return task;
}
/**
* Blocks on the completion of the given task and frees the task.
*/
void
_mesa_threadpool_wait_for_task(struct threadpool *pool,
struct threadpool_task **task_handle)
{
struct threadpool_task *task = *task_handle;
if (!pool || !task)
return;
pthread_mutex_lock(&pool->m);
while (!task->finished)
pthread_cond_wait(&task->finish, &pool->m);
pthread_mutex_unlock(&pool->m);
pthread_cond_destroy(&task->finish);
free(task);
*task_handle = NULL;
}

View file

@ -1,42 +0,0 @@
/*
* Copyright © 2012 Intel Corporation
* SPDX-License-Identifier: MIT
*/
#ifndef _THREADPOOL_H_
#define _THREADPOOL_H_
#include <pthread.h>
struct NineSwapChain9;
#define MAXTHREADS 1
struct threadpool {
pthread_mutex_t m;
pthread_cond_t new_work;
HANDLE wthread;
pthread_t pthread;
struct threadpool_task *workqueue;
BOOL shutdown;
};
typedef void (*threadpool_task_func)(void *data);
struct threadpool_task {
threadpool_task_func work;
void *data;
struct threadpool_task *next;
pthread_cond_t finish;
BOOL finished;
};
struct threadpool *_mesa_threadpool_create(struct NineSwapChain9 *swapchain);
void _mesa_threadpool_destroy(struct NineSwapChain9 *swapchain, struct threadpool *pool);
struct threadpool_task *_mesa_threadpool_queue_task(struct threadpool *pool,
threadpool_task_func func,
void *data);
void _mesa_threadpool_wait_for_task(struct threadpool *pool,
struct threadpool_task **task);
#endif

View file

@ -1,109 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#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 "util/format/u_formats.h"
#include "util/box.h"
#define DBG_CHANNEL DBG_VERTEXBUFFER
HRESULT
NineVertexBuffer9_ctor( struct NineVertexBuffer9 *This,
struct NineUnknownParams *pParams,
D3DVERTEXBUFFER_DESC *pDesc )
{
HRESULT hr;
DBG("This=%p Size=0x%x Usage=%x Pool=%u\n", This,
pDesc->Size, pDesc->Usage, pDesc->Pool);
hr = NineBuffer9_ctor(&This->base, pParams, D3DRTYPE_VERTEXBUFFER,
pDesc->Usage, pDesc->Size, 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 )
{
NineBuffer9_dtor(&This->base);
}
struct pipe_resource *
NineVertexBuffer9_GetResource( struct NineVertexBuffer9 *This, unsigned *offset )
{
return NineBuffer9_GetResource(&This->base, offset);
}
HRESULT NINE_WINAPI
NineVertexBuffer9_Lock( struct NineVertexBuffer9 *This,
UINT OffsetToLock,
UINT SizeToLock,
void **ppbData,
DWORD Flags )
{
return NineBuffer9_Lock(&This->base, OffsetToLock, SizeToLock, ppbData, Flags);
}
HRESULT NINE_WINAPI
NineVertexBuffer9_Unlock( struct NineVertexBuffer9 *This )
{
return NineBuffer9_Unlock(&This->base);
}
HRESULT NINE_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 *)NineUnknown_SetPrivateData,
(void *)NineUnknown_GetPrivateData,
(void *)NineUnknown_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

@ -1,62 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_VERTEXBUFFER9_H_
#define _NINE_VERTEXBUFFER9_H_
#include "resource9.h"
#include "buffer9.h"
struct pipe_screen;
struct pipe_context;
struct pipe_transfer;
struct NineVertexBuffer9
{
struct NineBuffer9 base;
/* G3D */
struct pipe_context *pipe;
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 );
/*** Nine private ***/
struct pipe_resource *
NineVertexBuffer9_GetResource( struct NineVertexBuffer9 *This, unsigned *offset );
/*** Direct3D public ***/
HRESULT NINE_WINAPI
NineVertexBuffer9_Lock( struct NineVertexBuffer9 *This,
UINT OffsetToLock,
UINT SizeToLock,
void **ppbData,
DWORD Flags );
HRESULT NINE_WINAPI
NineVertexBuffer9_Unlock( struct NineVertexBuffer9 *This );
HRESULT NINE_WINAPI
NineVertexBuffer9_GetDesc( struct NineVertexBuffer9 *This,
D3DVERTEXBUFFER_DESC *pDesc );
#endif /* _NINE_VERTEXBUFFER9_H_ */

View file

@ -1,515 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#include "vertexdeclaration9.h"
#include "vertexbuffer9.h"
#include "device9.h"
#include "nine_helpers.h"
#include "nine_shader.h"
#include "util/format/u_formats.h"
#include "pipe/p_context.h"
#include "util/u_math.h"
#include "util/format/u_format.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 bool
nine_d3ddeclusage_check(unsigned usage, unsigned usage_idx)
{
switch (usage) {
case D3DDECLUSAGE_POSITIONT:
case D3DDECLUSAGE_TESSFACTOR:
case D3DDECLUSAGE_DEPTH:
case D3DDECLUSAGE_NORMAL:
case D3DDECLUSAGE_TANGENT:
case D3DDECLUSAGE_BINORMAL:
case D3DDECLUSAGE_POSITION:
case D3DDECLUSAGE_BLENDWEIGHT:
case D3DDECLUSAGE_BLENDINDICES:
case D3DDECLUSAGE_COLOR:
return true;
case D3DDECLUSAGE_PSIZE:
case D3DDECLUSAGE_FOG:
case D3DDECLUSAGE_SAMPLE:
return usage_idx <= 0;
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_i(n, usage_idx)
uint16_t
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_CASEi(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] = "POSITION",
[NINE_DECLUSAGE_BLENDWEIGHT] = "BLENDWEIGHT",
[NINE_DECLUSAGE_BLENDINDICES] = "BLENDINDICES",
[NINE_DECLUSAGE_NORMAL] = "NORMAL",
[NINE_DECLUSAGE_PSIZE] = "PSIZE",
[NINE_DECLUSAGE_TEXCOORD] = "TEXCOORD",
[NINE_DECLUSAGE_TANGENT] = "TANGENT",
[NINE_DECLUSAGE_BINORMAL] = "BINORMAL",
[NINE_DECLUSAGE_TESSFACTOR] = "TESSFACTOR",
[NINE_DECLUSAGE_POSITIONT] = "POSITIONT",
[NINE_DECLUSAGE_COLOR] = "DIFFUSE",
[NINE_DECLUSAGE_DEPTH] = "DEPTH",
[NINE_DECLUSAGE_FOG] = "FOG",
[NINE_DECLUSAGE_NONE] = "(NONE)",
};
static inline const char *
nine_declusage_name(unsigned ndcl)
{
return nine_declusage_names[ndcl % NINE_DECLUSAGE_COUNT];
}
HRESULT
NineVertexDeclaration9_ctor( struct NineVertexDeclaration9 *This,
struct NineUnknownParams *pParams,
const D3DVERTEXELEMENT9 *pElements )
{
const D3DCAPS9 *caps;
unsigned i, nelems;
DBG("This=%p pParams=%p pElements=%p\n", This, pParams, pElements);
/* wine */
for (nelems = 0;
pElements[nelems].Stream != 0xFF;
++nelems) {
user_assert(pElements[nelems].Type != D3DDECLTYPE_UNUSED, E_FAIL);
user_assert(!(pElements[nelems].Offset & 3), E_FAIL);
}
caps = NineDevice9_GetCaps(pParams->device);
user_assert(nelems <= caps->MaxStreams, D3DERR_INVALIDCALL);
HRESULT hr = NineUnknown_ctor(&This->base, pParams);
if (FAILED(hr)) { return hr; }
This->nelems = nelems;
This->decls = CALLOC(This->nelems+1, sizeof(D3DVERTEXELEMENT9));
This->elems = CALLOC(This->nelems, sizeof(struct pipe_vertex_element));
This->usage_map = CALLOC(This->nelems, sizeof(uint16_t));
if (!This->decls || !This->elems || !This->usage_map) { return E_OUTOFMEMORY; }
memcpy(This->decls, pElements, sizeof(D3DVERTEXELEMENT9)*(This->nelems+1));
for (i = 0; i < This->nelems; ++i) {
uint16_t usage = nine_d3d9_to_nine_declusage(This->decls[i].Usage,
This->decls[i].UsageIndex);
This->usage_map[i] = usage;
if (This->decls[i].Usage == D3DDECLUSAGE_POSITIONT)
This->position_t = true;
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);
This->elems[i].dual_slot = false;
/* XXX Remember Method (tessellation), Usage, UsageIndex */
DBG("VERTEXELEMENT[%u]: Stream=%u Offset=%u Type=%s DeclUsage=%s%d\n", i,
This->decls[i].Stream,
This->decls[i].Offset,
util_format_name(This->elems[i].src_format),
nine_declusage_name(usage),
usage / NINE_DECLUSAGE_COUNT);
}
return D3D_OK;
}
void
NineVertexDeclaration9_dtor( struct NineVertexDeclaration9 *This )
{
DBG("This=%p\n", This);
FREE(This->decls);
FREE(This->elems);
FREE(This->usage_map);
NineUnknown_dtor(&This->base);
}
HRESULT NINE_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);
}
void
NineVertexDeclaration9_FillStreamOutputInfo(
struct NineVertexDeclaration9 *This,
struct nine_vs_output_info *ShaderOutputsInfo,
unsigned numOutputs,
struct pipe_stream_output_info *so )
{
unsigned so_outputs = 0;
int i, j;
memset(so, 0, sizeof(struct pipe_stream_output_info));
for (i = 0; i < numOutputs; i++) {
BYTE output_semantic = ShaderOutputsInfo[i].output_semantic;
unsigned output_semantic_index = ShaderOutputsInfo[i].output_semantic_index;
for (j = 0; j < This->nelems; j++) {
if ((This->decls[j].Usage == output_semantic ||
(output_semantic == D3DDECLUSAGE_POSITION &&
This->decls[j].Usage == D3DDECLUSAGE_POSITIONT)) &&
This->decls[j].UsageIndex == output_semantic_index) {
DBG("Matching %s %d: o%d -> %d\n",
nine_declusage_name(nine_d3d9_to_nine_declusage(This->decls[j].Usage, 0)),
This->decls[j].UsageIndex, i, j);
so->output[so_outputs].register_index = ShaderOutputsInfo[i].output_index;
so->output[so_outputs].start_component = 0;
if (ShaderOutputsInfo[i].mask & 8)
so->output[so_outputs].num_components = 4;
else if (ShaderOutputsInfo[i].mask & 4)
so->output[so_outputs].num_components = 3;
else if (ShaderOutputsInfo[i].mask & 2)
so->output[so_outputs].num_components = 2;
else
so->output[so_outputs].num_components = 1;
so->output[so_outputs].output_buffer = 0;
so->output[so_outputs].dst_offset = so_outputs * sizeof(float[4])/4;
so->output[so_outputs].stream = 0;
so_outputs++;
break;
}
}
}
so->num_outputs = so_outputs;
so->stride[0] = so_outputs * sizeof(float[4])/4;
}
/* 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,
void *pSrcBuf,
const struct pipe_stream_output_info *so )
{
struct translate *translate;
struct translate_key transkey;
HRESULT hr;
unsigned i;
void *dst_map;
DBG("This=%p pDstBuf=%p DestIndex=%u VertexCount=%u pSrcBuf=%p so=%p\n",
This, pDstBuf, DestIndex, VertexCount, pSrcBuf, so);
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;
translate->set_buffer(translate, 0, pSrcBuf, so->stride[0] * 4, ~0);
translate->run(translate, 0, VertexCount, 0, 0, dst_map);
NineVertexBuffer9_Unlock(pDstBuf);
out:
translate->release(translate); /* TODO: cache these */
return hr;
}

View file

@ -1,82 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#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 nine_vs_output_info;
struct NineVertexDeclaration9
{
struct NineUnknown base;
/* G3D state */
struct pipe_vertex_element *elems;
unsigned nelems;
/* index -> DECLUSAGE, for selecting the vertex element
* for each VS input */
uint16_t *usage_map;
D3DVERTEXELEMENT9 *decls;
DWORD fvf;
BOOL position_t;
};
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 NINE_WINAPI
NineVertexDeclaration9_GetDeclaration( struct NineVertexDeclaration9 *This,
D3DVERTEXELEMENT9 *pElement,
UINT *pNumElements );
void
NineVertexDeclaration9_FillStreamOutputInfo(
struct NineVertexDeclaration9 *This,
struct nine_vs_output_info *ShaderOutputsInfo,
unsigned numOutputs,
struct pipe_stream_output_info *so );
/* Convert stream output data to the vertex declaration's format. */
HRESULT
NineVertexDeclaration9_ConvertStreamOutput(
struct NineVertexDeclaration9 *This,
struct NineVertexBuffer9 *pDstBuf,
UINT DestIndex,
UINT VertexCount,
void *pSrcBuf,
const struct pipe_stream_output_info *so );
#endif /* _NINE_VERTEXDECLARATION9_H_ */

View file

@ -1,299 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#include "nine_helpers.h"
#include "nine_shader.h"
#include "vertexdeclaration9.h"
#include "vertexshader9.h"
#include "device9.h"
#include "pipe/p_context.h"
#include "cso_cache/cso_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;
struct pipe_context *pipe;
HRESULT hr;
unsigned i;
DBG("This=%p pParams=%p pFunction=%p cso=%p\n",
This, pParams, pFunction, cso);
hr = NineUnknown_ctor(&This->base, pParams);
if (FAILED(hr))
return hr;
if (cso) {
This->ff_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.fetch4 = 0x0;
info.sampler_ps1xtypes = 0x0;
info.fog_enable = 0;
info.point_size_min = 0;
info.point_size_max = 0;
info.clip_plane_emulation = 0;
info.add_constants_defs.c_combination = NULL;
info.add_constants_defs.int_const_added = NULL;
info.add_constants_defs.bool_const_added = NULL;
info.swvp_on = !!(device->params.BehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING);
info.process_vertices = false;
pipe = nine_context_get_pipe_acquire(device);
hr = nine_translate_shader(device, &info, pipe);
if (hr == D3DERR_INVALIDCALL &&
(device->params.BehaviorFlags & D3DCREATE_MIXED_VERTEXPROCESSING)) {
/* Retry with a swvp shader. It will require swvp to be on. */
info.swvp_on = true;
hr = nine_translate_shader(device, &info, pipe);
}
nine_context_get_pipe_release(device);
if (hr == D3DERR_INVALIDCALL)
ERR("Encountered buggy shader\n");
if (FAILED(hr))
return hr;
This->byte_code.version = info.version;
This->swvp_only = info.swvp_on;
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->variant.const_ranges = info.const_ranges;
This->variant.const_used_size = info.const_used_size;
This->last_cso = info.cso;
This->last_const_ranges = info.const_ranges;
This->last_const_used_size = info.const_used_size;
This->last_key = (uint32_t) (info.swvp_on << 9);
This->lconstf = info.lconstf;
This->sampler_mask = info.sampler_mask;
This->position_t = info.position_t;
This->point_size = info.point_size;
memcpy(This->int_slots_used, info.int_slots_used, sizeof(This->int_slots_used));
memcpy(This->bool_slots_used, info.bool_slots_used, sizeof(This->bool_slots_used));
This->const_int_slots = info.const_int_slots;
This->const_bool_slots = info.const_bool_slots;
This->c_combinations = NULL;
for (i = 0; i < info.num_inputs && i < ARRAY_SIZE(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\n", This);
if (This->base.device) {
struct pipe_context *pipe = nine_context_get_pipe_multithread(This->base.device);
struct nine_shader_variant *var = &This->variant;
struct nine_shader_variant_so *var_so = &This->variant_so;
do {
if (var->cso) {
if (This->base.device->context.cso_shader.vs == var->cso) {
/* unbind because it is illegal to delete something bound */
pipe->bind_vs_state(pipe, NULL);
/* This will rebind cso_shader.vs in case somehow actually
* an identical shader with same cso is bound */
This->base.device->context.commit |= NINE_STATE_COMMIT_VS;
}
pipe->delete_vs_state(pipe, var->cso);
FREE(var->const_ranges);
}
var = var->next;
} while (var);
while (var_so && var_so->vdecl) {
if (var_so->cso) {
This->base.device->pipe_sw->delete_vs_state(This->base.device->pipe_sw, var_so->cso);
}
var_so = var_so->next;
}
if (This->ff_cso) {
if (This->ff_cso == This->base.device->context.cso_shader.vs) {
pipe->bind_vs_state(pipe, NULL);
This->base.device->context.commit |= NINE_STATE_COMMIT_VS;
}
pipe->delete_vs_state(pipe, This->ff_cso);
}
}
nine_shader_variants_free(&This->variant);
nine_shader_variants_so_free(&This->variant_so);
nine_shader_constant_combination_free(This->c_combinations);
FREE((void *)This->byte_code.tokens); /* const_cast */
FREE(This->lconstf.data);
FREE(This->lconstf.ranges);
NineUnknown_dtor(&This->base);
}
HRESULT NINE_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,
unsigned **const_ranges,
unsigned *const_used_size )
{
/* GetVariant is called from nine_context, thus we can
* get pipe directly */
struct pipe_context *pipe = This->base.device->context.pipe;
void *cso;
uint64_t key;
key = This->next_key;
if (key == This->last_key) {
*const_ranges = This->last_const_ranges;
*const_used_size = This->last_const_used_size;
return This->last_cso;
}
cso = nine_shader_variant_get(&This->variant, const_ranges, const_used_size, 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;
info.fetch4 = 0x0;
info.fog_enable = device->context.rs[D3DRS_FOGENABLE];
info.point_size_min = asfloat(device->context.rs[D3DRS_POINTSIZE_MIN]);
info.point_size_max = asfloat(device->context.rs[D3DRS_POINTSIZE_MAX]);
info.clip_plane_emulation = (key >> 24) & 0xff;
info.add_constants_defs.c_combination =
nine_shader_constant_combination_get(This->c_combinations, (key >> 16) & 0xff);
info.add_constants_defs.int_const_added = &This->int_slots_used;
info.add_constants_defs.bool_const_added = &This->bool_slots_used;
info.swvp_on = device->context.swvp;
info.process_vertices = false;
hr = nine_translate_shader(This->base.device, &info, pipe);
if (FAILED(hr))
return NULL;
nine_shader_variant_add(&This->variant, key, info.cso,
info.const_ranges, info.const_used_size);
cso = info.cso;
*const_ranges = info.const_ranges;
*const_used_size = info.const_used_size;
}
This->last_key = key;
This->last_cso = cso;
This->last_const_ranges = *const_ranges;
This->last_const_used_size = *const_used_size;
return cso;
}
void *
NineVertexShader9_GetVariantProcessVertices( struct NineVertexShader9 *This,
struct NineVertexDeclaration9 *vdecl_out,
struct pipe_stream_output_info *so )
{
struct nine_shader_info info;
HRESULT hr;
void *cso;
cso = nine_shader_variant_so_get(&This->variant_so, vdecl_out, so);
if (cso)
return cso;
info.type = PIPE_SHADER_VERTEX;
info.const_i_base = 0;
info.const_b_base = 0;
info.byte_code = This->byte_code.tokens;
info.sampler_mask_shadow = 0;
info.fetch4 = 0x0;
info.fog_enable = false;
info.point_size_min = 0;
info.point_size_max = 0;
info.add_constants_defs.c_combination = NULL;
info.add_constants_defs.int_const_added = NULL;
info.add_constants_defs.bool_const_added = NULL;
info.swvp_on = true;
info.vdecl_out = vdecl_out;
info.process_vertices = true;
hr = nine_translate_shader(This->base.device, &info, This->base.device->pipe_sw);
if (FAILED(hr))
return NULL;
*so = info.so;
nine_shader_variant_so_add(&This->variant_so, vdecl_out, so, info.cso);
return info.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 )
{
if (cso) {
NINE_DEVICE_CHILD_BIND_NEW(VertexShader9, ppOut, pDevice, pFunction, cso);
} else {
NINE_DEVICE_CHILD_NEW(VertexShader9, ppOut, pDevice, pFunction, cso);
}
}

View file

@ -1,141 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_VERTEXSHADER9_H_
#define _NINE_VERTEXSHADER9_H_
#include "util/half_float.h"
#include "iunknown.h"
#include "device9.h"
#include "nine_helpers.h"
#include "nine_shader.h"
#include "nine_state.h"
struct NineVertexDeclaration9;
struct NineVertexShader9
{
struct NineUnknown base;
struct nine_shader_variant variant;
struct {
uint16_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;
bool position_t; /* if true, disable vport transform */
bool point_size; /* if true, set rasterizer.point_size_per_vertex to 1 */
bool swvp_only;
struct nine_lconstf lconstf;
bool int_slots_used[NINE_MAX_CONST_I];
bool bool_slots_used[NINE_MAX_CONST_B];
unsigned const_int_slots;
unsigned const_bool_slots;
struct nine_shader_constant_combination *c_combinations;
uint64_t ff_key[3];
void *ff_cso;
uint64_t last_key;
void *last_cso;
unsigned *last_const_ranges;
unsigned last_const_used_size; /* in bytes */
uint64_t next_key;
/* so */
struct nine_shader_variant_so variant_so;
};
static inline struct NineVertexShader9 *
NineVertexShader9( void *data )
{
return (struct NineVertexShader9 *)data;
}
static inline BOOL
NineVertexShader9_UpdateKey( struct NineVertexShader9 *vs,
struct NineDevice9 *device )
{
struct nine_context *context = &(device->context);
uint8_t samplers_shadow;
uint64_t key;
BOOL res;
samplers_shadow = (uint8_t)((context->samplers_shadow & NINE_VS_SAMPLERS_MASK) >> NINE_SAMPLER_VS(0));
samplers_shadow &= vs->sampler_mask;
key = samplers_shadow;
if (vs->byte_code.version < 0x30)
key |= (uint32_t) ((!!context->rs[D3DRS_FOGENABLE]) << 8);
key |= (uint32_t) (context->swvp << 9);
if ((vs->const_int_slots > 0 || vs->const_bool_slots > 0) && context->inline_constants && !context->swvp)
key |= ((uint64_t)nine_shader_constant_combination_key(&vs->c_combinations,
vs->int_slots_used,
vs->bool_slots_used,
context->vs_const_i,
context->vs_const_b)) << 16;
if (device->driver_caps.emulate_ucp)
key |= (context->rs[D3DRS_CLIPPLANEENABLE] & 0xff) << 24;
/* We want to use a 64 bits key for performance.
* Use compressed float16 values for the pointsize min/max in the key.
* Shaders do not usually output psize.*/
if (vs->point_size) {
key |= ((uint64_t)_mesa_float_to_half(asfloat(context->rs[D3DRS_POINTSIZE_MIN]))) << 32;
key |= ((uint64_t)_mesa_float_to_half(asfloat(context->rs[D3DRS_POINTSIZE_MAX]))) << 48;
}
res = vs->last_key != key;
if (res)
vs->next_key = key;
return res;
}
void *
NineVertexShader9_GetVariant( struct NineVertexShader9 *vs,
unsigned **const_ranges,
unsigned *const_used_size );
void *
NineVertexShader9_GetVariantProcessVertices( struct NineVertexShader9 *vs,
struct NineVertexDeclaration9 *vdecl_out,
struct pipe_stream_output_info *so );
/*** 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 NINE_WINAPI
NineVertexShader9_GetFunction( struct NineVertexShader9 *This,
void *pData,
UINT *pSizeOfData );
#endif /* _NINE_VERTEXSHADER9_H_ */

View file

@ -1,540 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#include "device9.h"
#include "volume9.h"
#include "basetexture9.h" /* for marking dirty */
#include "volumetexture9.h"
#include "nine_helpers.h"
#include "nine_pipe.h"
#include "nine_dump.h"
#include "util/format/u_format.h"
#include "util/u_surface.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 *)align_calloc(size, 32);
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;
pipe_resource_reference(&This->resource, pResource);
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.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.nr_storage_samples = 0;
This->info.usage = PIPE_USAGE_DEFAULT;
This->info.bind = PIPE_BIND_SAMPLER_VIEW;
This->info.flags = 0;
This->info.format = d3d9_to_pipe_format_checked(This->info.screen,
pDesc->Format,
This->info.target,
This->info.nr_samples,
This->info.bind, false,
pDesc->Pool == D3DPOOL_SCRATCH);
if (This->info.format == PIPE_FORMAT_NONE)
return D3DERR_DRIVERINTERNALERROR;
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);
/* Get true format */
This->format_internal = d3d9_to_pipe_format_checked(This->info.screen,
pDesc->Format,
This->info.target,
This->info.nr_samples,
This->info.bind, false,
true);
if (This->info.format != This->format_internal ||
/* See surface9.c */
(pParams->device->workarounds.dynamic_texture_workaround &&
pDesc->Pool == D3DPOOL_DEFAULT && pDesc->Usage & D3DUSAGE_DYNAMIC)) {
This->stride_internal = nine_format_get_stride(This->format_internal,
pDesc->Width);
This->layer_stride_internal = util_format_get_2d_size(This->format_internal,
This->stride_internal,
pDesc->Height);
This->data_internal = align_calloc(This->layer_stride_internal *
This->desc.Depth, 32);
if (!This->data_internal)
return E_OUTOFMEMORY;
}
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) {
struct pipe_context *pipe = nine_context_get_pipe_multithread(This->base.device);
pipe->texture_unmap(pipe, This->transfer);
This->transfer = NULL;
}
/* Note: Following condition cannot happen currently, since we
* refcount the volume in the functions increasing
* pending_uploads_counter. */
if (p_atomic_read(&This->pending_uploads_counter))
nine_csmt_process(This->base.device);
if (This->data)
align_free(This->data);
if (This->data_internal)
align_free(This->data_internal);
pipe_resource_reference(&This->resource, NULL);
NineUnknown_dtor(&This->base);
}
HRESULT NINE_WINAPI
NineVolume9_GetContainer( struct NineVolume9 *This,
REFIID riid,
void **ppContainer )
{
char guid_str[64];
DBG("This=%p riid=%p id=%s ppContainer=%p\n",
This, riid, riid ? GUID_sprintf(guid_str, riid) : "", ppContainer);
(void)guid_str;
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;
#if MESA_DEBUG || !defined(NDEBUG)
/* 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->managed.dirty = true;
BASETEX_REGISTER_UPDATE(tex);
}
HRESULT NINE_WINAPI
NineVolume9_GetDesc( struct NineVolume9 *This,
D3DVOLUME_DESC *pDesc )
{
user_assert(pDesc != NULL, E_POINTER);
*pDesc = This->desc;
return D3D_OK;
}
inline void
NineVolume9_AddDirtyRegion( struct NineVolume9 *This,
const struct pipe_box *box )
{
D3DBOX dirty_region;
struct NineVolumeTexture9 *tex = NineVolumeTexture9(This->base.container);
if (!box) {
NineVolumeTexture9_AddDirtyBox(tex, NULL);
} else {
dirty_region.Left = box->x << This->level_actual;
dirty_region.Top = box->y << This->level_actual;
dirty_region.Front = box->z << This->level_actual;
dirty_region.Right = dirty_region.Left + (box->width << This->level_actual);
dirty_region.Bottom = dirty_region.Top + (box->height << This->level_actual);
dirty_region.Back = dirty_region.Front + (box->depth << This->level_actual);
NineVolumeTexture9_AddDirtyBox(tex, &dirty_region);
}
}
static inline unsigned
NineVolume9_GetSystemMemOffset(enum pipe_format format, unsigned stride,
unsigned layer_stride,
int x, int y, int z)
{
unsigned x_offset = util_format_get_stride(format, x);
y = util_format_get_nblocksy(format, y);
return z * layer_stride + y * stride + x_offset;
}
HRESULT NINE_WINAPI
NineVolume9_LockBox( struct NineVolume9 *This,
D3DLOCKED_BOX *pLockedVolume,
const D3DBOX *pBox,
DWORD Flags )
{
struct pipe_context *pipe;
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));
/* check if it's already locked */
user_assert(This->lock_count == 0, D3DERR_INVALIDCALL);
/* set pBits to NULL after lock_count check */
user_assert(pLockedVolume, E_POINTER);
pLockedVolume->pBits = NULL;
user_assert(This->desc.Pool != D3DPOOL_DEFAULT ||
(This->desc.Usage & D3DUSAGE_DYNAMIC), D3DERR_INVALIDCALL);
user_assert(!((Flags & D3DLOCK_DISCARD) && (Flags & D3DLOCK_READONLY)),
D3DERR_INVALIDCALL);
if (pBox && compressed_format (This->desc.Format)) { /* For volume all pools are checked */
const unsigned w = util_format_get_blockwidth(This->info.format);
const unsigned h = util_format_get_blockheight(This->info.format);
user_assert((pBox->Left == 0 && pBox->Right == This->desc.Width &&
pBox->Top == 0 && pBox->Bottom == This->desc.Height) ||
(!(pBox->Left % w) && !(pBox->Right % w) &&
!(pBox->Top % h) && !(pBox->Bottom % h)),
D3DERR_INVALIDCALL);
}
if (Flags & D3DLOCK_DISCARD) {
usage = PIPE_MAP_WRITE | PIPE_MAP_DISCARD_RANGE;
} else {
usage = (Flags & D3DLOCK_READONLY) ?
PIPE_MAP_READ : PIPE_MAP_READ_WRITE;
}
if (Flags & D3DLOCK_DONOTWAIT)
usage |= PIPE_MAP_DONTBLOCK;
if (pBox) {
user_assert(pBox->Right > pBox->Left, D3DERR_INVALIDCALL);
user_assert(pBox->Bottom > pBox->Top, D3DERR_INVALIDCALL);
user_assert(pBox->Back > pBox->Front, D3DERR_INVALIDCALL);
user_assert(pBox->Right <= This->desc.Width, D3DERR_INVALIDCALL);
user_assert(pBox->Bottom <= This->desc.Height, D3DERR_INVALIDCALL);
user_assert(pBox->Back <= This->desc.Depth, D3DERR_INVALIDCALL);
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 (p_atomic_read(&This->pending_uploads_counter))
nine_csmt_process(This->base.device);
if (This->data_internal || This->data) {
enum pipe_format format = This->info.format;
unsigned stride = This->stride;
unsigned layer_stride = This->layer_stride;
uint8_t *data = This->data;
if (This->data_internal) {
format = This->format_internal;
stride = This->stride_internal;
layer_stride = This->layer_stride_internal;
data = This->data_internal;
}
pLockedVolume->RowPitch = stride;
pLockedVolume->SlicePitch = layer_stride;
pLockedVolume->pBits = data +
NineVolume9_GetSystemMemOffset(format, stride,
layer_stride,
box.x, box.y, box.z);
} else {
bool no_refs = !p_atomic_read(&This->base.bind) &&
!p_atomic_read(&This->base.container->bind);
if (no_refs)
pipe = nine_context_get_pipe_acquire(This->base.device);
else
pipe = NineDevice9_GetPipe(This->base.device);
pLockedVolume->pBits =
pipe->texture_map(pipe, resource, This->level, usage,
&box, &This->transfer);
if (no_refs)
nine_context_get_pipe_release(This->base.device);
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);
NineVolume9_AddDirtyRegion(This, &box);
}
++This->lock_count;
return D3D_OK;
}
HRESULT NINE_WINAPI
NineVolume9_UnlockBox( struct NineVolume9 *This )
{
struct pipe_context *pipe;
DBG("This=%p lock_count=%u\n", This, This->lock_count);
user_assert(This->lock_count, D3DERR_INVALIDCALL);
if (This->transfer) {
pipe = nine_context_get_pipe_acquire(This->base.device);
pipe->texture_unmap(pipe, This->transfer);
This->transfer = NULL;
nine_context_get_pipe_release(This->base.device);
}
--This->lock_count;
if (This->data_internal) {
struct pipe_box box;
u_box_3d(0, 0, 0, This->desc.Width, This->desc.Height, This->desc.Depth,
&box);
if (This->data) {
(void) util_format_translate_3d(This->info.format,
This->data, This->stride,
This->layer_stride,
0, 0, 0,
This->format_internal,
This->data_internal,
This->stride_internal,
This->layer_stride_internal,
0, 0, 0,
This->desc.Width, This->desc.Height,
This->desc.Depth);
} else {
nine_context_box_upload(This->base.device,
&This->pending_uploads_counter,
(struct NineUnknown *)This,
This->resource,
This->level,
&box,
This->format_internal,
This->data_internal,
This->stride_internal,
This->layer_stride_internal,
&box);
}
}
return D3D_OK;
}
/* When this function is called, we have already checked
* The copy regions fit the volumes */
void
NineVolume9_CopyMemToDefault( struct NineVolume9 *This,
struct NineVolume9 *From,
unsigned dstx, unsigned dsty, unsigned dstz,
struct pipe_box *pSrcBox )
{
struct pipe_resource *r_dst = This->resource;
struct pipe_box src_box;
struct pipe_box dst_box;
DBG("This=%p From=%p dstx=%u dsty=%u dstz=%u pSrcBox=%p\n",
This, From, dstx, dsty, dstz, pSrcBox);
assert(This->desc.Pool == D3DPOOL_DEFAULT &&
From->desc.Pool == D3DPOOL_SYSTEMMEM);
dst_box.x = dstx;
dst_box.y = dsty;
dst_box.z = dstz;
if (pSrcBox) {
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;
}
dst_box.width = src_box.width;
dst_box.height = src_box.height;
dst_box.depth = src_box.depth;
nine_context_box_upload(This->base.device,
&From->pending_uploads_counter,
(struct NineUnknown *)From,
r_dst,
This->level,
&dst_box,
From->info.format,
From->data, From->stride,
From->layer_stride,
&src_box);
if (This->data_internal)
(void) util_format_translate_3d(This->format_internal,
This->data_internal,
This->stride_internal,
This->layer_stride_internal,
dstx, dsty, dstz,
From->info.format,
From->data, From->stride,
From->layer_stride,
src_box.x, src_box.y,
src_box.z,
src_box.width,
src_box.height,
src_box.depth);
NineVolume9_MarkContainerDirty(This);
return;
}
HRESULT
NineVolume9_UploadSelf( struct NineVolume9 *This,
const struct pipe_box *damaged )
{
struct pipe_resource *res = This->resource;
struct pipe_box box;
DBG("This=%p damaged=%p data=%p res=%p\n", This, damaged,
This->data, res);
assert(This->desc.Pool == D3DPOOL_MANAGED);
assert(res);
if (damaged) {
box = *damaged;
} else {
box.x = 0;
box.y = 0;
box.z = 0;
box.width = This->desc.Width;
box.height = This->desc.Height;
box.depth = This->desc.Depth;
}
nine_context_box_upload(This->base.device,
&This->pending_uploads_counter,
(struct NineUnknown *)This,
res,
This->level,
&box,
res->format,
This->data, This->stride,
This->layer_stride,
&box);
return D3D_OK;
}
IDirect3DVolume9Vtbl NineVolume9_vtable = {
(void *)NineUnknown_QueryInterface,
(void *)NineUnknown_AddRef,
(void *)NineUnknown_Release,
(void *)NineUnknown_GetDevice, /* actually part of Volume9 iface */
(void *)NineUnknown_SetPrivateData,
(void *)NineUnknown_GetPrivateData,
(void *)NineUnknown_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);
}

View file

@ -1,101 +0,0 @@
/*
* Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
* SPDX-License-Identifier: MIT
*/
#ifndef _NINE_VOLUME9_H_
#define _NINE_VOLUME9_H_
#include "iunknown.h"
#include "pipe/p_state.h"
#include "util/u_inlines.h"
struct hash_table;
struct NineDevice9;
struct NineVolume9
{
struct NineUnknown base;
struct pipe_resource *resource;
unsigned level;
unsigned level_actual;
uint8_t *data; /* system memory backing */
uint8_t *data_internal; /* for conversions */
D3DVOLUME_DESC desc;
struct pipe_resource info;
enum pipe_format format_internal;
unsigned stride;
unsigned stride_internal;
unsigned layer_stride;
unsigned layer_stride_internal;
struct pipe_transfer *transfer;
unsigned lock_count;
unsigned pending_uploads_counter; /* pending uploads */
};
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 );
void
NineVolume9_CopyMemToDefault( struct NineVolume9 *This,
struct NineVolume9 *From,
unsigned dstx, unsigned dsty, unsigned dstz,
struct pipe_box *pSrcBox );
HRESULT
NineVolume9_UploadSelf( struct NineVolume9 *This,
const struct pipe_box *damaged );
/*** Direct3D public ***/
HRESULT NINE_WINAPI
NineVolume9_GetContainer( struct NineVolume9 *This,
REFIID riid,
void **ppContainer );
HRESULT NINE_WINAPI
NineVolume9_GetDesc( struct NineVolume9 *This,
D3DVOLUME_DESC *pDesc );
HRESULT NINE_WINAPI
NineVolume9_LockBox( struct NineVolume9 *This,
D3DLOCKED_BOX *pLockedVolume,
const D3DBOX *pBox,
DWORD Flags );
HRESULT NINE_WINAPI
NineVolume9_UnlockBox( struct NineVolume9 *This );
#endif /* _NINE_VOLUME9_H_ */

Some files were not shown because too many files have changed in this diff Show more