Git Product home page Git Product logo

vkk's Introduction

VK², Kotlin Wrapper for Vulkan

Build Status license Release Size Github All Releases

The goal of the VK² is to provide a library for the Vulkan C API to improve the developers Vulkan experience without introducing any considerable CPU runtime cost. It adds features like type safety for enums and bitfields, collection support, exceptions and simple enumerations.

Strongly inspired by Vulkan hpp, it's shaped on the Sasha examples port. It's the Vulkan counterpart of the OpenGL gln.

See it in action here!

How to retrieve it:

You can find all the instructions by mary

Usage

vk object

To avoid name collisions with the lwjgl Vulkan bindings, the VK² wrapper resides mostly under the object vk. The following rules apply to the new naming

  • All functions, extension functions, and structs have the Vk prefix removed. In addition to this the first letter of functions is lower case.
    • VkCreateImage can be accessed as vk.createImage
    • VkImageTiling can be accessed as vk.ImageTiling
    • VkImageCreateInfo can be accessed as vk.ImageCreateInfo
  • Enums are mapped to scoped enums to provide compile time type safety. The names have been changed to have the Enum Base in CamelCase with the VK_ prefix and the enum name in Capital letters (corresponding to the original counterpart). Enums starting with a number requires to be surrounded by backticks the underscore prefix _, this because Idea handles backticks this very poorly.

Some examples:

  • VK_COLOR_SPACE_SRGB_NONLINEAR_KHR is now VkColorSpace.SRGB_NONLINEAR_KHR
  • VK_IMAGETYPE_2D is now VkImageType._2D
  • Flag bits are handled like scoped enums with the addition that the _BIT suffix has also been removed.

Extension functions

This is one case where Kotlin really shines: VK² declares a class for all handles to ensure full type safety and to add support for member functions on handles. A member function has been added to a handle class for each function which accepts the corresponding handle as first parameter. Instead of vkBindBufferMemory(device, ...) one can write device.bindBufferMemory(...).

Mask Flags

All flags masks have been typealiased accordingly. For example a field of type VkBufferUsageFlags means that it represents a mask from the VkBufferUsage. enum. The postfix Flag has been eliminated from the enum name for conciseness matter. However, it has been kept for some special cases, such as VkQueueFlag, to avoid clashes with existing other structures, in this case the VkQueue class for example.

CreateInfo structs and appBuffer

When constructing a handle in Vulkan one usually has to create some CreateInfo struct which describes the new handle. Moreover, allocation has to be handled manually and everywhere C code uses pointers, we have to use buffers on the JVM. This can result in quite lengthy code as can be seen in the following Vulkan example:

val info = VkImageCreateInfo.calloc()
    .sType(VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO)
    .pNext(null)
    .flags(...some flags...)
    .imageType(VK_IMAGE_TYPE_2D)
    .format(VK_FORMAT_R8G8B8A8_UNORM)
    .extent().apply {
        .width(size.x)
        .height(size.y)
        .depth(1)
    }
    .mipLevels(1)
    .arrayLayers(1)
    .samples(VK_SAMPLE_COUNT_1_BIT)
    .tiling(VK_IMAGE_TILING_OPTIMAL)
    .usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
    .sharingMode(VK_SHARING_MODE_EXCLUSIVE)
    .pQueueFamilyIndices(null)
    .initialLayout(VK_IMAGE_LAYOUT_UNDEFINED)
val pImage = MemoryUtil.memAllocLong(1)
vkCreateImage(device, info, allocator, pImage)
image = pImage.get(0)
info.free()
memFree(pImage)

One typical issue Vulkan developers encounter when filling out a CreateInfo struct field by field is that sType is incorrect.

VK² provides constructors for all CreateInfo objects (and others) where sType is automatically filled with the correct value and pNext set to a nullptr by default. All other field are also initialized to zero. There are exceptions though.

Moreover, all the allocations takes place in the thread local memory, using the lwjgl MemoryStack class.

VK² provides also special method accepting glm classes, like extent accepting a (Vec3i) or (Vec2i, Int). Here's how the same code looks with a constructor:

val info = vk.ImageCreateInfo {
    flags = ...some flags...
    imageType = VkImageType.`2D`
    format = VkFormat.R8G8B8A8_UNORM
    extent(size, 1)
    mipLevels = 1
    arrayLayers = 1
    samples = VkSampleCount.`1_BIT`
    tiling = VkImageTiling.OPTIMAL
    usage = VkImageUsage.COLOR_ATTACHMENT_BIT.i
    sharingMode = VkSharingMode.EXCLUSIVE
}
image = device createImage info

Errors will be checked automatically in debug mode, but you can set DEBUG explicitely as you wish. In case VULKAN_NO_EXCEPTIONS is true, errors will be reported in the System.err stream, otherwise the exception to the corresponding error will be thrown.

TODO

vkk's People

Contributors

elect86 avatar sylvyrfysh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vkk's Issues

SIGSEGV in createDevice, EnumerateDeviceExtensionProperties

Hi, when i run such code (Java 13, Archlinux, com.github.kotlin-graphics:vkk:-SNAPSHOT)

val queueCreateInfos = ArrayList<DeviceQueueCreateInfo>()

graphicsQueueIndex = getQueueFamilyIndex(queueFamilyProperties, VkQueueFlag.GRAPHICS_BIT)
queueCreateInfos += DeviceQueueCreateInfo(
     queueFamilyIndex = graphicsQueueIndex,
     queuePriority = 1.0F
)

val createInfo = DeviceCreateInfo(
     queueCreateInfos = queueCreateInfos,
     enabledExtensionNames = setOf(KHRSwapchain.VK_KHR_SWAPCHAIN_EXTENSION_NAME),
     enabledFeatures = PhysicalDeviceFeatures()
)
physicalDevice.createDevice(createInfo)

