Skip to content

Commit

Permalink
Merge pull request microsoft#69 from lygstate/wsl-support-c-minimal
Browse files Browse the repository at this point in the history
WSL support for C code including d3d12.h.
  • Loading branch information
jenatali authored Jun 1, 2022
2 parents 107f25f + 2e23117 commit a4f80a9
Show file tree
Hide file tree
Showing 8 changed files with 234 additions and 55 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@
.vs
/out
/CMakeUserPresets.json
/build*
8 changes: 7 additions & 1 deletion include/wsl/stubs/rpcndr.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,10 @@

// Stub header to satisfy d3d12.h include
#pragma once
#define __RPCNDR_H_VERSION__
#define __RPCNDR_H_VERSION__

#ifdef CONST_VTABLE
#define CONST_VTBL const
#else
#define CONST_VTBL
#endif
3 changes: 3 additions & 0 deletions include/wsl/stubs/unknwn.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once

#include "unknwnbase.h"
124 changes: 124 additions & 0 deletions include/wsl/stubs/unknwnbase.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*-------------------------------------------------------------------------------------
*
* Copyright (c) Microsoft Corporation
* Licensed under the MIT license
*
*-------------------------------------------------------------------------------------*/

/* this ALWAYS GENERATED file contains the definitions for the interfaces */

/* File created by MIDL compiler version 8.01.0627 */

/* verify that the <rpcndr.h> version is high enough to compile this file*/
#ifndef __REQUIRED_RPCNDR_H_VERSION__
#define __REQUIRED_RPCNDR_H_VERSION__ 500
#endif

/* verify that the <rpcsal.h> version is high enough to compile this file*/
#ifndef __REQUIRED_RPCSAL_H_VERSION__
#define __REQUIRED_RPCSAL_H_VERSION__ 100
#endif

#include "rpc.h"
#include "rpcndr.h"

#ifndef __RPCNDR_H_VERSION__
#error this stub requires an updated version of <rpcndr.h>
#endif /* __RPCNDR_H_VERSION__ */

#ifndef COM_NO_WINDOWS_H
#include "windows.h"
#include "ole2.h"
#endif /*COM_NO_WINDOWS_H*/

#ifndef __unknwnbase_h__
#define __unknwnbase_h__

#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif

/* Forward Declarations */

#ifndef __IUnknown_FWD_DEFINED__
#define __IUnknown_FWD_DEFINED__
typedef interface IUnknown IUnknown;

#endif /* __IUnknown_FWD_DEFINED__ */

#ifndef __IUnknown_INTERFACE_DEFINED__
#define __IUnknown_INTERFACE_DEFINED__

/* interface IUnknown */
/* [unique][uuid][object][local] */

typedef /* [unique] */ IUnknown *LPUNKNOWN;

EXTERN_C const IID IID_IUnknown;

#if defined(__cplusplus) && !defined(CINTERFACE)
extern "C++"
{
MIDL_INTERFACE("00000000-0000-0000-c000-000000000046")
IUnknown
{
BEGIN_INTERFACE

virtual HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid,
void **ppvObject) = 0;

virtual ULONG STDMETHODCALLTYPE AddRef() = 0;

virtual ULONG STDMETHODCALLTYPE Release() = 0;

template <class Q>
HRESULT
STDMETHODCALLTYPE
QueryInterface(_COM_Outptr_ Q * *pp)
{
return QueryInterface(uuidof<Q>(), (void **)pp);
}
END_INTERFACE
};
}
#ifdef __CRT_UUID_DECL
__CRT_UUID_DECL(IUnknown, 0x00000000, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46)
#endif
#else
typedef struct IUnknownVtbl {
BEGIN_INTERFACE

/*** IUnknown methods ***/
HRESULT (STDMETHODCALLTYPE *QueryInterface)(
IUnknown *This,
REFIID riid,
void **ppvObject);

ULONG (STDMETHODCALLTYPE *AddRef)(
IUnknown *This);

ULONG (STDMETHODCALLTYPE *Release)(
IUnknown *This);

END_INTERFACE
} IUnknownVtbl;

interface IUnknown {
CONST_VTBL IUnknownVtbl* lpVtbl;
};

#ifdef COBJMACROS
/*** IUnknown methods ***/
#define IUnknown_QueryInterface(This,riid,ppvObject) (This)->lpVtbl->QueryInterface(This,riid,ppvObject)
#define IUnknown_AddRef(This) (This)->lpVtbl->AddRef(This)
#define IUnknown_Release(This) (This)->lpVtbl->Release(This)
#endif

#endif

#endif /* __IUnknown_INTERFACE_DEFINED__ */

DEFINE_GUID(IID_IUnknown, 0x00000000, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46);

