diff --git a/src/main/java/com/github/hydos/ginger/VulkanStarter.java b/src/main/java/com/github/hydos/ginger/VulkanStarter.java index e85842e..f6406a6 100644 --- a/src/main/java/com/github/hydos/ginger/VulkanStarter.java +++ b/src/main/java/com/github/hydos/ginger/VulkanStarter.java @@ -21,7 +21,6 @@ import static org.lwjgl.system.MemoryUtil.memAllocPointer; import static org.lwjgl.system.MemoryUtil.memByteBuffer; import static org.lwjgl.system.MemoryUtil.memCopy; import static org.lwjgl.system.MemoryUtil.memFree; -import static org.lwjgl.system.MemoryUtil.memUTF8; import static org.lwjgl.vulkan.EXTDebugReport.VK_DEBUG_REPORT_ERROR_BIT_EXT; import static org.lwjgl.vulkan.EXTDebugReport.VK_DEBUG_REPORT_WARNING_BIT_EXT; import static org.lwjgl.vulkan.EXTDebugReport.vkDestroyDebugReportCallbackEXT; @@ -46,7 +45,6 @@ import static org.lwjgl.vulkan.VK10.VK_ATTACHMENT_LOAD_OP_CLEAR; import static org.lwjgl.vulkan.VK10.VK_ATTACHMENT_LOAD_OP_DONT_CARE; import static org.lwjgl.vulkan.VK10.VK_ATTACHMENT_STORE_OP_DONT_CARE; import static org.lwjgl.vulkan.VK10.VK_ATTACHMENT_STORE_OP_STORE; -import static org.lwjgl.vulkan.VK10.VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; import static org.lwjgl.vulkan.VK10.VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; import static org.lwjgl.vulkan.VK10.VK_COMMAND_BUFFER_LEVEL_PRIMARY; import static org.lwjgl.vulkan.VK10.VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; @@ -92,7 +90,6 @@ import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; -import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; @@ -165,7 +162,6 @@ import org.lwjgl.vulkan.VkMemoryAllocateInfo; import org.lwjgl.vulkan.VkMemoryRequirements; import org.lwjgl.vulkan.VkPhysicalDevice; import org.lwjgl.vulkan.VkPhysicalDeviceMemoryProperties; -import org.lwjgl.vulkan.VkPipelineShaderStageCreateInfo; import org.lwjgl.vulkan.VkPipelineVertexInputStateCreateInfo; import org.lwjgl.vulkan.VkPresentInfoKHR; import org.lwjgl.vulkan.VkQueue; @@ -184,8 +180,10 @@ import org.lwjgl.vulkan.VkWriteDescriptorSet; import com.github.hydos.ginger.engine.common.info.RenderAPI; import com.github.hydos.ginger.engine.common.io.Window; import com.github.hydos.ginger.engine.vulkan.VKConstants; +import com.github.hydos.ginger.engine.vulkan.memory.VKMemory; +import com.github.hydos.ginger.engine.vulkan.render.ubo.Ubo; +import com.github.hydos.ginger.engine.vulkan.render.ubo.UboDescriptor; import com.github.hydos.ginger.engine.vulkan.shaders.Pipeline; -import com.github.hydos.ginger.engine.vulkan.shaders.VKShaderManager; import com.github.hydos.ginger.engine.vulkan.utils.VKDeviceProperties; import com.github.hydos.ginger.engine.vulkan.utils.VKLoader; import com.github.hydos.ginger.engine.vulkan.utils.VKUtils; @@ -534,7 +532,7 @@ public class VulkanStarter vkGetImageMemoryRequirements(device, depthStencilImage, memReqs); mem_alloc.allocationSize(memReqs.size()); IntBuffer pMemoryTypeIndex = memAllocInt(1); - getMemoryType(physicalDeviceMemoryProperties, memReqs.memoryTypeBits(), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, pMemoryTypeIndex); + VKMemory.getMemoryType(physicalDeviceMemoryProperties, memReqs.memoryTypeBits(), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, pMemoryTypeIndex); mem_alloc.memoryTypeIndex(pMemoryTypeIndex.get(0)); memFree(pMemoryTypeIndex); LongBuffer pDepthStencilMem = memAllocLong(1); @@ -657,24 +655,6 @@ public class VulkanStarter { throw new AssertionError("Failed to submit command buffer: " + VKUtils.translateVulkanResult(err)); } } - private static boolean getMemoryType(VkPhysicalDeviceMemoryProperties deviceMemoryProperties, int typeBits, int properties, IntBuffer typeIndex) - { - int bits = typeBits; - for (int i = 0; i < 32; i++) - { - if ((bits & 1) == 1) - { - if ((deviceMemoryProperties.memoryTypes(i).propertyFlags() & properties) == properties) - { - typeIndex.put(0, i); - return true; - } - } - bits >>= 1; - } - return false; - } - private static class Vertices { long verticesBuf; @@ -713,7 +693,7 @@ public class VulkanStarter vkGetBufferMemoryRequirements(device, verticesBuf, memReqs); memAlloc.allocationSize(memReqs.size()); IntBuffer memoryTypeIndex = memAllocInt(1); - getMemoryType(deviceMemoryProperties, memReqs.memoryTypeBits(), VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, memoryTypeIndex); + VKMemory.getMemoryType(deviceMemoryProperties, memReqs.memoryTypeBits(), VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, memoryTypeIndex); memAlloc.memoryTypeIndex(memoryTypeIndex.get(0)); memFree(memoryTypeIndex); memReqs.free(); @@ -798,65 +778,6 @@ public class VulkanStarter return descriptorPool; } - private static class UboDescriptor - { - long memory; - long buffer; - long offset; - long range; - } - - private static UboDescriptor createUniformBuffer(VkPhysicalDeviceMemoryProperties deviceMemoryProperties, VkDevice device) - { - int err; - // Create a new buffer - VkBufferCreateInfo bufferInfo = VkBufferCreateInfo.calloc() - .sType(VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO) - .size(16 * 4) - .usage(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); - LongBuffer pUniformDataVSBuffer = memAllocLong(1); - err = vkCreateBuffer(device, bufferInfo, null, pUniformDataVSBuffer); - long uniformDataVSBuffer = pUniformDataVSBuffer.get(0); - memFree(pUniformDataVSBuffer); - bufferInfo.free(); - if (err != VK_SUCCESS) - { throw new AssertionError("Failed to create UBO buffer: " + VKUtils.translateVulkanResult(err)); } - // Get memory requirements including size, alignment and memory type - VkMemoryRequirements memReqs = VkMemoryRequirements.calloc(); - vkGetBufferMemoryRequirements(device, uniformDataVSBuffer, memReqs); - long memSize = memReqs.size(); - int memoryTypeBits = memReqs.memoryTypeBits(); - memReqs.free(); - // Gets the appropriate memory type for this type of buffer allocation - // Only memory types that are visible to the host - IntBuffer pMemoryTypeIndex = memAllocInt(1); - getMemoryType(deviceMemoryProperties, memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, pMemoryTypeIndex); - int memoryTypeIndex = pMemoryTypeIndex.get(0); - memFree(pMemoryTypeIndex); - // Allocate memory for the uniform buffer - LongBuffer pUniformDataVSMemory = memAllocLong(1); - VkMemoryAllocateInfo allocInfo = VkMemoryAllocateInfo.calloc() - .sType(VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO) - .allocationSize(memSize) - .memoryTypeIndex(memoryTypeIndex); - err = vkAllocateMemory(device, allocInfo, null, pUniformDataVSMemory); - long uniformDataVSMemory = pUniformDataVSMemory.get(0); - memFree(pUniformDataVSMemory); - allocInfo.free(); - if (err != VK_SUCCESS) - { throw new AssertionError("Failed to allocate UBO memory: " + VKUtils.translateVulkanResult(err)); } - // Bind memory to buffer - err = vkBindBufferMemory(device, uniformDataVSBuffer, uniformDataVSMemory, 0); - if (err != VK_SUCCESS) - { throw new AssertionError("Failed to bind UBO memory: " + VKUtils.translateVulkanResult(err)); } - UboDescriptor ret = new UboDescriptor(); - ret.memory = uniformDataVSMemory; - ret.buffer = uniformDataVSBuffer; - ret.offset = 0L; - ret.range = 16 * 4; - return ret; - } - private static long createDescriptorSet(VkDevice device, long descriptorPool, long descriptorSetLayout, UboDescriptor uniformDataVSDescriptor) { LongBuffer pDescriptorSetLayout = memAllocLong(1); @@ -918,26 +839,6 @@ public class VulkanStarter return descriptorSetLayout; } - private static void updateUbo(VkDevice device, UboDescriptor ubo, float angle) - { //a UBO is a uniform buffer object - Matrix4f m = new Matrix4f() - .scale(1, -1, 1) // <- correcting viewport transformation (what Direct3D does, too) - .perspective((float) Math.toRadians(45.0f), (float) Window.getWidth() / Window.getHeight(), 0.1f, 10.0f, true) - .lookAt(0, 1, 3, - 0, 0, 0, - 0, 1, 0) - .rotateY(angle); - PointerBuffer pData = memAllocPointer(1); - int err = vkMapMemory(device, ubo.memory, 0, 16 * 4, 0, pData); - long data = pData.get(0); - memFree(pData); - if (err != VK_SUCCESS) - { throw new AssertionError("Failed to map UBO memory: " + VKUtils.translateVulkanResult(err)); } - ByteBuffer matrixBuffer = memByteBuffer(data, 16 * 4); - m.get(matrixBuffer); - vkUnmapMemory(device, ubo.memory); - } - /* * All resources that must be reallocated on window resize. */ @@ -986,10 +887,10 @@ public class VulkanStarter final long renderPass = createRenderPass(device, colorAndDepthFormatAndSpace.colorFormat, colorAndDepthFormatAndSpace.depthFormat); final long renderCommandPool = createCommandPool(device, queueFamilyIndex); Vertices vertices = createVertices(memoryProperties, device); - UboDescriptor uboDescriptor = createUniformBuffer(memoryProperties, device); + Ubo ubo = new Ubo(memoryProperties, device); final long descriptorPool = createDescriptorPool(device); final long descriptorSetLayout = createDescriptorSetLayout(device); - final long descriptorSet = createDescriptorSet(device, descriptorPool, descriptorSetLayout, uboDescriptor); + final long descriptorSet = createDescriptorSet(device, descriptorPool, descriptorSetLayout, ubo.uboData); final Pipeline pipeline = Pipeline.createPipeline(device, renderPass, vertices.createInfo, descriptorSetLayout); final class SwapchainRecreator { @@ -1098,7 +999,7 @@ public class VulkanStarter long thisTime = System.nanoTime(); time += (thisTime - lastTime) / 1E9f; lastTime = thisTime; - updateUbo(device, uboDescriptor, time); + ubo.updateUbo(device, time); // Submit to the graphics queue err = vkQueueSubmit(queue, submitInfo, VK_NULL_HANDLE); if (err != VK_SUCCESS) diff --git a/src/main/java/com/github/hydos/ginger/engine/vulkan/memory/VKMemory.java b/src/main/java/com/github/hydos/ginger/engine/vulkan/memory/VKMemory.java new file mode 100644 index 0000000..4d1d0fd --- /dev/null +++ b/src/main/java/com/github/hydos/ginger/engine/vulkan/memory/VKMemory.java @@ -0,0 +1,28 @@ +package com.github.hydos.ginger.engine.vulkan.memory; + +import java.nio.IntBuffer; + +import org.lwjgl.vulkan.VkPhysicalDeviceMemoryProperties; + +public class VKMemory { + + public static boolean getMemoryType(VkPhysicalDeviceMemoryProperties deviceMemoryProperties, int typeBits, int properties, IntBuffer typeIndex) + { + int bits = typeBits; + for (int i = 0; i < 32; i++) + { + if ((bits & 1) == 1) + { + if ((deviceMemoryProperties.memoryTypes(i).propertyFlags() & properties) == properties) + { + typeIndex.put(0, i); + return true; + } + } + bits >>= 1; + } + return false; + } + + +} diff --git a/src/main/java/com/github/hydos/ginger/engine/vulkan/render/ubo/Ubo.java b/src/main/java/com/github/hydos/ginger/engine/vulkan/render/ubo/Ubo.java new file mode 100644 index 0000000..317d1fb --- /dev/null +++ b/src/main/java/com/github/hydos/ginger/engine/vulkan/render/ubo/Ubo.java @@ -0,0 +1,116 @@ +package com.github.hydos.ginger.engine.vulkan.render.ubo; + +import static org.lwjgl.system.MemoryUtil.memAllocInt; +import static org.lwjgl.system.MemoryUtil.memAllocLong; +import static org.lwjgl.system.MemoryUtil.memAllocPointer; +import static org.lwjgl.system.MemoryUtil.memByteBuffer; +import static org.lwjgl.system.MemoryUtil.memFree; +import static org.lwjgl.vulkan.VK10.VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; +import static org.lwjgl.vulkan.VK10.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; +import static org.lwjgl.vulkan.VK10.VK_SUCCESS; +import static org.lwjgl.vulkan.VK10.vkAllocateMemory; +import static org.lwjgl.vulkan.VK10.vkBindBufferMemory; +import static org.lwjgl.vulkan.VK10.vkCreateBuffer; +import static org.lwjgl.vulkan.VK10.vkGetBufferMemoryRequirements; +import static org.lwjgl.vulkan.VK10.vkMapMemory; +import static org.lwjgl.vulkan.VK10.vkUnmapMemory; + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import java.nio.LongBuffer; + +import org.joml.Matrix4f; +import org.lwjgl.PointerBuffer; +import org.lwjgl.vulkan.VkBufferCreateInfo; +import org.lwjgl.vulkan.VkDevice; +import org.lwjgl.vulkan.VkMemoryAllocateInfo; +import org.lwjgl.vulkan.VkMemoryRequirements; +import org.lwjgl.vulkan.VkPhysicalDeviceMemoryProperties; + +import com.github.hydos.ginger.engine.common.io.Window; +import com.github.hydos.ginger.engine.vulkan.memory.VKMemory; +import com.github.hydos.ginger.engine.vulkan.utils.VKUtils; +/** + * A UBO is a uniform buffer object + * i believe its used to give data from code to the shaders + * @author hydos + * + */ +public class Ubo { + + public UboDescriptor uboData; + + public Ubo(VkPhysicalDeviceMemoryProperties deviceMemoryProperties, VkDevice device) + { + int err; + // Create a new buffer + VkBufferCreateInfo bufferInfo = VkBufferCreateInfo.calloc() + .sType(VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO) + .size(16 * 4) + .usage(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + LongBuffer pUniformDataVSBuffer = memAllocLong(1); + err = vkCreateBuffer(device, bufferInfo, null, pUniformDataVSBuffer); + long uniformDataVSBuffer = pUniformDataVSBuffer.get(0); + memFree(pUniformDataVSBuffer); + bufferInfo.free(); + if (err != VK_SUCCESS) + { throw new AssertionError("Failed to create UBO buffer: " + VKUtils.translateVulkanResult(err)); } + // Get memory requirements including size, alignment and memory type + VkMemoryRequirements memReqs = VkMemoryRequirements.calloc(); + vkGetBufferMemoryRequirements(device, uniformDataVSBuffer, memReqs); + long memSize = memReqs.size(); + int memoryTypeBits = memReqs.memoryTypeBits(); + memReqs.free(); + // Gets the appropriate memory type for this type of buffer allocation + // Only memory types that are visible to the host + IntBuffer pMemoryTypeIndex = memAllocInt(1); + VKMemory.getMemoryType(deviceMemoryProperties, memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, pMemoryTypeIndex); + int memoryTypeIndex = pMemoryTypeIndex.get(0); + memFree(pMemoryTypeIndex); + // Allocate memory for the uniform buffer + LongBuffer pUniformDataVSMemory = memAllocLong(1); + VkMemoryAllocateInfo allocInfo = VkMemoryAllocateInfo.calloc() + .sType(VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO) + .allocationSize(memSize) + .memoryTypeIndex(memoryTypeIndex); + err = vkAllocateMemory(device, allocInfo, null, pUniformDataVSMemory); + long uniformDataVSMemory = pUniformDataVSMemory.get(0); + memFree(pUniformDataVSMemory); + allocInfo.free(); + if (err != VK_SUCCESS) + { throw new AssertionError("Failed to allocate UBO memory: " + VKUtils.translateVulkanResult(err)); } + // Bind memory to buffer + err = vkBindBufferMemory(device, uniformDataVSBuffer, uniformDataVSMemory, 0); + if (err != VK_SUCCESS) + { throw new AssertionError("Failed to bind UBO memory: " + VKUtils.translateVulkanResult(err)); } + UboDescriptor ret = new UboDescriptor(); + ret.memory = uniformDataVSMemory; + ret.buffer = uniformDataVSBuffer; + ret.offset = 0L; + ret.range = 16 * 4; + this.uboData = ret; + } + + public void updateUbo(VkDevice device, float angle) + { + Matrix4f m = new Matrix4f() + .scale(1, -1, 1) // <- correcting viewport transformation (what Direct3D does, too) + .perspective((float) Math.toRadians(45.0f), (float) Window.getWidth() / Window.getHeight(), 0.1f, 10.0f, true) + .lookAt(0, 1, 3, + 0, 0, 0, + 0, 1, 0) + .rotateY(angle); + PointerBuffer pData = memAllocPointer(1); + int err = vkMapMemory(device, uboData.memory, 0, 16 * 4, 0, pData); + long data = pData.get(0); + memFree(pData); + if (err != VK_SUCCESS) + { throw new AssertionError("Failed to map UBO memory: " + VKUtils.translateVulkanResult(err)); } + ByteBuffer matrixBuffer = memByteBuffer(data, 16 * 4); + m.get(matrixBuffer); + vkUnmapMemory(device, uboData.memory); + } + +} diff --git a/src/main/java/com/github/hydos/ginger/engine/vulkan/render/ubo/UboDescriptor.java b/src/main/java/com/github/hydos/ginger/engine/vulkan/render/ubo/UboDescriptor.java new file mode 100644 index 0000000..83f0ee0 --- /dev/null +++ b/src/main/java/com/github/hydos/ginger/engine/vulkan/render/ubo/UboDescriptor.java @@ -0,0 +1,9 @@ +package com.github.hydos.ginger.engine.vulkan.render.ubo; + +public class UboDescriptor +{ + public long memory; //Memory location + public long buffer; //the Buffer? + public long offset; //some offset from the memory location + public long range; // the size +} \ No newline at end of file