pipeline construction?
authorJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 10 Jan 2023 04:01:29 +0000 (06:01 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 10 Jan 2023 04:01:29 +0000 (06:01 +0200)
src/vk.c
src/vk.h

index a22b7a3..8b12108 100644 (file)
--- a/src/vk.c
+++ b/src/vk.c
@@ -45,14 +45,17 @@ struct framebuf {
 
 struct pipeline {
        int used;
-       int vport[4], scissor[4];
+       VkViewport vport;
+       VkRect2D scissor;
        VkShaderModule sdr[VKSDR_MAX];
        VkPrimitiveTopology prim;
        VkPolygonMode polymode;
+       float line_width;
        VkCullModeFlags cull;
        VkFrontFace     frontface;
        VkColorComponentFlags colorwr;
        int zbuf, depthwr;
+       VkCompareOp zop;
        int stencil, stencilwr;
        VkStencilOp sfail, szfail, szpass;
        VkCompareOp sop;
@@ -60,8 +63,11 @@ struct pipeline {
        int blend;
        VkBlendFactor srcblend, dstblend, srcblend_a, dstblend_a;
 
+       VkRenderPass rpass;
+
        int vkobj_valid;
        VkPipeline vkobj;
+       VkPipelineLayout vkobj_layout;  /* TODO probably best to split this */
 };
 
 
@@ -606,14 +612,18 @@ int vk_create_pipeln(void)
        /* init pipeline defaults */
        memset(pp, 0, sizeof *pp);
        pp->used = 1;
-       pp->vport[2] = pp->scissor[2] = 640;
-       pp->vport[3] = pp->scissor[3] = 480;
+       pp->vport.width = pp->scissor.extent.width = 640;
+       pp->vport.height = pp->scissor.extent.height = 480;
+       pp->vport.minDepth = 0.0f;
+       pp->vport.maxDepth = 1.0f;
        pp->prim = VKPRIM_TRIANGLES;
        pp->polymode = VK_POLYGON_MODE_FILL;
        pp->cull = VK_CULL_MODE_BACK_BIT;
        pp->frontface = VK_FRONT_FACE_COUNTER_CLOCKWISE;
+       pp->line_width = 1.0f;
        pp->colorwr = 0xf;      /* RGBA */
        pp->zbuf = 1;
+       pp->zop = VK_COMPARE_OP_LESS;
        pp->depthwr = 1;
        pp->stencil = 0;
        pp->stencilwr = 1;
@@ -642,23 +652,30 @@ void vk_free_pipeln(int pp)
        pipelines[pp].used = 0;
 }
 
-void vk_viewport(int pp, int x, int y, int width, int height)
+void vk_pipeln_rpass(int pp, VkRenderPass rp)
 {
        struct pipeline *p = pipelines + pp;
-       p->vport[0] = x;
-       p->vport[1] = y;
-       p->vport[2] = width;
-       p->vport[3] = height;
+       p->rpass = rp;
        p->vkobj_valid = 0;
 }
 
-void vk_scissor(int pp, int x, int y, int width, int height)
+void vk_pipeln_viewport(int pp, int x, int y, int width, int height)
 {
        struct pipeline *p = pipelines + pp;
-       p->scissor[0] = x;
-       p->scissor[1] = y;
-       p->scissor[2] = width;
-       p->scissor[3] = height;
+       p->vport.x = x;
+       p->vport.y = y;
+       p->vport.width = width;
+       p->vport.height = height;
+       p->vkobj_valid = 0;
+}
+
+void vk_pipeln_scissor(int pp, int x, int y, int width, int height)
+{
+       struct pipeline *p = pipelines + pp;
+       p->scissor.offset.x = x;
+       p->scissor.offset.y = y;
+       p->scissor.extent.width = width;
+       p->scissor.extent.height = height;
        p->vkobj_valid = 0;
 }
 
@@ -698,6 +715,13 @@ void vk_pipeln_frontface(int pp, int ff)
        p->vkobj_valid = 0;
 }
 
+void vk_pipeln_linewidth(int pp, int w)
+{
+       struct pipeline *p = pipelines + pp;
+       p->line_width = w;
+       p->vkobj_valid = 0;
+}
+
 void vk_pipeln_multisample(int pp, int nsamples)
 {
        /* TODO */
@@ -735,6 +759,13 @@ void vk_pipeln_zbuffer(int pp, int enable)
        p->vkobj_valid = 0;
 }
 
+void vk_pipeln_zbuffer_op(int pp, int op)
+{
+       struct pipeline *p = pipelines + pp;
+       p->zop = op;
+       p->vkobj_valid = 0;
+}
+
 void vk_pipeln_stencil(int pp, int enable)
 {
        struct pipeline *p = pipelines + pp;
@@ -777,12 +808,126 @@ void vk_pipeln_blendfunc(int pp, int src, int dst)
 
 VkPipeline vk_pipeln(int pp)
 {
+       int i, idx, num_sdr;
        struct pipeline *p = pipelines + pp;
+       VkPipelineShaderStageCreateInfo ssinf[VKSDR_MAX];
+       VkPipelineVertexInputStateCreateInfo vinp;
+       VkPipelineInputAssemblyStateCreateInfo vasm;
+       VkPipelineViewportStateCreateInfo vp;
+       VkPipelineRasterizationStateCreateInfo rast;
+       VkPipelineMultisampleStateCreateInfo msaa;
+       VkPipelineDepthStencilStateCreateInfo zst;
+       VkPipelineColorBlendAttachmentState bat;
+       VkPipelineColorBlendStateCreateInfo blend;
+       VkPipelineLayoutCreateInfo lay;
+       VkGraphicsPipelineCreateInfo pinf;
+
 
        if(p->vkobj_valid) {
                return p->vkobj;
        }
+
+       if(p->vkobj) {
+               vkDestroyPipeline(vkdev, p->vkobj, 0);
+               p->vkobj = 0;
+       }
+
+       memset(ssinf, 0, sizeof ssinf);
+       idx = 0;
+       for(i=0; i<VKSDR_MAX; i++) {
+               if(p->sdr[idx]) {
+                       ssinf[idx].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+                       ssinf[idx].stage = VKSDR_STAGE(i);
+                       ssinf[idx].module = p->sdr[idx];
+                       ssinf[idx].pName = "main";
+                       idx++;
+               }
+       }
+       num_sdr = idx;
+
+       memset(&vinp, 0, sizeof vinp);
+       vinp.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
+
+       memset(&vasm, 0, sizeof vasm);
+       vasm.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+       vasm.topology = p->prim;
+
+       memset(&vp, 0, sizeof vp);
+       vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
+       vp.viewportCount = 1;
+       vp.pViewports = &p->vport;
+       vp.scissorCount = 1;
+       vp.pScissors = &p->scissor;
+
+       memset(&rast, 0, sizeof rast);
+       rast.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+       rast.polygonMode = p->polymode;
+       rast.lineWidth = p->line_width;
+       rast.cullMode = p->cull;
+       rast.frontFace = p->frontface;
+
+       /* TODO */
+       memset(&msaa, 0, sizeof msaa);
+       msaa.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
+       msaa.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
+       msaa.minSampleShading = 1.0f;
+
+       memset(&zst, 0, sizeof zst);
+       zst.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
+       zst.depthTestEnable = p->zbuf;
+       zst.depthWriteEnable = p->depthwr;
+       zst.depthCompareOp = p->zop;
+       zst.stencilTestEnable = p->stencil;
+       zst.front.writeMask = p->stencilwr;
+       zst.front.failOp = p->sfail;
+       zst.front.passOp = p->szpass;
+       zst.front.depthFailOp = p->szfail;
+       zst.front.compareOp = p->sop;
+       zst.front.compareMask = p->smask;
+       zst.front.reference = p->sref;
+       zst.back = zst.front;
+
+       memset(&bat, 0, sizeof bat);
+       bat.colorWriteMask = p->colorwr;
+       bat.blendEnable = p->blend;
+       bat.srcColorBlendFactor = p->srcblend;
+       bat.dstColorBlendFactor = p->dstblend;
+       bat.colorBlendOp = VK_BLEND_OP_ADD;     /* TODO */
+       bat.srcAlphaBlendFactor = p->srcblend_a;
+       bat.dstAlphaBlendFactor = p->dstblend_a;
+
+       memset(&blend, 0, sizeof blend);
+       blend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
+       blend.attachmentCount = 1;
+       blend.pAttachments = &bat;
+
        /* TODO */
+       memset(&lay, 0, sizeof lay);
+       lay.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+       if(vkCreatePipelineLayout(vkdev, &lay, 0, &p->vkobj_layout) != 0) {
+               return 0;
+       }
+
+       memset(&pinf, 0, sizeof pinf);
+       pinf.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
+       pinf.stageCount = num_sdr;
+       pinf.pStages = ssinf;
+       pinf.pVertexInputState = &vinp;
+       pinf.pInputAssemblyState = &vasm;
+       pinf.pViewportState = &vp;
+       pinf.pRasterizationState = &rast;
+       pinf.pDepthStencilState = &zst;
+       pinf.pMultisampleState = &msaa;
+       pinf.pColorBlendState = &blend;
+       pinf.layout = p->vkobj_layout;
+       pinf.renderPass = p->rpass;
+       pinf.basePipelineIndex = -1;
+
+       if(vkCreateGraphicsPipelines(vkdev, 0, 1, &pinf, 0, &p->vkobj) != 0) {
+               return 0;
+       }
+       p->vkobj_valid = 1;
+       return p->vkobj;
 }
 
 
index f93634f..f4187d3 100644 (file)
--- a/src/vk.h
+++ b/src/vk.h
@@ -40,6 +40,7 @@ enum {
 
        VKSDR_MAX
 };
+#define VKSDR_STAGE(x) (1 << (x))
 
 /* primitives */
 enum {
@@ -79,19 +80,22 @@ VkFramebuffer vk_fb(int fb);
 
 int vk_create_pipeln(void);
 void vk_free_pipeln(int pp);
-void vk_viewport(int pp, int x, int y, int width, int height);
-void vk_scissor(int pp, int x, int y, int width, int height);
+void vk_pipeln_rpass(int pp, VkRenderPass rp);
+void vk_pipeln_viewport(int pp, int x, int y, int width, int height);
+void vk_pipeln_scissor(int pp, int x, int y, int width, int height);
 void vk_pipeln_shader(int pp, int type, VkShaderModule sdr);
 /* TODO: vertex input */
 void vk_pipeln_prim(int pp, int prim);
 void vk_pipeln_polymode(int pp, int mode);
 void vk_pipeln_cull(int pp, int cull);
 void vk_pipeln_frontface(int pp, int ff);
+void vk_pipeln_linewidth(int pp, int w);
 void vk_pipeln_multisample(int pp, int nsamples);
 void vk_pipeln_colormask(int pp, int r, int g, int b, int a);
 void vk_pipeln_depthmask(int pp, int z);
 void vk_pipeln_stencilmask(int pp, int s);
 void vk_pipeln_zbuffer(int pp, int enable);
+void vk_pipeln_zbuffer_op(int pp, int op);
 void vk_pipeln_stencil(int pp, int enable);
 void vk_pipeln_stencil_op(int pp, int sfail, int zfail, int zpass);
 void vk_pipeln_stencil_func(int pp, int op, unsigned int ref, unsigned int mask);