#endif /* __unknwnbase_h__ */
120 changes: 68 additions & 52 deletions include/wsl/winadapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ typedef uint8_t UINT8;
typedef int8_t INT8;
typedef uint16_t UINT16;
typedef int16_t INT16;
typedef uint32_t UINT32, UINT, ULONG, DWORD, BOOL;
typedef uint32_t UINT32, UINT, ULONG, DWORD, BOOL, WINBOOL;
typedef int32_t INT32, INT, LONG;
typedef uint64_t UINT64, ULONG_PTR;
typedef int64_t INT64, LONG_PTR;
Expand Down Expand Up @@ -63,21 +63,17 @@ typedef const wchar_t *LPCWSTR, *PCWSTR;
#define ULONG_MAX UINT_MAX

// Misc defines
#define interface struct
#define MIDL_INTERFACE(x) interface
#define __analysis_assume(x)
#define TRUE 1u
#define FALSE 0u
#define DECLARE_INTERFACE(iface) interface iface
#define PURE = 0
#define THIS_
#define DECLSPEC_UUID(x)
#define DECLSPEC_NOVTABLE
#define DECLSPEC_SELECTANY
#ifdef __cplusplus
#define EXTERN_C extern "C"
#else
#define EXTERN_C
#define EXTERN_C extern
#endif
#define APIENTRY
#define OUT
Expand Down Expand Up @@ -110,23 +106,21 @@ typedef struct _GUID {
} GUID;

#ifdef __cplusplus
#ifdef INITGUID
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) extern "C" const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
#else
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) extern "C" const GUID name
#endif

template <typename T> GUID uuidof() = delete;
template <typename T> GUID uuidof(T*) { return uuidof<T>(); }
template <typename T> GUID uuidof(T**) { return uuidof<T>(); }
template <typename T> GUID uuidof(T&) { return uuidof<T>(); }
#define __uuidof(x) uuidof(x)
#else
#endif

#ifdef INITGUID
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
#ifdef __cplusplus
#define DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) EXTERN_C const GUID DECLSPEC_SELECTANY name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
#else
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) extern const GUID name
#define DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) const GUID DECLSPEC_SELECTANY name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
#endif
#else
#define DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) EXTERN_C const GUID name
#endif

typedef GUID IID;
Expand Down Expand Up @@ -228,12 +222,49 @@ inline bool operator!=(REFGUID guidOne, REFGUID guidOther)
#define __stdcall
#define STDMETHODCALLTYPE
#define STDAPICALLTYPE
#define STDAPI extern "C" HRESULT STDAPICALLTYPE
#define STDAPI EXTERN_C HRESULT STDAPICALLTYPE
#define WINAPI
#define STDMETHOD(name) virtual HRESULT name
#define STDMETHOD_(type,name) virtual type name
#define IFACEMETHOD(method) /*__override*/ STDMETHOD(method)
#define IFACEMETHOD_(type, method) /*__override*/ STDMETHOD_(type, method)

#define interface struct
#if defined (__cplusplus) && !defined (CINTERFACE)
#define STDMETHOD(method) virtual HRESULT STDMETHODCALLTYPE method
#define STDMETHOD_(type, method) virtual type STDMETHODCALLTYPE method
#define PURE = 0
#define THIS_
#define THIS void
#define DECLARE_INTERFACE(iface) interface DECLSPEC_NOVTABLE iface
#define DECLARE_INTERFACE_(iface, baseiface) interface DECLSPEC_NOVTABLE iface : public baseiface

interface IUnknown;
extern "C++"
{
template<typename T> void** IID_PPV_ARGS_Helper(T** pp)
{
static_cast<IUnknown*>(*pp);
return reinterpret_cast<void**>(pp);
}
}
#define IID_PPV_ARGS(ppType) __uuidof (**(ppType)), IID_PPV_ARGS_Helper (ppType)
#else
#define STDMETHOD(method) HRESULT (STDMETHODCALLTYPE *method)
#define STDMETHOD_(type, method) type (STDMETHODCALLTYPE *method)
#define PURE
#define THIS_ INTERFACE *This,
#define THIS INTERFACE *This
#ifdef CONST_VTABLE
#define DECLARE_INTERFACE(iface) typedef interface iface { const struct iface##Vtbl *lpVtbl; } iface; typedef const struct iface##Vtbl iface##Vtbl; const struct iface##Vtbl
#else
#define DECLARE_INTERFACE(iface) typedef interface iface { struct iface##Vtbl *lpVtbl; } iface; typedef struct iface##Vtbl iface##Vtbl; struct iface##Vtbl
#endif
#define DECLARE_INTERFACE_(iface, baseiface) DECLARE_INTERFACE (iface)
#endif

