summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-01-05 17:26:04 -0300
committerGravatar ReinUsesLisp2020-01-06 18:28:32 -0300
commit322d6a0311624b8304894baa102ab462ea6cf0ea (patch)
treee732f9f46a8f15b531a183b787ea20bd1303a26a /src
parentMerge pull request #3257 from degasus/no_busy_loops (diff)
downloadyuzu-322d6a0311624b8304894baa102ab462ea6cf0ea.tar.gz
yuzu-322d6a0311624b8304894baa102ab462ea6cf0ea.tar.xz
yuzu-322d6a0311624b8304894baa102ab462ea6cf0ea.zip
vk_update_descriptor: Initial implementation
The update descriptor is used to store in flat memory a large chunk of staging data used to update descriptor sets through templates. It provides a push interface to easily insert descriptors following the current pipeline. The order used in the descriptor update template has to be implicitly followed. We can catch bugs here using validation layers.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/CMakeLists.txt4
-rw-r--r--src/video_core/renderer_vulkan/vk_update_descriptor.cpp57
-rw-r--r--src/video_core/renderer_vulkan/vk_update_descriptor.h86
3 files changed, 146 insertions, 1 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index abbf218f5..47290cbcb 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -176,7 +176,9 @@ if (ENABLE_VULKAN)
176 renderer_vulkan/vk_stream_buffer.cpp 176 renderer_vulkan/vk_stream_buffer.cpp
177 renderer_vulkan/vk_stream_buffer.h 177 renderer_vulkan/vk_stream_buffer.h
178 renderer_vulkan/vk_swapchain.cpp 178 renderer_vulkan/vk_swapchain.cpp
179 renderer_vulkan/vk_swapchain.h) 179 renderer_vulkan/vk_swapchain.h
180 renderer_vulkan/vk_update_descriptor.cpp
181 renderer_vulkan/vk_update_descriptor.h)
180 182
181 target_include_directories(video_core PRIVATE sirit ../../externals/Vulkan-Headers/include) 183 target_include_directories(video_core PRIVATE sirit ../../externals/Vulkan-Headers/include)
182 target_compile_definitions(video_core PRIVATE HAS_VULKAN) 184 target_compile_definitions(video_core PRIVATE HAS_VULKAN)
diff --git a/src/video_core/renderer_vulkan/vk_update_descriptor.cpp b/src/video_core/renderer_vulkan/vk_update_descriptor.cpp
new file mode 100644
index 000000000..0e577b9ff
--- /dev/null
+++ b/src/video_core/renderer_vulkan/vk_update_descriptor.cpp
@@ -0,0 +1,57 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <variant>
6#include <boost/container/static_vector.hpp>
7
8#include "common/assert.h"
9#include "common/logging/log.h"
10#include "video_core/renderer_vulkan/declarations.h"
11#include "video_core/renderer_vulkan/vk_device.h"
12#include "video_core/renderer_vulkan/vk_scheduler.h"
13#include "video_core/renderer_vulkan/vk_update_descriptor.h"
14
15namespace Vulkan {
16
17VKUpdateDescriptorQueue::VKUpdateDescriptorQueue(const VKDevice& device, VKScheduler& scheduler)
18 : device{device}, scheduler{scheduler} {}
19
20VKUpdateDescriptorQueue::~VKUpdateDescriptorQueue() = default;
21
22void VKUpdateDescriptorQueue::TickFrame() {
23 payload.clear();
24}
25
26void VKUpdateDescriptorQueue::Acquire() {
27 entries.clear();
28}
29
30void VKUpdateDescriptorQueue::Send(vk::DescriptorUpdateTemplate update_template,
31 vk::DescriptorSet set) {
32 if (payload.size() + entries.size() >= payload.max_size()) {
33 LOG_WARNING(Render_Vulkan, "Payload overflow, waiting for worker thread");
34 scheduler.WaitWorker();
35 payload.clear();
36 }
37
38 const auto payload_start = payload.data() + payload.size();
39 for (const auto& entry : entries) {
40 if (const auto image = std::get_if<vk::DescriptorImageInfo>(&entry)) {
41 payload.push_back(*image);
42 } else if (const auto buffer = std::get_if<Buffer>(&entry)) {
43 payload.emplace_back(*buffer->buffer, buffer->offset, buffer->size);
44 } else if (const auto texel = std::get_if<vk::BufferView>(&entry)) {
45 payload.push_back(*texel);
46 } else {
47 UNREACHABLE();
48 }
49 }
50
51 scheduler.Record([dev = device.GetLogical(), payload_start, set,
52 update_template]([[maybe_unused]] auto cmdbuf, auto& dld) {
53 dev.updateDescriptorSetWithTemplate(set, update_template, payload_start, dld);
54 });
55}
56
57} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_update_descriptor.h b/src/video_core/renderer_vulkan/vk_update_descriptor.h
new file mode 100644
index 000000000..8c825aa29
--- /dev/null
+++ b/src/video_core/renderer_vulkan/vk_update_descriptor.h
@@ -0,0 +1,86 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <type_traits>
8#include <variant>
9#include <boost/container/static_vector.hpp>
10
11#include "common/common_types.h"
12#include "video_core/renderer_vulkan/declarations.h"
13
14namespace Vulkan {
15
16class VKDevice;
17class VKScheduler;
18
19class DescriptorUpdateEntry {
20public:
21 explicit DescriptorUpdateEntry() : image{} {}
22
23 DescriptorUpdateEntry(vk::DescriptorImageInfo image) : image{image} {}
24
25 DescriptorUpdateEntry(vk::Buffer buffer, vk::DeviceSize offset, vk::DeviceSize size)
26 : buffer{buffer, offset, size} {}
27
28 DescriptorUpdateEntry(vk::BufferView texel_buffer) : texel_buffer{texel_buffer} {}
29
30private:
31 union {
32 vk::DescriptorImageInfo image;
33 vk::DescriptorBufferInfo buffer;
34 vk::BufferView texel_buffer;
35 };
36};
37
38class VKUpdateDescriptorQueue final {
39public:
40 explicit VKUpdateDescriptorQueue(const VKDevice& device, VKScheduler& scheduler);
41 ~VKUpdateDescriptorQueue();
42
43 void TickFrame();
44
45 void Acquire();
46
47 void Send(vk::DescriptorUpdateTemplate update_template, vk::DescriptorSet set);
48
49 void AddSampledImage(vk::Sampler sampler, vk::ImageView image_view) {
50 entries.emplace_back(vk::DescriptorImageInfo{sampler, image_view, {}});
51 }
52
53 void AddImage(vk::ImageView image_view) {
54 entries.emplace_back(vk::DescriptorImageInfo{{}, image_view, {}});
55 }
56
57 void AddBuffer(const vk::Buffer* buffer, u64 offset, std::size_t size) {
58 entries.push_back(Buffer{buffer, offset, size});
59 }
60
61 void AddTexelBuffer(vk::BufferView texel_buffer) {
62 entries.emplace_back(texel_buffer);
63 }
64
65 vk::ImageLayout* GetLastImageLayout() {
66 return &std::get<vk::DescriptorImageInfo>(entries.back()).imageLayout;
67 }
68
69private:
70 struct Buffer {
71 const vk::Buffer* buffer{};
72 u64 offset{};
73 std::size_t size{};
74 };
75 using Variant = std::variant<vk::DescriptorImageInfo, Buffer, vk::BufferView>;
76 // Old gcc versions don't consider this trivially copyable.
77 // static_assert(std::is_trivially_copyable_v<Variant>);
78
79 const VKDevice& device;
80 VKScheduler& scheduler;
81
82 boost::container::static_vector<Variant, 0x400> entries;
83 boost::container::static_vector<DescriptorUpdateEntry, 0x10000> payload;
84};
85
86} // namespace Vulkan