├── .gitignore ├── README.md ├── build.ps1 ├── dx12.jar ├── jextract.ps1 ├── pom.xml └── src └── main └── java ├── com └── dx12 │ └── DX12.java └── module-info.java /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | *.iml 3 | .build/ 4 | com/ 5 | *.class -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Building Project Panama 2 | 3 | Download pre-built LLVM binaries (version 10.0.0 used below) https://releases.llvm.org/download.html and install to `C:\` (spaces in path is an issue). 4 | 5 | Make sure autoconf, zip (via sudo apt-get). 6 | 7 | From WSL: 8 | 9 | ```sh 10 | git clone https://github.com/openjdk/panama-foreign 11 | git checkout foreign-jextract 12 | bash configure --with-boot-jdk="/mnt/c/Program Files/Java/jdk-14" --with-libclang="/mnt/c/Program Files/LLVM" --with-clang-version=10.0.0 13 | make 14 | ``` 15 | 16 | ## Run jextract on d3d12.h 17 | 18 | ```powershell 19 | $jdk = "C:\Users\mikee\dev\panama-foreign\build\windows-x86_64-server-release\jdk" 20 | nal -Name jextract -Value "$jdk\bin\jextract.exe" 21 | $I = "C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0" 22 | jextract -d out -t com.dx12 -I "$I\um" --filter "d3d12.h" -- "$I\um\d3d12.h" 23 | ``` 24 | 25 | ## jextract Arguments 26 | 27 | ``` 28 | Option Description 29 | ------ ----------- 30 | -?, -h, --help print help 31 | -C pass through argument for clang 32 | -I specify include files path 33 | -d specify where to place generated files 34 | --filter header files to filter 35 | -l specify a library 36 | --source generate java sources 37 | -t, --target-package target package for specified header files 38 | ``` -------------------------------------------------------------------------------- /build.ps1: -------------------------------------------------------------------------------- 1 | #$jdk = "C:\Users\mikee\dev\panama-foreign\build\windows-x86_64-server-release\jdk" 2 | $jdk = "C:\Program Files\Java\jdk-17" 3 | $lib = "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x64" 4 | $lib2 = "C:\Windows\System32" 5 | New-Alias -Name java -Value "$jdk\bin\java.exe" -Force 6 | New-Alias -Name javac -Value "$jdk\bin\javac.exe" -Force 7 | javac --add-modules jdk.incubator.foreign src\main\java\com\dx12\DX12.java src\main\java\com\dx12\WindowProc.java src\main\java\com\dx12\RuntimeHelper.java src\main\java\com\dx12\d3d12*.java src\main\java\com\dx12\dxgi*.java 8 | java "-XX:+CreateCoredumpOnCrash" "-XX:+ShowMessageBoxOnError" -cp src/main/java "-Dforeign.restricted=permit" "-Djava.library.path=C:\Windows\System32" --add-modules jdk.incubator.foreign com.dx12.DX12 9 | # javac src\main\java\com\dx12\Windows_h.java 10 | # jar -cf dx12.jar -C com/ dx12 11 | # javac -cp ".;dx12.jar" src\main\java\com\dx12\DX12.java 12 | # java -cp ".;dx12.jar" "-XX:+ShowMessageBoxOnError" "-Dforeign.restricted=permit" "-Djava.library.path=C:\Windows\System32" --add-modules jdk.incubator.foreign com\dx12\DX12 -------------------------------------------------------------------------------- /dx12.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brcolow/java-dx12/f589bbab9849b680f8c5f4f676beadf6e3389d80/dx12.jar -------------------------------------------------------------------------------- /jextract.ps1: -------------------------------------------------------------------------------- 1 | #$jdk = "C:\Users\mikee\dev\panama-foreign\build\windows-x86_64-server-release\jdk" 2 | $jdk = "C:\Program Files\Java\jdk-17" 3 | New-Alias -Name jextract -Value "$jdk\bin\jextract.exe" -Force 4 | $I = "C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0" 5 | # This does nothing because Windows.h is purely includes and we are using --filter, but according to Wikipedia: 6 | # Many of these files cannot simply be included by themselves (they are not self-contained), because of dependencies. 7 | # So this will need to be trial and error on what we need. We definitely need the CreateWindowEx function. 8 | jextract -Xmx2048m --source -d . -t com.dx12 -I "$I\um" -I "$I\shared" -C "-DWIN32_LEAN_AND_MEAN" -- "$I\um\Windows.h" 9 | # jextract --source -d . -t com.dx12 -I "$I\shared" -I "$I\um" -C "-DWIN32_LEAN_AND_MEAN=1" -C "-D_AMD64_=1" -- "$I\um\WinUser.h" 10 | jextract --source -d . -t com.dx12 -I "$I\um" --filter "d3d12.h" -- "$I\um\d3d12.h" 11 | jextract --source -d . -t com.dx12 -I "$I\um" --filter "d3dcommon.h" -- "$I\um\d3dcommon.h" 12 | jextract --source -d . -t com.dx12 -I "$I\um" --filter "d3d12sdklayers.h" -- "$I\um\d3d12sdklayers.h" 13 | jextract --source -d . -t com.dx12 -I "$I\um" --filter "dxgi.h" --filter "dxgicommon.h" --filter "dxgitype.h" -- "$I\shared\dxgi.h" 14 | jextract --source -d . -t com.dx12 -I "$I\um" --filter "dxgi1_2.h" -- "$I\shared\dxgi1_2.h" 15 | jextract --source -d . -t com.dx12 -I "$I\um" --filter "dxgi1_3.h" -- "$I\shared\dxgi1_3.h" 16 | jextract --source -d . -t com.dx12 -I "$I\um" --filter "dxgi1_4.h" -- "$I\shared\dxgi1_4.h" 17 | jextract --source -d . -t com.dx12 -I "$I\um" --filter "dxgi1_5.h" -- "$I\shared\dxgi1_5.h" 18 | jextract --source -d . -t com.dx12 -I "$I\um" --filter "dxgi1_6.h" -- "$I\shared\dxgi1_6.h" 19 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.dx12 6 | dx12 7 | pom 8 | 0.0.1-SNAPSHOT 9 | 10 | 11 | 12 | org.apache.maven.plugins 13 | maven-compiler-plugin 14 | 15 | 16 16 | 16 17 | 18 | 19 | 20 | 21 | dx12 22 | 23 | 24 | scm:git:https://github.com/brcolow/java-dx12.git 25 | http://github.com/brcolow/java-dx12 26 | scm:git:https://github.com/brcolow/java-dx12.git 27 | 28 | 29 | 30 | UTF-8 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/main/java/com/dx12/DX12.java: -------------------------------------------------------------------------------- 1 | package com.dx12; 2 | 3 | import jdk.incubator.foreign.Addressable; 4 | import jdk.incubator.foreign.CLinker; 5 | import jdk.incubator.foreign.FunctionDescriptor; 6 | import jdk.incubator.foreign.LibraryLookup; 7 | import jdk.incubator.foreign.MemoryAccess; 8 | import jdk.incubator.foreign.MemoryAddress; 9 | import jdk.incubator.foreign.MemoryHandles; 10 | import jdk.incubator.foreign.MemoryLayout; 11 | import jdk.incubator.foreign.MemorySegment; 12 | import jdk.incubator.foreign.NativeScope; 13 | import jdk.incubator.foreign.ValueLayout; 14 | 15 | import java.lang.invoke.MethodHandle; 16 | import java.lang.invoke.MethodHandles; 17 | import java.lang.invoke.MethodType; 18 | import java.lang.invoke.VarHandle; 19 | import java.nio.charset.StandardCharsets; 20 | import java.util.Map; 21 | import java.util.concurrent.Executors; 22 | import java.util.concurrent.ScheduledExecutorService; 23 | import java.util.concurrent.TimeUnit; 24 | import java.util.stream.Collectors; 25 | import java.util.stream.IntStream; 26 | 27 | import static com.dx12.d3d12sdklayers_h.ID3D12Debug; 28 | import static com.dx12.d3d12sdklayers_h.ID3D12DebugVtbl; 29 | import static com.dx12.d3d12_h.D3D12CreateDevice; 30 | import static com.dx12.d3d12_h.D3D12GetDebugInterface; 31 | import static com.dx12.d3d12_h.ID3D12DescriptorHeap; 32 | import static com.dx12.d3d12_h.D3D12_COMMAND_LIST_TYPE_DIRECT; 33 | import static com.dx12.d3d12_h.D3D12_COMMAND_QUEUE_DESC; 34 | import static com.dx12.d3d12_h.D3D12_COMMAND_QUEUE_FLAG_NONE; 35 | import static com.dx12.d3d12_h.ID3D12CommandQueue; 36 | import static com.dx12.d3d12_h.ID3D12Resource; 37 | import static com.dx12.d3d12_h.ID3D12Device5; 38 | import static com.dx12.d3d12_h.ID3D12Device5Vtbl; 39 | import static com.dx12.d3d12_h.D3D12_DESCRIPTOR_HEAP_DESC; 40 | import static com.dx12.d3d12_h.D3D12_CPU_DESCRIPTOR_HANDLE; 41 | import static com.dx12.d3d12_h.ID3D12DescriptorHeapVtbl; 42 | import static com.dx12.dxgi1_3_h.CreateDXGIFactory2; 43 | import static com.dx12.dxgi_h.DXGI_ADAPTER_DESC1; 44 | import static com.dx12.dxgi1_2_h.DXGI_SWAP_CHAIN_DESC1; 45 | import static com.dx12.dxgi1_2_h.IDXGISwapChain1; 46 | import static com.dx12.dxgi1_2_h.IDXGISwapChain1Vtbl; 47 | 48 | import static com.dx12.dxgi1_5_h.IDXGIFactory5; 49 | import static com.dx12.dxgi1_6_h.IDXGIAdapter4; 50 | import static com.dx12.dxgi1_6_h.IDXGIAdapter4Vtbl; 51 | 52 | import static jdk.incubator.foreign.CLinker.C_CHAR; 53 | import static jdk.incubator.foreign.CLinker.C_INT; 54 | import static jdk.incubator.foreign.CLinker.C_LONG; 55 | import static jdk.incubator.foreign.CLinker.C_LONG_LONG; 56 | import static jdk.incubator.foreign.CLinker.C_POINTER; 57 | import static jdk.incubator.foreign.CLinker.C_SHORT; 58 | import static jdk.incubator.foreign.CLinker.getInstance; 59 | import static jdk.incubator.foreign.MemoryLayout.PathElement.groupElement; 60 | 61 | /** 62 | * https://github.com/Meith/DX12/tree/master/DX12 63 | *

