mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-12 13:54:14 +01:00
[d3d8] Unify source file endline delimiters
This commit is contained in:
parent
475bf4e9c1
commit
8ead28e481
@ -1,8 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace dxvk::d8caps {
|
namespace dxvk::d8caps {
|
||||||
|
|
||||||
inline constexpr uint32_t MAX_TEXTURE_STAGES = 8;
|
inline constexpr uint32_t MAX_TEXTURE_STAGES = 8;
|
||||||
inline constexpr uint32_t MAX_STREAMS = 16;
|
inline constexpr uint32_t MAX_STREAMS = 16;
|
||||||
|
|
||||||
}
|
}
|
@ -1,176 +1,176 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Utility functions for converting
|
// Utility functions for converting
|
||||||
// between DirectX8 and DirectX9 types.
|
// between DirectX8 and DirectX9 types.
|
||||||
|
|
||||||
#include "d3d8_include.h"
|
#include "d3d8_include.h"
|
||||||
#include "d3d8_format.h"
|
#include "d3d8_format.h"
|
||||||
#include "d3d8_options.h"
|
#include "d3d8_options.h"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
// (8<-9) D3DCAPSX: Writes to D3DCAPS8 from D3DCAPS9
|
// (8<-9) D3DCAPSX: Writes to D3DCAPS8 from D3DCAPS9
|
||||||
inline void ConvertCaps8(const d3d9::D3DCAPS9& caps9, D3DCAPS8* pCaps8) {
|
inline void ConvertCaps8(const d3d9::D3DCAPS9& caps9, D3DCAPS8* pCaps8) {
|
||||||
|
|
||||||
// should be aligned
|
// should be aligned
|
||||||
std::memcpy(pCaps8, &caps9, sizeof(D3DCAPS8));
|
std::memcpy(pCaps8, &caps9, sizeof(D3DCAPS8));
|
||||||
|
|
||||||
// Max supported shader model is PS 1.4 and VS 1.1
|
// Max supported shader model is PS 1.4 and VS 1.1
|
||||||
pCaps8->VertexShaderVersion = D3DVS_VERSION(1, 1);
|
pCaps8->VertexShaderVersion = D3DVS_VERSION(1, 1);
|
||||||
pCaps8->PixelShaderVersion = D3DPS_VERSION(1, 4);
|
pCaps8->PixelShaderVersion = D3DPS_VERSION(1, 4);
|
||||||
|
|
||||||
// This was removed by D3D9. We can probably render windowed.
|
// This was removed by D3D9. We can probably render windowed.
|
||||||
pCaps8->Caps2 |= D3DCAPS2_CANRENDERWINDOWED;
|
pCaps8->Caps2 |= D3DCAPS2_CANRENDERWINDOWED;
|
||||||
|
|
||||||
// Replaced by D3DPRASTERCAPS_DEPTHBIAS in D3D9
|
// Replaced by D3DPRASTERCAPS_DEPTHBIAS in D3D9
|
||||||
pCaps8->RasterCaps |= D3DPRASTERCAPS_ZBIAS;
|
pCaps8->RasterCaps |= D3DPRASTERCAPS_ZBIAS;
|
||||||
|
|
||||||
|
|
||||||
// Remove D3D9-specific caps:
|
// Remove D3D9-specific caps:
|
||||||
pCaps8->Caps2 &= ~D3DCAPS2_CANAUTOGENMIPMAP;
|
pCaps8->Caps2 &= ~D3DCAPS2_CANAUTOGENMIPMAP;
|
||||||
|
|
||||||
pCaps8->Caps3 &= ~D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION
|
pCaps8->Caps3 &= ~D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION
|
||||||
& ~D3DCAPS3_COPY_TO_VIDMEM
|
& ~D3DCAPS3_COPY_TO_VIDMEM
|
||||||
& ~D3DCAPS3_COPY_TO_SYSTEMMEM;
|
& ~D3DCAPS3_COPY_TO_SYSTEMMEM;
|
||||||
|
|
||||||
pCaps8->PrimitiveMiscCaps &= ~D3DPMISCCAPS_INDEPENDENTWRITEMASKS
|
pCaps8->PrimitiveMiscCaps &= ~D3DPMISCCAPS_INDEPENDENTWRITEMASKS
|
||||||
& ~D3DPMISCCAPS_PERSTAGECONSTANT
|
& ~D3DPMISCCAPS_PERSTAGECONSTANT
|
||||||
& ~D3DPMISCCAPS_FOGANDSPECULARALPHA
|
& ~D3DPMISCCAPS_FOGANDSPECULARALPHA
|
||||||
& ~D3DPMISCCAPS_SEPARATEALPHABLEND
|
& ~D3DPMISCCAPS_SEPARATEALPHABLEND
|
||||||
& ~D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
|
& ~D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
|
||||||
& ~D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING
|
& ~D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING
|
||||||
& ~D3DPMISCCAPS_FOGVERTEXCLAMPED
|
& ~D3DPMISCCAPS_FOGVERTEXCLAMPED
|
||||||
& ~D3DPMISCCAPS_POSTBLENDSRGBCONVERT;
|
& ~D3DPMISCCAPS_POSTBLENDSRGBCONVERT;
|
||||||
|
|
||||||
pCaps8->RasterCaps &= ~D3DPRASTERCAPS_SCISSORTEST
|
pCaps8->RasterCaps &= ~D3DPRASTERCAPS_SCISSORTEST
|
||||||
& ~D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS
|
& ~D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS
|
||||||
& ~D3DPRASTERCAPS_DEPTHBIAS
|
& ~D3DPRASTERCAPS_DEPTHBIAS
|
||||||
& ~D3DPRASTERCAPS_MULTISAMPLE_TOGGLE;
|
& ~D3DPRASTERCAPS_MULTISAMPLE_TOGGLE;
|
||||||
|
|
||||||
pCaps8->SrcBlendCaps &= ~D3DPBLENDCAPS_BLENDFACTOR;
|
pCaps8->SrcBlendCaps &= ~D3DPBLENDCAPS_BLENDFACTOR;
|
||||||
|
|
||||||
pCaps8->DestBlendCaps &= ~D3DPBLENDCAPS_BLENDFACTOR;
|
pCaps8->DestBlendCaps &= ~D3DPBLENDCAPS_BLENDFACTOR;
|
||||||
|
|
||||||
pCaps8->LineCaps &= ~D3DLINECAPS_ANTIALIAS;
|
pCaps8->LineCaps &= ~D3DLINECAPS_ANTIALIAS;
|
||||||
|
|
||||||
pCaps8->StencilCaps &= ~D3DSTENCILCAPS_TWOSIDED;
|
pCaps8->StencilCaps &= ~D3DSTENCILCAPS_TWOSIDED;
|
||||||
|
|
||||||
pCaps8->VertexProcessingCaps &= ~D3DVTXPCAPS_TEXGEN_SPHEREMAP;
|
pCaps8->VertexProcessingCaps &= ~D3DVTXPCAPS_TEXGEN_SPHEREMAP;
|
||||||
}
|
}
|
||||||
|
|
||||||
// (9<-8) D3DD3DPRESENT_PARAMETERS: Returns D3D9's params given an input for D3D8
|
// (9<-8) D3DD3DPRESENT_PARAMETERS: Returns D3D9's params given an input for D3D8
|
||||||
inline d3d9::D3DPRESENT_PARAMETERS ConvertPresentParameters9(D3DPRESENT_PARAMETERS* pParams) {
|
inline d3d9::D3DPRESENT_PARAMETERS ConvertPresentParameters9(D3DPRESENT_PARAMETERS* pParams) {
|
||||||
// A 0 back buffer count needs to be corrected and made visible to the D3D8 application as well
|
// A 0 back buffer count needs to be corrected and made visible to the D3D8 application as well
|
||||||
pParams->BackBufferCount = std::max(pParams->BackBufferCount, 1u);
|
pParams->BackBufferCount = std::max(pParams->BackBufferCount, 1u);
|
||||||
|
|
||||||
if (pParams->BackBufferFormat == D3DFMT_UNKNOWN)
|
if (pParams->BackBufferFormat == D3DFMT_UNKNOWN)
|
||||||
pParams->BackBufferFormat = D3DFMT_X8R8G8B8;
|
pParams->BackBufferFormat = D3DFMT_X8R8G8B8;
|
||||||
|
|
||||||
d3d9::D3DPRESENT_PARAMETERS params;
|
d3d9::D3DPRESENT_PARAMETERS params;
|
||||||
params.BackBufferWidth = pParams->BackBufferWidth;
|
params.BackBufferWidth = pParams->BackBufferWidth;
|
||||||
params.BackBufferHeight = pParams->BackBufferHeight;
|
params.BackBufferHeight = pParams->BackBufferHeight;
|
||||||
params.BackBufferFormat = d3d9::D3DFORMAT(pParams->BackBufferFormat);
|
params.BackBufferFormat = d3d9::D3DFORMAT(pParams->BackBufferFormat);
|
||||||
params.BackBufferCount = pParams->BackBufferCount;
|
params.BackBufferCount = pParams->BackBufferCount;
|
||||||
|
|
||||||
params.MultiSampleType = d3d9::D3DMULTISAMPLE_TYPE(pParams->MultiSampleType);
|
params.MultiSampleType = d3d9::D3DMULTISAMPLE_TYPE(pParams->MultiSampleType);
|
||||||
params.MultiSampleQuality = 0; // (D3D8: no MultiSampleQuality), TODO: get a value for this
|
params.MultiSampleQuality = 0; // (D3D8: no MultiSampleQuality), TODO: get a value for this
|
||||||
|
|
||||||
UINT PresentationInterval = pParams->FullScreen_PresentationInterval;
|
UINT PresentationInterval = pParams->FullScreen_PresentationInterval;
|
||||||
|
|
||||||
if (pParams->Windowed) {
|
if (pParams->Windowed) {
|
||||||
|
|
||||||
if (unlikely(PresentationInterval != D3DPRESENT_INTERVAL_DEFAULT)) {
|
if (unlikely(PresentationInterval != D3DPRESENT_INTERVAL_DEFAULT)) {
|
||||||
// TODO: what does dx8 do if windowed app sets FullScreen_PresentationInterval?
|
// TODO: what does dx8 do if windowed app sets FullScreen_PresentationInterval?
|
||||||
Logger::warn(str::format(
|
Logger::warn(str::format(
|
||||||
"D3D8: Application is windowed yet requested FullScreen_PresentationInterval ", PresentationInterval,
|
"D3D8: Application is windowed yet requested FullScreen_PresentationInterval ", PresentationInterval,
|
||||||
" (should be D3DPRESENT_INTERVAL_DEFAULT). This will be ignored."));
|
" (should be D3DPRESENT_INTERVAL_DEFAULT). This will be ignored."));
|
||||||
}
|
}
|
||||||
|
|
||||||
// D3D8: For windowed swap chain, the back buffer is copied to the window immediately.
|
// D3D8: For windowed swap chain, the back buffer is copied to the window immediately.
|
||||||
PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DSWAPEFFECT SwapEffect = pParams->SwapEffect;
|
D3DSWAPEFFECT SwapEffect = pParams->SwapEffect;
|
||||||
|
|
||||||
// D3DSWAPEFFECT_COPY_VSYNC has been removed
|
// D3DSWAPEFFECT_COPY_VSYNC has been removed
|
||||||
if (SwapEffect == D3DSWAPEFFECT_COPY_VSYNC) {
|
if (SwapEffect == D3DSWAPEFFECT_COPY_VSYNC) {
|
||||||
|
|
||||||
SwapEffect = D3DSWAPEFFECT_COPY;
|
SwapEffect = D3DSWAPEFFECT_COPY;
|
||||||
|
|
||||||
// D3D8: In windowed mode, D3DSWAPEFFECT_COPY_VSYNC enables VSYNC.
|
// D3D8: In windowed mode, D3DSWAPEFFECT_COPY_VSYNC enables VSYNC.
|
||||||
// In fullscreen, D3DPRESENT_INTERVAL_IMMEDIATE is meaningless.
|
// In fullscreen, D3DPRESENT_INTERVAL_IMMEDIATE is meaningless.
|
||||||
if (pParams->Windowed || (PresentationInterval & D3DPRESENT_INTERVAL_IMMEDIATE) != 0) {
|
if (pParams->Windowed || (PresentationInterval & D3DPRESENT_INTERVAL_IMMEDIATE) != 0) {
|
||||||
PresentationInterval = D3DPRESENT_INTERVAL_ONE;
|
PresentationInterval = D3DPRESENT_INTERVAL_ONE;
|
||||||
// TODO: what does dx8 do if multiple D3DPRESENT_INTERVAL flags are set?
|
// TODO: what does dx8 do if multiple D3DPRESENT_INTERVAL flags are set?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
params.SwapEffect = d3d9::D3DSWAPEFFECT(SwapEffect);
|
params.SwapEffect = d3d9::D3DSWAPEFFECT(SwapEffect);
|
||||||
params.hDeviceWindow = pParams->hDeviceWindow;
|
params.hDeviceWindow = pParams->hDeviceWindow;
|
||||||
params.Windowed = pParams->Windowed;
|
params.Windowed = pParams->Windowed;
|
||||||
params.EnableAutoDepthStencil = pParams->EnableAutoDepthStencil;
|
params.EnableAutoDepthStencil = pParams->EnableAutoDepthStencil;
|
||||||
params.AutoDepthStencilFormat = d3d9::D3DFORMAT(pParams->AutoDepthStencilFormat);
|
params.AutoDepthStencilFormat = d3d9::D3DFORMAT(pParams->AutoDepthStencilFormat);
|
||||||
params.Flags = pParams->Flags;
|
params.Flags = pParams->Flags;
|
||||||
|
|
||||||
// D3DPRESENT_RATE_UNLIMITED is unsupported, use D3DPRESENT_RATE_DEFAULT (or 0)
|
// D3DPRESENT_RATE_UNLIMITED is unsupported, use D3DPRESENT_RATE_DEFAULT (or 0)
|
||||||
if (unlikely(pParams->FullScreen_RefreshRateInHz == D3DPRESENT_RATE_UNLIMITED)) {
|
if (unlikely(pParams->FullScreen_RefreshRateInHz == D3DPRESENT_RATE_UNLIMITED)) {
|
||||||
params.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
|
params.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
|
||||||
} else {
|
} else {
|
||||||
params.FullScreen_RefreshRateInHz = pParams->FullScreen_RefreshRateInHz;
|
params.FullScreen_RefreshRateInHz = pParams->FullScreen_RefreshRateInHz;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FullScreen_PresentationInterval -> PresentationInterval
|
// FullScreen_PresentationInterval -> PresentationInterval
|
||||||
params.PresentationInterval = PresentationInterval;
|
params.PresentationInterval = PresentationInterval;
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
// (8<-9) Convert D3DSURFACE_DESC
|
// (8<-9) Convert D3DSURFACE_DESC
|
||||||
inline void ConvertSurfaceDesc8(const d3d9::D3DSURFACE_DESC* pSurf9, D3DSURFACE_DESC* pSurf8) {
|
inline void ConvertSurfaceDesc8(const d3d9::D3DSURFACE_DESC* pSurf9, D3DSURFACE_DESC* pSurf8) {
|
||||||
pSurf8->Format = D3DFORMAT(pSurf9->Format);
|
pSurf8->Format = D3DFORMAT(pSurf9->Format);
|
||||||
pSurf8->Type = D3DRESOURCETYPE(pSurf9->Type);
|
pSurf8->Type = D3DRESOURCETYPE(pSurf9->Type);
|
||||||
pSurf8->Usage = pSurf9->Usage;
|
pSurf8->Usage = pSurf9->Usage;
|
||||||
pSurf8->Pool = D3DPOOL(pSurf9->Pool);
|
pSurf8->Pool = D3DPOOL(pSurf9->Pool);
|
||||||
pSurf8->Size = getSurfaceSize(pSurf8->Format, pSurf9->Width, pSurf9->Height);
|
pSurf8->Size = getSurfaceSize(pSurf8->Format, pSurf9->Width, pSurf9->Height);
|
||||||
|
|
||||||
pSurf8->MultiSampleType = D3DMULTISAMPLE_TYPE(pSurf9->MultiSampleType);
|
pSurf8->MultiSampleType = D3DMULTISAMPLE_TYPE(pSurf9->MultiSampleType);
|
||||||
// DX8: No multisample quality
|
// DX8: No multisample quality
|
||||||
pSurf8->Width = pSurf9->Width;
|
pSurf8->Width = pSurf9->Width;
|
||||||
pSurf8->Height = pSurf9->Height;
|
pSurf8->Height = pSurf9->Height;
|
||||||
}
|
}
|
||||||
|
|
||||||
// (8<-9) Convert D3DVOLUME_DESC
|
// (8<-9) Convert D3DVOLUME_DESC
|
||||||
inline void ConvertVolumeDesc8(const d3d9::D3DVOLUME_DESC* pVol9, D3DVOLUME_DESC* pVol8) {
|
inline void ConvertVolumeDesc8(const d3d9::D3DVOLUME_DESC* pVol9, D3DVOLUME_DESC* pVol8) {
|
||||||
pVol8->Format = D3DFORMAT(pVol9->Format);
|
pVol8->Format = D3DFORMAT(pVol9->Format);
|
||||||
pVol8->Type = D3DRESOURCETYPE(pVol9->Type);
|
pVol8->Type = D3DRESOURCETYPE(pVol9->Type);
|
||||||
pVol8->Usage = pVol9->Usage;
|
pVol8->Usage = pVol9->Usage;
|
||||||
pVol8->Pool = D3DPOOL(pVol9->Pool);
|
pVol8->Pool = D3DPOOL(pVol9->Pool);
|
||||||
pVol8->Size = getSurfaceSize(pVol8->Format, pVol9->Width, pVol9->Height) * pVol9->Depth;
|
pVol8->Size = getSurfaceSize(pVol8->Format, pVol9->Width, pVol9->Height) * pVol9->Depth;
|
||||||
pVol8->Width = pVol9->Width;
|
pVol8->Width = pVol9->Width;
|
||||||
pVol8->Height = pVol9->Height;
|
pVol8->Height = pVol9->Height;
|
||||||
pVol8->Depth = pVol9->Depth;
|
pVol8->Depth = pVol9->Depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this D3DTEXTURESTAGESTATETYPE has been remapped to a d3d9::D3DSAMPLERSTATETYPE
|
// If this D3DTEXTURESTAGESTATETYPE has been remapped to a d3d9::D3DSAMPLERSTATETYPE
|
||||||
// it will be returned, otherwise returns -1u
|
// it will be returned, otherwise returns -1u
|
||||||
inline d3d9::D3DSAMPLERSTATETYPE GetSamplerStateType9(const D3DTEXTURESTAGESTATETYPE StageType) {
|
inline d3d9::D3DSAMPLERSTATETYPE GetSamplerStateType9(const D3DTEXTURESTAGESTATETYPE StageType) {
|
||||||
switch (StageType) {
|
switch (StageType) {
|
||||||
// 13-21:
|
// 13-21:
|
||||||
case D3DTSS_ADDRESSU: return d3d9::D3DSAMP_ADDRESSU;
|
case D3DTSS_ADDRESSU: return d3d9::D3DSAMP_ADDRESSU;
|
||||||
case D3DTSS_ADDRESSV: return d3d9::D3DSAMP_ADDRESSV;
|
case D3DTSS_ADDRESSV: return d3d9::D3DSAMP_ADDRESSV;
|
||||||
case D3DTSS_BORDERCOLOR: return d3d9::D3DSAMP_BORDERCOLOR;
|
case D3DTSS_BORDERCOLOR: return d3d9::D3DSAMP_BORDERCOLOR;
|
||||||
case D3DTSS_MAGFILTER: return d3d9::D3DSAMP_MAGFILTER;
|
case D3DTSS_MAGFILTER: return d3d9::D3DSAMP_MAGFILTER;
|
||||||
case D3DTSS_MINFILTER: return d3d9::D3DSAMP_MINFILTER;
|
case D3DTSS_MINFILTER: return d3d9::D3DSAMP_MINFILTER;
|
||||||
case D3DTSS_MIPFILTER: return d3d9::D3DSAMP_MIPFILTER;
|
case D3DTSS_MIPFILTER: return d3d9::D3DSAMP_MIPFILTER;
|
||||||
case D3DTSS_MIPMAPLODBIAS: return d3d9::D3DSAMP_MIPMAPLODBIAS;
|
case D3DTSS_MIPMAPLODBIAS: return d3d9::D3DSAMP_MIPMAPLODBIAS;
|
||||||
case D3DTSS_MAXMIPLEVEL: return d3d9::D3DSAMP_MAXMIPLEVEL;
|
case D3DTSS_MAXMIPLEVEL: return d3d9::D3DSAMP_MAXMIPLEVEL;
|
||||||
case D3DTSS_MAXANISOTROPY: return d3d9::D3DSAMP_MAXANISOTROPY;
|
case D3DTSS_MAXANISOTROPY: return d3d9::D3DSAMP_MAXANISOTROPY;
|
||||||
// 25:
|
// 25:
|
||||||
case D3DTSS_ADDRESSW: return d3d9::D3DSAMP_ADDRESSW;
|
case D3DTSS_ADDRESSW: return d3d9::D3DSAMP_ADDRESSW;
|
||||||
default: return d3d9::D3DSAMPLERSTATETYPE(-1u);
|
default: return d3d9::D3DSAMPLERSTATETYPE(-1u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,71 +1,71 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Common methods for device-tied objects.
|
// Common methods for device-tied objects.
|
||||||
// - AddRef, Release from IUnknown
|
// - AddRef, Release from IUnknown
|
||||||
// - GetDevice from various classes including IDirect3DResource8
|
// - GetDevice from various classes including IDirect3DResource8
|
||||||
|
|
||||||
#include "d3d8_include.h"
|
#include "d3d8_include.h"
|
||||||
#include "d3d8_wrapped_object.h"
|
#include "d3d8_wrapped_object.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
class D3D8Device;
|
class D3D8Device;
|
||||||
|
|
||||||
template <typename D3D9, typename D3D8>
|
template <typename D3D9, typename D3D8>
|
||||||
class D3D8DeviceChild : public D3D8WrappedObject<D3D9, D3D8> {
|
class D3D8DeviceChild : public D3D8WrappedObject<D3D9, D3D8> {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
D3D8DeviceChild(D3D8Device* pDevice, Com<D3D9>&& Object)
|
D3D8DeviceChild(D3D8Device* pDevice, Com<D3D9>&& Object)
|
||||||
: D3D8WrappedObject<D3D9, D3D8>(std::move(Object))
|
: D3D8WrappedObject<D3D9, D3D8>(std::move(Object))
|
||||||
, m_parent( pDevice ) { }
|
, m_parent( pDevice ) { }
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE AddRef() {
|
ULONG STDMETHODCALLTYPE AddRef() {
|
||||||
uint32_t refCount = this->m_refCount++;
|
uint32_t refCount = this->m_refCount++;
|
||||||
if (unlikely(!refCount)) {
|
if (unlikely(!refCount)) {
|
||||||
this->AddRefPrivate();
|
this->AddRefPrivate();
|
||||||
GetDevice()->AddRef();
|
GetDevice()->AddRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
return refCount + 1;
|
return refCount + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE Release() {
|
ULONG STDMETHODCALLTYPE Release() {
|
||||||
// ignore Release calls on objects with 0 refCount
|
// ignore Release calls on objects with 0 refCount
|
||||||
if(unlikely(!this->m_refCount))
|
if(unlikely(!this->m_refCount))
|
||||||
return this->m_refCount;
|
return this->m_refCount;
|
||||||
|
|
||||||
uint32_t refCount = --this->m_refCount;
|
uint32_t refCount = --this->m_refCount;
|
||||||
if (unlikely(!refCount)) {
|
if (unlikely(!refCount)) {
|
||||||
auto* pDevice = GetDevice();
|
auto* pDevice = GetDevice();
|
||||||
this->ReleasePrivate();
|
this->ReleasePrivate();
|
||||||
pDevice->Release();
|
pDevice->Release();
|
||||||
}
|
}
|
||||||
return refCount;
|
return refCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE GetDevice(IDirect3DDevice8** ppDevice) {
|
HRESULT STDMETHODCALLTYPE GetDevice(IDirect3DDevice8** ppDevice) {
|
||||||
InitReturnPtr(ppDevice);
|
InitReturnPtr(ppDevice);
|
||||||
|
|
||||||
if (ppDevice == nullptr)
|
if (ppDevice == nullptr)
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
*ppDevice = ref(GetDevice());
|
*ppDevice = ref(GetDevice());
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDirect3DDevice8* GetDevice() {
|
IDirect3DDevice8* GetDevice() {
|
||||||
return reinterpret_cast<IDirect3DDevice8*>(m_parent);
|
return reinterpret_cast<IDirect3DDevice8*>(m_parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D8Device* GetParent() {
|
D3D8Device* GetParent() {
|
||||||
return m_parent;
|
return m_parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
D3D8Device* m_parent;
|
D3D8Device* m_parent;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -1,153 +1,153 @@
|
|||||||
#include "d3d8_interface.h"
|
#include "d3d8_interface.h"
|
||||||
|
|
||||||
#include "d3d8_device.h"
|
#include "d3d8_device.h"
|
||||||
#include "d3d8_texture.h"
|
#include "d3d8_texture.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
namespace dxvk
|
namespace dxvk
|
||||||
{
|
{
|
||||||
D3D8Interface::D3D8Interface() {
|
D3D8Interface::D3D8Interface() {
|
||||||
m_d3d9 = d3d9::Direct3DCreate9(D3D_SDK_VERSION);
|
m_d3d9 = d3d9::Direct3DCreate9(D3D_SDK_VERSION);
|
||||||
|
|
||||||
// Get the bridge interface to D3D9.
|
// Get the bridge interface to D3D9.
|
||||||
if (FAILED(m_d3d9->QueryInterface(__uuidof(IDxvkD3D8InterfaceBridge), (void**)&m_bridge))) {
|
if (FAILED(m_d3d9->QueryInterface(__uuidof(IDxvkD3D8InterfaceBridge), (void**)&m_bridge))) {
|
||||||
throw DxvkError("D3D8Device: ERROR! Failed to get D3D9 Bridge. d3d9.dll might not be DXVK!");
|
throw DxvkError("D3D8Device: ERROR! Failed to get D3D9 Bridge. d3d9.dll might not be DXVK!");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_bridge->SetD3D8CompatibilityMode(true);
|
m_bridge->SetD3D8CompatibilityMode(true);
|
||||||
|
|
||||||
m_d3d8Options = D3D8Options(*m_bridge->GetConfig());
|
m_d3d8Options = D3D8Options(*m_bridge->GetConfig());
|
||||||
|
|
||||||
m_adapterCount = m_d3d9->GetAdapterCount();
|
m_adapterCount = m_d3d9->GetAdapterCount();
|
||||||
m_adapterModeCounts.resize(m_adapterCount);
|
m_adapterModeCounts.resize(m_adapterCount);
|
||||||
m_adapterModes.reserve(m_adapterCount);
|
m_adapterModes.reserve(m_adapterCount);
|
||||||
|
|
||||||
for (UINT adapter = 0; adapter < m_adapterCount; adapter++) {
|
for (UINT adapter = 0; adapter < m_adapterCount; adapter++) {
|
||||||
m_adapterModes.emplace_back();
|
m_adapterModes.emplace_back();
|
||||||
|
|
||||||
// cache adapter modes and mode counts for each d3d9 format
|
// cache adapter modes and mode counts for each d3d9 format
|
||||||
for (d3d9::D3DFORMAT fmt : ADAPTER_FORMATS) {
|
for (d3d9::D3DFORMAT fmt : ADAPTER_FORMATS) {
|
||||||
|
|
||||||
const UINT modeCount = m_d3d9->GetAdapterModeCount(adapter, fmt);
|
const UINT modeCount = m_d3d9->GetAdapterModeCount(adapter, fmt);
|
||||||
for (UINT mode = 0; mode < modeCount; mode++) {
|
for (UINT mode = 0; mode < modeCount; mode++) {
|
||||||
|
|
||||||
m_adapterModes[adapter].emplace_back();
|
m_adapterModes[adapter].emplace_back();
|
||||||
m_d3d9->EnumAdapterModes(adapter, fmt, mode, &(m_adapterModes[adapter].back()));
|
m_d3d9->EnumAdapterModes(adapter, fmt, mode, &(m_adapterModes[adapter].back()));
|
||||||
|
|
||||||
// can't use modeCount as it's only for one fmt
|
// can't use modeCount as it's only for one fmt
|
||||||
m_adapterModeCounts[adapter]++;
|
m_adapterModeCounts[adapter]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE D3D8Interface::QueryInterface(REFIID riid, void** ppvObject) {
|
HRESULT STDMETHODCALLTYPE D3D8Interface::QueryInterface(REFIID riid, void** ppvObject) {
|
||||||
if (ppvObject == nullptr)
|
if (ppvObject == nullptr)
|
||||||
return E_POINTER;
|
return E_POINTER;
|
||||||
|
|
||||||
*ppvObject = nullptr;
|
*ppvObject = nullptr;
|
||||||
|
|
||||||
if (riid == __uuidof(IUnknown)
|
if (riid == __uuidof(IUnknown)
|
||||||
|| riid == __uuidof(IDirect3D8)) {
|
|| riid == __uuidof(IDirect3D8)) {
|
||||||
*ppvObject = ref(this);
|
*ppvObject = ref(this);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::warn("D3D8Interface::QueryInterface: Unknown interface query");
|
Logger::warn("D3D8Interface::QueryInterface: Unknown interface query");
|
||||||
Logger::warn(str::format(riid));
|
Logger::warn(str::format(riid));
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE D3D8Interface::GetAdapterIdentifier(
|
HRESULT STDMETHODCALLTYPE D3D8Interface::GetAdapterIdentifier(
|
||||||
UINT Adapter,
|
UINT Adapter,
|
||||||
DWORD Flags,
|
DWORD Flags,
|
||||||
D3DADAPTER_IDENTIFIER8* pIdentifier) {
|
D3DADAPTER_IDENTIFIER8* pIdentifier) {
|
||||||
if (unlikely(pIdentifier == nullptr))
|
if (unlikely(pIdentifier == nullptr))
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
// This flag now has the opposite effect.
|
// This flag now has the opposite effect.
|
||||||
// Either way, WHQLevel will be 1 with Direct3D9Ex
|
// Either way, WHQLevel will be 1 with Direct3D9Ex
|
||||||
if (Flags & D3DENUM_NO_WHQL_LEVEL)
|
if (Flags & D3DENUM_NO_WHQL_LEVEL)
|
||||||
Flags &= ~D3DENUM_WHQL_LEVEL;
|
Flags &= ~D3DENUM_WHQL_LEVEL;
|
||||||
else
|
else
|
||||||
Flags |= D3DENUM_WHQL_LEVEL;
|
Flags |= D3DENUM_WHQL_LEVEL;
|
||||||
|
|
||||||
d3d9::D3DADAPTER_IDENTIFIER9 identifier9;
|
d3d9::D3DADAPTER_IDENTIFIER9 identifier9;
|
||||||
HRESULT res = m_d3d9->GetAdapterIdentifier(Adapter, Flags, &identifier9);
|
HRESULT res = m_d3d9->GetAdapterIdentifier(Adapter, Flags, &identifier9);
|
||||||
|
|
||||||
if (likely(SUCCEEDED(res))) {
|
if (likely(SUCCEEDED(res))) {
|
||||||
strncpy(pIdentifier->Driver, identifier9.Driver, MAX_DEVICE_IDENTIFIER_STRING);
|
strncpy(pIdentifier->Driver, identifier9.Driver, MAX_DEVICE_IDENTIFIER_STRING);
|
||||||
strncpy(pIdentifier->Description, identifier9.Description, MAX_DEVICE_IDENTIFIER_STRING);
|
strncpy(pIdentifier->Description, identifier9.Description, MAX_DEVICE_IDENTIFIER_STRING);
|
||||||
|
|
||||||
pIdentifier->DriverVersion = identifier9.DriverVersion;
|
pIdentifier->DriverVersion = identifier9.DriverVersion;
|
||||||
pIdentifier->VendorId = identifier9.VendorId;
|
pIdentifier->VendorId = identifier9.VendorId;
|
||||||
pIdentifier->DeviceId = identifier9.DeviceId;
|
pIdentifier->DeviceId = identifier9.DeviceId;
|
||||||
pIdentifier->SubSysId = identifier9.SubSysId;
|
pIdentifier->SubSysId = identifier9.SubSysId;
|
||||||
pIdentifier->Revision = identifier9.Revision;
|
pIdentifier->Revision = identifier9.Revision;
|
||||||
pIdentifier->DeviceIdentifier = identifier9.DeviceIdentifier;
|
pIdentifier->DeviceIdentifier = identifier9.DeviceIdentifier;
|
||||||
|
|
||||||
pIdentifier->WHQLLevel = identifier9.WHQLLevel;
|
pIdentifier->WHQLLevel = identifier9.WHQLLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT __stdcall D3D8Interface::EnumAdapterModes(
|
HRESULT __stdcall D3D8Interface::EnumAdapterModes(
|
||||||
UINT Adapter,
|
UINT Adapter,
|
||||||
UINT Mode,
|
UINT Mode,
|
||||||
D3DDISPLAYMODE* pMode) {
|
D3DDISPLAYMODE* pMode) {
|
||||||
if (Adapter >= m_adapterCount || Mode >= m_adapterModeCounts[Adapter] || pMode == nullptr) {
|
if (Adapter >= m_adapterCount || Mode >= m_adapterModeCounts[Adapter] || pMode == nullptr) {
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pMode->Width = m_adapterModes[Adapter][Mode].Width;
|
pMode->Width = m_adapterModes[Adapter][Mode].Width;
|
||||||
pMode->Height = m_adapterModes[Adapter][Mode].Height;
|
pMode->Height = m_adapterModes[Adapter][Mode].Height;
|
||||||
pMode->RefreshRate = m_adapterModes[Adapter][Mode].RefreshRate;
|
pMode->RefreshRate = m_adapterModes[Adapter][Mode].RefreshRate;
|
||||||
pMode->Format = D3DFORMAT(m_adapterModes[Adapter][Mode].Format);
|
pMode->Format = D3DFORMAT(m_adapterModes[Adapter][Mode].Format);
|
||||||
|
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT __stdcall D3D8Interface::CreateDevice(
|
HRESULT __stdcall D3D8Interface::CreateDevice(
|
||||||
UINT Adapter,
|
UINT Adapter,
|
||||||
D3DDEVTYPE DeviceType,
|
D3DDEVTYPE DeviceType,
|
||||||
HWND hFocusWindow,
|
HWND hFocusWindow,
|
||||||
DWORD BehaviorFlags,
|
DWORD BehaviorFlags,
|
||||||
D3DPRESENT_PARAMETERS* pPresentationParameters,
|
D3DPRESENT_PARAMETERS* pPresentationParameters,
|
||||||
IDirect3DDevice8** ppReturnedDeviceInterface) {
|
IDirect3DDevice8** ppReturnedDeviceInterface) {
|
||||||
InitReturnPtr(ppReturnedDeviceInterface);
|
InitReturnPtr(ppReturnedDeviceInterface);
|
||||||
|
|
||||||
if (unlikely(pPresentationParameters == nullptr ||
|
if (unlikely(pPresentationParameters == nullptr ||
|
||||||
ppReturnedDeviceInterface == nullptr))
|
ppReturnedDeviceInterface == nullptr))
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
// D3DSWAPEFFECT_COPY can not be used with more than one back buffer.
|
// D3DSWAPEFFECT_COPY can not be used with more than one back buffer.
|
||||||
// This is also technically true for D3DSWAPEFFECT_COPY_VSYNC, however
|
// This is also technically true for D3DSWAPEFFECT_COPY_VSYNC, however
|
||||||
// RC Cars depends on it not being rejected.
|
// RC Cars depends on it not being rejected.
|
||||||
if (unlikely(pPresentationParameters->SwapEffect == D3DSWAPEFFECT_COPY
|
if (unlikely(pPresentationParameters->SwapEffect == D3DSWAPEFFECT_COPY
|
||||||
&& pPresentationParameters->BackBufferCount > 1))
|
&& pPresentationParameters->BackBufferCount > 1))
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
Com<d3d9::IDirect3DDevice9> pDevice9 = nullptr;
|
Com<d3d9::IDirect3DDevice9> pDevice9 = nullptr;
|
||||||
d3d9::D3DPRESENT_PARAMETERS params = ConvertPresentParameters9(pPresentationParameters);
|
d3d9::D3DPRESENT_PARAMETERS params = ConvertPresentParameters9(pPresentationParameters);
|
||||||
HRESULT res = m_d3d9->CreateDevice(
|
HRESULT res = m_d3d9->CreateDevice(
|
||||||
Adapter,
|
Adapter,
|
||||||
(d3d9::D3DDEVTYPE)DeviceType,
|
(d3d9::D3DDEVTYPE)DeviceType,
|
||||||
hFocusWindow,
|
hFocusWindow,
|
||||||
BehaviorFlags,
|
BehaviorFlags,
|
||||||
¶ms,
|
¶ms,
|
||||||
&pDevice9
|
&pDevice9
|
||||||
);
|
);
|
||||||
|
|
||||||
if (likely(SUCCEEDED(res)))
|
if (likely(SUCCEEDED(res)))
|
||||||
*ppReturnedDeviceInterface = ref(new D3D8Device(
|
*ppReturnedDeviceInterface = ref(new D3D8Device(
|
||||||
this, std::move(pDevice9),
|
this, std::move(pDevice9),
|
||||||
DeviceType, hFocusWindow, BehaviorFlags,
|
DeviceType, hFocusWindow, BehaviorFlags,
|
||||||
pPresentationParameters
|
pPresentationParameters
|
||||||
));
|
));
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,172 +1,172 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "d3d8_include.h"
|
#include "d3d8_include.h"
|
||||||
#include "d3d8_d3d9_util.h"
|
#include "d3d8_d3d9_util.h"
|
||||||
#include "d3d8_options.h"
|
#include "d3d8_options.h"
|
||||||
#include "d3d8_format.h"
|
#include "d3d8_format.h"
|
||||||
#include "../d3d9/d3d9_bridge.h"
|
#include "../d3d9/d3d9_bridge.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief D3D8 interface implementation
|
* \brief D3D8 interface implementation
|
||||||
*
|
*
|
||||||
* Implements the IDirect3DDevice8 interfaces
|
* Implements the IDirect3DDevice8 interfaces
|
||||||
* which provides the way to get adapters and create other objects such as \ref IDirect3DDevice8.
|
* which provides the way to get adapters and create other objects such as \ref IDirect3DDevice8.
|
||||||
* similar to \ref DxgiFactory but for D3D8.
|
* similar to \ref DxgiFactory but for D3D8.
|
||||||
*/
|
*/
|
||||||
class D3D8Interface final : public ComObjectClamp<IDirect3D8> {
|
class D3D8Interface final : public ComObjectClamp<IDirect3D8> {
|
||||||
|
|
||||||
static constexpr d3d9::D3DFORMAT ADAPTER_FORMATS[] = {
|
static constexpr d3d9::D3DFORMAT ADAPTER_FORMATS[] = {
|
||||||
d3d9::D3DFMT_A1R5G5B5,
|
d3d9::D3DFMT_A1R5G5B5,
|
||||||
//d3d9::D3DFMT_A2R10G10B10, (not in D3D8)
|
//d3d9::D3DFMT_A2R10G10B10, (not in D3D8)
|
||||||
d3d9::D3DFMT_A8R8G8B8,
|
d3d9::D3DFMT_A8R8G8B8,
|
||||||
d3d9::D3DFMT_R5G6B5,
|
d3d9::D3DFMT_R5G6B5,
|
||||||
d3d9::D3DFMT_X1R5G5B5,
|
d3d9::D3DFMT_X1R5G5B5,
|
||||||
d3d9::D3DFMT_X8R8G8B8
|
d3d9::D3DFMT_X8R8G8B8
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
D3D8Interface();
|
D3D8Interface();
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
|
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE RegisterSoftwareDevice(void* pInitializeFunction) {
|
HRESULT STDMETHODCALLTYPE RegisterSoftwareDevice(void* pInitializeFunction) {
|
||||||
return m_d3d9->RegisterSoftwareDevice(pInitializeFunction);
|
return m_d3d9->RegisterSoftwareDevice(pInitializeFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT STDMETHODCALLTYPE GetAdapterCount() {
|
UINT STDMETHODCALLTYPE GetAdapterCount() {
|
||||||
return m_d3d9->GetAdapterCount();
|
return m_d3d9->GetAdapterCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE GetAdapterIdentifier(
|
HRESULT STDMETHODCALLTYPE GetAdapterIdentifier(
|
||||||
UINT Adapter,
|
UINT Adapter,
|
||||||
DWORD Flags,
|
DWORD Flags,
|
||||||
D3DADAPTER_IDENTIFIER8* pIdentifier);
|
D3DADAPTER_IDENTIFIER8* pIdentifier);
|
||||||
|
|
||||||
UINT STDMETHODCALLTYPE GetAdapterModeCount(UINT Adapter) {
|
UINT STDMETHODCALLTYPE GetAdapterModeCount(UINT Adapter) {
|
||||||
return m_adapterModeCounts[Adapter];
|
return m_adapterModeCounts[Adapter];
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE EnumAdapterModes(
|
HRESULT STDMETHODCALLTYPE EnumAdapterModes(
|
||||||
UINT Adapter,
|
UINT Adapter,
|
||||||
UINT Mode,
|
UINT Mode,
|
||||||
D3DDISPLAYMODE* pMode);
|
D3DDISPLAYMODE* pMode);
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE GetAdapterDisplayMode(UINT Adapter, D3DDISPLAYMODE* pMode) {
|
HRESULT STDMETHODCALLTYPE GetAdapterDisplayMode(UINT Adapter, D3DDISPLAYMODE* pMode) {
|
||||||
return m_d3d9->GetAdapterDisplayMode(Adapter, (d3d9::D3DDISPLAYMODE*)pMode);
|
return m_d3d9->GetAdapterDisplayMode(Adapter, (d3d9::D3DDISPLAYMODE*)pMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CheckDeviceType(
|
HRESULT STDMETHODCALLTYPE CheckDeviceType(
|
||||||
UINT Adapter,
|
UINT Adapter,
|
||||||
D3DDEVTYPE DevType,
|
D3DDEVTYPE DevType,
|
||||||
D3DFORMAT AdapterFormat,
|
D3DFORMAT AdapterFormat,
|
||||||
D3DFORMAT BackBufferFormat,
|
D3DFORMAT BackBufferFormat,
|
||||||
BOOL bWindowed) {
|
BOOL bWindowed) {
|
||||||
// Ignore the bWindowed parameter when querying D3D9. D3D8 does
|
// Ignore the bWindowed parameter when querying D3D9. D3D8 does
|
||||||
// identical validations between windowed and fullscreen modes, adhering
|
// identical validations between windowed and fullscreen modes, adhering
|
||||||
// to the stricter fullscreen adapter and back buffer format validations.
|
// to the stricter fullscreen adapter and back buffer format validations.
|
||||||
return m_d3d9->CheckDeviceType(
|
return m_d3d9->CheckDeviceType(
|
||||||
Adapter,
|
Adapter,
|
||||||
(d3d9::D3DDEVTYPE)DevType,
|
(d3d9::D3DDEVTYPE)DevType,
|
||||||
(d3d9::D3DFORMAT)AdapterFormat,
|
(d3d9::D3DFORMAT)AdapterFormat,
|
||||||
(d3d9::D3DFORMAT)BackBufferFormat,
|
(d3d9::D3DFORMAT)BackBufferFormat,
|
||||||
FALSE
|
FALSE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CheckDeviceFormat(
|
HRESULT STDMETHODCALLTYPE CheckDeviceFormat(
|
||||||
UINT Adapter,
|
UINT Adapter,
|
||||||
D3DDEVTYPE DeviceType,
|
D3DDEVTYPE DeviceType,
|
||||||
D3DFORMAT AdapterFormat,
|
D3DFORMAT AdapterFormat,
|
||||||
DWORD Usage,
|
DWORD Usage,
|
||||||
D3DRESOURCETYPE RType,
|
D3DRESOURCETYPE RType,
|
||||||
D3DFORMAT CheckFormat) {
|
D3DFORMAT CheckFormat) {
|
||||||
return m_d3d9->CheckDeviceFormat(
|
return m_d3d9->CheckDeviceFormat(
|
||||||
Adapter,
|
Adapter,
|
||||||
(d3d9::D3DDEVTYPE)DeviceType,
|
(d3d9::D3DDEVTYPE)DeviceType,
|
||||||
(d3d9::D3DFORMAT)AdapterFormat,
|
(d3d9::D3DFORMAT)AdapterFormat,
|
||||||
Usage,
|
Usage,
|
||||||
(d3d9::D3DRESOURCETYPE)RType,
|
(d3d9::D3DRESOURCETYPE)RType,
|
||||||
(d3d9::D3DFORMAT)CheckFormat
|
(d3d9::D3DFORMAT)CheckFormat
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CheckDeviceMultiSampleType(
|
HRESULT STDMETHODCALLTYPE CheckDeviceMultiSampleType(
|
||||||
UINT Adapter,
|
UINT Adapter,
|
||||||
D3DDEVTYPE DeviceType,
|
D3DDEVTYPE DeviceType,
|
||||||
D3DFORMAT SurfaceFormat,
|
D3DFORMAT SurfaceFormat,
|
||||||
BOOL Windowed,
|
BOOL Windowed,
|
||||||
D3DMULTISAMPLE_TYPE MultiSampleType) {
|
D3DMULTISAMPLE_TYPE MultiSampleType) {
|
||||||
DWORD* pQualityLevels = nullptr;
|
DWORD* pQualityLevels = nullptr;
|
||||||
return m_d3d9->CheckDeviceMultiSampleType(
|
return m_d3d9->CheckDeviceMultiSampleType(
|
||||||
Adapter,
|
Adapter,
|
||||||
(d3d9::D3DDEVTYPE)DeviceType,
|
(d3d9::D3DDEVTYPE)DeviceType,
|
||||||
(d3d9::D3DFORMAT)SurfaceFormat,
|
(d3d9::D3DFORMAT)SurfaceFormat,
|
||||||
Windowed,
|
Windowed,
|
||||||
(d3d9::D3DMULTISAMPLE_TYPE)MultiSampleType,
|
(d3d9::D3DMULTISAMPLE_TYPE)MultiSampleType,
|
||||||
pQualityLevels
|
pQualityLevels
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CheckDepthStencilMatch(
|
HRESULT STDMETHODCALLTYPE CheckDepthStencilMatch(
|
||||||
UINT Adapter,
|
UINT Adapter,
|
||||||
D3DDEVTYPE DeviceType,
|
D3DDEVTYPE DeviceType,
|
||||||
D3DFORMAT AdapterFormat,
|
D3DFORMAT AdapterFormat,
|
||||||
D3DFORMAT RenderTargetFormat,
|
D3DFORMAT RenderTargetFormat,
|
||||||
D3DFORMAT DepthStencilFormat) {
|
D3DFORMAT DepthStencilFormat) {
|
||||||
if (isSupportedDepthStencilFormat(DepthStencilFormat))
|
if (isSupportedDepthStencilFormat(DepthStencilFormat))
|
||||||
return m_d3d9->CheckDepthStencilMatch(
|
return m_d3d9->CheckDepthStencilMatch(
|
||||||
Adapter,
|
Adapter,
|
||||||
(d3d9::D3DDEVTYPE)DeviceType,
|
(d3d9::D3DDEVTYPE)DeviceType,
|
||||||
(d3d9::D3DFORMAT)AdapterFormat,
|
(d3d9::D3DFORMAT)AdapterFormat,
|
||||||
(d3d9::D3DFORMAT)RenderTargetFormat,
|
(d3d9::D3DFORMAT)RenderTargetFormat,
|
||||||
(d3d9::D3DFORMAT)DepthStencilFormat
|
(d3d9::D3DFORMAT)DepthStencilFormat
|
||||||
);
|
);
|
||||||
|
|
||||||
return D3DERR_NOTAVAILABLE;
|
return D3DERR_NOTAVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE GetDeviceCaps(
|
HRESULT STDMETHODCALLTYPE GetDeviceCaps(
|
||||||
UINT Adapter,
|
UINT Adapter,
|
||||||
D3DDEVTYPE DeviceType,
|
D3DDEVTYPE DeviceType,
|
||||||
D3DCAPS8* pCaps) {
|
D3DCAPS8* pCaps) {
|
||||||
if (unlikely(pCaps == nullptr))
|
if (unlikely(pCaps == nullptr))
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
d3d9::D3DCAPS9 caps9;
|
d3d9::D3DCAPS9 caps9;
|
||||||
HRESULT res = m_d3d9->GetDeviceCaps(Adapter, (d3d9::D3DDEVTYPE)DeviceType, &caps9);
|
HRESULT res = m_d3d9->GetDeviceCaps(Adapter, (d3d9::D3DDEVTYPE)DeviceType, &caps9);
|
||||||
|
|
||||||
if (likely(SUCCEEDED(res)))
|
if (likely(SUCCEEDED(res)))
|
||||||
dxvk::ConvertCaps8(caps9, pCaps);
|
dxvk::ConvertCaps8(caps9, pCaps);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
HMONITOR STDMETHODCALLTYPE GetAdapterMonitor(UINT Adapter) {
|
HMONITOR STDMETHODCALLTYPE GetAdapterMonitor(UINT Adapter) {
|
||||||
return m_d3d9->GetAdapterMonitor(Adapter);
|
return m_d3d9->GetAdapterMonitor(Adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CreateDevice(
|
HRESULT STDMETHODCALLTYPE CreateDevice(
|
||||||
UINT Adapter,
|
UINT Adapter,
|
||||||
D3DDEVTYPE DeviceType,
|
D3DDEVTYPE DeviceType,
|
||||||
HWND hFocusWindow,
|
HWND hFocusWindow,
|
||||||
DWORD BehaviorFlags,
|
DWORD BehaviorFlags,
|
||||||
D3DPRESENT_PARAMETERS* pPresentationParameters,
|
D3DPRESENT_PARAMETERS* pPresentationParameters,
|
||||||
IDirect3DDevice8** ppReturnedDeviceInterface);
|
IDirect3DDevice8** ppReturnedDeviceInterface);
|
||||||
|
|
||||||
|
|
||||||
const D3D8Options& GetOptions() { return m_d3d8Options; }
|
const D3D8Options& GetOptions() { return m_d3d8Options; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
UINT m_adapterCount;
|
UINT m_adapterCount;
|
||||||
std::vector<UINT> m_adapterModeCounts;
|
std::vector<UINT> m_adapterModeCounts;
|
||||||
std::vector<std::vector<d3d9::D3DDISPLAYMODE>> m_adapterModes;
|
std::vector<std::vector<d3d9::D3DDISPLAYMODE>> m_adapterModes;
|
||||||
|
|
||||||
Com<d3d9::IDirect3D9> m_d3d9;
|
Com<d3d9::IDirect3D9> m_d3d9;
|
||||||
Com<IDxvkD3D8InterfaceBridge> m_bridge;
|
Com<IDxvkD3D8InterfaceBridge> m_bridge;
|
||||||
D3D8Options m_d3d8Options;
|
D3D8Options m_d3d8Options;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -1,111 +1,111 @@
|
|||||||
#include "d3d8_interface.h"
|
#include "d3d8_interface.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
Logger Logger::s_instance("d3d8.log");
|
Logger Logger::s_instance("d3d8.log");
|
||||||
|
|
||||||
HRESULT CreateD3D8(IDirect3D8** ppDirect3D8) {
|
HRESULT CreateD3D8(IDirect3D8** ppDirect3D8) {
|
||||||
if (!ppDirect3D8)
|
if (!ppDirect3D8)
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
*ppDirect3D8 = ref(new D3D8Interface());
|
*ppDirect3D8 = ref(new D3D8Interface());
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
DLLEXPORT HRESULT __stdcall ValidatePixelShader(
|
DLLEXPORT HRESULT __stdcall ValidatePixelShader(
|
||||||
const DWORD* pPixelShader,
|
const DWORD* pPixelShader,
|
||||||
const D3DCAPS8* pCaps,
|
const D3DCAPS8* pCaps,
|
||||||
BOOL errorReturn,
|
BOOL errorReturn,
|
||||||
char** pErrorString) {
|
char** pErrorString) {
|
||||||
std::string errorMessage = "";
|
std::string errorMessage = "";
|
||||||
|
|
||||||
if (unlikely(pPixelShader == nullptr)) {
|
if (unlikely(pPixelShader == nullptr)) {
|
||||||
errorMessage = "D3D8: ValidatePixelShader: Null pPixelShader";
|
errorMessage = "D3D8: ValidatePixelShader: Null pPixelShader";
|
||||||
} else {
|
} else {
|
||||||
uint32_t majorVersion = (pPixelShader[0] >> 8) & 0xff;
|
uint32_t majorVersion = (pPixelShader[0] >> 8) & 0xff;
|
||||||
uint32_t minorVersion = pPixelShader[0] & 0xff;
|
uint32_t minorVersion = pPixelShader[0] & 0xff;
|
||||||
|
|
||||||
if (unlikely(majorVersion != 1 || minorVersion > 4)) {
|
if (unlikely(majorVersion != 1 || minorVersion > 4)) {
|
||||||
errorMessage = dxvk::str::format("D3D8: ValidatePixelShader: Unsupported PS version ",
|
errorMessage = dxvk::str::format("D3D8: ValidatePixelShader: Unsupported PS version ",
|
||||||
majorVersion, ".", minorVersion);
|
majorVersion, ".", minorVersion);
|
||||||
} else if (unlikely(pCaps && pPixelShader[0] > pCaps->PixelShaderVersion)) {
|
} else if (unlikely(pCaps && pPixelShader[0] > pCaps->PixelShaderVersion)) {
|
||||||
errorMessage = dxvk::str::format("D3D8: ValidatePixelShader: Caps: Unsupported PS version ",
|
errorMessage = dxvk::str::format("D3D8: ValidatePixelShader: Caps: Unsupported PS version ",
|
||||||
majorVersion, ".", minorVersion);
|
majorVersion, ".", minorVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t errorMessageSize = errorMessage.size() + 1;
|
const size_t errorMessageSize = errorMessage.size() + 1;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (pErrorString != nullptr && errorReturn) {
|
if (pErrorString != nullptr && errorReturn) {
|
||||||
// Wine tests call HeapFree() on the returned error string,
|
// Wine tests call HeapFree() on the returned error string,
|
||||||
// so the expectation is for it to be allocated on the heap.
|
// so the expectation is for it to be allocated on the heap.
|
||||||
*pErrorString = (char*) HeapAlloc(GetProcessHeap(), 0, errorMessageSize);
|
*pErrorString = (char*) HeapAlloc(GetProcessHeap(), 0, errorMessageSize);
|
||||||
if (*pErrorString)
|
if (*pErrorString)
|
||||||
memcpy(*pErrorString, errorMessage.c_str(), errorMessageSize);
|
memcpy(*pErrorString, errorMessage.c_str(), errorMessageSize);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (errorMessageSize > 1) {
|
if (errorMessageSize > 1) {
|
||||||
dxvk::Logger::warn(errorMessage);
|
dxvk::Logger::warn(errorMessage);
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
DLLEXPORT HRESULT __stdcall ValidateVertexShader(
|
DLLEXPORT HRESULT __stdcall ValidateVertexShader(
|
||||||
const DWORD* pVertexShader,
|
const DWORD* pVertexShader,
|
||||||
const DWORD* pVertexDecl,
|
const DWORD* pVertexDecl,
|
||||||
const D3DCAPS8* pCaps,
|
const D3DCAPS8* pCaps,
|
||||||
BOOL errorReturn,
|
BOOL errorReturn,
|
||||||
char** pErrorString) {
|
char** pErrorString) {
|
||||||
std::string errorMessage = "";
|
std::string errorMessage = "";
|
||||||
|
|
||||||
if (unlikely(pVertexShader == nullptr)) {
|
if (unlikely(pVertexShader == nullptr)) {
|
||||||
errorMessage = "D3D8: ValidateVertexShader: Null pVertexShader";
|
errorMessage = "D3D8: ValidateVertexShader: Null pVertexShader";
|
||||||
} else {
|
} else {
|
||||||
uint32_t majorVersion = (pVertexShader[0] >> 8) & 0xff;
|
uint32_t majorVersion = (pVertexShader[0] >> 8) & 0xff;
|
||||||
uint32_t minorVersion = pVertexShader[0] & 0xff;
|
uint32_t minorVersion = pVertexShader[0] & 0xff;
|
||||||
|
|
||||||
if (unlikely(majorVersion != 1 || minorVersion > 1)) {
|
if (unlikely(majorVersion != 1 || minorVersion > 1)) {
|
||||||
errorMessage = dxvk::str::format("D3D8: ValidateVertexShader: Unsupported VS version ",
|
errorMessage = dxvk::str::format("D3D8: ValidateVertexShader: Unsupported VS version ",
|
||||||
majorVersion, ".", minorVersion);
|
majorVersion, ".", minorVersion);
|
||||||
} else if (unlikely(pCaps && pVertexShader[0] > pCaps->VertexShaderVersion)) {
|
} else if (unlikely(pCaps && pVertexShader[0] > pCaps->VertexShaderVersion)) {
|
||||||
errorMessage = dxvk::str::format("D3D8: ValidateVertexShader: Caps: Unsupported VS version ",
|
errorMessage = dxvk::str::format("D3D8: ValidateVertexShader: Caps: Unsupported VS version ",
|
||||||
majorVersion, ".", minorVersion);
|
majorVersion, ".", minorVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t errorMessageSize = errorMessage.size() + 1;
|
const size_t errorMessageSize = errorMessage.size() + 1;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (pErrorString != nullptr && errorReturn) {
|
if (pErrorString != nullptr && errorReturn) {
|
||||||
// Wine tests call HeapFree() on the returned error string,
|
// Wine tests call HeapFree() on the returned error string,
|
||||||
// so the expectation is for it to be allocated on the heap.
|
// so the expectation is for it to be allocated on the heap.
|
||||||
*pErrorString = (char*) HeapAlloc(GetProcessHeap(), 0, errorMessageSize);
|
*pErrorString = (char*) HeapAlloc(GetProcessHeap(), 0, errorMessageSize);
|
||||||
if (*pErrorString)
|
if (*pErrorString)
|
||||||
memcpy(*pErrorString, errorMessage.c_str(), errorMessageSize);
|
memcpy(*pErrorString, errorMessage.c_str(), errorMessageSize);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (errorMessageSize > 1) {
|
if (errorMessageSize > 1) {
|
||||||
dxvk::Logger::warn(errorMessage);
|
dxvk::Logger::warn(errorMessage);
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
DLLEXPORT void __stdcall DebugSetMute() {}
|
DLLEXPORT void __stdcall DebugSetMute() {}
|
||||||
|
|
||||||
DLLEXPORT IDirect3D8* __stdcall Direct3DCreate8(UINT nSDKVersion) {
|
DLLEXPORT IDirect3D8* __stdcall Direct3DCreate8(UINT nSDKVersion) {
|
||||||
IDirect3D8* pDirect3D = nullptr;
|
IDirect3D8* pDirect3D = nullptr;
|
||||||
dxvk::CreateD3D8(&pDirect3D);
|
dxvk::CreateD3D8(&pDirect3D);
|
||||||
|
|
||||||
return pDirect3D;
|
return pDirect3D;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,56 +1,56 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "d3d8_include.h"
|
#include "d3d8_include.h"
|
||||||
#include "../d3d9/d3d9_bridge.h"
|
#include "../d3d9/d3d9_bridge.h"
|
||||||
#include "../util/config/config.h"
|
#include "../util/config/config.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
struct D3D8Options {
|
struct D3D8Options {
|
||||||
|
|
||||||
/// Some games rely on undefined behavior by using undeclared vertex shader inputs.
|
/// Some games rely on undefined behavior by using undeclared vertex shader inputs.
|
||||||
/// The simplest way to fix them is to simply modify their vertex shader decl.
|
/// The simplest way to fix them is to simply modify their vertex shader decl.
|
||||||
///
|
///
|
||||||
/// This option takes a comma-separated list of colon-separated number pairs, where
|
/// This option takes a comma-separated list of colon-separated number pairs, where
|
||||||
/// the first number is a D3DVSDE_REGISTER value, the second is a D3DVSDT_TYPE value.
|
/// the first number is a D3DVSDE_REGISTER value, the second is a D3DVSDT_TYPE value.
|
||||||
/// e.g. "0:2,3:2,7:1" for float3 position : v0, float3 normal : v3, float2 uv : v7
|
/// e.g. "0:2,3:2,7:1" for float3 position : v0, float3 normal : v3, float2 uv : v7
|
||||||
std::vector<std::pair<D3DVSDE_REGISTER, D3DVSDT_TYPE>> forceVsDecl;
|
std::vector<std::pair<D3DVSDE_REGISTER, D3DVSDT_TYPE>> forceVsDecl;
|
||||||
|
|
||||||
/// Specialized drawcall batcher, typically for games that draw a lot of similar
|
/// Specialized drawcall batcher, typically for games that draw a lot of similar
|
||||||
/// geometry in separate drawcalls (sometimes even one triangle at a time).
|
/// geometry in separate drawcalls (sometimes even one triangle at a time).
|
||||||
///
|
///
|
||||||
/// May hurt performance outside of specifc games that benefit from it.
|
/// May hurt performance outside of specifc games that benefit from it.
|
||||||
bool batching = false;
|
bool batching = false;
|
||||||
|
|
||||||
/// The Lord of the Rings: The Fellowship of the Ring tries to create a P8 texture
|
/// The Lord of the Rings: The Fellowship of the Ring tries to create a P8 texture
|
||||||
/// in D3DPOOL_MANAGED on Nvidia and Intel, which fails, but has a separate code
|
/// in D3DPOOL_MANAGED on Nvidia and Intel, which fails, but has a separate code
|
||||||
/// path for ATI/AMD that creates it in D3DPOOL_SCRATCH instead, which works.
|
/// path for ATI/AMD that creates it in D3DPOOL_SCRATCH instead, which works.
|
||||||
///
|
///
|
||||||
/// The internal logic determining this path doesn't seem to be d3d-related, but
|
/// The internal logic determining this path doesn't seem to be d3d-related, but
|
||||||
/// the game works universally if we mimic its own ATI/AMD workaround during P8
|
/// the game works universally if we mimic its own ATI/AMD workaround during P8
|
||||||
/// texture creation.
|
/// texture creation.
|
||||||
///
|
///
|
||||||
/// Early Nvidia GPUs, such as the GeForce 4 generation cards, included and exposed
|
/// Early Nvidia GPUs, such as the GeForce 4 generation cards, included and exposed
|
||||||
/// P8 texture support. However, it was no longer advertised with cards in the FX series
|
/// P8 texture support. However, it was no longer advertised with cards in the FX series
|
||||||
/// and above. Most likely ATI/AMD drivers never supported P8 in the first place.
|
/// and above. Most likely ATI/AMD drivers never supported P8 in the first place.
|
||||||
bool placeP8InScratch = false;
|
bool placeP8InScratch = false;
|
||||||
|
|
||||||
/// Rayman 3 relies on D3DLOCK_DISCARD being ignored for everything except D3DUSAGE_DYNAMIC +
|
/// Rayman 3 relies on D3DLOCK_DISCARD being ignored for everything except D3DUSAGE_DYNAMIC +
|
||||||
/// D3DUSAGE_WRITEONLY buffers, however this approach incurs a performance penalty.
|
/// D3DUSAGE_WRITEONLY buffers, however this approach incurs a performance penalty.
|
||||||
///
|
///
|
||||||
/// Some titles might abuse this early D3D8 quirk, however at some point in its history
|
/// Some titles might abuse this early D3D8 quirk, however at some point in its history
|
||||||
/// it was brought in line with standard D3D9 behavior.
|
/// it was brought in line with standard D3D9 behavior.
|
||||||
bool forceLegacyDiscard = false;
|
bool forceLegacyDiscard = false;
|
||||||
|
|
||||||
D3D8Options() {}
|
D3D8Options() {}
|
||||||
D3D8Options(const Config& config) {
|
D3D8Options(const Config& config) {
|
||||||
auto forceVsDeclStr = config.getOption<std::string>("d3d8.forceVsDecl", "");
|
auto forceVsDeclStr = config.getOption<std::string>("d3d8.forceVsDecl", "");
|
||||||
batching = config.getOption<bool> ("d3d8.batching", batching);
|
batching = config.getOption<bool> ("d3d8.batching", batching);
|
||||||
placeP8InScratch = config.getOption<bool> ("d3d8.placeP8InScratch", placeP8InScratch);
|
placeP8InScratch = config.getOption<bool> ("d3d8.placeP8InScratch", placeP8InScratch);
|
||||||
forceLegacyDiscard = config.getOption<bool> ("d3d8.forceLegacyDiscard", forceLegacyDiscard);
|
forceLegacyDiscard = config.getOption<bool> ("d3d8.forceLegacyDiscard", forceLegacyDiscard);
|
||||||
|
|
||||||
parseVsDecl(forceVsDeclStr);
|
parseVsDecl(forceVsDeclStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseVsDecl(const std::string& decl);
|
void parseVsDecl(const std::string& decl);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,111 +1,111 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/** Implements IDirect3DResource8
|
/** Implements IDirect3DResource8
|
||||||
*
|
*
|
||||||
* - SetPrivateData, GetPrivateData, FreePrivateData
|
* - SetPrivateData, GetPrivateData, FreePrivateData
|
||||||
* - SetPriority, GetPriority
|
* - SetPriority, GetPriority
|
||||||
*
|
*
|
||||||
* - Subclasses provide: PreLoad, GetType
|
* - Subclasses provide: PreLoad, GetType
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "d3d8_device_child.h"
|
#include "d3d8_device_child.h"
|
||||||
#include "../util/com/com_private_data.h"
|
#include "../util/com/com_private_data.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
template <typename D3D9, typename D3D8>
|
template <typename D3D9, typename D3D8>
|
||||||
class D3D8Resource : public D3D8DeviceChild<D3D9, D3D8> {
|
class D3D8Resource : public D3D8DeviceChild<D3D9, D3D8> {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
D3D8Resource(D3D8Device* pDevice, Com<D3D9>&& Object)
|
D3D8Resource(D3D8Device* pDevice, Com<D3D9>&& Object)
|
||||||
: D3D8DeviceChild<D3D9, D3D8>(pDevice, std::move(Object))
|
: D3D8DeviceChild<D3D9, D3D8>(pDevice, std::move(Object))
|
||||||
, m_priority ( 0 ) { }
|
, m_priority ( 0 ) { }
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE SetPrivateData(
|
HRESULT STDMETHODCALLTYPE SetPrivateData(
|
||||||
REFGUID refguid,
|
REFGUID refguid,
|
||||||
const void* pData,
|
const void* pData,
|
||||||
DWORD SizeOfData,
|
DWORD SizeOfData,
|
||||||
DWORD Flags) final {
|
DWORD Flags) final {
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
if (Flags & D3DSPD_IUNKNOWN) {
|
if (Flags & D3DSPD_IUNKNOWN) {
|
||||||
if(unlikely(SizeOfData != sizeof(IUnknown*)))
|
if(unlikely(SizeOfData != sizeof(IUnknown*)))
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
IUnknown* unknown =
|
IUnknown* unknown =
|
||||||
const_cast<IUnknown*>(
|
const_cast<IUnknown*>(
|
||||||
reinterpret_cast<const IUnknown*>(pData));
|
reinterpret_cast<const IUnknown*>(pData));
|
||||||
hr = m_privateData.setInterface(
|
hr = m_privateData.setInterface(
|
||||||
refguid, unknown);
|
refguid, unknown);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
hr = m_privateData.setData(
|
hr = m_privateData.setData(
|
||||||
refguid, SizeOfData, pData);
|
refguid, SizeOfData, pData);
|
||||||
|
|
||||||
if (unlikely(FAILED(hr)))
|
if (unlikely(FAILED(hr)))
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE GetPrivateData(
|
HRESULT STDMETHODCALLTYPE GetPrivateData(
|
||||||
REFGUID refguid,
|
REFGUID refguid,
|
||||||
void* pData,
|
void* pData,
|
||||||
DWORD* pSizeOfData) final {
|
DWORD* pSizeOfData) final {
|
||||||
if (unlikely(pData == nullptr && pSizeOfData == nullptr))
|
if (unlikely(pData == nullptr && pSizeOfData == nullptr))
|
||||||
return D3DERR_NOTFOUND;
|
return D3DERR_NOTFOUND;
|
||||||
|
|
||||||
HRESULT hr = m_privateData.getData(
|
HRESULT hr = m_privateData.getData(
|
||||||
refguid, reinterpret_cast<UINT*>(pSizeOfData), pData);
|
refguid, reinterpret_cast<UINT*>(pSizeOfData), pData);
|
||||||
|
|
||||||
if (unlikely(FAILED(hr))) {
|
if (unlikely(FAILED(hr))) {
|
||||||
if(hr == DXGI_ERROR_MORE_DATA)
|
if(hr == DXGI_ERROR_MORE_DATA)
|
||||||
return D3DERR_MOREDATA;
|
return D3DERR_MOREDATA;
|
||||||
else if (hr == DXGI_ERROR_NOT_FOUND)
|
else if (hr == DXGI_ERROR_NOT_FOUND)
|
||||||
return D3DERR_NOTFOUND;
|
return D3DERR_NOTFOUND;
|
||||||
else
|
else
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE FreePrivateData(REFGUID refguid) final {
|
HRESULT STDMETHODCALLTYPE FreePrivateData(REFGUID refguid) final {
|
||||||
HRESULT hr = m_privateData.setData(refguid, 0, nullptr);
|
HRESULT hr = m_privateData.setData(refguid, 0, nullptr);
|
||||||
|
|
||||||
if (unlikely(FAILED(hr)))
|
if (unlikely(FAILED(hr)))
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD STDMETHODCALLTYPE SetPriority(DWORD PriorityNew) {
|
DWORD STDMETHODCALLTYPE SetPriority(DWORD PriorityNew) {
|
||||||
DWORD oldPriority = m_priority;
|
DWORD oldPriority = m_priority;
|
||||||
m_priority = PriorityNew;
|
m_priority = PriorityNew;
|
||||||
return oldPriority;
|
return oldPriority;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD STDMETHODCALLTYPE GetPriority() {
|
DWORD STDMETHODCALLTYPE GetPriority() {
|
||||||
return m_priority;
|
return m_priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual IUnknown* GetInterface(REFIID riid) override try {
|
virtual IUnknown* GetInterface(REFIID riid) override try {
|
||||||
return D3D8DeviceChild<D3D9, D3D8>::GetInterface(riid);
|
return D3D8DeviceChild<D3D9, D3D8>::GetInterface(riid);
|
||||||
} catch (HRESULT err) {
|
} catch (HRESULT err) {
|
||||||
if (riid == __uuidof(IDirect3DResource8))
|
if (riid == __uuidof(IDirect3DResource8))
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
DWORD m_priority;
|
DWORD m_priority;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
ComPrivateData m_privateData;
|
ComPrivateData m_privateData;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,155 +1,155 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "d3d8_caps.h"
|
#include "d3d8_caps.h"
|
||||||
#include "d3d8_include.h"
|
#include "d3d8_include.h"
|
||||||
#include "d3d8_device.h"
|
#include "d3d8_device.h"
|
||||||
#include "d3d8_device_child.h"
|
#include "d3d8_device_child.h"
|
||||||
|
|
||||||
#include "../util/util_bit.h"
|
#include "../util/util_bit.h"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
struct D3D8StateCapture {
|
struct D3D8StateCapture {
|
||||||
bool vs : 1;
|
bool vs : 1;
|
||||||
bool ps : 1;
|
bool ps : 1;
|
||||||
bool indices : 1;
|
bool indices : 1;
|
||||||
bool swvp : 1;
|
bool swvp : 1;
|
||||||
|
|
||||||
bit::bitset<d8caps::MAX_TEXTURE_STAGES> textures;
|
bit::bitset<d8caps::MAX_TEXTURE_STAGES> textures;
|
||||||
bit::bitset<d8caps::MAX_STREAMS> streams;
|
bit::bitset<d8caps::MAX_STREAMS> streams;
|
||||||
|
|
||||||
D3D8StateCapture()
|
D3D8StateCapture()
|
||||||
: vs(false)
|
: vs(false)
|
||||||
, ps(false)
|
, ps(false)
|
||||||
, indices(false)
|
, indices(false)
|
||||||
, swvp(false) {
|
, swvp(false) {
|
||||||
// Ensure all bits are initialized to false
|
// Ensure all bits are initialized to false
|
||||||
textures.clearAll();
|
textures.clearAll();
|
||||||
streams.clearAll();
|
streams.clearAll();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Wrapper class for D3D9 state blocks. Captures D3D8-specific state.
|
// Wrapper class for D3D9 state blocks. Captures D3D8-specific state.
|
||||||
class D3D8StateBlock {
|
class D3D8StateBlock {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
D3D8StateBlock(
|
D3D8StateBlock(
|
||||||
D3D8Device* pDevice,
|
D3D8Device* pDevice,
|
||||||
D3DSTATEBLOCKTYPE Type,
|
D3DSTATEBLOCKTYPE Type,
|
||||||
Com<d3d9::IDirect3DStateBlock9>&& pStateBlock)
|
Com<d3d9::IDirect3DStateBlock9>&& pStateBlock)
|
||||||
: m_device(pDevice)
|
: m_device(pDevice)
|
||||||
, m_stateBlock(std::move(pStateBlock))
|
, m_stateBlock(std::move(pStateBlock))
|
||||||
, m_type(Type) {
|
, m_type(Type) {
|
||||||
if (Type == D3DSBT_VERTEXSTATE || Type == D3DSBT_ALL) {
|
if (Type == D3DSBT_VERTEXSTATE || Type == D3DSBT_ALL) {
|
||||||
// Lights, D3DTSS_TEXCOORDINDEX and D3DTSS_TEXTURETRANSFORMFLAGS,
|
// Lights, D3DTSS_TEXCOORDINDEX and D3DTSS_TEXTURETRANSFORMFLAGS,
|
||||||
// vertex shader, VS constants, and various render states.
|
// vertex shader, VS constants, and various render states.
|
||||||
m_capture.vs = true;
|
m_capture.vs = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Type == D3DSBT_PIXELSTATE || Type == D3DSBT_ALL) {
|
if (Type == D3DSBT_PIXELSTATE || Type == D3DSBT_ALL) {
|
||||||
// Pixel shader, PS constants, and various RS/TSS states.
|
// Pixel shader, PS constants, and various RS/TSS states.
|
||||||
m_capture.ps = true;
|
m_capture.ps = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Type == D3DSBT_ALL) {
|
if (Type == D3DSBT_ALL) {
|
||||||
m_capture.indices = true;
|
m_capture.indices = true;
|
||||||
m_capture.swvp = true;
|
m_capture.swvp = true;
|
||||||
m_capture.textures.setAll();
|
m_capture.textures.setAll();
|
||||||
m_capture.streams.setAll();
|
m_capture.streams.setAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_textures.fill(nullptr);
|
m_textures.fill(nullptr);
|
||||||
m_streams.fill(D3D8VBOP());
|
m_streams.fill(D3D8VBOP());
|
||||||
}
|
}
|
||||||
|
|
||||||
~D3D8StateBlock() {}
|
~D3D8StateBlock() {}
|
||||||
|
|
||||||
// Construct a state block without a D3D9 object
|
// Construct a state block without a D3D9 object
|
||||||
D3D8StateBlock(D3D8Device* pDevice)
|
D3D8StateBlock(D3D8Device* pDevice)
|
||||||
: D3D8StateBlock(pDevice, D3DSTATEBLOCKTYPE(0), nullptr) {
|
: D3D8StateBlock(pDevice, D3DSTATEBLOCKTYPE(0), nullptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach a D3D9 object to a state block that doesn't have one yet
|
// Attach a D3D9 object to a state block that doesn't have one yet
|
||||||
void SetD3D9(Com<d3d9::IDirect3DStateBlock9>&& pStateBlock) {
|
void SetD3D9(Com<d3d9::IDirect3DStateBlock9>&& pStateBlock) {
|
||||||
if (likely(m_stateBlock == nullptr)) {
|
if (likely(m_stateBlock == nullptr)) {
|
||||||
m_stateBlock = std::move(pStateBlock);
|
m_stateBlock = std::move(pStateBlock);
|
||||||
} else {
|
} else {
|
||||||
Logger::err("D3D8StateBlock::SetD3D9: m_stateBlock has already been initialized");
|
Logger::err("D3D8StateBlock::SetD3D9: m_stateBlock has already been initialized");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT Capture();
|
HRESULT Capture();
|
||||||
|
|
||||||
HRESULT Apply();
|
HRESULT Apply();
|
||||||
|
|
||||||
inline HRESULT SetVertexShader(DWORD Handle) {
|
inline HRESULT SetVertexShader(DWORD Handle) {
|
||||||
m_vertexShader = Handle;
|
m_vertexShader = Handle;
|
||||||
m_capture.vs = true;
|
m_capture.vs = true;
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline HRESULT SetPixelShader(DWORD Handle) {
|
inline HRESULT SetPixelShader(DWORD Handle) {
|
||||||
m_pixelShader = Handle;
|
m_pixelShader = Handle;
|
||||||
m_capture.ps = true;
|
m_capture.ps = true;
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline HRESULT SetTexture(DWORD Stage, IDirect3DBaseTexture8* pTexture) {
|
inline HRESULT SetTexture(DWORD Stage, IDirect3DBaseTexture8* pTexture) {
|
||||||
m_textures[Stage] = pTexture;
|
m_textures[Stage] = pTexture;
|
||||||
m_capture.textures.set(Stage, true);
|
m_capture.textures.set(Stage, true);
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline HRESULT SetStreamSource(UINT StreamNumber, IDirect3DVertexBuffer8* pStreamData, UINT Stride) {
|
inline HRESULT SetStreamSource(UINT StreamNumber, IDirect3DVertexBuffer8* pStreamData, UINT Stride) {
|
||||||
m_streams[StreamNumber].buffer = pStreamData;
|
m_streams[StreamNumber].buffer = pStreamData;
|
||||||
// The previous stride is preserved if pStreamData is NULL
|
// The previous stride is preserved if pStreamData is NULL
|
||||||
if (likely(pStreamData != nullptr))
|
if (likely(pStreamData != nullptr))
|
||||||
m_streams[StreamNumber].stride = Stride;
|
m_streams[StreamNumber].stride = Stride;
|
||||||
m_capture.streams.set(StreamNumber, true);
|
m_capture.streams.set(StreamNumber, true);
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline HRESULT SetIndices(IDirect3DIndexBuffer8* pIndexData, UINT BaseVertexIndex) {
|
inline HRESULT SetIndices(IDirect3DIndexBuffer8* pIndexData, UINT BaseVertexIndex) {
|
||||||
m_indices = pIndexData;
|
m_indices = pIndexData;
|
||||||
m_baseVertexIndex = BaseVertexIndex;
|
m_baseVertexIndex = BaseVertexIndex;
|
||||||
m_capture.indices = true;
|
m_capture.indices = true;
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline HRESULT SetSoftwareVertexProcessing(bool value) {
|
inline HRESULT SetSoftwareVertexProcessing(bool value) {
|
||||||
m_isSWVP = value;
|
m_isSWVP = value;
|
||||||
m_capture.swvp = true;
|
m_capture.swvp = true;
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
D3D8Device* m_device;
|
D3D8Device* m_device;
|
||||||
Com<d3d9::IDirect3DStateBlock9> m_stateBlock;
|
Com<d3d9::IDirect3DStateBlock9> m_stateBlock;
|
||||||
D3DSTATEBLOCKTYPE m_type;
|
D3DSTATEBLOCKTYPE m_type;
|
||||||
|
|
||||||
struct D3D8VBOP {
|
struct D3D8VBOP {
|
||||||
IDirect3DVertexBuffer8* buffer = nullptr;
|
IDirect3DVertexBuffer8* buffer = nullptr;
|
||||||
UINT stride = 0;
|
UINT stride = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
private: // State Data //
|
private: // State Data //
|
||||||
|
|
||||||
D3D8StateCapture m_capture;
|
D3D8StateCapture m_capture;
|
||||||
|
|
||||||
DWORD m_vertexShader; // vs
|
DWORD m_vertexShader; // vs
|
||||||
DWORD m_pixelShader; // ps
|
DWORD m_pixelShader; // ps
|
||||||
|
|
||||||
std::array<IDirect3DBaseTexture8*, d8caps::MAX_TEXTURE_STAGES> m_textures; // textures
|
std::array<IDirect3DBaseTexture8*, d8caps::MAX_TEXTURE_STAGES> m_textures; // textures
|
||||||
std::array<D3D8VBOP, d8caps::MAX_STREAMS> m_streams; // stream data
|
std::array<D3D8VBOP, d8caps::MAX_STREAMS> m_streams; // stream data
|
||||||
|
|
||||||
IDirect3DIndexBuffer8* m_indices = nullptr; // indices
|
IDirect3DIndexBuffer8* m_indices = nullptr; // indices
|
||||||
UINT m_baseVertexIndex; // indices
|
UINT m_baseVertexIndex; // indices
|
||||||
|
|
||||||
bool m_isSWVP; // D3DRS_SOFTWAREVERTEXPROCESSING
|
bool m_isSWVP; // D3DRS_SOFTWAREVERTEXPROCESSING
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,87 +1,87 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "d3d8_include.h"
|
#include "d3d8_include.h"
|
||||||
#include "d3d8_subresource.h"
|
#include "d3d8_subresource.h"
|
||||||
#include "d3d8_d3d9_util.h"
|
#include "d3d8_d3d9_util.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
// TODO: all inherited methods in D3D8Surface should be final like in d9vk
|
// TODO: all inherited methods in D3D8Surface should be final like in d9vk
|
||||||
|
|
||||||
using D3D8SurfaceBase = D3D8Subresource<d3d9::IDirect3DSurface9, IDirect3DSurface8>;
|
using D3D8SurfaceBase = D3D8Subresource<d3d9::IDirect3DSurface9, IDirect3DSurface8>;
|
||||||
class D3D8Surface final : public D3D8SurfaceBase {
|
class D3D8Surface final : public D3D8SurfaceBase {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
D3D8Surface(
|
D3D8Surface(
|
||||||
D3D8Device* pDevice,
|
D3D8Device* pDevice,
|
||||||
IDirect3DBaseTexture8* pTexture,
|
IDirect3DBaseTexture8* pTexture,
|
||||||
Com<d3d9::IDirect3DSurface9>&& pSurface)
|
Com<d3d9::IDirect3DSurface9>&& pSurface)
|
||||||
: D3D8SurfaceBase (pDevice, std::move(pSurface), pTexture) {
|
: D3D8SurfaceBase (pDevice, std::move(pSurface), pTexture) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// A surface does not need to be attached to a texture
|
// A surface does not need to be attached to a texture
|
||||||
D3D8Surface(
|
D3D8Surface(
|
||||||
D3D8Device* pDevice,
|
D3D8Device* pDevice,
|
||||||
Com<d3d9::IDirect3DSurface9>&& pSurface)
|
Com<d3d9::IDirect3DSurface9>&& pSurface)
|
||||||
: D3D8Surface (pDevice, nullptr, std::move(pSurface)) {
|
: D3D8Surface (pDevice, nullptr, std::move(pSurface)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DRESOURCETYPE STDMETHODCALLTYPE GetType() {
|
D3DRESOURCETYPE STDMETHODCALLTYPE GetType() {
|
||||||
return D3DRESOURCETYPE(GetD3D9()->GetType());
|
return D3DRESOURCETYPE(GetD3D9()->GetType());
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE GetDesc(D3DSURFACE_DESC* pDesc) {
|
HRESULT STDMETHODCALLTYPE GetDesc(D3DSURFACE_DESC* pDesc) {
|
||||||
if (unlikely(pDesc == nullptr))
|
if (unlikely(pDesc == nullptr))
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
d3d9::D3DSURFACE_DESC desc;
|
d3d9::D3DSURFACE_DESC desc;
|
||||||
HRESULT res = GetD3D9()->GetDesc(&desc);
|
HRESULT res = GetD3D9()->GetDesc(&desc);
|
||||||
|
|
||||||
if (likely(SUCCEEDED(res)))
|
if (likely(SUCCEEDED(res)))
|
||||||
ConvertSurfaceDesc8(&desc, pDesc);
|
ConvertSurfaceDesc8(&desc, pDesc);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE LockRect(D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) {
|
HRESULT STDMETHODCALLTYPE LockRect(D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) {
|
||||||
return GetD3D9()->LockRect((d3d9::D3DLOCKED_RECT*)pLockedRect, pRect, Flags);
|
return GetD3D9()->LockRect((d3d9::D3DLOCKED_RECT*)pLockedRect, pRect, Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE UnlockRect() {
|
HRESULT STDMETHODCALLTYPE UnlockRect() {
|
||||||
return GetD3D9()->UnlockRect();
|
return GetD3D9()->UnlockRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE GetDC(HDC* phDC) {
|
HRESULT STDMETHODCALLTYPE GetDC(HDC* phDC) {
|
||||||
return GetD3D9()->GetDC(phDC);
|
return GetD3D9()->GetDC(phDC);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE ReleaseDC(HDC hDC) {
|
HRESULT STDMETHODCALLTYPE ReleaseDC(HDC hDC) {
|
||||||
return GetD3D9()->ReleaseDC(hDC);
|
return GetD3D9()->ReleaseDC(hDC);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Allocate or reuse an image of the same size
|
* \brief Allocate or reuse an image of the same size
|
||||||
* as this texture for performing blit into system mem.
|
* as this texture for performing blit into system mem.
|
||||||
*
|
*
|
||||||
* TODO: Consider creating only one texture to
|
* TODO: Consider creating only one texture to
|
||||||
* encompass all surface levels of a texture.
|
* encompass all surface levels of a texture.
|
||||||
*/
|
*/
|
||||||
Com<d3d9::IDirect3DSurface9> GetBlitImage() {
|
Com<d3d9::IDirect3DSurface9> GetBlitImage() {
|
||||||
if (unlikely(m_blitImage == nullptr)) {
|
if (unlikely(m_blitImage == nullptr)) {
|
||||||
m_blitImage = CreateBlitImage();
|
m_blitImage = CreateBlitImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_blitImage;
|
return m_blitImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Com<d3d9::IDirect3DSurface9> CreateBlitImage();
|
Com<d3d9::IDirect3DSurface9> CreateBlitImage();
|
||||||
|
|
||||||
Com<d3d9::IDirect3DSurface9> m_blitImage = nullptr;
|
Com<d3d9::IDirect3DSurface9> m_blitImage = nullptr;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -1,254 +1,254 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "d3d8_resource.h"
|
#include "d3d8_resource.h"
|
||||||
#include "d3d8_surface.h"
|
#include "d3d8_surface.h"
|
||||||
#include "d3d8_volume.h"
|
#include "d3d8_volume.h"
|
||||||
|
|
||||||
#include "d3d8_d3d9_util.h"
|
#include "d3d8_d3d9_util.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
template <typename SubresourceType, typename D3D9, typename D3D8>
|
template <typename SubresourceType, typename D3D9, typename D3D8>
|
||||||
class D3D8BaseTexture : public D3D8Resource<D3D9, D3D8> {
|
class D3D8BaseTexture : public D3D8Resource<D3D9, D3D8> {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
constexpr static UINT CUBE_FACES = 6;
|
constexpr static UINT CUBE_FACES = 6;
|
||||||
|
|
||||||
using SubresourceType8 = typename SubresourceType::D3D8;
|
using SubresourceType8 = typename SubresourceType::D3D8;
|
||||||
using SubresourceType9 = typename SubresourceType::D3D9;
|
using SubresourceType9 = typename SubresourceType::D3D9;
|
||||||
|
|
||||||
D3D8BaseTexture(
|
D3D8BaseTexture(
|
||||||
D3D8Device* pDevice,
|
D3D8Device* pDevice,
|
||||||
Com<D3D9>&& pBaseTexture,
|
Com<D3D9>&& pBaseTexture,
|
||||||
UINT SubresourceCount)
|
UINT SubresourceCount)
|
||||||
: D3D8Resource<D3D9, D3D8> ( pDevice, std::move(pBaseTexture) ) {
|
: D3D8Resource<D3D9, D3D8> ( pDevice, std::move(pBaseTexture) ) {
|
||||||
m_subresources.resize(SubresourceCount, nullptr);
|
m_subresources.resize(SubresourceCount, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
~D3D8BaseTexture() {
|
~D3D8BaseTexture() {
|
||||||
for (size_t i = 0; i < m_subresources.size(); i++)
|
for (size_t i = 0; i < m_subresources.size(); i++)
|
||||||
if (m_subresources[i] != nullptr)
|
if (m_subresources[i] != nullptr)
|
||||||
m_subresources[i] = nullptr;
|
m_subresources[i] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual IUnknown* GetInterface(REFIID riid) final override try {
|
virtual IUnknown* GetInterface(REFIID riid) final override try {
|
||||||
return D3D8Resource<D3D9, D3D8>::GetInterface(riid);
|
return D3D8Resource<D3D9, D3D8>::GetInterface(riid);
|
||||||
} catch (HRESULT err) {
|
} catch (HRESULT err) {
|
||||||
if (riid == __uuidof(IDirect3DBaseTexture8))
|
if (riid == __uuidof(IDirect3DBaseTexture8))
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void STDMETHODCALLTYPE PreLoad() final {
|
void STDMETHODCALLTYPE PreLoad() final {
|
||||||
this->GetD3D9()->PreLoad();
|
this->GetD3D9()->PreLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD STDMETHODCALLTYPE SetLOD(DWORD LODNew) final {
|
DWORD STDMETHODCALLTYPE SetLOD(DWORD LODNew) final {
|
||||||
return this->GetD3D9()->SetLOD(LODNew);
|
return this->GetD3D9()->SetLOD(LODNew);
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD STDMETHODCALLTYPE GetLOD() final {
|
DWORD STDMETHODCALLTYPE GetLOD() final {
|
||||||
return this->GetD3D9()->GetLOD();
|
return this->GetD3D9()->GetLOD();
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD STDMETHODCALLTYPE GetLevelCount() final {
|
DWORD STDMETHODCALLTYPE GetLevelCount() final {
|
||||||
return this->GetD3D9()->GetLevelCount();
|
return this->GetD3D9()->GetLevelCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE GetSubresource(UINT Index, SubresourceType8** ppSubresource) {
|
HRESULT STDMETHODCALLTYPE GetSubresource(UINT Index, SubresourceType8** ppSubresource) {
|
||||||
InitReturnPtr(ppSubresource);
|
InitReturnPtr(ppSubresource);
|
||||||
|
|
||||||
if (unlikely(ppSubresource == nullptr))
|
if (unlikely(ppSubresource == nullptr))
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
if (unlikely(Index >= m_subresources.size()))
|
if (unlikely(Index >= m_subresources.size()))
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
if (m_subresources[Index] == nullptr) {
|
if (m_subresources[Index] == nullptr) {
|
||||||
try {
|
try {
|
||||||
Com<SubresourceType9> subresource = LookupSubresource(Index);
|
Com<SubresourceType9> subresource = LookupSubresource(Index);
|
||||||
|
|
||||||
// Cache the subresource
|
// Cache the subresource
|
||||||
m_subresources[Index] = new SubresourceType(this->m_parent, this, std::move(subresource));
|
m_subresources[Index] = new SubresourceType(this->m_parent, this, std::move(subresource));
|
||||||
} catch (HRESULT res) {
|
} catch (HRESULT res) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*ppSubresource = m_subresources[Index].ref();
|
*ppSubresource = m_subresources[Index].ref();
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Com<SubresourceType9> LookupSubresource(UINT Index) {
|
Com<SubresourceType9> LookupSubresource(UINT Index) {
|
||||||
Com<SubresourceType9> ptr = nullptr;
|
Com<SubresourceType9> ptr = nullptr;
|
||||||
HRESULT res = D3DERR_INVALIDCALL;
|
HRESULT res = D3DERR_INVALIDCALL;
|
||||||
if constexpr (std::is_same_v<D3D8, IDirect3DTexture8>) {
|
if constexpr (std::is_same_v<D3D8, IDirect3DTexture8>) {
|
||||||
res = this->GetD3D9()->GetSurfaceLevel(Index, &ptr);
|
res = this->GetD3D9()->GetSurfaceLevel(Index, &ptr);
|
||||||
} else if constexpr (std::is_same_v<D3D8, IDirect3DVolumeTexture8>) {
|
} else if constexpr (std::is_same_v<D3D8, IDirect3DVolumeTexture8>) {
|
||||||
res = this->GetD3D9()->GetVolumeLevel(Index, &ptr);
|
res = this->GetD3D9()->GetVolumeLevel(Index, &ptr);
|
||||||
} else if constexpr (std::is_same_v<D3D8, IDirect3DCubeTexture8>) {
|
} else if constexpr (std::is_same_v<D3D8, IDirect3DCubeTexture8>) {
|
||||||
res = this->GetD3D9()->GetCubeMapSurface(d3d9::D3DCUBEMAP_FACES(Index % CUBE_FACES), Index / CUBE_FACES, &ptr);
|
res = this->GetD3D9()->GetCubeMapSurface(d3d9::D3DCUBEMAP_FACES(Index % CUBE_FACES), Index / CUBE_FACES, &ptr);
|
||||||
}
|
}
|
||||||
if (FAILED(res))
|
if (FAILED(res))
|
||||||
throw res;
|
throw res;
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Com<SubresourceType, false>> m_subresources;
|
std::vector<Com<SubresourceType, false>> m_subresources;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using D3D8Texture2DBase = D3D8BaseTexture<D3D8Surface, d3d9::IDirect3DTexture9, IDirect3DTexture8>;
|
using D3D8Texture2DBase = D3D8BaseTexture<D3D8Surface, d3d9::IDirect3DTexture9, IDirect3DTexture8>;
|
||||||
class D3D8Texture2D final : public D3D8Texture2DBase {
|
class D3D8Texture2D final : public D3D8Texture2DBase {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
D3D8Texture2D(
|
D3D8Texture2D(
|
||||||
D3D8Device* pDevice,
|
D3D8Device* pDevice,
|
||||||
Com<d3d9::IDirect3DTexture9>&& pTexture)
|
Com<d3d9::IDirect3DTexture9>&& pTexture)
|
||||||
: D3D8Texture2DBase(pDevice, std::move(pTexture), pTexture->GetLevelCount()) {
|
: D3D8Texture2DBase(pDevice, std::move(pTexture), pTexture->GetLevelCount()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DRESOURCETYPE STDMETHODCALLTYPE GetType() final { return D3DRTYPE_TEXTURE; }
|
D3DRESOURCETYPE STDMETHODCALLTYPE GetType() final { return D3DRTYPE_TEXTURE; }
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE GetLevelDesc(UINT Level, D3DSURFACE_DESC* pDesc) {
|
HRESULT STDMETHODCALLTYPE GetLevelDesc(UINT Level, D3DSURFACE_DESC* pDesc) {
|
||||||
if (unlikely(pDesc == nullptr))
|
if (unlikely(pDesc == nullptr))
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
d3d9::D3DSURFACE_DESC surf;
|
d3d9::D3DSURFACE_DESC surf;
|
||||||
HRESULT res = GetD3D9()->GetLevelDesc(Level, &surf);
|
HRESULT res = GetD3D9()->GetLevelDesc(Level, &surf);
|
||||||
|
|
||||||
if (likely(SUCCEEDED(res)))
|
if (likely(SUCCEEDED(res)))
|
||||||
ConvertSurfaceDesc8(&surf, pDesc);
|
ConvertSurfaceDesc8(&surf, pDesc);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE GetSurfaceLevel(UINT Level, IDirect3DSurface8** ppSurfaceLevel) {
|
HRESULT STDMETHODCALLTYPE GetSurfaceLevel(UINT Level, IDirect3DSurface8** ppSurfaceLevel) {
|
||||||
return GetSubresource(Level, ppSurfaceLevel);
|
return GetSubresource(Level, ppSurfaceLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE LockRect(UINT Level, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) {
|
HRESULT STDMETHODCALLTYPE LockRect(UINT Level, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) {
|
||||||
return GetD3D9()->LockRect(Level, reinterpret_cast<d3d9::D3DLOCKED_RECT*>(pLockedRect), pRect, Flags);
|
return GetD3D9()->LockRect(Level, reinterpret_cast<d3d9::D3DLOCKED_RECT*>(pLockedRect), pRect, Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE UnlockRect(UINT Level) {
|
HRESULT STDMETHODCALLTYPE UnlockRect(UINT Level) {
|
||||||
return GetD3D9()->UnlockRect(Level);
|
return GetD3D9()->UnlockRect(Level);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE AddDirtyRect(CONST RECT* pDirtyRect) {
|
HRESULT STDMETHODCALLTYPE AddDirtyRect(CONST RECT* pDirtyRect) {
|
||||||
return GetD3D9()->AddDirtyRect(pDirtyRect);
|
return GetD3D9()->AddDirtyRect(pDirtyRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using D3D8Texture3DBase = D3D8BaseTexture<D3D8Volume, d3d9::IDirect3DVolumeTexture9, IDirect3DVolumeTexture8>;
|
using D3D8Texture3DBase = D3D8BaseTexture<D3D8Volume, d3d9::IDirect3DVolumeTexture9, IDirect3DVolumeTexture8>;
|
||||||
class D3D8Texture3D final : public D3D8Texture3DBase {
|
class D3D8Texture3D final : public D3D8Texture3DBase {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
D3D8Texture3D(
|
D3D8Texture3D(
|
||||||
D3D8Device* pDevice,
|
D3D8Device* pDevice,
|
||||||
Com<d3d9::IDirect3DVolumeTexture9>&& pVolumeTexture)
|
Com<d3d9::IDirect3DVolumeTexture9>&& pVolumeTexture)
|
||||||
: D3D8Texture3DBase(pDevice, std::move(pVolumeTexture), pVolumeTexture->GetLevelCount()) {}
|
: D3D8Texture3DBase(pDevice, std::move(pVolumeTexture), pVolumeTexture->GetLevelCount()) {}
|
||||||
|
|
||||||
D3DRESOURCETYPE STDMETHODCALLTYPE GetType() final { return D3DRTYPE_VOLUMETEXTURE; }
|
D3DRESOURCETYPE STDMETHODCALLTYPE GetType() final { return D3DRTYPE_VOLUMETEXTURE; }
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE GetLevelDesc(UINT Level, D3DVOLUME_DESC *pDesc) {
|
HRESULT STDMETHODCALLTYPE GetLevelDesc(UINT Level, D3DVOLUME_DESC *pDesc) {
|
||||||
if (unlikely(pDesc == nullptr))
|
if (unlikely(pDesc == nullptr))
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
d3d9::D3DVOLUME_DESC vol;
|
d3d9::D3DVOLUME_DESC vol;
|
||||||
HRESULT res = GetD3D9()->GetLevelDesc(Level, &vol);
|
HRESULT res = GetD3D9()->GetLevelDesc(Level, &vol);
|
||||||
|
|
||||||
if (likely(SUCCEEDED(res)))
|
if (likely(SUCCEEDED(res)))
|
||||||
ConvertVolumeDesc8(&vol, pDesc);
|
ConvertVolumeDesc8(&vol, pDesc);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE GetVolumeLevel(UINT Level, IDirect3DVolume8** ppVolumeLevel) {
|
HRESULT STDMETHODCALLTYPE GetVolumeLevel(UINT Level, IDirect3DVolume8** ppVolumeLevel) {
|
||||||
return GetSubresource(Level, ppVolumeLevel);
|
return GetSubresource(Level, ppVolumeLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE LockBox(UINT Level, D3DLOCKED_BOX* pLockedBox, CONST D3DBOX* pBox, DWORD Flags) {
|
HRESULT STDMETHODCALLTYPE LockBox(UINT Level, D3DLOCKED_BOX* pLockedBox, CONST D3DBOX* pBox, DWORD Flags) {
|
||||||
return GetD3D9()->LockBox(
|
return GetD3D9()->LockBox(
|
||||||
Level,
|
Level,
|
||||||
reinterpret_cast<d3d9::D3DLOCKED_BOX*>(pLockedBox),
|
reinterpret_cast<d3d9::D3DLOCKED_BOX*>(pLockedBox),
|
||||||
reinterpret_cast<const d3d9::D3DBOX*>(pBox),
|
reinterpret_cast<const d3d9::D3DBOX*>(pBox),
|
||||||
Flags
|
Flags
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE UnlockBox(UINT Level) {
|
HRESULT STDMETHODCALLTYPE UnlockBox(UINT Level) {
|
||||||
return GetD3D9()->UnlockBox(Level);
|
return GetD3D9()->UnlockBox(Level);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE AddDirtyBox(CONST D3DBOX* pDirtyBox) {
|
HRESULT STDMETHODCALLTYPE AddDirtyBox(CONST D3DBOX* pDirtyBox) {
|
||||||
return GetD3D9()->AddDirtyBox(reinterpret_cast<const d3d9::D3DBOX*>(pDirtyBox));
|
return GetD3D9()->AddDirtyBox(reinterpret_cast<const d3d9::D3DBOX*>(pDirtyBox));
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using D3D8TextureCubeBase = D3D8BaseTexture<D3D8Surface, d3d9::IDirect3DCubeTexture9, IDirect3DCubeTexture8>;
|
using D3D8TextureCubeBase = D3D8BaseTexture<D3D8Surface, d3d9::IDirect3DCubeTexture9, IDirect3DCubeTexture8>;
|
||||||
class D3D8TextureCube final : public D3D8TextureCubeBase {
|
class D3D8TextureCube final : public D3D8TextureCubeBase {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
D3D8TextureCube(
|
D3D8TextureCube(
|
||||||
D3D8Device* pDevice,
|
D3D8Device* pDevice,
|
||||||
Com<d3d9::IDirect3DCubeTexture9>&& pTexture)
|
Com<d3d9::IDirect3DCubeTexture9>&& pTexture)
|
||||||
: D3D8TextureCubeBase(pDevice, std::move(pTexture), pTexture->GetLevelCount() * CUBE_FACES) {
|
: D3D8TextureCubeBase(pDevice, std::move(pTexture), pTexture->GetLevelCount() * CUBE_FACES) {
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DRESOURCETYPE STDMETHODCALLTYPE GetType() final { return D3DRTYPE_CUBETEXTURE; }
|
D3DRESOURCETYPE STDMETHODCALLTYPE GetType() final { return D3DRTYPE_CUBETEXTURE; }
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE GetLevelDesc(UINT Level, D3DSURFACE_DESC* pDesc) {
|
HRESULT STDMETHODCALLTYPE GetLevelDesc(UINT Level, D3DSURFACE_DESC* pDesc) {
|
||||||
if (unlikely(pDesc == nullptr))
|
if (unlikely(pDesc == nullptr))
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
d3d9::D3DSURFACE_DESC surf;
|
d3d9::D3DSURFACE_DESC surf;
|
||||||
HRESULT res = GetD3D9()->GetLevelDesc(Level, &surf);
|
HRESULT res = GetD3D9()->GetLevelDesc(Level, &surf);
|
||||||
|
|
||||||
if (likely(SUCCEEDED(res)))
|
if (likely(SUCCEEDED(res)))
|
||||||
ConvertSurfaceDesc8(&surf, pDesc);
|
ConvertSurfaceDesc8(&surf, pDesc);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE GetCubeMapSurface(D3DCUBEMAP_FACES Face, UINT Level, IDirect3DSurface8** ppSurfaceLevel) {
|
HRESULT STDMETHODCALLTYPE GetCubeMapSurface(D3DCUBEMAP_FACES Face, UINT Level, IDirect3DSurface8** ppSurfaceLevel) {
|
||||||
return GetSubresource((Level * CUBE_FACES) + Face, ppSurfaceLevel);
|
return GetSubresource((Level * CUBE_FACES) + Face, ppSurfaceLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE LockRect(
|
HRESULT STDMETHODCALLTYPE LockRect(
|
||||||
D3DCUBEMAP_FACES Face,
|
D3DCUBEMAP_FACES Face,
|
||||||
UINT Level,
|
UINT Level,
|
||||||
D3DLOCKED_RECT* pLockedRect,
|
D3DLOCKED_RECT* pLockedRect,
|
||||||
const RECT* pRect,
|
const RECT* pRect,
|
||||||
DWORD Flags) {
|
DWORD Flags) {
|
||||||
return GetD3D9()->LockRect(
|
return GetD3D9()->LockRect(
|
||||||
d3d9::D3DCUBEMAP_FACES(Face),
|
d3d9::D3DCUBEMAP_FACES(Face),
|
||||||
Level,
|
Level,
|
||||||
reinterpret_cast<d3d9::D3DLOCKED_RECT*>(pLockedRect),
|
reinterpret_cast<d3d9::D3DLOCKED_RECT*>(pLockedRect),
|
||||||
pRect,
|
pRect,
|
||||||
Flags);
|
Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE UnlockRect(D3DCUBEMAP_FACES Face, UINT Level) {
|
HRESULT STDMETHODCALLTYPE UnlockRect(D3DCUBEMAP_FACES Face, UINT Level) {
|
||||||
return GetD3D9()->UnlockRect(d3d9::D3DCUBEMAP_FACES(Face), Level);
|
return GetD3D9()->UnlockRect(d3d9::D3DCUBEMAP_FACES(Face), Level);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE AddDirtyRect(D3DCUBEMAP_FACES Face, const RECT* pDirtyRect) {
|
HRESULT STDMETHODCALLTYPE AddDirtyRect(D3DCUBEMAP_FACES Face, const RECT* pDirtyRect) {
|
||||||
return GetD3D9()->AddDirtyRect(d3d9::D3DCUBEMAP_FACES(Face), pDirtyRect);
|
return GetD3D9()->AddDirtyRect(d3d9::D3DCUBEMAP_FACES(Face), pDirtyRect);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -1,46 +1,46 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "d3d8_subresource.h"
|
#include "d3d8_subresource.h"
|
||||||
#include "d3d8_d3d9_util.h"
|
#include "d3d8_d3d9_util.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
using D3D8VolumeBase = D3D8Subresource<d3d9::IDirect3DVolume9, IDirect3DVolume8>;
|
using D3D8VolumeBase = D3D8Subresource<d3d9::IDirect3DVolume9, IDirect3DVolume8>;
|
||||||
class D3D8Volume final : public D3D8VolumeBase {
|
class D3D8Volume final : public D3D8VolumeBase {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
D3D8Volume(
|
D3D8Volume(
|
||||||
D3D8Device* pDevice,
|
D3D8Device* pDevice,
|
||||||
IDirect3DVolumeTexture8* pTexture,
|
IDirect3DVolumeTexture8* pTexture,
|
||||||
Com<d3d9::IDirect3DVolume9>&& pVolume)
|
Com<d3d9::IDirect3DVolume9>&& pVolume)
|
||||||
: D3D8VolumeBase(pDevice, std::move(pVolume), pTexture) {}
|
: D3D8VolumeBase(pDevice, std::move(pVolume), pTexture) {}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE GetDesc(D3DVOLUME_DESC* pDesc) {
|
HRESULT STDMETHODCALLTYPE GetDesc(D3DVOLUME_DESC* pDesc) {
|
||||||
if (unlikely(pDesc == nullptr))
|
if (unlikely(pDesc == nullptr))
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
d3d9::D3DVOLUME_DESC desc;
|
d3d9::D3DVOLUME_DESC desc;
|
||||||
HRESULT res = GetD3D9()->GetDesc(&desc);
|
HRESULT res = GetD3D9()->GetDesc(&desc);
|
||||||
|
|
||||||
if (likely(SUCCEEDED(res)))
|
if (likely(SUCCEEDED(res)))
|
||||||
ConvertVolumeDesc8(&desc, pDesc);
|
ConvertVolumeDesc8(&desc, pDesc);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE LockBox(D3DLOCKED_BOX* pLockedBox, CONST D3DBOX* pBox, DWORD Flags) final {
|
HRESULT STDMETHODCALLTYPE LockBox(D3DLOCKED_BOX* pLockedBox, CONST D3DBOX* pBox, DWORD Flags) final {
|
||||||
return GetD3D9()->LockBox(
|
return GetD3D9()->LockBox(
|
||||||
reinterpret_cast<d3d9::D3DLOCKED_BOX*>(pLockedBox),
|
reinterpret_cast<d3d9::D3DLOCKED_BOX*>(pLockedBox),
|
||||||
reinterpret_cast<const d3d9::D3DBOX*>(pBox),
|
reinterpret_cast<const d3d9::D3DBOX*>(pBox),
|
||||||
Flags
|
Flags
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE UnlockBox() final {
|
HRESULT STDMETHODCALLTYPE UnlockBox() final {
|
||||||
return GetD3D9()->UnlockBox();
|
return GetD3D9()->UnlockBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -1,111 +1,111 @@
|
|||||||
|
|
||||||
#include "d3d9_device.h"
|
#include "d3d9_device.h"
|
||||||
#include "d3d9_interface.h"
|
#include "d3d9_interface.h"
|
||||||
#include "d3d9_bridge.h"
|
#include "d3d9_bridge.h"
|
||||||
#include "d3d9_swapchain.h"
|
#include "d3d9_swapchain.h"
|
||||||
#include "d3d9_surface.h"
|
#include "d3d9_surface.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
DxvkD3D8Bridge::DxvkD3D8Bridge(D3D9DeviceEx* pDevice)
|
DxvkD3D8Bridge::DxvkD3D8Bridge(D3D9DeviceEx* pDevice)
|
||||||
: m_device(pDevice) {
|
: m_device(pDevice) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DxvkD3D8Bridge::~DxvkD3D8Bridge() {
|
DxvkD3D8Bridge::~DxvkD3D8Bridge() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE DxvkD3D8Bridge::AddRef() {
|
ULONG STDMETHODCALLTYPE DxvkD3D8Bridge::AddRef() {
|
||||||
return m_device->AddRef();
|
return m_device->AddRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE DxvkD3D8Bridge::Release() {
|
ULONG STDMETHODCALLTYPE DxvkD3D8Bridge::Release() {
|
||||||
return m_device->Release();
|
return m_device->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE DxvkD3D8Bridge::QueryInterface(
|
HRESULT STDMETHODCALLTYPE DxvkD3D8Bridge::QueryInterface(
|
||||||
REFIID riid,
|
REFIID riid,
|
||||||
void** ppvObject) {
|
void** ppvObject) {
|
||||||
return m_device->QueryInterface(riid, ppvObject);
|
return m_device->QueryInterface(riid, ppvObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DxvkD3D8Bridge::SetAPIName(const char* name) {
|
void DxvkD3D8Bridge::SetAPIName(const char* name) {
|
||||||
m_device->m_implicitSwapchain->SetApiName(name);
|
m_device->m_implicitSwapchain->SetApiName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT DxvkD3D8Bridge::UpdateTextureFromBuffer(
|
HRESULT DxvkD3D8Bridge::UpdateTextureFromBuffer(
|
||||||
IDirect3DSurface9* pDestSurface,
|
IDirect3DSurface9* pDestSurface,
|
||||||
IDirect3DSurface9* pSrcSurface,
|
IDirect3DSurface9* pSrcSurface,
|
||||||
const RECT* pSrcRect,
|
const RECT* pSrcRect,
|
||||||
const POINT* pDestPoint) {
|
const POINT* pDestPoint) {
|
||||||
auto lock = m_device->LockDevice();
|
auto lock = m_device->LockDevice();
|
||||||
|
|
||||||
D3D9Surface* dst = static_cast<D3D9Surface*>(pDestSurface);
|
D3D9Surface* dst = static_cast<D3D9Surface*>(pDestSurface);
|
||||||
D3D9Surface* src = static_cast<D3D9Surface*>(pSrcSurface);
|
D3D9Surface* src = static_cast<D3D9Surface*>(pSrcSurface);
|
||||||
|
|
||||||
if (unlikely(dst == nullptr || src == nullptr))
|
if (unlikely(dst == nullptr || src == nullptr))
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
D3D9CommonTexture* srcTextureInfo = src->GetCommonTexture();
|
D3D9CommonTexture* srcTextureInfo = src->GetCommonTexture();
|
||||||
D3D9CommonTexture* dstTextureInfo = dst->GetCommonTexture();
|
D3D9CommonTexture* dstTextureInfo = dst->GetCommonTexture();
|
||||||
|
|
||||||
VkOffset3D srcOffset = { 0u, 0u, 0u };
|
VkOffset3D srcOffset = { 0u, 0u, 0u };
|
||||||
VkOffset3D dstOffset = { 0u, 0u, 0u };
|
VkOffset3D dstOffset = { 0u, 0u, 0u };
|
||||||
VkExtent3D texLevelExtent = srcTextureInfo->GetExtentMip(src->GetSubresource());
|
VkExtent3D texLevelExtent = srcTextureInfo->GetExtentMip(src->GetSubresource());
|
||||||
VkExtent3D extent = texLevelExtent;
|
VkExtent3D extent = texLevelExtent;
|
||||||
|
|
||||||
srcOffset = { pSrcRect->left,
|
srcOffset = { pSrcRect->left,
|
||||||
pSrcRect->top,
|
pSrcRect->top,
|
||||||
0u };
|
0u };
|
||||||
|
|
||||||
extent = { uint32_t(pSrcRect->right - pSrcRect->left), uint32_t(pSrcRect->bottom - pSrcRect->top), 1 };
|
extent = { uint32_t(pSrcRect->right - pSrcRect->left), uint32_t(pSrcRect->bottom - pSrcRect->top), 1 };
|
||||||
|
|
||||||
// TODO: Validate extents like in D3D9DeviceEx::UpdateSurface
|
// TODO: Validate extents like in D3D9DeviceEx::UpdateSurface
|
||||||
|
|
||||||
dstOffset = { pDestPoint->x,
|
dstOffset = { pDestPoint->x,
|
||||||
pDestPoint->y,
|
pDestPoint->y,
|
||||||
0u };
|
0u };
|
||||||
|
|
||||||
|
|
||||||
m_device->UpdateTextureFromBuffer(
|
m_device->UpdateTextureFromBuffer(
|
||||||
srcTextureInfo, dstTextureInfo,
|
srcTextureInfo, dstTextureInfo,
|
||||||
src->GetSubresource(), dst->GetSubresource(),
|
src->GetSubresource(), dst->GetSubresource(),
|
||||||
srcOffset, extent, dstOffset
|
srcOffset, extent, dstOffset
|
||||||
);
|
);
|
||||||
|
|
||||||
dstTextureInfo->SetNeedsReadback(dst->GetSubresource(), true);
|
dstTextureInfo->SetNeedsReadback(dst->GetSubresource(), true);
|
||||||
|
|
||||||
if (dstTextureInfo->IsAutomaticMip())
|
if (dstTextureInfo->IsAutomaticMip())
|
||||||
m_device->MarkTextureMipsDirty(dstTextureInfo);
|
m_device->MarkTextureMipsDirty(dstTextureInfo);
|
||||||
|
|
||||||
return D3D_OK;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
DxvkD3D8InterfaceBridge::DxvkD3D8InterfaceBridge(D3D9InterfaceEx* pObject)
|
DxvkD3D8InterfaceBridge::DxvkD3D8InterfaceBridge(D3D9InterfaceEx* pObject)
|
||||||
: m_interface(pObject) {
|
: m_interface(pObject) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DxvkD3D8InterfaceBridge::~DxvkD3D8InterfaceBridge() {
|
DxvkD3D8InterfaceBridge::~DxvkD3D8InterfaceBridge() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE DxvkD3D8InterfaceBridge::AddRef() {
|
ULONG STDMETHODCALLTYPE DxvkD3D8InterfaceBridge::AddRef() {
|
||||||
return m_interface->AddRef();
|
return m_interface->AddRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE DxvkD3D8InterfaceBridge::Release() {
|
ULONG STDMETHODCALLTYPE DxvkD3D8InterfaceBridge::Release() {
|
||||||
return m_interface->Release();
|
return m_interface->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE DxvkD3D8InterfaceBridge::QueryInterface(
|
HRESULT STDMETHODCALLTYPE DxvkD3D8InterfaceBridge::QueryInterface(
|
||||||
REFIID riid,
|
REFIID riid,
|
||||||
void** ppvObject) {
|
void** ppvObject) {
|
||||||
return m_interface->QueryInterface(riid, ppvObject);
|
return m_interface->QueryInterface(riid, ppvObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DxvkD3D8InterfaceBridge::SetD3D8CompatibilityMode(const bool compatMode) {
|
void DxvkD3D8InterfaceBridge::SetD3D8CompatibilityMode(const bool compatMode) {
|
||||||
m_interface->SetD3D8CompatibilityMode(compatMode);
|
m_interface->SetD3D8CompatibilityMode(compatMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Config* DxvkD3D8InterfaceBridge::GetConfig() const {
|
const Config* DxvkD3D8InterfaceBridge::GetConfig() const {
|
||||||
return &m_interface->GetInstance()->config();
|
return &m_interface->GetInstance()->config();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,117 +1,117 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "../util/config/config.h"
|
#include "../util/config/config.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The D3D9 bridge allows D3D8 to access DXVK internals.
|
* The D3D9 bridge allows D3D8 to access DXVK internals.
|
||||||
* For Vulkan interop without needing DXVK internals, see d3d9_interop.h.
|
* For Vulkan interop without needing DXVK internals, see d3d9_interop.h.
|
||||||
*
|
*
|
||||||
* NOTE: You must include "d3d9_include.h" or "d3d8_include.h" before this header.
|
* NOTE: You must include "d3d9_include.h" or "d3d8_include.h" before this header.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief D3D9 device interface for D3D8 interop
|
* \brief D3D9 device interface for D3D8 interop
|
||||||
*/
|
*/
|
||||||
MIDL_INTERFACE("D3D9D3D8-42A9-4C1E-AA97-BEEFCAFE2000")
|
MIDL_INTERFACE("D3D9D3D8-42A9-4C1E-AA97-BEEFCAFE2000")
|
||||||
IDxvkD3D8Bridge : public IUnknown {
|
IDxvkD3D8Bridge : public IUnknown {
|
||||||
|
|
||||||
// D3D8 keeps D3D9 objects contained in a namespace.
|
// D3D8 keeps D3D9 objects contained in a namespace.
|
||||||
#ifdef DXVK_D3D9_NAMESPACE
|
#ifdef DXVK_D3D9_NAMESPACE
|
||||||
using IDirect3DSurface9 = d3d9::IDirect3DSurface9;
|
using IDirect3DSurface9 = d3d9::IDirect3DSurface9;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Changes the API name displayed on the HUD
|
* \brief Changes the API name displayed on the HUD
|
||||||
*
|
*
|
||||||
* \param [in] name The new API name
|
* \param [in] name The new API name
|
||||||
*/
|
*/
|
||||||
virtual void SetAPIName(const char* name) = 0;
|
virtual void SetAPIName(const char* name) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Updates a D3D9 surface from a D3D9 buffer
|
* \brief Updates a D3D9 surface from a D3D9 buffer
|
||||||
*
|
*
|
||||||
* \param [in] pDestSurface Destination surface (typically in VRAM)
|
* \param [in] pDestSurface Destination surface (typically in VRAM)
|
||||||
* \param [in] pSrcSurface Source surface (typically in system memory)
|
* \param [in] pSrcSurface Source surface (typically in system memory)
|
||||||
* \param [in] pSrcRect Source rectangle
|
* \param [in] pSrcRect Source rectangle
|
||||||
* \param [in] pDestPoint Destination (top-left) point
|
* \param [in] pDestPoint Destination (top-left) point
|
||||||
*/
|
*/
|
||||||
virtual HRESULT UpdateTextureFromBuffer(
|
virtual HRESULT UpdateTextureFromBuffer(
|
||||||
IDirect3DSurface9* pDestSurface,
|
IDirect3DSurface9* pDestSurface,
|
||||||
IDirect3DSurface9* pSrcSurface,
|
IDirect3DSurface9* pSrcSurface,
|
||||||
const RECT* pSrcRect,
|
const RECT* pSrcRect,
|
||||||
const POINT* pDestPoint) = 0;
|
const POINT* pDestPoint) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief D3D9 instance interface for D3D8 interop
|
* \brief D3D9 instance interface for D3D8 interop
|
||||||
*/
|
*/
|
||||||
MIDL_INTERFACE("D3D9D3D8-A407-773E-18E9-CAFEBEEF3000")
|
MIDL_INTERFACE("D3D9D3D8-A407-773E-18E9-CAFEBEEF3000")
|
||||||
IDxvkD3D8InterfaceBridge : public IUnknown {
|
IDxvkD3D8InterfaceBridge : public IUnknown {
|
||||||
/**
|
/**
|
||||||
* \brief Enables or disables D3D9-specific features and validations
|
* \brief Enables or disables D3D9-specific features and validations
|
||||||
*
|
*
|
||||||
* \param [in] compatMode Compatibility state
|
* \param [in] compatMode Compatibility state
|
||||||
*/
|
*/
|
||||||
virtual void SetD3D8CompatibilityMode(const bool compatMode) = 0;
|
virtual void SetD3D8CompatibilityMode(const bool compatMode) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Retrieves the DXVK configuration
|
* \brief Retrieves the DXVK configuration
|
||||||
*
|
*
|
||||||
* \returns The DXVK Config object
|
* \returns The DXVK Config object
|
||||||
*/
|
*/
|
||||||
virtual const dxvk::Config* GetConfig() const = 0;
|
virtual const dxvk::Config* GetConfig() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
__CRT_UUID_DECL(IDxvkD3D8Bridge, 0xD3D9D3D8, 0x42A9, 0x4C1E, 0xAA, 0x97, 0xBE, 0xEF, 0xCA, 0xFE, 0x20, 0x00);
|
__CRT_UUID_DECL(IDxvkD3D8Bridge, 0xD3D9D3D8, 0x42A9, 0x4C1E, 0xAA, 0x97, 0xBE, 0xEF, 0xCA, 0xFE, 0x20, 0x00);
|
||||||
__CRT_UUID_DECL(IDxvkD3D8InterfaceBridge, 0xD3D9D3D8, 0xA407, 0x773E, 0x18, 0xE9, 0xCA, 0xFE, 0xBE, 0xEF, 0x30, 0x00);
|
__CRT_UUID_DECL(IDxvkD3D8InterfaceBridge, 0xD3D9D3D8, 0xA407, 0x773E, 0x18, 0xE9, 0xCA, 0xFE, 0xBE, 0xEF, 0x30, 0x00);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
class D3D9DeviceEx;
|
class D3D9DeviceEx;
|
||||||
class D3D9InterfaceEx;
|
class D3D9InterfaceEx;
|
||||||
|
|
||||||
class DxvkD3D8Bridge : public IDxvkD3D8Bridge {
|
class DxvkD3D8Bridge : public IDxvkD3D8Bridge {
|
||||||
public:
|
public:
|
||||||
DxvkD3D8Bridge(D3D9DeviceEx* pDevice);
|
DxvkD3D8Bridge(D3D9DeviceEx* pDevice);
|
||||||
~DxvkD3D8Bridge();
|
~DxvkD3D8Bridge();
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE AddRef();
|
ULONG STDMETHODCALLTYPE AddRef();
|
||||||
ULONG STDMETHODCALLTYPE Release();
|
ULONG STDMETHODCALLTYPE Release();
|
||||||
HRESULT STDMETHODCALLTYPE QueryInterface(
|
HRESULT STDMETHODCALLTYPE QueryInterface(
|
||||||
REFIID riid,
|
REFIID riid,
|
||||||
void** ppvObject);
|
void** ppvObject);
|
||||||
|
|
||||||
void SetAPIName(const char* name);
|
void SetAPIName(const char* name);
|
||||||
|
|
||||||
HRESULT UpdateTextureFromBuffer(
|
HRESULT UpdateTextureFromBuffer(
|
||||||
IDirect3DSurface9* pDestSurface,
|
IDirect3DSurface9* pDestSurface,
|
||||||
IDirect3DSurface9* pSrcSurface,
|
IDirect3DSurface9* pSrcSurface,
|
||||||
const RECT* pSrcRect,
|
const RECT* pSrcRect,
|
||||||
const POINT* pDestPoint);
|
const POINT* pDestPoint);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
D3D9DeviceEx* m_device;
|
D3D9DeviceEx* m_device;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DxvkD3D8InterfaceBridge : public IDxvkD3D8InterfaceBridge {
|
class DxvkD3D8InterfaceBridge : public IDxvkD3D8InterfaceBridge {
|
||||||
public:
|
public:
|
||||||
DxvkD3D8InterfaceBridge(D3D9InterfaceEx* pObject);
|
DxvkD3D8InterfaceBridge(D3D9InterfaceEx* pObject);
|
||||||
~DxvkD3D8InterfaceBridge();
|
~DxvkD3D8InterfaceBridge();
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE AddRef();
|
ULONG STDMETHODCALLTYPE AddRef();
|
||||||
ULONG STDMETHODCALLTYPE Release();
|
ULONG STDMETHODCALLTYPE Release();
|
||||||
HRESULT STDMETHODCALLTYPE QueryInterface(
|
HRESULT STDMETHODCALLTYPE QueryInterface(
|
||||||
REFIID riid,
|
REFIID riid,
|
||||||
void** ppvObject);
|
void** ppvObject);
|
||||||
|
|
||||||
void SetD3D8CompatibilityMode(const bool compatMode);
|
void SetD3D8CompatibilityMode(const bool compatMode);
|
||||||
|
|
||||||
const Config* GetConfig() const;
|
const Config* GetConfig() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
D3D9InterfaceEx* m_interface;
|
D3D9InterfaceEx* m_interface;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user