Windows DXGI Experiment
Hugo De Vaan
hdevaan76 at gmail.com
Thu Feb 27 16:32:05 UTC 2025
As Jorn pointed out to me, I missed another indirection in my previous
post. I guess it shows that I originally came from a pure C environment
before my Java days and so have little to no experience in C++
specifically. It's not as if in C we never had pointers to pointers, but I
feel C++ really takes it to another level. This is probably going to trip
me up a few more times, but that's okay, I am now at least aware of it and
it will be the first thing I check when my code runs into "FMM over C++"
bugs.
Anyway, the following snippet is taken from a fully working class and uses
the post incubation FFM API (replacing things like NativeScope,
MemoryAddress, MemoryAccess, and so forth from the 2020 example). I thought
I'd post it here to help other people who might Google their way into
examples or tutorials from the incubation era (an unavoidable risk for any
JDK preview projects, I guess).
private static MemorySegment DEFINE_GUID(
Arena arena,
int data1, int data2, int data3,
int data4_0, int data4_1, int data4_2, int data4_3,
int data4_4, int data4_5, int data4_6, int data4_7) {
MemorySegment refIID = IID.allocate(arena);
IID.Data1(refIID, data1);
IID.Data2(refIID, (short)data2);
IID.Data3(refIID, (short)data3);
MemorySegment data4 = IID.Data4(refIID);
IID.Data4(data4, 0, (byte) data4_0);
IID.Data4(data4, 1, (byte) data4_1);
IID.Data4(data4, 2, (byte) data4_2);
IID.Data4(data4, 3, (byte) data4_3);
IID.Data4(data4, 4, (byte) data4_4);
IID.Data4(data4, 5, (byte) data4_5);
IID.Data4(data4, 6, (byte) data4_6);
IID.Data4(data4, 7, (byte) data4_7);
return refIID;
}
static final MemorySegment IID_IDXGIFactory1 =
DEFINE_GUID(
Arena.global(),
0x770aae78, 0xf26f, 0x4dba,
0xa8, 0x29, 0x25, 0x3c, 0x83, 0xd1, 0xb3, 0x87);
public static final void main(String[] args) {
Linker linker = Linker.nativeLinker();
SymbolLookup symbols = SymbolLookup.
libraryLookup(
"C:\\Windows\\System32\\dxgi.dll",
arena);
try (Arena arena = Arena.ofConfined()) {
MemorySegment factoryPointer =
arena.allocate(ValueLayout.ADDRESS);
int hresult = dxgi_h.CreateDXGIFactory1(
IID_IDXGIFactory1, factoryPointer);
System.out.println(
"CreateDXGIFactory: " +
HexFormat.of().toHexDigits(hresult));
MemorySegment factory =
IDXGIFactory1.reinterpret(
factoryPointer.get(dxgi_h.C_POINTER, 0L),
arena,
null);
MemorySegment factoryVtable =
IDXGIFactory1.lpVtbl(factory);
MemorySegment EnumAdapters1 =
IDXGIFactory1Vtbl.EnumAdapters1(factoryVtable);
MemorySegment adapterPointer =
arena.allocate(dxgi_h.C_POINTER);
hresult = IDXGIFacotry1Vtbl.EnumAdapters1.invoke(
EnumAdapters1, factory, 0, adapterPointer);
System.out.println(
"EnumAdapters: " +
HexFormat.of().toHexDigits(hresult));
MemorySegment adapter =
IDXGIAdapter1.reinterpret(
adapterPointer.get(dxgi_h.C_POINTER, 0L),
arena,
null);
MemorySegment adapterVtable =
IDXGIAdapter1.lpVtbl(adapter);
MemorySegment GetDescriptor1 =
IDXGIAdapter1Vtbl.GetDesc1(adapterVtable);
MemorySegment descriptorPointer =
DXGI_ADAPTER_DESC.allocate(arena);
hresult = IDXGIAdapter1Vtbl.GetDesc1.invoke(
GetDescriptor1, adapter, descriptorPointer);
System.out.println(
"GetDescriptor: " +
HexFormat.of().toHexDigits(hresult));
MemorySegment cstring = DXGI_ADAPTER_DESC1.
Description(descriptorPointer);
String jstring = cstring.getString(
0, StandardCharsets.UTF_16LE);
System.out.println("Adapter[0]: " + jstring);
} catch (Throwable t) {
t.printStackTrace();
}
}
This should print the descriptor of the first adapter (for example: "NVIDIA
GeForce RTX 4060"). Anyone trying this in a headless environment such as a
cloud node might want to be careful, because I haven't tested whether or
not a software adapter would also qualify for this function (if it doesn't,
I expect this snippet will crash your JVM).
Thanks again for the help, getting over the first hurdles makes all the
difference between being able to continue a project at all or staying
completely stuck. I still got (and will get) some things wrong, but with
the basic parts up and running, I will be able to figure out problems for
myself.
Kind regards,
Hugo
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/panama-dev/attachments/20250227/9c9dabd3/attachment.htm>
More information about the panama-dev
mailing list