|
@@ -2932,16 +2932,22 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color,
|
|
|
|
|
|
VkCommandBuffer command_buffer = p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer;
|
|
|
|
|
|
- VkImageLayout layout = src_tex->layout;
|
|
|
+ VkImageLayout clear_layout = (src_tex->layout == VK_IMAGE_LAYOUT_GENERAL) ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
|
|
|
|
|
- if (src_tex->layout != VK_IMAGE_LAYOUT_GENERAL) { //storage may be in general state
|
|
|
+ // NOTE: Perhaps the valid stages/accesses for a given onwner should be a property of the owner. (Here and places like _get_buffer_from_owner)
|
|
|
+ const VkPipelineStageFlags valid_texture_stages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
|
|
+ constexpr VkAccessFlags read_access = VK_ACCESS_SHADER_READ_BIT;
|
|
|
+ constexpr VkAccessFlags read_write_access = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
|
|
|
+ const VkAccessFlags valid_texture_access = (src_tex->usage_flags & TEXTURE_USAGE_STORAGE_BIT) ? read_write_access : read_access;
|
|
|
+
|
|
|
+ { // Barrier from previous access with optional layout change (see clear_layout logic above)
|
|
|
VkImageMemoryBarrier image_memory_barrier;
|
|
|
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
|
|
image_memory_barrier.pNext = nullptr;
|
|
|
- image_memory_barrier.srcAccessMask = 0;
|
|
|
+ image_memory_barrier.srcAccessMask = valid_texture_access;
|
|
|
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.oldLayout = clear_layout;
|
|
|
|
|
|
image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
|
image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
@@ -2952,8 +2958,7 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color,
|
|
|
image_memory_barrier.subresourceRange.baseArrayLayer = src_tex->base_layer + 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, nullptr, 0, nullptr, 1, &image_memory_barrier);
|
|
|
+ vkCmdPipelineBarrier(command_buffer, valid_texture_stages, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
|
|
|
}
|
|
|
|
|
|
VkClearColorValue clear_color;
|
|
@@ -2969,16 +2974,15 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color,
|
|
|
range.baseMipLevel = src_tex->base_mipmap + 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
|
|
|
+ vkCmdClearColorImage(command_buffer, src_tex->image, clear_layout, &clear_color, 1, &range);
|
|
|
|
|
|
+ { // Barrier to post clear accesses (changing back the layout if needed)
|
|
|
VkImageMemoryBarrier image_memory_barrier;
|
|
|
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
|
|
image_memory_barrier.pNext = nullptr;
|
|
|
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.dstAccessMask = valid_texture_access;
|
|
|
+ image_memory_barrier.oldLayout = clear_layout;
|
|
|
image_memory_barrier.newLayout = src_tex->layout;
|
|
|
|
|
|
image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
@@ -2990,7 +2994,7 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color,
|
|
|
image_memory_barrier.subresourceRange.baseArrayLayer = src_tex->base_layer + 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_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
|
|
|
+ vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, valid_texture_stages, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
|
|
|
}
|
|
|
|
|
|
return OK;
|