diff options
Diffstat (limited to 'drivers/vulkan')
-rw-r--r-- | drivers/vulkan/SCsub | 21 | ||||
-rw-r--r-- | drivers/vulkan/rendering_device_vulkan.cpp | 141 | ||||
-rw-r--r-- | drivers/vulkan/rendering_device_vulkan.h | 6 | ||||
-rw-r--r-- | drivers/vulkan/vulkan_context.cpp | 60 | ||||
-rw-r--r-- | drivers/vulkan/vulkan_context.h | 8 |
5 files changed, 179 insertions, 57 deletions
diff --git a/drivers/vulkan/SCsub b/drivers/vulkan/SCsub index 3e0f5788c3..8fe75367a8 100644 --- a/drivers/vulkan/SCsub +++ b/drivers/vulkan/SCsub @@ -6,24 +6,13 @@ thirdparty_obj = [] thirdparty_dir = "#thirdparty/vulkan" thirdparty_volk_dir = "#thirdparty/volk" +# Use bundled Vulkan headers +env.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "/include"]) + if env["use_volk"]: env.AppendUnique(CPPDEFINES=["USE_VOLK"]) env.Prepend(CPPPATH=[thirdparty_volk_dir]) -if env["platform"] == "android" and not env["use_volk"]: - # Use NDK Vulkan headers - ndk_vulkan_dir = env["ANDROID_NDK_ROOT"] + "/sources/third_party/vulkan/src" - thirdparty_includes = [ - ndk_vulkan_dir, - ndk_vulkan_dir + "/include", - ndk_vulkan_dir + "/layers", - ndk_vulkan_dir + "/layers/generated", - ] - env.Prepend(CPPPATH=thirdparty_includes) -else: - # Use bundled Vulkan headers - env.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "/include"]) - if env["platform"] == "android": env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_ANDROID_KHR"]) elif env["platform"] == "iphone": @@ -47,6 +36,10 @@ if env["use_volk"]: thirdparty_sources_volk = [thirdparty_volk_dir + "/volk.c"] env_thirdparty_volk.add_source_files(thirdparty_obj, thirdparty_sources_volk) +elif env["platform"] == "android": + # Our current NDK version only provides old Vulkan headers, + # so we have to limit VMA. + env_thirdparty_vma.AppendUnique(CPPDEFINES=["VMA_VULKAN_VERSION=1000000"]) env_thirdparty_vma.add_source_files(thirdparty_obj, thirdparty_sources_vma) diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index f6677e2da4..a4324f0a2c 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -2740,6 +2740,14 @@ bool RenderingDeviceVulkan::texture_is_valid(RID p_texture) { return texture_owner.owns(p_texture); } +Size2i RenderingDeviceVulkan::texture_size(RID p_texture) { + _THREAD_SAFE_METHOD_ + + Texture *tex = texture_owner.getornull(p_texture); + ERR_FAIL_COND_V(!tex, Size2i()); + return Size2i(tex->width, tex->height); +} + 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, uint32_t p_post_barrier) { _THREAD_SAFE_METHOD_ @@ -4442,7 +4450,10 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa } #endif -#define SHADER_BINARY_VERSION 1 +//version 1: initial +//version 2: Added shader name + +#define SHADER_BINARY_VERSION 2 String RenderingDeviceVulkan::shader_get_binary_cache_key() const { return "Vulkan-SV" + itos(SHADER_BINARY_VERSION); @@ -4476,9 +4487,10 @@ struct RenderingDeviceVulkanShaderBinaryData { uint32_t push_constant_size; uint32_t push_constants_vk_stage; uint32_t stage_count; + uint32_t shader_name_len; }; -Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Vector<ShaderStageSPIRVData> &p_spirv) { +Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Vector<ShaderStageSPIRVData> &p_spirv, const String &p_shader_name) { RenderingDeviceVulkanShaderBinaryData binary_data; binary_data.vertex_input_mask = 0; binary_data.fragment_outputs = 0; @@ -4835,9 +4847,19 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve binary_data.set_count = uniform_info.size(); binary_data.stage_count = p_spirv.size(); + CharString shader_name_utf = p_shader_name.utf8(); + + binary_data.shader_name_len = shader_name_utf.length(); + uint32_t total_size = sizeof(uint32_t) * 3; //header + version + main datasize; total_size += sizeof(RenderingDeviceVulkanShaderBinaryData); + total_size += binary_data.shader_name_len; + + if ((binary_data.shader_name_len % 4) != 0) { //alignment rules are really strange + total_size += 4 - (binary_data.shader_name_len % 4); + } + for (int i = 0; i < uniform_info.size(); i++) { total_size += sizeof(uint32_t); total_size += uniform_info[i].size() * sizeof(RenderingDeviceVulkanShaderBinaryDataBinding); @@ -4864,6 +4886,12 @@ Vector<uint8_t> RenderingDeviceVulkan::shader_compile_binary_from_spirv(const Ve offset += sizeof(uint32_t); memcpy(binptr + offset, &binary_data, sizeof(RenderingDeviceVulkanShaderBinaryData)); offset += sizeof(RenderingDeviceVulkanShaderBinaryData); + memcpy(binptr + offset, shader_name_utf.ptr(), binary_data.shader_name_len); + offset += binary_data.shader_name_len; + + if ((binary_data.shader_name_len % 4) != 0) { //alignment rules are really strange + offset += 4 - (binary_data.shader_name_len % 4); + } for (int i = 0; i < uniform_info.size(); i++) { int count = uniform_info[i].size(); @@ -4934,6 +4962,16 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_ read_offset += sizeof(uint32_t) * 3 + bin_data_size; + String name; + + if (binary_data.shader_name_len) { + name.parse_utf8((const char *)(binptr + read_offset), binary_data.shader_name_len); + read_offset += binary_data.shader_name_len; + if ((binary_data.shader_name_len % 4) != 0) { //alignment rules are really strange + read_offset += 4 - (binary_data.shader_name_len % 4); + } + } + Vector<Vector<VkDescriptorSetLayoutBinding>> set_bindings; Vector<Vector<UniformInfo>> uniform_info; @@ -5088,6 +5126,7 @@ RID RenderingDeviceVulkan::shader_create_from_bytecode(const Vector<uint8_t> &p_ shader.compute_local_size[1] = compute_local_size[1]; shader.compute_local_size[2] = compute_local_size[2]; shader.specialization_constants = specialization_constants; + shader.name = name; String error_text; @@ -6449,7 +6488,6 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma specialization_info.write[i].pData = data_ptr; specialization_info.write[i].mapEntryCount = specialization_map_entries[i].size(); specialization_info.write[i].pMapEntries = specialization_map_entries[i].ptr(); - pipeline_stages.write[i].pSpecializationInfo = specialization_info.ptr() + i; } } @@ -6476,7 +6514,7 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma RenderPipeline pipeline; VkResult err = vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &graphics_pipeline_create_info, nullptr, &pipeline.pipeline); - ERR_FAIL_COND_V_MSG(err, RID(), "vkCreateGraphicsPipelines failed with error " + itos(err) + "."); + ERR_FAIL_COND_V_MSG(err, RID(), "vkCreateGraphicsPipelines failed with error " + itos(err) + " for shader '" + shader->name + "'."); pipeline.set_formats = shader->set_formats; pipeline.push_constant_stages = shader->push_constant.push_constants_vk_stage; @@ -7550,7 +7588,7 @@ Error RenderingDeviceVulkan::_draw_list_allocate(const Rect2i &p_viewport, uint3 VkCommandPoolCreateInfo cmd_pool_info; cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; cmd_pool_info.pNext = nullptr; - cmd_pool_info.queueFamilyIndex = context->get_graphics_queue(); + cmd_pool_info.queueFamilyIndex = context->get_graphics_queue_family_index(); cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; VkResult res = vkCreateCommandPool(device, &cmd_pool_info, nullptr, &split_draw_list_allocators.write[i].command_pool); @@ -7927,13 +7965,13 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list, textures_to_storage[i]->used_in_compute = false; textures_to_storage[i]->used_in_raster = false; - textures_to_storage[i]->used_in_compute = false; + textures_to_storage[i]->used_in_transfer = false; } else { src_access_flags = 0; textures_to_storage[i]->used_in_compute = false; textures_to_storage[i]->used_in_raster = false; - textures_to_storage[i]->used_in_compute = false; + textures_to_storage[i]->used_in_transfer = false; textures_to_storage[i]->used_in_frame = frames_drawn; } @@ -8794,6 +8832,7 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de memset(&allocatorInfo, 0, sizeof(VmaAllocatorCreateInfo)); allocatorInfo.physicalDevice = p_context->get_physical_device(); allocatorInfo.device = device; + allocatorInfo.instance = p_context->get_instance(); vmaCreateAllocator(&allocatorInfo, &allocator); } @@ -8807,7 +8846,7 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de VkCommandPoolCreateInfo cmd_pool_info; cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; cmd_pool_info.pNext = nullptr; - cmd_pool_info.queueFamilyIndex = p_context->get_graphics_queue(); + cmd_pool_info.queueFamilyIndex = p_context->get_graphics_queue_family_index(); cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; VkResult res = vkCreateCommandPool(device, &cmd_pool_info, nullptr, &frames[i].command_pool); @@ -8977,6 +9016,92 @@ void RenderingDeviceVulkan::capture_timestamp(const String &p_name) { frames[frame].timestamp_count++; } +uint64_t RenderingDeviceVulkan::get_driver_resource(DriverResource p_resource, RID p_rid, uint64_t p_index) { + _THREAD_SAFE_METHOD_ + + switch (p_resource) { + case DRIVER_RESOURCE_VULKAN_DEVICE: { + return (uint64_t)context->get_device(); + }; break; + case DRIVER_RESOURCE_VULKAN_PHYSICAL_DEVICE: { + return (uint64_t)context->get_physical_device(); + }; break; + case DRIVER_RESOURCE_VULKAN_INSTANCE: { + return (uint64_t)context->get_instance(); + }; break; + case DRIVER_RESOURCE_VULKAN_QUEUE: { + return (uint64_t)context->get_graphics_queue(); + }; break; + case DRIVER_RESOURCE_VULKAN_QUEUE_FAMILY_INDEX: { + return context->get_graphics_queue_family_index(); + }; break; + case DRIVER_RESOURCE_VULKAN_IMAGE: { + Texture *tex = texture_owner.getornull(p_rid); + ERR_FAIL_NULL_V(tex, 0); + + return (uint64_t)tex->image; + }; break; + case DRIVER_RESOURCE_VULKAN_IMAGE_VIEW: { + Texture *tex = texture_owner.getornull(p_rid); + ERR_FAIL_NULL_V(tex, 0); + + return (uint64_t)tex->view; + }; break; + case DRIVER_RESOURCE_VULKAN_IMAGE_NATIVE_TEXTURE_FORMAT: { + Texture *tex = texture_owner.getornull(p_rid); + ERR_FAIL_NULL_V(tex, 0); + + return vulkan_formats[tex->format]; + }; break; + case DRIVER_RESOURCE_VULKAN_SAMPLER: { + VkSampler *sampler = sampler_owner.getornull(p_rid); + ERR_FAIL_NULL_V(sampler, 0); + + return uint64_t(*sampler); + }; break; + case DRIVER_RESOURCE_VULKAN_DESCRIPTOR_SET: { + UniformSet *uniform_set = uniform_set_owner.getornull(p_rid); + ERR_FAIL_NULL_V(uniform_set, 0); + + return uint64_t(uniform_set->descriptor_set); + }; break; + case DRIVER_RESOURCE_VULKAN_BUFFER: { + Buffer *buffer = nullptr; + if (vertex_buffer_owner.owns(p_rid)) { + buffer = vertex_buffer_owner.getornull(p_rid); + } else if (index_buffer_owner.owns(p_rid)) { + buffer = index_buffer_owner.getornull(p_rid); + } else if (uniform_buffer_owner.owns(p_rid)) { + buffer = uniform_buffer_owner.getornull(p_rid); + } else if (texture_buffer_owner.owns(p_rid)) { + buffer = &texture_buffer_owner.getornull(p_rid)->buffer; + } else if (storage_buffer_owner.owns(p_rid)) { + buffer = storage_buffer_owner.getornull(p_rid); + } + + ERR_FAIL_NULL_V(buffer, 0); + + return uint64_t(buffer->buffer); + }; break; + case DRIVER_RESOURCE_VULKAN_COMPUTE_PIPELINE: { + ComputePipeline *compute_pipeline = compute_pipeline_owner.getornull(p_rid); + ERR_FAIL_NULL_V(compute_pipeline, 0); + + return uint64_t(compute_pipeline->pipeline); + }; break; + case DRIVER_RESOURCE_VULKAN_RENDER_PIPELINE: { + RenderPipeline *render_pipeline = render_pipeline_owner.getornull(p_rid); + ERR_FAIL_NULL_V(render_pipeline, 0); + + return uint64_t(render_pipeline->pipeline); + }; break; + default: { + // not supported for this driver + return 0; + }; break; + } +} + uint32_t RenderingDeviceVulkan::get_captured_timestamps_count() const { return frames[frame].timestamp_result_count; } diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 6175369285..38ec79c45f 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -639,6 +639,7 @@ class RenderingDeviceVulkan : public RenderingDevice { Vector<VkPipelineShaderStageCreateInfo> pipeline_stages; Vector<SpecializationConstant> specialization_constants; VkPipelineLayout pipeline_layout = VK_NULL_HANDLE; + String name; //used for debug }; String _shader_uniform_debug(RID p_shader, int p_set = -1); @@ -1043,6 +1044,7 @@ public: virtual bool texture_is_format_supported_for_usage(DataFormat p_format, uint32_t p_usage) const; virtual bool texture_is_shared(RID p_texture); virtual bool texture_is_valid(RID p_texture); + virtual Size2i texture_size(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, uint32_t p_post_barrier = BARRIER_MASK_ALL); 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, uint32_t p_post_barrier = BARRIER_MASK_ALL); @@ -1088,7 +1090,7 @@ public: /****************/ virtual String shader_get_binary_cache_key() const; - virtual Vector<uint8_t> shader_compile_binary_from_spirv(const Vector<ShaderStageSPIRVData> &p_spirv); + virtual Vector<uint8_t> shader_compile_binary_from_spirv(const Vector<ShaderStageSPIRVData> &p_spirv, const String &p_shader_name = ""); virtual RID shader_create_from_bytecode(const Vector<uint8_t> &p_shader_binary); @@ -1225,6 +1227,8 @@ public: virtual String get_device_name() const; virtual String get_device_pipeline_cache_uuid() const; + virtual uint64_t get_driver_resource(DriverResource p_resource, RID p_rid = RID(), uint64_t p_index = 0); + RenderingDeviceVulkan(); ~RenderingDeviceVulkan(); }; diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index 87749450c4..c14e3f0e93 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -976,37 +976,35 @@ Error VulkanContext::_create_device() { sdevice.queueCreateInfoCount = 2; } -#ifdef VK_VERSION_1_2 VkPhysicalDeviceVulkan11Features vulkan11features; - - vulkan11features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES; - vulkan11features.pNext = nullptr; - // !BAS! Need to figure out which ones of these we want enabled... - vulkan11features.storageBuffer16BitAccess = 0; - vulkan11features.uniformAndStorageBuffer16BitAccess = 0; - vulkan11features.storagePushConstant16 = 0; - vulkan11features.storageInputOutput16 = 0; - vulkan11features.multiview = multiview_capabilities.is_supported; - vulkan11features.multiviewGeometryShader = multiview_capabilities.geometry_shader_is_supported; - vulkan11features.multiviewTessellationShader = multiview_capabilities.tessellation_shader_is_supported; - vulkan11features.variablePointersStorageBuffer = 0; - vulkan11features.variablePointers = 0; - vulkan11features.protectedMemory = 0; - vulkan11features.samplerYcbcrConversion = 0; - vulkan11features.shaderDrawParameters = 0; - - sdevice.pNext = &vulkan11features; -#elif VK_VERSION_1_1 VkPhysicalDeviceMultiviewFeatures multiview_features; + if (vulkan_major > 1 || vulkan_minor >= 2) { + vulkan11features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES; + vulkan11features.pNext = nullptr; + // !BAS! Need to figure out which ones of these we want enabled... + vulkan11features.storageBuffer16BitAccess = 0; + vulkan11features.uniformAndStorageBuffer16BitAccess = 0; + vulkan11features.storagePushConstant16 = 0; + vulkan11features.storageInputOutput16 = 0; + vulkan11features.multiview = multiview_capabilities.is_supported; + vulkan11features.multiviewGeometryShader = multiview_capabilities.geometry_shader_is_supported; + vulkan11features.multiviewTessellationShader = multiview_capabilities.tessellation_shader_is_supported; + vulkan11features.variablePointersStorageBuffer = 0; + vulkan11features.variablePointers = 0; + vulkan11features.protectedMemory = 0; + vulkan11features.samplerYcbcrConversion = 0; + vulkan11features.shaderDrawParameters = 0; + + sdevice.pNext = &vulkan11features; + } else if (vulkan_major == 1 && vulkan_minor == 1) { + multiview_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES; + multiview_features.pNext = nullptr; + multiview_features.multiview = multiview_capabilities.is_supported; + multiview_features.multiviewGeometryShader = multiview_capabilities.geometry_shader_is_supported; + multiview_features.multiviewTessellationShader = multiview_capabilities.tessellation_shader_is_supported; - multiview_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES; - multiview_features.pNext = nullptr; - multiview_features.multiview = multiview_capabilities.is_supported; - multiview_features.multiviewGeometryShader = multiview_capabilities.geometry_shader_is_supported; - multiview_features.multiviewTessellationShader = multiview_capabilities.tessellation_shader_is_supported; - - sdevice.pNext = &multiview_features; -#endif + sdevice.pNext = &multiview_features; + } err = vkCreateDevice(gpu, &sdevice, nullptr, &device); ERR_FAIL_COND_V(err, ERR_CANT_CREATE); @@ -2030,7 +2028,11 @@ int VulkanContext::get_swapchain_image_count() const { return swapchainImageCount; } -uint32_t VulkanContext::get_graphics_queue() const { +VkQueue VulkanContext::get_graphics_queue() const { + return graphics_queue; +} + +uint32_t VulkanContext::get_graphics_queue_family_index() const { return graphics_queue_family_index; } diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h index 1690b853e3..19ea806616 100644 --- a/drivers/vulkan/vulkan_context.h +++ b/drivers/vulkan/vulkan_context.h @@ -233,10 +233,6 @@ protected: Error _get_preferred_validation_layers(uint32_t *count, const char *const **names); - VkInstance _get_instance() { - return inst; - } - public: uint32_t get_vulkan_major() const { return vulkan_major; }; uint32_t get_vulkan_minor() const { return vulkan_minor; }; @@ -245,8 +241,10 @@ public: VkDevice get_device(); VkPhysicalDevice get_physical_device(); + VkInstance get_instance() { return inst; } int get_swapchain_image_count() const; - uint32_t get_graphics_queue() const; + VkQueue get_graphics_queue() const; + uint32_t get_graphics_queue_family_index() const; void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height); int window_get_width(DisplayServer::WindowID p_window = 0); |