diff options
Diffstat (limited to 'drivers/vulkan/rendering_device_vulkan.cpp')
-rw-r--r-- | drivers/vulkan/rendering_device_vulkan.cpp | 669 |
1 files changed, 432 insertions, 237 deletions
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 23e9227a39..f37e21aa93 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -35,12 +35,12 @@ #include "core/os/os.h" #include "core/project_settings.h" #include "drivers/vulkan/vulkan_context.h" + #include "thirdparty/spirv-reflect/spirv_reflect.h" -//#define FORCE_FULL_BARRIER +#define FORCE_FULL_BARRIER void RenderingDeviceVulkan::_add_dependency(RID p_id, RID p_depends_on) { - if (!dependency_map.has(p_depends_on)) { dependency_map[p_depends_on] = Set<RID>(); } @@ -55,12 +55,10 @@ void RenderingDeviceVulkan::_add_dependency(RID p_id, RID p_depends_on) { } void RenderingDeviceVulkan::_free_dependencies(RID p_id) { - //direct dependencies must be freed Map<RID, Set<RID>>::Element *E = dependency_map.find(p_id); if (E) { - while (E->get().size()) { free(E->get().front()->get()); } @@ -71,7 +69,6 @@ void RenderingDeviceVulkan::_free_dependencies(RID p_id) { E = reverse_dependency_map.find(p_id); if (E) { - for (Set<RID>::Element *F = E->get().front(); F; F = F->next()) { Map<RID, Set<RID>>::Element *G = dependency_map.find(F->get()); ERR_CONTINUE(!G); @@ -566,81 +563,97 @@ int RenderingDeviceVulkan::get_format_vertex_size(DataFormat p_format) { case DATA_FORMAT_B8G8R8A8_UNORM: case DATA_FORMAT_B8G8R8A8_SNORM: case DATA_FORMAT_B8G8R8A8_UINT: - case DATA_FORMAT_B8G8R8A8_SINT: return 4; + case DATA_FORMAT_B8G8R8A8_SINT: + return 4; case DATA_FORMAT_R16_UNORM: case DATA_FORMAT_R16_SNORM: case DATA_FORMAT_R16_UINT: case DATA_FORMAT_R16_SINT: - case DATA_FORMAT_R16_SFLOAT: return 4; + case DATA_FORMAT_R16_SFLOAT: + return 4; case DATA_FORMAT_R16G16_UNORM: case DATA_FORMAT_R16G16_SNORM: case DATA_FORMAT_R16G16_UINT: case DATA_FORMAT_R16G16_SINT: - case DATA_FORMAT_R16G16_SFLOAT: return 4; + case DATA_FORMAT_R16G16_SFLOAT: + return 4; case DATA_FORMAT_R16G16B16_UNORM: case DATA_FORMAT_R16G16B16_SNORM: case DATA_FORMAT_R16G16B16_UINT: case DATA_FORMAT_R16G16B16_SINT: - case DATA_FORMAT_R16G16B16_SFLOAT: return 8; + case DATA_FORMAT_R16G16B16_SFLOAT: + return 8; case DATA_FORMAT_R16G16B16A16_UNORM: case DATA_FORMAT_R16G16B16A16_SNORM: case DATA_FORMAT_R16G16B16A16_UINT: case DATA_FORMAT_R16G16B16A16_SINT: - case DATA_FORMAT_R16G16B16A16_SFLOAT: return 8; + case DATA_FORMAT_R16G16B16A16_SFLOAT: + return 8; case DATA_FORMAT_R32_UINT: case DATA_FORMAT_R32_SINT: - case DATA_FORMAT_R32_SFLOAT: return 4; + case DATA_FORMAT_R32_SFLOAT: + return 4; case DATA_FORMAT_R32G32_UINT: case DATA_FORMAT_R32G32_SINT: - case DATA_FORMAT_R32G32_SFLOAT: return 8; + case DATA_FORMAT_R32G32_SFLOAT: + return 8; case DATA_FORMAT_R32G32B32_UINT: case DATA_FORMAT_R32G32B32_SINT: - case DATA_FORMAT_R32G32B32_SFLOAT: return 12; + case DATA_FORMAT_R32G32B32_SFLOAT: + return 12; case DATA_FORMAT_R32G32B32A32_UINT: case DATA_FORMAT_R32G32B32A32_SINT: - case DATA_FORMAT_R32G32B32A32_SFLOAT: return 16; + case DATA_FORMAT_R32G32B32A32_SFLOAT: + return 16; case DATA_FORMAT_R64_UINT: case DATA_FORMAT_R64_SINT: - case DATA_FORMAT_R64_SFLOAT: return 8; + case DATA_FORMAT_R64_SFLOAT: + return 8; case DATA_FORMAT_R64G64_UINT: case DATA_FORMAT_R64G64_SINT: - case DATA_FORMAT_R64G64_SFLOAT: return 16; + case DATA_FORMAT_R64G64_SFLOAT: + return 16; case DATA_FORMAT_R64G64B64_UINT: case DATA_FORMAT_R64G64B64_SINT: - case DATA_FORMAT_R64G64B64_SFLOAT: return 24; + case DATA_FORMAT_R64G64B64_SFLOAT: + return 24; case DATA_FORMAT_R64G64B64A64_UINT: case DATA_FORMAT_R64G64B64A64_SINT: - case DATA_FORMAT_R64G64B64A64_SFLOAT: return 32; - default: return 0; + case DATA_FORMAT_R64G64B64A64_SFLOAT: + return 32; + default: + return 0; } } uint32_t RenderingDeviceVulkan::get_image_format_pixel_size(DataFormat p_format) { - switch (p_format) { - - case DATA_FORMAT_R4G4_UNORM_PACK8: return 1; + case DATA_FORMAT_R4G4_UNORM_PACK8: + return 1; case DATA_FORMAT_R4G4B4A4_UNORM_PACK16: case DATA_FORMAT_B4G4R4A4_UNORM_PACK16: case DATA_FORMAT_R5G6B5_UNORM_PACK16: case DATA_FORMAT_B5G6R5_UNORM_PACK16: case DATA_FORMAT_R5G5B5A1_UNORM_PACK16: case DATA_FORMAT_B5G5R5A1_UNORM_PACK16: - case DATA_FORMAT_A1R5G5B5_UNORM_PACK16: return 2; + case DATA_FORMAT_A1R5G5B5_UNORM_PACK16: + return 2; case DATA_FORMAT_R8_UNORM: case DATA_FORMAT_R8_SNORM: case DATA_FORMAT_R8_USCALED: case DATA_FORMAT_R8_SSCALED: case DATA_FORMAT_R8_UINT: case DATA_FORMAT_R8_SINT: - case DATA_FORMAT_R8_SRGB: return 1; + case DATA_FORMAT_R8_SRGB: + return 1; case DATA_FORMAT_R8G8_UNORM: case DATA_FORMAT_R8G8_SNORM: case DATA_FORMAT_R8G8_USCALED: case DATA_FORMAT_R8G8_SSCALED: case DATA_FORMAT_R8G8_UINT: case DATA_FORMAT_R8G8_SINT: - case DATA_FORMAT_R8G8_SRGB: return 2; + case DATA_FORMAT_R8G8_SRGB: + return 2; case DATA_FORMAT_R8G8B8_UNORM: case DATA_FORMAT_R8G8B8_SNORM: case DATA_FORMAT_R8G8B8_USCALED: @@ -654,7 +667,8 @@ uint32_t RenderingDeviceVulkan::get_image_format_pixel_size(DataFormat p_format) case DATA_FORMAT_B8G8R8_SSCALED: case DATA_FORMAT_B8G8R8_UINT: case DATA_FORMAT_B8G8R8_SINT: - case DATA_FORMAT_B8G8R8_SRGB: return 3; + case DATA_FORMAT_B8G8R8_SRGB: + return 3; case DATA_FORMAT_R8G8B8A8_UNORM: case DATA_FORMAT_R8G8B8A8_SNORM: case DATA_FORMAT_R8G8B8A8_USCALED: @@ -668,7 +682,8 @@ uint32_t RenderingDeviceVulkan::get_image_format_pixel_size(DataFormat p_format) case DATA_FORMAT_B8G8R8A8_SSCALED: case DATA_FORMAT_B8G8R8A8_UINT: case DATA_FORMAT_B8G8R8A8_SINT: - case DATA_FORMAT_B8G8R8A8_SRGB: return 4; + case DATA_FORMAT_B8G8R8A8_SRGB: + return 4; case DATA_FORMAT_A8B8G8R8_UNORM_PACK32: case DATA_FORMAT_A8B8G8R8_SNORM_PACK32: case DATA_FORMAT_A8B8G8R8_USCALED_PACK32: @@ -687,67 +702,87 @@ uint32_t RenderingDeviceVulkan::get_image_format_pixel_size(DataFormat p_format) case DATA_FORMAT_A2B10G10R10_USCALED_PACK32: case DATA_FORMAT_A2B10G10R10_SSCALED_PACK32: case DATA_FORMAT_A2B10G10R10_UINT_PACK32: - case DATA_FORMAT_A2B10G10R10_SINT_PACK32: return 4; + case DATA_FORMAT_A2B10G10R10_SINT_PACK32: + return 4; case DATA_FORMAT_R16_UNORM: case DATA_FORMAT_R16_SNORM: case DATA_FORMAT_R16_USCALED: case DATA_FORMAT_R16_SSCALED: case DATA_FORMAT_R16_UINT: case DATA_FORMAT_R16_SINT: - case DATA_FORMAT_R16_SFLOAT: return 2; + case DATA_FORMAT_R16_SFLOAT: + return 2; case DATA_FORMAT_R16G16_UNORM: case DATA_FORMAT_R16G16_SNORM: case DATA_FORMAT_R16G16_USCALED: case DATA_FORMAT_R16G16_SSCALED: case DATA_FORMAT_R16G16_UINT: case DATA_FORMAT_R16G16_SINT: - case DATA_FORMAT_R16G16_SFLOAT: return 4; + case DATA_FORMAT_R16G16_SFLOAT: + return 4; case DATA_FORMAT_R16G16B16_UNORM: case DATA_FORMAT_R16G16B16_SNORM: case DATA_FORMAT_R16G16B16_USCALED: case DATA_FORMAT_R16G16B16_SSCALED: case DATA_FORMAT_R16G16B16_UINT: case DATA_FORMAT_R16G16B16_SINT: - case DATA_FORMAT_R16G16B16_SFLOAT: return 6; + case DATA_FORMAT_R16G16B16_SFLOAT: + return 6; case DATA_FORMAT_R16G16B16A16_UNORM: case DATA_FORMAT_R16G16B16A16_SNORM: case DATA_FORMAT_R16G16B16A16_USCALED: case DATA_FORMAT_R16G16B16A16_SSCALED: case DATA_FORMAT_R16G16B16A16_UINT: case DATA_FORMAT_R16G16B16A16_SINT: - case DATA_FORMAT_R16G16B16A16_SFLOAT: return 8; + case DATA_FORMAT_R16G16B16A16_SFLOAT: + return 8; case DATA_FORMAT_R32_UINT: case DATA_FORMAT_R32_SINT: - case DATA_FORMAT_R32_SFLOAT: return 4; + case DATA_FORMAT_R32_SFLOAT: + return 4; case DATA_FORMAT_R32G32_UINT: case DATA_FORMAT_R32G32_SINT: - case DATA_FORMAT_R32G32_SFLOAT: return 8; + case DATA_FORMAT_R32G32_SFLOAT: + return 8; case DATA_FORMAT_R32G32B32_UINT: case DATA_FORMAT_R32G32B32_SINT: - case DATA_FORMAT_R32G32B32_SFLOAT: return 12; + case DATA_FORMAT_R32G32B32_SFLOAT: + return 12; case DATA_FORMAT_R32G32B32A32_UINT: case DATA_FORMAT_R32G32B32A32_SINT: - case DATA_FORMAT_R32G32B32A32_SFLOAT: return 16; + case DATA_FORMAT_R32G32B32A32_SFLOAT: + return 16; case DATA_FORMAT_R64_UINT: case DATA_FORMAT_R64_SINT: - case DATA_FORMAT_R64_SFLOAT: return 8; + case DATA_FORMAT_R64_SFLOAT: + return 8; case DATA_FORMAT_R64G64_UINT: case DATA_FORMAT_R64G64_SINT: - case DATA_FORMAT_R64G64_SFLOAT: return 16; + case DATA_FORMAT_R64G64_SFLOAT: + return 16; case DATA_FORMAT_R64G64B64_UINT: case DATA_FORMAT_R64G64B64_SINT: - case DATA_FORMAT_R64G64B64_SFLOAT: return 24; + case DATA_FORMAT_R64G64B64_SFLOAT: + return 24; case DATA_FORMAT_R64G64B64A64_UINT: case DATA_FORMAT_R64G64B64A64_SINT: - case DATA_FORMAT_R64G64B64A64_SFLOAT: return 32; + case DATA_FORMAT_R64G64B64A64_SFLOAT: + return 32; case DATA_FORMAT_B10G11R11_UFLOAT_PACK32: - case DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32: return 4; - case DATA_FORMAT_D16_UNORM: return 2; - case DATA_FORMAT_X8_D24_UNORM_PACK32: return 4; - case DATA_FORMAT_D32_SFLOAT: return 4; - case DATA_FORMAT_S8_UINT: return 1; - case DATA_FORMAT_D16_UNORM_S8_UINT: return 4; - case DATA_FORMAT_D24_UNORM_S8_UINT: return 4; + case DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32: + return 4; + case DATA_FORMAT_D16_UNORM: + return 2; + case DATA_FORMAT_X8_D24_UNORM_PACK32: + return 4; + case DATA_FORMAT_D32_SFLOAT: + return 4; + case DATA_FORMAT_S8_UINT: + return 1; + case DATA_FORMAT_D16_UNORM_S8_UINT: + return 4; + case DATA_FORMAT_D24_UNORM_S8_UINT: + return 4; case DATA_FORMAT_D32_SFLOAT_S8_UINT: return 5; //? case DATA_FORMAT_BC1_RGB_UNORM_BLOCK: @@ -765,17 +800,20 @@ uint32_t RenderingDeviceVulkan::get_image_format_pixel_size(DataFormat p_format) case DATA_FORMAT_BC6H_UFLOAT_BLOCK: case DATA_FORMAT_BC6H_SFLOAT_BLOCK: case DATA_FORMAT_BC7_UNORM_BLOCK: - case DATA_FORMAT_BC7_SRGB_BLOCK: return 1; + case DATA_FORMAT_BC7_SRGB_BLOCK: + return 1; case DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: case DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: case DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: case DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: case DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: - case DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: return 1; + case DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: + return 1; case DATA_FORMAT_EAC_R11_UNORM_BLOCK: case DATA_FORMAT_EAC_R11_SNORM_BLOCK: case DATA_FORMAT_EAC_R11G11_UNORM_BLOCK: - case DATA_FORMAT_EAC_R11G11_SNORM_BLOCK: return 1; + case DATA_FORMAT_EAC_R11G11_SNORM_BLOCK: + return 1; case DATA_FORMAT_ASTC_4x4_UNORM_BLOCK: case DATA_FORMAT_ASTC_4x4_SRGB_BLOCK: case DATA_FORMAT_ASTC_5x4_UNORM_BLOCK: @@ -803,14 +841,17 @@ uint32_t RenderingDeviceVulkan::get_image_format_pixel_size(DataFormat p_format) case DATA_FORMAT_ASTC_12x10_UNORM_BLOCK: case DATA_FORMAT_ASTC_12x10_SRGB_BLOCK: case DATA_FORMAT_ASTC_12x12_UNORM_BLOCK: - case DATA_FORMAT_ASTC_12x12_SRGB_BLOCK: return 1; + case DATA_FORMAT_ASTC_12x12_SRGB_BLOCK: + return 1; case DATA_FORMAT_G8B8G8R8_422_UNORM: - case DATA_FORMAT_B8G8R8G8_422_UNORM: return 4; + case DATA_FORMAT_B8G8R8G8_422_UNORM: + return 4; case DATA_FORMAT_G8_B8_R8_3PLANE_420_UNORM: case DATA_FORMAT_G8_B8R8_2PLANE_420_UNORM: case DATA_FORMAT_G8_B8_R8_3PLANE_422_UNORM: case DATA_FORMAT_G8_B8R8_2PLANE_422_UNORM: - case DATA_FORMAT_G8_B8_R8_3PLANE_444_UNORM: return 4; + case DATA_FORMAT_G8_B8_R8_3PLANE_444_UNORM: + return 4; case DATA_FORMAT_R10X6_UNORM_PACK16: case DATA_FORMAT_R10X6G10X6_UNORM_2PACK16: case DATA_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16: @@ -830,14 +871,16 @@ uint32_t RenderingDeviceVulkan::get_image_format_pixel_size(DataFormat p_format) case DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: case DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: case DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: - case DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: return 2; + case DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: + return 2; case DATA_FORMAT_G16B16G16R16_422_UNORM: case DATA_FORMAT_B16G16R16G16_422_UNORM: case DATA_FORMAT_G16_B16_R16_3PLANE_420_UNORM: case DATA_FORMAT_G16_B16R16_2PLANE_420_UNORM: case DATA_FORMAT_G16_B16_R16_3PLANE_422_UNORM: case DATA_FORMAT_G16_B16R16_2PLANE_422_UNORM: - case DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM: return 8; + case DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM: + return 8; case DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG: case DATA_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG: case DATA_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG: @@ -845,7 +888,8 @@ uint32_t RenderingDeviceVulkan::get_image_format_pixel_size(DataFormat p_format) case DATA_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG: case DATA_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG: case DATA_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG: - case DATA_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG: return 1; + case DATA_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG: + return 1; default: { ERR_PRINT("Format not handled, bug"); } @@ -857,7 +901,6 @@ uint32_t RenderingDeviceVulkan::get_image_format_pixel_size(DataFormat p_format) // https://www.khronos.org/registry/DataFormat/specs/1.1/dataformat.1.1.pdf void RenderingDeviceVulkan::get_compressed_image_format_block_dimensions(DataFormat p_format, uint32_t &r_w, uint32_t &r_h) { - switch (p_format) { case DATA_FORMAT_BC1_RGB_UNORM_BLOCK: case DATA_FORMAT_BC1_RGB_SRGB_BLOCK: @@ -938,34 +981,45 @@ void RenderingDeviceVulkan::get_compressed_image_format_block_dimensions(DataFor } uint32_t RenderingDeviceVulkan::get_compressed_image_format_block_byte_size(DataFormat p_format) { - switch (p_format) { case DATA_FORMAT_BC1_RGB_UNORM_BLOCK: case DATA_FORMAT_BC1_RGB_SRGB_BLOCK: case DATA_FORMAT_BC1_RGBA_UNORM_BLOCK: - case DATA_FORMAT_BC1_RGBA_SRGB_BLOCK: return 8; + case DATA_FORMAT_BC1_RGBA_SRGB_BLOCK: + return 8; case DATA_FORMAT_BC2_UNORM_BLOCK: - case DATA_FORMAT_BC2_SRGB_BLOCK: return 16; + case DATA_FORMAT_BC2_SRGB_BLOCK: + return 16; case DATA_FORMAT_BC3_UNORM_BLOCK: - case DATA_FORMAT_BC3_SRGB_BLOCK: return 16; + case DATA_FORMAT_BC3_SRGB_BLOCK: + return 16; case DATA_FORMAT_BC4_UNORM_BLOCK: - case DATA_FORMAT_BC4_SNORM_BLOCK: return 8; + case DATA_FORMAT_BC4_SNORM_BLOCK: + return 8; case DATA_FORMAT_BC5_UNORM_BLOCK: - case DATA_FORMAT_BC5_SNORM_BLOCK: return 16; + case DATA_FORMAT_BC5_SNORM_BLOCK: + return 16; case DATA_FORMAT_BC6H_UFLOAT_BLOCK: - case DATA_FORMAT_BC6H_SFLOAT_BLOCK: return 16; + case DATA_FORMAT_BC6H_SFLOAT_BLOCK: + return 16; case DATA_FORMAT_BC7_UNORM_BLOCK: - case DATA_FORMAT_BC7_SRGB_BLOCK: return 16; + case DATA_FORMAT_BC7_SRGB_BLOCK: + return 16; case DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: - case DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: return 8; + case DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: + return 8; case DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: - case DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: return 8; + case DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: + return 8; case DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: - case DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: return 16; + case DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: + return 16; case DATA_FORMAT_EAC_R11_UNORM_BLOCK: - case DATA_FORMAT_EAC_R11_SNORM_BLOCK: return 8; + case DATA_FORMAT_EAC_R11_SNORM_BLOCK: + return 8; case DATA_FORMAT_EAC_R11G11_UNORM_BLOCK: - case DATA_FORMAT_EAC_R11G11_SNORM_BLOCK: return 16; + case DATA_FORMAT_EAC_R11G11_SNORM_BLOCK: + return 16; case DATA_FORMAT_ASTC_4x4_UNORM_BLOCK: //again, not sure about astc case DATA_FORMAT_ASTC_4x4_SRGB_BLOCK: case DATA_FORMAT_ASTC_5x4_UNORM_BLOCK: @@ -1011,7 +1065,6 @@ uint32_t RenderingDeviceVulkan::get_compressed_image_format_block_byte_size(Data } uint32_t RenderingDeviceVulkan::get_compressed_image_format_pixel_rshift(DataFormat p_format) { - switch (p_format) { case DATA_FORMAT_BC1_RGB_UNORM_BLOCK: //these formats are half byte size, so rshift is 1 case DATA_FORMAT_BC1_RGB_SRGB_BLOCK: @@ -1028,11 +1081,13 @@ uint32_t RenderingDeviceVulkan::get_compressed_image_format_pixel_rshift(DataFor case DATA_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG: case DATA_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG: case DATA_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG: - case DATA_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG: return 1; + case DATA_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG: + return 1; case DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG: //these formats are quarter byte size, so rshift is 1 case DATA_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG: case DATA_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG: - case DATA_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG: return 2; + case DATA_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG: + return 2; default: { } } @@ -1055,7 +1110,6 @@ bool RenderingDeviceVulkan::format_has_stencil(DataFormat p_format) { } uint32_t RenderingDeviceVulkan::get_image_format_required_size(DataFormat p_format, uint32_t p_width, uint32_t p_height, uint32_t p_depth, uint32_t p_mipmaps, uint32_t *r_blockw, uint32_t *r_blockh, uint32_t *r_depth) { - ERR_FAIL_COND_V(p_mipmaps == 0, 0); uint32_t w = p_width; uint32_t h = p_height; @@ -1095,7 +1149,6 @@ uint32_t RenderingDeviceVulkan::get_image_format_required_size(DataFormat p_form } uint32_t RenderingDeviceVulkan::get_image_required_mipmaps(uint32_t p_width, uint32_t p_height, uint32_t p_depth) { - //formats and block size don't really matter here since they can all go down to 1px (even if block is larger) int w = p_width; int h = p_height; @@ -1104,7 +1157,6 @@ uint32_t RenderingDeviceVulkan::get_image_required_mipmaps(uint32_t p_width, uin int mipmaps = 1; while (true) { - if (w == 1 && h == 1 && d == 1) { break; } @@ -1274,7 +1326,6 @@ Error RenderingDeviceVulkan::_buffer_free(Buffer *p_buffer) { } Error RenderingDeviceVulkan::_insert_staging_block() { - VkBufferCreateInfo bufferInfo; bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; bufferInfo.pNext = nullptr; @@ -1312,7 +1363,6 @@ Error RenderingDeviceVulkan::_staging_buffer_allocate(uint32_t p_amount, uint32_ r_alloc_size = p_amount; while (true) { - r_alloc_offset = 0; //see if we can use current block @@ -1368,7 +1418,6 @@ Error RenderingDeviceVulkan::_staging_buffer_allocate(uint32_t p_amount, uint32_ //block_until_next_frame() continue; } else { - //flush EVERYTHING including setup commands. IF not immediate, also need to flush the draw commands _flush(true); @@ -1413,7 +1462,6 @@ Error RenderingDeviceVulkan::_staging_buffer_allocate(uint32_t p_amount, uint32_ //block_until_next_frame() continue; //and try again } else { - _flush(false); for (int i = 0; i < staging_buffer_blocks.size(); i++) { @@ -1443,13 +1491,11 @@ Error RenderingDeviceVulkan::_staging_buffer_allocate(uint32_t p_amount, uint32_ } Error RenderingDeviceVulkan::_buffer_update(Buffer *p_buffer, size_t p_offset, const uint8_t *p_data, size_t p_data_size, bool p_use_draw_command_buffer, uint32_t p_required_align) { - //submitting may get chunked for various reasons, so convert this to a task size_t to_submit = p_data_size; size_t submit_from = 0; while (to_submit > 0) { - uint32_t block_write_offset; uint32_t block_write_amount; @@ -1490,7 +1536,6 @@ Error RenderingDeviceVulkan::_buffer_update(Buffer *p_buffer, size_t p_offset, c } void RenderingDeviceVulkan::_memory_barrier(VkPipelineStageFlags p_src_stage_mask, VkPipelineStageFlags p_dst_stage_mask, VkAccessFlags p_src_access, VkAccessFlags p_dst_sccess, bool p_sync_with_draw) { - VkMemoryBarrier mem_barrier; mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; mem_barrier.pNext = nullptr; @@ -1537,7 +1582,6 @@ void RenderingDeviceVulkan::_full_barrier(bool p_sync_with_draw) { } void RenderingDeviceVulkan::_buffer_memory_barrier(VkBuffer buffer, uint64_t p_from, uint64_t p_size, VkPipelineStageFlags p_src_stage_mask, VkPipelineStageFlags p_dst_stage_mask, VkAccessFlags p_src_access, VkAccessFlags p_dst_sccess, bool p_sync_with_draw) { - VkBufferMemoryBarrier buffer_mem_barrier; buffer_mem_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; buffer_mem_barrier.pNext = nullptr; @@ -1557,7 +1601,6 @@ void RenderingDeviceVulkan::_buffer_memory_barrier(VkBuffer buffer, uint64_t p_f /*****************/ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<Vector<uint8_t>> &p_data) { - _THREAD_SAFE_METHOD_ VkImageCreateInfo image_create_info; @@ -1687,7 +1730,6 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T "Too many mipmaps requested for texture format and dimensions (" + itos(image_create_info.mipLevels) + "), maximum allowed: (" + itos(required_mipmaps) + ")."); if (p_data.size()) { - ERR_FAIL_COND_V_MSG(!(p_format.usage_bits & TEXTURE_USAGE_CAN_UPDATE_BIT), RID(), "Texture needs the TEXTURE_USAGE_CAN_UPDATE_BIT usage flag in order to be updated at initialization or later"); @@ -1795,7 +1837,6 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T texture.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; } else if (p_format.usage_bits & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { - texture.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; } else { @@ -1803,7 +1844,6 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T } if (p_format.usage_bits & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { - texture.read_aspect_mask = VK_IMAGE_ASPECT_DEPTH_BIT; texture.barrier_aspect_mask = VK_IMAGE_ASPECT_DEPTH_BIT; @@ -1898,7 +1938,6 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T RID id = texture_owner.make_rid(texture); if (p_data.size()) { - for (uint32_t i = 0; i < image_create_info.arrayLayers; i++) { texture_update(id, i, p_data[i]); } @@ -1907,7 +1946,6 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T } RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID p_with_texture) { - _THREAD_SAFE_METHOD_ Texture *src_texture = texture_owner.getornull(p_with_texture); @@ -1987,7 +2025,6 @@ RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID } RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type) { - _THREAD_SAFE_METHOD_ Texture *src_texture = texture_owner.getornull(p_with_texture); @@ -2087,7 +2124,6 @@ RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p } Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, bool p_sync_with_draw) { - _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V_MSG(draw_list && p_sync_with_draw, ERR_INVALID_PARAMETER, @@ -2158,7 +2194,6 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con uint32_t mipmap_offset = 0; for (uint32_t mm_i = 0; mm_i < texture->mipmaps; mm_i++) { - uint32_t depth; uint32_t image_total = get_image_format_required_size(texture->format, texture->width, texture->height, texture->depth, mm_i + 1, &width, &height, &depth); @@ -2171,7 +2206,6 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con for (uint32_t x = 0; x < width; x += region_size) { for (uint32_t y = 0; y < height; y += region_size) { - uint32_t region_w = MIN(region_size, width - x); uint32_t region_h = MIN(region_size, height - y); @@ -2232,7 +2266,6 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con uint32_t dst_offset = (yr * region_w + xr) * pixel_size; //copy block for (uint32_t i = 0; i < pixel_size; i++) { - write_ptr[dst_offset + i] = read_ptr[src_offset + i]; } } @@ -2296,7 +2329,6 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con } Vector<uint8_t> RenderingDeviceVulkan::_texture_get_data_from_image(Texture *tex, VkImage p_image, VmaAllocation p_allocation, uint32_t p_layer, bool p_2d) { - uint32_t width, height, depth; uint32_t image_size = get_image_format_required_size(tex->format, tex->width, tex->height, p_2d ? 1 : tex->depth, tex->mipmaps, &width, &height, &depth); @@ -2316,7 +2348,6 @@ Vector<uint8_t> RenderingDeviceVulkan::_texture_get_data_from_image(Texture *tex uint32_t mipmap_offset = 0; for (uint32_t mm_i = 0; mm_i < tex->mipmaps; mm_i++) { - uint32_t image_total = get_image_format_required_size(tex->format, tex->width, tex->height, p_2d ? 1 : tex->depth, mm_i + 1, &width, &height, &depth); uint8_t *write_ptr_mipmap = w + mipmap_offset; @@ -2363,7 +2394,6 @@ Vector<uint8_t> RenderingDeviceVulkan::_texture_get_data_from_image(Texture *tex } Vector<uint8_t> RenderingDeviceVulkan::texture_get_data(RID p_texture, uint32_t p_layer) { - _THREAD_SAFE_METHOD_ Texture *tex = texture_owner.getornull(p_texture); @@ -2384,13 +2414,12 @@ Vector<uint8_t> RenderingDeviceVulkan::texture_get_data(RID p_texture, uint32_t //does not need anything fancy, map and read. return _texture_get_data_from_image(tex, tex->image, tex->allocation, p_layer); } else { - //compute total image size uint32_t width, height, depth; uint32_t buffer_size = get_image_format_required_size(tex->format, tex->width, tex->height, tex->depth, tex->mipmaps, &width, &height, &depth); //allocate buffer - VkCommandBuffer command_buffer = frames[frame].setup_command_buffer; + VkCommandBuffer command_buffer = frames[frame].draw_command_buffer; //makes more sense to retrieve Buffer tmp_buffer; _buffer_allocate(&tmp_buffer, buffer_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_CPU_ONLY); @@ -2422,7 +2451,6 @@ Vector<uint8_t> RenderingDeviceVulkan::texture_get_data(RID p_texture, uint32_t uint32_t prev_size = 0; uint32_t offset = 0; for (uint32_t i = 0; i < tex->mipmaps; i++) { - VkBufferImageCopy buffer_image_copy; uint32_t image_size = get_image_format_required_size(tex->format, tex->width, tex->height, tex->depth, i + 1); @@ -2479,7 +2507,6 @@ Vector<uint8_t> RenderingDeviceVulkan::texture_get_data(RID p_texture, uint32_t Vector<uint8_t> buffer_data; { - buffer_data.resize(buffer_size); uint8_t *w = buffer_data.ptrw(); copymem(w, buffer_mem, buffer_size); @@ -2506,7 +2533,6 @@ bool RenderingDeviceVulkan::texture_is_valid(RID p_texture) { } Error RenderingDeviceVulkan::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) { - _THREAD_SAFE_METHOD_ Texture *src_tex = texture_owner.getornull(p_from_texture); @@ -2557,7 +2583,6 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, VkCommandBuffer command_buffer = p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer; { - //PRE Copy the image { //Source @@ -2604,7 +2629,6 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, //COPY { - VkImageCopy image_copy_region; image_copy_region.srcSubresource.aspectMask = src_tex->read_aspect_mask; image_copy_region.srcSubresource.baseArrayLayer = p_src_layer; @@ -2676,6 +2700,7 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, return OK; } + Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID p_to_texture, bool p_sync_with_draw) { _THREAD_SAFE_METHOD_ @@ -2710,7 +2735,6 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID VkCommandBuffer command_buffer = p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer; { - //PRE Copy the image { //Source @@ -2757,7 +2781,6 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID //COPY { - VkImageResolve image_copy_region; image_copy_region.srcSubresource.aspectMask = src_tex->read_aspect_mask; image_copy_region.srcSubresource.baseArrayLayer = src_tex->base_layer; @@ -2831,7 +2854,6 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID } 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) { - _THREAD_SAFE_METHOD_ Texture *src_tex = texture_owner.getornull(p_texture); @@ -2964,14 +2986,12 @@ bool RenderingDeviceVulkan::texture_is_format_supported_for_usage(DataFormat p_f /********************/ 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; Vector<VkAttachmentReference> depth_stencil_references; Vector<VkAttachmentReference> resolve_references; for (int i = 0; i < p_format.size(); i++) { - VkAttachmentDescription description; description.flags = 0; @@ -2988,7 +3008,6 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF bool is_storage = p_format[i].usage_flags & TEXTURE_USAGE_STORAGE_BIT; 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; @@ -3046,13 +3065,11 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF 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; 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_STORE; description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); @@ -3068,7 +3085,6 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF 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); @@ -3084,7 +3100,6 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF 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; @@ -3159,7 +3174,6 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF } RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_create(const Vector<AttachmentFormat> &p_format) { - _THREAD_SAFE_METHOD_ FramebufferFormatKey key; @@ -3189,6 +3203,63 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c return id; } +RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_create_empty(const Size2i &p_size) { + ERR_FAIL_COND_V(p_size.width <= 0 || p_size.height <= 0, INVALID_FORMAT_ID); + + FramebufferFormatKey key; + key.empty_size = p_size; + + const Map<FramebufferFormatKey, FramebufferFormatID>::Element *E = framebuffer_format_cache.find(key); + if (E) { + //exists, return + return E->get(); + } + + VkSubpassDescription subpass; + subpass.flags = 0; + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.inputAttachmentCount = 0; //unsupported for now + subpass.pInputAttachments = nullptr; + subpass.colorAttachmentCount = 0; + subpass.pColorAttachments = nullptr; + subpass.pDepthStencilAttachment = nullptr; + subpass.pResolveAttachments = nullptr; + subpass.preserveAttachmentCount = 0; + subpass.pPreserveAttachments = nullptr; + + VkRenderPassCreateInfo render_pass_create_info; + render_pass_create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + render_pass_create_info.pNext = nullptr; + render_pass_create_info.flags = 0; + render_pass_create_info.attachmentCount = 0; + render_pass_create_info.pAttachments = nullptr; + render_pass_create_info.subpassCount = 1; + render_pass_create_info.pSubpasses = &subpass; + render_pass_create_info.dependencyCount = 0; + render_pass_create_info.pDependencies = nullptr; + + VkRenderPass render_pass; + VkResult res = vkCreateRenderPass(device, &render_pass_create_info, nullptr, &render_pass); + + ERR_FAIL_COND_V_MSG(res, VK_NULL_HANDLE, "vkCreateRenderPass for empty fb failed with error " + itos(res) + "."); + + if (render_pass == VK_NULL_HANDLE) { //was likely invalid + return INVALID_ID; + } + + FramebufferFormatID id = FramebufferFormatID(framebuffer_format_cache.size()) | (FramebufferFormatID(ID_TYPE_FRAMEBUFFER_FORMAT) << FramebufferFormatID(ID_BASE_SHIFT)); + + E = framebuffer_format_cache.insert(key, id); + + FramebufferFormat fb_format; + fb_format.E = E; + fb_format.color_attachments = 0; + fb_format.render_pass = render_pass; + fb_format.samples = TEXTURE_SAMPLES_1; + framebuffer_formats[id] = fb_format; + return id; +} + RenderingDevice::TextureSamples RenderingDeviceVulkan::framebuffer_format_get_texture_samples(FramebufferFormatID p_format) { Map<FramebufferFormatID, FramebufferFormat>::Element *E = framebuffer_formats.find(p_format); ERR_FAIL_COND_V(!E, TEXTURE_SAMPLES_1); @@ -3200,8 +3271,17 @@ RenderingDevice::TextureSamples RenderingDeviceVulkan::framebuffer_format_get_te /**** RENDER TARGET ****/ /***********************/ -RID RenderingDeviceVulkan::framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check) { +RID RenderingDeviceVulkan::framebuffer_create_empty(const Size2i &p_size, FramebufferFormatID p_format_check) { + _THREAD_SAFE_METHOD_ + Framebuffer framebuffer; + framebuffer.format_id = framebuffer_format_create_empty(p_size); + ERR_FAIL_COND_V(p_format_check != INVALID_FORMAT_ID && framebuffer.format_id != p_format_check, RID()); + framebuffer.size = p_size; + + return framebuffer_owner.make_rid(framebuffer); +} +RID RenderingDeviceVulkan::framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check) { _THREAD_SAFE_METHOD_ Vector<AttachmentFormat> attachments; @@ -3249,7 +3329,6 @@ RID RenderingDeviceVulkan::framebuffer_create(const Vector<RID> &p_texture_attac } RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_get_format(RID p_framebuffer) { - _THREAD_SAFE_METHOD_ Framebuffer *framebuffer = framebuffer_owner.getornull(p_framebuffer); @@ -3263,7 +3342,6 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_get_form /*****************/ RID RenderingDeviceVulkan::sampler_create(const SamplerState &p_state) { - _THREAD_SAFE_METHOD_ VkSamplerCreateInfo sampler_create_info; @@ -3309,7 +3387,6 @@ RID RenderingDeviceVulkan::sampler_create(const SamplerState &p_state) { /**********************/ RID RenderingDeviceVulkan::vertex_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data) { - _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(p_data.size() && (uint32_t)p_data.size() != p_size_bytes, RID()); @@ -3328,7 +3405,6 @@ RID RenderingDeviceVulkan::vertex_buffer_create(uint32_t p_size_bytes, const Vec // Internally reference counted, this ID is warranted to be unique for the same description, but needs to be freed as many times as it was allocated RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats) { - _THREAD_SAFE_METHOD_ VertexDescriptionKey key; @@ -3380,7 +3456,6 @@ RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(cons } RID RenderingDeviceVulkan::vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector<RID> &p_src_buffers) { - _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!vertex_formats.has(p_vertex_format), RID()); @@ -3437,7 +3512,6 @@ RID RenderingDeviceVulkan::vertex_array_create(uint32_t p_vertex_count, VertexFo } RID RenderingDeviceVulkan::index_buffer_create(uint32_t p_index_count, IndexBufferFormat p_format, const Vector<uint8_t> &p_data, bool p_use_restart_indices) { - _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(p_index_count == 0, RID()); @@ -3487,7 +3561,6 @@ RID RenderingDeviceVulkan::index_buffer_create(uint32_t p_index_count, IndexBuff } RID RenderingDeviceVulkan::index_array_create(RID p_index_buffer, uint32_t p_index_offset, uint32_t p_index_count) { - _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!index_buffer_owner.owns(p_index_buffer), RID()); @@ -3751,7 +3824,6 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa #endif RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages) { - //descriptor layouts Vector<Vector<VkDescriptorSetLayoutBinding>> set_bindings; Vector<Vector<UniformInfo>> uniform_info; @@ -3768,7 +3840,6 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages bool is_compute = false; for (int i = 0; i < p_stages.size(); i++) { - if (p_stages[i].shader_stage == SHADER_STAGE_COMPUTE) { is_compute = true; ERR_FAIL_COND_V_MSG(p_stages.size() != 1, RID(), @@ -3792,7 +3863,6 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages uint32_t stage = p_stages[i].shader_stage; if (binding_count > 0) { - //Parse bindings Vector<SpvReflectDescriptorBinding *> bindings; @@ -3943,7 +4013,6 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages } if (stage == SHADER_STAGE_VERTEX) { - uint32_t iv_count = 0; result = spvReflectEnumerateInputVariables(&module, &iv_count, nullptr); ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, RID(), @@ -3966,7 +4035,6 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages } if (stage == SHADER_STAGE_FRAGMENT) { - uint32_t ov_count = 0; result = spvReflectEnumerateOutputVariables(&module, &ov_count, nullptr); ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, RID(), @@ -4079,9 +4147,7 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages //proceed to create descriptor sets if (success) { - for (int i = 0; i < set_bindings.size(); i++) { - //empty ones are fine if they were not used according to spec (binding count will be 0) VkDescriptorSetLayoutCreateInfo layout_create_info; layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; @@ -4190,7 +4256,6 @@ uint32_t RenderingDeviceVulkan::shader_get_vertex_input_attribute_mask(RID p_sha /******************/ RID RenderingDeviceVulkan::uniform_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data) { - _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(p_data.size() && (uint32_t)p_data.size() != p_size_bytes, RID()); @@ -4207,14 +4272,18 @@ RID RenderingDeviceVulkan::uniform_buffer_create(uint32_t p_size_bytes, const Ve return uniform_buffer_owner.make_rid(buffer); } -RID RenderingDeviceVulkan::storage_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data) { - +RID RenderingDeviceVulkan::storage_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data, uint32_t p_usage) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(p_data.size() && (uint32_t)p_data.size() != p_size_bytes, RID()); Buffer buffer; - Error err = _buffer_allocate(&buffer, p_size_bytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_GPU_ONLY); + buffer.usage = p_usage; + uint32_t flags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + if (p_usage & STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT) { + flags |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; + } + Error err = _buffer_allocate(&buffer, p_size_bytes, flags, VMA_MEMORY_USAGE_GPU_ONLY); ERR_FAIL_COND_V(err != OK, RID()); if (p_data.size()) { @@ -4227,7 +4296,6 @@ RID RenderingDeviceVulkan::storage_buffer_create(uint32_t p_size_bytes, const Ve } RID RenderingDeviceVulkan::texture_buffer_create(uint32_t p_size_elements, DataFormat p_format, const Vector<uint8_t> &p_data) { - _THREAD_SAFE_METHOD_ uint32_t element_size = get_format_vertex_size(p_format); @@ -4384,7 +4452,6 @@ void RenderingDeviceVulkan::_descriptor_pool_free(const DescriptorPoolKey &p_key } RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set) { - _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(p_uniforms.size() == 0, RID()); @@ -4425,7 +4492,7 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, } } ERR_FAIL_COND_V_MSG(uniform_idx == -1, RID(), - "All the shader bindings for the given set must be covered by the uniforms provided."); + "All the shader bindings for the given set must be covered by the uniforms provided. Binding (" + itos(set_uniform.binding) + ") was not provided."); const Uniform &uniform = uniforms[uniform_idx]; @@ -4437,6 +4504,12 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, write.pNext = nullptr; write.dstSet = VK_NULL_HANDLE; //will assign afterwards when everything is valid write.dstBinding = set_uniform.binding; + write.dstArrayElement = 0; + write.descriptorCount = 0; + write.descriptorType = VK_DESCRIPTOR_TYPE_MAX_ENUM; //Invalid value. + write.pImageInfo = nullptr; + write.pBufferInfo = nullptr; + write.pTexelBufferView = nullptr; uint32_t type_size = 1; switch (uniform.type) { @@ -4474,7 +4547,6 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, } break; case UNIFORM_TYPE_SAMPLER_WITH_TEXTURE: { - if (uniform.ids.size() != set_uniform.length * 2) { if (set_uniform.length > 1) { ERR_FAIL_V_MSG(RID(), "SamplerTexture (binding: " + itos(uniform.binding) + ") is an array of (" + itos(set_uniform.length) + ") sampler&texture elements, so it should provided twice the amount of IDs (sampler,texture pairs) to satisfy it (IDs provided: " + itos(uniform.ids.size()) + ")."); @@ -4528,7 +4600,6 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, } break; case UNIFORM_TYPE_TEXTURE: { - if (uniform.ids.size() != set_uniform.length) { if (set_uniform.length > 1) { ERR_FAIL_V_MSG(RID(), "Texture (binding: " + itos(uniform.binding) + ") is an array of (" + itos(set_uniform.length) + ") textures, so it should be provided equal number of texture IDs to satisfy it (IDs provided: " + itos(uniform.ids.size()) + ")."); @@ -4579,7 +4650,6 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, type_size = uniform.ids.size(); } break; case UNIFORM_TYPE_IMAGE: { - if (uniform.ids.size() != set_uniform.length) { if (set_uniform.length > 1) { ERR_FAIL_V_MSG(RID(), "Image (binding: " + itos(uniform.binding) + ") is an array of (" + itos(set_uniform.length) + ") textures, so it should be provided equal number of texture IDs to satisfy it (IDs provided: " + itos(uniform.ids.size()) + ")."); @@ -4659,7 +4729,6 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, } break; case UNIFORM_TYPE_SAMPLER_WITH_TEXTURE_BUFFER: { - if (uniform.ids.size() != set_uniform.length * 2) { if (set_uniform.length > 1) { ERR_FAIL_V_MSG(RID(), "SamplerBuffer (binding: " + itos(uniform.binding) + ") is an array of (" + itos(set_uniform.length) + ") sampler buffer elements, so it should provided twice the amount of IDs (sampler,buffer pairs) to satisfy it (IDs provided: " + itos(uniform.ids.size()) + ")."); @@ -4741,7 +4810,6 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, write.pTexelBufferView = nullptr; } break; case UNIFORM_TYPE_INPUT_ATTACHMENT: { - } break; default: { } @@ -4865,7 +4933,6 @@ Error RenderingDeviceVulkan::buffer_update(RID p_buffer, uint32_t p_offset, uint } Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) { - _THREAD_SAFE_METHOD_ Buffer *buffer = nullptr; @@ -4898,7 +4965,6 @@ Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) { Vector<uint8_t> buffer_data; { - buffer_data.resize(buffer->size); uint8_t *w = buffer_data.ptrw(); copymem(w, buffer_mem, buffer->size); @@ -4916,7 +4982,6 @@ Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) { /*************************/ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags) { - _THREAD_SAFE_METHOD_ //needs a shader @@ -5326,7 +5391,6 @@ RID RenderingDeviceVulkan::compute_pipeline_create(RID p_shader) { } bool RenderingDeviceVulkan::compute_pipeline_is_valid(RID p_pipeline) { - return compute_pipeline_owner.owns(p_pipeline); } @@ -5339,14 +5403,15 @@ int RenderingDeviceVulkan::screen_get_width(DisplayServer::WindowID p_screen) co ERR_FAIL_COND_V_MSG(local_device.is_valid(), -1, "Local devices have no screen"); return context->window_get_width(p_screen); } + int RenderingDeviceVulkan::screen_get_height(DisplayServer::WindowID p_screen) const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V_MSG(local_device.is_valid(), -1, "Local devices have no screen"); return context->window_get_height(p_screen); } -RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::screen_get_framebuffer_format() const { +RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::screen_get_framebuffer_format() const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V_MSG(local_device.is_valid(), INVALID_ID, "Local devices have no screen"); @@ -5376,7 +5441,6 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::screen_get_framebuff /*******************/ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin_for_screen(DisplayServer::WindowID p_screen, const Color &p_clear_color) { - _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V_MSG(local_device.is_valid(), INVALID_ID, "Local devices have no screen"); @@ -5440,7 +5504,6 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin_for_screen(Di } 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_color_action = p_initial_color_action; vk.final_color_action = p_final_color_action; @@ -5484,8 +5547,7 @@ Error RenderingDeviceVulkan::_draw_list_setup_framebuffer(Framebuffer *p_framebu return OK; } -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) { - +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, const Vector<RID> &p_storage_textures) { VkRenderPassBeginInfo render_pass_begin; render_pass_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; render_pass_begin.pNext = nullptr; @@ -5530,6 +5592,37 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff render_pass_begin.clearValueCount = clear_values.size(); render_pass_begin.pClearValues = clear_values.ptr(); + for (int i = 0; i < p_storage_textures.size(); i++) { + Texture *texture = texture_owner.getornull(p_storage_textures[i]); + ERR_CONTINUE_MSG(!(texture->usage_flags & TEXTURE_USAGE_STORAGE_BIT), "Supplied storage texture " + itos(i) + " for draw list ist not set to be used for storage."); + + if (texture->usage_flags & TEXTURE_USAGE_SAMPLING_BIT) { + //must change layout to general + 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_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + image_memory_barrier.oldLayout = texture->layout; + image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; + + image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_memory_barrier.image = texture->image; + image_memory_barrier.subresourceRange.aspectMask = texture->read_aspect_mask; + image_memory_barrier.subresourceRange.baseMipLevel = texture->base_mipmap; + image_memory_barrier.subresourceRange.levelCount = texture->mipmaps; + image_memory_barrier.subresourceRange.baseArrayLayer = texture->base_layer; + image_memory_barrier.subresourceRange.layerCount = texture->layers; + + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); + + texture->layout = VK_IMAGE_LAYOUT_GENERAL; + + draw_list_storage_textures.push_back(p_storage_textures[i]); + } + } + vkCmdBeginRenderPass(command_buffer, &render_pass_begin, subpass_contents); //mark textures as bound @@ -5562,7 +5655,6 @@ void RenderingDeviceVulkan::_draw_list_insert_clear_region(DrawList *draw_list, clear_at.colorAttachment = color_index++; clear_at.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; } else if (p_clear_depth && texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { - clear_at.clearValue.depthStencil.depth = p_depth; clear_at.clearValue.depthStencil.stencil = p_stencil; clear_at.colorAttachment = 0; @@ -5587,8 +5679,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_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) { - +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, const Vector<RID> &p_storage_textures) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V_MSG(draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time."); @@ -5638,7 +5729,7 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu 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_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); + 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, p_storage_textures); if (err != OK) { return INVALID_ID; @@ -5678,8 +5769,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_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) { - +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, const Vector<RID> &p_storage_textures) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(p_splits < 1, ERR_INVALID_DECLARATION); @@ -5726,7 +5816,6 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p uint32_t from = split_draw_list_allocators.size(); split_draw_list_allocators.resize(p_splits); for (uint32_t i = from; i < p_splits; i++) { - VkCommandPoolCreateInfo cmd_pool_info; cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; cmd_pool_info.pNext = nullptr; @@ -5737,7 +5826,6 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p ERR_FAIL_COND_V_MSG(res, ERR_CANT_CREATE, "vkCreateCommandPool failed with error " + itos(res) + "."); for (int j = 0; j < frame_count; j++) { - VkCommandBuffer command_buffer; VkCommandBufferAllocateInfo cmdbuf; @@ -5763,7 +5851,7 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p 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_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); + 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, p_storage_textures); if (err != OK) { return ERR_CANT_CREATE; @@ -5774,7 +5862,6 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p draw_list_split = true; for (uint32_t i = 0; i < p_splits; i++) { - //take a command buffer and initialize it VkCommandBuffer command_buffer = split_draw_list_allocators[p_splits].command_buffers[frame]; @@ -5843,7 +5930,6 @@ 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 nullptr; } @@ -5873,7 +5959,6 @@ RenderingDeviceVulkan::DrawList *RenderingDeviceVulkan::_get_draw_list_ptr(DrawL } 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); #ifdef DEBUG_ENABLED @@ -5924,7 +6009,7 @@ void RenderingDeviceVulkan::draw_list_bind_render_pipeline(DrawListID p_list, RI if (pipeline->push_constant_size) { dl->state.pipeline_push_constant_stages = pipeline->push_constant_stages; #ifdef DEBUG_ENABLED - dl->validation.pipeline_push_constant_suppplied = false; + dl->validation.pipeline_push_constant_supplied = false; #endif } @@ -5944,7 +6029,6 @@ void RenderingDeviceVulkan::draw_list_bind_render_pipeline(DrawListID p_list, RI } void RenderingDeviceVulkan::draw_list_bind_uniform_set(DrawListID p_list, RID p_uniform_set, uint32_t p_index) { - #ifdef DEBUG_ENABLED ERR_FAIL_COND_MSG(p_index >= limits.maxBoundDescriptorSets || p_index > MAX_UNIFORM_SETS, "Attempting to bind a descriptor set (" + itos(p_index) + ") greater than what the hardware supports (" + itos(limits.maxBoundDescriptorSets) + ")."); @@ -6007,8 +6091,8 @@ void RenderingDeviceVulkan::draw_list_bind_vertex_array(DrawListID p_list, RID p dl->validation.vertex_array_size = vertex_array->vertex_count; vkCmdBindVertexBuffers(dl->command_buffer, 0, vertex_array->buffers.size(), vertex_array->buffers.ptr(), vertex_array->offsets.ptr()); } -void RenderingDeviceVulkan::draw_list_bind_index_array(DrawListID p_list, RID p_index_array) { +void RenderingDeviceVulkan::draw_list_bind_index_array(DrawListID p_list, RID p_index_array) { DrawList *dl = _get_draw_list_ptr(p_list); ERR_FAIL_COND(!dl); #ifdef DEBUG_ENABLED @@ -6033,7 +6117,6 @@ void RenderingDeviceVulkan::draw_list_bind_index_array(DrawListID p_list, RID p_ } void RenderingDeviceVulkan::draw_list_set_line_width(DrawListID p_list, float p_width) { - DrawList *dl = _get_draw_list_ptr(p_list); ERR_FAIL_COND(!dl); #ifdef DEBUG_ENABLED @@ -6057,12 +6140,11 @@ void RenderingDeviceVulkan::draw_list_set_push_constant(DrawListID p_list, const #endif vkCmdPushConstants(dl->command_buffer, dl->state.pipeline_layout, dl->state.pipeline_push_constant_stages, 0, p_data_size, p_data); #ifdef DEBUG_ENABLED - dl->validation.pipeline_push_constant_suppplied = true; + dl->validation.pipeline_push_constant_supplied = true; #endif } 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); #ifdef DEBUG_ENABLED @@ -6086,7 +6168,7 @@ void RenderingDeviceVulkan::draw_list_draw(DrawListID p_list, bool p_use_indices if (dl->validation.pipeline_push_constant_size > 0) { //using push constants, check that they were supplied - ERR_FAIL_COND_MSG(!dl->validation.pipeline_push_constant_suppplied, + ERR_FAIL_COND_MSG(!dl->validation.pipeline_push_constant_supplied, "The shader in this pipeline requires a push constant to be set before drawing, but it's not present."); } @@ -6095,13 +6177,11 @@ void RenderingDeviceVulkan::draw_list_draw(DrawListID p_list, bool p_use_indices //Bind descriptor sets for (uint32_t i = 0; i < dl->state.set_count; i++) { - if (dl->state.sets[i].pipeline_expected_format == 0) { continue; //nothing expected by this pipeline } #ifdef DEBUG_ENABLED if (dl->state.sets[i].pipeline_expected_format != dl->state.sets[i].uniform_set_format) { - if (dl->state.sets[i].uniform_set_format == 0) { ERR_FAIL_MSG("Uniforms were never supplied for set (" + itos(i) + ") at the time of drawing, which are required by the pipeline"); } else if (uniform_set_owner.owns(dl->state.sets[i].uniform_set)) { @@ -6120,7 +6200,6 @@ 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."); @@ -6148,7 +6227,6 @@ 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) { @@ -6158,7 +6236,6 @@ void RenderingDeviceVulkan::draw_list_draw(DrawListID p_list, bool p_use_indices #endif 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."); @@ -6201,6 +6278,7 @@ void RenderingDeviceVulkan::draw_list_enable_scissor(DrawListID p_list, const Re vkCmdSetScissor(dl->command_buffer, 0, 1, &scissor); } + void RenderingDeviceVulkan::draw_list_disable_scissor(DrawListID p_list) { DrawList *dl = _get_draw_list_ptr(p_list); ERR_FAIL_COND(!dl); @@ -6217,7 +6295,6 @@ void RenderingDeviceVulkan::draw_list_disable_scissor(DrawListID p_list) { } void RenderingDeviceVulkan::draw_list_end() { - _THREAD_SAFE_METHOD_ ERR_FAIL_COND_MSG(!draw_list, "Immediate draw list is already inactive."); @@ -6255,6 +6332,33 @@ void RenderingDeviceVulkan::draw_list_end() { draw_list_bound_textures.clear(); + for (int i = 0; i < draw_list_storage_textures.size(); i++) { + Texture *texture = texture_owner.getornull(draw_list_storage_textures[i]); + + 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_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + image_memory_barrier.oldLayout = texture->layout; + image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_memory_barrier.image = texture->image; + image_memory_barrier.subresourceRange.aspectMask = texture->read_aspect_mask; + image_memory_barrier.subresourceRange.baseMipLevel = texture->base_mipmap; + image_memory_barrier.subresourceRange.levelCount = texture->mipmaps; + image_memory_barrier.subresourceRange.baseArrayLayer = texture->base_layer; + image_memory_barrier.subresourceRange.layerCount = texture->layers; + + vkCmdPipelineBarrier(frames[frame].draw_command_buffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); + + texture->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + } + + draw_list_storage_textures.clear(); + // To ensure proper synchronization, we must make sure rendering is done before: // * Some buffer is copied // * Another render pass happens (since we may be done @@ -6271,7 +6375,6 @@ void RenderingDeviceVulkan::draw_list_end() { /***********************/ RenderingDevice::ComputeListID RenderingDeviceVulkan::compute_list_begin() { - ERR_FAIL_COND_V_MSG(draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time."); ERR_FAIL_COND_V_MSG(compute_list != nullptr, INVALID_ID, "Only one draw/compute list can be active at the same time."); @@ -6328,7 +6431,7 @@ void RenderingDeviceVulkan::compute_list_bind_compute_pipeline(ComputeListID p_l if (pipeline->push_constant_size) { cl->state.pipeline_push_constant_stages = pipeline->push_constant_stages; #ifdef DEBUG_ENABLED - cl->validation.pipeline_push_constant_suppplied = false; + cl->validation.pipeline_push_constant_supplied = false; #endif } @@ -6341,6 +6444,7 @@ void RenderingDeviceVulkan::compute_list_bind_compute_pipeline(ComputeListID p_l cl->validation.pipeline_push_constant_size = pipeline->push_constant_size; #endif } + void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list, RID p_uniform_set, uint32_t p_index) { ERR_FAIL_COND(p_list != ID_TYPE_COMPUTE_LIST); ERR_FAIL_COND(!compute_list); @@ -6373,7 +6477,6 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list, for (uint32_t i = 0; i < textures_to_sampled_count; i++) { if (textures_to_sampled[i]->layout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { - VkImageMemoryBarrier image_memory_barrier; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_memory_barrier.pNext = nullptr; @@ -6404,7 +6507,6 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list, for (uint32_t i = 0; i < textures_to_storage_count; i++) { if (textures_to_storage[i]->layout != VK_IMAGE_LAYOUT_GENERAL) { - VkImageMemoryBarrier image_memory_barrier; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_memory_barrier.pNext = nullptr; @@ -6462,9 +6564,10 @@ void RenderingDeviceVulkan::compute_list_set_push_constant(ComputeListID p_list, #endif vkCmdPushConstants(cl->command_buffer, cl->state.pipeline_layout, cl->state.pipeline_push_constant_stages, 0, p_data_size, p_data); #ifdef DEBUG_ENABLED - cl->validation.pipeline_push_constant_suppplied = true; + cl->validation.pipeline_push_constant_supplied = true; #endif } + void RenderingDeviceVulkan::compute_list_dispatch(ComputeListID p_list, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) { ERR_FAIL_COND(p_list != ID_TYPE_COMPUTE_LIST); ERR_FAIL_COND(!compute_list); @@ -6488,7 +6591,7 @@ void RenderingDeviceVulkan::compute_list_dispatch(ComputeListID p_list, uint32_t if (cl->validation.pipeline_push_constant_size > 0) { //using push constants, check that they were supplied - ERR_FAIL_COND_MSG(!cl->validation.pipeline_push_constant_suppplied, + ERR_FAIL_COND_MSG(!cl->validation.pipeline_push_constant_supplied, "The shader in this pipeline requires a push constant to be set before drawing, but it's not present."); } @@ -6497,13 +6600,11 @@ void RenderingDeviceVulkan::compute_list_dispatch(ComputeListID p_list, uint32_t //Bind descriptor sets for (uint32_t i = 0; i < cl->state.set_count; i++) { - if (cl->state.sets[i].pipeline_expected_format == 0) { continue; //nothing expected by this pipeline } #ifdef DEBUG_ENABLED if (cl->state.sets[i].pipeline_expected_format != cl->state.sets[i].uniform_set_format) { - if (cl->state.sets[i].uniform_set_format == 0) { ERR_FAIL_MSG("Uniforms were never supplied for set (" + itos(i) + ") at the time of drawing, which are required by the pipeline"); } else if (uniform_set_owner.owns(cl->state.sets[i].uniform_set)) { @@ -6524,6 +6625,62 @@ 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_dispatch_indirect(ComputeListID p_list, RID p_buffer, uint32_t p_offset) { + ERR_FAIL_COND(p_list != ID_TYPE_COMPUTE_LIST); + ERR_FAIL_COND(!compute_list); + + ComputeList *cl = compute_list; + Buffer *buffer = storage_buffer_owner.getornull(p_buffer); + ERR_FAIL_COND(!buffer); + + ERR_FAIL_COND_MSG(!(buffer->usage & STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT), "Buffer provided was not created to do indirect dispatch."); + + ERR_FAIL_COND_MSG(p_offset + 12 > buffer->size, "Offset provided (+12) is past the end of buffer."); + +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_MSG(!cl->validation.active, "Submitted Compute Lists can no longer be modified."); +#endif + +#ifdef DEBUG_ENABLED + + ERR_FAIL_COND_MSG(!cl->validation.pipeline_active, "No compute pipeline was set before attempting to draw."); + + if (cl->validation.pipeline_push_constant_size > 0) { + //using push constants, check that they were supplied + ERR_FAIL_COND_MSG(!cl->validation.pipeline_push_constant_supplied, + "The shader in this pipeline requires a push constant to be set before drawing, but it's not present."); + } + +#endif + + //Bind descriptor sets + + for (uint32_t i = 0; i < cl->state.set_count; i++) { + if (cl->state.sets[i].pipeline_expected_format == 0) { + continue; //nothing expected by this pipeline + } +#ifdef DEBUG_ENABLED + if (cl->state.sets[i].pipeline_expected_format != cl->state.sets[i].uniform_set_format) { + if (cl->state.sets[i].uniform_set_format == 0) { + ERR_FAIL_MSG("Uniforms were never supplied for set (" + itos(i) + ") at the time of drawing, which are required by the pipeline"); + } else if (uniform_set_owner.owns(cl->state.sets[i].uniform_set)) { + UniformSet *us = uniform_set_owner.getornull(cl->state.sets[i].uniform_set); + ERR_FAIL_MSG("Uniforms supplied for set (" + itos(i) + "):\n" + _shader_uniform_debug(us->shader_id, us->shader_set) + "\nare not the same format as required by the pipeline shader. Pipeline shader requires the following bindings:\n" + _shader_uniform_debug(cl->state.pipeline_shader)); + } else { + ERR_FAIL_MSG("Uniforms supplied for set (" + itos(i) + ", which was was just freed) are not the same format as required by the pipeline shader. Pipeline shader requires the following bindings:\n" + _shader_uniform_debug(cl->state.pipeline_shader)); + } + } +#endif + if (!cl->state.sets[i].bound) { + //All good, see if this requires re-binding + vkCmdBindDescriptorSets(cl->command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, cl->state.pipeline_layout, i, 1, &cl->state.sets[i].descriptor_set, 0, nullptr); + cl->state.sets[i].bound = true; + } + } + + vkCmdDispatchIndirect(cl->command_buffer, buffer->buffer, p_offset); +} + void RenderingDeviceVulkan::compute_list_add_barrier(ComputeListID p_list) { #ifdef FORCE_FULL_BARRIER _full_barrier(true); @@ -6536,7 +6693,6 @@ void RenderingDeviceVulkan::compute_list_end() { ERR_FAIL_COND(!compute_list); for (Set<Texture *>::Element *E = compute_list->state.textures_to_sampled_layout.front(); E; E = E->next()) { - VkImageMemoryBarrier image_memory_barrier; image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; image_memory_barrier.pNext = nullptr; @@ -6564,10 +6720,17 @@ void RenderingDeviceVulkan::compute_list_end() { #ifdef FORCE_FULL_BARRIER _full_barrier(true); #else - _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); + _memory_barrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 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 | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INDIRECT_COMMAND_READ_BIT, true); #endif } +void RenderingDeviceVulkan::full_barrier() { +#ifndef DEBUG_ENABLED + ERR_PRINT("Full barrier is debug-only, should not be used in production"); +#endif + _full_barrier(true); +} + #if 0 void RenderingDeviceVulkan::draw_list_render_secondary_to_framebuffer(ID p_framebuffer, ID *p_draw_lists, uint32_t p_draw_list_count, InitialAction p_initial_action, FinalAction p_final_action, const Vector<Variant> &p_clear_colors) { @@ -6628,7 +6791,6 @@ void RenderingDeviceVulkan::draw_list_render_secondary_to_framebuffer(ID p_frame #endif void RenderingDeviceVulkan::_free_internal(RID p_id) { - //push everything so it's disposed of next time this frame index is processed (means, it's safe to do it) if (texture_owner.owns(p_id)) { Texture *texture = texture_owner.getornull(p_id); @@ -6691,8 +6853,8 @@ void RenderingDeviceVulkan::_free_internal(RID p_id) { ERR_PRINT("Attempted to free invalid ID: " + itos(p_id.get_id())); } } -void RenderingDeviceVulkan::free(RID p_id) { +void RenderingDeviceVulkan::free(RID p_id) { _THREAD_SAFE_METHOD_ _free_dependencies(p_id); //recursively erase dependencies first, to avoid potential API problems @@ -6700,7 +6862,6 @@ void RenderingDeviceVulkan::free(RID p_id) { } void RenderingDeviceVulkan::_finalize_command_bufers() { - if (draw_list) { ERR_PRINT("Found open draw list at the end of the frame, this should never happen (further drawing will likely not work)."); } @@ -6716,7 +6877,6 @@ void RenderingDeviceVulkan::_finalize_command_bufers() { } void RenderingDeviceVulkan::_begin_frame() { - //erase pending resources _free_pending_resources(frame); @@ -6763,7 +6923,6 @@ void RenderingDeviceVulkan::_begin_frame() { } void RenderingDeviceVulkan::swap_buffers() { - ERR_FAIL_COND_MSG(local_device.is_valid(), "Local devices can't swap buffers."); _THREAD_SAFE_METHOD_ @@ -6790,12 +6949,12 @@ void RenderingDeviceVulkan::submit() { } void RenderingDeviceVulkan::sync() { - ERR_FAIL_COND_MSG(local_device.is_null(), "Only local devices can submit and sync."); ERR_FAIL_COND_MSG(!local_device_processing, "sync can only be called after a submit"); context->local_device_sync(local_device); _begin_frame(); + local_device_processing = false; } void RenderingDeviceVulkan::_free_pending_resources(int p_frame) { @@ -6895,7 +7054,6 @@ void RenderingDeviceVulkan::_free_pending_resources(int p_frame) { //buffers while (frames[p_frame].buffers_to_dispose_of.front()) { - _buffer_free(&frames[p_frame].buffers_to_dispose_of.front()->get()); frames[p_frame].buffers_to_dispose_of.pop_front(); @@ -6912,8 +7070,13 @@ uint32_t RenderingDeviceVulkan::get_frame_delay() const { return frame_count; } -void RenderingDeviceVulkan::_flush(bool p_current_frame) { +uint64_t RenderingDeviceVulkan::get_memory_usage() const { + VmaStats stats; + vmaCalculateStats(allocator, &stats); + return stats.total.usedBytes; +} +void RenderingDeviceVulkan::_flush(bool p_current_frame) { if (local_device.is_valid() && !p_current_frame) { return; //flushign previous frames has no effect with local device } @@ -6924,7 +7087,6 @@ void RenderingDeviceVulkan::_flush(bool p_current_frame) { } if (local_device.is_valid()) { - VkCommandBuffer command_buffers[2] = { frames[frame].setup_command_buffer, frames[frame].draw_command_buffer }; context->local_device_push_command_buffers(local_device, command_buffers, 2); context->local_device_sync(local_device); @@ -6970,12 +7132,12 @@ void RenderingDeviceVulkan::_flush(bool p_current_frame) { } void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_device) { - context = p_context; device = p_context->get_device(); if (p_local_device) { frame_count = 1; local_device = p_context->local_device_create(); + device = p_context->local_device_get_vk_device(local_device); } else { frame_count = p_context->get_swapchain_image_count() + 1; //always need one extra to ensure it's unused at any time, without having to use a fence for this. } @@ -6995,7 +7157,6 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de frame = 0; //create setup and frame buffers for (int i = 0; i < frame_count; i++) { - frames[i].index = 0; { //create command pool, one per frame is recommended @@ -7119,7 +7280,6 @@ void RenderingDeviceVulkan::_free_rids(T &p_owner, const char *p_type) { } void RenderingDeviceVulkan::capture_timestamp(const String &p_name, bool p_sync_to_draw) { - ERR_FAIL_COND(frames[frame].timestamp_count >= max_timestamp_query_elements); { @@ -7211,10 +7371,12 @@ uint64_t RenderingDeviceVulkan::get_captured_timestamp_gpu_time(uint32_t p_index return l; } + uint64_t RenderingDeviceVulkan::get_captured_timestamp_cpu_time(uint32_t p_index) const { ERR_FAIL_UNSIGNED_INDEX_V(p_index, frames[frame].timestamp_result_count, 0); return frames[frame].timestamp_cpu_result_values[p_index]; } + String RenderingDeviceVulkan::get_captured_timestamp_name(uint32_t p_index) const { ERR_FAIL_UNSIGNED_INDEX_V(p_index, frames[frame].timestamp_result_count, String()); return frames[frame].timestamp_result_names[p_index]; @@ -7222,49 +7384,83 @@ String RenderingDeviceVulkan::get_captured_timestamp_name(uint32_t p_index) cons int RenderingDeviceVulkan::limit_get(Limit p_limit) { switch (p_limit) { - case LIMIT_MAX_BOUND_UNIFORM_SETS: return limits.maxBoundDescriptorSets; - case LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS: return limits.maxColorAttachments; - case LIMIT_MAX_TEXTURES_PER_UNIFORM_SET: return limits.maxDescriptorSetSampledImages; - case LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET: return limits.maxDescriptorSetSamplers; - case LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET: return limits.maxDescriptorSetStorageBuffers; - case LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET: return limits.maxDescriptorSetStorageImages; - case LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET: return limits.maxDescriptorSetUniformBuffers; - case LIMIT_MAX_DRAW_INDEXED_INDEX: return limits.maxDrawIndexedIndexValue; - case LIMIT_MAX_FRAMEBUFFER_HEIGHT: return limits.maxFramebufferHeight; - case LIMIT_MAX_FRAMEBUFFER_WIDTH: return limits.maxFramebufferWidth; - case LIMIT_MAX_TEXTURE_ARRAY_LAYERS: return limits.maxImageArrayLayers; - case LIMIT_MAX_TEXTURE_SIZE_1D: return limits.maxImageDimension1D; - case LIMIT_MAX_TEXTURE_SIZE_2D: return limits.maxImageDimension2D; - case LIMIT_MAX_TEXTURE_SIZE_3D: return limits.maxImageDimension3D; - case LIMIT_MAX_TEXTURE_SIZE_CUBE: return limits.maxImageDimensionCube; - case LIMIT_MAX_TEXTURES_PER_SHADER_STAGE: return limits.maxPerStageDescriptorSampledImages; - case LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE: return limits.maxPerStageDescriptorSamplers; - case LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE: return limits.maxPerStageDescriptorStorageBuffers; - case LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE: return limits.maxPerStageDescriptorStorageImages; - case LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE: return limits.maxPerStageDescriptorUniformBuffers; - case LIMIT_MAX_PUSH_CONSTANT_SIZE: return limits.maxPushConstantsSize; - case LIMIT_MAX_UNIFORM_BUFFER_SIZE: return limits.maxUniformBufferRange; - case LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET: return limits.maxVertexInputAttributeOffset; - case LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES: return limits.maxVertexInputAttributes; - case LIMIT_MAX_VERTEX_INPUT_BINDINGS: return limits.maxVertexInputBindings; - case LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE: return limits.maxVertexInputBindingStride; - case LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT: return limits.minUniformBufferOffsetAlignment; - case LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X: return limits.maxComputeWorkGroupCount[0]; - case LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Y: return limits.maxComputeWorkGroupCount[1]; - case LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Z: return limits.maxComputeWorkGroupCount[2]; - case LIMIT_MAX_COMPUTE_WORKGROUP_INVOCATIONS: return limits.maxComputeWorkGroupInvocations; - case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X: return limits.maxComputeWorkGroupSize[0]; - case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y: return limits.maxComputeWorkGroupSize[1]; - case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z: return limits.maxComputeWorkGroupSize[2]; - - default: ERR_FAIL_V(0); + case LIMIT_MAX_BOUND_UNIFORM_SETS: + return limits.maxBoundDescriptorSets; + case LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS: + return limits.maxColorAttachments; + case LIMIT_MAX_TEXTURES_PER_UNIFORM_SET: + return limits.maxDescriptorSetSampledImages; + case LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET: + return limits.maxDescriptorSetSamplers; + case LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET: + return limits.maxDescriptorSetStorageBuffers; + case LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET: + return limits.maxDescriptorSetStorageImages; + case LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET: + return limits.maxDescriptorSetUniformBuffers; + case LIMIT_MAX_DRAW_INDEXED_INDEX: + return limits.maxDrawIndexedIndexValue; + case LIMIT_MAX_FRAMEBUFFER_HEIGHT: + return limits.maxFramebufferHeight; + case LIMIT_MAX_FRAMEBUFFER_WIDTH: + return limits.maxFramebufferWidth; + case LIMIT_MAX_TEXTURE_ARRAY_LAYERS: + return limits.maxImageArrayLayers; + case LIMIT_MAX_TEXTURE_SIZE_1D: + return limits.maxImageDimension1D; + case LIMIT_MAX_TEXTURE_SIZE_2D: + return limits.maxImageDimension2D; + case LIMIT_MAX_TEXTURE_SIZE_3D: + return limits.maxImageDimension3D; + case LIMIT_MAX_TEXTURE_SIZE_CUBE: + return limits.maxImageDimensionCube; + case LIMIT_MAX_TEXTURES_PER_SHADER_STAGE: + return limits.maxPerStageDescriptorSampledImages; + case LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE: + return limits.maxPerStageDescriptorSamplers; + case LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE: + return limits.maxPerStageDescriptorStorageBuffers; + case LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE: + return limits.maxPerStageDescriptorStorageImages; + case LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE: + return limits.maxPerStageDescriptorUniformBuffers; + case LIMIT_MAX_PUSH_CONSTANT_SIZE: + return limits.maxPushConstantsSize; + case LIMIT_MAX_UNIFORM_BUFFER_SIZE: + return limits.maxUniformBufferRange; + case LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET: + return limits.maxVertexInputAttributeOffset; + case LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES: + return limits.maxVertexInputAttributes; + case LIMIT_MAX_VERTEX_INPUT_BINDINGS: + return limits.maxVertexInputBindings; + case LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE: + return limits.maxVertexInputBindingStride; + case LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT: + return limits.minUniformBufferOffsetAlignment; + case LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X: + return limits.maxComputeWorkGroupCount[0]; + case LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Y: + return limits.maxComputeWorkGroupCount[1]; + case LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Z: + return limits.maxComputeWorkGroupCount[2]; + case LIMIT_MAX_COMPUTE_WORKGROUP_INVOCATIONS: + return limits.maxComputeWorkGroupInvocations; + case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X: + return limits.maxComputeWorkGroupSize[0]; + case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y: + return limits.maxComputeWorkGroupSize[1]; + case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z: + return limits.maxComputeWorkGroupSize[2]; + + default: + ERR_FAIL_V(0); } return 0; } void RenderingDeviceVulkan::finalize() { - //free all resources _flush(false); @@ -7290,7 +7486,6 @@ void RenderingDeviceVulkan::finalize() { WARN_PRINT(itos(owned.size()) + " RIDs of type 'Texture' were leaked."); //free shared first for (List<RID>::Element *E = owned.front(); E;) { - List<RID>::Element *N = E->next(); if (texture_is_shared(E->get())) { free(E->get()); |