diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index cd6ea28fc..8927083cd 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -62,6 +62,11 @@ public: return &gds_buffer; } + /// Retrieves the buffer with the specified id. + [[nodiscard]] Buffer& GetBuffer(BufferId id) { + return slot_buffers[id]; + } + /// Invalidates any buffer in the logical page range. void InvalidateMemory(VAddr device_addr, u64 size); diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index 96358bf67..d9296b501 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp @@ -221,8 +221,12 @@ bool ComputePipeline::BindResources(VideoCore::BufferCache& buffer_cache, const auto& image_view = texture_cache.FindTexture(image_info, view_info); const auto& image = texture_cache.GetImage(image_view.image_id); image_infos.emplace_back(VK_NULL_HANDLE, *image_view.image_view, image.layout); - } else { + } else if (instance.IsNullDescriptorSupported()) { image_infos.emplace_back(VK_NULL_HANDLE, VK_NULL_HANDLE, vk::ImageLayout::eGeneral); + } else { + auto& null_image = texture_cache.GetImageView(VideoCore::NULL_IMAGE_VIEW_ID); + image_infos.emplace_back(VK_NULL_HANDLE, *null_image.image_view, + vk::ImageLayout::eGeneral); } set_writes.push_back({ .dstSet = VK_NULL_HANDLE, diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index f7474b24e..dc311a7c6 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -386,8 +386,11 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs, push_data.AddOffset(binding, adjust); } buffer_infos.emplace_back(vk_buffer->Handle(), offset_aligned, size + adjust); - } else { + } else if (instance.IsNullDescriptorSupported()) { buffer_infos.emplace_back(VK_NULL_HANDLE, 0, VK_WHOLE_SIZE); + } else { + auto& null_buffer = buffer_cache.GetBuffer(VideoCore::NULL_BUFFER_ID); + buffer_infos.emplace_back(null_buffer.Handle(), 0, VK_WHOLE_SIZE); } set_writes.push_back({ .dstSet = VK_NULL_HANDLE, @@ -451,8 +454,12 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs, const auto& image_view = texture_cache.FindTexture(image_info, view_info); const auto& image = texture_cache.GetImage(image_view.image_id); image_infos.emplace_back(VK_NULL_HANDLE, *image_view.image_view, image.layout); - } else { + } else if (instance.IsNullDescriptorSupported()) { image_infos.emplace_back(VK_NULL_HANDLE, VK_NULL_HANDLE, vk::ImageLayout::eGeneral); + } else { + auto& null_image = texture_cache.GetImageView(VideoCore::NULL_IMAGE_VIEW_ID); + image_infos.emplace_back(VK_NULL_HANDLE, *null_image.image_view, + vk::ImageLayout::eGeneral); } set_writes.push_back({ .dstSet = VK_NULL_HANDLE, diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index d88d43291..5bd2fed44 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -376,9 +376,12 @@ bool Instance::CreateDevice() { device_chain.unlink(); } if (robustness) { - device_chain.get().nullDescriptor = + null_descriptor = feature_chain.get().nullDescriptor; + device_chain.get().nullDescriptor = + null_descriptor; } else { + null_descriptor = false; device_chain.unlink(); } if (!vertex_input_dynamic_state) { diff --git a/src/video_core/renderer_vulkan/vk_instance.h b/src/video_core/renderer_vulkan/vk_instance.h index 61687ac28..8b12494ab 100644 --- a/src/video_core/renderer_vulkan/vk_instance.h +++ b/src/video_core/renderer_vulkan/vk_instance.h @@ -132,6 +132,11 @@ public: return vertex_input_dynamic_state; } + /// Returns true when the nullDescriptor feature of VK_EXT_robustness2 is supported. + bool IsNullDescriptorSupported() const { + return null_descriptor; + } + /// Returns the vendor ID of the physical device u32 GetVendorID() const { return properties.vendorID; @@ -279,6 +284,7 @@ private: bool workgroup_memory_explicit_layout{}; bool color_write_en{}; bool vertex_input_dynamic_state{}; + bool null_descriptor{}; u64 min_imported_host_pointer_alignment{}; u32 subgroup_size{}; bool tooling_info{}; diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index cc19ac4a8..329128a3c 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -98,6 +98,11 @@ public: return slot_images[id]; } + /// Retrieves the image view with the specified id. + [[nodiscard]] ImageView& GetImageView(ImageId id) { + return slot_image_views[id]; + } + bool IsMeta(VAddr address) const { return surface_metas.contains(address); }