diff options
Diffstat (limited to 'drivers/vulkan')
-rw-r--r-- | drivers/vulkan/rendering_device_vulkan.cpp | 55 | ||||
-rw-r--r-- | drivers/vulkan/rendering_device_vulkan.h | 5 | ||||
-rw-r--r-- | drivers/vulkan/vulkan_context.cpp | 45 | ||||
-rw-r--r-- | drivers/vulkan/vulkan_context.h | 2 |
4 files changed, 69 insertions, 38 deletions
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index bcb6092d87..6a88f2c442 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -1733,7 +1733,7 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T ERR_FAIL_INDEX_V(p_format.samples, TEXTURE_SAMPLES_MAX, RID()); - image_create_info.samples = rasterization_sample_count[p_format.samples]; + image_create_info.samples = _ensure_supported_sample_count(p_format.samples); image_create_info.tiling = (p_format.usage_bits & TEXTURE_USAGE_CPU_READ_BIT) ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL; // Usage. @@ -1884,6 +1884,7 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T texture.mipmaps = image_create_info.mipLevels; texture.base_mipmap = 0; texture.base_layer = 0; + texture.is_resolve_buffer = p_format.is_resolve_buffer; texture.usage_flags = p_format.usage_bits; texture.samples = p_format.samples; texture.allowed_shared_formats = p_format.shareable_formats; @@ -3425,7 +3426,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF description.pNext = nullptr; description.flags = 0; description.format = vulkan_formats[p_attachments[i].format]; - description.samples = rasterization_sample_count[p_attachments[i].samples]; + description.samples = _ensure_supported_sample_count(p_attachments[i].samples); bool is_sampled = p_attachments[i].usage_flags & TEXTURE_USAGE_SAMPLING_BIT; bool is_storage = p_attachments[i].usage_flags & TEXTURE_USAGE_STORAGE_BIT; @@ -3546,7 +3547,8 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF break; } } - } else { + } + if (!used_last) { for (int j = 0; j < p_passes[last_pass].color_attachments.size(); j++) { if (p_passes[last_pass].color_attachments[j] == i) { used_last = true; @@ -4116,7 +4118,11 @@ RID RenderingDeviceVulkan::framebuffer_create(const Vector<RID> &p_texture_attac } else if (texture && texture->usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT) { pass.vrs_attachment = i; } else { - pass.color_attachments.push_back(texture ? i : FramebufferPass::ATTACHMENT_UNUSED); + if (texture && texture->is_resolve_buffer) { + pass.resolve_attachments.push_back(i); + } else { + pass.color_attachments.push_back(texture ? i : FramebufferPass::ATTACHMENT_UNUSED); + } } } @@ -6567,7 +6573,7 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma multisample_state_create_info.pNext = nullptr; multisample_state_create_info.flags = 0; - multisample_state_create_info.rasterizationSamples = rasterization_sample_count[p_multisample_state.sample_count]; + multisample_state_create_info.rasterizationSamples = _ensure_supported_sample_count(p_multisample_state.sample_count); multisample_state_create_info.sampleShadingEnable = p_multisample_state.enable_sample_shading; multisample_state_create_info.minSampleShading = p_multisample_state.min_sample_shading; Vector<VkSampleMask> sample_mask; @@ -7353,7 +7359,9 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu // If it is the first we're likely populating our VRS texture. // Bit dirty but... if (!texture || (!(texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && !(i != 0 && texture->usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT))) { - color_count++; + if (!texture || !texture->is_resolve_buffer) { + color_count++; + } } } ERR_FAIL_COND_V_MSG(p_clear_color_values.size() != color_count, INVALID_ID, "Clear color values supplied (" + itos(p_clear_color_values.size()) + ") differ from the amount required for framebuffer color attachments (" + itos(color_count) + ")."); @@ -7543,6 +7551,16 @@ RenderingDeviceVulkan::DrawList *RenderingDeviceVulkan::_get_draw_list_ptr(DrawL } } +void RenderingDeviceVulkan::draw_list_set_blend_constants(DrawListID p_list, const Color &p_color) { + DrawList *dl = _get_draw_list_ptr(p_list); + ERR_FAIL_COND(!dl); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_MSG(!dl->validation.active, "Submitted Draw Lists can no longer be modified."); +#endif + + vkCmdSetBlendConstants(dl->command_buffer, p_color.components); +} + void RenderingDeviceVulkan::draw_list_bind_render_pipeline(DrawListID p_list, RID p_render_pipeline) { DrawList *dl = _get_draw_list_ptr(p_list); ERR_FAIL_COND(!dl); @@ -7805,12 +7823,6 @@ void RenderingDeviceVulkan::draw_list_draw(DrawListID p_list, bool p_use_indices ERR_FAIL_COND_MSG(!dl->validation.index_array_size, "Draw command requested indices, but no index buffer was set."); - if (dl->validation.pipeline_vertex_format != INVALID_ID) { - // Uses vertices, do some vertex validations. - ERR_FAIL_COND_MSG(dl->validation.vertex_array_size < dl->validation.index_array_max_index, - "Index array references (max index: " + itos(dl->validation.index_array_max_index) + ") indices beyond the vertex array size (" + itos(dl->validation.vertex_array_size) + ")."); - } - ERR_FAIL_COND_MSG(dl->validation.pipeline_uses_restart_indices != dl->validation.index_buffer_uses_restart_indices, "The usage of restart indices in index buffer does not match the render primitive in the pipeline."); #endif @@ -8989,6 +9001,25 @@ void RenderingDeviceVulkan::_begin_frame() { frames[frame].index = Engine::get_singleton()->get_frames_drawn(); } +VkSampleCountFlagBits RenderingDeviceVulkan::_ensure_supported_sample_count(TextureSamples p_requested_sample_count) const { + VkSampleCountFlags sample_count_flags = limits.framebufferColorSampleCounts & limits.framebufferDepthSampleCounts; + + if (sample_count_flags & rasterization_sample_count[p_requested_sample_count]) { + // The requested sample count is supported. + return rasterization_sample_count[p_requested_sample_count]; + } else { + // Find the closest lower supported sample count. + VkSampleCountFlagBits sample_count = rasterization_sample_count[p_requested_sample_count]; + while (sample_count > VK_SAMPLE_COUNT_1_BIT) { + if (sample_count_flags & rasterization_sample_count[sample_count]) { + return sample_count; + } + sample_count = (VkSampleCountFlagBits)(sample_count >> 1); + } + } + return VK_SAMPLE_COUNT_1_BIT; +} + void RenderingDeviceVulkan::swap_buffers() { ERR_FAIL_COND_MSG(local_device.is_valid(), "Local devices can't swap buffers."); _THREAD_SAFE_METHOD_ diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 6572de7c52..abec1b0e1b 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -150,6 +150,8 @@ class RenderingDeviceVulkan : public RenderingDevice { bool used_in_raster = false; bool used_in_compute = false; + bool is_resolve_buffer = false; + uint32_t read_aspect_mask = 0; uint32_t barrier_aspect_mask = 0; bool bound = false; // Bound to framebffer. @@ -1042,6 +1044,8 @@ class RenderingDeviceVulkan : public RenderingDevice { HashMap<RID, String> resource_names; #endif + VkSampleCountFlagBits _ensure_supported_sample_count(TextureSamples p_requested_sample_count) const; + public: virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<Vector<uint8_t>> &p_data = Vector<Vector<uint8_t>>()); virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture); @@ -1155,6 +1159,7 @@ public: virtual DrawListID draw_list_begin(RID p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const Vector<RID> &p_storage_textures = Vector<RID>()); virtual Error draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, DrawListID *r_split_ids, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const Vector<RID> &p_storage_textures = Vector<RID>()); + virtual void draw_list_set_blend_constants(DrawListID p_list, const Color &p_color); virtual void draw_list_bind_render_pipeline(DrawListID p_list, RID p_render_pipeline); virtual void draw_list_bind_uniform_set(DrawListID p_list, RID p_uniform_set, uint32_t p_index); virtual void draw_list_bind_vertex_array(DrawListID p_list, RID p_vertex_array); diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index afc3e78372..b52179b4f3 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -1436,6 +1436,24 @@ bool VulkanContext::_use_validation_layers() { return Engine::get_singleton()->is_validation_layers_enabled(); } +VkExtent2D VulkanContext::_compute_swapchain_extent(const VkSurfaceCapabilitiesKHR &p_surf_capabilities, int *p_window_width, int *p_window_height) const { + // Width and height are either both 0xFFFFFFFF, or both not 0xFFFFFFFF. + if (p_surf_capabilities.currentExtent.width == 0xFFFFFFFF) { + // If the surface size is undefined, the size is set to the size + // of the images requested, which must fit within the minimum and + // maximum values. + VkExtent2D extent = {}; + extent.width = CLAMP((uint32_t)(*p_window_width), p_surf_capabilities.minImageExtent.width, p_surf_capabilities.maxImageExtent.width); + extent.height = CLAMP((uint32_t)(*p_window_height), p_surf_capabilities.minImageExtent.height, p_surf_capabilities.maxImageExtent.height); + return extent; + } else { + // If the surface size is defined, the swap chain size must match. + *p_window_width = p_surf_capabilities.currentExtent.width; + *p_window_height = p_surf_capabilities.currentExtent.height; + return p_surf_capabilities.currentExtent; + } +} + Error VulkanContext::_window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, VkSurfaceKHR p_surface, int p_width, int p_height) { ERR_FAIL_COND_V(windows.has(p_window_id), ERR_INVALID_PARAMETER); @@ -1576,32 +1594,7 @@ Error VulkanContext::_update_swap_chain(Window *window) { ERR_FAIL_V(ERR_CANT_CREATE); } - VkExtent2D swapchainExtent; - // Width and height are either both 0xFFFFFFFF, or both not 0xFFFFFFFF. - if (surfCapabilities.currentExtent.width == 0xFFFFFFFF) { - // If the surface size is undefined, the size is set to the size - // of the images requested, which must fit within the minimum and - // maximum values. - swapchainExtent.width = window->width; - swapchainExtent.height = window->height; - - if (swapchainExtent.width < surfCapabilities.minImageExtent.width) { - swapchainExtent.width = surfCapabilities.minImageExtent.width; - } else if (swapchainExtent.width > surfCapabilities.maxImageExtent.width) { - swapchainExtent.width = surfCapabilities.maxImageExtent.width; - } - - if (swapchainExtent.height < surfCapabilities.minImageExtent.height) { - swapchainExtent.height = surfCapabilities.minImageExtent.height; - } else if (swapchainExtent.height > surfCapabilities.maxImageExtent.height) { - swapchainExtent.height = surfCapabilities.maxImageExtent.height; - } - } else { - // If the surface size is defined, the swap chain size must match. - swapchainExtent = surfCapabilities.currentExtent; - window->width = surfCapabilities.currentExtent.width; - window->height = surfCapabilities.currentExtent.height; - } + VkExtent2D swapchainExtent = _compute_swapchain_extent(surfCapabilities, &window->width, &window->height); if (window->width == 0 || window->height == 0) { free(presentModes); diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h index 5cc3b515d9..9889cf336b 100644 --- a/drivers/vulkan/vulkan_context.h +++ b/drivers/vulkan/vulkan_context.h @@ -266,6 +266,8 @@ protected: Error _get_preferred_validation_layers(uint32_t *count, const char *const **names); + virtual VkExtent2D _compute_swapchain_extent(const VkSurfaceCapabilitiesKHR &p_surf_capabilities, int *p_window_width, int *p_window_height) const; + public: // Extension calls. VkResult vkCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass); |