# HG changeset patch # User John Tsiombikas # Date 1529902857 -10800 # Node ID d34f84bede17c98825889fc0b8d36e02c48b4146 # Parent e17abe477616f5bb00dd2b45f6c563cbbf48af4d pipeline madness diff -r e17abe477616 -r d34f84bede17 src/main.c --- a/src/main.c Sat Jun 23 07:47:49 2018 +0300 +++ b/src/main.c Mon Jun 25 08:00:57 2018 +0300 @@ -1,12 +1,16 @@ #include #include "wsys.h" #include "vku.h" +#include "vkpipe.h" #include "vkgl.h" static void display(void); static void reshape(int x, int y); static void keyboard(int key, int pressed); +static struct vku_pipeline pipeline; +static VkShaderModule vsdr, psdr; + int main(void) { if(vku_create_dev() == -1) { @@ -22,6 +26,23 @@ wsys_reshape_callback(reshape); wsys_keyboard_callback(keyboard); + wsys_process_events(WSYS_NONBLOCK); + + if(!(vsdr = vku_load_shader("sdr/vertex.spv")) || + !(psdr = vku_load_shader("sdr/pixel.spv"))) { + return 1; + } + + vku_init_pipeline(&pipeline); + vku_pipeline_shader(&pipeline, vsdr, VK_SHADER_STAGE_VERTEX_BIT); + vku_pipeline_shader(&pipeline, psdr, VK_SHADER_STAGE_FRAGMENT_BIT); + vku_pipeline_viewport(&pipeline, 0, 0, 800, 600); + vku_pipeline_renderpass(&pipeline, vkrpass); + if(!vku_create_pipeline(&pipeline)) { + return 1; + } + + while(wsys_process_events(WSYS_BLOCKING) != -1); wsys_destroy_window(); diff -r e17abe477616 -r d34f84bede17 src/vkpipe.c --- a/src/vkpipe.c Sat Jun 23 07:47:49 2018 +0300 +++ b/src/vkpipe.c Mon Jun 25 08:00:57 2018 +0300 @@ -5,7 +5,7 @@ #include "vkpipe.h" #include "vku.h" -int vku_init_pstate(struct vku_pstate *st) +int vku_init_pipeline(struct vku_pipeline *st) { int i; @@ -21,7 +21,7 @@ st->msaa.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; st->zstencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; st->blend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - st->layout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + st->lay.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; st->vport.pViewports = &st->vport_data; st->vport.pScissors = &st->scissor_data; @@ -35,18 +35,18 @@ st->blend.pAttachments = &st->atblend; /* set some reasonable defaults (just the non-zero ones) */ - vku_pstate_primitive(st, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); - vku_pstate_polygon_mode(st, VK_POLYGON_MODE_FILL); - vku_pstate_line_width(st, 1.0f); - vku_pstate_front_face(st, VK_FRONT_FACE_COUNTER_CLOCKWISE); + vku_pipeline_primitive(st, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); + vku_pipeline_polygon_mode(st, VK_POLYGON_MODE_FILL); + vku_pipeline_line_width(st, 1.0f); + vku_pipeline_front_face(st, VK_FRONT_FACE_COUNTER_CLOCKWISE); return 0; } -void vku_pstate_shader(struct vku_pstate *st, VkShaderModule sdr, VkShaderStageFlagBits type) +void vku_pipeline_shader(struct vku_pipeline *st, VkShaderModule sdr, VkShaderStageFlagBits type) { if(st->num_sdr_stages >= VKU_MAX_SDR_STAGES) { - fprintf(stderr, "vku_pstate_shader: too many shaders\n"); + fprintf(stderr, "vku_pipeline_shader: too many shaders\n"); abort(); } @@ -56,12 +56,12 @@ ++st->num_sdr_stages; } -void vku_pstate_primitive(struct vku_pstate *st, VkPrimitiveTopology prim) +void vku_pipeline_primitive(struct vku_pipeline *st, VkPrimitiveTopology prim) { st->inpasm.topology = prim; } -void vku_pstate_viewport(struct vku_pstate *st, int x, int y, int w, int h) +void vku_pipeline_viewport(struct vku_pipeline *st, int x, int y, int w, int h) { st->vport_data.x = x; st->vport_data.y = y; @@ -69,7 +69,7 @@ st->vport_data.height = h; } -void vku_pstate_scissor(struct vku_pstate *st, int x, int y, int w, int h) +void vku_pipeline_scissor(struct vku_pipeline *st, int x, int y, int w, int h) { st->scissor_data.offset.x = x; st->scissor_data.offset.y = y; @@ -77,27 +77,27 @@ st->scissor_data.extent.height = h; } -void vku_pstate_polygon_mode(struct vku_pstate *st, VkPolygonMode pmode) +void vku_pipeline_polygon_mode(struct vku_pipeline *st, VkPolygonMode pmode) { st->rast.polygonMode = pmode; } -void vku_pstate_line_width(struct vku_pstate *st, float w) +void vku_pipeline_line_width(struct vku_pipeline *st, float w) { st->rast.lineWidth = w; } -void vku_pstate_cull_mode(struct vku_pstate *st, VkCullModeFlagBits cull) +void vku_pipeline_cull_mode(struct vku_pipeline *st, VkCullModeFlagBits cull) { st->rast.cullMode = cull; } -void vku_pstate_front_face(struct vku_pstate *st, VkFrontFace front) +void vku_pipeline_front_face(struct vku_pipeline *st, VkFrontFace front) { st->rast.frontFace = front; } -void vku_pstate_depth_bias(struct vku_pstate *st, float fslope, float fconst, float clamp) +void vku_pipeline_depth_bias(struct vku_pipeline *st, float fslope, float fconst, float clamp) { st->rast.depthBiasEnable = VK_TRUE; st->rast.depthBiasSlopeFactor = fslope; @@ -105,46 +105,46 @@ st->rast.depthBiasClamp = clamp; } -void vku_pstate_depth_test(struct vku_pstate *st, int enable) +void vku_pipeline_depth_test(struct vku_pipeline *st, int enable) { st->zstencil.depthTestEnable = enable ? VK_TRUE : VK_FALSE; } -void vku_pstate_depth_func(struct vku_pstate *st, VkCompareOp op) +void vku_pipeline_depth_func(struct vku_pipeline *st, VkCompareOp op) { st->zstencil.depthCompareOp = op; } -void vku_pstate_depth_mask(struct vku_pstate *st, int zmask) +void vku_pipeline_depth_mask(struct vku_pipeline *st, int zmask) { st->zstencil.depthWriteEnable = zmask ? VK_TRUE : VK_FALSE; } -void vku_pstate_stencil_test(struct vku_pstate *st, int enable) +void vku_pipeline_stencil_test(struct vku_pipeline *st, int enable) { st->zstencil.stencilTestEnable = enable ? VK_TRUE : VK_FALSE; } -void vku_pstate_stencil_func(struct vku_pstate *st, VkCompareOp op, int ref, unsigned int mask) +void vku_pipeline_stencil_func(struct vku_pipeline *st, VkCompareOp op, int ref, unsigned int mask) { st->zstencil.front.compareOp = st->zstencil.back.compareOp = op; st->zstencil.front.reference = st->zstencil.back.reference = ref; st->zstencil.front.writeMask = st->zstencil.back.compareMask = mask; } -void vku_pstate_stencil_op(struct vku_pstate *st, VkStencilOp sfail, VkStencilOp dfail, VkStencilOp pass) +void vku_pipeline_stencil_op(struct vku_pipeline *st, VkStencilOp sfail, VkStencilOp dfail, VkStencilOp pass) { st->zstencil.front.failOp = st->zstencil.back.failOp = sfail; st->zstencil.front.depthFailOp = st->zstencil.back.depthFailOp = dfail; st->zstencil.front.passOp = st->zstencil.back.passOp = pass; } -void vku_pstate_stencil_mask(struct vku_pstate *st, unsigned int smask) +void vku_pipeline_stencil_mask(struct vku_pipeline *st, unsigned int smask) { st->zstencil.front.writeMask = st->zstencil.back.writeMask = smask; } -void vku_pstate_color_mask(struct vku_pstate *st, int rmask, int gmask, int bmask, int amask) +void vku_pipeline_color_mask(struct vku_pipeline *st, int rmask, int gmask, int bmask, int amask) { unsigned int mask = 0; @@ -156,12 +156,12 @@ st->atblend.colorWriteMask = mask; } -void vku_pstate_blend_enable(struct vku_pstate *st, int enable) +void vku_pipeline_blend_enable(struct vku_pipeline *st, int enable) { st->atblend.blendEnable = enable ? VK_TRUE : VK_FALSE; } -void vku_pstate_blend_func(struct vku_pstate *st, VkBlendFactor src, VkBlendFactor dst) +void vku_pipeline_blend_func(struct vku_pipeline *st, VkBlendFactor src, VkBlendFactor dst) { st->atblend.srcColorBlendFactor = src; st->atblend.dstColorBlendFactor = dst; @@ -171,10 +171,52 @@ st->atblend.alphaBlendOp = VK_BLEND_OP_ADD; } +void vku_pipeline_renderpass(struct vku_pipeline *st, VkRenderPass rpass) +{ + st->rpass = rpass; +} -VkPipeline vku_create_pipeline(struct vku_pstate *st) + +VkPipeline vku_create_pipeline(struct vku_pipeline *st) { - return 0; /* TODO */ + VkGraphicsPipelineCreateInfo pinf; + + if(vkCreatePipelineLayout(vkdev, &st->lay, 0, &st->layout) != 0) { + fprintf(stderr, "vku_create_pipeline: failed to create layout\n"); + return 0; + } + + memset(&pinf, 0, sizeof pinf); + pinf.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pinf.stageCount = st->num_sdr_stages; + pinf.pStages = st->sdrstage; + pinf.pVertexInputState = &st->vertinp; + pinf.pInputAssemblyState = &st->inpasm; + pinf.pViewportState = &st->vport; + pinf.pRasterizationState = &st->rast; + pinf.pMultisampleState = &st->msaa; + //pinf.pDepthStencilState = &st->zstencil; + pinf.pColorBlendState = &st->blend; + + pinf.layout = st->layout; + pinf.renderPass = st->rpass; + + if(vkCreateGraphicsPipelines(vkdev, 0, 1, &pinf, 0, &st->pipeline) != 0) { + fprintf(stderr, "vku_create_pipeline failed\n"); + vkDestroyPipelineLayout(vkdev, st->layout, 0); + return 0; + } + return st->pipeline; +} + +void vku_destroy_pipeline(struct vku_pipeline *p) +{ + if(p->layout) { + vkDestroyPipelineLayout(vkdev, p->layout, 0); + } + if(p->pipeline) { + vkDestroyPipeline(vkdev, p->pipeline, 0); + } } VkShaderModule vku_load_shader(const char *fname) diff -r e17abe477616 -r d34f84bede17 src/vkpipe.h --- a/src/vkpipe.h Sat Jun 23 07:47:49 2018 +0300 +++ b/src/vkpipe.h Mon Jun 25 08:00:57 2018 +0300 @@ -5,7 +5,7 @@ #define VKU_MAX_SDR_STAGES 8 -struct vku_pstate { +struct vku_pipeline { VkPipelineShaderStageCreateInfo sdrstage[VKU_MAX_SDR_STAGES]; int num_sdr_stages; VkPipelineVertexInputStateCreateInfo vertinp; @@ -16,7 +16,11 @@ VkPipelineDepthStencilStateCreateInfo zstencil; VkPipelineColorBlendStateCreateInfo blend; /*VkPipelineDynamicStateCreateInfo dyn;*/ - VkPipelineLayoutCreateInfo layout; + VkPipelineLayoutCreateInfo lay; + + VkRenderPass rpass; + VkPipeline pipeline; + VkPipelineLayout layout; /* data needed by the structs above */ VkViewport vport_data; @@ -24,28 +28,30 @@ VkPipelineColorBlendAttachmentState atblend; }; -int vku_init_pstate(struct vku_pstate *st); -void vku_pstate_shader(struct vku_pstate *st, VkShaderModule sdr, VkShaderStageFlagBits type); -void vku_pstate_primitive(struct vku_pstate *st, VkPrimitiveTopology prim); -void vku_pstate_viewport(struct vku_pstate *st, int x, int y, int w, int h); -void vku_pstate_scissor(struct vku_pstate *st, int x, int y, int w, int h); -void vku_pstate_polygon_mode(struct vku_pstate *st, VkPolygonMode pmode); -void vku_pstate_line_width(struct vku_pstate *st, float w); -void vku_pstate_cull_mode(struct vku_pstate *st, VkCullModeFlagBits cull); -void vku_pstate_front_face(struct vku_pstate *st, VkFrontFace front); -void vku_pstate_depth_bias(struct vku_pstate *st, float fslope, float fconst, float clamp); -void vku_pstate_depth_test(struct vku_pstate *st, int enable); -void vku_pstate_depth_func(struct vku_pstate *st, VkCompareOp op); -void vku_pstate_depth_mask(struct vku_pstate *st, int zmask); -void vku_pstate_stencil_test(struct vku_pstate *st, int enable); -void vku_pstate_stencil_func(struct vku_pstate *st, VkCompareOp op, int ref, unsigned int mask); -void vku_pstate_stencil_op(struct vku_pstate *st, VkStencilOp sfail, VkStencilOp dfail, VkStencilOp pass); -void vku_pstate_stencil_mask(struct vku_pstate *st, unsigned int smask); -void vku_pstate_color_mask(struct vku_pstate *st, int rmask, int gmask, int bmask, int amask); -void vku_pstate_blend_enable(struct vku_pstate *st, int enable); -void vku_pstate_blend_func(struct vku_pstate *st, VkBlendFactor src, VkBlendFactor dst); +int vku_init_pipeline(struct vku_pipeline *st); +void vku_pipeline_shader(struct vku_pipeline *st, VkShaderModule sdr, VkShaderStageFlagBits type); +void vku_pipeline_primitive(struct vku_pipeline *st, VkPrimitiveTopology prim); +void vku_pipeline_viewport(struct vku_pipeline *st, int x, int y, int w, int h); +void vku_pipeline_scissor(struct vku_pipeline *st, int x, int y, int w, int h); +void vku_pipeline_polygon_mode(struct vku_pipeline *st, VkPolygonMode pmode); +void vku_pipeline_line_width(struct vku_pipeline *st, float w); +void vku_pipeline_cull_mode(struct vku_pipeline *st, VkCullModeFlagBits cull); +void vku_pipeline_front_face(struct vku_pipeline *st, VkFrontFace front); +void vku_pipeline_depth_bias(struct vku_pipeline *st, float fslope, float fconst, float clamp); +void vku_pipeline_depth_test(struct vku_pipeline *st, int enable); +void vku_pipeline_depth_func(struct vku_pipeline *st, VkCompareOp op); +void vku_pipeline_depth_mask(struct vku_pipeline *st, int zmask); +void vku_pipeline_stencil_test(struct vku_pipeline *st, int enable); +void vku_pipeline_stencil_func(struct vku_pipeline *st, VkCompareOp op, int ref, unsigned int mask); +void vku_pipeline_stencil_op(struct vku_pipeline *st, VkStencilOp sfail, VkStencilOp dfail, VkStencilOp pass); +void vku_pipeline_stencil_mask(struct vku_pipeline *st, unsigned int smask); +void vku_pipeline_color_mask(struct vku_pipeline *st, int rmask, int gmask, int bmask, int amask); +void vku_pipeline_blend_enable(struct vku_pipeline *st, int enable); +void vku_pipeline_blend_func(struct vku_pipeline *st, VkBlendFactor src, VkBlendFactor dst); +void vku_pipeline_renderpass(struct vku_pipeline *st, VkRenderPass rpass); -VkPipeline vku_create_pipeline(struct vku_pstate *st); +VkPipeline vku_create_pipeline(struct vku_pipeline *st); +void vku_destroy_pipeline(struct vku_pipeline *p); VkShaderModule vku_load_shader(const char *fname); void vku_destroy_shader(VkShaderModule sdr); diff -r e17abe477616 -r d34f84bede17 src/vku.c --- a/src/vku.c Sat Jun 23 07:47:49 2018 +0300 +++ b/src/vku.c Mon Jun 25 08:00:57 2018 +0300 @@ -426,8 +426,70 @@ } +VkRenderPass vku_create_renderpass(VkFormat cfmt, VkFormat dsfmt) +{ + int count = 1; /* always assume we have a color attachment for now */ + VkAttachmentDescription at[2]; + VkAttachmentReference colref, dsref; + VkSubpassDescription subpass; + VkRenderPass pass; + VkRenderPassCreateInfo rpinf; + + colref.attachment = 0; + colref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + dsref.attachment = 1; + dsref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + + memset(&subpass, 0, sizeof subpass); + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.colorAttachmentCount = 1; + subpass.pColorAttachments = &colref; + + at[0].format = cfmt; + at[0].samples = VK_SAMPLE_COUNT_1_BIT; /* TODO multisampling */ + at[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + at[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; + at[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + at[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + at[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + at[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + + if(dsfmt != VK_FORMAT_UNDEFINED) { + at[1].format = dsfmt; + at[1].samples = VK_SAMPLE_COUNT_1_BIT; + at[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + at[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE; + at[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + at[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; + at[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + at[1].finalLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + subpass.pDepthStencilAttachment = &dsref; + count++; + } + + memset(&rpinf, 0, sizeof rpinf); + rpinf.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + rpinf.attachmentCount = count; + rpinf.pAttachments = at; + rpinf.subpassCount = 1; + rpinf.pSubpasses = &subpass; + + if(vkCreateRenderPass(vkdev, &rpinf, 0, &pass) != 0) { + fprintf(stderr, "vku_create_renderpass: failed to create renderpass\n"); + return 0; + } + + return pass; +} + +void vku_destroy_renderpass(VkRenderPass rpass) +{ + vkDestroyRenderPass(vkdev, rpass, 0); +} + + #ifdef VK_USE_PLATFORM_XLIB_KHR - int vku_xlib_usable_visual(Display *dpy, VisualID vid) { return vkGetPhysicalDeviceXlibPresentationSupportKHR(phys_devices[sel_dev], diff -r e17abe477616 -r d34f84bede17 src/vku.h --- a/src/vku.h Sat Jun 23 07:47:49 2018 +0300 +++ b/src/vku.h Mon Jun 25 08:00:57 2018 +0300 @@ -17,6 +17,7 @@ int next_swapchain_image; VkViewport vkvport; +VkRenderPass vkrpass; struct vku_buffer { @@ -52,6 +53,9 @@ void vku_cmd_copybuf(VkCommandBuffer cmdbuf, VkBuffer dest, int doffs, VkBuffer src, int soffs, int size); +VkRenderPass vku_create_renderpass(VkFormat cfmt, VkFormat dsfmt); +void vku_destroy_renderpass(VkRenderPass rpass); + /* platform-specific */ #ifdef VK_USE_PLATFORM_XLIB_KHR #include diff -r e17abe477616 -r d34f84bede17 src/wsys_x11.c --- a/src/wsys_x11.c Sat Jun 23 07:47:49 2018 +0300 +++ b/src/wsys_x11.c Mon Jun 25 08:00:57 2018 +0300 @@ -228,6 +228,12 @@ swapchain_images = vku_get_swapchain_images(sc, 0); next_swapchain_image = vku_get_next_image(swapchain); + if(!vkrpass) { + if(!(vkrpass = vku_create_renderpass(VK_FORMAT_R8G8B8_UNORM, VK_FORMAT_UNDEFINED))) { + abort(); + } + } + if(cb.reshape) { cb.reshape(win_width, win_height); }