diff --git a/build.gradle b/build.gradle index 32be347c0..72347f910 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ group = 'com.github.kotlin-graphics' buildscript { - ext.kotlinVersion = '1.2.60' + ext.kotlinVersion = '1.2.70' repositories { jcenter() // shadow @@ -25,7 +25,7 @@ buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.4' - classpath "org.junit.platform:junit-platform-gradle-plugin:1.1.0" + classpath "org.junit.platform:junit-platform-gradle-plugin:1.2.0" } } @@ -33,9 +33,9 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" - implementation 'com.github.kotlin-graphics:uno-sdk:869ee1b' + implementation 'com.github.kotlin-graphics:uno-sdk:c74defd9f15267646ae0205e8a3525d581ec2d9e' - testImplementation 'io.kotlintest:kotlintest-runner-junit5:3.0.6' + testImplementation 'io.kotlintest:kotlintest-runner-junit5:3.1.10' def joglVersion = '2.3.2' implementation "org.jogamp.gluegen:gluegen-rt-main:$joglVersion" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a3a763411..e755500c5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/src/main/kotlin/imgui/font.kt b/src/main/kotlin/imgui/font.kt index e2c00b06c..91bfc5a3b 100644 --- a/src/main/kotlin/imgui/font.kt +++ b/src/main/kotlin/imgui/font.kt @@ -2,8 +2,8 @@ package imgui import glm_.* -import glm_.buffer.bufferBig -import glm_.buffer.free +import kool.bufferBig +import kool.free import glm_.vec2.Vec2 import glm_.vec2.Vec2i import glm_.vec2.operators.div diff --git a/src/main/kotlin/imgui/imgui.kt b/src/main/kotlin/imgui/imgui.kt index 4497e2884..98e645089 100644 --- a/src/main/kotlin/imgui/imgui.kt +++ b/src/main/kotlin/imgui/imgui.kt @@ -82,7 +82,7 @@ object ImGui : imgui_internal { // Version - val beta = 1 + val beta = 2 /** get the compiled version string e.g. "1.23" */ val version = "1.63.$beta" /** Integer encoded as XYYZZ for use in #if preprocessor conditionals. diff --git a/src/main/kotlin/imgui/impl/ImplGL3.kt b/src/main/kotlin/imgui/impl/ImplGL3.kt index 484d68b59..43c8a251f 100644 --- a/src/main/kotlin/imgui/impl/ImplGL3.kt +++ b/src/main/kotlin/imgui/impl/ImplGL3.kt @@ -1,9 +1,9 @@ package imgui.impl import glm_.* -import glm_.buffer.bufferBig -import glm_.buffer.free -import glm_.buffer.intBufferBig +import kool.bufferBig +import kool.free +import kool.intBufferBig import glm_.vec2.Vec2 import gln.* import gln.buffer.BufferTarget diff --git a/src/main/kotlin/imgui/impl/ImplVk.kt b/src/main/kotlin/imgui/impl/ImplVk.kt index b23c924d9..9e755a179 100644 --- a/src/main/kotlin/imgui/impl/ImplVk.kt +++ b/src/main/kotlin/imgui/impl/ImplVk.kt @@ -1,843 +1,843 @@ -package imgui.impl - -import ab.appBuffer -import gli_.has -import glm_.* -import glm_.buffer.adr -import glm_.vec2.Vec2 -import glm_.vec2.Vec2i -import glm_.vec4.Vec4b -import imgui.* -import org.lwjgl.system.MemoryUtil.* -import org.lwjgl.vulkan.* -import org.lwjgl.vulkan.VK10.* -import uno.buffer.toBuffer -import vkk.* -import kotlin.reflect.KMutableProperty0 - -object ImplVk { - - - // ===== impl_vk.h ===== - - var VK_QUEUED_FRAMES = 2 - val BINDING = 0 // TODO -> Omar - - fun init(): Boolean { - - assert(::instance.isInitialized) - assert(::physicalDevice.isInitialized) - assert(::device.isInitialized) - assert(::queue.isInitialized) - assert(descriptorPool != NULL) - assert(renderPass != NULL) - - renderPass = wd.renderPass - - createDeviceObjects() - - return true - } - - fun shutdown() = invalidateDeviceObjects() - - fun newFrame() {} - - /** Render function - * (this used to be set in io.renderDrawListsFn and called by ImGui::render(), - * but you can now call this directly from your main loop) */ - fun renderDrawData(drawData: DrawData) { - - if (drawData.totalVtxCount == 0) return - - val fd = framesDataBuffers[frameIndex] - frameIndex = (frameIndex + 1) % VK_QUEUED_FRAMES - - // Create the Vertex and Index buffers: - val vertexSize = drawData.totalVtxCount * DrawVert.size.L - val indexSize = drawData.totalIdxCount * DrawIdx.BYTES.L - if (fd.vertexBuffer == NULL || fd.vertexBufferSize < vertexSize) - fd.vertexBufferSize = createOrResizeBuffer(fd::vertexBuffer, fd::vertexBufferMemory, vertexSize, VkBufferUsage.VERTEX_BUFFER_BIT) - if (fd.indexBuffer == NULL || fd.indexBufferSize < indexSize) - fd.indexBufferSize = createOrResizeBuffer(fd::indexBuffer, fd::indexBufferMemory, indexSize, VkBufferUsage.INDEX_BUFFER_BIT) - - // Upload Vertex and index Data: - run { - var vtxDst = device.mapMemory(fd.vertexBufferMemory, 0, vertexSize) - var idxDst = device.mapMemory(fd.indexBufferMemory, 0, indexSize) - for (n in 0 until drawData.cmdListsCount) { - val cmdList = drawData.cmdLists[n] - cmdList.vtxBuffer.forEachIndexed { i, v -> - memPutFloat(vtxDst + DrawVert.size * i, v.pos.x) - memPutFloat(vtxDst + DrawVert.size * i + Float.BYTES, v.pos.y) - memPutFloat(vtxDst + DrawVert.size * i + Vec2.size, v.uv.x) - memPutFloat(vtxDst + DrawVert.size * i + Vec2.size + Float.BYTES, v.uv.y) - memPutInt(vtxDst + DrawVert.size * i + Vec2.size * 2, v.col) - } - cmdList.idxBuffer.forEachIndexed { i, it -> memPutInt(idxDst + DrawIdx.BYTES * i, it) } - vtxDst += cmdList.vtxBuffer.size.L - idxDst += cmdList.idxBuffer.size.L - } - val range = vk.MappedMemoryRange(2).also { - it[0].apply { - memory = fd.vertexBufferMemory - size = VK_WHOLE_SIZE - } - it[1].apply { - memory = fd.indexBufferMemory - size = VK_WHOLE_SIZE - } - } - device.apply { - flushMappedMemoryRanges(range) - unmapMemory(fd.vertexBufferMemory) - unmapMemory(fd.indexBufferMemory) - } - } - - val commandBuffer = wd.frame.commandBuffer.apply { - - // Bind pipeline and descriptor sets: - bindPipeline(VkPipelineBindPoint.GRAPHICS, pipeline) - bindDescriptorSets(VkPipelineBindPoint.GRAPHICS, pipelineLayout, descriptorSet) - - // Bind Vertex And Index Buffer: - bindVertexBuffers(fd.vertexBuffer) - bindIndexBuffer(fd.indexBuffer, 0, VkIndexType.UINT16) - - // Setup viewport: - setViewport(vk.Viewport(drawData.displaySize.x, drawData.displaySize.y)) - - /* Setup scale and translation: - Our visible imgui space lies from drawData.displayPps (top left) to drawData.displayPos+dataData.displaySize (bottom right). - DisplayMin is typically (0,0) for single viewport apps. */ - val scale = appBuffer.floatBufferOf(2f / drawData.displaySize.x, 2f / drawData.displaySize.y) - val translate = appBuffer.floatBufferOf(-1f - drawData.displayPos.x * scale[0], -1f - drawData.displayPos.y * scale[1]) - pushConstants(pipelineLayout, VkShaderStage.VERTEX_BIT.i, 0, scale) - pushConstants(pipelineLayout, VkShaderStage.VERTEX_BIT.i, scale.size, translate) - } - - // Render the command lists: - var vtxOffset = 0 - var idxOffset = 0 - val displayPos = drawData.displayPos - for (cmdList in drawData.cmdLists) { - for (cmd in cmdList.cmdBuffer) { - val cb = cmd.userCallback - if (cb != null) - cb(cmdList, cmd) - else { - // Apply scissor/clipping rectangle - // FIXME: We could clamp width/height based on clamped min/max values. - commandBuffer setScissor vk.Rect2D( - offsetX = (cmd.clipRect.x - displayPos.x).i.takeIf { it > 0 } ?: 0, - offsetY = (cmd.clipRect.y - displayPos.y).i.takeIf { it > 0 } ?: 0, - width = (cmd.clipRect.z - cmd.clipRect.x).i, - height = (cmd.clipRect.w - cmd.clipRect.y + 1).i) // FIXME: Why +1 here? - - // Draw - commandBuffer.drawIndexed(cmd.elemCount, 1, idxOffset, vtxOffset, 0) - } - idxOffset += cmd.elemCount * Int.BYTES // TODO check - } - vtxOffset += cmdList.vtxBuffer.size * DrawVert.size - } - } - - fun createOrResizeBuffer(bufferPtr: KMutableProperty0, bufferMemoryPtr: KMutableProperty0, newSize: Long, usage: VkBufferUsage): VkDeviceSize { - - var buffer by bufferPtr - var bufferMemory by bufferMemoryPtr - if (buffer != NULL) - device destroyBuffer buffer - if (bufferMemory != NULL) - device freeMemory bufferMemory - - val vertexBufferSizeAligned: VkDeviceSize = ((newSize - 1) / bufferMemoryAlignment + 1) * bufferMemoryAlignment - val bufferInfo = vk.BufferCreateInfo { - size = vertexBufferSizeAligned - this.usage = usage.i - sharingMode = VkSharingMode.EXCLUSIVE - } - buffer = device createBuffer bufferInfo - - val req = device getBufferMemoryRequirements buffer - bufferMemoryAlignment = bufferMemoryAlignment.takeIf { it > req.alignment } ?: req.alignment - val allocInfo = vk.MemoryAllocateInfo { - allocationSize = req.size - memoryTypeIndex = memoryType(VkMemoryProperty.HOST_VISIBLE_BIT, req.memoryTypeBits) - } - bufferMemory = device allocateMemory allocInfo - - device.bindBufferMemory(buffer, bufferMemory) - - return newSize - } - -// Called by Init/NewFrame/Shutdown - - -// ===== impl_vk.cpp ===== - - // Vulkan data - lateinit var physicalDevice: VkPhysicalDevice - lateinit var instance: VkInstance - lateinit var device: VkDevice - var queueFamily = -1 - lateinit var queue: VkQueue - var debugReport: VkDebugReportCallback = NULL - var pipelineCache: VkPipelineCache = NULL - var descriptorPool: VkDescriptorPool = NULL - var renderPass: VkRenderPass = NULL - - var bufferMemoryAlignment: VkDeviceSize = 256 - var pipelineCreateFlags: VkPipelineCreateFlags = 0 - - var descriptorSetLayout: VkDescriptorSetLayout = NULL - var pipelineLayout: VkPipelineLayout = NULL - var descriptorSet: VkDescriptorSet = NULL - var pipeline: VkPipeline = NULL - - // Frame data - class FrameDataForRender { - var vertexBufferMemory: VkDeviceMemory = NULL - var indexBufferMemory: VkDeviceMemory = NULL - var vertexBufferSize: VkDeviceSize = NULL - var indexBufferSize: VkDeviceSize = NULL - var vertexBuffer: VkBuffer = NULL - var indexBuffer: VkBuffer = NULL - } - - var frameIndex = 0 - val framesDataBuffers = Array(VK_QUEUED_FRAMES) { FrameDataForRender() } - - // Font data - var fontSampler: VkSampler = NULL - var fontMemory: VkDeviceMemory = NULL - var fontImage: VkImage = NULL - var fontView: VkImageView = NULL - var uploadBufferMemory: VkDeviceMemory = NULL - var uploadBuffer: VkBuffer = NULL - - // Called by Init/NewFrame/Shutdown - - fun invalidateFontUploadObjects() { - if (uploadBuffer != NULL) { - device destroyBuffer uploadBuffer - uploadBuffer = NULL - } - if (uploadBufferMemory != NULL) { - device freeMemory uploadBufferMemory - uploadBufferMemory = NULL - } - } - - fun invalidateDeviceObjects() { - invalidateFontUploadObjects() - device.apply { - framesDataBuffers.forEach { fd -> - if (fd.vertexBuffer != NULL) destroyBuffer(fd.vertexBuffer).also { fd.vertexBuffer = NULL } - if (fd.vertexBufferMemory != NULL) freeMemory(fd.vertexBufferMemory).also { fd.vertexBufferMemory = NULL } - if (fd.indexBuffer != NULL) destroyBuffer(fd.indexBuffer).also { fd.indexBuffer = NULL } - if (fd.indexBufferMemory != NULL) freeMemory(fd.indexBufferMemory).also { fd.indexBufferMemory = NULL } - } - - if (fontView != NULL) destroyImageView(fontView).also { fontView = NULL } - if (fontImage != NULL) destroyImage(fontImage).also { fontImage = NULL } - if (fontMemory != NULL) freeMemory(fontMemory).also { fontMemory = NULL } - if (fontSampler != NULL) destroySampler(fontSampler).also { fontSampler = NULL } - if (descriptorSetLayout != NULL) destroyDescriptorSetLayout(descriptorSetLayout).also { descriptorSetLayout = NULL } - if (pipelineLayout != NULL) destroyPipelineLayout(pipelineLayout).also { pipelineLayout = NULL } - if (pipeline != NULL) destroyPipeline(pipeline).also { pipeline = NULL } - } - } - - fun createFontsTexture(commandBuffer: VkCommandBuffer): Boolean { - - val (pixels, size) = ImGui.io.fonts.getTexDataAsRGBA32() - val uploadSize = size.x * size.y * Vec4b.size.L - - // Create the Image: - run { - val info = vk.ImageCreateInfo { - imageType = VkImageType.`2D` - format = VkFormat.R8G8B8A8_UNORM - extent(size, 1) - mipLevels = 1 - arrayLayers = 1 - samples = VkSampleCount.`1_BIT` - tiling = VkImageTiling.OPTIMAL - usage = VkImageUsage.SAMPLED_BIT or VkImageUsage.TRANSFER_DST_BIT - sharingMode = VkSharingMode.EXCLUSIVE - initialLayout = VkImageLayout.UNDEFINED - } - fontImage = device createImage info - val req = device getImageMemoryRequirements fontImage - val allocInfo = vk.MemoryAllocateInfo { - allocationSize = req.size - memoryTypeIndex = memoryType(VkMemoryProperty.DEVICE_LOCAL_BIT, req.memoryTypeBits) - } - fontMemory = device allocateMemory allocInfo - device.bindImageMemory(fontImage, fontMemory) - } - - // Create the Image View: - fontView = device createImageView vk.ImageViewCreateInfo { - image = fontImage - viewType = VkImageViewType.`2D` - format = VkFormat.R8G8B8A8_UNORM - subresourceRange.apply { - aspectMask = VkImageAspect.COLOR_BIT.i - levelCount = 1 - layerCount = 1 - } - } - - // Update the Descriptor Set: - run { - val descImage = vk.DescriptorImageInfo(fontSampler, fontView, VkImageLayout.SHADER_READ_ONLY_OPTIMAL) - val writeDesc = vk.WriteDescriptorSet(descriptorSet, VkDescriptorType.COMBINED_IMAGE_SAMPLER, 0, descImage) - device updateDescriptorSets writeDesc - } - - // Create the Upload Buffer: - run { - val bufferInfo = vk.BufferCreateInfo { - this.size = uploadSize - usage = VkBufferUsage.TRANSFER_SRC_BIT.i - sharingMode = VkSharingMode.EXCLUSIVE - } - uploadBuffer = device createBuffer bufferInfo - val req = device getBufferMemoryRequirements uploadBuffer - bufferMemoryAlignment = if (bufferMemoryAlignment > req.alignment) bufferMemoryAlignment else req.alignment - val allocInfo = vk.MemoryAllocateInfo { - allocationSize = req.size - memoryTypeIndex = memoryType(VkMemoryProperty.HOST_VISIBLE_BIT, req.memoryTypeBits) - } - uploadBufferMemory = device allocateMemory allocInfo - device.bindBufferMemory(uploadBuffer, uploadBufferMemory) - } - - // Upload to Buffer: - device.mappingMemory(uploadBufferMemory, 0, uploadSize) { map -> - memCopy(pixels.adr, map, uploadSize) - val range = vk.MappedMemoryRange { - memory = uploadBufferMemory - this.size = uploadSize - } - device flushMappedMemoryRanges range - } - - // Copy to Image: - run { - val copyBarrier = vk.ImageMemoryBarrier { - dstAccessMask = VkAccess.TRANSFER_WRITE_BIT.i - oldLayout = VkImageLayout.UNDEFINED - newLayout = VkImageLayout.TRANSFER_DST_OPTIMAL - srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED - dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED - image = fontImage - subresourceRange.apply { - aspectMask = VkImageAspect.COLOR_BIT.i - levelCount = 1 - layerCount = 1 - } - } - commandBuffer.pipelineBarrier(VkPipelineStage.HOST_BIT, VkPipelineStage.TRANSFER_BIT, imageMemoryBarrier = copyBarrier) - - val region = vk.BufferImageCopy { - imageSubresource.apply { - aspectMask = VkImageAspect.COLOR_BIT.i - layerCount = 1 - } - imageExtent(size, 1) - } - commandBuffer.copyBufferToImage(uploadBuffer, fontImage, VkImageLayout.TRANSFER_DST_OPTIMAL, region) - - val useBarrier = vk.ImageMemoryBarrier { - srcAccessMask = VkAccess.TRANSFER_WRITE_BIT.i - dstAccessMask = VkAccess.SHADER_READ_BIT.i - oldLayout = VkImageLayout.TRANSFER_DST_OPTIMAL - newLayout = VkImageLayout.SHADER_READ_ONLY_OPTIMAL - srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED - dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED - image = fontImage - subresourceRange.apply { - aspectMask = VkImageAspect.COLOR_BIT.i - levelCount = 1 - layerCount = 1 - } - } - commandBuffer.pipelineBarrier(VkPipelineStage.TRANSFER_BIT, VkPipelineStage.FRAGMENT_SHADER_BIT, imageMemoryBarrier = useBarrier) - } - - // Store our identifier - ImGui.io.fonts.texId = fontImage.i - - return true - } - - fun createDeviceObjects(): Boolean { - - // Create The Shader Modules: - val vertModule: VkShaderModule = device createShaderModule vk.ShaderModuleCreateInfo { code = glslShaderVertSpv } - val fragModule: VkShaderModule = device createShaderModule vk.ShaderModuleCreateInfo { code = glslShaderFragSpv } - - if (fontSampler == NULL) - fontSampler = device createSampler vk.SamplerCreateInfo { - magFilter = VkFilter.LINEAR - minFilter = VkFilter.LINEAR - mipmapMode = VkSamplerMipmapMode.LINEAR - addressMode = VkSamplerAddressMode.REPEAT - minLod = -1000f - maxLod = 1000f - maxAnisotropy = 1f - } - - if (descriptorSetLayout == NULL) { - val binding = vk.DescriptorSetLayoutBinding { - descriptorType = VkDescriptorType.COMBINED_IMAGE_SAMPLER - descriptorCount = 1 - stageFlag = VkShaderStage.FRAGMENT_BIT - - val pSampler = appBuffer.long - memPutLong(pSampler, fontSampler) - memPutAddress(adr + VkDescriptorSetLayoutBinding.PIMMUTABLESAMPLERS, pSampler) - VkDescriptorSetLayoutBinding.ndescriptorCount(adr, 1) -// immutableSampler = fontSampler TODO BUG - } - val info = vk.DescriptorSetLayoutCreateInfo(binding) - descriptorSetLayout = device createDescriptorSetLayout info - } - - // Create Descriptor Set: - descriptorSet = device allocateDescriptorSets vk.DescriptorSetAllocateInfo(descriptorPool, descriptorSetLayout) - - if (pipelineLayout == NULL) { - // Constants: we are using 'vec2 offset' and 'vec2 scale' instead of a full 3d projection matrix - val pushConstant = vk.PushConstantRange(VkShaderStage.VERTEX_BIT, Vec2.size * 2) - val layoutInfo = vk.PipelineLayoutCreateInfo { - setLayout = descriptorSetLayout - pushConstantRange = pushConstant - } - pipelineLayout = device createPipelineLayout layoutInfo - } - - val stage = vk.PipelineShaderStageCreateInfo(2).also { - it[0].apply { - stage = VkShaderStage.VERTEX_BIT - module = vertModule - name = "main" - } - it[1].apply { - stage = VkShaderStage.FRAGMENT_BIT - module = fragModule - name = "main" - } - } - - val bindingDesc = vk.VertexInputBindingDescription(BINDING, DrawVert.size, VkVertexInputRate.VERTEX) - - val attributeDesc = vk.VertexInputAttributeDescription( - bindingDesc.binding, 0, VkFormat.R32G32_SFLOAT, DrawVert.ofsPos, - bindingDesc.binding, 1, VkFormat.R32G32_SFLOAT, DrawVert.ofsUv, - bindingDesc.binding, 2, VkFormat.R8G8B8A8_UNORM, DrawVert.ofsCol) - - val vertexInfo = vk.PipelineVertexInputStateCreateInfo { - vertexBindingDescription = bindingDesc - vertexAttributeDescriptions = attributeDesc - } - val iaInfo = vk.PipelineInputAssemblyStateCreateInfo(VkPrimitiveTopology.TRIANGLE_LIST) - - val viewportInfo = vk.PipelineViewportStateCreateInfo(1, 1) - - val rasterInfo = vk.PipelineRasterizationStateCreateInfo(VkPolygonMode.FILL, VkCullMode.NONE.i, VkFrontFace.COUNTER_CLOCKWISE) - - val msInfo = vk.PipelineMultisampleStateCreateInfo(VkSampleCount.`1_BIT`) - - val colorAttachment = vk.PipelineColorBlendAttachmentState { - blendEnable = true - srcColorBlendFactor = VkBlendFactor.SRC_ALPHA - dstColorBlendFactor = VkBlendFactor.ONE_MINUS_SRC_ALPHA - colorBlendOp = VkBlendOp.ADD - srcAlphaBlendFactor = VkBlendFactor.ONE_MINUS_SRC_ALPHA - dstAlphaBlendFactor = VkBlendFactor.ZERO - alphaBlendOp = VkBlendOp.ADD - colorWriteMask = VkColorComponent.R_BIT or VkColorComponent.G_BIT or VkColorComponent.B_BIT or VkColorComponent.A_BIT - } - - val depthInfo = vk.PipelineDepthStencilStateCreateInfo() - - val blendInfo = vk.PipelineColorBlendStateCreateInfo(colorAttachment) - - val dynamicStates = listOf(VkDynamicState.VIEWPORT, VkDynamicState.SCISSOR) - val dynamicState = vk.PipelineDynamicStateCreateInfo(dynamicStates) - - val info = vk.GraphicsPipelineCreateInfo { - flags = pipelineCreateFlags - stages = stage - vertexInputState = vertexInfo - inputAssemblyState = iaInfo - viewportState = viewportInfo - rasterizationState = rasterInfo - multisampleState = msInfo - depthStencilState = depthInfo - colorBlendState = blendInfo - this.dynamicState = dynamicState - layout = pipelineLayout - renderPass = this@ImplVk.renderPass - } - pipeline = device.createGraphicsPipelines(pipelineCache, info) - - device destroyShaderModule vertModule - device destroyShaderModule fragModule - - return true - } - - /** ------------------------------------------------------------------------- - * Miscellaneous Vulkan Helpers - * Generally we try to NOT provide any kind of superfluous high-level helpers in the examples. - * But for the upcoming multi-viewport feature, the Vulkan will need this code anyway, - * so we decided to shared it and use it in the examples' main.cpp - * If your application/engine already has code to create all that data - * (swap chain, render pass, frame buffers, etc.) you can ignore all of this. - * ------------------------------------------------------------------------- - * NB: Those functions do NOT use any of the state used/affected by the regular ImplVk.XXX functions. - * ------------------------------------------------------------------------- */ - - /** Window Data */ - var wd = WindowData() - - class WindowData { - var size = Vec2i() - var swapchain: VkSwapchainKHR = NULL - var surface: VkSurfaceKHR = NULL - lateinit var surfaceFormat: VkSurfaceFormatKHR - var presentMode = VkPresentMode.IMMEDIATE_KHR - var renderPass: VkRenderPass = NULL - var clearEnable = false - var clearValue: VkClearValue = VkClearValue.calloc() - var backBufferCount = 0 - var backBuffer = VkImageArray(16) - var backBufferView = VkImageViewArray(16) - var framebuffer = VkFramebufferArray(16) - var frameIndex = 0 - var frames = Array(VK_QUEUED_FRAMES) { FrameData() } - val frame: FrameData - get() = frames[frameIndex] - } - - class FrameData { - /** keep track of recently rendered swapchain frame indices */ - var backbufferIndex = 0 - var commandPool: VkCommandPool = NULL - lateinit var commandBuffer: VkCommandBuffer - var fence: VkFence = NULL - var imageAcquiredSemaphore: VkSemaphore = NULL - var renderCompleteSemaphore: VkSemaphore = NULL - } - - fun createWindowDataCommandBuffers() { - - // Create Command Buffers - for (i in 0 until VK_QUEUED_FRAMES) - - wd.frames[i].apply { - - commandPool = device createCommandPool vk.CommandPoolCreateInfo { - flag = VkCommandPoolCreate.RESET_COMMAND_BUFFER_BIT - queueFamilyIndex = queueFamily - } - - commandBuffer = device allocateCommandBuffer vk.CommandBufferAllocateInfo { - this.commandPool = this@apply.commandPool - level = VkCommandBufferLevel.PRIMARY - commandBufferCount = 1 - } - fence = device createFence VkFenceCreate.SIGNALED_BIT - - val info = vk.SemaphoreCreateInfo() - imageAcquiredSemaphore = device createSemaphore info - renderCompleteSemaphore = device createSemaphore info - } - } - - fun createWindowDataSwapChainAndFramebuffer(size: Vec2i) { - - var minImageCount = 2 // FIXME: this should become a function parameter - - val oldSwapchain = wd.swapchain - device.waitIdle() - - // Destroy old Framebuffer - for (i in 0 until wd.backBufferCount) { - if (wd.backBufferView[i] != NULL) - device destroyImageView wd.backBufferView[i] - if (wd.framebuffer[i] != NULL) - device destroyFramebuffer wd.framebuffer[i] - } - wd.backBufferCount = 0 - if (wd.renderPass != NULL) - device destroyRenderPass wd.renderPass - - // If min image count was not specified, request different count of images dependent on selected present mode - if (minImageCount == 0) - minImageCount = getMinImageCountFromPresentMode(wd.presentMode) - - // Create Swapchain - run { - val info = vk.SwapchainCreateInfoKHR { - surface = wd.surface - this.minImageCount = minImageCount - imageFormat = wd.surfaceFormat.format - imageColorSpace = wd.surfaceFormat.colorSpace - imageArrayLayers = 1 - imageUsage = VkImageUsage.COLOR_ATTACHMENT_BIT.i - imageSharingMode = VkSharingMode.EXCLUSIVE // Assume that graphics family == present family - preTransform = VkSurfaceTransform.IDENTITY_BIT_KHR - compositeAlpha = VkCompositeAlpha.OPAQUE_BIT_KHR - presentMode = wd.presentMode - clipped = true - this.oldSwapchain = oldSwapchain - } - val cap = physicalDevice getSurfaceCapabilitiesKHR wd.surface - - if (info.minImageCount < cap.minImageCount) - info.minImageCount = cap.minImageCount - else if (info.minImageCount > cap.maxImageCount) - info.minImageCount = cap.maxImageCount - - if (cap.currentExtent.width == 0xffffffff.i) { - wd.size(size) // TODO bug cant inception - info.imageExtent(size) - } else { - wd.size(cap.currentExtent.width, cap.currentExtent.height) // TOOD bug - info.imageExtent(wd.size) - } - wd.swapchain = device createSwapchainKHR info - wd.backBuffer = device getSwapchainImagesKHR wd.swapchain - wd.backBufferCount = wd.backBuffer.size - } - if (oldSwapchain != NULL) - device destroySwapchainKHR oldSwapchain - - // Create the Render Pass - run { - val attachment = vk.AttachmentDescription { - format = wd.surfaceFormat.format - samples = VkSampleCount.`1_BIT` - loadOp = if (wd.clearEnable) VkAttachmentLoadOp.CLEAR else VkAttachmentLoadOp.DONT_CARE - storeOp = VkAttachmentStoreOp.STORE - stencilLoadOp = VkAttachmentLoadOp.DONT_CARE - stencilStoreOp = VkAttachmentStoreOp.DONT_CARE - initialLayout = VkImageLayout.UNDEFINED - finalLayout = VkImageLayout.PRESENT_SRC_KHR - } - val colorAttachment = vk.AttachmentReference(0, VkImageLayout.COLOR_ATTACHMENT_OPTIMAL) - val subpass = vk.SubpassDescription { - pipelineBindPoint = VkPipelineBindPoint.GRAPHICS - colorAttachmentCount = 1 - this.colorAttachment = colorAttachment - } - val dependency = vk.SubpassDependency { - srcSubpass = VK_SUBPASS_EXTERNAL - dstSubpass = 0 - srcStageMask = VkPipelineStage.COLOR_ATTACHMENT_OUTPUT_BIT.i - dstStageMask = VkPipelineStage.COLOR_ATTACHMENT_OUTPUT_BIT.i - srcAccessMask = 0 - dstAccessMask = VkAccess.COLOR_ATTACHMENT_WRITE_BIT.i - } - val info = vk.RenderPassCreateInfo().also { - it.attachment = attachment - it.subpass = subpass - it.dependency = dependency - } - wd.renderPass = device createRenderPass info - } - - // Create The Image Views - run { - val info = vk.ImageViewCreateInfo { - viewType = VkImageViewType.`2D` - format = wd.surfaceFormat.format - components(VkComponentSwizzle.R, VkComponentSwizzle.G, VkComponentSwizzle.B, VkComponentSwizzle.A) - } - val imageRange = vk.ImageSubresourceRange(VkImageAspect.COLOR_BIT, 0, 1, 0, 1) - info.subresourceRange = imageRange - for (i in 0 until wd.backBufferCount) { - info.image = wd.backBuffer[i] - wd.backBufferView[i] = device createImageView info - } - } - - // Create Framebuffer - run { - val attachment: VkImageViewBuffer = appBuffer.longBuffer - val info = vk.FramebufferCreateInfo { - renderPass = wd.renderPass - this.attachments = attachment //TODO bug - extent(wd.size, 1) - } - for (i in 0 until wd.backBufferCount) { - attachment[0] = wd.backBufferView[i] - wd.framebuffer[i] = device createFramebuffer info - } - } - } - - fun destroyWindowData() { - device.apply { - waitIdle() // FIXME: We could wait on the Queue if we had the queue in wd-> (otherwise VulkanH functions can't use globals) - //vkQueueWaitIdle(g_Queue); - - wd.frames.forEach { fd -> - destroyFence(fd.fence) - freeCommandBuffer(fd.commandPool, fd.commandBuffer) - destroyCommandPool(fd.commandPool) - destroySemaphores(fd.imageAcquiredSemaphore, fd.renderCompleteSemaphore) - } - for (i in 0 until wd.backBufferCount) { - destroyImageView(wd.backBufferView[i]) - destroyFramebuffer(wd.framebuffer[i]) - } - destroyRenderPass(wd.renderPass) - destroySwapchainKHR(wd.swapchain) - instance destroySurfaceKHR wd.surface - wd = WindowData() - } - } - - fun selectSurfaceFormat(physicalDevice: VkPhysicalDevice, surface: VkSurfaceKHR, requestFormats: Array, requestColorSpace: VkColorSpace): VkSurfaceFormatKHR { - assert(requestFormats.isNotEmpty()) - - /* Per Spec Format and View Format are expected to be the same unless VK_IMAGE_CREATE_MUTABLE_BIT was set at image creation - Assuming that the default behavior is without setting this bit, there is no need for separate Swapchain image and image view format - Additionally several new color spaces were introduced with Vulkan Spec v1.0.40, - hence we must make sure that a format with the mostly available color space, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, is found and used. */ - val availFormat = physicalDevice getSurfaceFormatsKHR surface - - // First check if only one format, VK_FORMAT_UNDEFINED, is available, which would imply that any format is available - return when (availFormat.size) { - 1 -> when (availFormat[0].format) { - VkFormat.UNDEFINED -> vk.SurfaceFormatKHR(requestFormats[0], requestColorSpace) - else -> availFormat[0] // No point in searching another format - } - else -> { - // Request several formats, the first found will be used - for (request in requestFormats.indices) - for (avail in availFormat.indices) - if (availFormat[avail].format == requestFormats[request] && availFormat[avail].colorSpace == requestColorSpace) - return availFormat[avail] - - // If none of the requested image formats could be found, use the first available - return availFormat[0] - } - } - } - - fun selectPresentMode(requestModes: Array): VkPresentMode { - - // Request a certain mode and confirm that it is available. If not use VK_PRESENT_MODE_FIFO_KHR which is mandatory - val availModes = physicalDevice getSurfacePresentModesKHR wd.surface - for (request in requestModes.indices) - for (avail in availModes.indices) - if (requestModes[request] == availModes[avail]) - return requestModes[request] - - return VkPresentMode.FIFO_KHR // Always available - } - - fun getMinImageCountFromPresentMode(presentMode: VkPresentMode) = when (presentMode) { - VkPresentMode.MAILBOX_KHR -> 3 - VkPresentMode.FIFO_KHR, VkPresentMode.FIFO_RELAXED_KHR -> 2 - VkPresentMode.IMMEDIATE_KHR -> 1 - else -> throw Error() - } - - - fun memoryType(properties: VkMemoryProperty, typeBits: Int) = memoryType(properties.i, typeBits) - fun memoryType(properties: VkMemoryPropertyFlags, typeBits: Int): Int { - val prop = physicalDevice.memoryProperties - for (i in 0 until prop.memoryTypeCount) - if ((prop.memoryTypes[i].propertyFlags and properties) == properties && typeBits has (1 shl i)) - return i - return -1 // Unable to find memoryType - } - - /** glsl_shader.vert, compiled with: - * # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert - */ - val glslShaderVertSpv = intArrayOf( - 0x07230203, 0x00010000, 0x00080001, 0x0000002e, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, - 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, - 0x000a000f, 0x00000000, 0x00000004, 0x6e69616d, 0x00000000, 0x0000000b, 0x0000000f, 0x00000015, - 0x0000001b, 0x0000001c, 0x00030003, 0x00000002, 0x000001c2, 0x00040005, 0x00000004, 0x6e69616d, - 0x00000000, 0x00030005, 0x00000009, 0x00000000, 0x00050006, 0x00000009, 0x00000000, 0x6f6c6f43, - 0x00000072, 0x00040006, 0x00000009, 0x00000001, 0x00005655, 0x00030005, 0x0000000b, 0x0074754f, - 0x00040005, 0x0000000f, 0x6c6f4361, 0x0000726f, 0x00030005, 0x00000015, 0x00565561, 0x00060005, - 0x00000019, 0x505f6c67, 0x65567265, 0x78657472, 0x00000000, 0x00060006, 0x00000019, 0x00000000, - 0x505f6c67, 0x7469736f, 0x006e6f69, 0x00030005, 0x0000001b, 0x00000000, 0x00040005, 0x0000001c, - 0x736f5061, 0x00000000, 0x00060005, 0x0000001e, 0x73755075, 0x6e6f4368, 0x6e617473, 0x00000074, - 0x00050006, 0x0000001e, 0x00000000, 0x61635375, 0x0000656c, 0x00060006, 0x0000001e, 0x00000001, - 0x61725475, 0x616c736e, 0x00006574, 0x00030005, 0x00000020, 0x00006370, 0x00040047, 0x0000000b, - 0x0000001e, 0x00000000, 0x00040047, 0x0000000f, 0x0000001e, 0x00000002, 0x00040047, 0x00000015, - 0x0000001e, 0x00000001, 0x00050048, 0x00000019, 0x00000000, 0x0000000b, 0x00000000, 0x00030047, - 0x00000019, 0x00000002, 0x00040047, 0x0000001c, 0x0000001e, 0x00000000, 0x00050048, 0x0000001e, - 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x0000001e, 0x00000001, 0x00000023, 0x00000008, - 0x00030047, 0x0000001e, 0x00000002, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, - 0x00030016, 0x00000006, 0x00000020, 0x00040017, 0x00000007, 0x00000006, 0x00000004, 0x00040017, - 0x00000008, 0x00000006, 0x00000002, 0x0004001e, 0x00000009, 0x00000007, 0x00000008, 0x00040020, - 0x0000000a, 0x00000003, 0x00000009, 0x0004003b, 0x0000000a, 0x0000000b, 0x00000003, 0x00040015, - 0x0000000c, 0x00000020, 0x00000001, 0x0004002b, 0x0000000c, 0x0000000d, 0x00000000, 0x00040020, - 0x0000000e, 0x00000001, 0x00000007, 0x0004003b, 0x0000000e, 0x0000000f, 0x00000001, 0x00040020, - 0x00000011, 0x00000003, 0x00000007, 0x0004002b, 0x0000000c, 0x00000013, 0x00000001, 0x00040020, - 0x00000014, 0x00000001, 0x00000008, 0x0004003b, 0x00000014, 0x00000015, 0x00000001, 0x00040020, - 0x00000017, 0x00000003, 0x00000008, 0x0003001e, 0x00000019, 0x00000007, 0x00040020, 0x0000001a, - 0x00000003, 0x00000019, 0x0004003b, 0x0000001a, 0x0000001b, 0x00000003, 0x0004003b, 0x00000014, - 0x0000001c, 0x00000001, 0x0004001e, 0x0000001e, 0x00000008, 0x00000008, 0x00040020, 0x0000001f, - 0x00000009, 0x0000001e, 0x0004003b, 0x0000001f, 0x00000020, 0x00000009, 0x00040020, 0x00000021, - 0x00000009, 0x00000008, 0x0004002b, 0x00000006, 0x00000028, 0x00000000, 0x0004002b, 0x00000006, - 0x00000029, 0x3f800000, 0x00050036, 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, - 0x00000005, 0x0004003d, 0x00000007, 0x00000010, 0x0000000f, 0x00050041, 0x00000011, 0x00000012, - 0x0000000b, 0x0000000d, 0x0003003e, 0x00000012, 0x00000010, 0x0004003d, 0x00000008, 0x00000016, - 0x00000015, 0x00050041, 0x00000017, 0x00000018, 0x0000000b, 0x00000013, 0x0003003e, 0x00000018, - 0x00000016, 0x0004003d, 0x00000008, 0x0000001d, 0x0000001c, 0x00050041, 0x00000021, 0x00000022, - 0x00000020, 0x0000000d, 0x0004003d, 0x00000008, 0x00000023, 0x00000022, 0x00050085, 0x00000008, - 0x00000024, 0x0000001d, 0x00000023, 0x00050041, 0x00000021, 0x00000025, 0x00000020, 0x00000013, - 0x0004003d, 0x00000008, 0x00000026, 0x00000025, 0x00050081, 0x00000008, 0x00000027, 0x00000024, - 0x00000026, 0x00050051, 0x00000006, 0x0000002a, 0x00000027, 0x00000000, 0x00050051, 0x00000006, - 0x0000002b, 0x00000027, 0x00000001, 0x00070050, 0x00000007, 0x0000002c, 0x0000002a, 0x0000002b, - 0x00000028, 0x00000029, 0x00050041, 0x00000011, 0x0000002d, 0x0000001b, 0x0000000d, 0x0003003e, - 0x0000002d, 0x0000002c, 0x000100fd, 0x00010038).toBuffer() - - /** glsl_shader.frag, compiled with: - * # glslangValidator -V -x -o glsl_shader.frag.u32 glsl_shader.frag - */ - val glslShaderFragSpv = intArrayOf( - 0x07230203, 0x00010000, 0x00080001, 0x0000001e, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, - 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, - 0x0007000f, 0x00000004, 0x00000004, 0x6e69616d, 0x00000000, 0x00000009, 0x0000000d, 0x00030010, - 0x00000004, 0x00000007, 0x00030003, 0x00000002, 0x000001c2, 0x00040005, 0x00000004, 0x6e69616d, - 0x00000000, 0x00040005, 0x00000009, 0x6c6f4366, 0x0000726f, 0x00030005, 0x0000000b, 0x00000000, - 0x00050006, 0x0000000b, 0x00000000, 0x6f6c6f43, 0x00000072, 0x00040006, 0x0000000b, 0x00000001, - 0x00005655, 0x00030005, 0x0000000d, 0x00006e49, 0x00050005, 0x00000016, 0x78655473, 0x65727574, - 0x00000000, 0x00040047, 0x00000009, 0x0000001e, 0x00000000, 0x00040047, 0x0000000d, 0x0000001e, - 0x00000000, 0x00040047, 0x00000016, 0x00000022, 0x00000000, 0x00040047, 0x00000016, 0x00000021, - 0x00000000, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00030016, 0x00000006, - 0x00000020, 0x00040017, 0x00000007, 0x00000006, 0x00000004, 0x00040020, 0x00000008, 0x00000003, - 0x00000007, 0x0004003b, 0x00000008, 0x00000009, 0x00000003, 0x00040017, 0x0000000a, 0x00000006, - 0x00000002, 0x0004001e, 0x0000000b, 0x00000007, 0x0000000a, 0x00040020, 0x0000000c, 0x00000001, - 0x0000000b, 0x0004003b, 0x0000000c, 0x0000000d, 0x00000001, 0x00040015, 0x0000000e, 0x00000020, - 0x00000001, 0x0004002b, 0x0000000e, 0x0000000f, 0x00000000, 0x00040020, 0x00000010, 0x00000001, - 0x00000007, 0x00090019, 0x00000013, 0x00000006, 0x00000001, 0x00000000, 0x00000000, 0x00000000, - 0x00000001, 0x00000000, 0x0003001b, 0x00000014, 0x00000013, 0x00040020, 0x00000015, 0x00000000, - 0x00000014, 0x0004003b, 0x00000015, 0x00000016, 0x00000000, 0x0004002b, 0x0000000e, 0x00000018, - 0x00000001, 0x00040020, 0x00000019, 0x00000001, 0x0000000a, 0x00050036, 0x00000002, 0x00000004, - 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x00050041, 0x00000010, 0x00000011, 0x0000000d, - 0x0000000f, 0x0004003d, 0x00000007, 0x00000012, 0x00000011, 0x0004003d, 0x00000014, 0x00000017, - 0x00000016, 0x00050041, 0x00000019, 0x0000001a, 0x0000000d, 0x00000018, 0x0004003d, 0x0000000a, - 0x0000001b, 0x0000001a, 0x00050057, 0x00000007, 0x0000001c, 0x00000017, 0x0000001b, 0x00050085, - 0x00000007, 0x0000001d, 0x00000012, 0x0000001c, 0x0003003e, 0x00000009, 0x0000001d, 0x000100fd, - 0x00010038).toBuffer() -} \ No newline at end of file +//package imgui.impl +// +//import ab.appBuffer +//import gli_.has +//import glm_.* +//import glm_.buffer.adr +//import glm_.vec2.Vec2 +//import glm_.vec2.Vec2i +//import glm_.vec4.Vec4b +//import imgui.* +//import org.lwjgl.system.MemoryUtil.* +//import org.lwjgl.vulkan.* +//import org.lwjgl.vulkan.VK10.* +//import uno.buffer.toBuffer +//import vkk.* +//import kotlin.reflect.KMutableProperty0 +// +//object ImplVk { +// +// +// // ===== impl_vk.h ===== +// +// var VK_QUEUED_FRAMES = 2 +// val BINDING = 0 // TODO -> Omar +// +// fun init(): Boolean { +// +// assert(::instance.isInitialized) +// assert(::physicalDevice.isInitialized) +// assert(::device.isInitialized) +// assert(::queue.isInitialized) +// assert(descriptorPool != NULL) +// assert(renderPass != NULL) +// +// renderPass = wd.renderPass +// +// createDeviceObjects() +// +// return true +// } +// +// fun shutdown() = invalidateDeviceObjects() +// +// fun newFrame() {} +// +// /** Render function +// * (this used to be set in io.renderDrawListsFn and called by ImGui::render(), +// * but you can now call this directly from your main loop) */ +// fun renderDrawData(drawData: DrawData) { +// +// if (drawData.totalVtxCount == 0) return +// +// val fd = framesDataBuffers[frameIndex] +// frameIndex = (frameIndex + 1) % VK_QUEUED_FRAMES +// +// // Create the Vertex and Index buffers: +// val vertexSize = drawData.totalVtxCount * DrawVert.size.L +// val indexSize = drawData.totalIdxCount * DrawIdx.BYTES.L +// if (fd.vertexBuffer == NULL || fd.vertexBufferSize < vertexSize) +// fd.vertexBufferSize = createOrResizeBuffer(fd::vertexBuffer, fd::vertexBufferMemory, vertexSize, VkBufferUsage.VERTEX_BUFFER_BIT) +// if (fd.indexBuffer == NULL || fd.indexBufferSize < indexSize) +// fd.indexBufferSize = createOrResizeBuffer(fd::indexBuffer, fd::indexBufferMemory, indexSize, VkBufferUsage.INDEX_BUFFER_BIT) +// +// // Upload Vertex and index Data: +// run { +// var vtxDst = device.mapMemory(fd.vertexBufferMemory, 0, vertexSize) +// var idxDst = device.mapMemory(fd.indexBufferMemory, 0, indexSize) +// for (n in 0 until drawData.cmdListsCount) { +// val cmdList = drawData.cmdLists[n] +// cmdList.vtxBuffer.forEachIndexed { i, v -> +// memPutFloat(vtxDst + DrawVert.size * i, v.pos.x) +// memPutFloat(vtxDst + DrawVert.size * i + Float.BYTES, v.pos.y) +// memPutFloat(vtxDst + DrawVert.size * i + Vec2.size, v.uv.x) +// memPutFloat(vtxDst + DrawVert.size * i + Vec2.size + Float.BYTES, v.uv.y) +// memPutInt(vtxDst + DrawVert.size * i + Vec2.size * 2, v.col) +// } +// cmdList.idxBuffer.forEachIndexed { i, it -> memPutInt(idxDst + DrawIdx.BYTES * i, it) } +// vtxDst += cmdList.vtxBuffer.size.L +// idxDst += cmdList.idxBuffer.size.L +// } +// val range = vk.MappedMemoryRange(2).also { +// it[0].apply { +// memory = fd.vertexBufferMemory +// size = VK_WHOLE_SIZE +// } +// it[1].apply { +// memory = fd.indexBufferMemory +// size = VK_WHOLE_SIZE +// } +// } +// device.apply { +// flushMappedMemoryRanges(range) +// unmapMemory(fd.vertexBufferMemory) +// unmapMemory(fd.indexBufferMemory) +// } +// } +// +// val commandBuffer = wd.frame.commandBuffer.apply { +// +// // Bind pipeline and descriptor sets: +// bindPipeline(VkPipelineBindPoint.GRAPHICS, pipeline) +// bindDescriptorSets(VkPipelineBindPoint.GRAPHICS, pipelineLayout, descriptorSet) +// +// // Bind Vertex And Index Buffer: +// bindVertexBuffers(fd.vertexBuffer) +// bindIndexBuffer(fd.indexBuffer, 0, VkIndexType.UINT16) +// +// // Setup viewport: +// setViewport(vk.Viewport(drawData.displaySize.x, drawData.displaySize.y)) +// +// /* Setup scale and translation: +// Our visible imgui space lies from drawData.displayPps (top left) to drawData.displayPos+dataData.displaySize (bottom right). +// DisplayMin is typically (0,0) for single viewport apps. */ +// val scale = appBuffer.floatBufferOf(2f / drawData.displaySize.x, 2f / drawData.displaySize.y) +// val translate = appBuffer.floatBufferOf(-1f - drawData.displayPos.x * scale[0], -1f - drawData.displayPos.y * scale[1]) +// pushConstants(pipelineLayout, VkShaderStage.VERTEX_BIT.i, 0, scale) +// pushConstants(pipelineLayout, VkShaderStage.VERTEX_BIT.i, scale.size, translate) +// } +// +// // Render the command lists: +// var vtxOffset = 0 +// var idxOffset = 0 +// val displayPos = drawData.displayPos +// for (cmdList in drawData.cmdLists) { +// for (cmd in cmdList.cmdBuffer) { +// val cb = cmd.userCallback +// if (cb != null) +// cb(cmdList, cmd) +// else { +// // Apply scissor/clipping rectangle +// // FIXME: We could clamp width/height based on clamped min/max values. +// commandBuffer setScissor vk.Rect2D( +// offsetX = (cmd.clipRect.x - displayPos.x).i.takeIf { it > 0 } ?: 0, +// offsetY = (cmd.clipRect.y - displayPos.y).i.takeIf { it > 0 } ?: 0, +// width = (cmd.clipRect.z - cmd.clipRect.x).i, +// height = (cmd.clipRect.w - cmd.clipRect.y + 1).i) // FIXME: Why +1 here? +// +// // Draw +// commandBuffer.drawIndexed(cmd.elemCount, 1, idxOffset, vtxOffset, 0) +// } +// idxOffset += cmd.elemCount * Int.BYTES // TODO check +// } +// vtxOffset += cmdList.vtxBuffer.size * DrawVert.size +// } +// } +// +// fun createOrResizeBuffer(bufferPtr: KMutableProperty0, bufferMemoryPtr: KMutableProperty0, newSize: Long, usage: VkBufferUsage): VkDeviceSize { +// +// var buffer by bufferPtr +// var bufferMemory by bufferMemoryPtr +// if (buffer != NULL) +// device destroyBuffer buffer +// if (bufferMemory != NULL) +// device freeMemory bufferMemory +// +// val vertexBufferSizeAligned: VkDeviceSize = ((newSize - 1) / bufferMemoryAlignment + 1) * bufferMemoryAlignment +// val bufferInfo = vk.BufferCreateInfo { +// size = vertexBufferSizeAligned +// this.usage = usage.i +// sharingMode = VkSharingMode.EXCLUSIVE +// } +// buffer = device createBuffer bufferInfo +// +// val req = device getBufferMemoryRequirements buffer +// bufferMemoryAlignment = bufferMemoryAlignment.takeIf { it > req.alignment } ?: req.alignment +// val allocInfo = vk.MemoryAllocateInfo { +// allocationSize = req.size +// memoryTypeIndex = memoryType(VkMemoryProperty.HOST_VISIBLE_BIT, req.memoryTypeBits) +// } +// bufferMemory = device allocateMemory allocInfo +// +// device.bindBufferMemory(buffer, bufferMemory) +// +// return newSize +// } +// +//// Called by Init/NewFrame/Shutdown +// +// +//// ===== impl_vk.cpp ===== +// +// // Vulkan data +// lateinit var physicalDevice: VkPhysicalDevice +// lateinit var instance: VkInstance +// lateinit var device: VkDevice +// var queueFamily = -1 +// lateinit var queue: VkQueue +// var debugReport: VkDebugReportCallback = NULL +// var pipelineCache: VkPipelineCache = NULL +// var descriptorPool: VkDescriptorPool = NULL +// var renderPass: VkRenderPass = NULL +// +// var bufferMemoryAlignment: VkDeviceSize = 256 +// var pipelineCreateFlags: VkPipelineCreateFlags = 0 +// +// var descriptorSetLayout: VkDescriptorSetLayout = NULL +// var pipelineLayout: VkPipelineLayout = NULL +// var descriptorSet: VkDescriptorSet = NULL +// var pipeline: VkPipeline = NULL +// +// // Frame data +// class FrameDataForRender { +// var vertexBufferMemory: VkDeviceMemory = NULL +// var indexBufferMemory: VkDeviceMemory = NULL +// var vertexBufferSize: VkDeviceSize = NULL +// var indexBufferSize: VkDeviceSize = NULL +// var vertexBuffer: VkBuffer = NULL +// var indexBuffer: VkBuffer = NULL +// } +// +// var frameIndex = 0 +// val framesDataBuffers = Array(VK_QUEUED_FRAMES) { FrameDataForRender() } +// +// // Font data +// var fontSampler: VkSampler = NULL +// var fontMemory: VkDeviceMemory = NULL +// var fontImage: VkImage = NULL +// var fontView: VkImageView = NULL +// var uploadBufferMemory: VkDeviceMemory = NULL +// var uploadBuffer: VkBuffer = NULL +// +// // Called by Init/NewFrame/Shutdown +// +// fun invalidateFontUploadObjects() { +// if (uploadBuffer != NULL) { +// device destroyBuffer uploadBuffer +// uploadBuffer = NULL +// } +// if (uploadBufferMemory != NULL) { +// device freeMemory uploadBufferMemory +// uploadBufferMemory = NULL +// } +// } +// +// fun invalidateDeviceObjects() { +// invalidateFontUploadObjects() +// device.apply { +// framesDataBuffers.forEach { fd -> +// if (fd.vertexBuffer != NULL) destroyBuffer(fd.vertexBuffer).also { fd.vertexBuffer = NULL } +// if (fd.vertexBufferMemory != NULL) freeMemory(fd.vertexBufferMemory).also { fd.vertexBufferMemory = NULL } +// if (fd.indexBuffer != NULL) destroyBuffer(fd.indexBuffer).also { fd.indexBuffer = NULL } +// if (fd.indexBufferMemory != NULL) freeMemory(fd.indexBufferMemory).also { fd.indexBufferMemory = NULL } +// } +// +// if (fontView != NULL) destroyImageView(fontView).also { fontView = NULL } +// if (fontImage != NULL) destroyImage(fontImage).also { fontImage = NULL } +// if (fontMemory != NULL) freeMemory(fontMemory).also { fontMemory = NULL } +// if (fontSampler != NULL) destroySampler(fontSampler).also { fontSampler = NULL } +// if (descriptorSetLayout != NULL) destroyDescriptorSetLayout(descriptorSetLayout).also { descriptorSetLayout = NULL } +// if (pipelineLayout != NULL) destroyPipelineLayout(pipelineLayout).also { pipelineLayout = NULL } +// if (pipeline != NULL) destroyPipeline(pipeline).also { pipeline = NULL } +// } +// } +// +// fun createFontsTexture(commandBuffer: VkCommandBuffer): Boolean { +// +// val (pixels, size) = ImGui.io.fonts.getTexDataAsRGBA32() +// val uploadSize = size.x * size.y * Vec4b.size.L +// +// // Create the Image: +// run { +// val info = vk.ImageCreateInfo { +// imageType = VkImageType.`2D` +// format = VkFormat.R8G8B8A8_UNORM +// extent(size, 1) +// mipLevels = 1 +// arrayLayers = 1 +// samples = VkSampleCount.`1_BIT` +// tiling = VkImageTiling.OPTIMAL +// usage = VkImageUsage.SAMPLED_BIT or VkImageUsage.TRANSFER_DST_BIT +// sharingMode = VkSharingMode.EXCLUSIVE +// initialLayout = VkImageLayout.UNDEFINED +// } +// fontImage = device createImage info +// val req = device getImageMemoryRequirements fontImage +// val allocInfo = vk.MemoryAllocateInfo { +// allocationSize = req.size +// memoryTypeIndex = memoryType(VkMemoryProperty.DEVICE_LOCAL_BIT, req.memoryTypeBits) +// } +// fontMemory = device allocateMemory allocInfo +// device.bindImageMemory(fontImage, fontMemory) +// } +// +// // Create the Image View: +// fontView = device createImageView vk.ImageViewCreateInfo { +// image = fontImage +// viewType = VkImageViewType.`2D` +// format = VkFormat.R8G8B8A8_UNORM +// subresourceRange.apply { +// aspectMask = VkImageAspect.COLOR_BIT.i +// levelCount = 1 +// layerCount = 1 +// } +// } +// +// // Update the Descriptor Set: +// run { +// val descImage = vk.DescriptorImageInfo(fontSampler, fontView, VkImageLayout.SHADER_READ_ONLY_OPTIMAL) +// val writeDesc = vk.WriteDescriptorSet(descriptorSet, VkDescriptorType.COMBINED_IMAGE_SAMPLER, 0, descImage) +// device updateDescriptorSets writeDesc +// } +// +// // Create the Upload Buffer: +// run { +// val bufferInfo = vk.BufferCreateInfo { +// this.size = uploadSize +// usage = VkBufferUsage.TRANSFER_SRC_BIT.i +// sharingMode = VkSharingMode.EXCLUSIVE +// } +// uploadBuffer = device createBuffer bufferInfo +// val req = device getBufferMemoryRequirements uploadBuffer +// bufferMemoryAlignment = if (bufferMemoryAlignment > req.alignment) bufferMemoryAlignment else req.alignment +// val allocInfo = vk.MemoryAllocateInfo { +// allocationSize = req.size +// memoryTypeIndex = memoryType(VkMemoryProperty.HOST_VISIBLE_BIT, req.memoryTypeBits) +// } +// uploadBufferMemory = device allocateMemory allocInfo +// device.bindBufferMemory(uploadBuffer, uploadBufferMemory) +// } +// +// // Upload to Buffer: +// device.mappingMemory(uploadBufferMemory, 0, uploadSize) { map -> +// memCopy(pixels.adr, map, uploadSize) +// val range = vk.MappedMemoryRange { +// memory = uploadBufferMemory +// this.size = uploadSize +// } +// device flushMappedMemoryRanges range +// } +// +// // Copy to Image: +// run { +// val copyBarrier = vk.ImageMemoryBarrier { +// dstAccessMask = VkAccess.TRANSFER_WRITE_BIT.i +// oldLayout = VkImageLayout.UNDEFINED +// newLayout = VkImageLayout.TRANSFER_DST_OPTIMAL +// srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED +// dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED +// image = fontImage +// subresourceRange.apply { +// aspectMask = VkImageAspect.COLOR_BIT.i +// levelCount = 1 +// layerCount = 1 +// } +// } +// commandBuffer.pipelineBarrier(VkPipelineStage.HOST_BIT, VkPipelineStage.TRANSFER_BIT, imageMemoryBarrier = copyBarrier) +// +// val region = vk.BufferImageCopy { +// imageSubresource.apply { +// aspectMask = VkImageAspect.COLOR_BIT.i +// layerCount = 1 +// } +// imageExtent(size, 1) +// } +// commandBuffer.copyBufferToImage(uploadBuffer, fontImage, VkImageLayout.TRANSFER_DST_OPTIMAL, region) +// +// val useBarrier = vk.ImageMemoryBarrier { +// srcAccessMask = VkAccess.TRANSFER_WRITE_BIT.i +// dstAccessMask = VkAccess.SHADER_READ_BIT.i +// oldLayout = VkImageLayout.TRANSFER_DST_OPTIMAL +// newLayout = VkImageLayout.SHADER_READ_ONLY_OPTIMAL +// srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED +// dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED +// image = fontImage +// subresourceRange.apply { +// aspectMask = VkImageAspect.COLOR_BIT.i +// levelCount = 1 +// layerCount = 1 +// } +// } +// commandBuffer.pipelineBarrier(VkPipelineStage.TRANSFER_BIT, VkPipelineStage.FRAGMENT_SHADER_BIT, imageMemoryBarrier = useBarrier) +// } +// +// // Store our identifier +// ImGui.io.fonts.texId = fontImage.i +// +// return true +// } +// +// fun createDeviceObjects(): Boolean { +// +// // Create The Shader Modules: +// val vertModule: VkShaderModule = device createShaderModule vk.ShaderModuleCreateInfo { code = glslShaderVertSpv } +// val fragModule: VkShaderModule = device createShaderModule vk.ShaderModuleCreateInfo { code = glslShaderFragSpv } +// +// if (fontSampler == NULL) +// fontSampler = device createSampler vk.SamplerCreateInfo { +// magFilter = VkFilter.LINEAR +// minFilter = VkFilter.LINEAR +// mipmapMode = VkSamplerMipmapMode.LINEAR +// addressMode = VkSamplerAddressMode.REPEAT +// minLod = -1000f +// maxLod = 1000f +// maxAnisotropy = 1f +// } +// +// if (descriptorSetLayout == NULL) { +// val binding = vk.DescriptorSetLayoutBinding { +// descriptorType = VkDescriptorType.COMBINED_IMAGE_SAMPLER +// descriptorCount = 1 +// stageFlag = VkShaderStage.FRAGMENT_BIT +// +// val pSampler = appBuffer.long +// memPutLong(pSampler, fontSampler) +// memPutAddress(adr + VkDescriptorSetLayoutBinding.PIMMUTABLESAMPLERS, pSampler) +// VkDescriptorSetLayoutBinding.ndescriptorCount(adr, 1) +//// immutableSampler = fontSampler TODO BUG +// } +// val info = vk.DescriptorSetLayoutCreateInfo(binding) +// descriptorSetLayout = device createDescriptorSetLayout info +// } +// +// // Create Descriptor Set: +// descriptorSet = device allocateDescriptorSets vk.DescriptorSetAllocateInfo(descriptorPool, descriptorSetLayout) +// +// if (pipelineLayout == NULL) { +// // Constants: we are using 'vec2 offset' and 'vec2 scale' instead of a full 3d projection matrix +// val pushConstant = vk.PushConstantRange(VkShaderStage.VERTEX_BIT, Vec2.size * 2) +// val layoutInfo = vk.PipelineLayoutCreateInfo { +// setLayout = descriptorSetLayout +// pushConstantRange = pushConstant +// } +// pipelineLayout = device createPipelineLayout layoutInfo +// } +// +// val stage = vk.PipelineShaderStageCreateInfo(2).also { +// it[0].apply { +// stage = VkShaderStage.VERTEX_BIT +// module = vertModule +// name = "main" +// } +// it[1].apply { +// stage = VkShaderStage.FRAGMENT_BIT +// module = fragModule +// name = "main" +// } +// } +// +// val bindingDesc = vk.VertexInputBindingDescription(BINDING, DrawVert.size, VkVertexInputRate.VERTEX) +// +// val attributeDesc = vk.VertexInputAttributeDescription( +// bindingDesc.binding, 0, VkFormat.R32G32_SFLOAT, DrawVert.ofsPos, +// bindingDesc.binding, 1, VkFormat.R32G32_SFLOAT, DrawVert.ofsUv, +// bindingDesc.binding, 2, VkFormat.R8G8B8A8_UNORM, DrawVert.ofsCol) +// +// val vertexInfo = vk.PipelineVertexInputStateCreateInfo { +// vertexBindingDescription = bindingDesc +// vertexAttributeDescriptions = attributeDesc +// } +// val iaInfo = vk.PipelineInputAssemblyStateCreateInfo(VkPrimitiveTopology.TRIANGLE_LIST) +// +// val viewportInfo = vk.PipelineViewportStateCreateInfo(1, 1) +// +// val rasterInfo = vk.PipelineRasterizationStateCreateInfo(VkPolygonMode.FILL, VkCullMode.NONE.i, VkFrontFace.COUNTER_CLOCKWISE) +// +// val msInfo = vk.PipelineMultisampleStateCreateInfo(VkSampleCount.`1_BIT`) +// +// val colorAttachment = vk.PipelineColorBlendAttachmentState { +// blendEnable = true +// srcColorBlendFactor = VkBlendFactor.SRC_ALPHA +// dstColorBlendFactor = VkBlendFactor.ONE_MINUS_SRC_ALPHA +// colorBlendOp = VkBlendOp.ADD +// srcAlphaBlendFactor = VkBlendFactor.ONE_MINUS_SRC_ALPHA +// dstAlphaBlendFactor = VkBlendFactor.ZERO +// alphaBlendOp = VkBlendOp.ADD +// colorWriteMask = VkColorComponent.R_BIT or VkColorComponent.G_BIT or VkColorComponent.B_BIT or VkColorComponent.A_BIT +// } +// +// val depthInfo = vk.PipelineDepthStencilStateCreateInfo() +// +// val blendInfo = vk.PipelineColorBlendStateCreateInfo(colorAttachment) +// +// val dynamicStates = listOf(VkDynamicState.VIEWPORT, VkDynamicState.SCISSOR) +// val dynamicState = vk.PipelineDynamicStateCreateInfo(dynamicStates) +// +// val info = vk.GraphicsPipelineCreateInfo { +// flags = pipelineCreateFlags +// stages = stage +// vertexInputState = vertexInfo +// inputAssemblyState = iaInfo +// viewportState = viewportInfo +// rasterizationState = rasterInfo +// multisampleState = msInfo +// depthStencilState = depthInfo +// colorBlendState = blendInfo +// this.dynamicState = dynamicState +// layout = pipelineLayout +// renderPass = this@ImplVk.renderPass +// } +// pipeline = device.createGraphicsPipelines(pipelineCache, info) +// +// device destroyShaderModule vertModule +// device destroyShaderModule fragModule +// +// return true +// } +// +// /** ------------------------------------------------------------------------- +// * Miscellaneous Vulkan Helpers +// * Generally we try to NOT provide any kind of superfluous high-level helpers in the examples. +// * But for the upcoming multi-viewport feature, the Vulkan will need this code anyway, +// * so we decided to shared it and use it in the examples' main.cpp +// * If your application/engine already has code to create all that data +// * (swap chain, render pass, frame buffers, etc.) you can ignore all of this. +// * ------------------------------------------------------------------------- +// * NB: Those functions do NOT use any of the state used/affected by the regular ImplVk.XXX functions. +// * ------------------------------------------------------------------------- */ +// +// /** Window Data */ +// var wd = WindowData() +// +// class WindowData { +// var size = Vec2i() +// var swapchain: VkSwapchainKHR = NULL +// var surface: VkSurfaceKHR = NULL +// lateinit var surfaceFormat: VkSurfaceFormatKHR +// var presentMode = VkPresentMode.IMMEDIATE_KHR +// var renderPass: VkRenderPass = NULL +// var clearEnable = false +// var clearValue: VkClearValue = VkClearValue.calloc() +// var backBufferCount = 0 +// var backBuffer = VkImageArray(16) +// var backBufferView = VkImageViewArray(16) +// var framebuffer = VkFramebufferArray(16) +// var frameIndex = 0 +// var frames = Array(VK_QUEUED_FRAMES) { FrameData() } +// val frame: FrameData +// get() = frames[frameIndex] +// } +// +// class FrameData { +// /** keep track of recently rendered swapchain frame indices */ +// var backbufferIndex = 0 +// var commandPool: VkCommandPool = NULL +// lateinit var commandBuffer: VkCommandBuffer +// var fence: VkFence = NULL +// var imageAcquiredSemaphore: VkSemaphore = NULL +// var renderCompleteSemaphore: VkSemaphore = NULL +// } +// +// fun createWindowDataCommandBuffers() { +// +// // Create Command Buffers +// for (i in 0 until VK_QUEUED_FRAMES) +// +// wd.frames[i].apply { +// +// commandPool = device createCommandPool vk.CommandPoolCreateInfo { +// flag = VkCommandPoolCreate.RESET_COMMAND_BUFFER_BIT +// queueFamilyIndex = queueFamily +// } +// +// commandBuffer = device allocateCommandBuffer vk.CommandBufferAllocateInfo { +// this.commandPool = this@apply.commandPool +// level = VkCommandBufferLevel.PRIMARY +// commandBufferCount = 1 +// } +// fence = device createFence VkFenceCreate.SIGNALED_BIT +// +// val info = vk.SemaphoreCreateInfo() +// imageAcquiredSemaphore = device createSemaphore info +// renderCompleteSemaphore = device createSemaphore info +// } +// } +// +// fun createWindowDataSwapChainAndFramebuffer(size: Vec2i) { +// +// var minImageCount = 2 // FIXME: this should become a function parameter +// +// val oldSwapchain = wd.swapchain +// device.waitIdle() +// +// // Destroy old Framebuffer +// for (i in 0 until wd.backBufferCount) { +// if (wd.backBufferView[i] != NULL) +// device destroyImageView wd.backBufferView[i] +// if (wd.framebuffer[i] != NULL) +// device destroyFramebuffer wd.framebuffer[i] +// } +// wd.backBufferCount = 0 +// if (wd.renderPass != NULL) +// device destroyRenderPass wd.renderPass +// +// // If min image count was not specified, request different count of images dependent on selected present mode +// if (minImageCount == 0) +// minImageCount = getMinImageCountFromPresentMode(wd.presentMode) +// +// // Create Swapchain +// run { +// val info = vk.SwapchainCreateInfoKHR { +// surface = wd.surface +// this.minImageCount = minImageCount +// imageFormat = wd.surfaceFormat.format +// imageColorSpace = wd.surfaceFormat.colorSpace +// imageArrayLayers = 1 +// imageUsage = VkImageUsage.COLOR_ATTACHMENT_BIT.i +// imageSharingMode = VkSharingMode.EXCLUSIVE // Assume that graphics family == present family +// preTransform = VkSurfaceTransform.IDENTITY_BIT_KHR +// compositeAlpha = VkCompositeAlpha.OPAQUE_BIT_KHR +// presentMode = wd.presentMode +// clipped = true +// this.oldSwapchain = oldSwapchain +// } +// val cap = physicalDevice getSurfaceCapabilitiesKHR wd.surface +// +// if (info.minImageCount < cap.minImageCount) +// info.minImageCount = cap.minImageCount +// else if (info.minImageCount > cap.maxImageCount) +// info.minImageCount = cap.maxImageCount +// +// if (cap.currentExtent.width == 0xffffffff.i) { +// wd.size(size) // TODO bug cant inception +// info.imageExtent(size) +// } else { +// wd.size(cap.currentExtent.width, cap.currentExtent.height) // TOOD bug +// info.imageExtent(wd.size) +// } +// wd.swapchain = device createSwapchainKHR info +// wd.backBuffer = device getSwapchainImagesKHR wd.swapchain +// wd.backBufferCount = wd.backBuffer.size +// } +// if (oldSwapchain != NULL) +// device destroySwapchainKHR oldSwapchain +// +// // Create the Render Pass +// run { +// val attachment = vk.AttachmentDescription { +// format = wd.surfaceFormat.format +// samples = VkSampleCount.`1_BIT` +// loadOp = if (wd.clearEnable) VkAttachmentLoadOp.CLEAR else VkAttachmentLoadOp.DONT_CARE +// storeOp = VkAttachmentStoreOp.STORE +// stencilLoadOp = VkAttachmentLoadOp.DONT_CARE +// stencilStoreOp = VkAttachmentStoreOp.DONT_CARE +// initialLayout = VkImageLayout.UNDEFINED +// finalLayout = VkImageLayout.PRESENT_SRC_KHR +// } +// val colorAttachment = vk.AttachmentReference(0, VkImageLayout.COLOR_ATTACHMENT_OPTIMAL) +// val subpass = vk.SubpassDescription { +// pipelineBindPoint = VkPipelineBindPoint.GRAPHICS +// colorAttachmentCount = 1 +// this.colorAttachment = colorAttachment +// } +// val dependency = vk.SubpassDependency { +// srcSubpass = VK_SUBPASS_EXTERNAL +// dstSubpass = 0 +// srcStageMask = VkPipelineStage.COLOR_ATTACHMENT_OUTPUT_BIT.i +// dstStageMask = VkPipelineStage.COLOR_ATTACHMENT_OUTPUT_BIT.i +// srcAccessMask = 0 +// dstAccessMask = VkAccess.COLOR_ATTACHMENT_WRITE_BIT.i +// } +// val info = vk.RenderPassCreateInfo().also { +// it.attachment = attachment +// it.subpass = subpass +// it.dependency = dependency +// } +// wd.renderPass = device createRenderPass info +// } +// +// // Create The Image Views +// run { +// val info = vk.ImageViewCreateInfo { +// viewType = VkImageViewType.`2D` +// format = wd.surfaceFormat.format +// components(VkComponentSwizzle.R, VkComponentSwizzle.G, VkComponentSwizzle.B, VkComponentSwizzle.A) +// } +// val imageRange = vk.ImageSubresourceRange(VkImageAspect.COLOR_BIT, 0, 1, 0, 1) +// info.subresourceRange = imageRange +// for (i in 0 until wd.backBufferCount) { +// info.image = wd.backBuffer[i] +// wd.backBufferView[i] = device createImageView info +// } +// } +// +// // Create Framebuffer +// run { +// val attachment: VkImageViewBuffer = appBuffer.longBuffer +// val info = vk.FramebufferCreateInfo { +// renderPass = wd.renderPass +// this.attachments = attachment //TODO bug +// extent(wd.size, 1) +// } +// for (i in 0 until wd.backBufferCount) { +// attachment[0] = wd.backBufferView[i] +// wd.framebuffer[i] = device createFramebuffer info +// } +// } +// } +// +// fun destroyWindowData() { +// device.apply { +// waitIdle() // FIXME: We could wait on the Queue if we had the queue in wd-> (otherwise VulkanH functions can't use globals) +// //vkQueueWaitIdle(g_Queue); +// +// wd.frames.forEach { fd -> +// destroyFence(fd.fence) +// freeCommandBuffer(fd.commandPool, fd.commandBuffer) +// destroyCommandPool(fd.commandPool) +// destroySemaphores(fd.imageAcquiredSemaphore, fd.renderCompleteSemaphore) +// } +// for (i in 0 until wd.backBufferCount) { +// destroyImageView(wd.backBufferView[i]) +// destroyFramebuffer(wd.framebuffer[i]) +// } +// destroyRenderPass(wd.renderPass) +// destroySwapchainKHR(wd.swapchain) +// instance destroySurfaceKHR wd.surface +// wd = WindowData() +// } +// } +// +// fun selectSurfaceFormat(physicalDevice: VkPhysicalDevice, surface: VkSurfaceKHR, requestFormats: Array, requestColorSpace: VkColorSpace): VkSurfaceFormatKHR { +// assert(requestFormats.isNotEmpty()) +// +// /* Per Spec Format and View Format are expected to be the same unless VK_IMAGE_CREATE_MUTABLE_BIT was set at image creation +// Assuming that the default behavior is without setting this bit, there is no need for separate Swapchain image and image view format +// Additionally several new color spaces were introduced with Vulkan Spec v1.0.40, +// hence we must make sure that a format with the mostly available color space, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, is found and used. */ +// val availFormat = physicalDevice getSurfaceFormatsKHR surface +// +// // First check if only one format, VK_FORMAT_UNDEFINED, is available, which would imply that any format is available +// return when (availFormat.size) { +// 1 -> when (availFormat[0].format) { +// VkFormat.UNDEFINED -> vk.SurfaceFormatKHR(requestFormats[0], requestColorSpace) +// else -> availFormat[0] // No point in searching another format +// } +// else -> { +// // Request several formats, the first found will be used +// for (request in requestFormats.indices) +// for (avail in availFormat.indices) +// if (availFormat[avail].format == requestFormats[request] && availFormat[avail].colorSpace == requestColorSpace) +// return availFormat[avail] +// +// // If none of the requested image formats could be found, use the first available +// return availFormat[0] +// } +// } +// } +// +// fun selectPresentMode(requestModes: Array): VkPresentMode { +// +// // Request a certain mode and confirm that it is available. If not use VK_PRESENT_MODE_FIFO_KHR which is mandatory +// val availModes = physicalDevice getSurfacePresentModesKHR wd.surface +// for (request in requestModes.indices) +// for (avail in availModes.indices) +// if (requestModes[request] == availModes[avail]) +// return requestModes[request] +// +// return VkPresentMode.FIFO_KHR // Always available +// } +// +// fun getMinImageCountFromPresentMode(presentMode: VkPresentMode) = when (presentMode) { +// VkPresentMode.MAILBOX_KHR -> 3 +// VkPresentMode.FIFO_KHR, VkPresentMode.FIFO_RELAXED_KHR -> 2 +// VkPresentMode.IMMEDIATE_KHR -> 1 +// else -> throw Error() +// } +// +// +// fun memoryType(properties: VkMemoryProperty, typeBits: Int) = memoryType(properties.i, typeBits) +// fun memoryType(properties: VkMemoryPropertyFlags, typeBits: Int): Int { +// val prop = physicalDevice.memoryProperties +// for (i in 0 until prop.memoryTypeCount) +// if ((prop.memoryTypes[i].propertyFlags and properties) == properties && typeBits has (1 shl i)) +// return i +// return -1 // Unable to find memoryType +// } +// +// /** glsl_shader.vert, compiled with: +// * # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert +// */ +// val glslShaderVertSpv = intArrayOf( +// 0x07230203, 0x00010000, 0x00080001, 0x0000002e, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, +// 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, +// 0x000a000f, 0x00000000, 0x00000004, 0x6e69616d, 0x00000000, 0x0000000b, 0x0000000f, 0x00000015, +// 0x0000001b, 0x0000001c, 0x00030003, 0x00000002, 0x000001c2, 0x00040005, 0x00000004, 0x6e69616d, +// 0x00000000, 0x00030005, 0x00000009, 0x00000000, 0x00050006, 0x00000009, 0x00000000, 0x6f6c6f43, +// 0x00000072, 0x00040006, 0x00000009, 0x00000001, 0x00005655, 0x00030005, 0x0000000b, 0x0074754f, +// 0x00040005, 0x0000000f, 0x6c6f4361, 0x0000726f, 0x00030005, 0x00000015, 0x00565561, 0x00060005, +// 0x00000019, 0x505f6c67, 0x65567265, 0x78657472, 0x00000000, 0x00060006, 0x00000019, 0x00000000, +// 0x505f6c67, 0x7469736f, 0x006e6f69, 0x00030005, 0x0000001b, 0x00000000, 0x00040005, 0x0000001c, +// 0x736f5061, 0x00000000, 0x00060005, 0x0000001e, 0x73755075, 0x6e6f4368, 0x6e617473, 0x00000074, +// 0x00050006, 0x0000001e, 0x00000000, 0x61635375, 0x0000656c, 0x00060006, 0x0000001e, 0x00000001, +// 0x61725475, 0x616c736e, 0x00006574, 0x00030005, 0x00000020, 0x00006370, 0x00040047, 0x0000000b, +// 0x0000001e, 0x00000000, 0x00040047, 0x0000000f, 0x0000001e, 0x00000002, 0x00040047, 0x00000015, +// 0x0000001e, 0x00000001, 0x00050048, 0x00000019, 0x00000000, 0x0000000b, 0x00000000, 0x00030047, +// 0x00000019, 0x00000002, 0x00040047, 0x0000001c, 0x0000001e, 0x00000000, 0x00050048, 0x0000001e, +// 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x0000001e, 0x00000001, 0x00000023, 0x00000008, +// 0x00030047, 0x0000001e, 0x00000002, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, +// 0x00030016, 0x00000006, 0x00000020, 0x00040017, 0x00000007, 0x00000006, 0x00000004, 0x00040017, +// 0x00000008, 0x00000006, 0x00000002, 0x0004001e, 0x00000009, 0x00000007, 0x00000008, 0x00040020, +// 0x0000000a, 0x00000003, 0x00000009, 0x0004003b, 0x0000000a, 0x0000000b, 0x00000003, 0x00040015, +// 0x0000000c, 0x00000020, 0x00000001, 0x0004002b, 0x0000000c, 0x0000000d, 0x00000000, 0x00040020, +// 0x0000000e, 0x00000001, 0x00000007, 0x0004003b, 0x0000000e, 0x0000000f, 0x00000001, 0x00040020, +// 0x00000011, 0x00000003, 0x00000007, 0x0004002b, 0x0000000c, 0x00000013, 0x00000001, 0x00040020, +// 0x00000014, 0x00000001, 0x00000008, 0x0004003b, 0x00000014, 0x00000015, 0x00000001, 0x00040020, +// 0x00000017, 0x00000003, 0x00000008, 0x0003001e, 0x00000019, 0x00000007, 0x00040020, 0x0000001a, +// 0x00000003, 0x00000019, 0x0004003b, 0x0000001a, 0x0000001b, 0x00000003, 0x0004003b, 0x00000014, +// 0x0000001c, 0x00000001, 0x0004001e, 0x0000001e, 0x00000008, 0x00000008, 0x00040020, 0x0000001f, +// 0x00000009, 0x0000001e, 0x0004003b, 0x0000001f, 0x00000020, 0x00000009, 0x00040020, 0x00000021, +// 0x00000009, 0x00000008, 0x0004002b, 0x00000006, 0x00000028, 0x00000000, 0x0004002b, 0x00000006, +// 0x00000029, 0x3f800000, 0x00050036, 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, +// 0x00000005, 0x0004003d, 0x00000007, 0x00000010, 0x0000000f, 0x00050041, 0x00000011, 0x00000012, +// 0x0000000b, 0x0000000d, 0x0003003e, 0x00000012, 0x00000010, 0x0004003d, 0x00000008, 0x00000016, +// 0x00000015, 0x00050041, 0x00000017, 0x00000018, 0x0000000b, 0x00000013, 0x0003003e, 0x00000018, +// 0x00000016, 0x0004003d, 0x00000008, 0x0000001d, 0x0000001c, 0x00050041, 0x00000021, 0x00000022, +// 0x00000020, 0x0000000d, 0x0004003d, 0x00000008, 0x00000023, 0x00000022, 0x00050085, 0x00000008, +// 0x00000024, 0x0000001d, 0x00000023, 0x00050041, 0x00000021, 0x00000025, 0x00000020, 0x00000013, +// 0x0004003d, 0x00000008, 0x00000026, 0x00000025, 0x00050081, 0x00000008, 0x00000027, 0x00000024, +// 0x00000026, 0x00050051, 0x00000006, 0x0000002a, 0x00000027, 0x00000000, 0x00050051, 0x00000006, +// 0x0000002b, 0x00000027, 0x00000001, 0x00070050, 0x00000007, 0x0000002c, 0x0000002a, 0x0000002b, +// 0x00000028, 0x00000029, 0x00050041, 0x00000011, 0x0000002d, 0x0000001b, 0x0000000d, 0x0003003e, +// 0x0000002d, 0x0000002c, 0x000100fd, 0x00010038).toBuffer() +// +// /** glsl_shader.frag, compiled with: +// * # glslangValidator -V -x -o glsl_shader.frag.u32 glsl_shader.frag +// */ +// val glslShaderFragSpv = intArrayOf( +// 0x07230203, 0x00010000, 0x00080001, 0x0000001e, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, +// 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, +// 0x0007000f, 0x00000004, 0x00000004, 0x6e69616d, 0x00000000, 0x00000009, 0x0000000d, 0x00030010, +// 0x00000004, 0x00000007, 0x00030003, 0x00000002, 0x000001c2, 0x00040005, 0x00000004, 0x6e69616d, +// 0x00000000, 0x00040005, 0x00000009, 0x6c6f4366, 0x0000726f, 0x00030005, 0x0000000b, 0x00000000, +// 0x00050006, 0x0000000b, 0x00000000, 0x6f6c6f43, 0x00000072, 0x00040006, 0x0000000b, 0x00000001, +// 0x00005655, 0x00030005, 0x0000000d, 0x00006e49, 0x00050005, 0x00000016, 0x78655473, 0x65727574, +// 0x00000000, 0x00040047, 0x00000009, 0x0000001e, 0x00000000, 0x00040047, 0x0000000d, 0x0000001e, +// 0x00000000, 0x00040047, 0x00000016, 0x00000022, 0x00000000, 0x00040047, 0x00000016, 0x00000021, +// 0x00000000, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00030016, 0x00000006, +// 0x00000020, 0x00040017, 0x00000007, 0x00000006, 0x00000004, 0x00040020, 0x00000008, 0x00000003, +// 0x00000007, 0x0004003b, 0x00000008, 0x00000009, 0x00000003, 0x00040017, 0x0000000a, 0x00000006, +// 0x00000002, 0x0004001e, 0x0000000b, 0x00000007, 0x0000000a, 0x00040020, 0x0000000c, 0x00000001, +// 0x0000000b, 0x0004003b, 0x0000000c, 0x0000000d, 0x00000001, 0x00040015, 0x0000000e, 0x00000020, +// 0x00000001, 0x0004002b, 0x0000000e, 0x0000000f, 0x00000000, 0x00040020, 0x00000010, 0x00000001, +// 0x00000007, 0x00090019, 0x00000013, 0x00000006, 0x00000001, 0x00000000, 0x00000000, 0x00000000, +// 0x00000001, 0x00000000, 0x0003001b, 0x00000014, 0x00000013, 0x00040020, 0x00000015, 0x00000000, +// 0x00000014, 0x0004003b, 0x00000015, 0x00000016, 0x00000000, 0x0004002b, 0x0000000e, 0x00000018, +// 0x00000001, 0x00040020, 0x00000019, 0x00000001, 0x0000000a, 0x00050036, 0x00000002, 0x00000004, +// 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x00050041, 0x00000010, 0x00000011, 0x0000000d, +// 0x0000000f, 0x0004003d, 0x00000007, 0x00000012, 0x00000011, 0x0004003d, 0x00000014, 0x00000017, +// 0x00000016, 0x00050041, 0x00000019, 0x0000001a, 0x0000000d, 0x00000018, 0x0004003d, 0x0000000a, +// 0x0000001b, 0x0000001a, 0x00050057, 0x00000007, 0x0000001c, 0x00000017, 0x0000001b, 0x00050085, +// 0x00000007, 0x0000001d, 0x00000012, 0x0000001c, 0x0003003e, 0x00000009, 0x0000001d, 0x000100fd, +// 0x00010038).toBuffer() +//} \ No newline at end of file diff --git a/src/main/kotlin/imgui/impl/JoglGL3.kt b/src/main/kotlin/imgui/impl/JoglGL3.kt index fbb1d9aa4..f8c076fac 100644 --- a/src/main/kotlin/imgui/impl/JoglGL3.kt +++ b/src/main/kotlin/imgui/impl/JoglGL3.kt @@ -9,18 +9,19 @@ import com.jogamp.opengl.GL import com.jogamp.opengl.GL2ES3.* import com.jogamp.opengl.GL3 import glm_.* -import glm_.buffer.bufferBig -import glm_.buffer.free -import glm_.buffer.intBufferBig +import glm_.mat4x4.Mat4 import glm_.vec2.Vec2 import glm_.vec2.Vec2i import glm_.vec4.Vec4i -import gln.buf import gln.get import gln.glf.semantic import imgui.* import imgui.ImGui.io import imgui.ImGui.mouseCursor +import kool.bufferBig +import kool.free +import kool.intBufferBig +import kool.stak import org.lwjgl.opengl.GL11.GL_FILL import org.lwjgl.opengl.GL11.GL_POLYGON_MODE import org.lwjgl.opengl.GL33.GL_SAMPLER_BINDING @@ -285,8 +286,8 @@ object JoglGL3 { val lastArrayBuffer = glGetInteger(GL_ARRAY_BUFFER_BINDING) val lastVertexArray = glGetInteger(GL_VERTEX_ARRAY_BINDING) val lastPolygonMode = glGetInteger(GL_POLYGON_MODE) - val lastViewport = Vec4i(buf.apply { glGetIntegerv(GL_VIEWPORT, asIntBuffer()) }) - val lastScissorBox = Vec4i(buf.apply { glGetIntegerv(GL_SCISSOR_BOX, asIntBuffer()) }) + val lastViewport = Vec4i(stak { s -> s.callocInt(4).also { glGetIntegerv(GL_VIEWPORT, it) } }) + val lastScissorBox = Vec4i(stak { s -> s.callocInt(4).also { glGetIntegerv(GL_SCISSOR_BOX, it) } }) val lastBlendSrcRgb = glGetInteger(GL_BLEND_SRC_RGB) val lastBlendDstRgb = glGetInteger(GL_BLEND_DST_RGB) val lastBlendSrcAlpha = glGetInteger(GL_BLEND_SRC_ALPHA) @@ -311,7 +312,7 @@ object JoglGL3 { glViewport(0, 0, fbSize.x, fbSize.y) val ortho = glm.ortho(mat, 0f, io.displaySize.x.f, io.displaySize.y.f, 0f) glUseProgram(program.name) - glUniformMatrix4fv(program.mat, 1, false, (ortho to buf).asFloatBuffer()) + glUniformMatrix4fv(program.mat, 1, false, ortho to stak { it.mallocFloat(Mat4.length) }) checkSize(drawData.cmdLists) @@ -434,7 +435,7 @@ object JoglGL3 { glDeleteVertexArrays(1, vaoName) glDeleteBuffers(Buffer.MAX, bufferName) - if(program.name >= 0) glDeleteProgram(program.name) + if (program.name >= 0) glDeleteProgram(program.name) destroyFontsTexture(gl) } @@ -448,7 +449,8 @@ object JoglGL3 { } } -fun GL3.glGetInteger(name: Int): Int { - glGetIntegerv(name, buf.asIntBuffer()) - return buf.getInt(0) +fun GL3.glGetInteger(name: Int): Int = stak { + val buff = it.mallocInt(1) + glGetIntegerv(name, buff) + return buff[0] } diff --git a/src/main/kotlin/imgui/impl/JoglVrGL3.kt b/src/main/kotlin/imgui/impl/JoglVrGL3.kt index c17bb43bc..a1e816b67 100644 --- a/src/main/kotlin/imgui/impl/JoglVrGL3.kt +++ b/src/main/kotlin/imgui/impl/JoglVrGL3.kt @@ -13,18 +13,19 @@ import com.jogamp.opengl.GL2GL3.GL_POLYGON_MODE import com.jogamp.opengl.GL3 import com.jogamp.opengl.GL3ES3.GL_SAMPLER_BINDING import glm_.* -import glm_.buffer.bufferBig -import glm_.buffer.free -import glm_.buffer.intBufferBig +import glm_.mat4x4.Mat4 import glm_.vec2.Vec2 import glm_.vec2.Vec2i import glm_.vec4.Vec4i -import gln.buf import gln.get import gln.glf.semantic import imgui.* import imgui.ImGui.io import imgui.ImGui.mouseCursor +import kool.bufferBig +import kool.free +import kool.intBufferBig +import kool.stak object JoglVrGL3 { @@ -287,8 +288,8 @@ object JoglVrGL3 { val lastArrayBuffer = glGetInteger(GL_ARRAY_BUFFER_BINDING) val lastVertexArray = glGetInteger(GL2ES3.GL_VERTEX_ARRAY_BINDING) val lastPolygonMode = glGetInteger(GL_POLYGON_MODE) - val lastViewport = Vec4i(buf.apply { glGetIntegerv(GL_VIEWPORT, asIntBuffer()) }) - val lastScissorBox = Vec4i(buf.apply { glGetIntegerv(GL_SCISSOR_BOX, asIntBuffer()) }) + val lastViewport = Vec4i(stak { s -> s.callocInt(4).also { glGetIntegerv(GL_VIEWPORT, it) } }) + val lastScissorBox = Vec4i(stak { s -> s.callocInt(4).also { glGetIntegerv(GL_SCISSOR_BOX, it) } }) val lastBlendSrcRgb = glGetInteger(GL_BLEND_SRC_RGB) val lastBlendDstRgb = glGetInteger(GL_BLEND_DST_RGB) val lastBlendSrcAlpha = glGetInteger(GL_BLEND_SRC_ALPHA) @@ -313,7 +314,7 @@ object JoglVrGL3 { glViewport(0, 0, fbSize.x, fbSize.y) val ortho = glm.ortho(mat, 0f, io.displaySize.x.f, io.displaySize.y.f, 0f) glUseProgram(program.name) - glUniformMatrix4fv(program.mat, 1, false, (ortho to buf).asFloatBuffer()) + glUniformMatrix4fv(program.mat, 1, false, ortho to stak { it.mallocFloat(Mat4.length) }) checkSize(drawData.cmdLists) diff --git a/src/main/kotlin/imgui/impl/LwjglGlfw.kt b/src/main/kotlin/imgui/impl/LwjglGlfw.kt index f455e5141..69b2fc374 100644 --- a/src/main/kotlin/imgui/impl/LwjglGlfw.kt +++ b/src/main/kotlin/imgui/impl/LwjglGlfw.kt @@ -1,7 +1,6 @@ package imgui.impl import glm_.b -import glm_.buffer.cap import glm_.c import glm_.f import glm_.vec2.Vec2d @@ -9,15 +8,12 @@ import imgui.* import imgui.ImGui.io import imgui.ImGui.mouseCursor import imgui.impl.windowsIme.imeListener +import kool.cap import org.lwjgl.glfw.GLFW.* -import org.lwjgl.glfw.GLFWNativeWin32.glfwGetWin32Window import org.lwjgl.system.MemoryUtil.NULL import org.lwjgl.system.Platform import uno.glfw.* import uno.glfw.GlfwWindow.CursorStatus -import kotlin.collections.fill -import kotlin.collections.forEach -import kotlin.collections.indices import kotlin.collections.set @@ -86,8 +82,8 @@ object LwjglGlfw { clientApi = clientApi_ - if (clientApi == GlfwClientApi.Vulkan) - ImplVk.init() +// if (clientApi == GlfwClientApi.Vulkan) +// ImplVk.init() return true } @@ -246,7 +242,7 @@ object LwjglGlfw { when (clientApi) { GlfwClientApi.OpenGL -> ImplGL3.destroyDeviceObjects() - else -> ImplVk.invalidateDeviceObjects() + else -> TODO()//ImplVk.invalidateDeviceObjects() } } diff --git a/src/main/kotlin/imgui/impl/common.kt b/src/main/kotlin/imgui/impl/common.kt index d5d6b8840..c6699118e 100644 --- a/src/main/kotlin/imgui/impl/common.kt +++ b/src/main/kotlin/imgui/impl/common.kt @@ -3,8 +3,8 @@ package imgui.impl import com.jogamp.opengl.GL2ES3 import com.jogamp.opengl.GL3 import glm_.BYTES -import glm_.buffer.bufferBig -import glm_.buffer.intBufferBig +import kool.bufferBig +import kool.intBufferBig import glm_.mat4x4.Mat4 import gln.glf.semantic import org.lwjgl.system.Platform diff --git a/src/main/kotlin/imgui/impl/windowsIme/imeListener.kt b/src/main/kotlin/imgui/impl/windowsIme/imeListener.kt index 84d288dc9..bcaa5c9f4 100644 --- a/src/main/kotlin/imgui/impl/windowsIme/imeListener.kt +++ b/src/main/kotlin/imgui/impl/windowsIme/imeListener.kt @@ -12,7 +12,7 @@ import org.lwjgl.system.windows.RECT import org.lwjgl.system.windows.User32.* import org.lwjgl.system.windows.WindowProc import uno.glfw.GlfwWindow -import vkk.adr +//import vkk.adr object imeListener : WindowProc() { @@ -29,7 +29,7 @@ object imeListener : WindowProc() { if (Platform.get() == Platform.WINDOWS) { hwnd = glfwGetWin32Window(window.handle) glfwProc = GetWindowLongPtr(hwnd, GWL_WNDPROC) - SetWindowLongPtr(hwnd, GWL_WNDPROC, adr) + SetWindowLongPtr(hwnd, GWL_WNDPROC, address()) // TODO adr } } diff --git a/src/main/kotlin/imgui/impl/windowsIme/imm.kt b/src/main/kotlin/imgui/impl/windowsIme/imm.kt index c3fe5cec8..4acd0ca84 100644 --- a/src/main/kotlin/imgui/impl/windowsIme/imm.kt +++ b/src/main/kotlin/imgui/impl/windowsIme/imm.kt @@ -1,9 +1,8 @@ package imgui.impl.windowsIme -import ab.advance -import ab.appBuffer import glm_.BYTES -import glm_.buffer.adr +import glm_.L +import kool.adr import org.lwjgl.system.JNI import org.lwjgl.system.Library import org.lwjgl.system.MemoryUtil @@ -90,8 +89,7 @@ class COMPOSITIONFORM constructor(val adr: Long) { val buffer: ByteBuffer = MemoryUtil.memByteBuffer(adr, size) - constructor() : this(appBuffer.ptr.advance(size)) - constructor(buffer: ByteBuffer) : this(buffer.adr) + constructor() : this(MemoryUtil.nmemAlloc(size.L)) var dwStyle: DWORD get() = memGetLong(adr + ofs.dwStyle) @@ -105,6 +103,8 @@ class COMPOSITIONFORM constructor(val adr: Long) { get() = RECT(adr + ofs.rcArea) set(value) = value.to(adr + ofs.rcArea) + fun free() = MemoryUtil.nmemFree(adr) + companion object { val size = 2 * Int.BYTES + POINT.size + RECT.size } @@ -132,7 +132,7 @@ class POINT constructor(val adr: Long) { get() = MemoryUtil.memGetLong(adr + ofs.y) set(value) = MemoryUtil.memPutLong(adr + ofs.y, value) - constructor() : this(appBuffer.ptr.advance(size)) + constructor() : this(MemoryUtil.nmemAlloc(size.L)) fun to(adr: Long) { MemoryUtil.memPutLong(adr + ofs.x, x) @@ -174,7 +174,7 @@ class RECT(val adr: Long) { get() = MemoryUtil.memGetLong(adr + ofs.bottom) set(value) = MemoryUtil.memPutLong(adr + ofs.bottom, value) - constructor() : this(appBuffer.ptr.advance(size)) + constructor() : this(MemoryUtil.nmemAlloc(size.L)) fun to(adr: Long) { MemoryUtil.memPutLong(adr + ofs.left, left) diff --git a/src/main/kotlin/imgui/static funcs.kt b/src/main/kotlin/imgui/static funcs.kt index e1b198db1..4a5c6c5c4 100644 --- a/src/main/kotlin/imgui/static funcs.kt +++ b/src/main/kotlin/imgui/static funcs.kt @@ -5,7 +5,7 @@ package imgui import gli_.has import gli_.hasnt import glm_.* -import glm_.buffer.bufferBig +import kool.bufferBig import glm_.vec2.Vec2 import glm_.vec2.Vec2i import imgui.ImGui.begin @@ -1362,7 +1362,7 @@ var imeSetInputScreenPosFn_Win32 = { x: Int, y: Int -> if (hwnd != NULL) { val himc: HIMC = imm.getContext(hwnd) if (himc != NULL) { - val cf = COMPOSITIONFORM(bufferBig(COMPOSITIONFORM.size)).apply { + val cf = COMPOSITIONFORM().apply { ptCurrentPos.x = x.L ptCurrentPos.y = y.L dwStyle = imm.CFS_FORCE_POSITION.L diff --git a/src/test/java/imgui/gl/Test_lwjgl.java b/src/test/java/imgui/gl/Test_lwjgl.java index e72c63085..ba6dfac03 100644 --- a/src/test/java/imgui/gl/Test_lwjgl.java +++ b/src/test/java/imgui/gl/Test_lwjgl.java @@ -9,6 +9,7 @@ import imgui.impl.LwjglGlfw.GlfwClientApi; import kotlin.Unit; import org.lwjgl.glfw.GLFW; +import org.lwjgl.system.MemoryStack; import uno.glfw.GlfwWindow; import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT; @@ -82,7 +83,7 @@ Poll and handle events (inputs, window resize, etc.) - When io.wantCaptureMouse is true, do not dispatch mouse input data to your main application. - When io.wantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. */ - window.loop(() -> { + window.loop((MemoryStack stack) -> { mainLoop(); return Unit.INSTANCE; }); diff --git a/src/test/kotlin/imgui/gl/test lwjgl.kt b/src/test/kotlin/imgui/gl/test lwjgl.kt index 35696438c..90e32004d 100644 --- a/src/test/kotlin/imgui/gl/test lwjgl.kt +++ b/src/test/kotlin/imgui/gl/test lwjgl.kt @@ -15,6 +15,7 @@ import imgui.impl.LwjglGlfw import imgui.impl.LwjglGlfw.GlfwClientApi import org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT import org.lwjgl.opengl.GL11.glClear +import org.lwjgl.system.MemoryStack import org.lwjgl.system.Platform import uno.glfw.GlfwWindow import uno.glfw.glfw @@ -93,7 +94,7 @@ private class HelloWorld_lwjgl { glfw.terminate() } - fun mainLoop() { + fun mainLoop(stack: MemoryStack) { // Start the Dear ImGui frame LwjglGlfw.newFrame() diff --git a/src/test/kotlin/imgui/vk/test lwjgl vk.kt b/src/test/kotlin/imgui/vk/test lwjgl vk.kt index 37a7030f0..adf4e3a81 100644 --- a/src/test/kotlin/imgui/vk/test lwjgl vk.kt +++ b/src/test/kotlin/imgui/vk/test lwjgl vk.kt @@ -1,378 +1,378 @@ -package imgui.vk - -import ab.appBuffer -import glm_.vec2.Vec2 -import glm_.vec2.Vec2i -import glm_.vec4.Vec4 -import imgui.Cond -import imgui.Context -import imgui.ImGui -import imgui.ImGui.button -import imgui.ImGui.setNextWindowPos -import imgui.ImGui.showDemoWindow -import imgui.ImGui.text -import imgui.destroy -import imgui.functionalProgramming.withWindow -import imgui.impl.ImplVk -import imgui.impl.LwjglGlfw -import imgui.impl.LwjglGlfw.GlfwClientApi -import imgui.impl.LwjglGlfw.window -import org.lwjgl.system.MemoryUtil -import org.lwjgl.vulkan.VkPresentInfoKHR -import uno.glfw.GlfwWindow -import uno.glfw.glfw -import uno.glfw.windowHint.Api -import vkk.* - -fun main(args: Array) { - HelloWorld_lwjgl().run() -} - -var DEBUG_REPORT = true -var UNLIMITED_FRAME_RATE = false - -private class HelloWorld_lwjgl { - - var resizeWanted = false - var resizeSize = Vec2i() - - val wd: ImplVk.WindowData - get() = ImplVk.wd - - val ctx: Context - - init { - // Setup window - glfw.errorCallback = glfw.defaultErrorCallback - glfw.init() - - glfw.windowHint { api = Api.None } - val window = GlfwWindow(1280, 720, "ImGui GLFW+Vulkan example").apply { - autoSwap = false // no swapBuffer with vk - } - - // Setup Vulkan - if (!glfw.vulkanSupported) - throw Error("GLFW: Vulkan Not Supported") - - setupVulkan(glfw.requiredInstanceExtensions) - - // Create Window Surface - wd.surface = window createSurface ImplVk.instance - - // Create Framebuffers - val size = window.framebufferSize - window.framebufferSizeCallback = ::resizeCallback - setupVulkanWindowData(size) - - // Setup Dear ImGui binding - ctx = Context() - //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls - //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls - - // Setup GLFW and Vulkan binding - LwjglGlfw.init(window, true, GlfwClientApi.Vulkan) - - // Setup style - ImGui.styleColorsDark() - //ImGui.styleColorsClassic() - - // Load Fonts - // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. - // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. - // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). - // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. - // - Read 'misc/fonts/README.txt' for more instructions and details. - // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! - //io.Fonts->AddFontDefault(); - //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); - //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); - //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); - //IM_ASSERT(font != NULL); - - uploadFonts() - } - - fun setupVulkan(extensions: ArrayList) { - - // Create Vulkan Instance - run { - val createInfo = vk.InstanceCreateInfo { enabledExtensionNames = extensions } - if (DEBUG_REPORT) { - // Enabling multiple validation layers grouped as LunarG standard validation - createInfo.enabledLayerNames = listOf("VK_LAYER_LUNARG_standard_validation") - - // Enable debug report extension - extensions += "VK_EXT_debug_report" - createInfo.enabledExtensionNames = extensions - - // Create Vulkan Instance - ImplVk.instance = vk.createInstance(createInfo) - - // Setup the debug report callback - val debugReportCi = vk.DebugReportCallbackCreateInfoEXT { - flags = VkDebugReport.ERROR_BIT_EXT or VkDebugReport.WARNING_BIT_EXT or VkDebugReport.PERFORMANCE_WARNING_BIT_EXT - callback = { _, objType, _, _, _, _, msg, _ -> - System.err.println("[vulkan] ObjectType: $objType\nMessage: $msg\n\n") - false - } - } - ImplVk.debugReport = ImplVk.instance createDebugReportCallbackEXT debugReportCi - - } else // Create Vulkan Instance without any debug feature - ImplVk.instance = vk.createInstance(createInfo) - } - - // Select GPU - run { - val gpus = ImplVk.instance.enumeratePhysicalDevices() - - /* If a number >1 of GPUs got reported, you should find the best fit GPU for your purpose - e.g. VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU if available, or with the greatest memory available, etc. - for sake of simplicity we'll just take the first one, assuming it has a graphics queue family. */ - ImplVk.physicalDevice = gpus[0] - } - - // Select graphics queue family - run { - val queues = ImplVk.physicalDevice.queueFamilyProperties - for (i in queues.indices) - if (queues[i].queueFlags has VkQueueFlag.GRAPHICS_BIT) { - ImplVk.queueFamily = i - break - } - assert(ImplVk.queueFamily != -1) - } - - // Create Logical Device (with 1 queue) - run { - val queueInfo = vk.DeviceQueueCreateInfo { - queueFamilyIndex = ImplVk.queueFamily - queuePriority = 1f - } - val createInfo = vk.DeviceCreateInfo { - queueCreateInfo = queueInfo - enabledExtensionNames = listOf("VK_KHR_swapchain") - } - ImplVk.device = ImplVk.physicalDevice createDevice createInfo - ImplVk.queue = ImplVk.device getQueue ImplVk.queueFamily - } - - // Create Descriptor Pool - run { - val poolSizes = vk.DescriptorPoolSize( - VkDescriptorType.SAMPLER, 1000, - VkDescriptorType.COMBINED_IMAGE_SAMPLER, 1000, - VkDescriptorType.SAMPLED_IMAGE, 1000, - VkDescriptorType.STORAGE_IMAGE, 1000, - VkDescriptorType.UNIFORM_TEXEL_BUFFER, 1000, - VkDescriptorType.STORAGE_TEXEL_BUFFER, 1000, - VkDescriptorType.UNIFORM_BUFFER, 1000, - VkDescriptorType.STORAGE_BUFFER, 1000, - VkDescriptorType.UNIFORM_BUFFER_DYNAMIC, 1000, - VkDescriptorType.STORAGE_BUFFER_DYNAMIC, 1000, - VkDescriptorType.INPUT_ATTACHMENT, 1000) - val poolInfo = vk.DescriptorPoolCreateInfo { - flags = VkDescriptorPoolCreate.FREE_DESCRIPTOR_SET_BIT.i - maxSets = 1000 * poolSizes.capacity() - this.poolSizes = poolSizes - } - ImplVk.descriptorPool = ImplVk.device createDescriptorPool poolInfo - } - } - - fun resizeCallback(size: Vec2i) { - resizeWanted = true - resizeSize put size - } - - fun setupVulkanWindowData(size: Vec2i) { - - // Check for WSI support - if (!ImplVk.physicalDevice.getSurfaceSupportKHR(ImplVk.queueFamily, wd.surface)) - throw Error("Error no WSI support on physical device 0") - - // Get Surface Format - val requestSurfaceImageFormat = arrayOf(VkFormat.B8G8R8A8_UNORM, VkFormat.R8G8B8A8_UNORM, VkFormat.B8G8R8_UNORM, VkFormat.R8G8B8_UNORM) - val requestSurfaceColorSpace = VkColorSpace.SRGB_NONLINEAR_KHR - wd.surfaceFormat = ImplVk.selectSurfaceFormat(ImplVk.physicalDevice, wd.surface, requestSurfaceImageFormat, requestSurfaceColorSpace) - - // Get Present Mode - val presentMode = when { - UNLIMITED_FRAME_RATE -> VkPresentMode.MAILBOX_KHR // VK_PRESENT_MODE_IMMEDIATE_KHR; - else -> VkPresentMode.FIFO_KHR - } - wd.presentMode = ImplVk.selectPresentMode(arrayOf(presentMode)) - - // Create SwapChain, RenderPass, Framebuffer, etc. - ImplVk.createWindowDataCommandBuffers() - ImplVk.createWindowDataSwapChainAndFramebuffer(size) - } - - fun uploadFonts() { - // Use any command queue - val commandPool = wd.frame.commandPool - val commandBuffer = wd.frame.commandBuffer - - ImplVk.device resetCommandPool commandPool - val beginInfo = vk.CommandBufferBeginInfo { - flags = flags or VkCommandBufferUsage.ONE_TIME_SUBMIT_BIT - } - commandBuffer begin beginInfo - - ImplVk.createFontsTexture(commandBuffer) - - val endInfo = vk.SubmitInfo { this.commandBuffer = commandBuffer } - commandBuffer.end() - ImplVk.queue submit endInfo - - ImplVk.device.waitIdle() - ImplVk.invalidateFontUploadObjects() - } - - var showDemoWindow = true - var showAnotherWindow = false - val clearColor = Vec4(0.45f, 0.55f, 0.6f, 1f) - var f = 0f - var counter = 0 - - fun run() { - // Main loop - // Poll and handle events (inputs, window resize, etc.) - // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. - // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. - // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. - // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. - LwjglGlfw.window.loop { - - if (resizeWanted) { - ImplVk.createWindowDataSwapChainAndFramebuffer(resizeSize) - resizeWanted = false - } - - // Start the ImGui frame - LwjglGlfw.newFrame() - - // 1. Show a simple window. - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets automatically appears in a window called "Debug". - ImGui.apply { - text("Hello, world!") // Display some text (you can use a format string too) - sliderFloat("float", ::f, 0f, 1f) // Edit 1 float using a slider from 0.0f to 1.0f - colorEdit3("clear color", clearColor) // Edit 3 floats representing a color (nb: you could use (float*)&wd->ClearValue instead) - - checkbox("Demo Window", this@HelloWorld_lwjgl::showDemoWindow) // Edit bools storing our windows open/close state - checkbox("Another Window", ::showAnotherWindow) - - if (button("Button")) // Buttons return true when clicked (NB: most widgets return true when edited/activated) - counter++ - sameLine() - text("counter = %d", counter) - - text("Application average %.3f ms/frame (%.1f FPS)", 1000f / io.framerate, io.framerate) - } - - // 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name your windows. - if (showAnotherWindow) - withWindow("Another Window", ::showAnotherWindow) { - text("Hello from another window!") - if (button("Close Me")) - showAnotherWindow = false - } - - // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). Read its code to learn more about Dear ImGui! - if (showDemoWindow) { - setNextWindowPos(Vec2(650, 20), Cond.FirstUseEver) // Normally user code doesn't need/want to call this because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! - showDemoWindow(::showDemoWindow) - } - - // Rendering - ImGui.render() - wd.clearValue.color(clearColor) - frameRender() - - framePresent() - } - - // Cleanup - ImplVk.device.waitIdle() - LwjglGlfw.shutdown() - ctx.destroy() - cleanupVulkan() - - window.destroy() - glfw.terminate() - } - - fun frameRender() { - - val imageAcquiredSemaphore = wd.frame.imageAcquiredSemaphore - wd.frameIndex = ImplVk.device.acquireNextImageKHR(wd.swapchain, UINT64_MAX, imageAcquiredSemaphore) - - val fd = wd.frame - ImplVk.device.apply { - waitForFence(fd.fence, true, UINT64_MAX) // wait indefinitely instead of periodically checking - resetFence(fd.fence) - } - run { - ImplVk.device.resetCommandPool(fd.commandPool) - fd.commandBuffer begin vk.CommandBufferBeginInfo { flags = flags or VkCommandBufferUsage.ONE_TIME_SUBMIT_BIT } - } - run { - val info = vk.RenderPassBeginInfo { - renderPass = wd.renderPass - framebuffer = wd.framebuffer[wd.frameIndex] - renderArea.extent(wd.size) - clearValue = wd.clearValue - } - fd.commandBuffer.beginRenderPass(info, VkSubpassContents.INLINE) - } - - // Record Imgui Draw Data and draw funcs into command buffer - ImplVk.renderDrawData(ImGui.drawData!!) - - // Submit command buffer - fd.commandBuffer.endRenderPass() - run { - val waitStage = appBuffer intBufferOf VkPipelineStage.COLOR_ATTACHMENT_OUTPUT_BIT.i - val info = vk.SubmitInfo { - waitSemaphoreCount = 1 - waitSemaphore = imageAcquiredSemaphore - waitDstStageMask = waitStage - commandBuffer = fd.commandBuffer - signalSemaphore = fd.renderCompleteSemaphore - } - fd.commandBuffer.end() - ImplVk.queue.submit(info, fd.fence) - } - } - - fun framePresent() { - val fd = wd.frame - val info = vk.PresentInfoKHR { -// waitSemaphore = fd.renderCompleteSemaphore - val pLong = appBuffer.long - MemoryUtil.memPutLong(pLong, fd.renderCompleteSemaphore) - MemoryUtil.memPutAddress(adr + VkPresentInfoKHR.PWAITSEMAPHORES, pLong) - VkPresentInfoKHR.nwaitSemaphoreCount(adr, 1) - swapchainCount = 1 - swapchain = ImplVk.wd.swapchain - imageIndex = wd.frameIndex - } - ImplVk.queue presentKHR info - } - - fun cleanupVulkan() { - ImplVk.destroyWindowData() - ImplVk.device destroyDescriptorPool ImplVk.descriptorPool - - if (DEBUG_REPORT) - // Remove the debug report callback - ImplVk.instance destroyDebugReportCallbackEXT ImplVk.debugReport - - ImplVk.device.destroy() - ImplVk.instance.destroy() - } -} - +//package imgui.vk +// +//import ab.appBuffer +//import glm_.vec2.Vec2 +//import glm_.vec2.Vec2i +//import glm_.vec4.Vec4 +//import imgui.Cond +//import imgui.Context +//import imgui.ImGui +//import imgui.ImGui.button +//import imgui.ImGui.setNextWindowPos +//import imgui.ImGui.showDemoWindow +//import imgui.ImGui.text +//import imgui.destroy +//import imgui.functionalProgramming.withWindow +//import imgui.impl.ImplVk +//import imgui.impl.LwjglGlfw +//import imgui.impl.LwjglGlfw.GlfwClientApi +//import imgui.impl.LwjglGlfw.window +//import org.lwjgl.system.MemoryUtil +//import org.lwjgl.vulkan.VkPresentInfoKHR +//import uno.glfw.GlfwWindow +//import uno.glfw.glfw +//import uno.glfw.windowHint.Api +//import vkk.* +// +//fun main(args: Array) { +// HelloWorld_lwjgl().run() +//} +// +//var DEBUG_REPORT = true +//var UNLIMITED_FRAME_RATE = false +// +//private class HelloWorld_lwjgl { +// +// var resizeWanted = false +// var resizeSize = Vec2i() +// +// val wd: ImplVk.WindowData +// get() = ImplVk.wd +// +// val ctx: Context +// +// init { +// // Setup window +// glfw.errorCallback = glfw.defaultErrorCallback +// glfw.init() +// +// glfw.windowHint { api = Api.None } +// val window = GlfwWindow(1280, 720, "ImGui GLFW+Vulkan example").apply { +// autoSwap = false // no swapBuffer with vk +// } +// +// // Setup Vulkan +// if (!glfw.vulkanSupported) +// throw Error("GLFW: Vulkan Not Supported") +// +// setupVulkan(glfw.requiredInstanceExtensions) +// +// // Create Window Surface +// wd.surface = window createSurface ImplVk.instance +// +// // Create Framebuffers +// val size = window.framebufferSize +// window.framebufferSizeCallback = ::resizeCallback +// setupVulkanWindowData(size) +// +// // Setup Dear ImGui binding +// ctx = Context() +// //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls +// //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls +// +// // Setup GLFW and Vulkan binding +// LwjglGlfw.init(window, true, GlfwClientApi.Vulkan) +// +// // Setup style +// ImGui.styleColorsDark() +// //ImGui.styleColorsClassic() +// +// // Load Fonts +// // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. +// // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. +// // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). +// // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. +// // - Read 'misc/fonts/README.txt' for more instructions and details. +// // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! +// //io.Fonts->AddFontDefault(); +// //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); +// //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); +// //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); +// //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); +// //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); +// //IM_ASSERT(font != NULL); +// +// uploadFonts() +// } +// +// fun setupVulkan(extensions: ArrayList) { +// +// // Create Vulkan Instance +// run { +// val createInfo = vk.InstanceCreateInfo { enabledExtensionNames = extensions } +// if (DEBUG_REPORT) { +// // Enabling multiple validation layers grouped as LunarG standard validation +// createInfo.enabledLayerNames = listOf("VK_LAYER_LUNARG_standard_validation") +// +// // Enable debug report extension +// extensions += "VK_EXT_debug_report" +// createInfo.enabledExtensionNames = extensions +// +// // Create Vulkan Instance +// ImplVk.instance = vk.createInstance(createInfo) +// +// // Setup the debug report callback +// val debugReportCi = vk.DebugReportCallbackCreateInfoEXT { +// flags = VkDebugReport.ERROR_BIT_EXT or VkDebugReport.WARNING_BIT_EXT or VkDebugReport.PERFORMANCE_WARNING_BIT_EXT +// callback = { _, objType, _, _, _, _, msg, _ -> +// System.err.println("[vulkan] ObjectType: $objType\nMessage: $msg\n\n") +// false +// } +// } +// ImplVk.debugReport = ImplVk.instance createDebugReportCallbackEXT debugReportCi +// +// } else // Create Vulkan Instance without any debug feature +// ImplVk.instance = vk.createInstance(createInfo) +// } +// +// // Select GPU +// run { +// val gpus = ImplVk.instance.enumeratePhysicalDevices() +// +// /* If a number >1 of GPUs got reported, you should find the best fit GPU for your purpose +// e.g. VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU if available, or with the greatest memory available, etc. +// for sake of simplicity we'll just take the first one, assuming it has a graphics queue family. */ +// ImplVk.physicalDevice = gpus[0] +// } +// +// // Select graphics queue family +// run { +// val queues = ImplVk.physicalDevice.queueFamilyProperties +// for (i in queues.indices) +// if (queues[i].queueFlags has VkQueueFlag.GRAPHICS_BIT) { +// ImplVk.queueFamily = i +// break +// } +// assert(ImplVk.queueFamily != -1) +// } +// +// // Create Logical Device (with 1 queue) +// run { +// val queueInfo = vk.DeviceQueueCreateInfo { +// queueFamilyIndex = ImplVk.queueFamily +// queuePriority = 1f +// } +// val createInfo = vk.DeviceCreateInfo { +// queueCreateInfo = queueInfo +// enabledExtensionNames = listOf("VK_KHR_swapchain") +// } +// ImplVk.device = ImplVk.physicalDevice createDevice createInfo +// ImplVk.queue = ImplVk.device getQueue ImplVk.queueFamily +// } +// +// // Create Descriptor Pool +// run { +// val poolSizes = vk.DescriptorPoolSize( +// VkDescriptorType.SAMPLER, 1000, +// VkDescriptorType.COMBINED_IMAGE_SAMPLER, 1000, +// VkDescriptorType.SAMPLED_IMAGE, 1000, +// VkDescriptorType.STORAGE_IMAGE, 1000, +// VkDescriptorType.UNIFORM_TEXEL_BUFFER, 1000, +// VkDescriptorType.STORAGE_TEXEL_BUFFER, 1000, +// VkDescriptorType.UNIFORM_BUFFER, 1000, +// VkDescriptorType.STORAGE_BUFFER, 1000, +// VkDescriptorType.UNIFORM_BUFFER_DYNAMIC, 1000, +// VkDescriptorType.STORAGE_BUFFER_DYNAMIC, 1000, +// VkDescriptorType.INPUT_ATTACHMENT, 1000) +// val poolInfo = vk.DescriptorPoolCreateInfo { +// flags = VkDescriptorPoolCreate.FREE_DESCRIPTOR_SET_BIT.i +// maxSets = 1000 * poolSizes.capacity() +// this.poolSizes = poolSizes +// } +// ImplVk.descriptorPool = ImplVk.device createDescriptorPool poolInfo +// } +// } +// +// fun resizeCallback(size: Vec2i) { +// resizeWanted = true +// resizeSize put size +// } +// +// fun setupVulkanWindowData(size: Vec2i) { +// +// // Check for WSI support +// if (!ImplVk.physicalDevice.getSurfaceSupportKHR(ImplVk.queueFamily, wd.surface)) +// throw Error("Error no WSI support on physical device 0") +// +// // Get Surface Format +// val requestSurfaceImageFormat = arrayOf(VkFormat.B8G8R8A8_UNORM, VkFormat.R8G8B8A8_UNORM, VkFormat.B8G8R8_UNORM, VkFormat.R8G8B8_UNORM) +// val requestSurfaceColorSpace = VkColorSpace.SRGB_NONLINEAR_KHR +// wd.surfaceFormat = ImplVk.selectSurfaceFormat(ImplVk.physicalDevice, wd.surface, requestSurfaceImageFormat, requestSurfaceColorSpace) +// +// // Get Present Mode +// val presentMode = when { +// UNLIMITED_FRAME_RATE -> VkPresentMode.MAILBOX_KHR // VK_PRESENT_MODE_IMMEDIATE_KHR; +// else -> VkPresentMode.FIFO_KHR +// } +// wd.presentMode = ImplVk.selectPresentMode(arrayOf(presentMode)) +// +// // Create SwapChain, RenderPass, Framebuffer, etc. +// ImplVk.createWindowDataCommandBuffers() +// ImplVk.createWindowDataSwapChainAndFramebuffer(size) +// } +// +// fun uploadFonts() { +// // Use any command queue +// val commandPool = wd.frame.commandPool +// val commandBuffer = wd.frame.commandBuffer +// +// ImplVk.device resetCommandPool commandPool +// val beginInfo = vk.CommandBufferBeginInfo { +// flags = flags or VkCommandBufferUsage.ONE_TIME_SUBMIT_BIT +// } +// commandBuffer begin beginInfo +// +// ImplVk.createFontsTexture(commandBuffer) +// +// val endInfo = vk.SubmitInfo { this.commandBuffer = commandBuffer } +// commandBuffer.end() +// ImplVk.queue submit endInfo +// +// ImplVk.device.waitIdle() +// ImplVk.invalidateFontUploadObjects() +// } +// +// var showDemoWindow = true +// var showAnotherWindow = false +// val clearColor = Vec4(0.45f, 0.55f, 0.6f, 1f) +// var f = 0f +// var counter = 0 +// +// fun run() { +// // Main loop +// // Poll and handle events (inputs, window resize, etc.) +// // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. +// // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. +// // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. +// // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. +// LwjglGlfw.window.loop { +// +// if (resizeWanted) { +// ImplVk.createWindowDataSwapChainAndFramebuffer(resizeSize) +// resizeWanted = false +// } +// +// // Start the ImGui frame +// LwjglGlfw.newFrame() +// +// // 1. Show a simple window. +// // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets automatically appears in a window called "Debug". +// ImGui.apply { +// text("Hello, world!") // Display some text (you can use a format string too) +// sliderFloat("float", ::f, 0f, 1f) // Edit 1 float using a slider from 0.0f to 1.0f +// colorEdit3("clear color", clearColor) // Edit 3 floats representing a color (nb: you could use (float*)&wd->ClearValue instead) +// +// checkbox("Demo Window", this@HelloWorld_lwjgl::showDemoWindow) // Edit bools storing our windows open/close state +// checkbox("Another Window", ::showAnotherWindow) +// +// if (button("Button")) // Buttons return true when clicked (NB: most widgets return true when edited/activated) +// counter++ +// sameLine() +// text("counter = %d", counter) +// +// text("Application average %.3f ms/frame (%.1f FPS)", 1000f / io.framerate, io.framerate) +// } +// +// // 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name your windows. +// if (showAnotherWindow) +// withWindow("Another Window", ::showAnotherWindow) { +// text("Hello from another window!") +// if (button("Close Me")) +// showAnotherWindow = false +// } +// +// // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). Read its code to learn more about Dear ImGui! +// if (showDemoWindow) { +// setNextWindowPos(Vec2(650, 20), Cond.FirstUseEver) // Normally user code doesn't need/want to call this because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! +// showDemoWindow(::showDemoWindow) +// } +// +// // Rendering +// ImGui.render() +// wd.clearValue.color(clearColor) +// frameRender() +// +// framePresent() +// } +// +// // Cleanup +// ImplVk.device.waitIdle() +// LwjglGlfw.shutdown() +// ctx.destroy() +// cleanupVulkan() +// +// window.destroy() +// glfw.terminate() +// } +// +// fun frameRender() { +// +// val imageAcquiredSemaphore = wd.frame.imageAcquiredSemaphore +// wd.frameIndex = ImplVk.device.acquireNextImageKHR(wd.swapchain, UINT64_MAX, imageAcquiredSemaphore) +// +// val fd = wd.frame +// ImplVk.device.apply { +// waitForFence(fd.fence, true, UINT64_MAX) // wait indefinitely instead of periodically checking +// resetFence(fd.fence) +// } +// run { +// ImplVk.device.resetCommandPool(fd.commandPool) +// fd.commandBuffer begin vk.CommandBufferBeginInfo { flags = flags or VkCommandBufferUsage.ONE_TIME_SUBMIT_BIT } +// } +// run { +// val info = vk.RenderPassBeginInfo { +// renderPass = wd.renderPass +// framebuffer = wd.framebuffer[wd.frameIndex] +// renderArea.extent(wd.size) +// clearValue = wd.clearValue +// } +// fd.commandBuffer.beginRenderPass(info, VkSubpassContents.INLINE) +// } +// +// // Record Imgui Draw Data and draw funcs into command buffer +// ImplVk.renderDrawData(ImGui.drawData!!) +// +// // Submit command buffer +// fd.commandBuffer.endRenderPass() +// run { +// val waitStage = appBuffer intBufferOf VkPipelineStage.COLOR_ATTACHMENT_OUTPUT_BIT.i +// val info = vk.SubmitInfo { +// waitSemaphoreCount = 1 +// waitSemaphore = imageAcquiredSemaphore +// waitDstStageMask = waitStage +// commandBuffer = fd.commandBuffer +// signalSemaphore = fd.renderCompleteSemaphore +// } +// fd.commandBuffer.end() +// ImplVk.queue.submit(info, fd.fence) +// } +// } +// +// fun framePresent() { +// val fd = wd.frame +// val info = vk.PresentInfoKHR { +//// waitSemaphore = fd.renderCompleteSemaphore +// val pLong = appBuffer.long +// MemoryUtil.memPutLong(pLong, fd.renderCompleteSemaphore) +// MemoryUtil.memPutAddress(adr + VkPresentInfoKHR.PWAITSEMAPHORES, pLong) +// VkPresentInfoKHR.nwaitSemaphoreCount(adr, 1) +// swapchainCount = 1 +// swapchain = ImplVk.wd.swapchain +// imageIndex = wd.frameIndex +// } +// ImplVk.queue presentKHR info +// } +// +// fun cleanupVulkan() { +// ImplVk.destroyWindowData() +// ImplVk.device destroyDescriptorPool ImplVk.descriptorPool +// +// if (DEBUG_REPORT) +// // Remove the debug report callback +// ImplVk.instance destroyDebugReportCallbackEXT ImplVk.debugReport +// +// ImplVk.device.destroy() +// ImplVk.instance.destroy() +// } +//} +//