#define IFACEMETHOD(method) /*override*/ STDMETHOD (method)
#define IFACEMETHOD_(type, method) /*override*/ STDMETHOD_(type, method)
#ifndef BEGIN_INTERFACE
#define BEGIN_INTERFACE
#define END_INTERFACE
#endif

// Error codes
typedef LONG HRESULT;
Expand Down Expand Up @@ -298,7 +329,12 @@ typedef ULARGE_INTEGER *PULARGE_INTEGER;
}; \
typedef struct name##__ *name

struct SECURITY_ATTRIBUTES;
typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength;
LPVOID lpSecurityDescriptor;
WINBOOL bInheritHandle;
} SECURITY_ATTRIBUTES;

struct STATSTG;

#ifdef __cplusplus
Expand Down Expand Up @@ -352,44 +388,15 @@ inline constexpr ENUMTYPE operator ~ (ENUMTYPE a) { return ENUMTYPE(~((_ENUM_FLA
inline constexpr ENUMTYPE operator ^ (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((_ENUM_FLAG_SIZED_INTEGER<ENUMTYPE>::type)a) ^ ((_ENUM_FLAG_SIZED_INTEGER<ENUMTYPE>::type)b)); } \
inline ENUMTYPE &operator ^= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((_ENUM_FLAG_SIZED_INTEGER<ENUMTYPE>::type &)a) ^= ((_ENUM_FLAG_SIZED_INTEGER<ENUMTYPE>::type)b)); } \
}
#else
#define DEFINE_ENUM_FLAG_OPERATORS(ENUMTYPE) /* */
#endif

// D3DX12 uses these
#include <stdlib.h>
#define HeapAlloc(heap, flags, size) malloc(size)
#define HeapFree(heap, flags, ptr) free(ptr)

#ifdef __cplusplus
// IUnknown

interface DECLSPEC_UUID("00000000-0000-0000-C000-000000000046") DECLSPEC_NOVTABLE IUnknown
{
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) = 0;
virtual ULONG STDMETHODCALLTYPE AddRef() = 0;
virtual ULONG STDMETHODCALLTYPE Release() = 0;

template <class Q> HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp) {
return QueryInterface(uuidof<Q>(), (void **)pp);
}
};

template <> constexpr GUID uuidof<IUnknown>()
{
return { 0x00000000, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
}

extern "C++"
{
template<typename T> void** IID_PPV_ARGS_Helper(T** pp)
{
static_cast<IUnknown*>(*pp);
return reinterpret_cast<void**>(pp);
}
}

#define IID_PPV_ARGS(ppType) __uuidof(**(ppType)), IID_PPV_ARGS_Helper(ppType)
#endif

#if defined(lint)
// Note: lint -e530 says don't complain about uninitialized variables for
// this variable. Error 527 has to do with unreachable code.
Expand All @@ -403,3 +410,12 @@ extern "C++"
#else
#define UNREFERENCED_PARAMETER(P) (P)
#endif

#include <unknwn.h>

#if defined(__cplusplus) && !defined(CINTERFACE)
template <> constexpr GUID uuidof<IUnknown>()
{
return { 0x00000000, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
}
#endif
6 changes: 5 additions & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ if(EXISTS "/usr/lib/wsl/lib/")
list(APPEND dxlibs ${libd3d12} ${libdxcore})
else()
# Fallback to default: let CMake look for libs
list(APPEND dxlibs d3d12 dxcore)
list(APPEND dxlibs d3d12)
if (MSVC)
# MINGW doesn't have dxcore yet
list(APPEND dxlibs dxcore)
endif()
endif()

project(DirectX-Headers-Test
Expand Down
10 changes: 10 additions & 0 deletions test/feature_check_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,16 @@ int run_per_adapter(IUnknown* adapter)
return 0;
}

#ifdef __MINGW32__
STDAPI
DXCoreCreateAdapterFactory(
REFIID riid,
_COM_Outptr_ void** ppvFactory
) {
return 0;
}
#endif

int main()
{
ComPtr<IDXCoreAdapterFactory> adapter_factory;
Expand Down
17 changes: 16 additions & 1 deletion test/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,26 @@
#include <directx/d3dx12.h>
#include "dxguids/dxguids.h"

#ifdef __MINGW32__
STDAPI
DXCoreCreateAdapterFactory(
REFIID riid,
_COM_Outptr_ void** ppvFactory
) {
return 0;
}
#endif

int check_uuid_linkage() {
auto uuid_i_unknown = IID_IUnknown;
return sizeof(uuid_i_unknown);
}

int main()
{
IDXCoreAdapter *adapter = nullptr;
ID3D12Device *device = nullptr;

check_uuid_linkage();
{
IDXCoreAdapterFactory *factory = nullptr;
if (FAILED(DXCoreCreateAdapterFactory(&factory)))
Expand Down

0 comments on commit a4f80a9

Please sign in to comment.