Vulkan surface, this is what displays an image to the screen, working on queues next
This commit is contained in:
parent
6717970a23
commit
934f949881
2 changed files with 149 additions and 4 deletions
|
|
@ -1,25 +1,33 @@
|
||||||
package net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers;
|
package net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers;
|
||||||
|
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||||
import org.lwjgl.PointerBuffer;
|
import org.lwjgl.PointerBuffer;
|
||||||
import org.lwjgl.system.MemoryStack;
|
import org.lwjgl.system.MemoryStack;
|
||||||
import org.lwjgl.vulkan.VkDevice;
|
import org.lwjgl.vulkan.VkDevice;
|
||||||
import org.lwjgl.vulkan.VkDeviceCreateInfo;
|
import org.lwjgl.vulkan.VkDeviceCreateInfo;
|
||||||
import org.lwjgl.vulkan.VkDeviceQueueCreateInfo;
|
import org.lwjgl.vulkan.VkDeviceQueueCreateInfo;
|
||||||
|
import org.lwjgl.vulkan.VkExtensionProperties;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import static net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils.vkCheck;
|
import static net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils.vkCheck;
|
||||||
import static org.lwjgl.vulkan.VK10.vkCreateDevice;
|
import static org.lwjgl.vulkan.KHRPortabilitySubset.VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME;
|
||||||
|
import static org.lwjgl.vulkan.VK10.*;
|
||||||
|
|
||||||
public class Device {
|
public class Device {
|
||||||
VkDevice VulkanDevice;
|
private final VkDevice VulkanDevice;
|
||||||
|
|
||||||
public Device(PhysicalDevice PhysDevice){
|
public Device(PhysicalDevice PhysDevice){
|
||||||
PointerBuffer RequiredExtensions = null; // to be finished later
|
|
||||||
|
|
||||||
Logger.debug("Creating Device Interface Layer");
|
Logger.debug("Creating Device Interface Layer");
|
||||||
try (var MemStack = MemoryStack.stackPush()) {
|
try (var MemStack = MemoryStack.stackPush()) {
|
||||||
|
PointerBuffer RequiredExtensions = CreateRequiredExtensions(PhysDevice, MemStack);
|
||||||
var QueuePropertyBuffer = PhysDevice.GetQueueFamilyProperties();
|
var QueuePropertyBuffer = PhysDevice.GetQueueFamilyProperties();
|
||||||
int QueueFamilyCount = QueuePropertyBuffer.capacity();
|
int QueueFamilyCount = QueuePropertyBuffer.capacity();
|
||||||
var QueueCreationInfoBuffer = VkDeviceQueueCreateInfo.calloc(QueueFamilyCount, MemStack);
|
var QueueCreationInfoBuffer = VkDeviceQueueCreateInfo.calloc(QueueFamilyCount, MemStack);
|
||||||
|
|
@ -39,6 +47,62 @@ public class Device {
|
||||||
VulkanDevice = new VkDevice(pp.get(0), PhysDevice.GetPhysicalDevice(), DeviceCreateInfo);
|
VulkanDevice = new VkDevice(pp.get(0), PhysDevice.GetPhysicalDevice(), DeviceCreateInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static PointerBuffer CreateRequiredExtensions(PhysicalDevice PhysDevice, MemoryStack MemStack){
|
||||||
|
Set<String> DeviceExtensions = GetDeviceExtensions(PhysDevice);
|
||||||
|
//cross platform support for that fuckass Metal API mac uses
|
||||||
|
boolean UsePortability = DeviceExtensions.contains(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME) && VulkanUtils.getOS() == VulkanUtils.OSType.MACOS;
|
||||||
|
|
||||||
|
var ExtentionList = new ArrayList<ByteBuffer>();
|
||||||
|
for(String Extension : PhysicalDevice.REQUIRED_EXTENSIONS){
|
||||||
|
ExtentionList.add(MemStack.ASCII(Extension));
|
||||||
|
}
|
||||||
|
if (UsePortability){
|
||||||
|
ExtentionList.add(MemStack.ASCII(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME));
|
||||||
|
}
|
||||||
|
|
||||||
|
PointerBuffer RequiredExtensions = MemStack.mallocPointer(ExtentionList.size());
|
||||||
|
ExtentionList.forEach(RequiredExtensions::put);
|
||||||
|
RequiredExtensions.flip();
|
||||||
|
|
||||||
|
return RequiredExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Set<String> GetDeviceExtensions(PhysicalDevice PhysDevice){
|
||||||
|
Set<String> DeviceExtensions = new HashSet<>();
|
||||||
|
try(var MemStack = MemoryStack.stackPush()){
|
||||||
|
IntBuffer ExtensionsBufferCount = MemStack.callocInt(1);
|
||||||
|
vkEnumerateDeviceExtensionProperties(PhysDevice.GetPhysicalDevice(),(String) null, ExtensionsBufferCount, null);
|
||||||
|
int ExtensionCount = ExtensionsBufferCount.get(0);
|
||||||
|
Logger.trace("Device supports [{}] number of extensions", ExtensionCount);
|
||||||
|
|
||||||
|
try(var PropertiesBuffer = VkExtensionProperties.calloc(ExtensionCount)){
|
||||||
|
vkEnumerateDeviceExtensionProperties(PhysDevice.GetPhysicalDevice(), (String) null, ExtensionsBufferCount,PropertiesBuffer);
|
||||||
|
for(int i = 0; i < ExtensionCount; i++){
|
||||||
|
VkExtensionProperties Properties = PropertiesBuffer.get(i);
|
||||||
|
String ExtensionName = Properties.extensionNameString();
|
||||||
|
DeviceExtensions.add(ExtensionName);
|
||||||
|
Logger.trace("[{}] is a supported extension", ExtensionCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DeviceExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cleanup(){
|
||||||
|
Logger.debug("Removing Vulkan Device");
|
||||||
|
vkDestroyDevice(VulkanDevice,null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public VkDevice FetchVulkanDevice()
|
||||||
|
{
|
||||||
|
return VulkanDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void waitIdle(){
|
||||||
|
vkDeviceWaitIdle(VulkanDevice);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,85 @@
|
||||||
package net.halbear.Terrain4J.EngineCore.Vulkan.Structure;
|
package net.halbear.Terrain4J.EngineCore.Vulkan.Structure;
|
||||||
|
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Display.Window;
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.PhysicalDevice;
|
||||||
|
import org.lwjgl.glfw.GLFWVulkan;
|
||||||
|
import org.lwjgl.system.MemoryStack;
|
||||||
|
import org.lwjgl.vulkan.KHRSurface;
|
||||||
|
import org.lwjgl.vulkan.VkSurfaceCapabilitiesKHR;
|
||||||
|
import org.lwjgl.vulkan.VkSurfaceFormatKHR;
|
||||||
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
import java.nio.LongBuffer;
|
||||||
|
|
||||||
|
import static net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils.vkCheck;
|
||||||
|
import static org.lwjgl.vulkan.VK10.VK_FORMAT_B8G8R8A8_SRGB;
|
||||||
|
|
||||||
public class Surface {
|
public class Surface {
|
||||||
|
private final VkSurfaceCapabilitiesKHR SurfaceCapabilities;
|
||||||
|
private final SurfaceFormat SurfaceFormatVar;
|
||||||
|
private final long VulkanSurface;
|
||||||
|
|
||||||
|
public record SurfaceFormat(int ImageFormat, int ColourSpace){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Surface(VulkanInstance VkInstance, PhysicalDevice PhysDevice, Window window){
|
||||||
|
Logger.debug("Creating Vulkan Surface");
|
||||||
|
try(var MemStack = MemoryStack.stackPush()){
|
||||||
|
LongBuffer SurfacePtr = MemStack.mallocLong(1);
|
||||||
|
GLFWVulkan.glfwCreateWindowSurface(VkInstance.getVkInstance(), window.getHandle(), null, SurfacePtr);
|
||||||
|
VulkanSurface = SurfacePtr.get(0);
|
||||||
|
|
||||||
|
SurfaceCapabilities = VkSurfaceCapabilitiesKHR.calloc();
|
||||||
|
vkCheck(KHRSurface.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(PhysDevice.GetPhysicalDevice(), VulkanSurface,SurfaceCapabilities),"Failed to get surface capabilities");
|
||||||
|
|
||||||
|
SurfaceFormatVar = CalculateSurfaceFormat(PhysDevice, VulkanSurface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SurfaceFormat CalculateSurfaceFormat(PhysicalDevice PhysDevice, long VulkanSurface){
|
||||||
|
int ImageFormat;
|
||||||
|
int ColourSpace ;
|
||||||
|
try(var MemStack = MemoryStack.stackPush()){
|
||||||
|
IntBuffer IntPointer = MemStack.mallocInt(1);
|
||||||
|
vkCheck(KHRSurface.vkGetPhysicalDeviceSurfaceFormatsKHR(PhysDevice.GetPhysicalDevice(), VulkanSurface, IntPointer, null),"Failed to get number of surface formats");
|
||||||
|
int SurfaceFormatCount = IntPointer.get(0);
|
||||||
|
if (SurfaceFormatCount <= 0){
|
||||||
|
throw new RuntimeException("Vulkan Error: Unable to locate and surface formats");
|
||||||
|
}
|
||||||
|
|
||||||
|
var SurfaceFormats = VkSurfaceFormatKHR.calloc(SurfaceFormatCount, MemStack);
|
||||||
|
vkCheck(KHRSurface.vkGetPhysicalDeviceSurfaceFormatsKHR(PhysDevice.GetPhysicalDevice(),VulkanSurface, IntPointer, SurfaceFormats), "Failed to get surface formats");
|
||||||
|
|
||||||
|
ImageFormat = VK_FORMAT_B8G8R8A8_SRGB;
|
||||||
|
ColourSpace = SurfaceFormats.get(0).colorSpace();
|
||||||
|
for(int i = 0; i < SurfaceFormatCount; i++){
|
||||||
|
VkSurfaceFormatKHR SurfaceFormatKHR = SurfaceFormats.get(i);
|
||||||
|
if (SurfaceFormatKHR.format() == VK_FORMAT_B8G8R8A8_SRGB && SurfaceFormatKHR.colorSpace() == KHRSurface.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR){
|
||||||
|
ImageFormat = SurfaceFormatKHR.format();
|
||||||
|
ColourSpace = SurfaceFormatKHR.colorSpace();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new SurfaceFormat(ImageFormat, ColourSpace);
|
||||||
|
}
|
||||||
|
public void cleanup(VulkanInstance instance){
|
||||||
|
Logger.debug("Cleaning Up Surfaces");
|
||||||
|
SurfaceCapabilities.free();
|
||||||
|
KHRSurface.vkDestroySurfaceKHR(instance.getVkInstance(), VulkanSurface, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public VkSurfaceCapabilitiesKHR GetSurfaceCapabilities(){
|
||||||
|
return SurfaceCapabilities;
|
||||||
|
}
|
||||||
|
public SurfaceFormat GetSurfaceFormat(){
|
||||||
|
return SurfaceFormatVar;
|
||||||
|
}
|
||||||
|
public long GetVkSurface(){
|
||||||
|
return VulkanSurface;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue