212 lines
11 KiB
Java
212 lines
11 KiB
Java
package com.github.hydos.ginger.engine.vulkan.render.pipelines;
|
|
|
|
import static org.lwjgl.system.MemoryStack.stackPush;
|
|
import static org.lwjgl.vulkan.VK10.VK_COLOR_COMPONENT_A_BIT;
|
|
import static org.lwjgl.vulkan.VK10.VK_COLOR_COMPONENT_B_BIT;
|
|
import static org.lwjgl.vulkan.VK10.VK_COLOR_COMPONENT_G_BIT;
|
|
import static org.lwjgl.vulkan.VK10.VK_COLOR_COMPONENT_R_BIT;
|
|
import static org.lwjgl.vulkan.VK10.VK_COMPARE_OP_LESS;
|
|
import static org.lwjgl.vulkan.VK10.VK_CULL_MODE_BACK_BIT;
|
|
import static org.lwjgl.vulkan.VK10.VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
|
import static org.lwjgl.vulkan.VK10.VK_LOGIC_OP_COPY;
|
|
import static org.lwjgl.vulkan.VK10.VK_NULL_HANDLE;
|
|
import static org.lwjgl.vulkan.VK10.VK_POLYGON_MODE_FILL;
|
|
import static org.lwjgl.vulkan.VK10.VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
|
import static org.lwjgl.vulkan.VK10.VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
import static org.lwjgl.vulkan.VK10.VK_SHADER_STAGE_VERTEX_BIT;
|
|
import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
|
import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
|
import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
|
import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
|
import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
|
import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
|
import static org.lwjgl.vulkan.VK10.VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_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_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
|
import static org.lwjgl.vulkan.VK10.VK_SUCCESS;
|
|
import static org.lwjgl.vulkan.VK10.vkCreateGraphicsPipelines;
|
|
import static org.lwjgl.vulkan.VK10.vkCreatePipelineLayout;
|
|
import static org.lwjgl.vulkan.VK10.vkDestroyShaderModule;
|
|
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.LongBuffer;
|
|
|
|
import org.lwjgl.system.MemoryStack;
|
|
import org.lwjgl.vulkan.VkGraphicsPipelineCreateInfo;
|
|
import org.lwjgl.vulkan.VkOffset2D;
|
|
import org.lwjgl.vulkan.VkPipelineColorBlendAttachmentState;
|
|
import org.lwjgl.vulkan.VkPipelineColorBlendStateCreateInfo;
|
|
import org.lwjgl.vulkan.VkPipelineDepthStencilStateCreateInfo;
|
|
import org.lwjgl.vulkan.VkPipelineInputAssemblyStateCreateInfo;
|
|
import org.lwjgl.vulkan.VkPipelineLayoutCreateInfo;
|
|
import org.lwjgl.vulkan.VkPipelineMultisampleStateCreateInfo;
|
|
import org.lwjgl.vulkan.VkPipelineRasterizationStateCreateInfo;
|
|
import org.lwjgl.vulkan.VkPipelineShaderStageCreateInfo;
|
|
import org.lwjgl.vulkan.VkPipelineVertexInputStateCreateInfo;
|
|
import org.lwjgl.vulkan.VkPipelineViewportStateCreateInfo;
|
|
import org.lwjgl.vulkan.VkRect2D;
|
|
import org.lwjgl.vulkan.VkViewport;
|
|
|
|
import com.github.hydos.ginger.engine.vulkan.VKVariables;
|
|
import com.github.hydos.ginger.engine.vulkan.model.VKVertex;
|
|
import com.github.hydos.ginger.engine.vulkan.shaders.VKShaderManager;
|
|
import com.github.hydos.ginger.engine.vulkan.shaders.VKShaderUtils;
|
|
import com.github.hydos.ginger.engine.vulkan.shaders.VKShaderUtils.SPIRV;
|
|
|
|
public class VKPipelineManager
|
|
{
|
|
|
|
public static void createGraphicsPipeline() {
|
|
|
|
try(MemoryStack stack = stackPush()) {
|
|
SPIRV vertShaderSPIRV = VKShaderUtils.compileShaderFile("vulkan/shaders/entity.vert", VKShaderUtils.ShaderType.VERTEX_SHADER);
|
|
SPIRV fragShaderSPIRV = VKShaderUtils.compileShaderFile("vulkan/shaders/entity.frag", VKShaderUtils.ShaderType.FRAGMENT_SHADER);
|
|
|
|
long vertShaderModule = VKShaderManager.createShaderModule(vertShaderSPIRV.bytecode());
|
|
long fragShaderModule = VKShaderManager.createShaderModule(fragShaderSPIRV.bytecode());
|
|
|
|
ByteBuffer entryPoint = stack.UTF8("main");
|
|
|
|
VkPipelineShaderStageCreateInfo.Buffer shaderStages = VkPipelineShaderStageCreateInfo.callocStack(2, stack);
|
|
|
|
VkPipelineShaderStageCreateInfo vertShaderStageInfo = shaderStages.get(0);
|
|
|
|
vertShaderStageInfo.sType(VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO);
|
|
vertShaderStageInfo.stage(VK_SHADER_STAGE_VERTEX_BIT);
|
|
vertShaderStageInfo.module(vertShaderModule);
|
|
vertShaderStageInfo.pName(entryPoint);
|
|
|
|
VkPipelineShaderStageCreateInfo fragShaderStageInfo = shaderStages.get(1);
|
|
|
|
fragShaderStageInfo.sType(VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO);
|
|
fragShaderStageInfo.stage(VK_SHADER_STAGE_FRAGMENT_BIT);
|
|
fragShaderStageInfo.module(fragShaderModule);
|
|
fragShaderStageInfo.pName(entryPoint);
|
|
|
|
// VERTEX STAGE
|
|
|
|
VkPipelineVertexInputStateCreateInfo vertexInputInfo = VkPipelineVertexInputStateCreateInfo.callocStack(stack);
|
|
vertexInputInfo.sType(VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO);
|
|
vertexInputInfo.pVertexBindingDescriptions(VKVertex.getBindingDescription());
|
|
vertexInputInfo.pVertexAttributeDescriptions(VKVertex.getAttributeDescriptions());
|
|
|
|
// ASSEMBLY STAGE
|
|
|
|
VkPipelineInputAssemblyStateCreateInfo inputAssembly = VkPipelineInputAssemblyStateCreateInfo.callocStack(stack);
|
|
inputAssembly.sType(VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO);
|
|
inputAssembly.topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
|
|
inputAssembly.primitiveRestartEnable(false);
|
|
|
|
// VIEWPORT & SCISSOR
|
|
|
|
VkViewport.Buffer viewport = VkViewport.callocStack(1, stack);
|
|
viewport.x(0.0f);
|
|
viewport.y(0.0f);
|
|
viewport.width(VKVariables .swapChainExtent.width());
|
|
viewport.height(VKVariables.swapChainExtent.height());
|
|
viewport.minDepth(0.0f);
|
|
viewport.maxDepth(1.0f);
|
|
|
|
VkRect2D.Buffer scissor = VkRect2D.callocStack(1, stack);
|
|
scissor.offset(VkOffset2D.callocStack(stack).set(0, 0));
|
|
scissor.extent(VKVariables.swapChainExtent);
|
|
|
|
VkPipelineViewportStateCreateInfo viewportState = VkPipelineViewportStateCreateInfo.callocStack(stack);
|
|
viewportState.sType(VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO);
|
|
viewportState.pViewports(viewport);
|
|
viewportState.pScissors(scissor);
|
|
|
|
// RASTERIZATION STAGE
|
|
|
|
VkPipelineRasterizationStateCreateInfo rasterizer = VkPipelineRasterizationStateCreateInfo.callocStack(stack);
|
|
rasterizer.sType(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO);
|
|
rasterizer.depthClampEnable(false);
|
|
rasterizer.rasterizerDiscardEnable(false);
|
|
rasterizer.polygonMode(VK_POLYGON_MODE_FILL);
|
|
rasterizer.lineWidth(1.0f);
|
|
rasterizer.cullMode(VK_CULL_MODE_BACK_BIT);
|
|
rasterizer.frontFace(VK_FRONT_FACE_COUNTER_CLOCKWISE);
|
|
rasterizer.depthBiasEnable(false);
|
|
|
|
// MULTISAMPLING
|
|
|
|
VkPipelineMultisampleStateCreateInfo multisampling = VkPipelineMultisampleStateCreateInfo.callocStack(stack);
|
|
multisampling.sType(VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO);
|
|
multisampling.sampleShadingEnable(true);
|
|
multisampling.minSampleShading(0.2f); // Enable sample shading in the pipeline
|
|
multisampling.rasterizationSamples(VKVariables.msaaSamples); // Min fraction for sample shading; closer to one is smoother
|
|
|
|
VkPipelineDepthStencilStateCreateInfo depthStencil = VkPipelineDepthStencilStateCreateInfo.callocStack(stack);
|
|
depthStencil.sType(VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO);
|
|
depthStencil.depthTestEnable(true);
|
|
depthStencil.depthWriteEnable(true);
|
|
depthStencil.depthCompareOp(VK_COMPARE_OP_LESS);
|
|
depthStencil.depthBoundsTestEnable(false);
|
|
depthStencil.minDepthBounds(0.0f);
|
|
depthStencil.maxDepthBounds(1.0f);
|
|
depthStencil.stencilTestEnable(false);
|
|
|
|
// COLOR BLENDING
|
|
|
|
VkPipelineColorBlendAttachmentState.Buffer colorBlendAttachment = VkPipelineColorBlendAttachmentState.callocStack(1, stack);
|
|
colorBlendAttachment.colorWriteMask(VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);
|
|
colorBlendAttachment.blendEnable(false);
|
|
|
|
VkPipelineColorBlendStateCreateInfo colorBlending = VkPipelineColorBlendStateCreateInfo.callocStack(stack);
|
|
colorBlending.sType(VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO);
|
|
colorBlending.logicOpEnable(false);
|
|
colorBlending.logicOp(VK_LOGIC_OP_COPY);
|
|
colorBlending.pAttachments(colorBlendAttachment);
|
|
colorBlending.blendConstants(stack.floats(0.0f, 0.0f, 0.0f, 0.0f));
|
|
|
|
// PIPELINE LAYOUT CREATION
|
|
|
|
VkPipelineLayoutCreateInfo pipelineLayoutInfo = VkPipelineLayoutCreateInfo.callocStack(stack);
|
|
pipelineLayoutInfo.sType(VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO);
|
|
pipelineLayoutInfo.pSetLayouts(stack.longs(VKVariables.descriptorSetLayout));
|
|
|
|
LongBuffer pPipelineLayout = stack.longs(VK_NULL_HANDLE);
|
|
|
|
if(vkCreatePipelineLayout(VKVariables.device, pipelineLayoutInfo, null, pPipelineLayout) != VK_SUCCESS) {
|
|
throw new RuntimeException("Failed to create pipeline layout");
|
|
}
|
|
|
|
VKVariables.pipelineLayout = pPipelineLayout.get(0);
|
|
|
|
VkGraphicsPipelineCreateInfo.Buffer pipelineInfo = VkGraphicsPipelineCreateInfo.callocStack(1, stack);
|
|
pipelineInfo.sType(VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO);
|
|
pipelineInfo.pStages(shaderStages);
|
|
pipelineInfo.pVertexInputState(vertexInputInfo);
|
|
pipelineInfo.pInputAssemblyState(inputAssembly);
|
|
pipelineInfo.pViewportState(viewportState);
|
|
pipelineInfo.pRasterizationState(rasterizer);
|
|
pipelineInfo.pMultisampleState(multisampling);
|
|
pipelineInfo.pDepthStencilState(depthStencil);
|
|
pipelineInfo.pColorBlendState(colorBlending);
|
|
pipelineInfo.layout(VKVariables.pipelineLayout);
|
|
pipelineInfo.renderPass(VKVariables.renderPass);
|
|
pipelineInfo.subpass(0);
|
|
pipelineInfo.basePipelineHandle(VK_NULL_HANDLE);
|
|
pipelineInfo.basePipelineIndex(-1);
|
|
|
|
LongBuffer pGraphicsPipeline = stack.mallocLong(1);
|
|
|
|
if(vkCreateGraphicsPipelines(VKVariables.device, VK_NULL_HANDLE, pipelineInfo, null, pGraphicsPipeline) != VK_SUCCESS) {
|
|
throw new RuntimeException("Failed to create graphics pipeline");
|
|
}
|
|
|
|
VKVariables.graphicsPipeline = pGraphicsPipeline.get(0);
|
|
|
|
// Cleanup
|
|
|
|
vkDestroyShaderModule(VKVariables.device, vertShaderModule, null);
|
|
vkDestroyShaderModule(VKVariables.device, fragShaderModule, null);
|
|
|
|
vertShaderSPIRV.free();
|
|
fragShaderSPIRV.free();
|
|
}
|
|
}
|
|
|
|
}
|