summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_vulkan
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_vulkan')
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp57
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h4
2 files changed, 47 insertions, 14 deletions
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index ac1eb9895..9b75f33dd 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -180,7 +180,8 @@ RasterizerVulkan::RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra
RasterizerVulkan::~RasterizerVulkan() = default;
-void RasterizerVulkan::Draw(bool is_indexed, u32 instance_count) {
+template <typename Func>
+void RasterizerVulkan::PrepareDraw(bool is_indexed, Func&& draw_func) {
MICROPROFILE_SCOPE(Vulkan_Drawing);
SCOPE_EXIT({ gpu.TickWork(); });
@@ -201,22 +202,50 @@ void RasterizerVulkan::Draw(bool is_indexed, u32 instance_count) {
UpdateDynamicStates();
- const auto& draw_state = maxwell3d->draw_manager->GetDrawState();
- const u32 num_instances{instance_count};
- const DrawParams draw_params{MakeDrawParams(draw_state, num_instances, is_indexed)};
- scheduler.Record([draw_params](vk::CommandBuffer cmdbuf) {
- if (draw_params.is_indexed) {
- cmdbuf.DrawIndexed(draw_params.num_vertices, draw_params.num_instances,
- draw_params.first_index, draw_params.base_vertex,
- draw_params.base_instance);
- } else {
- cmdbuf.Draw(draw_params.num_vertices, draw_params.num_instances,
- draw_params.base_vertex, draw_params.base_instance);
- }
- });
+ draw_func();
+
EndTransformFeedback();
}
+void RasterizerVulkan::Draw(bool is_indexed, u32 instance_count) {
+ PrepareDraw(is_indexed, [this, is_indexed, instance_count] {
+ const auto& draw_state = maxwell3d->draw_manager->GetDrawState();
+ const u32 num_instances{instance_count};
+ const DrawParams draw_params{MakeDrawParams(draw_state, num_instances, is_indexed)};
+ scheduler.Record([draw_params](vk::CommandBuffer cmdbuf) {
+ if (draw_params.is_indexed) {
+ cmdbuf.DrawIndexed(draw_params.num_vertices, draw_params.num_instances,
+ draw_params.first_index, draw_params.base_vertex,
+ draw_params.base_instance);
+ } else {
+ cmdbuf.Draw(draw_params.num_vertices, draw_params.num_instances,
+ draw_params.base_vertex, draw_params.base_instance);
+ }
+ });
+ });
+}
+
+void RasterizerVulkan::DrawIndirect(bool is_indexed) {
+ PrepareDraw(is_indexed, [this, is_indexed] {
+ const auto params = maxwell3d->draw_manager->GetIndirectParams();
+ const auto [buffer, offset] = buffer_cache.ObtainBuffer(
+ params.start_address, static_cast<u32>(params.buffer_size), true, false);
+ scheduler.Record([buffer_obj = buffer->Handle(), offset,
+ max_draw_counts = params.max_draw_counts, stride = params.stride,
+ is_indexed](vk::CommandBuffer cmdbuf) {
+ if (is_indexed) {
+ cmdbuf.DrawIndexedIndirectCount(buffer_obj, offset + 4ULL, buffer_obj, offset,
+ static_cast<u32>(max_draw_counts),
+ static_cast<u32>(stride));
+ } else {
+ cmdbuf.DrawIndirectCount(buffer_obj, offset + 4ULL, buffer_obj, offset,
+ static_cast<u32>(max_draw_counts),
+ static_cast<u32>(stride));
+ }
+ });
+ });
+}
+
void RasterizerVulkan::Clear(u32 layer_count) {
MICROPROFILE_SCOPE(Vulkan_Clearing);
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index ee483cfd9..bc43a8a1f 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -65,6 +65,7 @@ public:
~RasterizerVulkan() override;
void Draw(bool is_indexed, u32 instance_count) override;
+ void DrawIndirect(bool is_indexed) override;
void Clear(u32 layer_count) override;
void DispatchCompute() override;
void ResetCounter(VideoCore::QueryType type) override;
@@ -114,6 +115,9 @@ private:
static constexpr VkDeviceSize DEFAULT_BUFFER_SIZE = 4 * sizeof(float);
+ template <typename Func>
+ void PrepareDraw(bool is_indexed, Func&&);
+
void FlushWork();
void UpdateDynamicStates();