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;
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 */
};
/* 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;
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;
}
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 */
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;
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;
}
VKSDR_MAX
};
+#define VKSDR_STAGE(x) (1 << (x))
/* primitives */
enum {
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);