I get:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f0c16c2ea88, pid=57643, tid=57644
#
# JRE version: OpenJDK Runtime Environment (13.0.1+9) (build 13.0.1+9)
# Java VM: OpenJDK 64-Bit Server VM (13.0.1+9, mixed mode, tiered, compressed oops, g1 gc, linux-amd64)
# Problematic frame:
# C  [libvulkan.so.1+0x2ea88]  loader_layer_create_device+0x408
#
# Core dump will be written. Default location: Core dumps may be processed with "/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h" (or dumping to /home/runx/misc/src/universe/core.57643)
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

I rebuilt the libvulkan.so.1 library with debug information and open dump in gdb:

rogram terminated with signal SIGABRT, Aborted.
#0  0x00007f0c6792cf25 in raise () from /usr/lib/libc.so.6
[Current thread is 1 (Thread 0x7f0c66147700 (LWP 57644))]
(gdb) bt
#0  0x00007f0c6792cf25 in raise () from /usr/lib/libc.so.6
#1  0x00007f0c67916897 in abort () from /usr/lib/libc.so.6
#2  0x00007f0c6671d096 in ?? () from /usr/lib/jvm/java-13-openjdk/lib/server/libjvm.so
#3  0x00007f0c6742f277 in ?? () from /usr/lib/jvm/java-13-openjdk/lib/server/libjvm.so
#4  0x00007f0c6742fbfb in ?? () from /usr/lib/jvm/java-13-openjdk/lib/server/libjvm.so
#5  0x00007f0c6742fc2e in ?? () from /usr/lib/jvm/java-13-openjdk/lib/server/libjvm.so
#6  0x00007f0c670e8a2f in JVM_handle_linux_signal () from /usr/lib/jvm/java-13-openjdk/lib/server/libjvm.so
#7  0x00007f0c670dc6aa in ?? () from /usr/lib/jvm/java-13-openjdk/lib/server/libjvm.so
#8  <signal handler called>
#9  loader_layer_create_device (instance=instance@entry=0x0, physicalDevice=physicalDevice@entry=0x7f0c609f9220, pCreateInfo=pCreateInfo@entry=0x7f0c60a091d0, 
    pAllocator=pAllocator@entry=0x0, pDevice=pDevice@entry=0x7f0c60a09218, layerGIPA=layerGIPA@entry=0x0, nextGDPA=0x0) at /usr/src/debug/Vulkan-Loader-1.1.130/loader/loader.c:5537
#10 0x00007f0c16c320b1 in vkCreateDevice (physicalDevice=0x7f0c609f9220, pCreateInfo=0x7f0c60a091d0, pAllocator=0x0, pDevice=0x7f0c60a09218)
    at /usr/src/debug/Vulkan-Loader-1.1.130/loader/trampoline.c:756
#11 0x00007f0c487b4597 in ?? ()
#12 0x00007f0c16c32070 in ?? () at /usr/src/debug/Vulkan-Loader-1.1.130/loader/trampoline.c:665 from /usr/lib/libvulkan.so.1
#13 0x0000000800108670 in ?? ()
#14 0x00007f0c1745cff8 in ?? ()
#15 0x00007f0c6001a800 in ?? ()
#16 0x00007f0c1745cff8 in ?? ()
#17 0x00007f0c6001a800 in ?? ()
#18 0xfffffffe00000000 in ?? ()
#19 0x0000000000000000 in ?? ()

/usr/src/debug/Vulkan-Loader-1.1.130/loader/loader.c:5537:

enumDeviceExtensionProperties = inst->disp->layer_inst_disp.EnumerateDeviceExtensionProperties;

in

// Get the physical device (ICD) extensions
    struct loader_extension_list icd_exts;
    icd_exts.list = NULL;
    res = loader_init_generic_list(inst, (struct loader_generic_list *)&icd_exts, sizeof(VkExtensionProperties));
    if (VK_SUCCESS != res) {
        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "vkCreateDevice:  Failed to create ICD extension list");
        goto out;
    }

    PFN_vkEnumerateDeviceExtensionProperties enumDeviceExtensionProperties = NULL;
    if (layerGIPA != NULL) {
        enumDeviceExtensionProperties =
            (PFN_vkEnumerateDeviceExtensionProperties)layerGIPA(instance, "vkEnumerateDeviceExtensionProperties");
    } else {
        enumDeviceExtensionProperties = inst->disp->layer_inst_disp.EnumerateDeviceExtensionProperties;
    }
    res = loader_add_device_extensions(inst, enumDeviceExtensionProperties, internal_device, "Unknown", &icd_exts);
    if (res != VK_SUCCESS) {
        loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "vkCreateDevice:  Failed to add extensions to list");
        goto out;
    }

SIGSEGV in createDevice when using queuePriorities

Hi Folks,

I believe there is a bug with the priorities float buffer allocation in vk.DeviceQueueCreateInfo.

When doing the following the creation of a logical device fails with a SIGSEGV:

val queue = vk.DeviceQueueCreateInfo {
    queueFamilyIndex = graphics
    queuePriority = 1.0f
}

Results in

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x0000000122816a51, pid=88962, tid=0x0000000000000307
#
# JRE version: Java(TM) SE Runtime Environment (8.0_171-b11) (build 1.8.0_171-b11)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.171-b11 mixed mode bsd-amd64 compressed oops)
# Problematic frame:
# C  [libMoltenVK.dylib+0x56a51]

However, when I push the float buffer myself, everything works fine:

val queue = vk.DeviceQueueCreateInfo {
    queueFamilyIndex = graphics
    queuePriorities = stack.floats(1.0f)
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.