summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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