1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-21 22:54:16 +01:00

[d3d8] Alignment and formatting improvements

This commit is contained in:
WinterSnowfall 2025-01-09 11:59:59 +02:00 committed by Philip Rebohle
parent 639f815432
commit 4151d35e8e
24 changed files with 120 additions and 94 deletions

View File

@ -16,7 +16,9 @@ namespace dxvk {
// Vertex buffer that can handle many tiny locks while // Vertex buffer that can handle many tiny locks while
// still maintaing the lock ordering of direct-mapped buffers. // still maintaing the lock ordering of direct-mapped buffers.
class D3D8BatchBuffer final : public D3D8VertexBuffer { class D3D8BatchBuffer final : public D3D8VertexBuffer {
public: public:
D3D8BatchBuffer( D3D8BatchBuffer(
D3D8Device* pDevice, D3D8Device* pDevice,
D3DPOOL Pool, D3DPOOL Pool,
@ -67,11 +69,13 @@ namespace dxvk {
} }
private: private:
std::vector<BYTE> m_data; std::vector<BYTE> m_data;
DWORD m_fvf; DWORD m_fvf;
}; };
// Main handler for batching D3D8 draw calls. // Main handler for batching D3D8 draw calls.
class D3D8Batcher { class D3D8Batcher {
@ -86,6 +90,7 @@ namespace dxvk {
}; };
public: public:
D3D8Batcher(D3D8Device* pDevice8, Com<d3d9::IDirect3DDevice9>&& pDevice9) D3D8Batcher(D3D8Device* pDevice8, Com<d3d9::IDirect3DDevice9>&& pDevice9)
: m_device8(pDevice8) : m_device8(pDevice8)
, m_device(std::move(pDevice9)) { , m_device(std::move(pDevice9)) {
@ -115,10 +120,10 @@ namespace dxvk {
d3d9::D3DFMT_INDEX16, d3d9::D3DFMT_INDEX16,
m_stream->GetPtr(draw.MinVertex * m_stride), m_stream->GetPtr(draw.MinVertex * m_stride),
m_stride); m_stride);
m_device->SetStreamSource(0, D3D8VertexBuffer::GetD3D9Nullable(m_stream), 0, m_stride); m_device->SetStreamSource(0, D3D8VertexBuffer::GetD3D9Nullable(m_stream), 0, m_stride);
m_device->SetIndices(D3D8IndexBuffer::GetD3D9Nullable(m_indices)); m_device->SetIndices(D3D8IndexBuffer::GetD3D9Nullable(m_indices));
draw.PrimitiveType = D3DPRIMITIVETYPE(0); draw.PrimitiveType = D3DPRIMITIVETYPE(0);
draw.Offset = 0; draw.Offset = 0;
draw.MinVertex = UINT_MAX; draw.MinVertex = UINT_MAX;
@ -231,6 +236,7 @@ namespace dxvk {
} }
private: private:
D3D8Device* m_device8; D3D8Device* m_device8;
Com<d3d9::IDirect3DDevice9> m_device; Com<d3d9::IDirect3DDevice9> m_device;
@ -239,5 +245,7 @@ namespace dxvk {
D3D8IndexBuffer* m_indices = nullptr; D3D8IndexBuffer* m_indices = nullptr;
INT m_baseVertexIndex = 0; INT m_baseVertexIndex = 0;
std::array<Batch, D3DPT_COUNT> m_batches; std::array<Batch, D3DPT_COUNT> m_batches;
}; };
} }

View File

@ -103,7 +103,7 @@ namespace dxvk {
// 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?
} }
} }
@ -172,5 +172,5 @@ namespace dxvk {
default: return d3d9::D3DSAMPLERSTATETYPE(-1u); default: return d3d9::D3DSAMPLERSTATETYPE(-1u);
} }
} }
}
}

View File