64 | * https://cr.openjdk.java.net/~mcimadamore/panama/ffi.html#appendix-full-source-code 65 | *

66 | * https://github.com/CRYTEK/CRYENGINE/blob/release/Code/CryEngine/RenderDll/XRenderD3D9/DX12/API/DX12Device.cpp 67 | *

68 | * https://chromium.googlesource.com/chromium/src/+/master/base/win/windows_version.cc 69 | */ 70 | public class DX12 { 71 | public static MemoryAddress createWindow(NativeScope scope) { 72 | MemorySegment pWindowClass = tagWNDCLASSEXW.allocate(scope); 73 | tagWNDCLASSEXW.cbSize$set(pWindowClass, (int) tagWNDCLASSEXW.sizeof()); 74 | tagWNDCLASSEXW.style$set(pWindowClass, CS_HREDRAW() | CS_VREDRAW()); 75 | // https://stackoverflow.com/questions/25341565/how-do-i-obtain-the-hinstance-for-the-createwindowex-function-when-using-it-outs 76 | tagWNDCLASSEXW.hInstance$set(pWindowClass, MemoryAddress.NULL); 77 | tagWNDCLASSEXW.hCursor$set(pWindowClass, LoadCursorW(MemoryAddress.NULL, IDC_ARROW())); 78 | 79 | MethodHandle winProcHandle; 80 | try { 81 | winProcHandle = MethodHandles.lookup() 82 | .findStatic(WindowProc.class, "WindowProc", 83 | MethodType.methodType(long.class, MemoryAddress.class, int.class, long.class, long.class)); 84 | } catch (NoSuchMethodException | IllegalAccessException ex) { 85 | ex.printStackTrace(); 86 | throw new RuntimeException(ex); 87 | } 88 | MemorySegment winProcFunc = CLinker.getInstance().upcallStub(winProcHandle, WindowProc); 89 | tagWNDCLASSEXW.lpfnWndProc$set(pWindowClass, winProcFunc.address()); 90 | MemoryAddress windowName = CLinker.toCString("JavaDX12Win", StandardCharsets.UTF_16LE).address(); 91 | tagWNDCLASSEXW.lpszClassName$set(pWindowClass, windowName); 92 | short atom = RegisterClassExW(pWindowClass.address()); 93 | if (atom == 0) { 94 | System.out.println("RegisterClassExW failed!"); 95 | System.out.println("Error: " + GetLastError()); 96 | System.exit(-1); 97 | } 98 | MemoryAddress hwndMain = CreateWindowExW(0, windowName, 99 | CLinker.toCString("My Window", StandardCharsets.UTF_16LE).address(), WS_OVERLAPPEDWINDOW(), CW_USEDEFAULT(), 100 | CW_USEDEFAULT(), 800, 600, MemoryAddress.NULL, MemoryAddress.NULL, MemoryAddress.NULL, MemoryAddress.NULL); 101 | if (hwndMain == MemoryAddress.NULL) { 102 | System.out.println("CreateWindowExW failed!"); 103 | System.exit(-1); 104 | } 105 | ShowWindow(hwndMain, SW_SHOW()); 106 | UpdateWindow(hwndMain); 107 | return hwndMain; 108 | } 109 | 110 | public static void main(String[] args) throws Throwable { 111 | // TODO: Create a utility to check what Windows version we are running on, and then what Windows versions 112 | // introduced which version of the various class like ID3D12Device1, 2, 3, etc. 113 | // https://docs.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_feature 114 | 115 | // TODO: Use an app manifest to target Windows 10. If we are lucky we can do this with jlink...MAYBE... 116 | // need to see if jlink calls link.exe and if so how we can set arguments: 117 | // https://docs.microsoft.com/en-us/cpp/build/reference/manifestinput-specify-manifest-input?view=vs-2019 118 | // https://docs.microsoft.com/en-us/windows/win32/w8cookbook/application--executable--manifest 119 | // https://github.com/rust-lang/rfcs/issues/721 120 | LibraryLookup user32 = LibraryLookup.ofLibrary("user32"); 121 | LibraryLookup d3d12 = LibraryLookup.ofLibrary("D3D12"); 122 | LibraryLookup dxgi = LibraryLookup.ofLibrary("dxgi"); 123 | try (NativeScope scope = NativeScope.unboundedScope()) { 124 | MemoryAddress hwndMain = createWindow(scope); 125 | var ppvDebug = ID3D12Debug.allocatePointer(scope); 126 | checkResult("D3D12GetDebugInterface", D3D12GetDebugInterface(IID.IID_ID3D12Debug.guid, ppvDebug)); 127 | // This one is trickier because it doesn't take a pp that it sets, it just does an action - need to make 128 | // a different signature 129 | //callMethodOnVTable(ppvDebug, ID3D12Debug.class, MethodType.methodType(int.class, MemoryAddress.class), "EnableDebugLayer"); 130 | MemorySegment pvDebug = asSegment(MemoryAccess.getAddress(ppvDebug), ID3D12Debug.$LAYOUT()); 131 | MemorySegment vDebugVtbl = asSegment(ID3D12Debug.lpVtbl$get(pvDebug), ID3D12DebugVtbl.$LAYOUT()); 132 | MemoryAddress enableDebugLayerAddr = ID3D12DebugVtbl.EnableDebugLayer$get(vDebugVtbl); 133 | MethodHandle ID3D12Debug_EnableDebugLayer = getInstance().downcallHandle( 134 | enableDebugLayerAddr, 135 | MethodType.methodType(int.class, MemoryAddress.class), 136 | FunctionDescriptor.of(C_INT, C_POINTER)); 137 | checkResult("EnableDebugLayer", (int) ID3D12Debug_EnableDebugLayer.invokeExact(pvDebug.address())); 138 | 139 | // IDXGIFactory1** dxgiFactory; 140 | var ppDxgiFactory = IDXGIFactory5.allocatePointer(scope); 141 | // HRESULT = CreateDXGIFactory2(_uuid(dxgiFactory), &dxgiFactory)) 142 | checkResult("CreateDXGIFactory2", CreateDXGIFactory2(DXGI_CREATE_FACTORY_DEBUG(), IID.IID_IDXGIFactory5.guid, ppDxgiFactory)); 143 | var result = callClassMethod(IDXGIFactory5.class, ppDxgiFactory, "EnumAdapters1", 144 | IDXGIAdapter4.class, scope, 145 | MethodType.methodType(int.class, MemoryAddress.class, int.class, MemoryAddress.class), 0); 146 | var ppAdapter = result.ppOut; 147 | //var pDxgiFactory = result.pThis; 148 | //var dxgiFactoryVtbl = result.pThisVtbl; 149 | /* 150 | // IDXGIFactory1* 151 | MemorySegment pDxgiFactory = asSegment(MemoryAccess.getAddress(ppDxgiFactory), IDXGIFactory5.$LAYOUT()); 152 | 153 | // (This)->lpVtbl 154 | MemorySegment dxgiFactoryVtbl = asSegment(IDXGIFactory5.lpVtbl$get(pDxgiFactory), IDXGIFactory5Vtbl.$LAYOUT()); 155 | // lpVtbl->EnumAdapters1 156 | MemoryAddress enumAdaptersAddr = IDXGIFactory5Vtbl.EnumAdapters1$get(dxgiFactoryVtbl); 157 | 158 | // link the pointer 159 | MethodHandle EnumAdapters1MethodHandle = getInstance().downcallHandle( 160 | enumAdaptersAddr, 161 | MethodType.methodType(int.class, MemoryAddress.class, int.class, MemoryAddress.class), 162 | FunctionDescriptor.of(C_INT, C_POINTER, C_INT, C_POINTER)); 163 | 164 | // [annotation][out] _COM_Outptr_ IDXGIAdapter4** 165 | MemorySegment ppOut = IDXGIAdapter4.allocatePointer(scope); 166 | checkResult("EnumAdapters1", (int) EnumAdapters1MethodHandle.invokeExact(pDxgiFactory.address(), 0, ppOut.address())); 167 | 168 | */ 169 | // IDXGIAdapter1* 170 | MemorySegment pAdapter = asSegment(MemoryAccess.getAddress(ppAdapter), IDXGIAdapter4.$LAYOUT()); 171 | 172 | // (This)->lpVtbl 173 | MemorySegment dxgiAdapterVtbl = asSegment(IDXGIAdapter4.lpVtbl$get(pAdapter), IDXGIAdapter4Vtbl.$LAYOUT()); 174 | // lpVtbl->EnumAdapters1 175 | // HRESULT(*)(IDXGIAdapter1*,DXGI_ADAPTER_DESC1*) 176 | MemoryAddress getDesc1Addr = IDXGIAdapter4Vtbl.GetDesc1$get(dxgiAdapterVtbl); 177 | 178 | // link the pointer 179 | MethodHandle IDXGIAdapter4_GetDesc = getInstance().downcallHandle( 180 | getDesc1Addr, 181 | MethodType.methodType(int.class, MemoryAddress.class, MemoryAddress.class), 182 | FunctionDescriptor.of(C_INT, C_POINTER, C_POINTER)); 183 | 184 | /* DXGI_ADAPTER_DESC1* */ 185 | MemorySegment pDesc = DXGI_ADAPTER_DESC1.allocate(scope); 186 | checkResult("getDesc1", (int) IDXGIAdapter4_GetDesc.invokeExact(pAdapter.address(), pDesc.address())); 187 | 188 | // print description 189 | MemorySegment descStr = DXGI_ADAPTER_DESC1.Description$slice(pDesc); 190 | String str = new String(descStr.toByteArray(), StandardCharsets.UTF_16LE); 191 | System.out.println(str); 192 | 193 | // ID3D12Device** d3d12Device; 194 | var ppDevice = ID3D12Device5.allocatePointer(scope); 195 | 196 | // D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&ppDevice)) 197 | //MemorySegment pDevice = asSegment(MemoryAccess.getAddress(ppDevice), ID3D12Device5.$LAYOUT()); 198 | // MemorySegment deviceVtbl = asSegment(ID3D12Device5.lpVtbl$get(pDevice), ID3D12Device5Vtbl.$LAYOUT()); 199 | // MemoryAddress createCommandQueueAddr = ID3D12Device5Vtbl.CreateCommandQueue$get(deviceVtbl); 200 | checkResult("D3D12CreateDevice", D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_1(), IID.IID_ID3D12Device5.guid, ppDevice)); 201 | MemorySegment pQueueDesc = D3D12_COMMAND_QUEUE_DESC.allocate(scope); 202 | D3D12_COMMAND_QUEUE_DESC.Type$set(pQueueDesc, D3D12_COMMAND_LIST_TYPE_DIRECT()); 203 | D3D12_COMMAND_QUEUE_DESC.Flags$set(pQueueDesc, D3D12_COMMAND_QUEUE_FLAG_NONE()); 204 | /* 205 | MethodHandle MH_ID3D12Device_CreateCommandQueue = getInstance().downcallHandle( 206 | createCommandQueueAddr, 207 | MethodType.methodType(int.class, MemoryAddress.class, MemoryAddress.class, MemoryAddress.class, MemoryAddress.class), 208 | FunctionDescriptor.of(C_INT, C_POINTER, C_POINTER, C_POINTER, C_POINTER)); 209 | var ppQueue = ID3D12CommandQueue.allocatePointer(scope); 210 | checkResult("ID3D12Device_CreateCommandQueue", (int) MH_ID3D12Device_CreateCommandQueue.invokeExact( 211 | pDevice.address(), pQueueDesc.address(), 212 | IID.IID_ID3D12CommandQueue.guid.address(), ppQueue.address())); 213 | */ 214 | result = callClassMethod(ID3D12Device5.class, ppDevice, "CreateCommandQueue", 215 | ID3D12CommandQueue.class, scope, 216 | MethodType.methodType( 217 | int.class, MemoryAddress.class, MemoryAddress.class, MemoryAddress.class, MemoryAddress.class), 218 | pQueueDesc.address(), IID.IID_ID3D12CommandQueue.guid.address()); 219 | var pDevice = result.pThis; 220 | var deviceVtbl = result.pThisVtbl; 221 | var ppQueue = result.ppOut; 222 | 223 | MemorySegment pSwapChainDesc = DXGI_SWAP_CHAIN_DESC1.allocate(scope); 224 | DXGI_SWAP_CHAIN_DESC1.Width$set(pSwapChainDesc, 0); 225 | DXGI_SWAP_CHAIN_DESC1.Height$set(pSwapChainDesc, 0); 226 | DXGI_SWAP_CHAIN_DESC1.Format$set(pSwapChainDesc, DXGI_FORMAT_B8G8R8A8_UNORM()); 227 | DXGI_SWAP_CHAIN_DESC1.$LAYOUT().varHandle(int.class, MemoryLayout.PathElement.groupElement("SampleDesc"), 228 | MemoryLayout.PathElement.groupElement("Count")).set(pSwapChainDesc, 1); 229 | DXGI_SWAP_CHAIN_DESC1.$LAYOUT().varHandle(int.class, MemoryLayout.PathElement.groupElement("SampleDesc"), 230 | MemoryLayout.PathElement.groupElement("Quality")).set(pSwapChainDesc, 0); 231 | DXGI_SWAP_CHAIN_DESC1.BufferUsage$set(pSwapChainDesc, DXGI_USAGE_RENDER_TARGET_OUTPUT()); 232 | DXGI_SWAP_CHAIN_DESC1.BufferCount$set(pSwapChainDesc, 2); 233 | DXGI_SWAP_CHAIN_DESC1.SwapEffect$set(pSwapChainDesc, DXGI_SWAP_EFFECT_FLIP_DISCARD()); 234 | DXGI_SWAP_CHAIN_DESC1.AlphaMode$set(pSwapChainDesc, DXGI_ALPHA_MODE_UNSPECIFIED()); 235 | DXGI_SWAP_CHAIN_DESC1.Scaling$set(pSwapChainDesc, DXGI_SCALING_STRETCH()); 236 | DXGI_SWAP_CHAIN_DESC1.Stereo$set(pSwapChainDesc, 0); 237 | DXGI_SWAP_CHAIN_DESC1.Flags$set(pSwapChainDesc, 0); 238 | MemorySegment pQueue = asSegment(MemoryAccess.getAddress(ppQueue), ID3D12CommandQueue.$LAYOUT()); 239 | 240 | // FIXME: We should be passing in dxgiFactoryVtbl instead of creating a new one? Also passing in pDxgiFactory? 241 | result = callClassMethod(IDXGIFactory5.class, ppDxgiFactory, "CreateSwapChainForHwnd", 242 | IDXGISwapChain1.class, scope, 243 | MethodType.methodType(int.class, MemoryAddress.class, MemoryAddress.class, MemoryAddress.class, 244 | MemoryAddress.class, MemoryAddress.class, MemoryAddress.class, MemoryAddress.class), 245 | pQueue.address(), hwndMain.address(), pSwapChainDesc.address(), MemoryAddress.NULL, MemoryAddress.NULL); 246 | var ppSwapChain = result.ppOut; 247 | MemorySegment pSwapChain = asSegment(MemoryAccess.getAddress(ppSwapChain), IDXGISwapChain1.$LAYOUT()); 248 | /* 249 | MemoryAddress addrCreateSwapChainForHwnd = IDXGIFactory5Vtbl.CreateSwapChainForHwnd$get(dxgiFactoryVtbl); 250 | MethodHandle createSwapChainForHwndMethodHandle = getInstance().downcallHandle( 251 | addrCreateSwapChainForHwnd, 252 | MethodType.methodType(int.class, MemoryAddress.class, MemoryAddress.class, MemoryAddress.class, 253 | MemoryAddress.class, MemoryAddress.class, MemoryAddress.class, MemoryAddress.class), 254 | FunctionDescriptor.of( 255 | C_INT, C_POINTER, C_POINTER, C_POINTER, C_POINTER, C_POINTER, C_POINTER, C_POINTER)); 256 | MemorySegment ppSwapChain = IDXGISwapChain1.allocatePointer(scope); 257 | MemorySegment pQueue = asSegment(MemoryAccess.getAddress(ppQueue), ID3D12CommandQueue.$LAYOUT()); 258 | 259 | checkResult("createSwapChainForHwnd", (int) createSwapChainForHwndMethodHandle.invokeExact( 260 | pDxgiFactory.address(), 261 | pQueue.address(), 262 | hwndMain.address(), 263 | pSwapChainDesc.address(), MemoryAddress.NULL, MemoryAddress.NULL, 264 | ppSwapChain.address())); 265 | */ 266 | 267 | // https://github.com/microsoft/DirectX-Graphics-Samples/blob/master/Samples/Desktop/D3D12HelloWorld/src/HelloWindow/D3D12HelloWindow.cpp 268 | /* 269 | D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {}; 270 | rtvHeapDesc.NumDescriptors = FrameCount; 271 | rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; 272 | rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; 273 | ThrowIfFailed(m_device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&m_rtvHeap))); 274 | */ 275 | MemorySegment pHeapDesc = D3D12_DESCRIPTOR_HEAP_DESC.allocate(scope); 276 | D3D12_DESCRIPTOR_HEAP_DESC.NumDescriptors$set(pHeapDesc, 1); 277 | D3D12_DESCRIPTOR_HEAP_DESC.Type$set(pHeapDesc, D3D12_DESCRIPTOR_HEAP_TYPE_RTV()); 278 | D3D12_DESCRIPTOR_HEAP_DESC.Flags$set(pHeapDesc, D3D12_DESCRIPTOR_HEAP_FLAG_NONE()); 279 | result = callClassMethod(ID3D12Device5.class, ppDevice, "CreateDescriptorHeap", 280 | ID3D12DescriptorHeap.class, scope, 281 | MethodType.methodType(int.class, MemoryAddress.class, MemoryAddress.class, MemoryAddress.class, MemoryAddress.class), 282 | pHeapDesc.address(), IID.IID_ID3D12DescriptorHeap.guid.address()); 283 | var ppHeapDescriptor = result.ppOut; 284 | var pHeapDescriptor = asSegment(MemoryAccess.getAddress(ppHeapDescriptor), ID3D12DescriptorHeap.$LAYOUT()); 285 | 286 | // UINT rtvDescriptorIncrementSize = mDevice->lpVtbl->GetDescriptorHandleIncrementSize(pDevice, D3D12_DESCRIPTOR_HEAP_TYPE_RTV); 287 | MemoryAddress getDescriptorHandleIncrementSizeAddr = ID3D12Device5Vtbl.GetDescriptorHandleIncrementSize$get(deviceVtbl); 288 | MethodHandle ID3D12Device_GetDescriptorHandleIncrementSize = getInstance().downcallHandle( 289 | getDescriptorHandleIncrementSizeAddr, 290 | MethodType.methodType(int.class, MemoryAddress.class, int.class), 291 | FunctionDescriptor.of(C_INT, C_POINTER, C_INT)); 292 | int rtvDescriptorIncrementSize = (int) ID3D12Device_GetDescriptorHandleIncrementSize.invoke( 293 | pDevice.address(), D3D12_DESCRIPTOR_HEAP_TYPE_RTV()); 294 | System.out.println("rtvDescriptorIncrementSize: " + rtvDescriptorIncrementSize); 295 | 296 | // ((void(__stdcall*)(ID3D12DescriptorHeap*, D3D12_CPU_DESCRIPTOR_HANDLE*)) mDescriptorHeap->lpVtbl->GetCPUDescriptorHandleForHeapStart)(pHeapDescriptor, &pRtvHandle); 297 | MemorySegment heapDescriptorVtbl = asSegment(ID3D12DescriptorHeap.lpVtbl$get(pHeapDescriptor), ID3D12DescriptorHeapVtbl.$LAYOUT()); 298 | MemoryAddress getCPUDescriptorHandleForHeapStartAddr = ID3D12DescriptorHeapVtbl.GetCPUDescriptorHandleForHeapStart$get(heapDescriptorVtbl); 299 | var pRtvHandle = D3D12_CPU_DESCRIPTOR_HANDLE.allocate(scope); 300 | MethodHandle ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart = getInstance().downcallHandle( 301 | getCPUDescriptorHandleForHeapStartAddr, 302 | MethodType.methodType(void.class, MemoryAddress.class, MemoryAddress.class), 303 | FunctionDescriptor.ofVoid(C_POINTER, C_POINTER)); 304 | // Even though GetCPUDescriptorHandleForHeapStart is documented as taking no arguments (except for the 305 | // this pointer), to use from C code it needs to take an additional rtvHandle argument, see, for example: 306 | // https://joshstaiger.org/notes/C-Language-Problems-in-Direct3D-12-GetCPUDescriptorHandleForHeapStart.html 307 | // https://github.com/curldivergence/dx12bindings/blob/841974943b7fbbd146d5372e9b496a9d72daf771/build.rs#L33 308 | ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart.invokeExact( 309 | pHeapDescriptor.address(), pRtvHandle.address()); 310 | long pRtvHandlePtr = D3D12_CPU_DESCRIPTOR_HANDLE.ptr$get(pRtvHandle); 311 | System.out.println("pRtvHandlePtr: " + pRtvHandlePtr); 312 | System.out.println("pRtvHandlePtr: " + MemoryAddress.ofLong(pRtvHandlePtr)); 313 | 314 | // mSwapChain->lpVtbl->GetBuffer(mSwapChain, n, (REFIID)&IID_ID3D12Resource, (LPVOID*)(&mRenderTarget[n]))); //IID_PPV_ARGS(&m_renderTargets[n]))); 315 | MemorySegment swapChainVtbl = asSegment(IDXGISwapChain1.lpVtbl$get(pSwapChain), IDXGISwapChain1Vtbl.$LAYOUT()); 316 | MemoryAddress IDXGISwapChain1_GetBuffer_Addr = IDXGISwapChain1Vtbl.GetBuffer$get(swapChainVtbl); 317 | MethodHandle IDXGISwapChain1_GetBuffer = getInstance().downcallHandle( 318 | IDXGISwapChain1_GetBuffer_Addr, 319 | MethodType.methodType(int.class, MemoryAddress.class, int.class, MemoryAddress.class, MemoryAddress.class), 320 | FunctionDescriptor.of( 321 | C_INT, C_POINTER, C_INT, C_POINTER, C_POINTER)); 322 | var ppSurface0 = ID3D12Resource.allocatePointer(scope); 323 | checkResult("IDXGISwapChain1_GetBuffer", (int) IDXGISwapChain1_GetBuffer.invokeExact( 324 | pSwapChain.address(), 0, 325 | IID.IID_ID3D12Resource.guid.address(), ppSurface0.address())); 326 | var pSurface0 = asSegment(ppSurface0.address(), ID3D12Resource.$LAYOUT()); 327 | 328 | MemoryAddress createRenderTargetViewAddr = ID3D12Device5Vtbl.CreateRenderTargetView$get(deviceVtbl); 329 | MethodHandle ID3D12Device_CreateRenderTargetView = getInstance().downcallHandle( 330 | createRenderTargetViewAddr, 331 | MethodType.methodType(void.class, MemoryAddress.class, MemoryAddress.class, MemoryAddress.class, MemoryAddress.class), 332 | FunctionDescriptor.ofVoid(C_POINTER, C_POINTER, C_POINTER, C_POINTER)); 333 | 334 | // This line is causing a crash C [D3D12SDKLayers.dll+0x1e6f9] 335 | // mDevice->lpVtbl->CreateRenderTargetView(mDevice, mRenderTarget[n], NULL, rtvHandle); 336 | // A null pDesc is used to initialize a default descriptor, if possible. 337 | // https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12device-createrendertargetview 338 | ID3D12Device_CreateRenderTargetView.invokeExact(pDevice.address(), ppSurface0.address(), MemoryAddress.NULL, pRtvHandle.address()); 339 | 340 | // mDevice->lpVtbl->CreateRenderTargetView(mDevice, mRenderTarget[n], NULL, rtvHandle); 341 | // rtvHandle.ptr += mrtvDescriptorIncrSize; 342 | // D3D12_CPU_DESCRIPTOR_HANDLE.ptr$set(rtvHandle, pRtvHandlePtr + rtvDescriptorIncrementSize); 343 | // 344 | // then we "create" a render target view which binds the swap chain buffer (ID3D12Resource[n]) to the rtv handle 345 | // device->CreateRenderTargetView(renderTargets[i], nullptr, rtvHandle); 346 | // 347 | // we increment the rtv handle by the rtv descriptor size we got above 348 | // rtvHandle.Offset(1, rtvDescriptorIncrementSize); 349 | 350 | 351 | ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1); 352 | executorService.schedule(() -> {}, 1, TimeUnit.MINUTES); 353 | } 354 | } 355 | 356 | public static class VTableMethodResult { 357 | MemorySegment ppThis; 358 | MemorySegment pThis; 359 | MemorySegment pThisVtbl; 360 | MemorySegment ppOut; 361 | 362 | public VTableMethodResult(MemorySegment ppThis, MemorySegment pThis, MemorySegment pThisVtbl, MemorySegment ppOut) { 363 | this.ppThis = ppThis; 364 | this.pThis = pThis; 365 | this.pThisVtbl = pThisVtbl; 366 | this.ppOut = ppOut; 367 | } 368 | } 369 | 370 | /** 371 | * This method uses reflection and thus may be too slow to use. Benchmark this. 372 | * 373 | * Helper method that makes it easier to call the C++ equivalent of (pThis)->someMethod(ppOut) which, because 374 | * we are actually using the DirectX 12 C interface is done using vtable structs and it takes quite a lot of 375 | * boilerplate. 376 | *

