summaryrefslogtreecommitdiffstats
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)
renderer_vulkan/vk_stream_buffer.cpp
renderer_vulkan/vk_stream_buffer.h
renderer_vulkan/vk_swapchain.cpp
- renderer_vulkan/vk_swapchain.h)
+ renderer_vulkan/vk_swapchain.h
+ renderer_vulkan/vk_update_descriptor.cpp
+ renderer_vulkan/vk_update_descriptor.h)
target_include_directories(video_core PRIVATE sirit ../../externals/Vulkan-Headers/include)
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 @@
+// Copyright 2019 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <variant>
+#include <boost/container/static_vector.hpp>
+
+#include "common/assert.h"
+#include "common/logging/log.h"
+#include "video_core/renderer_vulkan/declarations.h"
+#include "video_core/renderer_vulkan/vk_device.h"
+#include "video_core/renderer_vulkan/vk_scheduler.h"
+#include "video_core/renderer_vulkan/vk_update_descriptor.h"
+
+namespace Vulkan {
+
+VKUpdateDescriptorQueue::VKUpdateDescriptorQueue(const VKDevice& device, VKScheduler& scheduler)
+ : device{device}, scheduler{scheduler} {}
+
+VKUpdateDescriptorQueue::~VKUpdateDescriptorQueue() = default;
+
+void VKUpdateDescriptorQueue::TickFrame() {
+ payload.clear();
+}
+
+void VKUpdateDescriptorQueue::Acquire() {
+ entries.clear();
+}
+
+void VKUpdateDescriptorQueue::Send(vk::DescriptorUpdateTemplate update_template,
+ vk::DescriptorSet set) {
+ if (payload.size() + entries.size() >= payload.max_size()) {
+ LOG_WARNING(Render_Vulkan, "Payload overflow, waiting for worker thread");
+ scheduler.WaitWorker();
+ payload.clear();
+ }
+
+ const auto payload_start = payload.data() + payload.size();
+ for (const auto& entry : entries) {
+ if (const auto image = std::get_if<vk::DescriptorImageInfo>(&entry)) {
+ payload.push_back(*image);
+ } else if (const auto buffer = std::get_if<Buffer>(&entry)) {
+ payload.emplace_back(*buffer->buffer, buffer->offset, buffer->size);
+ } else if (const auto texel = std::get_if<vk::BufferView>(&entry)) {
+ payload.push_back(*texel);
+ } else {
+ UNREACHABLE();
+ }
+ }
+
+ scheduler.Record([dev = device.GetLogical(), payload_start, set,
+ update_template]([[maybe_unused]] auto cmdbuf, auto& dld) {
+ dev.updateDescriptorSetWithTemplate(set, update_template, payload_start, dld);
+ });
+}
+
+} // 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 @@
+// Copyright 2019 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <type_traits>
+#include <variant>
+#include <boost/container/static_vector.hpp>
+
+#include "common/common_types.h"
+#include "video_core/renderer_vulkan/declarations.h"
+
+namespace Vulkan {
+
+class VKDevice;
+class VKScheduler;
+
+class DescriptorUpdateEntry {
+public:
+ explicit DescriptorUpdateEntry() : image{} {}
+
+ DescriptorUpdateEntry(vk::DescriptorImageInfo image) : image{image} {}
+
+ DescriptorUpdateEntry(vk::Buffer buffer, vk::DeviceSize offset, vk::DeviceSize size)
+ : buffer{buffer, offset, size} {}
+
+ DescriptorUpdateEntry(vk::BufferView texel_buffer) : texel_buffer{texel_buffer} {}
+
+private:
+ union {
+ vk::DescriptorImageInfo image;
+ vk::DescriptorBufferInfo buffer;
+ vk::BufferView texel_buffer;
+ };
+};
+
+class VKUpdateDescriptorQueue final {
+public:
+ explicit VKUpdateDescriptorQueue(const VKDevice& device, VKScheduler& scheduler);
+ ~VKUpdateDescriptorQueue();
+
+ void TickFrame();
+
+ void Acquire();
+
+ void Send(vk::DescriptorUpdateTemplate update_template, vk::DescriptorSet set);
+
+ void AddSampledImage(vk::Sampler sampler, vk::ImageView image_view) {
+ entries.emplace_back(vk::DescriptorImageInfo{sampler, image_view, {}});
+ }
+
+ void AddImage(vk::ImageView image_view) {
+ entries.emplace_back(vk::DescriptorImageInfo{{}, image_view, {}});
+ }
+
+ void AddBuffer(const vk::Buffer* buffer, u64 offset, std::size_t size) {
+ entries.push_back(Buffer{buffer, offset, size});
+ }
+
+ void AddTexelBuffer(vk::BufferView texel_buffer) {
+ entries.emplace_back(texel_buffer);
+ }
+
+ vk::ImageLayout* GetLastImageLayout() {
+ return &std::get<vk::DescriptorImageInfo>(entries.back()).imageLayout;
+ }
+
+private:
+ struct Buffer {
+ const vk::Buffer* buffer{};
+ u64 offset{};
+ std::size_t size{};
+ };
+ using Variant = std::variant<vk::DescriptorImageInfo, Buffer, vk::BufferView>;
+ // Old gcc versions don't consider this trivially copyable.
+ // static_assert(std::is_trivially_copyable_v<Variant>);
+
+ const VKDevice& device;
+ VKScheduler& scheduler;
+
+ boost::container::static_vector<Variant, 0x400> entries;
+ boost::container::static_vector<DescriptorUpdateEntry, 0x10000> payload;
+};
+
+} // namespace Vulkan