diff options
Diffstat (limited to 'video.cpp')
| -rw-r--r-- | video.cpp | 363 | 
1 files changed, 284 insertions, 79 deletions
@@ -6,6 +6,7 @@  #define max_buffers 1024  #define max_vertex_formats 64  #define max_rpos 64 +#define max_fbos 64  #define max_pipelines 64  #define max_descriptor_sets 64  #define max_shaders 32 @@ -203,11 +204,42 @@ static VkFormat get_vk_format(Texture_Format fmt) {  		case texture_format_rgb16f:  return VK_FORMAT_R16G16B16_SFLOAT;  		case texture_format_rgb32f:  return VK_FORMAT_R32G32B32_SFLOAT;  		case texture_format_rgba8i:  return VK_FORMAT_R8G8B8A8_UNORM; +		case texture_format_rgba8i_srgb: return VK_FORMAT_R8G8B8A8_SRGB; +		case texture_format_bgra8i_srgb: return VK_FORMAT_B8G8R8A8_SRGB;  		case texture_format_rgba16f: return VK_FORMAT_R16G16B16A16_SFLOAT;  		case texture_format_rgba32f: return VK_FORMAT_R32G32B32A32_SFLOAT;  		case texture_format_bc1:     return VK_FORMAT_BC1_RGB_UNORM_BLOCK; -		default: assert(0); return VK_FORMAT_UNDEFINED; +		case texture_format_d16:     return VK_FORMAT_D16_UNORM; +		case texture_format_d24s8:   return VK_FORMAT_D24_UNORM_S8_UINT; +		case texture_format_d32:     return VK_FORMAT_D32_SFLOAT; +		case texture_format_count:   break;  	} +	assert(0); +	return VK_FORMAT_UNDEFINED; +} + +static VkImageUsageFlags get_texture_usage(int flags) { +	VkImageUsageFlags f = 0; +	if (flags & Texture_Flags::sampleable) +		f |= VK_IMAGE_USAGE_SAMPLED_BIT; +	if (flags & Texture_Flags::colour_target) +		f |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; +	if (flags & Texture_Flags::depth_stencil_target) +		f |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; +	if (flags & Texture_Flags::copy_src) +		f |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; +	if (flags & Texture_Flags::copy_dst) +		f |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; +	return f; +} + +static VkImageAspectFlags get_image_aspect(int flags) { +	VkImageUsageFlags f = 0; +	if (flags & Texture_Flags::depth_stencil_target) +		f |= VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; +	else +		f |= VK_IMAGE_ASPECT_COLOR_BIT; +	return f;  }  VkImageLayout state_to_image_layout(Resource_State s) { @@ -446,6 +478,7 @@ struct Shader_Vk : public Shader, public Late_Terminated {  };  struct Renderpass_Vk; +struct Framebuffer_Vk;  struct Context_Vk : public Context {  	int state;  	Device_Vk* dev; @@ -463,8 +496,10 @@ struct Context_Vk : public Context {  	void release();  	void destroy(); -	Renderpass_Vk& begin_rp(const Render_Pass& rp); -	void end_rp(Renderpass_Vk& rpo); +	std::pair<Renderpass_Vk&, Framebuffer_Vk&> begin_rp( +		const Render_Pass& rp +	); +	void end_rp(Renderpass_Vk& rpo, Framebuffer_Vk& fbo);  };  struct Texture_Vk : public Texture, public Late_Terminated { @@ -520,7 +555,14 @@ struct Rpo_Key {  	bool operator==(const Rpo_Key& other) const {  		return  			is_first == other.is_first && -			rpo == other.rpo; +			rpo.layout_eq(other.rpo); +	} +}; + +struct Fbo_Key { +	Render_Pass rpo; +	bool operator==(const Fbo_Key& other) const { +		return rpo.resources_eq(other.rpo);  	}  }; @@ -546,8 +588,6 @@ struct Dso_Key {  struct Renderpass_Vk {  	VkRenderPass rpo; -	VkFramebuffer fbo; -	VkClearValue clear;  	int age;  	void on_submit() { @@ -556,8 +596,23 @@ struct Renderpass_Vk {  	VkAttachmentLoadOp load_op_from_mode(Clear_Mode m); -	void init_rp(Device_Vk* dev, const Rpo_Key& rp); -	void init_fb(Device_Vk* dev, const Render_Pass& rp); +	void init(Device_Vk* dev, const Rpo_Key& rp); +	void destroy(Device_Vk* dev); +}; + +struct Framebuffer_Vk { +	VkFramebuffer fbo; +	int age; + +	void on_submit() { +		age = 0; +	} + +	void init( +		Device_Vk* dev, +		const Renderpass_Vk& rpo, +		const Render_Pass& rp +	);  	void destroy(Device_Vk* dev);  }; @@ -626,6 +681,8 @@ struct Pipeline_Vk {  		const Pipeline& desc  	); +	static VkCompareOp get_compare_op(Depth_Mode m); +  	void on_submit() {  		age = 0;  	} @@ -673,10 +730,18 @@ struct Sampler_Vk : public Late_Terminated {  template<>  struct Hash_Function<Rpo_Key> {  	size_t operator()(const Rpo_Key& k) const { -		return (size_t)fnv1a64_2(fnv1a64( -			(uint8_t*)&k.rpo, -			sizeof k.rpo -		), (uint8_t*)&k.is_first, 1); +		return (size_t)fnv1a64_2( +			k.rpo.layout_hash, +			(uint8_t*)&k.is_first, +			1 +		); +	} +}; + +template<> +struct Hash_Function<Fbo_Key> { +	size_t operator()(const Fbo_Key& k) const { +		return k.rpo.resource_hash;  	}  }; @@ -736,13 +801,6 @@ struct Hash_Function<Sampler_Id> {  	}  }; -template<> -struct std::hash<Render_Pass> { -	size_t operator()(const Render_Pass& rp) const { -		return (size_t)fnv1a64((uint8_t*)&rp, sizeof rp); -	} -}; -  struct Shader_Loader : public Asset_Loader {  	Device_Vk* dev;  	void init(Device_Vk* d); @@ -818,6 +876,7 @@ struct Device_Vk : public Device {  	uint32_t sampler_count;  	Hash_Map<Rpo_Key, Renderpass_Vk, max_rpos> rpo_cache; +	Hash_Map<Fbo_Key, Framebuffer_Vk, max_fbos> fbo_cache;  	Hash_Map<Pso_Key, Pipeline_Vk, max_pipelines> pso_cache;  	Hash_Map<Dso_Key, Descriptor_Set_Vk, max_descriptor_sets> dso_cache; @@ -825,6 +884,8 @@ struct Device_Vk : public Device {  	uint32_t terminator_index;  	bool first_rp; +	Texture_Id depth; +  	Texture_Id alloc_texture();  	Buffer_Id alloc_buffer();  	Vertex_Format_Id alloc_vf(); @@ -846,6 +907,14 @@ struct Device_Vk : public Device {  	Renderpass_Vk& create_rpo(const Rpo_Key& rp);  	Renderpass_Vk& get_rpo(const Rpo_Key& rp); +	Framebuffer_Vk& create_fbo( +		const Renderpass_Vk& rpo, +		const Fbo_Key& fb +	); +	Framebuffer_Vk& get_fbo( +		const Renderpass_Vk& rpo, +		const Fbo_Key& fb +	);  	Pipeline_Vk& create_pso(const Pso_Key& pip);  	Pipeline_Vk& get_pso(const Pso_Key& pop);  	Descriptor_Set_Vk& create_dso( @@ -860,6 +929,7 @@ struct Device_Vk : public Device {  	void collect_garbage();  	void queue_destroy(Late_Terminated* obj);  	void create_terminators(); +	void create_depth(int w, int h);  	int find_memory_type(  		uint32_t filter, @@ -1175,6 +1245,7 @@ void Device_Vk::init_internal() {  	samplers.init();  	sampler_count = 1;  	rpo_cache.init(); +	fbo_cache.init();  	pso_cache.init();  	dso_cache.init();  	shader_loader.init(this); @@ -1198,6 +1269,8 @@ void Device_Vk::init_internal() {  		contexts[i].state = context_state_avail;  	swapchain.init(*app, this);  	create_terminators(); +	depth = 0; +	create_depth(app->w, app->h);  }  void Device_Vk::create_terminators() { @@ -1216,14 +1289,29 @@ void Device_Vk::create_terminators() {  	}  } +void Device_Vk::create_depth(int w, int h) { +	if (depth) +		destroy_texture(depth); +	depth = create_texture( +		texture_format_d24s8, +		Texture_Flags::sampleable | Texture_Flags::depth_stencil_target, +		w, +		h, +		0 +	); +} +  void Device_Vk::deinit_internal() {  	int i, image_count = swapchain.image_count;  	vkDeviceWaitIdle(dev); +	destroy_texture(depth);  	swapchain.destroy(this);  	deinit_swap_cap(this, &swap_cap);  	app_destroy_vk_surface(app, inst, surf);  	for (auto i : rpo_cache)  		i.second.destroy(this); +	for (auto i : fbo_cache) +		i.second.destroy(this);  	for (auto i : pso_cache)  		i.second.destroy(this);  	for (auto i : dso_cache) @@ -1255,20 +1343,13 @@ void Device_Vk::on_resize_internal(int w, int h) {  	get_swap_cap(this, phys_dev, surf, &swap_cap);  	swapchain.recreate(*app, this);  	create_terminators(); +	create_depth(w, h);  }  Renderpass_Vk& Device_Vk::create_rpo(const Rpo_Key& k) { -	VkClearValue clear{}; -	auto& rp = k.rpo; -	clear.color.float32[0] = (float)rp.clear.r / 255.0f; -	clear.color.float32[1] = (float)rp.clear.g / 255.0f; -	clear.color.float32[2] = (float)rp.clear.b / 255.0f; -	clear.color.float32[3] = (float)rp.clear.a / 255.0f;  	Renderpass_Vk rpo; -	rpo.init_rp(this, k); -	rpo.init_fb(this, rp); +	rpo.init(this, k);  	rpo.age = 0; -	rpo.clear = clear;  	return rpo_cache.set(k, rpo);  } @@ -1279,6 +1360,27 @@ Renderpass_Vk& Device_Vk::get_rpo(const Rpo_Key& rp) {  	return *rpo;  } +Framebuffer_Vk& Device_Vk::create_fbo( +	const Renderpass_Vk& rpo, +	const Fbo_Key& k +) { +	auto& fb = k.rpo; +	Framebuffer_Vk fbo; +	fbo.init(this, rpo, fb); +	fbo.age = 0; +	return fbo_cache.set(k, fbo); +} + +Framebuffer_Vk& Device_Vk::get_fbo( +	const Renderpass_Vk& rpo, +	const Fbo_Key& fb +) { +	Framebuffer_Vk* fbo = fbo_cache.get(fb); +	if (!fbo) +		return create_fbo(rpo, fb); +	return *fbo; +} +  Pipeline_Vk& Device_Vk::create_pso(const Pso_Key& pip) {  	Pipeline_Vk pso;  	pso.age = 0; @@ -1313,11 +1415,6 @@ Descriptor_Set_Vk& Device_Vk::get_dso(  	return *dso;  } -void Renderpass_Vk::destroy(Device_Vk* dev) { -	vkDestroyRenderPass(dev->dev, rpo, &dev->ac); -	vkDestroyFramebuffer(dev->dev, fbo, &dev->ac); -} -  void Device_Vk::collect_garbage() {  	int max_age = swapchain.image_count + 3;  	for (const auto& i: rpo_cache) { @@ -1328,6 +1425,14 @@ void Device_Vk::collect_garbage() {  			rpo_cache.remove(i.first);  		}  	} +	for (const auto& i: fbo_cache) { +		auto& fb = i.second; +		fb.age++; +		if (fb.age > max_age) { +			fb.destroy(this); +			fbo_cache.remove(i.first); +		} +	}  	for (const auto& i: pso_cache) {  		auto& pip = i.second;  		pip.age++; @@ -1377,39 +1482,63 @@ VkAttachmentLoadOp Renderpass_Vk::load_op_from_mode(  	return VK_ATTACHMENT_LOAD_OP_DONT_CARE;  } -void Renderpass_Vk::init_rp( +void Renderpass_Vk::init(  	Device_Vk* dev,  	const Rpo_Key& rpk  ) {  	VkRenderPassCreateInfo ri{}; -	VkAttachmentDescription ad{}; -	VkAttachmentReference ar{}; +	VkAttachmentDescription ads[2]; +	VkAttachmentReference car, dar;  	VkSubpassDescription sd{};  	VkResult r;  	auto& rp = rpk.rpo; - -	ad.format = dev->swapchain.format.format; -	ad.samples = VK_SAMPLE_COUNT_1_BIT; -	ad.loadOp = load_op_from_mode(rp.mode); -	ad.storeOp = VK_ATTACHMENT_STORE_OP_STORE; -	ad.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; -	ad.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; -	if (rpk.is_first) -		ad.initialLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; -	else -		ad.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; -	ad.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - -	ar.attachment = 0; -	ar.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; +	bool has_depth = rp.depth.id; +	int count = 0, i, c = rp.colour_count; +	zero(ads, sizeof ads); +	for (i = 0; i < c; i++) { +		int index = count++; +		auto& colour = rp.colours[i]; +		auto& ad = ads[index]; +		ad.format = get_vk_format(colour.fmt); +		ad.samples = VK_SAMPLE_COUNT_1_BIT; +		ad.loadOp = load_op_from_mode(colour.mode); +		ad.storeOp = VK_ATTACHMENT_STORE_OP_STORE; +		ad.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; +		ad.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; +		if (rpk.is_first) +			ad.initialLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; +		else +			ad.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; +		ad.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; +		car.attachment = index; +		car.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; +	} +	if (has_depth) { +		int i = count++; +		auto& ad = ads[i]; +		ad.format = get_vk_format(dev->get_texture(rp.depth.id).fmt); +		ad.samples = VK_SAMPLE_COUNT_1_BIT; +		ad.loadOp = load_op_from_mode(rp.depth.mode); +		ad.storeOp = VK_ATTACHMENT_STORE_OP_STORE; +		ad.stencilLoadOp = ad.loadOp; +		ad.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; +		if (rpk.is_first) +			ad.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; +		else +			ad.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; +		ad.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; +		dar.attachment = i; +		dar.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; +	}  	sd.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;  	sd.colorAttachmentCount = 1; -	sd.pColorAttachments = &ar; +	sd.pColorAttachments = &car; +	sd.pDepthStencilAttachment = has_depth? &dar: 0;  	ri.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; -	ri.attachmentCount = 1; -	ri.pAttachments = &ad; +	ri.attachmentCount = count; +	ri.pAttachments = ads;  	ri.subpassCount = 1;  	ri.pSubpasses = &sd; @@ -1420,21 +1549,42 @@ void Renderpass_Vk::init_rp(  	}  } -void Renderpass_Vk::init_fb( +void Renderpass_Vk::destroy(Device_Vk* dev) { +	vkDestroyRenderPass(dev->dev, rpo, &dev->ac); +} + +void Framebuffer_Vk::init(  	Device_Vk* dev, +	const Renderpass_Vk& rpo,  	const Render_Pass& rp  ) { -	const Texture_Vk& texture = -		*(const Texture_Vk*)&dev->get_texture(rp.target); +	bool has_depth = rp.depth.id; +	int i, count = 0, w, h; +	VkImageView atts[2];  	VkResult r;  	VkFramebufferCreateInfo fbi{}; +	for (i = 0; i < rp.colour_count; i++) { +		const auto& tar = rp.colours[i]; +		const Texture_Vk& texture = +			*(const Texture_Vk*)&dev->get_texture(tar.id); +		atts[count++] = texture.view; +		w = texture.w; +		h = texture.h; +	} +	if (has_depth) { +		const Texture_Vk& texture = +			*(const Texture_Vk*)&dev->get_texture(rp.depth.id); +		atts[count++] = texture.view; +		w = texture.w; +		h = texture.h; +	}  	fbi.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; -	fbi.renderPass = rpo; -	fbi.width = texture.w; -	fbi.height = texture.h; +	fbi.renderPass = rpo.rpo; +	fbi.width = w; +	fbi.height = h;  	fbi.layers = 1; -	fbi.attachmentCount = 1; -	fbi.pAttachments = &texture.view; +	fbi.attachmentCount = count; +	fbi.pAttachments = atts;  	r = vkCreateFramebuffer(dev->dev, &fbi, &dev->ac, &fbo);  	if (r != VK_SUCCESS) {  		print_err("Failed to create a framebuffer.\n"); @@ -1442,6 +1592,10 @@ void Renderpass_Vk::init_fb(  	}  } +void Framebuffer_Vk::destroy(Device_Vk* dev) { +	vkDestroyFramebuffer(dev->dev, fbo, &dev->ac); +} +  static int get_image_count(const Swap_Cap& s) {  	const VkSurfaceCapabilitiesKHR& cap = s.cap;  	return cap.minImageCount + (cap.minImageCount < cap.maxImageCount); @@ -1479,7 +1633,7 @@ static VkImageView make_view(  	Device_Vk* dev,  	VkImage image,  	VkFormat fmt, -	VkImageAspectFlagBits flags +	VkImageAspectFlags flags  ) {  	VkImageViewCreateInfo vi{};  	VkResult r; @@ -1568,6 +1722,7 @@ Texture_Id Swapchain::create_image(  	tex.view = view;  	tex.w = w;  	tex.h = h; +	tex.fmt = texture_format_bgra8i_srgb;  	tex.alias = true;  	return id;  } @@ -1716,6 +1871,10 @@ Texture_Id Device::get_backbuffer() {  	return ((Device_Vk*)this)->backbuffer_id;  } +Texture_Id Device::get_depth_target() { +	return ((Device_Vk*)this)->depth; +} +  Texture& Device::get_texture(Texture_Id id) {  	return ((Device_Vk*)this)->textures[id];  } @@ -1802,7 +1961,7 @@ void Context::submit(  	Descriptor_Set_Vk* dso = 0;  	if (p.descriptor_count)  		dso = &dev->get_dso(pso, *(Dso_Key*)&p); -	auto& rpo = ctx->begin_rp(rp); +	auto [rpo, fbo] = ctx->begin_rp(rp);  	Texture_Vk& target = *(Texture_Vk*)&dev->get_texture(  		dev->get_backbuffer()  	); @@ -1855,7 +2014,7 @@ void Context::submit(  			draw.first_instance  		);  	} -	ctx->end_rp(rpo); +	ctx->end_rp(rpo, fbo);  	pso.on_submit();  	if (dso)  		dso->on_submit(); @@ -2003,33 +2162,56 @@ void Context::transition(Texture_Id id, Resource_State state) {  	);  } -Renderpass_Vk& Context_Vk::begin_rp(const Render_Pass& rp) { +std::pair<Renderpass_Vk&, Framebuffer_Vk&> Context_Vk::begin_rp( +	const Render_Pass& rp +) {  	Renderpass_Vk& rpo = dev->get_rpo({ dev->first_rp, rp}); +	Framebuffer_Vk& fbo = dev->get_fbo(rpo, { rp });  	VkRenderPassBeginInfo rpbi{}; +	VkClearValue clears[max_colour_attachments + 1]; +	int i, c = rp.colour_count, clear_count = 0; +	bool has_depth = rp.depth.id; +	for (i = 0; i < c; i++) { +		VkClearValue clear{}; +		const auto& tar = rp.colours[i]; +		const auto col = tar.clear.colour; +		clear.color.float32[0] = (float)col.r / 255.0f; +		clear.color.float32[1] = (float)col.g / 255.0f; +		clear.color.float32[2] = (float)col.b / 255.0f; +		clear.color.float32[3] = (float)col.a / 255.0f; +		clears[clear_count++] = clear; +	} +	if (has_depth) { +		VkClearValue dc{}; +		dc.depthStencil.depth = rp.depth.clear.depth; +		dc.depthStencil.stencil = 0; /* todo */ +		clears[clear_count++] = dc; +	}  	rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;  	rpbi.renderPass = rpo.rpo; -	rpbi.framebuffer = rpo.fbo; +	rpbi.framebuffer = fbo.fbo;  	rpbi.renderArea.extent = dev->swapchain.size; -	rpbi.clearValueCount = rp.mode == Clear_Mode::clear? 1: 0; -	rpbi.pClearValues = &rpo.clear; +	rpbi.clearValueCount = clear_count; +	rpbi.pClearValues = clears;  	vkCmdBeginRenderPass(  		cb,  		&rpbi,  		VK_SUBPASS_CONTENTS_INLINE  	);  	dev->first_rp = false; -	return rpo; +	return { rpo, fbo };  } -void Context_Vk::end_rp(Renderpass_Vk& rpo) { +void Context_Vk::end_rp(Renderpass_Vk& rpo, Framebuffer_Vk& fbo) {  	vkCmdEndRenderPass(cb);  	rpo.on_submit(); +	fbo.on_submit();  }  void Context::submit(const Render_Pass& rp) {  	Context_Vk* ctx = (Context_Vk*)this; -	auto& rpo = ctx->begin_rp(rp); -	ctx->end_rp(rpo); +	auto [rpo, fbo] = ctx->begin_rp(rp); +	ctx->end_rp(rpo, fbo);  }  void Context_Vk::init_pool() { @@ -2305,9 +2487,9 @@ void Pipeline_Vk::init_depthstencil(  	(void)desc;  	zero(&ds, sizeof ds);  	ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; -	ds.depthTestEnable = VK_FALSE; -	ds.depthWriteEnable = VK_FALSE; -	ds.depthCompareOp = VK_COMPARE_OP_LESS; +	ds.depthTestEnable = desc.depth_test; +	ds.depthWriteEnable = desc.depth_write; +	ds.depthCompareOp = get_compare_op(desc.depth_mode);  	ds.depthBoundsTestEnable = VK_FALSE;  	ds.stencilTestEnable = VK_FALSE;  	info.pDepthStencilState = &ds; @@ -2403,6 +2585,20 @@ void Pipeline_Vk::init_descriptors(  	}  } +VkCompareOp Pipeline_Vk::get_compare_op(Depth_Mode m) { +	switch (m) { +		case Depth_Mode::less:          return VK_COMPARE_OP_LESS; +		case Depth_Mode::less_equal:    return VK_COMPARE_OP_LESS_OR_EQUAL; +		case Depth_Mode::equal:         return VK_COMPARE_OP_EQUAL; +		case Depth_Mode::greater:       return VK_COMPARE_OP_GREATER; +		case Depth_Mode::greater_equal: return VK_COMPARE_OP_GREATER_OR_EQUAL; +		case Depth_Mode::always:        return VK_COMPARE_OP_ALWAYS; +		case Depth_Mode::never:         return VK_COMPARE_OP_NEVER; +	} +	assert(0); +	return VK_COMPARE_OP_LESS; +} +  void Pipeline_Vk::init_layout(  	Device_Vk* dev,  	const Pipeline& desc @@ -2903,6 +3099,7 @@ Buffer& Device::get_buffer(Buffer_Id id) {  Texture_Id Device::create_texture(  	Texture_Format fmt, +	int flags,  	int w,  	int h,  	Buffer_Id init @@ -2913,6 +3110,7 @@ Texture_Id Device::create_texture(  	Texture_Id id = dev->alloc_texture();  	Texture_Vk& tex = *(Texture_Vk*)&dev->get_texture(id);  	VkMemoryRequirements req; +	VkImageAspectFlags aspect = get_image_aspect(flags);  	tex.state = Resource_State::undefined;  	ii.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;  	ii.imageType = VK_IMAGE_TYPE_2D; @@ -2924,7 +3122,7 @@ Texture_Id Device::create_texture(  	ii.format = get_vk_format(fmt);  	ii.tiling = VK_IMAGE_TILING_OPTIMAL;  	ii.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; -	ii.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; +	ii.usage = get_texture_usage(flags);  	ii.sharingMode = VK_SHARING_MODE_EXCLUSIVE;  	ii.samples = VK_SAMPLE_COUNT_1_BIT;  	r = vkCreateImage(dev->dev, &ii, &dev->ac, &tex.image); @@ -2957,12 +3155,13 @@ Texture_Id Device::create_texture(  	vkBindImageMemory(dev->dev, tex.image, tex.memory, 0);  	tex.w = w;  	tex.h = h; +	tex.fmt = fmt;  	tex.alias = false;  	tex.view = make_view(  		dev,  		tex.image,  		ii.format, -		VK_IMAGE_ASPECT_COLOR_BIT +		aspect  	);  	if (init) {  		Context& ctx = dev->acquire(); @@ -3170,7 +3369,13 @@ Asset* Texture_Loader::load(Arena* a, Arena* s, Pack_File* f) {  	pack_read(f, data, size);  	{  		Buffer_Id buf = upload(data, size); -		Texture_Id tex = dev->create_texture(fmt, w, h, buf); +		Texture_Id tex = dev->create_texture( +			fmt, +			Texture_Flags::sampleable | Texture_Flags::copy_dst, +			w, +			h, +			buf +		);  		dev->destroy_buffer(buf);  		return &dev->get_texture(tex);  	}  |