377 | * Consider the following C++ code that is typical of DirectX 12: 378 | * 379 | * {@code 380 | * IDXGIAdapter1 * pAdapter; 381 | * pFactory->EnumAdapters1(0, &pAdapter) 382 | * } 383 | * 384 | * This type of class method structure is emulated in C via the following API: 385 | * 386 | * {@code 387 | * HRESULT ( STDMETHODCALLTYPE *EnumAdapters1 )( 388 | * IDXGIFactory1 * This, 389 | * // [in] UINT Adapter, 390 | * // [out] IDXGIAdapter1 **ppAdapter); 391 | * } 392 | * 393 | * Which must be called like so: 394 | * 395 | * {@code factory->lpVtbl->EnumAdapters1(factory, 0, &adapter)} 396 | * 397 | * To replicate this in Panama requires quite a bit of fiddling, so this method would be used thusly: 398 | * 399 | * {@code 400 | * var ppDxgiFactory = IDXGIFactory5.allocatePointer(scope); 401 | * var result = callClassMethod(scope, ppDxgiFactory, IDXGIFactory5.class, IDXGIAdapter4.class, 402 | * MethodType.methodType(int.class, MemoryAddress.class, int.class, MemoryAddress.class), "EnumAdapters1", 0); 403 | * } 404 | */ 405 | private static VTableMethodResult callClassMethod(Class pThisType, MemorySegment ppThis, 406 | String methodName, 407 | Class pOutType, NativeScope scope, 408 | MethodType methodType, 409 | Object... inArgs) throws IllegalArgumentException { 410 | try { 411 | MemorySegment pThis = asSegment(MemoryAccess.getAddress(ppThis), 412 | (MemoryLayout) pThisType.getMethod("$LAYOUT").invoke(null)); 413 | Class vtblClazz = Class.forName(pThisType.getName() + "Vtbl"); 414 | MemorySegment pVtbl = asSegment((MemoryAddress) pThisType.getMethod("lpVtbl$get", MemorySegment.class) 415 | .invoke(null, pThis), 416 | (MemoryLayout) vtblClazz.getMethod("$LAYOUT").invoke(null)); 417 | MemoryAddress methodAddr = (MemoryAddress) vtblClazz.getMethod(methodName + "$get", MemorySegment.class) 418 | .invoke(null, pVtbl); 419 | FunctionDescriptor functionDescriptor = methodType.returnType().equals(void.class) ? 420 | FunctionDescriptor.ofVoid( 421 | methodType.parameterList().stream() 422 | .map(DX12::getCType) 423 | .collect(Collectors.toList()) 424 | .toArray(new ValueLayout[]{})) 425 | : FunctionDescriptor.of( 426 | getCType(methodType.returnType()), 427 | methodType.parameterList().stream() 428 | .map(DX12::getCType) 429 | .collect(Collectors.toList()) 430 | .toArray(new ValueLayout[]{})); 431 | MethodHandle methodHandle = getInstance().downcallHandle(methodAddr, methodType, functionDescriptor); 432 | MemorySegment ppOut = null; 433 | if (pOutType != null) { 434 | ppOut = (MemorySegment) pOutType.getMethod("allocatePointer", NativeScope.class).invoke(null, scope); 435 | } 436 | // This is super gross but can't think of a better way at the moment... 437 | if (inArgs.length == 0) { 438 | if (ppOut != null) { 439 | checkResult(methodName, (int) methodHandle.invokeExact(pThis.address(), ppOut.address())); 440 | } else { 441 | checkResult(methodName, (int) methodHandle.invoke(pThis.address())); 442 | } 443 | } else if (inArgs.length == 1) { 444 | if (ppOut != null) { 445 | checkResult(methodName, (int) methodHandle.invoke(pThis.address(), inArgs[0], ppOut.address())); 446 | } else { 447 | checkResult(methodName, (int) methodHandle.invoke(pThis.address(), inArgs[0])); 448 | } 449 | } else if (inArgs.length == 2) { 450 | if (ppOut != null) { 451 | checkResult(methodName, (int) methodHandle.invoke(pThis.address(), inArgs[0], inArgs[1], ppOut.address())); 452 | } else { 453 | checkResult(methodName, (int) methodHandle.invoke(pThis.address(), inArgs[0], inArgs[1])); 454 | } 455 | } else if (inArgs.length == 3) { 456 | if (ppOut != null) { 457 | checkResult(methodName, (int) methodHandle.invoke(pThis.address(), inArgs[0], inArgs[1], inArgs[2], ppOut.address())); 458 | } else { 459 | checkResult(methodName, (int) methodHandle.invoke(pThis.address(), inArgs[0], inArgs[1], inArgs[2])); 460 | } 461 | } else if (inArgs.length == 4) { 462 | if (ppOut != null) { 463 | checkResult(methodName, (int) methodHandle.invoke(pThis.address(), inArgs[0], inArgs[1], inArgs[2], inArgs[3], ppOut.address())); 464 | } else { 465 | checkResult(methodName, (int) methodHandle.invoke(pThis.address(), inArgs[0], inArgs[1], inArgs[2], inArgs[3])); 466 | } 467 | } else if (inArgs.length == 5) { 468 | if (ppOut != null) { 469 | checkResult(methodName, (int) methodHandle.invoke(pThis.address(), inArgs[0], inArgs[1], inArgs[2], inArgs[3], inArgs[4], ppOut.address())); 470 | } else { 471 | checkResult(methodName, (int) methodHandle.invoke(pThis.address(), inArgs[0], inArgs[1], inArgs[2], inArgs[3], inArgs[4])); 472 | } 473 | } else { 474 | throw new IllegalArgumentException("Cannot handle arguments of length \"" + inArgs.length + "\"."); 475 | } 476 | return new VTableMethodResult(ppThis, pThis, pVtbl, ppOut); 477 | } catch (Throwable ex) { 478 | ex.printStackTrace(); 479 | throw new IllegalArgumentException(ex); 480 | } 481 | } 482 | 483 | private static final Map, ValueLayout> TYPES = Map.of(int.class, C_INT, MemoryAddress.class, C_POINTER); 484 | private static ValueLayout getCType(Class clazz) { 485 | if (!TYPES.containsKey(clazz)) { 486 | throw new IllegalArgumentException("Cannot get CTYPE of class \"" + clazz + "\"."); 487 | } 488 | return TYPES.get(clazz); 489 | } 490 | 491 | public static MemorySegment asSegment(MemoryAddress addr, MemoryLayout layout) { 492 | return addr.asSegmentRestricted(layout.byteSize()); 493 | } 494 | 495 | private static final int S_OK = 0x00000000; 496 | private static final int DXGI_ERROR_INVALID_CALL = (int) -2005270527L; 497 | 498 | private static void checkResult(String function, int result) { 499 | switch (result) { 500 | case S_OK -> 501 | System.out.println("Function \"" + function + "\" returned successfully!"); 502 | case DXGI_ERROR_INVALID_CALL -> 503 | System.out.println("Function \"" + function + "\" returned result: DXGI_ERROR_INVALID_CALL"); 504 | default -> 505 | System.out.println("Function \"" + function + "\" returned unknown result: " + Integer.toHexString(result)); 506 | } 507 | } 508 | 509 | public enum IID { 510 | // https://github.com/terrafx/terrafx.interop.windows/blob/2d5817519219dc963dbe08baa67997c2821befc4/sources/Interop/Windows/um/d3d12/Windows.cs#L180 511 | IID_ID3D12Debug(0x344488b7, 0x6846, 0x474b, 0xb9, 0x89, 0xf0, 0x27, 0x44, 0x82, 0x45, 0xe0), 512 | IID_ID3D12Resource(0x696442be, 0xa72e, 0x4059, 0xbc, 0x79, 0x5b, 0x5c, 0x98, 0x04, 0x0f, 0xad), 513 | IID_IDXGIAdapter1(0x29038f61, 0x3839, 0x4626, 0x91, 0xfd, 0x08, 0x68, 0x79, 0x01, 0x1a, 0x05), 514 | IID_IDXGIAdapter4(0x3c8d99d1, 0x4fbf, 0x4181, 0xa8, 0x2c, 0xaf, 0x66, 0xbf, 0x7b, 0xd2, 0x4e), 515 | IID_IDXGIFactory1(0x770aae78, 0xf26f, 0x4dba, 0xa8, 0x29, 0x25, 0x3c, 0x83, 0xd1, 0xb3, 0x87), 516 | IID_IDXGIFactory5(0x7632e1f5, 0xee65, 0x4dca, 0x87, 0xfd, 0x84, 0xcd, 0x75, 0xf8, 0x83, 0x8d), 517 | IID_IDXGIFactory7(0xa4966eed, 0x76db, 0x44da, 0x84, 0xc1, 0xee, 0x9a, 0x7a, 0xfb, 0x20, 0xa8), 518 | IID_ID3D12Device(0x189819f1, 0x1db6, 0x4b57, 0xbe, 0x54, 0x18, 0x21, 0x33, 0x9b, 0x85, 0xf7), 519 | IID_ID3D12Device5(0x8b4f173b, 0x2fea, 0x4b80, 0x8f, 0x58, 0x43, 0x07, 0x19, 0x1a, 0xb9, 0x5d), 520 | IID_ID3D12Device8(0x9218e6bb, 0xf944, 0x4f7e, 0xa7, 0x5c, 0xb1, 0xb2, 0xc7, 0xb7, 0x01, 0xf3), 521 | IID_ID3D12DescriptorHeap(0x8efb471d, 0x616c, 0x4f49, 0x90, 0xf7, 0x12, 0x7b, 0xb7, 0x63, 0xfa, 0x51), 522 | IID_ID3D12CommandQueue(0x0ec870a6, 0x5d7e, 0x4c22, 0x8c, 0xfc, 0x5b, 0xaa, 0xe0, 0x76, 0x16, 0xed); 523 | 524 | private final MemorySegment guid; 525 | 526 | IID(int data1, int data2, int data3, int... data4) { 527 | MemoryLayout GUID = MemoryLayout.ofStruct( 528 | C_INT.withName("Data1"), 529 | C_SHORT.withName("Data2"), 530 | C_SHORT.withName("Data3"), 531 | MemoryLayout.ofSequence(8, C_CHAR).withName("Data4") 532 | ).withName("_GUID"); 533 | VarHandle data1Handle = GUID.varHandle(int.class, groupElement("Data1")); 534 | VarHandle data2Handle = GUID.varHandle(short.class, groupElement("Data2")); 535 | VarHandle data3Handle = GUID.varHandle(short.class, groupElement("Data3")); 536 | VarHandle data4Handle = GUID.varHandle(byte.class, groupElement("Data4"), 537 | MemoryLayout.PathElement.sequenceElement()); 538 | MemorySegment segment = MemorySegment.allocateNative(GUID); 539 | data1Handle.set(segment, data1); 540 | data2Handle.set(segment, (short) data2); 541 | data3Handle.set(segment, (short) data3); 542 | IntStream.range(0, 8).forEachOrdered(i -> data4Handle.set(segment, i, (byte) data4[i])); 543 | this.guid = segment; 544 | } 545 | } 546 | 547 | static final MemoryLayout tagWNDCLASSEXW$struct$LAYOUT_ = MemoryLayout.ofStruct( 548 | C_INT.withName("cbSize"), 549 | C_INT.withName("style"), 550 | C_POINTER.withName("lpfnWndProc"), 551 | C_INT.withName("cbClsExtra"), 552 | C_INT.withName("cbWndExtra"), 553 | C_POINTER.withName("hInstance"), 554 | C_POINTER.withName("hIcon"), 555 | C_POINTER.withName("hCursor"), 556 | C_POINTER.withName("hbrBackground"), 557 | C_POINTER.withName("lpszMenuName"), 558 | C_POINTER.withName("lpszClassName"), 559 | C_POINTER.withName("hIconSm") 560 | ).withName("tagWNDCLASSEXW"); 561 | 562 | static MemoryLayout tagWNDCLASSEXW$struct$LAYOUT() { 563 | return tagWNDCLASSEXW$struct$LAYOUT_; 564 | } 565 | 566 | public static class tagWNDCLASSEXW { 567 | static final VarHandle tagWNDCLASSEXW$cbSize$VH_ = tagWNDCLASSEXW$struct$LAYOUT_.varHandle(int.class, MemoryLayout.PathElement.groupElement("cbSize")); 568 | 569 | static final java.lang.invoke.VarHandle tagWNDCLASSEXW$cbSize$VH() { 570 | return tagWNDCLASSEXW$cbSize$VH_; 571 | } 572 | 573 | static final VarHandle tagWNDCLASSEXW$style$VH_ = tagWNDCLASSEXW$struct$LAYOUT_.varHandle(int.class, MemoryLayout.PathElement.groupElement("style")); 574 | 575 | static final java.lang.invoke.VarHandle tagWNDCLASSEXW$style$VH() { 576 | return tagWNDCLASSEXW$style$VH_; 577 | } 578 | 579 | static final VarHandle tagWNDCLASSEXW$lpfnWndProc$VH_ = MemoryHandles.asAddressVarHandle(tagWNDCLASSEXW$struct$LAYOUT_.varHandle(long.class, MemoryLayout.PathElement.groupElement("lpfnWndProc"))); 580 | 581 | static final java.lang.invoke.VarHandle tagWNDCLASSEXW$lpfnWndProc$VH() { 582 | return tagWNDCLASSEXW$lpfnWndProc$VH_; 583 | } 584 | 585 | static final VarHandle tagWNDCLASSEXW$cbClsExtra$VH_ = tagWNDCLASSEXW$struct$LAYOUT_.varHandle(int.class, MemoryLayout.PathElement.groupElement("cbClsExtra")); 586 | 587 | static final java.lang.invoke.VarHandle tagWNDCLASSEXW$cbClsExtra$VH() { 588 | return tagWNDCLASSEXW$cbClsExtra$VH_; 589 | } 590 | 591 | static final VarHandle tagWNDCLASSEXW$cbWndExtra$VH_ = tagWNDCLASSEXW$struct$LAYOUT_.varHandle(int.class, MemoryLayout.PathElement.groupElement("cbWndExtra")); 592 | 593 | static final java.lang.invoke.VarHandle tagWNDCLASSEXW$cbWndExtra$VH() { 594 | return tagWNDCLASSEXW$cbWndExtra$VH_; 595 | } 596 | 597 | static final VarHandle tagWNDCLASSEXW$hInstance$VH_ = MemoryHandles.asAddressVarHandle(tagWNDCLASSEXW$struct$LAYOUT_.varHandle(long.class, MemoryLayout.PathElement.groupElement("hInstance"))); 598 | 599 | static final java.lang.invoke.VarHandle tagWNDCLASSEXW$hInstance$VH() { 600 | return tagWNDCLASSEXW$hInstance$VH_; 601 | } 602 | 603 | static final VarHandle tagWNDCLASSEXW$hIcon$VH_ = MemoryHandles.asAddressVarHandle(tagWNDCLASSEXW$struct$LAYOUT_.varHandle(long.class, MemoryLayout.PathElement.groupElement("hIcon"))); 604 | 605 | static final java.lang.invoke.VarHandle tagWNDCLASSEXW$hIcon$VH() { 606 | return tagWNDCLASSEXW$hIcon$VH_; 607 | } 608 | 609 | static final VarHandle tagWNDCLASSEXW$hCursor$VH_ = MemoryHandles.asAddressVarHandle(tagWNDCLASSEXW$struct$LAYOUT_.varHandle(long.class, MemoryLayout.PathElement.groupElement("hCursor"))); 610 | 611 | static final java.lang.invoke.VarHandle tagWNDCLASSEXW$hCursor$VH() { 612 | return tagWNDCLASSEXW$hCursor$VH_; 613 | } 614 | 615 | static final VarHandle tagWNDCLASSEXW$hbrBackground$VH_ = MemoryHandles.asAddressVarHandle(tagWNDCLASSEXW$struct$LAYOUT_.varHandle(long.class, MemoryLayout.PathElement.groupElement("hbrBackground"))); 616 | 617 | static final java.lang.invoke.VarHandle tagWNDCLASSEXW$hbrBackground$VH() { 618 | return tagWNDCLASSEXW$hbrBackground$VH_; 619 | } 620 | 621 | static final VarHandle tagWNDCLASSEXW$lpszMenuName$VH_ = MemoryHandles.asAddressVarHandle(tagWNDCLASSEXW$struct$LAYOUT_.varHandle(long.class, MemoryLayout.PathElement.groupElement("lpszMenuName"))); 622 | 623 | static final java.lang.invoke.VarHandle tagWNDCLASSEXW$lpszMenuName$VH() { 624 | return tagWNDCLASSEXW$lpszMenuName$VH_; 625 | } 626 | 627 | static final VarHandle tagWNDCLASSEXW$lpszClassName$VH_ = MemoryHandles.asAddressVarHandle(tagWNDCLASSEXW$struct$LAYOUT_.varHandle(long.class, MemoryLayout.PathElement.groupElement("lpszClassName"))); 628 | 629 | static final java.lang.invoke.VarHandle tagWNDCLASSEXW$lpszClassName$VH() { 630 | return tagWNDCLASSEXW$lpszClassName$VH_; 631 | } 632 | 633 | static final VarHandle tagWNDCLASSEXW$hIconSm$VH_ = MemoryHandles.asAddressVarHandle(tagWNDCLASSEXW$struct$LAYOUT_.varHandle(long.class, MemoryLayout.PathElement.groupElement("hIconSm"))); 634 | 635 | static final java.lang.invoke.VarHandle tagWNDCLASSEXW$hIconSm$VH() { 636 | return tagWNDCLASSEXW$hIconSm$VH_; 637 | } 638 | 639 | 640 | private tagWNDCLASSEXW() { 641 | } 642 | 643 | public static MemoryLayout $LAYOUT() { 644 | return tagWNDCLASSEXW$struct$LAYOUT(); 645 | } 646 | 647 | public static VarHandle cbSize$VH() { 648 | return tagWNDCLASSEXW$cbSize$VH(); 649 | } 650 | 651 | public static @C("UINT") int cbSize$get(@C("struct tagWNDCLASSEXW") MemorySegment seg) { 652 | return (int) tagWNDCLASSEXW$cbSize$VH().get(seg); 653 | } 654 | 655 | public static @C("UINT") int cbSize$get(@C("struct tagWNDCLASSEXW") MemorySegment seg, long index) { 656 | return (int) tagWNDCLASSEXW$cbSize$VH().get(seg.asSlice(index * sizeof())); 657 | } 658 | 659 | public static void cbSize$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, @C("UINT") int x) { 660 | tagWNDCLASSEXW$cbSize$VH().set(seg, x); 661 | } 662 | 663 | public static void cbSize$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, long index, @C("UINT") int x) { 664 | tagWNDCLASSEXW$cbSize$VH().set(seg.asSlice(index * sizeof()), x); 665 | } 666 | 667 | public static VarHandle style$VH() { 668 | return tagWNDCLASSEXW$style$VH(); 669 | } 670 | 671 | public static void style$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, @C("UINT") int x) { 672 | tagWNDCLASSEXW$style$VH().set(seg, x); 673 | } 674 | 675 | public static void style$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, long index, @C("UINT") int x) { 676 | tagWNDCLASSEXW$style$VH().set(seg.asSlice(index * sizeof()), x); 677 | } 678 | 679 | public static VarHandle lpfnWndProc$VH() { 680 | return tagWNDCLASSEXW$lpfnWndProc$VH(); 681 | } 682 | 683 | public static void lpfnWndProc$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, @C("WNDPROC") MemoryAddress x) { 684 | tagWNDCLASSEXW$lpfnWndProc$VH().set(seg, x); 685 | } 686 | 687 | public static void lpfnWndProc$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, long index, @C("WNDPROC") MemoryAddress x) { 688 | tagWNDCLASSEXW$lpfnWndProc$VH().set(seg.asSlice(index * sizeof()), x); 689 | } 690 | 691 | public static VarHandle cbClsExtra$VH() { 692 | return tagWNDCLASSEXW$cbClsExtra$VH(); 693 | } 694 | 695 | public static void cbClsExtra$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, @C("int") int x) { 696 | tagWNDCLASSEXW$cbClsExtra$VH().set(seg, x); 697 | } 698 | 699 | public static void cbClsExtra$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, long index, @C("int") int x) { 700 | tagWNDCLASSEXW$cbClsExtra$VH().set(seg.asSlice(index * sizeof()), x); 701 | } 702 | 703 | public static VarHandle cbWndExtra$VH() { 704 | return tagWNDCLASSEXW$cbWndExtra$VH(); 705 | } 706 | 707 | public static void cbWndExtra$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, @C("int") int x) { 708 | tagWNDCLASSEXW$cbWndExtra$VH().set(seg, x); 709 | } 710 | 711 | public static void cbWndExtra$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, long index, @C("int") int x) { 712 | tagWNDCLASSEXW$cbWndExtra$VH().set(seg.asSlice(index * sizeof()), x); 713 | } 714 | 715 | public static VarHandle hInstance$VH() { 716 | return tagWNDCLASSEXW$hInstance$VH(); 717 | } 718 | 719 | public static void hInstance$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, @C("HINSTANCE") MemoryAddress x) { 720 | tagWNDCLASSEXW$hInstance$VH().set(seg, x); 721 | } 722 | 723 | public static void hInstance$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, long index, @C("HINSTANCE") MemoryAddress x) { 724 | tagWNDCLASSEXW$hInstance$VH().set(seg.asSlice(index * sizeof()), x); 725 | } 726 | 727 | public static VarHandle hIcon$VH() { 728 | return tagWNDCLASSEXW$hIcon$VH(); 729 | } 730 | 731 | public static void hIcon$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, @C("HICON") MemoryAddress x) { 732 | tagWNDCLASSEXW$hIcon$VH().set(seg, x); 733 | } 734 | 735 | public static void hIcon$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, long index, @C("HICON") MemoryAddress x) { 736 | tagWNDCLASSEXW$hIcon$VH().set(seg.asSlice(index * sizeof()), x); 737 | } 738 | 739 | public static VarHandle hCursor$VH() { 740 | return tagWNDCLASSEXW$hCursor$VH(); 741 | } 742 | 743 | public static void hCursor$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, @C("HCURSOR") MemoryAddress x) { 744 | tagWNDCLASSEXW$hCursor$VH().set(seg, x); 745 | } 746 | 747 | public static void hCursor$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, long index, @C("HCURSOR") MemoryAddress x) { 748 | tagWNDCLASSEXW$hCursor$VH().set(seg.asSlice(index * sizeof()), x); 749 | } 750 | 751 | public static VarHandle hbrBackground$VH() { 752 | return tagWNDCLASSEXW$hbrBackground$VH(); 753 | } 754 | 755 | public static void hbrBackground$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, @C("HBRUSH") MemoryAddress x) { 756 | tagWNDCLASSEXW$hbrBackground$VH().set(seg, x); 757 | } 758 | 759 | public static void hbrBackground$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, long index, @C("HBRUSH") MemoryAddress x) { 760 | tagWNDCLASSEXW$hbrBackground$VH().set(seg.asSlice(index * sizeof()), x); 761 | } 762 | 763 | public static VarHandle lpszMenuName$VH() { 764 | return tagWNDCLASSEXW$lpszMenuName$VH(); 765 | } 766 | 767 | public static void lpszMenuName$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, @C("LPCWSTR") MemoryAddress x) { 768 | tagWNDCLASSEXW$lpszMenuName$VH().set(seg, x); 769 | } 770 | 771 | public static void lpszMenuName$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, long index, @C("LPCWSTR") MemoryAddress x) { 772 | tagWNDCLASSEXW$lpszMenuName$VH().set(seg.asSlice(index * sizeof()), x); 773 | } 774 | 775 | public static VarHandle lpszClassName$VH() { 776 | return tagWNDCLASSEXW$lpszClassName$VH(); 777 | } 778 | 779 | public static void lpszClassName$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, @C("LPCWSTR") MemoryAddress x) { 780 | tagWNDCLASSEXW$lpszClassName$VH().set(seg, x); 781 | } 782 | 783 | public static void lpszClassName$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, long index, @C("LPCWSTR") MemoryAddress x) { 784 | tagWNDCLASSEXW$lpszClassName$VH().set(seg.asSlice(index * sizeof()), x); 785 | } 786 | 787 | public static VarHandle hIconSm$VH() { 788 | return tagWNDCLASSEXW$hIconSm$VH(); 789 | } 790 | 791 | public static void hIconSm$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, @C("HICON") MemoryAddress x) { 792 | tagWNDCLASSEXW$hIconSm$VH().set(seg, x); 793 | } 794 | 795 | public static void hIconSm$set(@C("struct tagWNDCLASSEXW") MemorySegment seg, long index, @C("HICON") MemoryAddress x) { 796 | tagWNDCLASSEXW$hIconSm$VH().set(seg.asSlice(index * sizeof()), x); 797 | } 798 | 799 | public static long sizeof() { 800 | return $LAYOUT().byteSize(); 801 | } 802 | 803 | public static @C("struct tagWNDCLASSEXW") MemorySegment allocate() { 804 | return MemorySegment.allocateNative($LAYOUT()); 805 | } 806 | 807 | public static @C("struct tagWNDCLASSEXW") MemorySegment allocate(NativeScope scope) { 808 | return scope.allocate($LAYOUT()); 809 | } 810 | 811 | public static @C("struct tagWNDCLASSEXW[]") MemorySegment allocateArray(int len) { 812 | return MemorySegment.allocateNative(MemoryLayout.ofSequence(len, $LAYOUT())); 813 | } 814 | 815 | public static @C("struct tagWNDCLASSEXW[]") MemorySegment allocateArray(int len, NativeScope scope) { 816 | return scope.allocate(MemoryLayout.ofSequence(len, $LAYOUT())); 817 | } 818 | 819 | public static @C("struct tagWNDCLASSEXW*") MemorySegment allocatePointer() { 820 | return MemorySegment.allocateNative(C_POINTER); 821 | } 822 | 823 | public static @C("struct tagWNDCLASSEXW*") MemorySegment allocatePointer(NativeScope scope) { 824 | return scope.allocate(C_POINTER); 825 | } 826 | 827 | public static @C("struct tagWNDCLASSEXW") MemorySegment ofAddressRestricted(MemoryAddress addr) { 828 | return RuntimeHelper.asArrayRestricted(addr, $LAYOUT(), 1); 829 | } 830 | } 831 | 832 | public static @C("struct tagWNDCLASSEXW") class WNDCLASSEXW extends tagWNDCLASSEXW { 833 | private WNDCLASSEXW() { 834 | } 835 | } 836 | 837 | public static @C("int") int CS_VREDRAW() { 838 | return (int) 1L; 839 | } 840 | 841 | public static @C("int") int CS_HREDRAW() { 842 | return (int) 2L; 843 | } 844 | 845 | static final FunctionDescriptor WindowProc = FunctionDescriptor.of(C_LONG_LONG, 846 | C_POINTER, 847 | C_INT, 848 | C_LONG_LONG, 849 | C_LONG_LONG 850 | ); 851 | static final FunctionDescriptor LoadCursorW$FUNC_ = FunctionDescriptor.of(C_POINTER, 852 | C_POINTER, 853 | C_POINTER 854 | ); 855 | static final LibraryLookup[] LIBRARIES = RuntimeHelper.libraries(new String[]{}); 856 | 857 | static final MethodHandle LoadCursorW$MH_ = RuntimeHelper.downcallHandle( 858 | LIBRARIES, "LoadCursorW", 859 | "(Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;)Ljdk/incubator/foreign/MemoryAddress;", 860 | LoadCursorW$FUNC_, false 861 | ); 862 | 863 | public static @C("HCURSOR") MemoryAddress LoadCursorW(@C("HINSTANCE") Addressable hInstance, @C("LPCWSTR") Addressable lpCursorName) { 864 | try { 865 | return (MemoryAddress) LoadCursorW$MH_.invokeExact(hInstance.address(), lpCursorName.address()); 866 | } catch (Throwable ex) { 867 | throw new AssertionError(ex); 868 | } 869 | } 870 | 871 | static final MemoryAddress IDC_ARROW$ADDR_CONSTANT_ = MemoryAddress.ofLong(32512L); 872 | 873 | static MemoryAddress IDC_ARROW() { 874 | return IDC_ARROW$ADDR_CONSTANT_; 875 | } 876 | 877 | static final FunctionDescriptor RegisterClassExW$FUNC_ = FunctionDescriptor.of(C_SHORT, 878 | C_POINTER 879 | ); 880 | 881 | static final MethodHandle RegisterClassExW$MH_ = RuntimeHelper.downcallHandle( 882 | LIBRARIES, "RegisterClassExW", 883 | "(Ljdk/incubator/foreign/MemoryAddress;)S", 884 | RegisterClassExW$FUNC_, false 885 | ); 886 | 887 | static MethodHandle RegisterClassExW$MH() { 888 | return RegisterClassExW$MH_; 889 | } 890 | 891 | public static @C("ATOM") short RegisterClassExW(@C("const WNDCLASSEXW*") Addressable x0) { 892 | try { 893 | return (short) RegisterClassExW$MH().invokeExact(x0.address()); 894 | } catch (Throwable ex) { 895 | throw new AssertionError(ex); 896 | } 897 | } 898 | 899 | static final FunctionDescriptor CreateWindowExW$FUNC_ = FunctionDescriptor.of(C_POINTER, 900 | C_LONG, 901 | C_POINTER, 902 | C_POINTER, 903 | C_LONG, 904 | C_INT, 905 | C_INT, 906 | C_INT, 907 | C_INT, 908 | C_POINTER, 909 | C_POINTER, 910 | C_POINTER, 911 | C_POINTER 912 | ); 913 | 914 | static final MethodHandle CreateWindowExW$MH_ = RuntimeHelper.downcallHandle( 915 | LIBRARIES, "CreateWindowExW", 916 | "(ILjdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;" + 917 | "IIIIILjdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;" + 918 | "Ljdk/incubator/foreign/MemoryAddress;Ljdk/incubator/foreign/MemoryAddress;" + 919 | ")Ljdk/incubator/foreign/MemoryAddress;", 920 | CreateWindowExW$FUNC_, false 921 | ); 922 | 923 | public static MethodHandle CreateWindowExW$MH() { 924 | return CreateWindowExW$MH_; 925 | } 926 | 927 | public static @C("HWND") MemoryAddress CreateWindowExW (@C("DWORD") int dwExStyle, 928 | @C("LPCWSTR") Addressable lpClassName, 929 | @C("LPCWSTR") Addressable lpWindowName, 930 | @C("DWORD") int dwStyle, @C("int") int X, @C("int") int Y, 931 | @C("int") int nWidth, @C("int") int nHeight, 932 | @C("HWND") Addressable hWndParent, 933 | @C("HMENU") Addressable hMenu, 934 | @C("HINSTANCE") Addressable hInstance, 935 | @C("LPVOID") Addressable lpParam) { 936 | try { 937 | return (MemoryAddress) CreateWindowExW$MH().invokeExact(dwExStyle, lpClassName.address(), 938 | lpWindowName.address(), dwStyle, X, Y, nWidth, nHeight, hWndParent.address(), hMenu.address(), 939 | hInstance.address(), lpParam.address()); 940 | } catch (Throwable ex) { 941 | throw new AssertionError(ex); 942 | } 943 | } 944 | 945 | static final int WS_OVERLAPPEDWINDOW() { return (int)13565952L; } 946 | static final int CW_USEDEFAULT() { return (int)-2147483648L; } 947 | static final FunctionDescriptor GetLastError$FUNC_ = FunctionDescriptor.of(C_LONG); 948 | public static @C("DWORD") int GetLastError () { 949 | try { 950 | return (int) GetLastError$MH().invokeExact(); 951 | } catch (Throwable ex) { 952 | throw new AssertionError(ex); 953 | } 954 | } 955 | static final MethodHandle GetLastError$MH_ = RuntimeHelper.downcallHandle( 956 | LIBRARIES, "GetLastError", 957 | "()I", 958 | GetLastError$FUNC_, false 959 | ); 960 | static final MethodHandle GetLastError$MH() { return GetLastError$MH_; } 961 | static final FunctionDescriptor ShowWindow$FUNC_ = FunctionDescriptor.of(C_INT, 962 | C_POINTER, 963 | C_INT 964 | ); 965 | static final jdk.incubator.foreign.FunctionDescriptor ShowWindow$FUNC() { return ShowWindow$FUNC_; } 966 | 967 | static final MethodHandle ShowWindow$MH_ = RuntimeHelper.downcallHandle( 968 | LIBRARIES, "ShowWindow", 969 | "(Ljdk/incubator/foreign/MemoryAddress;I)I", 970 | ShowWindow$FUNC_, false 971 | ); 972 | static final MethodHandle ShowWindow$MH() { return ShowWindow$MH_; } 973 | public static @C("BOOL") int ShowWindow (@C("HWND") Addressable hWnd, @C("int") int nCmdShow) { 974 | try { 975 | return (int)ShowWindow$MH().invokeExact(hWnd.address(), nCmdShow); 976 | } catch (Throwable ex) { 977 | throw new AssertionError(ex); 978 | } 979 | } 980 | static final int SW_SHOW() { return (int)5L; } 981 | static final FunctionDescriptor UpdateWindow$FUNC_ = FunctionDescriptor.of(C_INT, 982 | C_POINTER 983 | ); 984 | static final FunctionDescriptor UpdateWindow$FUNC() { return UpdateWindow$FUNC_; } 985 | 986 | static final MethodHandle UpdateWindow$MH_ = RuntimeHelper.downcallHandle( 987 | LIBRARIES, "UpdateWindow", 988 | "(Ljdk/incubator/foreign/MemoryAddress;)I", 989 | UpdateWindow$FUNC_, false 990 | ); 991 | static final java.lang.invoke.MethodHandle UpdateWindow$MH() { return UpdateWindow$MH_; } 992 | public static @C("BOOL") int UpdateWindow (@C("HWND") Addressable hWnd) { 993 | try { 994 | return (int)UpdateWindow$MH().invokeExact(hWnd.address()); 995 | } catch (Throwable ex) { 996 | throw new AssertionError(ex); 997 | } 998 | } 999 | 1000 | static final int DXGI_FORMAT_R8G8B8A8_UNORM() { return (int)28L; } 1001 | static final int DXGI_FORMAT_B8G8R8A8_UNORM() { return (int)87L; } 1002 | 1003 | static final int DXGI_USAGE_SHADER_INPUT() { return (int)16L; } 1004 | static final int DXGI_USAGE_RENDER_TARGET_OUTPUT() { return (int)32L; } 1005 | static final int DXGI_USAGE_BACK_BUFFER() { return (int)64L; } 1006 | static final int DXGI_USAGE_SHARED() { return (int)128L; } 1007 | static final int DXGI_USAGE_READ_ONLY() { return (int)256L; } 1008 | static final int DXGI_USAGE_DISCARD_ON_PRESENT() { return (int)512L; } 1009 | static final int DXGI_USAGE_UNORDERED_ACCESS() { return (int)1024L; } 1010 | 1011 | static final int DXGI_SWAP_EFFECT_DISCARD() { return (int)0L; } 1012 | static final int DXGI_SWAP_EFFECT_SEQUENTIAL() { return (int)1L; } 1013 | static final int DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL() { return (int)3L; } 1014 | static final int DXGI_SWAP_EFFECT_FLIP_DISCARD() { return (int)4L; } 1015 | 1016 | static final int DXGI_ALPHA_MODE_UNSPECIFIED() { return (int)0L; } 1017 | static final int DXGI_ALPHA_MODE_PREMULTIPLIED() { return (int)1L; } 1018 | static final int DXGI_ALPHA_MODE_STRAIGHT() { return (int)2L; } 1019 | static final int DXGI_ALPHA_MODE_IGNORE() { return (int)3L; } 1020 | static final int DXGI_ALPHA_MODE_FORCE_DWORD() { return (int)-1L; } 1021 | 1022 | static final int DXGI_SCALING_STRETCH() { return (int)0L; } 1023 | static final int DXGI_SCALING_NONE() { return (int)1L; } 1024 | static final int DXGI_SCALING_ASPECT_RATIO_STRETCH() { return (int)2L; } 1025 | 1026 | static final int D3D_FEATURE_LEVEL_11_0() { return (int)45056L; } 1027 | static final int D3D_FEATURE_LEVEL_11_1() { return (int)45312L; } 1028 | static final int D3D_FEATURE_LEVEL_12_0() { return (int)49152L; } 1029 | static final int D3D_FEATURE_LEVEL_12_1() { return (int)49408L; } 1030 | 1031 | static final int DXGI_CREATE_FACTORY_DEBUG() { return (int)1L; } 1032 | 1033 | static final int D3D12_DESCRIPTOR_HEAP_FLAG_NONE() { return (int)0L; } 1034 | static final int D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE() { return (int)1L; } 1035 | 1036 | static final int D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV() { return (int)0L; } 1037 | static final int D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER() { return (int)1L; } 1038 | static final int D3D12_DESCRIPTOR_HEAP_TYPE_RTV() { return (int)2L; } 1039 | static final int D3D12_DESCRIPTOR_HEAP_TYPE_DSV() { return (int)3L; } 1040 | static final int D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES() { return (int)4L; } 1041 | } -------------------------------------------------------------------------------- /src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | module com.dx12 { 2 | requires jdk.incubator.foreign; 3 | } --------------------------------------------------------------------------------