Hello Guest

Logical device creation problem[resolved]

  • 2 Replies
  • 1368 Views
Logical device creation problem[resolved]
« on: November 02, 2023, 08:24:53 »
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:
Code: [Select]
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!
« Last Edit: November 03, 2023, 00:09:51 by GhCa »

The report:
Code: [Select]
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

Re: Logical device creation problem[resolved]
« Reply #2 on: November 03, 2023, 00:31:06 »
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.