diff options
author | quou <quou@disroot.org> | 2025-03-10 13:18:03 +1100 |
---|---|---|
committer | quou <quou@disroot.org> | 2025-03-10 13:18:03 +1100 |
commit | a7ef36bc519dff1700048ba8f21658daa138a81a (patch) | |
tree | 8778d112afdf21be6c1856fc062b8969f5ee3739 /video.cpp | |
parent | 0bc95e2084b970819d15306f7e3ab8b81a108dcd (diff) |
msaa
Diffstat (limited to 'video.cpp')
-rw-r--r-- | video.cpp | 115 |
1 files changed, 100 insertions, 15 deletions
@@ -561,7 +561,8 @@ struct Texture_Vk : public Texture, public Late_Terminated { int array_size, int start_mip, int start_array, - bool alias + bool alias, + int samples ); void destroy(Device_Vk*) override; void set_name(Device_Vk* dev, const char* name); @@ -732,7 +733,8 @@ struct Pipeline_Vk { Arena& scope, Device_Vk* dev, VkGraphicsPipelineCreateInfo& info, - const Pipeline& desc + const Pipeline& desc, + const Render_Pass& rpo ); void init_depthstencil( Arena& scope, @@ -934,6 +936,7 @@ struct Device_Vk : public Device { VkPhysicalDevice phys_dev; VkSurfaceKHR surf; uint32_t backbuffer_index; + VkSampleCountFlagBits max_samples; Texture_Id backbuffer_id; Swap_Cap swap_cap; VkPhysicalDeviceMemoryProperties mem_props; @@ -1021,6 +1024,9 @@ struct Device_Vk : public Device { void create_terminators(); void create_depth(int w, int h); + VkSampleCountFlagBits get_max_samples(); + VkSampleCountFlagBits get_samples(int); + int find_memory_type( uint32_t filter, VkMemoryPropertyFlags flags @@ -1114,6 +1120,37 @@ void Device_Vk::init_validation() { #endif +VkSampleCountFlagBits Device_Vk::get_max_samples() { + VkPhysicalDeviceProperties p; + VkSampleCountFlagBits + i = VK_SAMPLE_COUNT_64_BIT, + e = VK_SAMPLE_COUNT_1_BIT; + VkSampleCountFlags c; + vkGetPhysicalDeviceProperties(phys_dev, &p); + c = + p.limits.framebufferColorSampleCounts & + p.limits.framebufferDepthSampleCounts; + for (; i >= e; i = (VkSampleCountFlagBits)(i >> 1)) + if (c & i) return i; + return VK_SAMPLE_COUNT_1_BIT; +} + +VkSampleCountFlagBits Device_Vk::get_samples( + int c +) { + VkSampleCountFlagBits b = VK_SAMPLE_COUNT_1_BIT; + switch (c) { + case 1: b = VK_SAMPLE_COUNT_1_BIT; break; + case 2: b = VK_SAMPLE_COUNT_2_BIT; break; + case 4: b = VK_SAMPLE_COUNT_4_BIT; break; + case 8: b = VK_SAMPLE_COUNT_8_BIT; break; + case 16: b = VK_SAMPLE_COUNT_16_BIT; break; + case 32: b = VK_SAMPLE_COUNT_32_BIT; break; + case 64: b = VK_SAMPLE_COUNT_64_BIT; break; + default: break; + } + return std::min(max_samples, b); +} bool Device_Vk::has_validation() { unsigned count, i; @@ -1352,6 +1389,7 @@ void Device_Vk::init_internal() { #endif surf = app_create_vk_surface(app, inst); create_dev(&swap_cap); + max_samples = get_max_samples(); vrama.init(this); gladLoaderLoadVulkan(inst, phys_dev, dev); vkGetDeviceQueue(dev, (uint32_t)queue_index, 0, &queue); @@ -1642,7 +1680,7 @@ void Renderpass_Vk::init( auto& colour = rp.colours[i]; auto& ad = ads[index]; ad.format = get_vk_format(colour.fmt); - ad.samples = VK_SAMPLE_COUNT_1_BIT; + ad.samples = dev->get_samples(colour.samples); ad.loadOp = load_op_from_mode(colour.mode); ad.storeOp = VK_ATTACHMENT_STORE_OP_STORE; ad.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; @@ -1659,9 +1697,10 @@ void Renderpass_Vk::init( 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); + auto& depth = rp.depth; + ad.format = get_vk_format(dev->get_texture(depth.id).fmt); + ad.samples = dev->get_samples(depth.samples); + ad.loadOp = load_op_from_mode(depth.mode); ad.storeOp = VK_ATTACHMENT_STORE_OP_STORE; ad.stencilLoadOp = ad.loadOp; ad.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; @@ -1887,7 +1926,8 @@ Texture_Id Swapchain::create_image( 1, 0, 0, - true + true, + 1 ); return id; } @@ -2286,6 +2326,37 @@ void Context::copy( ); } +void Context::resolve(Texture_Id dst, Texture_Id src) { + Context_Vk* ctx = (Context_Vk*)this; + Device_Vk* dev = ctx->dev; + Texture_Vk& d = *(Texture_Vk*)&dev->get_texture(dst); + Texture_Vk& s = *(Texture_Vk*)&dev->get_texture(src); + VkImageResolve r{}; + r.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + r.srcSubresource.layerCount = 1; + r.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + r.dstSubresource.layerCount = 1; + r.extent.width = d.w; + r.extent.height = d.h; + r.extent.depth = 1; + assert(d.w == s.w); + assert(d.h == s.h); + assert(d.d == 1 && s.d == 1); + assert(d.samples == 1 && s.samples > 1); + ctx->check_end_rp(); + transition(src, Resource_State::copy_src); + transition(dst, Resource_State::copy_dst); + vkCmdResolveImage( + ctx->cb, + s.image, + state_to_image_layout(s.state), + d.image, + state_to_image_layout(d.state), + 1, + &r + ); +} + void Context::transition(Texture_Id id, Resource_State state) { Context_Vk* ctx = (Context_Vk*)this; Device_Vk* dev = ctx->dev; @@ -2434,6 +2505,14 @@ void Context::transition(Texture_Id id, Resource_State state) { b.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; src_stage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; dst_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + } else if ( + src_layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && + dst_layout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL + ) { + b.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + b.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + src_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dst_stage = VK_PIPELINE_STAGE_TRANSFER_BIT; } else { print_err("Bad resource transition.\n"); assert(0); @@ -2857,7 +2936,8 @@ void Pipeline_Vk::init_msaa( Arena& scope, Device_Vk* dev, VkGraphicsPipelineCreateInfo& info, - const Pipeline& desc + const Pipeline& desc, + const Render_Pass& rpo ) { VkPipelineMultisampleStateCreateInfo& mi = *(VkPipelineMultisampleStateCreateInfo*)arena_alloc( @@ -2869,7 +2949,7 @@ void Pipeline_Vk::init_msaa( zero(&mi, sizeof mi); mi.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; mi.sampleShadingEnable = VK_FALSE; - mi.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + mi.rasterizationSamples = dev->get_samples(rpo.get_samples()); info.pMultisampleState = &mi; } @@ -3064,7 +3144,7 @@ void Pipeline_Vk::init(Device_Vk* dev, const Pso_Key& key) { init_input_assembly(scope, dev, info, desc); init_viewport(scope, info, desc); init_rasterisation(scope, dev, info, desc); - init_msaa(scope, dev, info, desc); + init_msaa(scope, dev, info, desc, key.rpo.rpo); init_depthstencil(scope, dev, info, desc); init_blending(scope, dev, info, key.rpo.rpo, desc); info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; @@ -3594,7 +3674,8 @@ Texture_Id Device::create_texture( int d, int mip_count, int array_size, - Buffer_Id init + Buffer_Id init, + int samples ) { VkImageCreateInfo ii{}; VkResult r; @@ -3626,7 +3707,7 @@ Texture_Id Device::create_texture( ii.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; ii.usage = get_texture_usage(flags); ii.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - ii.samples = VK_SAMPLE_COUNT_1_BIT; + ii.samples = dev->get_samples(samples); ii.flags = image_flags; r = vkCreateImage(dev->dev, &ii, &dev->ac, &image); if (r != VK_SUCCESS) { @@ -3684,7 +3765,8 @@ Texture_Id Device::create_texture( array_size, 0, 0, - false + false, + samples ); if (init) { Context& ctx = dev->acquire(); @@ -3747,7 +3829,8 @@ Texture_Id Device::alias_texture( array_size, start_mip, start_array, - true + true, + texture.samples ); nt.set_name(dev, name); return ntid; @@ -4049,7 +4132,8 @@ void Texture_Vk::init( int array_size, int start_mip, int start_array, - bool alias + bool alias, + int samples ) { t->id = id; t->parent = parent; @@ -4069,6 +4153,7 @@ void Texture_Vk::init( t->start_mip = start_mip; t->start_array = start_array; t->alias = alias; + t->samples = samples; } void Texture_Vk::destroy(Device_Vk* dev) { |