Skip to content

Commit

Permalink
[WIP] Native Port Work
Browse files Browse the repository at this point in the history
  • Loading branch information
Joshua-Ashton committed Nov 6, 2019
1 parent 8667733 commit c333d4f
Show file tree
Hide file tree
Showing 49 changed files with 1,278 additions and 487 deletions.
32 changes: 31 additions & 1 deletion meson.build
Expand Up @@ -13,6 +13,8 @@ else
dxvk_msvc=false
endif

dxvk_native = (not meson.is_cross_build() and not dxvk_msvc) or get_option('dxvk_native_force')

if dxvk_compiler.get_id() == 'msvc'
add_project_arguments('/std:' + dxvk_cpp_std, language : 'cpp')
endif
Expand All @@ -32,6 +34,10 @@ code = '''#ifndef __WINE__
dxvk_winelib = dxvk_compiler.compiles(code, name: 'winelib check')
dxvk_extradep = [ ]

dxvk_platform = 'windows'
dxvk_wsi = 'win32'
so_prefix = ''

if dxvk_winelib
if dxvk_compiler.has_argument('--no-gnu-unique')
add_project_arguments('--no-gnu-unique', language : ['cpp'])
Expand All @@ -47,7 +53,7 @@ if dxvk_winelib
dll_ext = '.dll'
res_ext = '.res'
def_spec_ext = '.spec'
else
elif not dxvk_native
if dxvk_compiler.get_id() == 'msvc'
wrc = find_program('rc')
else
Expand Down Expand Up @@ -83,8 +89,28 @@ else
endif

def_spec_ext = '.def'
else
add_project_arguments('-DDXVK_NATIVE', language : 'cpp')

dxvk_wsi = get_option('dxvk_native_wsi')
dxvk_platform = target_machine.system()

dxvk_include_path = include_directories('./include', './include/native', './include/native/mingw')

lib_vulkan = dxvk_compiler.find_library('vulkan')
lib_sdl2 = dxvk_compiler.find_library('SDL2')

wrc = find_program('echo')
res_ext = ''
exe_ext = ''
dll_ext = ''
def_spec_ext = '.def'
so_prefix = 'lib'
endif

add_project_arguments('-DDXVK_WSI_' + dxvk_wsi.to_upper(), language : 'cpp')
add_project_arguments('-DDXVK_PLATFORM_' + dxvk_platform.to_upper(), language : 'cpp')

glsl_compiler = find_program('glslangValidator')
glsl_generator = generator(glsl_compiler,
output : [ '@BASENAME@.h' ],
Expand All @@ -94,6 +120,10 @@ if dxvk_compiler.get_id() == 'msvc'
wrc_generator = generator(wrc,
output : [ '@BASENAME@' + res_ext ],
arguments : [ '/fo', '@OUTPUT@', '@INPUT@' ])
elif dxvk_native
wrc_generator = generator(wrc,
output : [ '@BASENAME@_ignored.h' ],
arguments : [ 'Ignoring: ', '@INPUT@' ])
else
wrc_generator = generator(wrc,
output : [ '@BASENAME@' + res_ext ],
Expand Down
3 changes: 3 additions & 0 deletions meson_options.txt
Expand Up @@ -2,3 +2,6 @@ option('enable_tests', type : 'boolean', value : false)
option('enable_dxgi', type : 'boolean', value : true, description: 'Build DXGI')
option('enable_d3d10', type : 'boolean', value : true, description: 'Build D3D10')
option('enable_d3d11', type : 'boolean', value : true, description: 'Build D3D11')

option('dxvk_native_force', type : 'boolean', value : false, description: 'Force building using DXVK native. Eg. for Windows')
option('dxvk_native_wsi', type : 'string', value : 'sdl2', description: 'WSI system to use if building natively.')
4 changes: 2 additions & 2 deletions src/d3d10/d3d10_multithread.cpp
Expand Up @@ -17,8 +17,8 @@ namespace dxvk {


bool D3D10DeviceMutex::try_lock() {
uint32_t threadId = GetCurrentThreadId();
uint32_t expected = 0;
thread_id threadId = dxvk::this_thread::get_id();
thread_id expected = 0;

bool status = m_owner.compare_exchange_weak(
expected, threadId, std::memory_order_acquire);
Expand Down
4 changes: 2 additions & 2 deletions src/d3d10/d3d10_multithread.h
Expand Up @@ -22,8 +22,8 @@ namespace dxvk {

private:

std::atomic<uint32_t> m_owner = { 0u };
uint32_t m_counter = { 0u };
std::atomic<thread_id> m_owner = { 0u };
uint32_t m_counter = { 0u };

};

Expand Down
2 changes: 2 additions & 0 deletions src/d3d11/d3d11_device.cpp
Expand Up @@ -2535,8 +2535,10 @@ namespace dxvk {
return context->QueryInterface(riid, ppvObject);
}

#ifndef DXVK_NATIVE

This comment has been minimized.

Copy link
@doitsujin

doitsujin Nov 15, 2019

Why?

if (riid == __uuidof(ID3D11Debug))
return E_NOINTERFACE;
#endif

// Undocumented interfaces that are queried by some games
if (riid == GUID{0xd56e2a4c,0x5127,0x8437,{0x65,0x8a,0x98,0xc5,0xbb,0x78,0x94,0x98}})
Expand Down
2 changes: 1 addition & 1 deletion src/d3d11/d3d11_include.h
Expand Up @@ -44,7 +44,7 @@ typedef enum D3D11_FORMAT_SUPPORT2 {
#ifndef __WINE__

//MinGW-Headers supports these typedefs since 6.0.0
#if !defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 6
#if (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 6) && !defined(DXVK_NATIVE)
typedef enum D3D11_COPY_FLAGS {
D3D11_COPY_NO_OVERWRITE = 0x1,
D3D11_COPY_DISCARD = 0x2,
Expand Down
3 changes: 3 additions & 0 deletions src/d3d11/d3d11_interfaces.h
Expand Up @@ -97,6 +97,9 @@ ID3D11VkExtContext : public IUnknown {
#ifdef _MSC_VER
struct __declspec(uuid("8a6e3c42-f74c-45b7-8265-a231b677ca17")) ID3D11VkExtDevice;
struct __declspec(uuid("fd0bca13-5cb6-4c3a-987e-4750de2ca791")) ID3D11VkExtContext;
#elif DXVK_NATIVE
DECLARE_UUIDOF_HELPER(ID3D11VkExtDevice, 0x8a6e3c42,0xf74c,0x45b7,0x82,0x65,0xa2,0x31,0xb6,0x77,0xca,0x17);
DECLARE_UUIDOF_HELPER(ID3D11VkExtContext,0xfd0bca13,0x5cb6,0x4c3a,0x98,0x7e,0x47,0x50,0xde,0x2c,0xa7,0x91);
#else
DXVK_DEFINE_GUID(ID3D11VkExtDevice);
DXVK_DEFINE_GUID(ID3D11VkExtContext);
Expand Down
2 changes: 1 addition & 1 deletion src/d3d11/d3d11_options.cpp
Expand Up @@ -23,7 +23,7 @@ namespace dxvk {
&& DxvkGpuVendor(devInfo.core.properties.vendorID) != DxvkGpuVendor::Amd;

bool apitraceAttached = false;
#ifndef __WINE__
#if !defined(__WINE__) && !defined(DXVK_NATIVE)
apitraceAttached = ::GetModuleHandle("dxgitrace.dll") != nullptr;
#endif

Expand Down
25 changes: 22 additions & 3 deletions src/d3d11/meson.build
Expand Up @@ -41,7 +41,6 @@ d3d11_src = [
'd3d11_depth_stencil.cpp',
'd3d11_device.cpp',
'd3d11_enums.cpp',
'd3d11_gdi.cpp',
'd3d11_initializer.cpp',
'd3d11_input_layout.cpp',
'd3d11_interop.cpp',
Expand All @@ -63,12 +62,32 @@ d3d11_src = [
'd3d11_view_uav.cpp',
]

d3d11_dll = shared_library('d3d11'+dll_ext, dxgi_common_src + d3d11_src + d3d10_src, glsl_generator.process(dxgi_shaders), d3d11_res,
d3d11_src_win32 = [
'platform/d3d11_gdi_win32.cpp'
]

d3d11_src_linux = [
'platform/d3d11_gdi_stub.cpp'
]

if dxvk_platform == 'win32'
d3d11_src += d3d11_src_win32
elif dxvk_platform == 'linux'
d3d11_src += d3d11_src_linux
else
error('Unknown platform for d3d11')
endif

if dxvk_native
lib_dxgi = dxgi_dep
endif

d3d11_dll = shared_library(so_prefix+'d3d11'+dll_ext, dxgi_common_src + d3d11_src + d3d10_src, glsl_generator.process(dxgi_shaders), d3d11_res,
name_prefix : '',
dependencies : [ lib_dxgi, dxbc_dep, dxvk_dep ],
include_directories : dxvk_include_path,
install : true,
objects : not dxvk_msvc ? 'd3d11'+def_spec_ext : [],
objects : not dxvk_msvc and not dxvk_native ? 'd3d11'+def_spec_ext : [],
vs_module_defs : 'd3d11'+def_spec_ext,
override_options : ['cpp_std='+dxvk_cpp_std])

Expand Down
37 changes: 37 additions & 0 deletions src/d3d11/platform/d3d11_gdi_stub.cpp
@@ -0,0 +1,37 @@
#include "d3d11_context.h"
#include "d3d11_device.h"
#include "d3d11_gdi.h"

namespace dxvk {

D3D11GDISurface::D3D11GDISurface(
ID3D11Resource* pResource,
UINT Subresource)
: m_resource (pResource),
m_subresource (Subresource),
m_readback (nullptr),
m_hdc (nullptr),
m_hbitmap (nullptr),
m_acquired (false) { }


D3D11GDISurface::~D3D11GDISurface() {
}


HRESULT D3D11GDISurface::Acquire(BOOL Discard, HDC* phdc) {
Logger::err("D3D11: GDI Interop not supported on this platform.");
return DXGI_ERROR_INVALID_CALL;
}


HRESULT D3D11GDISurface::Release(const RECT* pDirtyRect) {
Logger::err("D3D11: GDI Interop not supported on this platform.");

return DXGI_ERROR_INVALID_CALL;
}


HRESULT D3D11GDISurface::CreateReadbackResource() { return S_OK; }

This comment has been minimized.

Copy link
@doitsujin

doitsujin Nov 15, 2019

Formatting. Don't put everything into a single line for non-inline methods.


}
File renamed without changes.
7 changes: 6 additions & 1 deletion src/dxgi/dxgi_adapter.cpp
Expand Up @@ -141,7 +141,7 @@ namespace dxvk {
}

// TODO support multiple monitors
HMONITOR monitor = ::MonitorFromPoint({ 0, 0 }, MONITOR_DEFAULTTOPRIMARY);
HMONITOR monitor = GetPrimaryMonitor();

This comment has been minimized.

Copy link
@doitsujin

doitsujin Nov 15, 2019

This isn't forward-looking, and I'd much rather have a method EnumMonitors somewhere that would return a monitor with the given number, even if we only support 0 as an argument for now.

*ppOutput = ref(new DxgiOutput(m_factory, this, monitor));
return S_OK;
}
Expand Down Expand Up @@ -223,8 +223,13 @@ namespace dxvk {

// Convert device name
std::memset(pDesc->Description, 0, sizeof(pDesc->Description));

#ifndef DXVK_NATIVE
::MultiByteToWideChar(CP_UTF8, 0, deviceProp.deviceName, -1,
pDesc->Description, sizeof(pDesc->Description) / sizeof(*pDesc->Description));
#else
mbstowcs(pDesc->Description, deviceProp.deviceName, sizeof(pDesc->Description) / sizeof(*pDesc->Description));

This comment has been minimized.

Copy link
@doitsujin

doitsujin Nov 15, 2019

std:: prefix.

Also I'd prefer to have a generic implementation of this somewhere, rather than #ifdef hacks inside DXGI code.

#endif

// Get amount of video memory
// based on the Vulkan heaps
Expand Down
2 changes: 1 addition & 1 deletion src/dxgi/dxgi_include.h
@@ -1,7 +1,7 @@
#pragma once

//for some reason we need to specify __declspec(dllexport) for MinGW
#if defined(__WINE__)
#if defined(__WINE__) || defined(DXVK_NATIVE)
#define DLLEXPORT __attribute__((visibility("default")))
#elif defined(_MSC_VER)
#define DLLEXPORT
Expand Down
8 changes: 8 additions & 0 deletions src/dxgi/dxgi_interfaces.h
Expand Up @@ -326,6 +326,14 @@ struct __declspec(uuid("e2ef5fa5-dc21-4af7-90c4-f67ef6a09323")) IDXGIVkInteropDe
struct __declspec(uuid("5546cf8c-77e7-4341-b05d-8d4d5000e77d")) IDXGIVkInteropSurface;
struct __declspec(uuid("104001a6-7f36-4957-b932-86ade9567d91")) IDXGIVkSwapChain;
struct __declspec(uuid("53cb4ff0-c25a-4164-a891-0e83db0a7aac")) IWineDXGISwapChainFactory;
#elif DXVK_NATIVE
DECLARE_UUIDOF_HELPER(IDXGIDXVKAdapter, 0x907bf281,0xea3c,0x43b4,0xa8,0xe4,0x9f,0x23,0x11,0x07,0xb4,0xff);
DECLARE_UUIDOF_HELPER(IDXGIVkMonitorInfo, 0xc06a236f,0x5be3,0x448a,0x89,0x43,0x89,0xc6,0x11,0xc0,0xc2,0xc1);
DECLARE_UUIDOF_HELPER(IDXGIVkInteropAdapter, 0x3a6d8f2c,0xb0e8,0x4ab4,0xb4,0xdc,0x4f,0xd2,0x48,0x91,0xbf,0xa5);
DECLARE_UUIDOF_HELPER(IDXGIVkInteropDevice, 0xe2ef5fa5,0xdc21,0x4af7,0x90,0xc4,0xf6,0x7e,0xf6,0xa0,0x93,0x23);
DECLARE_UUIDOF_HELPER(IDXGIVkInteropSurface, 0x5546cf8c,0x77e7,0x4341,0xb0,0x5d,0x8d,0x4d,0x50,0x00,0xe7,0x7d);
DECLARE_UUIDOF_HELPER(IDXGIVkSwapChain, 0x104001a6,0x7f36,0x4957,0xb9,0x32,0x86,0xad,0xe9,0x56,0x7d,0x91);
DECLARE_UUIDOF_HELPER(IWineDXGISwapChainFactory, 0x53cb4ff0,0xc25a,0x4164,0xa8,0x91,0x0e,0x83,0xdb,0x0a,0x7a,0xac);
#else
DXVK_DEFINE_GUID(IDXGIDXVKAdapter);
DXVK_DEFINE_GUID(IDXGIVkMonitorInfo);
Expand Down
78 changes: 0 additions & 78 deletions src/dxgi/dxgi_monitor.cpp
Expand Up @@ -89,82 +89,4 @@ namespace dxvk {
}
}


HRESULT GetMonitorDisplayMode(
HMONITOR hMonitor,
DWORD ModeNum,
DXGI_MODE_DESC* pMode) {
::MONITORINFOEXW monInfo;
monInfo.cbSize = sizeof(monInfo);

if (!::GetMonitorInfoW(hMonitor, reinterpret_cast<MONITORINFO*>(&monInfo))) {
Logger::err("DXGI: Failed to query monitor info");
return E_FAIL;
}

DEVMODEW devMode = { };
devMode.dmSize = sizeof(devMode);

if (!::EnumDisplaySettingsW(monInfo.szDevice, ModeNum, &devMode))
return DXGI_ERROR_NOT_FOUND;

pMode->Width = devMode.dmPelsWidth;
pMode->Height = devMode.dmPelsHeight;
pMode->RefreshRate = { devMode.dmDisplayFrequency, 1 };
pMode->Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; // FIXME
pMode->ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE;
pMode->Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
return S_OK;
}


HRESULT SetMonitorDisplayMode(
HMONITOR hMonitor,
const DXGI_MODE_DESC* pMode) {
::MONITORINFOEXW monInfo;
monInfo.cbSize = sizeof(monInfo);

if (!::GetMonitorInfoW(hMonitor, reinterpret_cast<MONITORINFO*>(&monInfo))) {
Logger::err("DXGI: Failed to query monitor info");
return E_FAIL;
}

DEVMODEW devMode = { };
devMode.dmSize = sizeof(devMode);
devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
devMode.dmPelsWidth = pMode->Width;
devMode.dmPelsHeight = pMode->Height;
devMode.dmBitsPerPel = GetMonitorFormatBpp(pMode->Format);

if (pMode->RefreshRate.Numerator != 0) {
devMode.dmFields |= DM_DISPLAYFREQUENCY;
devMode.dmDisplayFrequency = pMode->RefreshRate.Numerator
/ pMode->RefreshRate.Denominator;
}

Logger::info(str::format("DXGI: Setting display mode: ",
devMode.dmPelsWidth, "x", devMode.dmPelsHeight, "@",
devMode.dmDisplayFrequency));

LONG status = ::ChangeDisplaySettingsExW(
monInfo.szDevice, &devMode, nullptr, CDS_FULLSCREEN, nullptr);

return status == DISP_CHANGE_SUCCESSFUL ? S_OK : DXGI_ERROR_NOT_CURRENTLY_AVAILABLE;;
}


void GetWindowClientSize(
HWND hWnd,
UINT* pWidth,
UINT* pHeight) {
RECT rect = { };
::GetClientRect(hWnd, &rect);

if (pWidth)
*pWidth = rect.right - rect.left;

if (pHeight)
*pHeight = rect.bottom - rect.top;
}

}
8 changes: 8 additions & 0 deletions src/dxgi/dxgi_monitor.h
Expand Up @@ -76,6 +76,7 @@ namespace dxvk {
* \returns S_OK on success
*/
HRESULT SetMonitorDisplayMode(
HWND hWnd,
HMONITOR hMonitor,
const DXGI_MODE_DESC* pMode);

Expand All @@ -91,4 +92,11 @@ namespace dxvk {
UINT* pWidth,
UINT* pHeight);

/**
* \brief Get the system's primary monitor
*
* \returns A handle the the primary monitor
*/
HMONITOR GetPrimaryMonitor();

}

0 comments on commit c333d4f

Please sign in to comment.