From 76f102e8659059ad7a85dbd9648e5b030c77c9f0 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Fri, 24 Aug 2018 10:52:31 +0300 Subject: [PATCH] vk: Check for allowed texbuffer range instead of assuming 64M --- rpcs3/Emu/RSX/VK/VKGSRender.cpp | 9 +++++++++ rpcs3/Emu/RSX/VK/VKGSRender.h | 2 ++ rpcs3/Emu/RSX/VK/VKHelpers.h | 7 +++++++ rpcs3/Emu/RSX/VK/VKVertexBuffers.cpp | 8 ++++++-- 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 82cf605186..de9f466110 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -594,6 +594,15 @@ VKGSRender::VKGSRender() : GSRender() m_index_buffer_ring_info.create(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_INDEX_RING_BUFFER_SIZE_M * 0x100000, "index buffer"); m_texture_upload_buffer_ring_info.create(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_TEXTURE_UPLOAD_RING_BUFFER_SIZE_M * 0x100000, "texture upload buffer", 32 * 0x100000); + const auto limits = m_device->gpu().get_limits(); + m_texbuffer_view_size = std::min(limits.maxTexelBufferElements, 0x4000000u); + + if (m_texbuffer_view_size < 0x800000) + { + // Warn, only possibly expected on macOS + LOG_WARNING(RSX, "Current driver may crash due to memory limitations (%uk)", m_texbuffer_view_size / 1024); + } + for (auto &ctx : frame_context_storage) { vkCreateSemaphore((*m_device), &semaphore_info, nullptr, &ctx.present_semaphore); diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.h b/rpcs3/Emu/RSX/VK/VKGSRender.h index 0fcb41d0e1..82b75f74e5 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.h +++ b/rpcs3/Emu/RSX/VK/VKGSRender.h @@ -327,6 +327,8 @@ private: bool renderer_unavailable = false; u64 m_last_heap_sync_time = 0; + u32 m_texbuffer_view_size = 0; + vk::vk_data_heap m_attrib_ring_info; vk::vk_data_heap m_uniform_buffer_ring_info; vk::vk_data_heap m_transform_constants_ring_info; diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index e9f8fdfc35..d01aa621de 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -398,6 +398,8 @@ namespace vk dev = pdev; vkGetPhysicalDeviceProperties(pdev, &props); vkGetPhysicalDeviceMemoryProperties(pdev, &memory_properties); + + LOG_NOTICE(RSX, "Physical device intialized. GPU=%s, driver=%u", props.deviceName, props.driverVersion); } std::string name() const @@ -436,6 +438,11 @@ namespace vk return memory_properties; } + VkPhysicalDeviceLimits get_limits() const + { + return props.limits; + } + operator VkPhysicalDevice() const { return dev; diff --git a/rpcs3/Emu/RSX/VK/VKVertexBuffers.cpp b/rpcs3/Emu/RSX/VK/VKVertexBuffers.cpp index 9aafef0e29..f316a830a4 100644 --- a/rpcs3/Emu/RSX/VK/VKVertexBuffers.cpp +++ b/rpcs3/Emu/RSX/VK/VKVertexBuffers.cpp @@ -322,11 +322,13 @@ vk::vertex_upload_info VKGSRender::upload_vertex_data() { if (!m_persistent_attribute_storage || !m_persistent_attribute_storage->in_range(persistent_range_base, required.first, persistent_range_base)) { + verify("Incompatible driver (MacOS?)" HERE), m_texbuffer_view_size >= required.first; + if (m_persistent_attribute_storage) m_current_frame->buffer_views_to_clean.push_back(std::move(m_persistent_attribute_storage)); //View 64M blocks at a time (different drivers will only allow a fixed viewable heap size, 64M should be safe) - const size_t view_size = (persistent_range_base + 0x4000000) > m_attrib_ring_info.size() ? m_attrib_ring_info.size() - persistent_range_base : 0x4000000; + const size_t view_size = (persistent_range_base + m_texbuffer_view_size) > m_attrib_ring_info.size() ? m_attrib_ring_info.size() - persistent_range_base : m_texbuffer_view_size; m_persistent_attribute_storage = std::make_unique(*m_device, m_attrib_ring_info.heap->value, VK_FORMAT_R8_UINT, persistent_range_base, view_size); persistent_range_base = 0; } @@ -336,10 +338,12 @@ vk::vertex_upload_info VKGSRender::upload_vertex_data() { if (!m_volatile_attribute_storage || !m_volatile_attribute_storage->in_range(volatile_range_base, required.second, volatile_range_base)) { + verify("Incompatible driver (MacOS?)" HERE), m_texbuffer_view_size >= required.second; + if (m_volatile_attribute_storage) m_current_frame->buffer_views_to_clean.push_back(std::move(m_volatile_attribute_storage)); - const size_t view_size = (volatile_range_base + 0x4000000) > m_attrib_ring_info.size() ? m_attrib_ring_info.size() - volatile_range_base : 0x4000000; + const size_t view_size = (volatile_range_base + m_texbuffer_view_size) > m_attrib_ring_info.size() ? m_attrib_ring_info.size() - volatile_range_base : m_texbuffer_view_size; m_volatile_attribute_storage = std::make_unique(*m_device, m_attrib_ring_info.heap->value, VK_FORMAT_R8_UINT, volatile_range_base, view_size); volatile_range_base = 0; }