I am following the guide and Javadoc, but there is a fatal error occurs when creating logic device by function VK13.vkCreateDevice().
I have tried it for whole day, but I can't resolve it. :'(
the code:
package pers.ghostcaptain.creativecreation.view;
import org.lwjgl.PointerBuffer;
import org.lwjgl.glfw.GLFWVulkan;
import org.lwjgl.vulkan.*;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.charset.StandardCharsets;
public class VulkanDriver {
public static final ByteBuffer appName;
public static final ByteBuffer engineName;
public static final int whichDevice = 0; //the index of RTX3070 on my computer
public static VkInstance vkInstance;
public static VkPhysicalDevice physicalDevice;
public static VkDevice logicalDevice;
public static VkQueue graphicsQueue;
static {
byte[] name1 = "创éâ,¬Â ä¸â€"ç•Å'".getBytes(StandardCharsets.UTF_8);
appName = ByteBuffer.allocateDirect(name1.length + 1);
appName.put(0,name1);
appName.put(name1.length, (byte) 0);
byte[] name2 = "No Engine".getBytes(StandardCharsets.UTF_8);
engineName = ByteBuffer.allocateDirect(name2.length +1);
appName.put(0,name2);
appName.put(name1.length, (byte) 0);
}
public static void initialize() {
createInstance();
selectPhysicalDevice();
createLogicalDevice();
}
public static void createInstance() {
VkApplicationInfo appInfo = VkApplicationInfo.create();
appInfo.sType(VK13.VK_STRUCTURE_TYPE_APPLICATION_INFO);
appInfo.pApplicationName(appName);
appInfo.applicationVersion(VK13.VK_MAKE_VERSION(1, 0, 0));
appInfo.pEngineName(engineName);
appInfo.engineVersion(VK13.VK_MAKE_VERSION(1, 0, 0));
appInfo.apiVersion(VK13.VK_API_VERSION_1_3);
VkInstanceCreateInfo createInfo = VkInstanceCreateInfo.create();
createInfo.sType(VK13.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
createInfo.pApplicationInfo(appInfo);
PointerBuffer temp1 = GLFWVulkan.glfwGetRequiredInstanceExtensions();
createInfo.ppEnabledExtensionNames(temp1);
createInfo.ppEnabledLayerNames(null);
PointerBuffer vkInstanceP = PointerBuffer.allocateDirect(1);
if (VK13.vkCreateInstance(createInfo, null, vkInstanceP) != VK13.VK_SUCCESS) {
throw new RuntimeException("å¯动vulkan失败ï¼Âæâ€" æ³•åˆ›å»ºå®žä¾‹ï¼Â");
}
vkInstance = new VkInstance(vkInstanceP.get(0), createInfo);
}
public static void selectPhysicalDevice() {
int[] temp1 = new int[1];
if (VK13.vkEnumeratePhysicalDevices(vkInstance, temp1, null) != VK13.VK_SUCCESS) {
throw new RuntimeException("å¯动vulkan失败ï¼Â获åÂâ€"显å¡失败ï¼Â");
}
PointerBuffer temp2 = PointerBuffer.allocateDirect(temp1[0]);
if (VK13.vkEnumeratePhysicalDevices(vkInstance, temp1, temp2) != VK13.VK_SUCCESS) {
throw new RuntimeException("å¯动vulkan失败ï¼Â获åÂâ€"显å¡失败ï¼Â");
}
physicalDevice = new VkPhysicalDevice(temp2.get(whichDevice), vkInstance);
}
public static void createLogicalDevice() {
int[] temp1 = new int[1];
VK13.vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, temp1, null);
VkQueueFamilyProperties.Buffer temp2 = VkQueueFamilyProperties.create(temp1[0]);
VK13.vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, temp1, temp2);
int n = temp1[0];
int result = -1;
VkQueueFamilyProperties.Buffer tempQ;
for (int i = 0; i < n; i++) {
tempQ = temp2.slice(i,1);
if (tempQ.queueCount() > 0 && (tempQ.queueFlags() & VK13.VK_QUEUE_GRAPHICS_BIT) > 0) {
result = i;
break;
}
}
if (result == -1) {
throw new RuntimeException("å¯动vulkan失败ï¼Â没æÅ"‰å¯çâ€Â¨Ã§Å¡â€žÃ©ËœÅ¸Ã¥Ë†â€"æâ€"Âï¼Â");
}
VkDeviceQueueCreateInfo queueInfo = VkDeviceQueueCreateInfo.create();
queueInfo.sType(VK13.VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO);
queueInfo.queueFamilyIndex(result);
FloatBuffer temp3 = FloatBuffer.allocate(1);
temp3.put(0, 1.0f);
queueInfo.pQueuePriorities(temp3);
VkPhysicalDeviceFeatures features = VkPhysicalDeviceFeatures.create();
VkDeviceCreateInfo createInfo = VkDeviceCreateInfo.create();
createInfo.sType(VK13.VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
VkDeviceQueueCreateInfo.Buffer temp4 = VkDeviceQueueCreateInfo.create(1);
temp4.put(0, queueInfo);
createInfo.pQueueCreateInfos(temp4);
createInfo.pEnabledFeatures(features);
createInfo.ppEnabledLayerNames(null);
createInfo.ppEnabledExtensionNames(null);
PointerBuffer temp5 = PointerBuffer.allocateDirect(1);
//fatal error occurred while executing the following function: (VK13.vkCreateDevice(physicalDevice, createInfo, null, temp5)
if (VK13.vkCreateDevice(physicalDevice, createInfo, null, temp5) != VK13.VK_SUCCESS) { //fatal error occurred
throw new RuntimeException("å¯动vulkan失败ï¼Âæâ€" æ³•åˆ›å»ºéâ,¬Â»Ã¨Â¾â€˜Ã¨Â®Â¾Ã¥Â¤â€¡Ã¯Â¼Â");
}
logicalDevice = new VkDevice(temp5.get(0), physicalDevice, createInfo);
PointerBuffer temp6 = PointerBuffer.allocateDirect(1);
VK13.vkGetDeviceQueue(logicalDevice, result, 0, temp6);
graphicsQueue = new VkQueue(temp6.get(0), logicalDevice);
}
public static void destroy() {
VK13.vkDestroyInstance(vkInstance, null);
VK13.vkDestroyDevice(logicalDevice, null);
}
}
The report is followed.
If anynoe could help me. Thanks for a lot!
The report:
Current thread (0x00000209a78fde20): JavaThread "main" [_thread_in_native, id=1448, stack(0x0000006519600000,0x0000006519700000)]
Stack: [0x0000006519600000,0x0000006519700000], sp=0x00000065196fe358, free space=1016k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [VCRUNTIME140.dll+0x140a]
C [VkLayer_khronos_validation.dll+0xdd2e31]
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j org.lwjgl.system.JNI.callPPPPI(JJJJJ)I+0
j org.lwjgl.vulkan.VK10.nvkCreateDevice(Lorg/lwjgl/vulkan/VkPhysicalDevice;JJJ)I+29
j org.lwjgl.vulkan.VK10.vkCreateDevice(Lorg/lwjgl/vulkan/VkPhysicalDevice;Lorg/lwjgl/vulkan/VkDeviceCreateInfo;Lorg/lwjgl/vulkan/VkAllocationCallbacks;Lorg/lwjgl/PointerBuffer;)I+24
j pers.ghostcaptain.creativecreation.view.VulkanDriver.createLogicalDevice()V+216
j pers.ghostcaptain.creativecreation.view.VulkanDriver.initialize()V+6
j pers.ghostcaptain.creativecreation.Main.main([Ljava/lang/String;)V+3
v ~StubRoutines::call_stub
siginfo: EXCEPTION_ACCESS_VIOLATION (0xc0000005), reading address 0x0000000000000010
Register to memory mapping:
RIP=0x00007ffa3fb2140a VCRUNTIME140.dll
RAX=0x000003a620750090 points into unknown readable memory: 0x000003a620750098 | 98 00 75 20 a6 03 00 00
RBX=0x000003a6207062c8 points into unknown readable memory: 0x7069726300000002 | 02 00 00 00 63 72 69 70
RCX=0x000003a620750090 points into unknown readable memory: 0x000003a620750098 | 98 00 75 20 a6 03 00 00
RDX=0x0000000000000010 is an unknown value
RSP=0x00000065196fe358 is pointing into the stack for thread: 0x00000209a78fde20
RBP=0x000003a620750088 points into unknown readable memory: 0x000003a620750090 | 90 00 75 20 a6 03 00 00
RSI=0x0000000000000001 is an unknown value
RDI=0x0000020a26953010 points into unknown readable memory: 0x0000000000000002 | 02 00 00 00 00 00 00 00
R8 =0x0000000000000004 is an unknown value
R9 =0x00007ffa3fb2140a VCRUNTIME140.dll
R10=0x00007ffa3fb20000 VCRUNTIME140.dll
R11=0x0000000000000001 is an unknown value
R12=0x0 is NULL
R13=0xffffffffffffffff is an unknown value
R14=0x0 is NULL
R15=0x00000065196fecd0 is pointing into the stack for thread: 0x00000209a78fde20
Well, I have resolved it. 8)
The reason is that I use FloatBuffer.allocate() to create a FloatBuffer, but this method only can create HeapBuffer based on JVM.
On jdk8, MemoryUtil.memAddress(Buffer) will return 0(nullptr) with a non-direct buffer which can be caught by Check() and throw a NullPointerException, but on jdk11 or later, it will return a address based on JVM which will be recognized as a wild pointer when transfer to JNI, then the wild pointer causes a fatal error in native.