diff options
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 1 | ||||
| -rw-r--r-- | src/video_core/engines/fermi_2d.h | 2 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_dma.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_base.cpp | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_base.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_buffer_cache.cpp | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_compute_pass.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp | 29 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_stream_buffer.cpp | 168 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_stream_buffer.h | 76 | ||||
| -rw-r--r-- | src/video_core/texture_cache/render_targets.h | 6 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_wrapper.cpp | 2 |
14 files changed, 41 insertions, 279 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 24c858104..3b43554f9 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -817,7 +817,6 @@ void BufferCache<P>::CommitAsyncFlushesHigh() { const std::size_t size = interval.upper() - interval.lower(); const VAddr cpu_addr = interval.lower(); ForEachBufferInRange(cpu_addr, size, [&](BufferId buffer_id, Buffer& buffer) { - boost::container::small_vector<BufferCopy, 1> copies; buffer.ForEachDownloadRangeAndClear( cpu_addr, size, [&](u64 range_offset, u64 range_size) { const VAddr buffer_addr = buffer.CpuAddr(); diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h index a4170ffff..d76c5ed56 100644 --- a/src/video_core/engines/fermi_2d.h +++ b/src/video_core/engines/fermi_2d.h @@ -299,7 +299,7 @@ public: }; private: - VideoCore::RasterizerInterface* rasterizer; + VideoCore::RasterizerInterface* rasterizer = nullptr; /// Performs the copy from the source surface to the destination surface as configured in the /// registers. diff --git a/src/video_core/engines/maxwell_dma.h b/src/video_core/engines/maxwell_dma.h index d3329b0f8..9e457ae16 100644 --- a/src/video_core/engines/maxwell_dma.h +++ b/src/video_core/engines/maxwell_dma.h @@ -227,7 +227,7 @@ private: Core::System& system; MemoryManager& memory_manager; - VideoCore::RasterizerInterface* rasterizer; + VideoCore::RasterizerInterface* rasterizer = nullptr; std::vector<u8> read_buffer; std::vector<u8> write_buffer; diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp index c9a360aaf..3ea72fda9 100644 --- a/src/video_core/renderer_base.cpp +++ b/src/video_core/renderer_base.cpp @@ -19,9 +19,6 @@ RendererBase::~RendererBase() = default; void RendererBase::RefreshBaseSettings() { UpdateCurrentFramebufferLayout(); - - renderer_settings.use_framelimiter = Settings::values.use_frame_limit.GetValue(); - renderer_settings.set_background_color = true; } void RendererBase::UpdateCurrentFramebufferLayout() { diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h index 63d8ad42a..22b80c328 100644 --- a/src/video_core/renderer_base.h +++ b/src/video_core/renderer_base.h @@ -21,9 +21,6 @@ class GraphicsContext; namespace VideoCore { struct RendererSettings { - std::atomic_bool use_framelimiter{false}; - std::atomic_bool set_background_color{false}; - // Screenshot std::atomic<bool> screenshot_requested{false}; void* screenshot_bits{}; diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 8d6cc074c..1f4dda17e 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -441,7 +441,6 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline( std::array<const Shader::Info*, Maxwell::MaxShaderStage> infos{}; - OGLProgram source_program; std::array<std::string, 5> sources; std::array<std::vector<u32>, 5> sources_spirv; Shader::Backend::Bindings binding; diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 285e78384..f1b00c24c 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -328,12 +328,10 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, } void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { - if (renderer_settings.set_background_color) { - // Update background color before drawing - glClearColor(Settings::values.bg_red.GetValue() / 255.0f, - Settings::values.bg_green.GetValue() / 255.0f, - Settings::values.bg_blue.GetValue() / 255.0f, 1.0f); - } + // Update background color before drawing + glClearColor(Settings::values.bg_red.GetValue() / 255.0f, + Settings::values.bg_green.GetValue() / 255.0f, + Settings::values.bg_blue.GetValue() / 255.0f, 1.0f); // Set projection matrix const std::array ortho_matrix = diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index f4b3ee95c..8ac58bc2f 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp @@ -358,7 +358,7 @@ void BufferCacheRuntime::ReserveNullBuffer() { if (null_buffer) { return; } - null_buffer = device.GetLogical().CreateBuffer(VkBufferCreateInfo{ + VkBufferCreateInfo create_info{ .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .pNext = nullptr, .flags = 0, @@ -367,9 +367,13 @@ void BufferCacheRuntime::ReserveNullBuffer() { .sharingMode = VK_SHARING_MODE_EXCLUSIVE, .queueFamilyIndexCount = 0, .pQueueFamilyIndices = nullptr, - }); + }; + if (device.IsExtTransformFeedbackSupported()) { + create_info.usage |= VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT; + } + null_buffer = device.GetLogical().CreateBuffer(create_info); if (device.HasDebuggingToolAttached()) { - null_buffer.SetObjectNameEXT("Null index buffer"); + null_buffer.SetObjectNameEXT("Null buffer"); } null_buffer_commit = memory_allocator.Commit(null_buffer, MemoryUsage::DeviceLocal); diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp index 8e426ce2c..561cf5e11 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp @@ -258,10 +258,9 @@ std::pair<VkBuffer, VkDeviceSize> Uint8Pass::Assemble(u32 num_vertices, VkBuffer update_descriptor_queue.AddBuffer(src_buffer, src_offset, num_vertices); update_descriptor_queue.AddBuffer(staging.buffer, staging.offset, staging_size); const void* const descriptor_data{update_descriptor_queue.UpdateData()}; - const VkBuffer buffer{staging.buffer}; scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([this, buffer, descriptor_data, num_vertices](vk::CommandBuffer cmdbuf) { + scheduler.Record([this, descriptor_data, num_vertices](vk::CommandBuffer cmdbuf) { static constexpr u32 DISPATCH_SIZE = 1024; static constexpr VkMemoryBarrier WRITE_BARRIER{ .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, @@ -319,14 +318,14 @@ std::pair<VkBuffer, VkDeviceSize> QuadIndexedPass::Assemble( const void* const descriptor_data{update_descriptor_queue.UpdateData()}; scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([this, buffer = staging.buffer, descriptor_data, num_tri_vertices, base_vertex, + scheduler.Record([this, descriptor_data, num_tri_vertices, base_vertex, index_shift](vk::CommandBuffer cmdbuf) { static constexpr u32 DISPATCH_SIZE = 1024; static constexpr VkMemoryBarrier WRITE_BARRIER{ .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, .pNext = nullptr, .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, - .dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, + .dstAccessMask = VK_ACCESS_INDEX_READ_BIT, }; const std::array push_constants{base_vertex, index_shift}; const VkDescriptorSet set = descriptor_allocator.Commit(); diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp index 555b12ed7..5d5329abf 100644 --- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp +++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp @@ -61,11 +61,15 @@ std::optional<u32> FindMemoryTypeIndex(const VkPhysicalDeviceMemoryProperties& p return std::nullopt; } -u32 FindMemoryTypeIndex(const VkPhysicalDeviceMemoryProperties& props, u32 type_mask) { - // Try to find a DEVICE_LOCAL_BIT type, Nvidia and AMD have a dedicated heap for this - std::optional<u32> type = FindMemoryTypeIndex(props, type_mask, STREAM_FLAGS); - if (type) { - return *type; +u32 FindMemoryTypeIndex(const VkPhysicalDeviceMemoryProperties& props, u32 type_mask, + bool try_device_local) { + std::optional<u32> type; + if (try_device_local) { + // Try to find a DEVICE_LOCAL_BIT type, Nvidia and AMD have a dedicated heap for this + type = FindMemoryTypeIndex(props, type_mask, STREAM_FLAGS); + if (type) { + return *type; + } } // Otherwise try without the DEVICE_LOCAL_BIT type = FindMemoryTypeIndex(props, type_mask, HOST_FLAGS); @@ -115,12 +119,21 @@ StagingBufferPool::StagingBufferPool(const Device& device_, MemoryAllocator& mem .buffer = *stream_buffer, }; const auto memory_properties = device.GetPhysical().GetMemoryProperties(); - stream_memory = dev.AllocateMemory(VkMemoryAllocateInfo{ + VkMemoryAllocateInfo stream_memory_info{ .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, .pNext = make_dedicated ? &dedicated_info : nullptr, .allocationSize = requirements.size, - .memoryTypeIndex = FindMemoryTypeIndex(memory_properties, requirements.memoryTypeBits), - }); + .memoryTypeIndex = + FindMemoryTypeIndex(memory_properties, requirements.memoryTypeBits, true), + }; + stream_memory = dev.TryAllocateMemory(stream_memory_info); + if (!stream_memory) { + LOG_INFO(Render_Vulkan, "Dynamic memory allocation failed, trying with system memory"); + stream_memory_info.memoryTypeIndex = + FindMemoryTypeIndex(memory_properties, requirements.memoryTypeBits, false); + stream_memory = dev.AllocateMemory(stream_memory_info); + } + if (device.HasDebuggingToolAttached()) { stream_memory.SetObjectNameEXT("Stream Buffer Memory"); } diff --git a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp deleted file mode 100644 index 7b4875d0e..000000000 --- a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright 2019 yuzu Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include <algorithm> -#include <limits> -#include <optional> -#include <tuple> -#include <vector> - -#include "common/alignment.h" -#include "common/assert.h" -#include "common/literals.h" -#include "video_core/renderer_vulkan/vk_scheduler.h" -#include "video_core/renderer_vulkan/vk_stream_buffer.h" -#include "video_core/vulkan_common/vulkan_device.h" -#include "video_core/vulkan_common/vulkan_wrapper.h" - -namespace Vulkan { - -namespace { - -using namespace Common::Literals; - -constexpr VkBufferUsageFlags BUFFER_USAGE = - VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT | - VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; - -constexpr u64 WATCHES_INITIAL_RESERVE = 0x4000; -constexpr u64 WATCHES_RESERVE_CHUNK = 0x1000; - -constexpr u64 PREFERRED_STREAM_BUFFER_SIZE = 256_MiB; - -/// Find a memory type with the passed requirements -std::optional<u32> FindMemoryType(const VkPhysicalDeviceMemoryProperties& properties, - VkMemoryPropertyFlags wanted, - u32 filter = std::numeric_limits<u32>::max()) { - for (u32 i = 0; i < properties.memoryTypeCount; ++i) { - const auto flags = properties.memoryTypes[i].propertyFlags; - if ((flags & wanted) == wanted && (filter & (1U << i)) != 0) { - return i; - } - } - return std::nullopt; -} - -/// Get the preferred host visible memory type. -u32 GetMemoryType(const VkPhysicalDeviceMemoryProperties& properties, - u32 filter = std::numeric_limits<u32>::max()) { - // Prefer device local host visible allocations. Both AMD and Nvidia now provide one. - // Otherwise search for a host visible allocation. - static constexpr auto HOST_MEMORY = - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; - static constexpr auto DYNAMIC_MEMORY = HOST_MEMORY | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - - std::optional preferred_type = FindMemoryType(properties, DYNAMIC_MEMORY); - if (!preferred_type) { - preferred_type = FindMemoryType(properties, HOST_MEMORY); - ASSERT_MSG(preferred_type, "No host visible and coherent memory type found"); - } - return preferred_type.value_or(0); -} - -} // Anonymous namespace - -VKStreamBuffer::VKStreamBuffer(const Device& device_, VKScheduler& scheduler_) - : device{device_}, scheduler{scheduler_} { - CreateBuffers(); - ReserveWatches(current_watches, WATCHES_INITIAL_RESERVE); - ReserveWatches(previous_watches, WATCHES_INITIAL_RESERVE); -} - -VKStreamBuffer::~VKStreamBuffer() = default; - -std::pair<u8*, u64> VKStreamBuffer::Map(u64 size, u64 alignment) { - ASSERT(size <= stream_buffer_size); - mapped_size = size; - - if (alignment > 0) { - offset = Common::AlignUp(offset, alignment); - } - - WaitPendingOperations(offset); - - if (offset + size > stream_buffer_size) { - // The buffer would overflow, save the amount of used watches and reset the state. - invalidation_mark = current_watch_cursor; - current_watch_cursor = 0; - offset = 0; - - // Swap watches and reset waiting cursors. - std::swap(previous_watches, current_watches); - wait_cursor = 0; - wait_bound = 0; - - // Ensure that we don't wait for uncommitted fences. - scheduler.Flush(); - } - - return std::make_pair(memory.Map(offset, size), offset); -} - -void VKStreamBuffer::Unmap(u64 size) { - ASSERT_MSG(size <= mapped_size, "Reserved size is too small"); - - memory.Unmap(); - - offset += size; - - if (current_watch_cursor + 1 >= current_watches.size()) { - // Ensure that there are enough watches. - ReserveWatches(current_watches, WATCHES_RESERVE_CHUNK); - } - auto& watch = current_watches[current_watch_cursor++]; - watch.upper_bound = offset; - watch.tick = scheduler.CurrentTick(); -} - -void VKStreamBuffer::CreateBuffers() { - const auto memory_properties = device.GetPhysical().GetMemoryProperties(); - const u32 preferred_type = GetMemoryType(memory_properties); - const u32 preferred_heap = memory_properties.memoryTypes[preferred_type].heapIndex; - - // Substract from the preferred heap size some bytes to avoid getting out of memory. - const VkDeviceSize heap_size = memory_properties.memoryHeaps[preferred_heap].size; - // As per DXVK's example, using `heap_size / 2` - const VkDeviceSize allocable_size = heap_size / 2; - buffer = device.GetLogical().CreateBuffer({ - .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .size = std::min(PREFERRED_STREAM_BUFFER_SIZE, allocable_size), - .usage = BUFFER_USAGE, - .sharingMode = VK_SHARING_MODE_EXCLUSIVE, - .queueFamilyIndexCount = 0, - .pQueueFamilyIndices = nullptr, - }); - - const auto requirements = device.GetLogical().GetBufferMemoryRequirements(*buffer); - const u32 required_flags = requirements.memoryTypeBits; - stream_buffer_size = static_cast<u64>(requirements.size); - - memory = device.GetLogical().AllocateMemory({ - .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, - .pNext = nullptr, - .allocationSize = requirements.size, - .memoryTypeIndex = GetMemoryType(memory_properties, required_flags), - }); - buffer.BindMemory(*memory, 0); -} - -void VKStreamBuffer::ReserveWatches(std::vector<Watch>& watches, std::size_t grow_size) { - watches.resize(watches.size() + grow_size); -} - -void VKStreamBuffer::WaitPendingOperations(u64 requested_upper_bound) { - if (!invalidation_mark) { - return; - } - while (requested_upper_bound < wait_bound && wait_cursor < *invalidation_mark) { - auto& watch = previous_watches[wait_cursor]; - wait_bound = watch.upper_bound; - scheduler.Wait(watch.tick); - ++wait_cursor; - } -} - -} // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_stream_buffer.h b/src/video_core/renderer_vulkan/vk_stream_buffer.h deleted file mode 100644 index 2e9c8cb46..000000000 --- a/src/video_core/renderer_vulkan/vk_stream_buffer.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2019 yuzu Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include <optional> -#include <utility> -#include <vector> - -#include "common/common_types.h" -#include "video_core/vulkan_common/vulkan_wrapper.h" - -namespace Vulkan { - -class Device; -class VKFenceWatch; -class VKScheduler; - -class VKStreamBuffer final { -public: - explicit VKStreamBuffer(const Device& device, VKScheduler& scheduler); - ~VKStreamBuffer(); - - /** - * Reserves a region of memory from the stream buffer. - * @param size Size to reserve. - * @returns A pair of a raw memory pointer (with offset added), and the buffer offset - */ - std::pair<u8*, u64> Map(u64 size, u64 alignment); - - /// Ensures that "size" bytes of memory are available to the GPU, potentially recording a copy. - void Unmap(u64 size); - - VkBuffer Handle() const noexcept { - return *buffer; - } - - u64 Address() const noexcept { - return 0; - } - -private: - struct Watch { - u64 tick{}; - u64 upper_bound{}; - }; - - /// Creates Vulkan buffer handles committing the required the required memory. - void CreateBuffers(); - - /// Increases the amount of watches available. - void ReserveWatches(std::vector<Watch>& watches, std::size_t grow_size); - - void WaitPendingOperations(u64 requested_upper_bound); - - const Device& device; ///< Vulkan device manager. - VKScheduler& scheduler; ///< Command scheduler. - - vk::Buffer buffer; ///< Mapped buffer. - vk::DeviceMemory memory; ///< Memory allocation. - u64 stream_buffer_size{}; ///< Stream buffer size. - - u64 offset{}; ///< Buffer iterator. - u64 mapped_size{}; ///< Size reserved for the current copy. - - std::vector<Watch> current_watches; ///< Watches recorded in the current iteration. - std::size_t current_watch_cursor{}; ///< Count of watches, reset on invalidation. - std::optional<std::size_t> invalidation_mark; ///< Number of watches used in the previous cycle. - - std::vector<Watch> previous_watches; ///< Watches used in the previous iteration. - std::size_t wait_cursor{}; ///< Last watch being waited for completion. - u64 wait_bound{}; ///< Highest offset being watched for completion. -}; - -} // namespace Vulkan diff --git a/src/video_core/texture_cache/render_targets.h b/src/video_core/texture_cache/render_targets.h index 9b9544b07..0cb227d69 100644 --- a/src/video_core/texture_cache/render_targets.h +++ b/src/video_core/texture_cache/render_targets.h @@ -24,10 +24,10 @@ struct RenderTargets { return std::ranges::any_of(color_buffer_ids, contains) || contains(depth_buffer_id); } - std::array<ImageViewId, NUM_RT> color_buffer_ids; - ImageViewId depth_buffer_id; + std::array<ImageViewId, NUM_RT> color_buffer_ids{}; + ImageViewId depth_buffer_id{}; std::array<u8, NUM_RT> draw_buffers{}; - Extent2D size; + Extent2D size{}; }; } // namespace VideoCommon diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp index bbf0fccae..70898004a 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.cpp +++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp @@ -202,7 +202,7 @@ void SetObjectName(const DeviceDispatch* dld, VkDevice device, T handle, VkObjec const VkDebugUtilsObjectNameInfoEXT name_info{ .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, .pNext = nullptr, - .objectType = VK_OBJECT_TYPE_IMAGE, + .objectType = type, .objectHandle = reinterpret_cast<u64>(handle), .pObjectName = name, }; |
