vulkan_test2

changeset 13:d34f84bede17

pipeline madness
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 25 Jun 2018 08:00:57 +0300
parents e17abe477616
children 9fb6c24691ea
files src/main.c src/vkpipe.c src/vkpipe.h src/vku.c src/vku.h src/wsys_x11.c
diffstat 6 files changed, 193 insertions(+), 52 deletions(-) [+]
line diff
     1.1 --- a/src/main.c	Sat Jun 23 07:47:49 2018 +0300
     1.2 +++ b/src/main.c	Mon Jun 25 08:00:57 2018 +0300
     1.3 @@ -1,12 +1,16 @@
     1.4  #include <stdio.h>
     1.5  #include "wsys.h"
     1.6  #include "vku.h"
     1.7 +#include "vkpipe.h"
     1.8  #include "vkgl.h"
     1.9  
    1.10  static void display(void);
    1.11  static void reshape(int x, int y);
    1.12  static void keyboard(int key, int pressed);
    1.13  
    1.14 +static struct vku_pipeline pipeline;
    1.15 +static VkShaderModule vsdr, psdr;
    1.16 +
    1.17  int main(void)
    1.18  {
    1.19  	if(vku_create_dev() == -1) {
    1.20 @@ -22,6 +26,23 @@
    1.21  	wsys_reshape_callback(reshape);
    1.22  	wsys_keyboard_callback(keyboard);
    1.23  
    1.24 +	wsys_process_events(WSYS_NONBLOCK);
    1.25 +
    1.26 +	if(!(vsdr = vku_load_shader("sdr/vertex.spv")) ||
    1.27 +			!(psdr = vku_load_shader("sdr/pixel.spv"))) {
    1.28 +		return 1;
    1.29 +	}
    1.30 +
    1.31 +	vku_init_pipeline(&pipeline);
    1.32 +	vku_pipeline_shader(&pipeline, vsdr, VK_SHADER_STAGE_VERTEX_BIT);
    1.33 +	vku_pipeline_shader(&pipeline, psdr, VK_SHADER_STAGE_FRAGMENT_BIT);
    1.34 +	vku_pipeline_viewport(&pipeline, 0, 0, 800, 600);
    1.35 +	vku_pipeline_renderpass(&pipeline, vkrpass);
    1.36 +	if(!vku_create_pipeline(&pipeline)) {
    1.37 +		return 1;
    1.38 +	}
    1.39 +
    1.40 +
    1.41  	while(wsys_process_events(WSYS_BLOCKING) != -1);
    1.42  
    1.43  	wsys_destroy_window();
     2.1 --- a/src/vkpipe.c	Sat Jun 23 07:47:49 2018 +0300
     2.2 +++ b/src/vkpipe.c	Mon Jun 25 08:00:57 2018 +0300
     2.3 @@ -5,7 +5,7 @@
     2.4  #include "vkpipe.h"
     2.5  #include "vku.h"
     2.6  
     2.7 -int vku_init_pstate(struct vku_pstate *st)
     2.8 +int vku_init_pipeline(struct vku_pipeline *st)
     2.9  {
    2.10  	int i;
    2.11  
    2.12 @@ -21,7 +21,7 @@
    2.13  	st->msaa.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
    2.14  	st->zstencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
    2.15  	st->blend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
    2.16 -	st->layout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
    2.17 +	st->lay.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
    2.18  
    2.19  	st->vport.pViewports = &st->vport_data;
    2.20  	st->vport.pScissors = &st->scissor_data;
    2.21 @@ -35,18 +35,18 @@
    2.22  	st->blend.pAttachments = &st->atblend;
    2.23  
    2.24  	/* set some reasonable defaults (just the non-zero ones) */
    2.25 -	vku_pstate_primitive(st, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
    2.26 -	vku_pstate_polygon_mode(st, VK_POLYGON_MODE_FILL);
    2.27 -	vku_pstate_line_width(st, 1.0f);
    2.28 -	vku_pstate_front_face(st, VK_FRONT_FACE_COUNTER_CLOCKWISE);
    2.29 +	vku_pipeline_primitive(st, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
    2.30 +	vku_pipeline_polygon_mode(st, VK_POLYGON_MODE_FILL);
    2.31 +	vku_pipeline_line_width(st, 1.0f);
    2.32 +	vku_pipeline_front_face(st, VK_FRONT_FACE_COUNTER_CLOCKWISE);
    2.33  
    2.34  	return 0;
    2.35  }
    2.36  
    2.37 -void vku_pstate_shader(struct vku_pstate *st, VkShaderModule sdr, VkShaderStageFlagBits type)
    2.38 +void vku_pipeline_shader(struct vku_pipeline *st, VkShaderModule sdr, VkShaderStageFlagBits type)
    2.39  {
    2.40  	if(st->num_sdr_stages >= VKU_MAX_SDR_STAGES) {
    2.41 -		fprintf(stderr, "vku_pstate_shader: too many shaders\n");
    2.42 +		fprintf(stderr, "vku_pipeline_shader: too many shaders\n");
    2.43  		abort();
    2.44  	}
    2.45  
    2.46 @@ -56,12 +56,12 @@
    2.47  	++st->num_sdr_stages;
    2.48  }
    2.49  
    2.50 -void vku_pstate_primitive(struct vku_pstate *st, VkPrimitiveTopology prim)
    2.51 +void vku_pipeline_primitive(struct vku_pipeline *st, VkPrimitiveTopology prim)
    2.52  {
    2.53  	st->inpasm.topology = prim;
    2.54  }
    2.55  
    2.56 -void vku_pstate_viewport(struct vku_pstate *st, int x, int y, int w, int h)
    2.57 +void vku_pipeline_viewport(struct vku_pipeline *st, int x, int y, int w, int h)
    2.58  {
    2.59  	st->vport_data.x = x;
    2.60  	st->vport_data.y = y;
    2.61 @@ -69,7 +69,7 @@
    2.62  	st->vport_data.height = h;
    2.63  }
    2.64  
    2.65 -void vku_pstate_scissor(struct vku_pstate *st, int x, int y, int w, int h)
    2.66 +void vku_pipeline_scissor(struct vku_pipeline *st, int x, int y, int w, int h)
    2.67  {
    2.68  	st->scissor_data.offset.x = x;
    2.69  	st->scissor_data.offset.y = y;
    2.70 @@ -77,27 +77,27 @@
    2.71  	st->scissor_data.extent.height = h;
    2.72  }
    2.73  
    2.74 -void vku_pstate_polygon_mode(struct vku_pstate *st, VkPolygonMode pmode)
    2.75 +void vku_pipeline_polygon_mode(struct vku_pipeline *st, VkPolygonMode pmode)
    2.76  {
    2.77  	st->rast.polygonMode = pmode;
    2.78  }
    2.79  
    2.80 -void vku_pstate_line_width(struct vku_pstate *st, float w)
    2.81 +void vku_pipeline_line_width(struct vku_pipeline *st, float w)
    2.82  {
    2.83  	st->rast.lineWidth = w;
    2.84  }
    2.85  
    2.86 -void vku_pstate_cull_mode(struct vku_pstate *st, VkCullModeFlagBits cull)
    2.87 +void vku_pipeline_cull_mode(struct vku_pipeline *st, VkCullModeFlagBits cull)
    2.88  {
    2.89  	st->rast.cullMode = cull;
    2.90  }
    2.91  
    2.92 -void vku_pstate_front_face(struct vku_pstate *st, VkFrontFace front)
    2.93 +void vku_pipeline_front_face(struct vku_pipeline *st, VkFrontFace front)
    2.94  {
    2.95  	st->rast.frontFace = front;
    2.96  }
    2.97  
    2.98 -void vku_pstate_depth_bias(struct vku_pstate *st, float fslope, float fconst, float clamp)
    2.99 +void vku_pipeline_depth_bias(struct vku_pipeline *st, float fslope, float fconst, float clamp)
   2.100  {
   2.101  	st->rast.depthBiasEnable = VK_TRUE;
   2.102  	st->rast.depthBiasSlopeFactor = fslope;
   2.103 @@ -105,46 +105,46 @@
   2.104  	st->rast.depthBiasClamp = clamp;
   2.105  }
   2.106  
   2.107 -void vku_pstate_depth_test(struct vku_pstate *st, int enable)
   2.108 +void vku_pipeline_depth_test(struct vku_pipeline *st, int enable)
   2.109  {
   2.110  	st->zstencil.depthTestEnable = enable ? VK_TRUE : VK_FALSE;
   2.111  }
   2.112  
   2.113 -void vku_pstate_depth_func(struct vku_pstate *st, VkCompareOp op)
   2.114 +void vku_pipeline_depth_func(struct vku_pipeline *st, VkCompareOp op)
   2.115  {
   2.116  	st->zstencil.depthCompareOp = op;
   2.117  }
   2.118  
   2.119 -void vku_pstate_depth_mask(struct vku_pstate *st, int zmask)
   2.120 +void vku_pipeline_depth_mask(struct vku_pipeline *st, int zmask)
   2.121  {
   2.122  	st->zstencil.depthWriteEnable = zmask ? VK_TRUE : VK_FALSE;
   2.123  }
   2.124  
   2.125 -void vku_pstate_stencil_test(struct vku_pstate *st, int enable)
   2.126 +void vku_pipeline_stencil_test(struct vku_pipeline *st, int enable)
   2.127  {
   2.128  	st->zstencil.stencilTestEnable = enable ? VK_TRUE : VK_FALSE;
   2.129  }
   2.130  
   2.131 -void vku_pstate_stencil_func(struct vku_pstate *st, VkCompareOp op, int ref, unsigned int mask)
   2.132 +void vku_pipeline_stencil_func(struct vku_pipeline *st, VkCompareOp op, int ref, unsigned int mask)
   2.133  {
   2.134  	st->zstencil.front.compareOp = st->zstencil.back.compareOp = op;
   2.135  	st->zstencil.front.reference = st->zstencil.back.reference = ref;
   2.136  	st->zstencil.front.writeMask = st->zstencil.back.compareMask = mask;
   2.137  }
   2.138  
   2.139 -void vku_pstate_stencil_op(struct vku_pstate *st, VkStencilOp sfail, VkStencilOp dfail, VkStencilOp pass)
   2.140 +void vku_pipeline_stencil_op(struct vku_pipeline *st, VkStencilOp sfail, VkStencilOp dfail, VkStencilOp pass)
   2.141  {
   2.142  	st->zstencil.front.failOp = st->zstencil.back.failOp = sfail;
   2.143  	st->zstencil.front.depthFailOp = st->zstencil.back.depthFailOp = dfail;
   2.144  	st->zstencil.front.passOp = st->zstencil.back.passOp = pass;
   2.145  }
   2.146  
   2.147 -void vku_pstate_stencil_mask(struct vku_pstate *st, unsigned int smask)
   2.148 +void vku_pipeline_stencil_mask(struct vku_pipeline *st, unsigned int smask)
   2.149  {
   2.150  	st->zstencil.front.writeMask = st->zstencil.back.writeMask = smask;
   2.151  }
   2.152  
   2.153 -void vku_pstate_color_mask(struct vku_pstate *st, int rmask, int gmask, int bmask, int amask)
   2.154 +void vku_pipeline_color_mask(struct vku_pipeline *st, int rmask, int gmask, int bmask, int amask)
   2.155  {
   2.156  	unsigned int mask = 0;
   2.157  
   2.158 @@ -156,12 +156,12 @@
   2.159  	st->atblend.colorWriteMask = mask;
   2.160  }
   2.161  
   2.162 -void vku_pstate_blend_enable(struct vku_pstate *st, int enable)
   2.163 +void vku_pipeline_blend_enable(struct vku_pipeline *st, int enable)
   2.164  {
   2.165  	st->atblend.blendEnable = enable ? VK_TRUE : VK_FALSE;
   2.166  }
   2.167  
   2.168 -void vku_pstate_blend_func(struct vku_pstate *st, VkBlendFactor src, VkBlendFactor dst)
   2.169 +void vku_pipeline_blend_func(struct vku_pipeline *st, VkBlendFactor src, VkBlendFactor dst)
   2.170  {
   2.171  	st->atblend.srcColorBlendFactor = src;
   2.172  	st->atblend.dstColorBlendFactor = dst;
   2.173 @@ -171,10 +171,52 @@
   2.174  	st->atblend.alphaBlendOp = VK_BLEND_OP_ADD;
   2.175  }
   2.176  
   2.177 +void vku_pipeline_renderpass(struct vku_pipeline *st, VkRenderPass rpass)
   2.178 +{
   2.179 +	st->rpass = rpass;
   2.180 +}
   2.181  
   2.182 -VkPipeline vku_create_pipeline(struct vku_pstate *st)
   2.183 +
   2.184 +VkPipeline vku_create_pipeline(struct vku_pipeline *st)
   2.185  {
   2.186 -	return 0;	/* TODO */
   2.187 +	VkGraphicsPipelineCreateInfo pinf;
   2.188 +
   2.189 +	if(vkCreatePipelineLayout(vkdev, &st->lay, 0, &st->layout) != 0) {
   2.190 +		fprintf(stderr, "vku_create_pipeline: failed to create layout\n");
   2.191 +		return 0;
   2.192 +	}
   2.193 +
   2.194 +	memset(&pinf, 0, sizeof pinf);
   2.195 +	pinf.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
   2.196 +	pinf.stageCount = st->num_sdr_stages;
   2.197 +	pinf.pStages = st->sdrstage;
   2.198 +	pinf.pVertexInputState = &st->vertinp;
   2.199 +	pinf.pInputAssemblyState = &st->inpasm;
   2.200 +	pinf.pViewportState = &st->vport;
   2.201 +	pinf.pRasterizationState = &st->rast;
   2.202 +	pinf.pMultisampleState = &st->msaa;
   2.203 +	//pinf.pDepthStencilState = &st->zstencil;
   2.204 +	pinf.pColorBlendState = &st->blend;
   2.205 +
   2.206 +	pinf.layout = st->layout;
   2.207 +	pinf.renderPass = st->rpass;
   2.208 +
   2.209 +	if(vkCreateGraphicsPipelines(vkdev, 0, 1, &pinf, 0, &st->pipeline) != 0) {
   2.210 +		fprintf(stderr, "vku_create_pipeline failed\n");
   2.211 +		vkDestroyPipelineLayout(vkdev, st->layout, 0);
   2.212 +		return 0;
   2.213 +	}
   2.214 +	return st->pipeline;
   2.215 +}
   2.216 +
   2.217 +void vku_destroy_pipeline(struct vku_pipeline *p)
   2.218 +{
   2.219 +	if(p->layout) {
   2.220 +		vkDestroyPipelineLayout(vkdev, p->layout, 0);
   2.221 +	}
   2.222 +	if(p->pipeline) {
   2.223 +		vkDestroyPipeline(vkdev, p->pipeline, 0);
   2.224 +	}
   2.225  }
   2.226  
   2.227  VkShaderModule vku_load_shader(const char *fname)
     3.1 --- a/src/vkpipe.h	Sat Jun 23 07:47:49 2018 +0300
     3.2 +++ b/src/vkpipe.h	Mon Jun 25 08:00:57 2018 +0300
     3.3 @@ -5,7 +5,7 @@
     3.4  
     3.5  #define VKU_MAX_SDR_STAGES	8
     3.6  
     3.7 -struct vku_pstate {
     3.8 +struct vku_pipeline {
     3.9  	VkPipelineShaderStageCreateInfo sdrstage[VKU_MAX_SDR_STAGES];
    3.10  	int num_sdr_stages;
    3.11  	VkPipelineVertexInputStateCreateInfo vertinp;
    3.12 @@ -16,7 +16,11 @@
    3.13  	VkPipelineDepthStencilStateCreateInfo zstencil;
    3.14  	VkPipelineColorBlendStateCreateInfo blend;
    3.15  	/*VkPipelineDynamicStateCreateInfo dyn;*/
    3.16 -	VkPipelineLayoutCreateInfo layout;
    3.17 +	VkPipelineLayoutCreateInfo lay;
    3.18 +
    3.19 +	VkRenderPass rpass;
    3.20 +	VkPipeline pipeline;
    3.21 +	VkPipelineLayout layout;
    3.22  
    3.23  	/* data needed by the structs above */
    3.24  	VkViewport vport_data;
    3.25 @@ -24,28 +28,30 @@
    3.26  	VkPipelineColorBlendAttachmentState atblend;
    3.27  };
    3.28  
    3.29 -int vku_init_pstate(struct vku_pstate *st);
    3.30 -void vku_pstate_shader(struct vku_pstate *st, VkShaderModule sdr, VkShaderStageFlagBits type);
    3.31 -void vku_pstate_primitive(struct vku_pstate *st, VkPrimitiveTopology prim);
    3.32 -void vku_pstate_viewport(struct vku_pstate *st, int x, int y, int w, int h);
    3.33 -void vku_pstate_scissor(struct vku_pstate *st, int x, int y, int w, int h);
    3.34 -void vku_pstate_polygon_mode(struct vku_pstate *st, VkPolygonMode pmode);
    3.35 -void vku_pstate_line_width(struct vku_pstate *st, float w);
    3.36 -void vku_pstate_cull_mode(struct vku_pstate *st, VkCullModeFlagBits cull);
    3.37 -void vku_pstate_front_face(struct vku_pstate *st, VkFrontFace front);
    3.38 -void vku_pstate_depth_bias(struct vku_pstate *st, float fslope, float fconst, float clamp);
    3.39 -void vku_pstate_depth_test(struct vku_pstate *st, int enable);
    3.40 -void vku_pstate_depth_func(struct vku_pstate *st, VkCompareOp op);
    3.41 -void vku_pstate_depth_mask(struct vku_pstate *st, int zmask);
    3.42 -void vku_pstate_stencil_test(struct vku_pstate *st, int enable);
    3.43 -void vku_pstate_stencil_func(struct vku_pstate *st, VkCompareOp op, int ref, unsigned int mask);
    3.44 -void vku_pstate_stencil_op(struct vku_pstate *st, VkStencilOp sfail, VkStencilOp dfail, VkStencilOp pass);
    3.45 -void vku_pstate_stencil_mask(struct vku_pstate *st, unsigned int smask);
    3.46 -void vku_pstate_color_mask(struct vku_pstate *st, int rmask, int gmask, int bmask, int amask);
    3.47 -void vku_pstate_blend_enable(struct vku_pstate *st, int enable);
    3.48 -void vku_pstate_blend_func(struct vku_pstate *st, VkBlendFactor src, VkBlendFactor dst);
    3.49 +int vku_init_pipeline(struct vku_pipeline *st);
    3.50 +void vku_pipeline_shader(struct vku_pipeline *st, VkShaderModule sdr, VkShaderStageFlagBits type);
    3.51 +void vku_pipeline_primitive(struct vku_pipeline *st, VkPrimitiveTopology prim);
    3.52 +void vku_pipeline_viewport(struct vku_pipeline *st, int x, int y, int w, int h);
    3.53 +void vku_pipeline_scissor(struct vku_pipeline *st, int x, int y, int w, int h);
    3.54 +void vku_pipeline_polygon_mode(struct vku_pipeline *st, VkPolygonMode pmode);
    3.55 +void vku_pipeline_line_width(struct vku_pipeline *st, float w);
    3.56 +void vku_pipeline_cull_mode(struct vku_pipeline *st, VkCullModeFlagBits cull);
    3.57 +void vku_pipeline_front_face(struct vku_pipeline *st, VkFrontFace front);
    3.58 +void vku_pipeline_depth_bias(struct vku_pipeline *st, float fslope, float fconst, float clamp);
    3.59 +void vku_pipeline_depth_test(struct vku_pipeline *st, int enable);
    3.60 +void vku_pipeline_depth_func(struct vku_pipeline *st, VkCompareOp op);
    3.61 +void vku_pipeline_depth_mask(struct vku_pipeline *st, int zmask);
    3.62 +void vku_pipeline_stencil_test(struct vku_pipeline *st, int enable);
    3.63 +void vku_pipeline_stencil_func(struct vku_pipeline *st, VkCompareOp op, int ref, unsigned int mask);
    3.64 +void vku_pipeline_stencil_op(struct vku_pipeline *st, VkStencilOp sfail, VkStencilOp dfail, VkStencilOp pass);
    3.65 +void vku_pipeline_stencil_mask(struct vku_pipeline *st, unsigned int smask);
    3.66 +void vku_pipeline_color_mask(struct vku_pipeline *st, int rmask, int gmask, int bmask, int amask);
    3.67 +void vku_pipeline_blend_enable(struct vku_pipeline *st, int enable);
    3.68 +void vku_pipeline_blend_func(struct vku_pipeline *st, VkBlendFactor src, VkBlendFactor dst);
    3.69 +void vku_pipeline_renderpass(struct vku_pipeline *st, VkRenderPass rpass);
    3.70  
    3.71 -VkPipeline vku_create_pipeline(struct vku_pstate *st);
    3.72 +VkPipeline vku_create_pipeline(struct vku_pipeline *st);
    3.73 +void vku_destroy_pipeline(struct vku_pipeline *p);
    3.74  
    3.75  VkShaderModule vku_load_shader(const char *fname);
    3.76  void vku_destroy_shader(VkShaderModule sdr);
     4.1 --- a/src/vku.c	Sat Jun 23 07:47:49 2018 +0300
     4.2 +++ b/src/vku.c	Mon Jun 25 08:00:57 2018 +0300
     4.3 @@ -426,8 +426,70 @@
     4.4  }
     4.5  
     4.6  
     4.7 +VkRenderPass vku_create_renderpass(VkFormat cfmt, VkFormat dsfmt)
     4.8 +{
     4.9 +	int count = 1;	/* always assume we have a color attachment for now */
    4.10 +	VkAttachmentDescription at[2];
    4.11 +	VkAttachmentReference colref, dsref;
    4.12 +	VkSubpassDescription subpass;
    4.13 +	VkRenderPass pass;
    4.14 +	VkRenderPassCreateInfo rpinf;
    4.15 +
    4.16 +	colref.attachment = 0;
    4.17 +	colref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
    4.18 +	dsref.attachment = 1;
    4.19 +	dsref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
    4.20 +
    4.21 +	memset(&subpass, 0, sizeof subpass);
    4.22 +	subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
    4.23 +	subpass.colorAttachmentCount = 1;
    4.24 +	subpass.pColorAttachments = &colref;
    4.25 +
    4.26 +	at[0].format = cfmt;
    4.27 +	at[0].samples = VK_SAMPLE_COUNT_1_BIT;	/* TODO multisampling */
    4.28 +	at[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
    4.29 +	at[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
    4.30 +	at[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
    4.31 +	at[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
    4.32 +	at[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    4.33 +	at[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
    4.34 +
    4.35 +	if(dsfmt != VK_FORMAT_UNDEFINED) {
    4.36 +		at[1].format = dsfmt;
    4.37 +		at[1].samples = VK_SAMPLE_COUNT_1_BIT;
    4.38 +		at[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
    4.39 +		at[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
    4.40 +		at[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
    4.41 +		at[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
    4.42 +		at[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    4.43 +		at[1].finalLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    4.44 +
    4.45 +		subpass.pDepthStencilAttachment = &dsref;
    4.46 +		count++;
    4.47 +	}
    4.48 +
    4.49 +	memset(&rpinf, 0, sizeof rpinf);
    4.50 +	rpinf.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
    4.51 +	rpinf.attachmentCount = count;
    4.52 +	rpinf.pAttachments = at;
    4.53 +	rpinf.subpassCount = 1;
    4.54 +	rpinf.pSubpasses = &subpass;
    4.55 +
    4.56 +	if(vkCreateRenderPass(vkdev, &rpinf, 0, &pass) != 0) {
    4.57 +		fprintf(stderr, "vku_create_renderpass: failed to create renderpass\n");
    4.58 +		return 0;
    4.59 +	}
    4.60 +
    4.61 +	return pass;
    4.62 +}
    4.63 +
    4.64 +void vku_destroy_renderpass(VkRenderPass rpass)
    4.65 +{
    4.66 +	vkDestroyRenderPass(vkdev, rpass, 0);
    4.67 +}
    4.68 +
    4.69 +
    4.70  #ifdef VK_USE_PLATFORM_XLIB_KHR
    4.71 -
    4.72  int vku_xlib_usable_visual(Display *dpy, VisualID vid)
    4.73  {
    4.74  	return vkGetPhysicalDeviceXlibPresentationSupportKHR(phys_devices[sel_dev],
     5.1 --- a/src/vku.h	Sat Jun 23 07:47:49 2018 +0300
     5.2 +++ b/src/vku.h	Mon Jun 25 08:00:57 2018 +0300
     5.3 @@ -17,6 +17,7 @@
     5.4  int next_swapchain_image;
     5.5  
     5.6  VkViewport vkvport;
     5.7 +VkRenderPass vkrpass;
     5.8  
     5.9  
    5.10  struct vku_buffer {
    5.11 @@ -52,6 +53,9 @@
    5.12  void vku_cmd_copybuf(VkCommandBuffer cmdbuf, VkBuffer dest, int doffs,
    5.13  		VkBuffer src, int soffs, int size);
    5.14  
    5.15 +VkRenderPass vku_create_renderpass(VkFormat cfmt, VkFormat dsfmt);
    5.16 +void vku_destroy_renderpass(VkRenderPass rpass);
    5.17 +
    5.18  /* platform-specific */
    5.19  #ifdef VK_USE_PLATFORM_XLIB_KHR
    5.20  #include <X11/Xlib.h>
     6.1 --- a/src/wsys_x11.c	Sat Jun 23 07:47:49 2018 +0300
     6.2 +++ b/src/wsys_x11.c	Mon Jun 25 08:00:57 2018 +0300
     6.3 @@ -228,6 +228,12 @@
     6.4  		swapchain_images = vku_get_swapchain_images(sc, 0);
     6.5  		next_swapchain_image = vku_get_next_image(swapchain);
     6.6  
     6.7 +		if(!vkrpass) {
     6.8 +			if(!(vkrpass = vku_create_renderpass(VK_FORMAT_R8G8B8_UNORM, VK_FORMAT_UNDEFINED))) {
     6.9 +				abort();
    6.10 +			}
    6.11 +		}
    6.12 +
    6.13  		if(cb.reshape) {
    6.14  			cb.reshape(win_width, win_height);
    6.15  		}