diff options
Diffstat (limited to 'drivers/vulkan')
-rw-r--r-- | drivers/vulkan/rendering_device_vulkan.cpp | 356 | ||||
-rw-r--r-- | drivers/vulkan/rendering_device_vulkan.h | 41 | ||||
-rw-r--r-- | drivers/vulkan/vulkan_context.cpp | 5 |
3 files changed, 267 insertions, 135 deletions
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 7e9d11137e..118679a8b5 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -1950,6 +1950,9 @@ RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p ERR_FAIL_COND_V_MSG(p_slice_type == TEXTURE_SLICE_CUBEMAP && (src_texture->type != TEXTURE_TYPE_CUBE && src_texture->type != TEXTURE_TYPE_CUBE_ARRAY), RID(), "Can only create a cubemap slice from a cubemap or cubemap array mipmap"); + ERR_FAIL_COND_V_MSG(p_slice_type == TEXTURE_SLICE_3D && src_texture->type != TEXTURE_TYPE_3D, RID(), + "Can only create a 3D slice from a 3D texture"); + //create view ERR_FAIL_INDEX_V(p_mipmap, src_texture->mipmaps, RID()); @@ -1976,7 +1979,7 @@ RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p VK_IMAGE_VIEW_TYPE_2D, }; - image_view_create_info.viewType = p_slice_type == TEXTURE_SLICE_CUBEMAP ? VK_IMAGE_VIEW_TYPE_CUBE : view_types[texture.type]; + image_view_create_info.viewType = p_slice_type == TEXTURE_SLICE_CUBEMAP ? VK_IMAGE_VIEW_TYPE_CUBE : (p_slice_type == TEXTURE_SLICE_3D ? VK_IMAGE_VIEW_TYPE_3D : view_types[texture.type]); if (p_view.format_override == DATA_FORMAT_MAX || p_view.format_override == texture.format) { image_view_create_info.format = vulkan_formats[texture.format]; } else { @@ -2676,6 +2679,94 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, return OK; } +Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, bool p_sync_with_draw) { + + Texture *src_tex = texture_owner.getornull(p_texture); + ERR_FAIL_COND_V(!src_tex, ERR_INVALID_PARAMETER); + + ERR_FAIL_COND_V_MSG(p_sync_with_draw && src_tex->bound, ERR_INVALID_PARAMETER, + "Source texture can't be cleared while a render pass that uses it is being created. Ensure render pass is finalized (and that it was created with RENDER_PASS_CONTENTS_FINISH) to unbind this texture."); + + ERR_FAIL_COND_V(p_layers == 0, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(p_mipmaps == 0, ERR_INVALID_PARAMETER); + + ERR_FAIL_COND_V_MSG(!(src_tex->usage_flags & TEXTURE_USAGE_CAN_COPY_TO_BIT), ERR_INVALID_PARAMETER, + "Source texture requires the TEXTURE_USAGE_CAN_COPY_TO_BIT in order to be cleared."); + + uint32_t src_layer_count = src_tex->layers; + if (src_tex->type == TEXTURE_TYPE_CUBE || src_tex->type == TEXTURE_TYPE_CUBE_ARRAY) { + src_layer_count *= 6; + } + + ERR_FAIL_COND_V(p_base_mipmap + p_mipmaps > src_tex->mipmaps, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(p_base_layer + p_layers > src_layer_count, ERR_INVALID_PARAMETER); + + VkCommandBuffer command_buffer = p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer; + + VkImageLayout layout = src_tex->layout; + + if (src_tex->layout != VK_IMAGE_LAYOUT_GENERAL) { //storage may be in general state + VkImageMemoryBarrier image_memory_barrier; + image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + image_memory_barrier.pNext = NULL; + image_memory_barrier.srcAccessMask = 0; + image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + image_memory_barrier.oldLayout = src_tex->layout; + image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + + image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_memory_barrier.image = src_tex->image; + image_memory_barrier.subresourceRange.aspectMask = src_tex->read_aspect_mask; + image_memory_barrier.subresourceRange.baseMipLevel = p_base_mipmap; + image_memory_barrier.subresourceRange.levelCount = p_mipmaps; + image_memory_barrier.subresourceRange.baseArrayLayer = p_base_layer; + image_memory_barrier.subresourceRange.layerCount = p_layers; + + layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1, &image_memory_barrier); + } + + VkClearColorValue clear_color; + clear_color.float32[0] = p_color.r; + clear_color.float32[1] = p_color.g; + clear_color.float32[2] = p_color.b; + clear_color.float32[3] = p_color.a; + + VkImageSubresourceRange range; + range.aspectMask = src_tex->read_aspect_mask; + range.baseArrayLayer = p_base_layer; + range.layerCount = p_layers; + range.baseMipLevel = p_base_mipmap; + range.levelCount = p_mipmaps; + + vkCmdClearColorImage(command_buffer, src_tex->image, layout, &clear_color, 1, &range); + + if (src_tex->layout != VK_IMAGE_LAYOUT_GENERAL) { //storage may be in general state + + VkImageMemoryBarrier image_memory_barrier; + image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + image_memory_barrier.pNext = NULL; + image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + image_memory_barrier.newLayout = src_tex->layout; + + image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_memory_barrier.image = src_tex->image; + image_memory_barrier.subresourceRange.aspectMask = src_tex->read_aspect_mask; + image_memory_barrier.subresourceRange.baseMipLevel = p_base_mipmap; + image_memory_barrier.subresourceRange.levelCount = p_mipmaps; + image_memory_barrier.subresourceRange.baseArrayLayer = p_base_layer; + image_memory_barrier.subresourceRange.layerCount = p_layers; + + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, NULL, 0, NULL, 1, &image_memory_barrier); + } + + return OK; +} + bool RenderingDeviceVulkan::texture_is_format_supported_for_usage(DataFormat p_format, uint32_t p_usage) const { ERR_FAIL_INDEX_V(p_format, DATA_FORMAT_MAX, false); @@ -2719,7 +2810,7 @@ bool RenderingDeviceVulkan::texture_is_format_supported_for_usage(DataFormat p_f /**** ATTACHMENT ****/ /********************/ -VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentFormat> &p_format, InitialAction p_initial_action, FinalAction p_final_action, int *r_color_attachment_count) { +VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentFormat> &p_format, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, int *r_color_attachment_count) { Vector<VkAttachmentDescription> attachments; Vector<VkAttachmentReference> color_references; @@ -2739,17 +2830,18 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF ERR_FAIL_COND_V_MSG(!(p_format[i].usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_RESOLVE_ATTACHMENT_BIT)), VK_NULL_HANDLE, "Texture format for index (" + itos(i) + ") requires an attachment (depth, stencil or resolve) bit set."); + bool is_depth_stencil = p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; bool is_sampled = p_format[i].usage_flags & TEXTURE_USAGE_SAMPLING_BIT; bool is_storage = p_format[i].usage_flags & TEXTURE_USAGE_STORAGE_BIT; - switch (p_initial_action) { + switch (is_depth_stencil ? p_initial_depth_action : p_initial_color_action) { case INITIAL_ACTION_CLEAR: { description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there } break; - case INITIAL_ACTION_KEEP_COLOR: { + case INITIAL_ACTION_KEEP: { if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); @@ -2764,22 +2856,6 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there } } break; - case INITIAL_ACTION_KEEP_COLOR_AND_DEPTH: { - - if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { - description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - } else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { - description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - } else { - description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there - } - - } break; case INITIAL_ACTION_CONTINUE: { if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; @@ -2800,8 +2876,8 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF } } - switch (p_final_action) { - case FINAL_ACTION_READ_COLOR_AND_DEPTH: { + switch (is_depth_stencil ? p_final_depth_action : p_final_color_action) { + case FINAL_ACTION_READ: { if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { description.storeOp = VK_ATTACHMENT_STORE_OP_STORE; @@ -2817,59 +2893,42 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there } - break; - case FINAL_ACTION_READ_COLOR_DISCARD_DEPTH: { - if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { - description.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - } else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { - - description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - } else { - description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there - } - } break; - case FINAL_ACTION_DISCARD: { - if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { - description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - } else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { - - description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - } else { - description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there - } - } break; - case FINAL_ACTION_CONTINUE: { - if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { - description.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - description.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - } else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { - - description.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - description.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - } else { - description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there - } + } break; + case FINAL_ACTION_DISCARD: { + if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { + description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + } else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { + + description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + } else { + description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there + } + } break; + case FINAL_ACTION_CONTINUE: { + if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { + description.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + description.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + } else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { - } break; - default: { - ERR_FAIL_V(VK_NULL_HANDLE); //should never reach here + description.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; + description.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + } else { + description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there } + + } break; + default: { + ERR_FAIL_V(VK_NULL_HANDLE); //should never reach here } } @@ -2945,7 +3004,7 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c } int color_references; - VkRenderPass render_pass = _render_pass_create(p_format, INITIAL_ACTION_CLEAR, FINAL_ACTION_DISCARD, &color_references); //actions don't matter for this use case + VkRenderPass render_pass = _render_pass_create(p_format, INITIAL_ACTION_CLEAR, FINAL_ACTION_DISCARD, INITIAL_ACTION_CLEAR, FINAL_ACTION_DISCARD, &color_references); //actions don't matter for this use case if (render_pass == VK_NULL_HANDLE) { //was likely invalid return INVALID_ID; @@ -5240,17 +5299,19 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin_for_screen(in return ID_TYPE_DRAW_LIST; } -Error RenderingDeviceVulkan::_draw_list_setup_framebuffer(Framebuffer *p_framebuffer, InitialAction p_initial_action, FinalAction p_final_action, VkFramebuffer *r_framebuffer, VkRenderPass *r_render_pass) { +Error RenderingDeviceVulkan::_draw_list_setup_framebuffer(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, VkFramebuffer *r_framebuffer, VkRenderPass *r_render_pass) { Framebuffer::VersionKey vk; - vk.initial_action = p_initial_action; - vk.final_action = p_final_action; + vk.initial_color_action = p_initial_color_action; + vk.final_color_action = p_final_color_action; + vk.initial_depth_action = p_initial_depth_action; + vk.final_depth_action = p_final_depth_action; if (!p_framebuffer->framebuffers.has(vk)) { //need to create this version Framebuffer::Version version; - version.render_pass = _render_pass_create(framebuffer_formats[p_framebuffer->format_id].E->key().attachments, p_initial_action, p_final_action); + version.render_pass = _render_pass_create(framebuffer_formats[p_framebuffer->format_id].E->key().attachments, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action); VkFramebufferCreateInfo framebuffer_create_info; framebuffer_create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; @@ -5283,7 +5344,7 @@ Error RenderingDeviceVulkan::_draw_list_setup_framebuffer(Framebuffer *p_framebu return OK; } -Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuffer, InitialAction p_initial_action, FinalAction p_final_action, const Vector<Color> &p_clear_colors, Point2i viewport_offset, Point2i viewport_size, VkFramebuffer vkframebuffer, VkRenderPass render_pass, VkCommandBuffer command_buffer, VkSubpassContents subpass_contents) { +Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *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_colors, float p_clear_depth, uint32_t p_clear_stencil, Point2i viewport_offset, Point2i viewport_size, VkFramebuffer vkframebuffer, VkRenderPass render_pass, VkCommandBuffer command_buffer, VkSubpassContents subpass_contents) { VkRenderPassBeginInfo render_pass_begin; render_pass_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; @@ -5297,12 +5358,15 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff render_pass_begin.renderArea.offset.y = viewport_offset.y; Vector<VkClearValue> clear_values; - if (p_initial_action == INITIAL_ACTION_CLEAR) { + clear_values.resize(framebuffer->texture_ids.size()); + + { int color_index = 0; for (int i = 0; i < framebuffer->texture_ids.size(); i++) { Texture *texture = texture_owner.getornull(framebuffer->texture_ids[i]); VkClearValue clear_value; - if (texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { + + if (color_index < p_clear_colors.size() && texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { ERR_FAIL_INDEX_V(color_index, p_clear_colors.size(), ERR_BUG); //a bug Color clear_color = p_clear_colors[color_index]; clear_value.color.float32[0] = clear_color.r; @@ -5311,15 +5375,15 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff clear_value.color.float32[3] = clear_color.a; color_index++; } else if (texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { - clear_value.depthStencil.depth = 1.0; - clear_value.depthStencil.stencil = 0; + clear_value.depthStencil.depth = p_clear_depth; + clear_value.depthStencil.stencil = p_clear_stencil; } else { clear_value.color.float32[0] = 0; clear_value.color.float32[1] = 0; clear_value.color.float32[2] = 0; clear_value.color.float32[3] = 0; } - clear_values.push_back(clear_value); + clear_values.write[i] = clear_value; } } @@ -5330,7 +5394,9 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff //mark textures as bound draw_list_bound_textures.clear(); - draw_list_unbind_textures = p_final_action != FINAL_ACTION_CONTINUE; + draw_list_unbind_color_textures = p_final_color_action != FINAL_ACTION_CONTINUE; + draw_list_unbind_depth_textures = p_final_depth_action != FINAL_ACTION_CONTINUE; + for (int i = 0; i < framebuffer->texture_ids.size(); i++) { Texture *texture = texture_owner.getornull(framebuffer->texture_ids[i]); texture->bound = true; @@ -5340,13 +5406,13 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff return OK; } -void RenderingDeviceVulkan::_draw_list_insert_clear_region(DrawList *draw_list, Framebuffer *framebuffer, Point2i viewport_offset, Point2i viewport_size, const Vector<Color> &p_clear_colors) { +void RenderingDeviceVulkan::_draw_list_insert_clear_region(DrawList *draw_list, Framebuffer *framebuffer, Point2i viewport_offset, Point2i viewport_size, bool p_clear_color, const Vector<Color> &p_clear_colors, bool p_clear_depth, float p_depth, uint32_t p_stencil) { Vector<VkClearAttachment> clear_attachments; int color_index = 0; for (int i = 0; i < framebuffer->texture_ids.size(); i++) { Texture *texture = texture_owner.getornull(framebuffer->texture_ids[i]); VkClearAttachment clear_at; - if (texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { + if (p_clear_color && texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { ERR_FAIL_INDEX(color_index, p_clear_colors.size()); //a bug Color clear_color = p_clear_colors[color_index]; clear_at.clearValue.color.float32[0] = clear_color.r; @@ -5355,10 +5421,10 @@ void RenderingDeviceVulkan::_draw_list_insert_clear_region(DrawList *draw_list, clear_at.clearValue.color.float32[3] = clear_color.a; clear_at.colorAttachment = color_index++; clear_at.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - } else if (texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { + } else if (p_clear_depth && texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { - clear_at.clearValue.depthStencil.depth = 1.0; - clear_at.clearValue.depthStencil.stencil = 0; + clear_at.clearValue.depthStencil.depth = p_depth; + clear_at.clearValue.depthStencil.stencil = p_stencil; clear_at.colorAttachment = 0; clear_at.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; if (format_has_stencil(texture->format)) { @@ -5381,7 +5447,7 @@ void RenderingDeviceVulkan::_draw_list_insert_clear_region(DrawList *draw_list, vkCmdClearAttachments(draw_list->command_buffer, clear_attachments.size(), clear_attachments.ptr(), 1, &cr); } -RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebuffer, InitialAction p_initial_action, FinalAction p_final_action, const Vector<Color> &p_clear_colors, const Rect2 &p_region) { +RenderingDevice::DrawListID RenderingDeviceVulkan::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, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region) { _THREAD_SAFE_METHOD_ @@ -5393,7 +5459,8 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu Point2i viewport_offset; Point2i viewport_size = framebuffer->size; - bool needs_clear_region = false; + bool needs_clear_color = false; + bool needs_clear_depth = false; if (p_region != Rect2() && p_region != Rect2(Vector2(), viewport_size)) { //check custom region Rect2i viewport(viewport_offset, viewport_size); @@ -5407,27 +5474,31 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu viewport_offset = regioni.position; viewport_size = regioni.size; - if (p_initial_action == INITIAL_ACTION_CLEAR) { - p_initial_action = INITIAL_ACTION_KEEP_COLOR_AND_DEPTH; - needs_clear_region = true; + if (p_initial_color_action == INITIAL_ACTION_CLEAR) { + needs_clear_color = true; + p_initial_color_action = INITIAL_ACTION_KEEP; + } + if (p_initial_depth_action == INITIAL_ACTION_CLEAR) { + needs_clear_depth = true; + p_initial_depth_action = INITIAL_ACTION_KEEP; } } - if (p_initial_action == INITIAL_ACTION_CLEAR) { //check clear values + if (p_initial_color_action == INITIAL_ACTION_CLEAR) { //check clear values int color_attachments = framebuffer_formats[framebuffer->format_id].color_attachments; - ERR_FAIL_COND_V_MSG(p_clear_colors.size() != color_attachments, INVALID_ID, - "Clear color values supplied (" + itos(p_clear_colors.size()) + ") differ from the amount required for framebuffer (" + itos(color_attachments) + ")."); + ERR_FAIL_COND_V_MSG(p_clear_color_values.size() != color_attachments, INVALID_ID, + "Clear color values supplied (" + itos(p_clear_color_values.size()) + ") differ from the amount required for framebuffer (" + itos(color_attachments) + ")."); } VkFramebuffer vkframebuffer; VkRenderPass render_pass; - Error err = _draw_list_setup_framebuffer(framebuffer, p_initial_action, p_final_action, &vkframebuffer, &render_pass); + Error err = _draw_list_setup_framebuffer(framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, &vkframebuffer, &render_pass); ERR_FAIL_COND_V(err != OK, INVALID_ID); VkCommandBuffer command_buffer = frames[frame].draw_command_buffer; - err = _draw_list_render_pass_begin(framebuffer, p_initial_action, p_final_action, p_clear_colors, viewport_offset, viewport_size, vkframebuffer, render_pass, command_buffer, VK_SUBPASS_CONTENTS_INLINE); + err = _draw_list_render_pass_begin(framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, viewport_offset, viewport_size, vkframebuffer, render_pass, command_buffer, VK_SUBPASS_CONTENTS_INLINE); if (err != OK) { return INVALID_ID; @@ -5441,8 +5512,8 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu draw_list_count = 0; draw_list_split = false; - if (needs_clear_region) { - _draw_list_insert_clear_region(draw_list, framebuffer, viewport_offset, viewport_size, p_clear_colors); + if (needs_clear_color || needs_clear_depth) { + _draw_list_insert_clear_region(draw_list, framebuffer, viewport_offset, viewport_size, needs_clear_color, p_clear_color_values, needs_clear_depth, p_clear_depth, p_clear_stencil); } VkViewport viewport; @@ -5467,7 +5538,7 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu return ID_TYPE_DRAW_LIST; } -Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, DrawListID *r_split_ids, InitialAction p_initial_action, FinalAction p_final_action, const Vector<Color> &p_clear_colors, const Rect2 &p_region) { +Error RenderingDeviceVulkan::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, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region) { _THREAD_SAFE_METHOD_ @@ -5479,7 +5550,8 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p Point2i viewport_offset; Point2i viewport_size = framebuffer->size; - bool needs_clear_region = false; + bool needs_clear_color = false; + bool needs_clear_depth = false; if (p_region != Rect2() && p_region != Rect2(Vector2(), viewport_size)) { //check custom region Rect2i viewport(viewport_offset, viewport_size); @@ -5493,17 +5565,21 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p viewport_offset = regioni.position; viewport_size = regioni.size; - if (p_initial_action == INITIAL_ACTION_CLEAR) { - p_initial_action = INITIAL_ACTION_KEEP_COLOR_AND_DEPTH; - needs_clear_region = true; + if (p_initial_color_action == INITIAL_ACTION_CLEAR) { + needs_clear_color = true; + p_initial_color_action = INITIAL_ACTION_KEEP; + } + if (p_initial_depth_action == INITIAL_ACTION_CLEAR) { + needs_clear_depth = true; + p_initial_depth_action = INITIAL_ACTION_KEEP; } } - if (p_initial_action == INITIAL_ACTION_CLEAR) { //check clear values + if (p_initial_color_action == INITIAL_ACTION_CLEAR) { //check clear values int color_attachments = framebuffer_formats[framebuffer->format_id].color_attachments; - ERR_FAIL_COND_V_MSG(p_clear_colors.size() != color_attachments, ERR_INVALID_PARAMETER, - "Clear color values supplied (" + itos(p_clear_colors.size()) + ") differ from the amount required for framebuffer (" + itos(color_attachments) + ")."); + ERR_FAIL_COND_V_MSG(p_clear_color_values.size() != color_attachments, ERR_INVALID_PARAMETER, + "Clear color values supplied (" + itos(p_clear_color_values.size()) + ") differ from the amount required for framebuffer (" + itos(color_attachments) + ")."); } if (p_splits > (uint32_t)split_draw_list_allocators.size()) { @@ -5543,11 +5619,11 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p VkFramebuffer vkframebuffer; VkRenderPass render_pass; - Error err = _draw_list_setup_framebuffer(framebuffer, p_initial_action, p_final_action, &vkframebuffer, &render_pass); + Error err = _draw_list_setup_framebuffer(framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, &vkframebuffer, &render_pass); ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE); VkCommandBuffer frame_command_buffer = frames[frame].draw_command_buffer; - err = _draw_list_render_pass_begin(framebuffer, p_initial_action, p_final_action, p_clear_colors, viewport_offset, viewport_size, vkframebuffer, render_pass, frame_command_buffer, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); + err = _draw_list_render_pass_begin(framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, viewport_offset, viewport_size, vkframebuffer, render_pass, frame_command_buffer, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); if (err != OK) { return ERR_CANT_CREATE; @@ -5596,8 +5672,9 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p #ifdef DEBUG_ENABLED draw_list[i].validation.framebuffer_format = framebuffer->format_id; #endif - if (i == 0 && needs_clear_region) { - _draw_list_insert_clear_region(&draw_list[i], framebuffer, viewport_offset, viewport_size, p_clear_colors); + + if (i == 0 && (needs_clear_color || needs_clear_depth)) { + _draw_list_insert_clear_region(draw_list, framebuffer, viewport_offset, viewport_size, needs_clear_color, p_clear_color_values, needs_clear_depth, p_clear_depth, p_clear_stencil); } VkViewport viewport; @@ -5626,6 +5703,7 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p } RenderingDeviceVulkan::DrawList *RenderingDeviceVulkan::_get_draw_list_ptr(DrawListID p_id) { + if (p_id < 0) { return NULL; } @@ -5841,7 +5919,7 @@ void RenderingDeviceVulkan::draw_list_set_push_constant(DrawListID p_list, void #endif } -void RenderingDeviceVulkan::draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances) { +void RenderingDeviceVulkan::draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances, uint32_t p_procedural_vertices) { DrawList *dl = _get_draw_list_ptr(p_list); ERR_FAIL_COND(!dl); @@ -5902,8 +5980,12 @@ void RenderingDeviceVulkan::draw_list_draw(DrawListID p_list, bool p_use_indices if (p_use_indices) { #ifdef DEBUG_ENABLED + ERR_FAIL_COND_MSG(p_procedural_vertices > 0, + "Procedural vertices can't be used together with 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, @@ -5924,11 +6006,23 @@ void RenderingDeviceVulkan::draw_list_draw(DrawListID p_list, bool p_use_indices #endif vkCmdDrawIndexed(dl->command_buffer, to_draw, p_instances, dl->validation.index_array_offset, 0, 0); } else { + + uint32_t to_draw; + + if (p_procedural_vertices > 0) { #ifdef DEBUG_ENABLED ERR_FAIL_COND_MSG(dl->validation.pipeline_vertex_format == INVALID_ID, - "Draw command lacks indices, but pipeline format does not use vertices."); + "Procedural vertices requested, but pipeline expects a vertex array."); #endif - uint32_t to_draw = dl->validation.vertex_array_size; + to_draw = p_procedural_vertices; + } else { + +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_MSG(dl->validation.pipeline_vertex_format == INVALID_ID, + "Draw command lacks indices, but pipeline format does not use vertices."); +#endif + to_draw = dl->validation.vertex_array_size; + } #ifdef DEBUG_ENABLED ERR_FAIL_COND_MSG(to_draw < dl->validation.pipeline_primitive_minimum, @@ -5937,6 +6031,7 @@ void RenderingDeviceVulkan::draw_list_draw(DrawListID p_list, bool p_use_indices ERR_FAIL_COND_MSG((to_draw % dl->validation.pipeline_primitive_divisor) != 0, "Vertex amount (" + itos(to_draw) + ") must be a multiple of the amount of vertices required by the render primitive (" + itos(dl->validation.pipeline_primitive_divisor) + ")."); #endif + vkCmdDraw(dl->command_buffer, to_draw, p_instances, 0, 0); } } @@ -6005,13 +6100,17 @@ void RenderingDeviceVulkan::draw_list_end() { draw_list = NULL; } - if (draw_list_unbind_textures) { - for (int i = 0; i < draw_list_bound_textures.size(); i++) { - Texture *texture = texture_owner.getornull(draw_list_bound_textures[i]); - ERR_CONTINUE(!texture); //wtf + for (int i = 0; i < draw_list_bound_textures.size(); i++) { + Texture *texture = texture_owner.getornull(draw_list_bound_textures[i]); + ERR_CONTINUE(!texture); //wtf + if (draw_list_unbind_color_textures && (texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT)) { + texture->bound = false; + } + if (draw_list_unbind_depth_textures && (texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) { texture->bound = false; } } + draw_list_bound_textures.clear(); // To ensure proper synchronization, we must make sure rendering is done before: @@ -6168,7 +6267,7 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list, image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; image_memory_barrier.image = textures_to_storage[i]->image; - image_memory_barrier.subresourceRange.aspectMask = textures_to_sampled[i]->read_aspect_mask; + image_memory_barrier.subresourceRange.aspectMask = textures_to_storage[i]->read_aspect_mask; image_memory_barrier.subresourceRange.baseMipLevel = 0; image_memory_barrier.subresourceRange.levelCount = textures_to_storage[i]->mipmaps; image_memory_barrier.subresourceRange.baseArrayLayer = 0; @@ -6197,6 +6296,7 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list, } #endif } + void RenderingDeviceVulkan::compute_list_set_push_constant(ComputeListID p_list, void *p_data, uint32_t p_data_size) { ERR_FAIL_COND(p_list != ID_TYPE_COMPUTE_LIST); ERR_FAIL_COND(!compute_list); @@ -6223,6 +6323,10 @@ void RenderingDeviceVulkan::compute_list_dispatch(ComputeListID p_list, uint32_t ComputeList *cl = compute_list; #ifdef DEBUG_ENABLED + ERR_FAIL_COND(p_x_groups > limits.maxComputeWorkGroupCount[0]); + ERR_FAIL_COND(p_y_groups > limits.maxComputeWorkGroupCount[1]); + ERR_FAIL_COND(p_z_groups > limits.maxComputeWorkGroupCount[2]); + ERR_FAIL_COND_MSG(!cl->validation.active, "Submitted Compute Lists can no longer be modified."); #endif @@ -6267,6 +6371,11 @@ void RenderingDeviceVulkan::compute_list_dispatch(ComputeListID p_list, uint32_t vkCmdDispatch(cl->command_buffer, p_x_groups, p_y_groups, p_z_groups); } + +void RenderingDeviceVulkan::compute_list_add_barrier(ComputeListID p_list) { + _memory_barrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, true); +} + void RenderingDeviceVulkan::compute_list_end() { ERR_FAIL_COND(!compute_list); @@ -6295,6 +6404,9 @@ void RenderingDeviceVulkan::compute_list_end() { } memdelete(compute_list); + compute_list = NULL; + + _memory_barrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_SHADER_WRITE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT, true); } #if 0 diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 2781fc71e2..d487f4612e 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -259,7 +259,7 @@ class RenderingDeviceVulkan : public RenderingDevice { } }; - VkRenderPass _render_pass_create(const Vector<AttachmentFormat> &p_format, InitialAction p_initial_action, FinalAction p_final_action, int *r_color_attachment_count = NULL); + VkRenderPass _render_pass_create(const Vector<AttachmentFormat> &p_format, InitialAction p_initial_action, FinalAction p_final_action, InitialAction p_initial_depth_action, FinalAction p_final_depthcolor_action, int *r_color_attachment_count = NULL); // This is a cache and it's never freed, it ensures // IDs for a given format are always unique. @@ -276,13 +276,23 @@ class RenderingDeviceVulkan : public RenderingDevice { struct Framebuffer { FramebufferFormatID format_id; struct VersionKey { - InitialAction initial_action; - FinalAction final_action; + InitialAction initial_color_action; + FinalAction final_color_action; + InitialAction initial_depth_action; + FinalAction final_depth_action; bool operator<(const VersionKey &p_key) const { - if (initial_action == p_key.initial_action) { - return final_action < p_key.final_action; + if (initial_color_action == p_key.initial_color_action) { + if (final_color_action == p_key.final_color_action) { + if (initial_depth_action == p_key.initial_depth_action) { + return final_depth_action < p_key.final_depth_action; + } else { + return initial_depth_action < p_key.initial_depth_action; + } + } else { + return final_color_action < p_key.final_color_action; + } } else { - return initial_action < p_key.initial_action; + return initial_color_action < p_key.initial_color_action; } } }; @@ -806,11 +816,12 @@ class RenderingDeviceVulkan : public RenderingDevice { uint32_t draw_list_count; bool draw_list_split; Vector<RID> draw_list_bound_textures; - bool draw_list_unbind_textures; + bool draw_list_unbind_color_textures; + bool draw_list_unbind_depth_textures; - void _draw_list_insert_clear_region(DrawList *draw_list, Framebuffer *framebuffer, Point2i viewport_offset, Point2i viewport_size, const Vector<Color> &p_clear_colors); - Error _draw_list_setup_framebuffer(Framebuffer *p_framebuffer, InitialAction p_initial_action, FinalAction p_final_action, VkFramebuffer *r_framebuffer, VkRenderPass *r_render_pass); - Error _draw_list_render_pass_begin(Framebuffer *framebuffer, InitialAction p_initial_action, FinalAction p_final_action, const Vector<Color> &p_clear_colors, Point2i viewport_offset, Point2i viewport_size, VkFramebuffer vkframebuffer, VkRenderPass render_pass, VkCommandBuffer command_buffer, VkSubpassContents subpass_contents); + void _draw_list_insert_clear_region(DrawList *draw_list, Framebuffer *framebuffer, Point2i viewport_offset, Point2i viewport_size, bool p_clear_color, const Vector<Color> &p_clear_colors, bool p_clear_depth, float p_depth, uint32_t p_stencil); + Error _draw_list_setup_framebuffer(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, VkFramebuffer *r_framebuffer, VkRenderPass *r_render_pass); + Error _draw_list_render_pass_begin(Framebuffer *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_colors, float p_clear_depth, uint32_t p_clear_stencil, Point2i viewport_offset, Point2i viewport_size, VkFramebuffer vkframebuffer, VkRenderPass render_pass, VkCommandBuffer command_buffer, VkSubpassContents subpass_contents); _FORCE_INLINE_ DrawList *_get_draw_list_ptr(DrawListID p_id); /**********************/ @@ -966,6 +977,7 @@ public: virtual bool texture_is_valid(RID p_texture); virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, bool p_sync_with_draw = false); + virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, bool p_sync_with_draw = false); /*********************/ /**** FRAMEBUFFER ****/ @@ -1046,8 +1058,9 @@ public: /********************/ virtual DrawListID draw_list_begin_for_screen(int p_screen = 0, const Color &p_clear_color = Color()); - virtual DrawListID draw_list_begin(RID p_framebuffer, InitialAction p_initial_action, FinalAction p_final_action, const Vector<Color> &p_clear_colors = Vector<Color>(), const Rect2 &p_region = Rect2()); - virtual Error draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, DrawListID *r_split_ids, InitialAction p_initial_action, FinalAction p_final_action, const Vector<Color> &p_clear_colors = Vector<Color>(), const Rect2 &p_region = Rect2()); + + 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()); + 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()); 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); @@ -1056,7 +1069,7 @@ public: virtual void draw_list_set_line_width(DrawListID p_list, float p_width); virtual void draw_list_set_push_constant(DrawListID p_list, void *p_data, uint32_t p_data_size); - virtual void draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances = 1); + virtual void draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances = 1, uint32_t p_procedural_vertices = 0); virtual void draw_list_enable_scissor(DrawListID p_list, const Rect2 &p_rect); virtual void draw_list_disable_scissor(DrawListID p_list); @@ -1071,6 +1084,8 @@ public: virtual void compute_list_bind_compute_pipeline(ComputeListID p_list, RID p_compute_pipeline); virtual void compute_list_bind_uniform_set(ComputeListID p_list, RID p_uniform_set, uint32_t p_index); virtual void compute_list_set_push_constant(ComputeListID p_list, void *p_data, uint32_t p_data_size); + virtual void compute_list_add_barrier(ComputeListID p_list); + virtual void compute_list_dispatch(ComputeListID p_list, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups); virtual void compute_list_end(); diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index f232073f47..34ce79ab02 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -53,6 +53,11 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_messenger_callback(VkDebugU strstr(pCallbackData->pMessage, "can result in undefined behavior if this memory is used by the device") != NULL) { return VK_FALSE; } + // This needs to be ignored because Validator is wrong here + if (strstr(pCallbackData->pMessage, "SPIR-V module not valid: Pointer operand") != NULL && + strstr(pCallbackData->pMessage, "must be a memory object") != NULL) { + return VK_FALSE; + } if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) { strcat(prefix, "VERBOSE : "); |