@ -32,12 +32,12 @@ namespace dxvk {
}; };
D3D8Device::D3D8Device( D3D8Device::D3D8Device(
D3D8Interface* pParent, D3D8Interface* pParent,
Com<d3d9::IDirect3DDevice9>&& pDevice, Com<d3d9::IDirect3DDevice9>&& pDevice,
D3DDEVTYPE DeviceType, D3DDEVTYPE DeviceType,
HWND hFocusWindow, HWND hFocusWindow,
DWORD BehaviorFlags, DWORD BehaviorFlags,
D3DPRESENT_PARAMETERS* pParams) D3DPRESENT_PARAMETERS* pParams)
: D3D8DeviceBase(std::move(pDevice)) : D3D8DeviceBase(std::move(pDevice))
, m_d3d8Options(pParent->GetOptions()) , m_d3d8Options(pParent->GetOptions())
, m_parent(pParent) , m_parent(pParent)
@ -55,7 +55,7 @@ namespace dxvk {
ResetState(); ResetState();
RecreateBackBuffersAndAutoDepthStencil(); RecreateBackBuffersAndAutoDepthStencil();
if (m_d3d8Options.batching) if (m_d3d8Options.batching)
m_batcher = new D3D8Batcher(this, GetD3D9()); m_batcher = new D3D8Batcher(this, GetD3D9());
} }
@ -73,7 +73,7 @@ namespace dxvk {
HRESULT res; HRESULT res;
Com<d3d9::IDirect3DQuery9> pQuery; Com<d3d9::IDirect3DQuery9> pQuery;
switch (DevInfoID) { switch (DevInfoID) {
// pre-D3D8 queries // pre-D3D8 queries
case 0: case 0:
@ -81,7 +81,7 @@ namespace dxvk {
case D3DDEVINFOID_D3DTEXTUREMANAGER: case D3DDEVINFOID_D3DTEXTUREMANAGER:
case D3DDEVINFOID_TEXTURING: case D3DDEVINFOID_TEXTURING:
return E_FAIL; return E_FAIL;
case D3DDEVINFOID_VCACHE: case D3DDEVINFOID_VCACHE:
// The query will return D3D_OK on Nvidia and D3DERR_NOTAVAILABLE on AMD/Intel // The query will return D3D_OK on Nvidia and D3DERR_NOTAVAILABLE on AMD/Intel
// in D3D9, however in the case of the latter we'll need to return a // in D3D9, however in the case of the latter we'll need to return a
@ -148,7 +148,7 @@ namespace dxvk {
return GetD3D9()->GetAvailableTextureMem(); return GetD3D9()->GetAvailableTextureMem();
} }
HRESULT STDMETHODCALLTYPE D3D8Device::ResourceManagerDiscardBytes(DWORD bytes) { HRESULT STDMETHODCALLTYPE D3D8Device::ResourceManagerDiscardBytes(DWORD bytes) {
return GetD3D9()->EvictManagedResources(); return GetD3D9()->EvictManagedResources();
} }
@ -165,7 +165,7 @@ namespace dxvk {
HRESULT res = GetD3D9()->GetDeviceCaps(&caps9); HRESULT res = GetD3D9()->GetDeviceCaps(&caps9);
if (likely(SUCCEEDED(res))) if (likely(SUCCEEDED(res)))
dxvk::ConvertCaps8(caps9, pCaps); ConvertCaps8(caps9, pCaps);
return res; return res;
} }
@ -207,7 +207,7 @@ namespace dxvk {
if (unlikely(pPresentationParameters == nullptr || ppSwapChain == nullptr)) if (unlikely(pPresentationParameters == nullptr || ppSwapChain == nullptr))
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
Com<d3d9::IDirect3DSwapChain9> pSwapChain9; Com<d3d9::IDirect3DSwapChain9> pSwapChain9;
d3d9::D3DPRESENT_PARAMETERS params = ConvertPresentParameters9(pPresentationParameters); d3d9::D3DPRESENT_PARAMETERS params = ConvertPresentParameters9(pPresentationParameters);
HRESULT res = GetD3D9()->CreateAdditionalSwapChain( HRESULT res = GetD3D9()->CreateAdditionalSwapChain(
@ -429,7 +429,7 @@ namespace dxvk {
if (likely(SUCCEEDED(res))) if (likely(SUCCEEDED(res)))
*ppVertexBuffer = ref(new D3D8VertexBuffer(this, std::move(pVertexBuffer9), Pool, Usage)); *ppVertexBuffer = ref(new D3D8VertexBuffer(this, std::move(pVertexBuffer9), Pool, Usage));
return res; return res;
} }
@ -446,10 +446,10 @@ namespace dxvk {
Com<d3d9::IDirect3DIndexBuffer9> pIndexBuffer9 = nullptr; Com<d3d9::IDirect3DIndexBuffer9> pIndexBuffer9 = nullptr;
HRESULT res = GetD3D9()->CreateIndexBuffer(Length, Usage, d3d9::D3DFORMAT(Format), d3d9::D3DPOOL(Pool), &pIndexBuffer9, NULL); HRESULT res = GetD3D9()->CreateIndexBuffer(Length, Usage, d3d9::D3DFORMAT(Format), d3d9::D3DPOOL(Pool), &pIndexBuffer9, NULL);
if (likely(SUCCEEDED(res))) if (likely(SUCCEEDED(res)))
*ppIndexBuffer = ref(new D3D8IndexBuffer(this, std::move(pIndexBuffer9), Pool, Usage)); *ppIndexBuffer = ref(new D3D8IndexBuffer(this, std::move(pIndexBuffer9), Pool, Usage));
return res; return res;
} }
@ -570,7 +570,7 @@ namespace dxvk {
res = src->LockRect(&srcLocked, &srcRect, D3DLOCK_READONLY); res = src->LockRect(&srcLocked, &srcRect, D3DLOCK_READONLY);
if (FAILED(res)) if (FAILED(res))
return res; return res;
res = dst->LockRect(&dstLocked, &dstRect, 0); res = dst->LockRect(&dstLocked, &dstRect, 0);
if (FAILED(res)) { if (FAILED(res)) {
src->UnlockRect(); src->UnlockRect();
@ -1012,7 +1012,7 @@ namespace dxvk {
} }
HRESULT STDMETHODCALLTYPE D3D8Device::BeginScene() { return GetD3D9()->BeginScene(); } HRESULT STDMETHODCALLTYPE D3D8Device::BeginScene() { return GetD3D9()->BeginScene(); }
HRESULT STDMETHODCALLTYPE D3D8Device::EndScene() { StateChange(); return GetD3D9()->EndScene(); } HRESULT STDMETHODCALLTYPE D3D8Device::EndScene() { StateChange(); return GetD3D9()->EndScene(); }
HRESULT STDMETHODCALLTYPE D3D8Device::Clear( HRESULT STDMETHODCALLTYPE D3D8Device::Clear(
@ -1115,7 +1115,7 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE D3D8Device::GetClipPlane(DWORD Index, float* pPlane) { HRESULT STDMETHODCALLTYPE D3D8Device::GetClipPlane(DWORD Index, float* pPlane) {
return GetD3D9()->GetClipPlane(Index, pPlane); return GetD3D9()->GetClipPlane(Index, pPlane);
} }
HRESULT STDMETHODCALLTYPE D3D8Device::CreateStateBlock( HRESULT STDMETHODCALLTYPE D3D8Device::CreateStateBlock(
D3DSTATEBLOCKTYPE Type, D3DSTATEBLOCKTYPE Type,
DWORD* pToken) { DWORD* pToken) {
@ -1404,7 +1404,7 @@ namespace dxvk {
m_streams[0] = D3D8VBO {nullptr, 0}; m_streams[0] = D3D8VBO {nullptr, 0};
m_indices = nullptr; m_indices = nullptr;
m_baseVertexIndex = 0; m_baseVertexIndex = 0;
return GetD3D9()->DrawIndexedPrimitiveUP( return GetD3D9()->DrawIndexedPrimitiveUP(
d3d9::D3DPRIMITIVETYPE(PrimitiveType), d3d9::D3DPRIMITIVETYPE(PrimitiveType),
MinVertexIndex, MinVertexIndex,
@ -1490,12 +1490,12 @@ namespace dxvk {
if (unlikely(StreamNumber >= d8caps::MAX_STREAMS)) if (unlikely(StreamNumber >= d8caps::MAX_STREAMS))
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
const D3D8VBO& vbo = m_streams[StreamNumber]; const D3D8VBO& vbo = m_streams[StreamNumber];
*ppStreamData = vbo.buffer.ref(); *ppStreamData = vbo.buffer.ref();
*pStride = vbo.stride; *pStride = vbo.stride;
return D3D_OK; return D3D_OK;
} }
@ -1719,7 +1719,7 @@ namespace dxvk {
info.function.push_back(pFunction[i]); info.function.push_back(pFunction[i]);
info.function.push_back(D3DVS_END()); info.function.push_back(D3DVS_END());
} }
D3D9VertexShaderCode result = TranslateVertexShader8(pDeclaration, pFunction, m_d3d8Options); D3D9VertexShaderCode result = TranslateVertexShader8(pDeclaration, pFunction, m_d3d8Options);
// Create vertex declaration // Create vertex declaration
@ -1821,7 +1821,7 @@ namespace dxvk {
/* /*
// Slow path. Use to debug cached shader validation. // // Slow path. Use to debug cached shader validation. //
d3d9::IDirect3DVertexShader9* pVertexShader; d3d9::IDirect3DVertexShader9* pVertexShader;
HRESULT res = GetD3D9()->GetVertexShader(&pVertexShader); HRESULT res = GetD3D9()->GetVertexShader(&pVertexShader);
@ -1873,12 +1873,12 @@ namespace dxvk {
if (unlikely(!pInfo)) if (unlikely(!pInfo))
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
UINT SizeOfData = *pSizeOfData; UINT SizeOfData = *pSizeOfData;
// Get actual size // Get actual size
UINT ActualSize = pInfo->declaration.size() * sizeof(DWORD); UINT ActualSize = pInfo->declaration.size() * sizeof(DWORD);
if (pData == nullptr) { if (pData == nullptr) {
*pSizeOfData = ActualSize; *pSizeOfData = ActualSize;
return D3D_OK; return D3D_OK;
@ -1903,12 +1903,12 @@ namespace dxvk {
if (unlikely(!pInfo)) if (unlikely(!pInfo))
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
UINT SizeOfData = *pSizeOfData; UINT SizeOfData = *pSizeOfData;
// Get actual size // Get actual size
UINT ActualSize = pInfo->function.size() * sizeof(DWORD); UINT ActualSize = pInfo->function.size() * sizeof(DWORD);
if (pData == nullptr) { if (pData == nullptr) {
*pSizeOfData = ActualSize; *pSizeOfData = ActualSize;
return D3D_OK; return D3D_OK;
@ -1946,7 +1946,7 @@ namespace dxvk {
} }
d3d9::IDirect3DPixelShader9* pPixelShader; d3d9::IDirect3DPixelShader9* pPixelShader;
HRESULT res = GetD3D9()->CreatePixelShader(pFunction, &pPixelShader); HRESULT res = GetD3D9()->CreatePixelShader(pFunction, &pPixelShader);
if (likely(SUCCEEDED(res))) { if (likely(SUCCEEDED(res))) {
@ -1959,7 +1959,7 @@ namespace dxvk {
} }
inline d3d9::IDirect3DPixelShader9* getPixelShaderPtr(D3D8Device* device, DWORD Handle) { inline d3d9::IDirect3DPixelShader9* getPixelShaderPtr(D3D8Device* device, DWORD Handle) {
Handle = getShaderIndex(Handle); Handle = getShaderIndex(Handle);
if (unlikely(Handle >= device->m_pixelShaders.size())) { if (unlikely(Handle >= device->m_pixelShaders.size())) {
@ -2045,11 +2045,11 @@ namespace dxvk {
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
UINT SizeOfData = *pSizeOfData; UINT SizeOfData = *pSizeOfData;
// Get actual size // Get actual size
UINT ActualSize = 0; UINT ActualSize = 0;
pPixelShader->GetFunction(nullptr, &ActualSize); pPixelShader->GetFunction(nullptr, &ActualSize);
if (pData == nullptr) { if (pData == nullptr) {
*pSizeOfData = ActualSize; *pSizeOfData = ActualSize;
return D3D_OK; return D3D_OK;

View File

@ -27,18 +27,19 @@ namespace dxvk {
class D3D8Device final : public D3D8DeviceBase { class D3D8Device final : public D3D8DeviceBase {
friend class D3D8StateBlock; friend class D3D8StateBlock;
public: public:
D3D8Device( D3D8Device(
D3D8Interface* pParent, D3D8Interface* pParent,
Com<d3d9::IDirect3DDevice9>&& pDevice, Com<d3d9::IDirect3DDevice9>&& pDevice,
D3DDEVTYPE DeviceType, D3DDEVTYPE DeviceType,
HWND hFocusWindow, HWND hFocusWindow,
DWORD BehaviorFlags, DWORD BehaviorFlags,
D3DPRESENT_PARAMETERS* pParams); D3DPRESENT_PARAMETERS* pParams);
~D3D8Device(); ~D3D8Device();
HRESULT STDMETHODCALLTYPE TestCooperativeLevel(); HRESULT STDMETHODCALLTYPE TestCooperativeLevel();
UINT STDMETHODCALLTYPE GetAvailableTextureMem(); UINT STDMETHODCALLTYPE GetAvailableTextureMem();
@ -206,7 +207,7 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE SetRenderState(D3DRENDERSTATETYPE State, DWORD Value); HRESULT STDMETHODCALLTYPE SetRenderState(D3DRENDERSTATETYPE State, DWORD Value);
HRESULT STDMETHODCALLTYPE GetRenderState(D3DRENDERSTATETYPE State, DWORD* pValue); HRESULT STDMETHODCALLTYPE GetRenderState(D3DRENDERSTATETYPE State, DWORD* pValue);
HRESULT STDMETHODCALLTYPE CreateStateBlock( HRESULT STDMETHODCALLTYPE CreateStateBlock(
D3DSTATEBLOCKTYPE Type, D3DSTATEBLOCKTYPE Type,
DWORD* pToken); DWORD* pToken);
@ -306,7 +307,7 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE GetVertexShaderConstant(DWORD Register, void* pConstantData, DWORD ConstantCount); HRESULT STDMETHODCALLTYPE GetVertexShaderConstant(DWORD Register, void* pConstantData, DWORD ConstantCount);
HRESULT STDMETHODCALLTYPE GetVertexShaderDeclaration(DWORD Handle, void* pData, DWORD* pSizeOfData); HRESULT STDMETHODCALLTYPE GetVertexShaderDeclaration(DWORD Handle, void* pData, DWORD* pSizeOfData);
HRESULT STDMETHODCALLTYPE GetVertexShaderFunction(DWORD Handle, void* pData, DWORD* pSizeOfData); HRESULT STDMETHODCALLTYPE GetVertexShaderFunction(DWORD Handle, void* pData, DWORD* pSizeOfData);
HRESULT STDMETHODCALLTYPE SetStreamSource( HRESULT STDMETHODCALLTYPE SetStreamSource(
@ -326,7 +327,7 @@ namespace dxvk {
UINT* pBaseVertexIndex); UINT* pBaseVertexIndex);
HRESULT STDMETHODCALLTYPE CreatePixelShader( HRESULT STDMETHODCALLTYPE CreatePixelShader(
const DWORD* pFunction, const DWORD* pFunction,
DWORD* pHandle); DWORD* pHandle);
HRESULT STDMETHODCALLTYPE SetPixelShader(DWORD Handle); HRESULT STDMETHODCALLTYPE SetPixelShader(DWORD Handle);
@ -356,8 +357,6 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE DeletePatch(UINT Handle); HRESULT STDMETHODCALLTYPE DeletePatch(UINT Handle);
public: // Internal Methods //
const D3D8Options* GetOptions() const { const D3D8Options* GetOptions() const {
return &m_d3d8Options; return &m_d3d8Options;
} }
@ -394,7 +393,7 @@ namespace dxvk {
m_backBuffers.clear(); m_backBuffers.clear();
m_backBuffers.resize(m_presentParams.BackBufferCount); m_backBuffers.resize(m_presentParams.BackBufferCount);
m_autoDepthStencil = nullptr; m_autoDepthStencil = nullptr;
} }
@ -437,7 +436,7 @@ namespace dxvk {
Com<D3D8VertexBuffer, false> buffer = nullptr; Com<D3D8VertexBuffer, false> buffer = nullptr;
UINT stride = 0; UINT stride = 0;
}; };
// Remember to fill() these in the constructor! // Remember to fill() these in the constructor!
std::array<Com<D3D8Texture2D, false>, d8caps::MAX_TEXTURE_STAGES> m_textures; std::array<Com<D3D8Texture2D, false>, d8caps::MAX_TEXTURE_STAGES> m_textures;
std::array<D3D8VBO, d8caps::MAX_STREAMS> m_streams; std::array<D3D8VBO, d8caps::MAX_STREAMS> m_streams;

View File

@ -29,7 +29,7 @@ namespace dxvk {
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))

View File

@ -3,6 +3,7 @@
#include "d3d8_include.h" #include "d3d8_include.h"
namespace dxvk { namespace dxvk {
constexpr bool isDXT(D3DFORMAT fmt) { constexpr bool isDXT(D3DFORMAT fmt) {
return fmt == D3DFMT_DXT1 return fmt == D3DFMT_DXT1
|| fmt == D3DFMT_DXT2 || fmt == D3DFMT_DXT2
@ -208,7 +209,6 @@ namespace dxvk {
return size; return size;
} }
constexpr UINT getSurfaceSize(D3DFORMAT Format, UINT Width, UINT Height) { constexpr UINT getSurfaceSize(D3DFORMAT Format, UINT Width, UINT Height) {
if (isDXT(Format)) { if (isDXT(Format)) {
Width = ((Width + 3) >> 2); Width = ((Width + 3) >> 2);

View File

@ -86,7 +86,7 @@ namespace d3d9 {
/** /**
* \brief Direct3D 9 * \brief Direct3D 9
* *
* All D3D9 interfaces are included within * All D3D9 interfaces are included within
* a namespace, so as not to collide with * a namespace, so as not to collide with
* D3D8 interfaces. * D3D8 interfaces.

View File

@ -5,8 +5,8 @@
#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);
@ -89,7 +89,7 @@ namespace dxvk
pIdentifier->WHQLLevel = identifier9.WHQLLevel; pIdentifier->WHQLLevel = identifier9.WHQLLevel;
} }
return res; return res;
} }

View File

@ -138,7 +138,7 @@ namespace dxvk {
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); ConvertCaps8(caps9, pCaps);
return res; return res;
} }

View File

@ -1,6 +1,7 @@
#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) {
@ -10,6 +11,7 @@ namespace dxvk {
*ppDirect3D8 = ref(new D3D8Interface()); *ppDirect3D8 = ref(new D3D8Interface());
return D3D_OK; return D3D_OK;
} }
} }
extern "C" { extern "C" {

View File

@ -1,4 +1,5 @@
#include "d3d8_options.h" #include "d3d8_options.h"
#include "../d3d9/d3d9_bridge.h" #include "../d3d9/d3d9_bridge.h"
#include "../util/config/config.h" #include "../util/config/config.h"
#include "../util/util_string.h" #include "../util/util_string.h"
@ -6,6 +7,7 @@
#include <charconv> #include <charconv>
namespace dxvk { namespace dxvk {
static inline uint32_t parseDword(std::string_view str) { static inline uint32_t parseDword(std::string_view str) {
uint32_t value = UINT32_MAX; uint32_t value = UINT32_MAX;
std::from_chars(str.data(), str.data() + str.size(), value); std::from_chars(str.data(), str.data() + str.size(), value);
@ -50,6 +52,6 @@ namespace dxvk {
forceVsDecl.emplace_back(D3DVSDE_REGISTER(reg), D3DVSDT_TYPE(type)); forceVsDecl.emplace_back(D3DVSDE_REGISTER(reg), D3DVSDT_TYPE(type));
} }
} }
} }

View File

@ -5,11 +5,12 @@
#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
@ -42,6 +43,7 @@ namespace dxvk {
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);
@ -53,4 +55,5 @@ namespace dxvk {
void parseVsDecl(const std::string& decl); void parseVsDecl(const std::string& decl);
}; };
} }

View File

@ -1,10 +1,10 @@
#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
*/ */
@ -12,7 +12,7 @@
#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> {
@ -93,7 +93,7 @@ namespace dxvk {
} catch (HRESULT err) { } catch (HRESULT err) {
if (riid == __uuidof(IDirect3DResource8)) if (riid == __uuidof(IDirect3DResource8))
return this; return this;
throw err; throw err;
} }
@ -107,5 +107,4 @@ namespace dxvk {
}; };
} }

View File

@ -333,4 +333,5 @@ namespace dxvk {
return result; return result;
} }
} }

View File

@ -3,14 +3,14 @@
namespace dxvk { namespace dxvk {
D3D8StateBlock::D3D8StateBlock( 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)
, m_isSWVP(pDevice->GetD3D9()->GetSoftwareVertexProcessing()) { , m_isSWVP(pDevice->GetD3D9()->GetSoftwareVertexProcessing()) {
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.

View File

@ -56,6 +56,7 @@ namespace dxvk {
protected: protected:
IDirect3DBaseTexture8* m_container; IDirect3DBaseTexture8* m_container;
}; };
} }

View File

@ -55,7 +55,7 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE D3D8Surface::ReleaseDC(HDC hDC) { HRESULT STDMETHODCALLTYPE D3D8Surface::ReleaseDC(HDC hDC) {
return GetD3D9()->ReleaseDC(hDC); return GetD3D9()->ReleaseDC(hDC);
} }
// 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> D3D8Surface::GetBlitImage() { Com<d3d9::IDirect3DSurface9> D3D8Surface::GetBlitImage() {
@ -78,11 +78,11 @@ namespace dxvk {
d3d9::D3DMULTISAMPLE_NONE, 0, d3d9::D3DMULTISAMPLE_NONE, 0,
FALSE, FALSE,
&image, &image,
NULL); NULL);
if (FAILED(res)) if (FAILED(res))
throw new DxvkError("D3D8: Failed to create blit image"); throw new DxvkError("D3D8: Failed to create blit image");
return image; return image;
} }

View File

@ -4,7 +4,7 @@
#include "d3d8_surface.h" #include "d3d8_surface.h"
namespace dxvk { namespace dxvk {
using D3D8SwapChainBase = D3D8DeviceChild<d3d9::IDirect3DSwapChain9, IDirect3DSwapChain8>; using D3D8SwapChainBase = D3D8DeviceChild<d3d9::IDirect3DSwapChain9, IDirect3DSwapChain8>;
class D3D8SwapChain final : public D3D8SwapChainBase { class D3D8SwapChain final : public D3D8SwapChainBase {

View File

@ -38,7 +38,7 @@ namespace dxvk {
} catch (HRESULT err) { } catch (HRESULT err) {
if (riid == __uuidof(IDirect3DBaseTexture8)) if (riid == __uuidof(IDirect3DBaseTexture8))
return this; return this;
throw err; throw err;
} }
@ -68,7 +68,7 @@ namespace dxvk {
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);
@ -90,7 +90,7 @@ namespace dxvk {
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>) {

View File

@ -8,7 +8,7 @@ namespace dxvk {
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 D3D8Volume::GetDesc(D3DVOLUME_DESC* pDesc) { HRESULT STDMETHODCALLTYPE D3D8Volume::GetDesc(D3DVOLUME_DESC* pDesc) {

View File

@ -3,7 +3,7 @@
#include "d3d8_subresource.h" #include "d3d8_subresource.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 {

View File

@ -38,7 +38,7 @@ namespace dxvk {
return this; return this;
if (riid == __uuidof(D3D8)) if (riid == __uuidof(D3D8))
return this; return this;
throw E_NOINTERFACE; throw E_NOINTERFACE;
} }
@ -58,7 +58,6 @@ namespace dxvk {
} }
} }
private: private:
Com<D3D9> m_d3d9; Com<D3D9> m_d3d9;

View File

@ -76,7 +76,7 @@ namespace dxvk {
if (dstTextureInfo->IsAutomaticMip()) if (dstTextureInfo->IsAutomaticMip())
m_device->MarkTextureMipsDirty(dstTextureInfo); m_device->MarkTextureMipsDirty(dstTextureInfo);
return D3D_OK; return D3D_OK;
} }
@ -108,4 +108,5 @@ namespace dxvk {
const Config* DxvkD3D8InterfaceBridge::GetConfig() const { const Config* DxvkD3D8InterfaceBridge::GetConfig() const {
return &m_interface->GetInstance()->config(); return &m_interface->GetInstance()->config();
} }
} }

View File

@ -6,7 +6,7 @@
/** /**
* 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.
*/ */
@ -23,14 +23,14 @@ IDxvkD3D8Bridge : public IUnknown {
/** /**
* \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
@ -50,14 +50,14 @@ 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;
@ -74,8 +74,11 @@ namespace dxvk {
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();
@ -93,12 +96,17 @@ namespace dxvk {
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();
@ -112,6 +120,9 @@ namespace dxvk {
const Config* GetConfig() const; const Config* GetConfig() const;
protected: protected:
D3D9InterfaceEx* m_interface; D3D9InterfaceEx* m_interface;
}; };
} }