summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-02-26 02:09:43 -0300
committerGravatar ReinUsesLisp2019-02-26 02:09:43 -0300
commit730eb1dad74756256a3f839215f6dc4f97181928 (patch)
tree497ed0a321578fe19ec60efba4df4c13b6cf0205 /src
parentvk_stream_buffer: Implement a stream buffer (diff)
downloadyuzu-730eb1dad74756256a3f839215f6dc4f97181928.tar.gz
yuzu-730eb1dad74756256a3f839215f6dc4f97181928.tar.xz
yuzu-730eb1dad74756256a3f839215f6dc4f97181928.zip
vk_stream_buffer: Remove copy code path
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_vulkan/vk_stream_buffer.cpp52
-rw-r--r--src/video_core/renderer_vulkan/vk_stream_buffer.h19
2 files changed, 18 insertions, 53 deletions
diff --git a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp
index 1c5aefaec..58ffa42f2 100644
--- a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp
+++ b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp
@@ -23,16 +23,15 @@ constexpr u64 WATCHES_RESERVE_CHUNK = 0x1000;
23VKStreamBuffer::VKStreamBuffer(const VKDevice& device, VKMemoryManager& memory_manager, 23VKStreamBuffer::VKStreamBuffer(const VKDevice& device, VKMemoryManager& memory_manager,
24 VKScheduler& scheduler, u64 size, vk::BufferUsageFlags usage, 24 VKScheduler& scheduler, u64 size, vk::BufferUsageFlags usage,
25 vk::AccessFlags access, vk::PipelineStageFlags pipeline_stage) 25 vk::AccessFlags access, vk::PipelineStageFlags pipeline_stage)
26 : device{device}, scheduler{scheduler}, 26 : device{device}, scheduler{scheduler}, buffer_size{size}, access{access}, pipeline_stage{
27 has_device_exclusive_memory{!memory_manager.IsMemoryUnified()}, 27 pipeline_stage} {
28 buffer_size{size}, access{access}, pipeline_stage{pipeline_stage} {
29 CreateBuffers(memory_manager, usage); 28 CreateBuffers(memory_manager, usage);
30 ReserveWatches(WATCHES_INITIAL_RESERVE); 29 ReserveWatches(WATCHES_INITIAL_RESERVE);
31} 30}
32 31
33VKStreamBuffer::~VKStreamBuffer() = default; 32VKStreamBuffer::~VKStreamBuffer() = default;
34 33
35std::tuple<u8*, u64, vk::Buffer, bool> VKStreamBuffer::Reserve(u64 size, bool keep_in_host) { 34std::tuple<u8*, u64, bool> VKStreamBuffer::Reserve(u64 size) {
36 ASSERT(size <= buffer_size); 35 ASSERT(size <= buffer_size);
37 mapped_size = size; 36 mapped_size = size;
38 37
@@ -44,10 +43,7 @@ std::tuple<u8*, u64, vk::Buffer, bool> VKStreamBuffer::Reserve(u64 size, bool ke
44 offset = 0; 43 offset = 0;
45 } 44 }
46 45
47 use_device = has_device_exclusive_memory && !keep_in_host; 46 return {mapped_pointer + offset, offset, invalidation_mark.has_value()};
48
49 const vk::Buffer buffer = use_device ? *device_buffer : *mappable_buffer;
50 return {mapped_pointer + offset, offset, buffer, invalidation_mark.has_value()};
51} 47}
52 48
53VKExecutionContext VKStreamBuffer::Send(VKExecutionContext exctx, u64 size) { 49VKExecutionContext VKStreamBuffer::Send(VKExecutionContext exctx, u64 size) {
@@ -61,24 +57,6 @@ VKExecutionContext VKStreamBuffer::Send(VKExecutionContext exctx, u64 size) {
61 invalidation_mark = std::nullopt; 57 invalidation_mark = std::nullopt;
62 } 58 }
63 59
64 // Only copy to VRAM when requested.
65 if (use_device) {
66 const auto& dld = device.GetDispatchLoader();
67 const u32 graphics_family = device.GetGraphicsFamily();
68 const auto cmdbuf = exctx.GetCommandBuffer();
69
70 // Buffers are mirrored, that's why the copy is done with the same offset on both buffers.
71 const vk::BufferCopy copy_region(offset, offset, size);
72 cmdbuf.copyBuffer(*mappable_buffer, *device_buffer, {copy_region}, dld);
73
74 // Protect the buffer from GPU usage until the copy has finished.
75 const vk::BufferMemoryBarrier barrier(vk::AccessFlagBits::eTransferWrite, access,
76 graphics_family, graphics_family, *device_buffer,
77 offset, size);
78 cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, pipeline_stage, {}, {},
79 {barrier}, {}, dld);
80 }
81
82 if (used_watches + 1 >= watches.size()) { 60 if (used_watches + 1 >= watches.size()) {
83 // Ensure that there are enough watches. 61 // Ensure that there are enough watches.
84 ReserveWatches(WATCHES_RESERVE_CHUNK); 62 ReserveWatches(WATCHES_RESERVE_CHUNK);
@@ -92,26 +70,14 @@ VKExecutionContext VKStreamBuffer::Send(VKExecutionContext exctx, u64 size) {
92} 70}
93 71
94void VKStreamBuffer::CreateBuffers(VKMemoryManager& memory_manager, vk::BufferUsageFlags usage) { 72void VKStreamBuffer::CreateBuffers(VKMemoryManager& memory_manager, vk::BufferUsageFlags usage) {
95 vk::BufferUsageFlags mappable_usage = usage; 73 const vk::BufferCreateInfo buffer_ci({}, buffer_size, usage, vk::SharingMode::eExclusive, 0,
96 if (has_device_exclusive_memory) { 74 nullptr);
97 mappable_usage |= vk::BufferUsageFlagBits::eTransferSrc;
98 }
99 const vk::BufferCreateInfo buffer_ci({}, buffer_size, mappable_usage,
100 vk::SharingMode::eExclusive, 0, nullptr);
101 75
102 const auto dev = device.GetLogical(); 76 const auto dev = device.GetLogical();
103 const auto& dld = device.GetDispatchLoader(); 77 const auto& dld = device.GetDispatchLoader();
104 mappable_buffer = dev.createBufferUnique(buffer_ci, nullptr, dld); 78 buffer = dev.createBufferUnique(buffer_ci, nullptr, dld);
105 mappable_commit = memory_manager.Commit(*mappable_buffer, true); 79 commit = memory_manager.Commit(*buffer, true);
106 mapped_pointer = mappable_commit->GetData(); 80 mapped_pointer = commit->GetData();
107
108 if (has_device_exclusive_memory) {
109 const vk::BufferCreateInfo buffer_ci({}, buffer_size,
110 usage | vk::BufferUsageFlagBits::eTransferDst,
111 vk::SharingMode::eExclusive, 0, nullptr);
112 device_buffer = dev.createBufferUnique(buffer_ci, nullptr, dld);
113 device_commit = memory_manager.Commit(*device_buffer, false);
114 }
115} 81}
116 82
117void VKStreamBuffer::ReserveWatches(std::size_t grow_size) { 83void VKStreamBuffer::ReserveWatches(std::size_t grow_size) {
diff --git a/src/video_core/renderer_vulkan/vk_stream_buffer.h b/src/video_core/renderer_vulkan/vk_stream_buffer.h
index 8c00d383a..69d036ccd 100644
--- a/src/video_core/renderer_vulkan/vk_stream_buffer.h
+++ b/src/video_core/renderer_vulkan/vk_stream_buffer.h
@@ -31,15 +31,18 @@ public:
31 /** 31 /**
32 * Reserves a region of memory from the stream buffer. 32 * Reserves a region of memory from the stream buffer.
33 * @param size Size to reserve. 33 * @param size Size to reserve.
34 * @param keep_in_host Mapped buffer will be in host memory, skipping the copy to device local.
35 * @returns A tuple in the following order: Raw memory pointer (with offset added), buffer 34 * @returns A tuple in the following order: Raw memory pointer (with offset added), buffer
36 * offset, Vulkan buffer handle, buffer has been invalited. 35 * offset and a boolean that's true when buffer has been invalidated.
37 */ 36 */
38 std::tuple<u8*, u64, vk::Buffer, bool> Reserve(u64 size, bool keep_in_host); 37 std::tuple<u8*, u64, bool> Reserve(u64 size);
39 38
40 /// Ensures that "size" bytes of memory are available to the GPU, potentially recording a copy. 39 /// Ensures that "size" bytes of memory are available to the GPU, potentially recording a copy.
41 [[nodiscard]] VKExecutionContext Send(VKExecutionContext exctx, u64 size); 40 [[nodiscard]] VKExecutionContext Send(VKExecutionContext exctx, u64 size);
42 41
42 vk::Buffer GetBuffer() const {
43 return *buffer;
44 }
45
43private: 46private:
44 /// Creates Vulkan buffer handles committing the required the required memory. 47 /// Creates Vulkan buffer handles committing the required the required memory.
45 void CreateBuffers(VKMemoryManager& memory_manager, vk::BufferUsageFlags usage); 48 void CreateBuffers(VKMemoryManager& memory_manager, vk::BufferUsageFlags usage);
@@ -50,19 +53,15 @@ private:
50 const VKDevice& device; ///< Vulkan device manager. 53 const VKDevice& device; ///< Vulkan device manager.
51 VKScheduler& scheduler; ///< Command scheduler. 54 VKScheduler& scheduler; ///< Command scheduler.
52 const u64 buffer_size; ///< Total size of the stream buffer. 55 const u64 buffer_size; ///< Total size of the stream buffer.
53 const bool has_device_exclusive_memory; ///< True if the streaming buffer will use VRAM.
54 const vk::AccessFlags access; ///< Access usage of this stream buffer. 56 const vk::AccessFlags access; ///< Access usage of this stream buffer.
55 const vk::PipelineStageFlags pipeline_stage; ///< Pipeline usage of this stream buffer. 57 const vk::PipelineStageFlags pipeline_stage; ///< Pipeline usage of this stream buffer.
56 58
57 UniqueBuffer mappable_buffer; ///< Mapped buffer. 59 UniqueBuffer buffer; ///< Mapped buffer.
58 UniqueBuffer device_buffer; ///< Buffer exclusive to the GPU. 60 VKMemoryCommit commit; ///< Memory commit.
59 VKMemoryCommit mappable_commit; ///< Commit visible from the CPU. 61 u8* mapped_pointer{}; ///< Pointer to the host visible commit
60 VKMemoryCommit device_commit; ///< Commit stored in VRAM.
61 u8* mapped_pointer{}; ///< Pointer to the host visible commit
62 62
63 u64 offset{}; ///< Buffer iterator. 63 u64 offset{}; ///< Buffer iterator.
64 u64 mapped_size{}; ///< Size reserved for the current copy. 64 u64 mapped_size{}; ///< Size reserved for the current copy.
65 bool use_device{}; ///< True if the current uses VRAM.
66 65
67 std::vector<std::unique_ptr<VKFenceWatch>> watches; ///< Total watches 66 std::vector<std::unique_ptr<VKFenceWatch>> watches; ///< Total watches
68 std::size_t used_watches{}; ///< Count of watches, reset on invalidation. 67 std::size_t used_watches{}; ///< Count of watches, reset on invalidation.