vulkan_test2

annotate src/vkpipe.c @ 13:d34f84bede17

pipeline madness
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 25 Jun 2018 08:00:57 +0300
parents e17abe477616
children f8bd29f124a8
rev   line source
nuclear@8 1 #include <stdio.h>
nuclear@8 2 #include <stdlib.h>
nuclear@8 3 #include <string.h>
nuclear@8 4 #include <errno.h>
nuclear@12 5 #include "vkpipe.h"
nuclear@8 6 #include "vku.h"
nuclear@8 7
nuclear@13 8 int vku_init_pipeline(struct vku_pipeline *st)
nuclear@12 9 {
nuclear@12 10 int i;
nuclear@12 11
nuclear@12 12 memset(st, 0, sizeof *st);
nuclear@12 13
nuclear@12 14 for(i=0; i<VKU_MAX_SDR_STAGES; i++) {
nuclear@12 15 st->sdrstage[i].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
nuclear@12 16 }
nuclear@12 17 st->vertinp.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
nuclear@12 18 st->inpasm.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
nuclear@12 19 st->vport.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
nuclear@12 20 st->rast.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
nuclear@12 21 st->msaa.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
nuclear@12 22 st->zstencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
nuclear@12 23 st->blend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
nuclear@13 24 st->lay.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
nuclear@12 25
nuclear@12 26 st->vport.pViewports = &st->vport_data;
nuclear@12 27 st->vport.pScissors = &st->scissor_data;
nuclear@12 28 st->vport.viewportCount = st->vport.scissorCount = 1;
nuclear@12 29
nuclear@12 30 st->vport_data.minDepth = 0.0f;
nuclear@12 31 st->vport_data.maxDepth = 1.0f;
nuclear@12 32
nuclear@12 33 st->blend.logicOp = VK_LOGIC_OP_COPY;
nuclear@12 34 st->blend.attachmentCount = 1;
nuclear@12 35 st->blend.pAttachments = &st->atblend;
nuclear@12 36
nuclear@12 37 /* set some reasonable defaults (just the non-zero ones) */
nuclear@13 38 vku_pipeline_primitive(st, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
nuclear@13 39 vku_pipeline_polygon_mode(st, VK_POLYGON_MODE_FILL);
nuclear@13 40 vku_pipeline_line_width(st, 1.0f);
nuclear@13 41 vku_pipeline_front_face(st, VK_FRONT_FACE_COUNTER_CLOCKWISE);
nuclear@12 42
nuclear@12 43 return 0;
nuclear@12 44 }
nuclear@12 45
nuclear@13 46 void vku_pipeline_shader(struct vku_pipeline *st, VkShaderModule sdr, VkShaderStageFlagBits type)
nuclear@12 47 {
nuclear@12 48 if(st->num_sdr_stages >= VKU_MAX_SDR_STAGES) {
nuclear@13 49 fprintf(stderr, "vku_pipeline_shader: too many shaders\n");
nuclear@12 50 abort();
nuclear@12 51 }
nuclear@12 52
nuclear@12 53 st->sdrstage[st->num_sdr_stages].stage = type;
nuclear@12 54 st->sdrstage[st->num_sdr_stages].module = sdr;
nuclear@12 55 st->sdrstage[st->num_sdr_stages].pName = "main";
nuclear@12 56 ++st->num_sdr_stages;
nuclear@12 57 }
nuclear@12 58
nuclear@13 59 void vku_pipeline_primitive(struct vku_pipeline *st, VkPrimitiveTopology prim)
nuclear@12 60 {
nuclear@12 61 st->inpasm.topology = prim;
nuclear@12 62 }
nuclear@12 63
nuclear@13 64 void vku_pipeline_viewport(struct vku_pipeline *st, int x, int y, int w, int h)
nuclear@12 65 {
nuclear@12 66 st->vport_data.x = x;
nuclear@12 67 st->vport_data.y = y;
nuclear@12 68 st->vport_data.width = w;
nuclear@12 69 st->vport_data.height = h;
nuclear@12 70 }
nuclear@12 71
nuclear@13 72 void vku_pipeline_scissor(struct vku_pipeline *st, int x, int y, int w, int h)
nuclear@12 73 {
nuclear@12 74 st->scissor_data.offset.x = x;
nuclear@12 75 st->scissor_data.offset.y = y;
nuclear@12 76 st->scissor_data.extent.width = w;
nuclear@12 77 st->scissor_data.extent.height = h;
nuclear@12 78 }
nuclear@12 79
nuclear@13 80 void vku_pipeline_polygon_mode(struct vku_pipeline *st, VkPolygonMode pmode)
nuclear@12 81 {
nuclear@12 82 st->rast.polygonMode = pmode;
nuclear@12 83 }
nuclear@12 84
nuclear@13 85 void vku_pipeline_line_width(struct vku_pipeline *st, float w)
nuclear@12 86 {
nuclear@12 87 st->rast.lineWidth = w;
nuclear@12 88 }
nuclear@12 89
nuclear@13 90 void vku_pipeline_cull_mode(struct vku_pipeline *st, VkCullModeFlagBits cull)
nuclear@12 91 {
nuclear@12 92 st->rast.cullMode = cull;
nuclear@12 93 }
nuclear@12 94
nuclear@13 95 void vku_pipeline_front_face(struct vku_pipeline *st, VkFrontFace front)
nuclear@12 96 {
nuclear@12 97 st->rast.frontFace = front;
nuclear@12 98 }
nuclear@12 99
nuclear@13 100 void vku_pipeline_depth_bias(struct vku_pipeline *st, float fslope, float fconst, float clamp)
nuclear@12 101 {
nuclear@12 102 st->rast.depthBiasEnable = VK_TRUE;
nuclear@12 103 st->rast.depthBiasSlopeFactor = fslope;
nuclear@12 104 st->rast.depthBiasConstantFactor = fconst;
nuclear@12 105 st->rast.depthBiasClamp = clamp;
nuclear@12 106 }
nuclear@12 107
nuclear@13 108 void vku_pipeline_depth_test(struct vku_pipeline *st, int enable)
nuclear@12 109 {
nuclear@12 110 st->zstencil.depthTestEnable = enable ? VK_TRUE : VK_FALSE;
nuclear@12 111 }
nuclear@12 112
nuclear@13 113 void vku_pipeline_depth_func(struct vku_pipeline *st, VkCompareOp op)
nuclear@12 114 {
nuclear@12 115 st->zstencil.depthCompareOp = op;
nuclear@12 116 }
nuclear@12 117
nuclear@13 118 void vku_pipeline_depth_mask(struct vku_pipeline *st, int zmask)
nuclear@12 119 {
nuclear@12 120 st->zstencil.depthWriteEnable = zmask ? VK_TRUE : VK_FALSE;
nuclear@12 121 }
nuclear@12 122
nuclear@13 123 void vku_pipeline_stencil_test(struct vku_pipeline *st, int enable)
nuclear@12 124 {
nuclear@12 125 st->zstencil.stencilTestEnable = enable ? VK_TRUE : VK_FALSE;
nuclear@12 126 }
nuclear@12 127
nuclear@13 128 void vku_pipeline_stencil_func(struct vku_pipeline *st, VkCompareOp op, int ref, unsigned int mask)
nuclear@12 129 {
nuclear@12 130 st->zstencil.front.compareOp = st->zstencil.back.compareOp = op;
nuclear@12 131 st->zstencil.front.reference = st->zstencil.back.reference = ref;
nuclear@12 132 st->zstencil.front.writeMask = st->zstencil.back.compareMask = mask;
nuclear@12 133 }
nuclear@12 134
nuclear@13 135 void vku_pipeline_stencil_op(struct vku_pipeline *st, VkStencilOp sfail, VkStencilOp dfail, VkStencilOp pass)
nuclear@12 136 {
nuclear@12 137 st->zstencil.front.failOp = st->zstencil.back.failOp = sfail;
nuclear@12 138 st->zstencil.front.depthFailOp = st->zstencil.back.depthFailOp = dfail;
nuclear@12 139 st->zstencil.front.passOp = st->zstencil.back.passOp = pass;
nuclear@12 140 }
nuclear@12 141
nuclear@13 142 void vku_pipeline_stencil_mask(struct vku_pipeline *st, unsigned int smask)
nuclear@12 143 {
nuclear@12 144 st->zstencil.front.writeMask = st->zstencil.back.writeMask = smask;
nuclear@12 145 }
nuclear@12 146
nuclear@13 147 void vku_pipeline_color_mask(struct vku_pipeline *st, int rmask, int gmask, int bmask, int amask)
nuclear@12 148 {
nuclear@12 149 unsigned int mask = 0;
nuclear@12 150
nuclear@12 151 if(rmask) mask |= VK_COLOR_COMPONENT_R_BIT;
nuclear@12 152 if(gmask) mask |= VK_COLOR_COMPONENT_G_BIT;
nuclear@12 153 if(bmask) mask |= VK_COLOR_COMPONENT_B_BIT;
nuclear@12 154 if(amask) mask |= VK_COLOR_COMPONENT_A_BIT;
nuclear@12 155
nuclear@12 156 st->atblend.colorWriteMask = mask;
nuclear@12 157 }
nuclear@12 158
nuclear@13 159 void vku_pipeline_blend_enable(struct vku_pipeline *st, int enable)
nuclear@12 160 {
nuclear@12 161 st->atblend.blendEnable = enable ? VK_TRUE : VK_FALSE;
nuclear@12 162 }
nuclear@12 163
nuclear@13 164 void vku_pipeline_blend_func(struct vku_pipeline *st, VkBlendFactor src, VkBlendFactor dst)
nuclear@12 165 {
nuclear@12 166 st->atblend.srcColorBlendFactor = src;
nuclear@12 167 st->atblend.dstColorBlendFactor = dst;
nuclear@12 168 st->atblend.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
nuclear@12 169 st->atblend.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
nuclear@12 170 st->atblend.colorBlendOp = VK_BLEND_OP_ADD;
nuclear@12 171 st->atblend.alphaBlendOp = VK_BLEND_OP_ADD;
nuclear@12 172 }
nuclear@12 173
nuclear@13 174 void vku_pipeline_renderpass(struct vku_pipeline *st, VkRenderPass rpass)
nuclear@13 175 {
nuclear@13 176 st->rpass = rpass;
nuclear@13 177 }
nuclear@12 178
nuclear@13 179
nuclear@13 180 VkPipeline vku_create_pipeline(struct vku_pipeline *st)
nuclear@12 181 {
nuclear@13 182 VkGraphicsPipelineCreateInfo pinf;
nuclear@13 183
nuclear@13 184 if(vkCreatePipelineLayout(vkdev, &st->lay, 0, &st->layout) != 0) {
nuclear@13 185 fprintf(stderr, "vku_create_pipeline: failed to create layout\n");
nuclear@13 186 return 0;
nuclear@13 187 }
nuclear@13 188
nuclear@13 189 memset(&pinf, 0, sizeof pinf);
nuclear@13 190 pinf.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
nuclear@13 191 pinf.stageCount = st->num_sdr_stages;
nuclear@13 192 pinf.pStages = st->sdrstage;
nuclear@13 193 pinf.pVertexInputState = &st->vertinp;
nuclear@13 194 pinf.pInputAssemblyState = &st->inpasm;
nuclear@13 195 pinf.pViewportState = &st->vport;
nuclear@13 196 pinf.pRasterizationState = &st->rast;
nuclear@13 197 pinf.pMultisampleState = &st->msaa;
nuclear@13 198 //pinf.pDepthStencilState = &st->zstencil;
nuclear@13 199 pinf.pColorBlendState = &st->blend;
nuclear@13 200
nuclear@13 201 pinf.layout = st->layout;
nuclear@13 202 pinf.renderPass = st->rpass;
nuclear@13 203
nuclear@13 204 if(vkCreateGraphicsPipelines(vkdev, 0, 1, &pinf, 0, &st->pipeline) != 0) {
nuclear@13 205 fprintf(stderr, "vku_create_pipeline failed\n");
nuclear@13 206 vkDestroyPipelineLayout(vkdev, st->layout, 0);
nuclear@13 207 return 0;
nuclear@13 208 }
nuclear@13 209 return st->pipeline;
nuclear@13 210 }
nuclear@13 211
nuclear@13 212 void vku_destroy_pipeline(struct vku_pipeline *p)
nuclear@13 213 {
nuclear@13 214 if(p->layout) {
nuclear@13 215 vkDestroyPipelineLayout(vkdev, p->layout, 0);
nuclear@13 216 }
nuclear@13 217 if(p->pipeline) {
nuclear@13 218 vkDestroyPipeline(vkdev, p->pipeline, 0);
nuclear@13 219 }
nuclear@12 220 }
nuclear@12 221
nuclear@8 222 VkShaderModule vku_load_shader(const char *fname)
nuclear@8 223 {
nuclear@8 224 int size;
nuclear@8 225 VkShaderModuleCreateInfo inf;
nuclear@8 226 VkShaderModule sdr;
nuclear@8 227 FILE *fp;
nuclear@9 228 void *buf = 0;
nuclear@8 229
nuclear@8 230 if(!(fp = fopen(fname, "rb"))) {
nuclear@8 231 fprintf(stderr, "vku_load_shader: failed to load %s: %s\n", fname, strerror(errno));
nuclear@8 232 return 0;
nuclear@8 233 }
nuclear@8 234 fseek(fp, 0, SEEK_END);
nuclear@8 235 size = ftell(fp);
nuclear@8 236 rewind(fp);
nuclear@8 237
nuclear@8 238 if(!(buf = malloc(size + 1))) {
nuclear@8 239 fprintf(stderr, "vku_load_shader: failed to allocate buffer\n");
nuclear@8 240 goto err;
nuclear@8 241 }
nuclear@8 242 if(fread(buf, 1, size, fp) < size) {
nuclear@8 243 fprintf(stderr, "vku_load_shader: unexpected end of file while reading: %s\n", fname);
nuclear@8 244 goto err;
nuclear@8 245 }
nuclear@8 246
nuclear@8 247 memset(&inf, 0, sizeof inf);
nuclear@8 248 inf.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
nuclear@8 249 inf.codeSize = size;
nuclear@9 250 inf.pCode = buf;
nuclear@8 251
nuclear@8 252 if(vkCreateShaderModule(vkdev, &inf, 0, &sdr) != 0) {
nuclear@8 253 fprintf(stderr, "vku_load_shader: failed to create shader: %s\n", fname);
nuclear@8 254 goto err;
nuclear@8 255 }
nuclear@8 256 return sdr;
nuclear@8 257
nuclear@8 258 err:
nuclear@8 259 fclose(fp);
nuclear@8 260 free(buf);
nuclear@8 261 return 0;
nuclear@8 262 }
nuclear@8 263
nuclear@8 264 void vku_destroy_shader(VkShaderModule sdr)
nuclear@8 265 {
nuclear@8 266 vkDestroyShaderModule(vkdev, sdr, 0);
nuclear@8 267 }