mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-10-07 22:29:48 +00:00
A quick topology test
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#include "video_core/host_shaders/queries_prefix_scan_sum_comp_spv.h"
|
||||
#include "video_core/host_shaders/queries_prefix_scan_sum_nosubgroups_comp_spv.h"
|
||||
#include "video_core/host_shaders/resolve_conditional_render_comp_spv.h"
|
||||
#include "video_core/host_shaders/vulkan_indirect_quads_comp_spv.h"
|
||||
#include "video_core/host_shaders/vulkan_quad_indexed_comp_spv.h"
|
||||
#include "video_core/host_shaders/vulkan_uint8_comp_spv.h"
|
||||
#include "video_core/renderer_vulkan/vk_compute_pass.h"
|
||||
@@ -375,6 +376,56 @@ std::pair<VkBuffer, VkDeviceSize> QuadIndexedPass::Assemble(
|
||||
return {staging.buffer, staging.offset};
|
||||
}
|
||||
|
||||
IndirectQuadsPass::IndirectQuadsPass(const Device& device_, Scheduler& scheduler_,
|
||||
DescriptorPool& descriptor_pool_,
|
||||
StagingBufferPool& staging_buffer_pool_,
|
||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue_)
|
||||
: ComputePass(device_, scheduler_, descriptor_pool_, INPUT_OUTPUT_DESCRIPTOR_SET_BINDINGS,
|
||||
INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE, INPUT_OUTPUT_BANK_INFO,
|
||||
COMPUTE_PUSH_CONSTANT_RANGE<sizeof(u32) * 2>, VULKAN_INDIRECT_QUADS_COMP_SPV),
|
||||
scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_},
|
||||
compute_pass_descriptor_queue{compute_pass_descriptor_queue_} {}
|
||||
|
||||
IndirectQuadsPass::~IndirectQuadsPass() = default;
|
||||
|
||||
std::pair<VkBuffer, VkDeviceSize> IndirectQuadsPass::Assemble(u32 num_draws, u32 stride,
|
||||
VkBuffer src_buffer, u32 src_offset) {
|
||||
u32 src_stride = stride / static_cast<u32>(sizeof(u32));
|
||||
if (src_stride < COMMAND_WORDS) {
|
||||
src_stride = COMMAND_WORDS;
|
||||
}
|
||||
const u32 input_size = num_draws * src_stride * static_cast<u32>(sizeof(u32));
|
||||
const std::size_t staging_size = std::size_t(num_draws) * COMMAND_WORDS * sizeof(u32);
|
||||
const auto staging = staging_buffer_pool.Request(staging_size, MemoryUsage::DeviceLocal);
|
||||
|
||||
compute_pass_descriptor_queue.Acquire(scheduler, 2);
|
||||
compute_pass_descriptor_queue.AddBuffer(src_buffer, src_offset, input_size);
|
||||
compute_pass_descriptor_queue.AddBuffer(staging.buffer, staging.offset, staging_size);
|
||||
const void* const descriptor_data{compute_pass_descriptor_queue.UpdateData()};
|
||||
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.Record([this, descriptor_data, num_draws, src_stride](vk::CommandBuffer cmdbuf) {
|
||||
static constexpr u32 DISPATCH_SIZE = 32;
|
||||
static constexpr VkMemoryBarrier WRITE_BARRIER{
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
|
||||
};
|
||||
const std::array<u32, 2> push_constants{num_draws, src_stride};
|
||||
const VkDescriptorSet set = descriptor_allocator.Commit();
|
||||
device.GetLogical().UpdateDescriptorSet(set, *descriptor_template, descriptor_data);
|
||||
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
|
||||
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, *layout, 0, set, {});
|
||||
cmdbuf.PushConstants(*layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(push_constants),
|
||||
&push_constants);
|
||||
cmdbuf.Dispatch(Common::DivCeil(num_draws, DISPATCH_SIZE), 1, 1);
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 0, WRITE_BARRIER);
|
||||
});
|
||||
return {staging.buffer, staging.offset};
|
||||
}
|
||||
|
||||
ConditionalRenderingResolvePass::ConditionalRenderingResolvePass(
|
||||
const Device& device_, Scheduler& scheduler_, DescriptorPool& descriptor_pool_,
|
||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue_)
|
||||
|
||||
@@ -88,6 +88,25 @@ private:
|
||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue;
|
||||
};
|
||||
|
||||
class IndirectQuadsPass final : public ComputePass {
|
||||
public:
|
||||
explicit IndirectQuadsPass(const Device& device_, Scheduler& scheduler_,
|
||||
DescriptorPool& descriptor_pool_,
|
||||
StagingBufferPool& staging_buffer_pool_,
|
||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue_);
|
||||
~IndirectQuadsPass();
|
||||
|
||||
static constexpr u32 COMMAND_WORDS = 5;
|
||||
|
||||
std::pair<VkBuffer, VkDeviceSize> Assemble(u32 num_draws, u32 stride, VkBuffer src_buffer,
|
||||
u32 src_offset);
|
||||
|
||||
private:
|
||||
Scheduler& scheduler;
|
||||
StagingBufferPool& staging_buffer_pool;
|
||||
ComputePassDescriptorQueue& compute_pass_descriptor_queue;
|
||||
};
|
||||
|
||||
class ConditionalRenderingResolvePass final : public ComputePass {
|
||||
public:
|
||||
explicit ConditionalRenderingResolvePass(
|
||||
|
||||
@@ -212,6 +212,8 @@ RasterizerVulkan::RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra
|
||||
compute_pass_descriptor_queue(device, UpdateDescriptorQueue::COMPUTE_FRAME_PAYLOAD_SIZE),
|
||||
descriptor_buffer_ring(device, memory_allocator),
|
||||
blit_image(device, scheduler, state_tracker, descriptor_pool), render_pass_cache(device),
|
||||
indirect_quads_pass(device, scheduler, descriptor_pool, staging_pool,
|
||||
compute_pass_descriptor_queue),
|
||||
texture_cache_runtime{
|
||||
device, scheduler, memory_allocator, staging_pool,
|
||||
blit_image, render_pass_cache, descriptor_pool, compute_pass_descriptor_queue},
|
||||
@@ -314,6 +316,18 @@ void RasterizerVulkan::DrawIndirect() {
|
||||
const auto indirect_buffer = buffer_cache.GetDrawIndirectBuffer();
|
||||
const auto& buffer = indirect_buffer.first;
|
||||
const auto& offset = indirect_buffer.second;
|
||||
VkBuffer command_buffer = buffer->Handle();
|
||||
VkDeviceSize command_offset = offset;
|
||||
u32 command_stride = static_cast<u32>(params.stride);
|
||||
if (params.is_indexed &&
|
||||
maxwell3d->draw_manager.draw_state.topology == Maxwell::PrimitiveTopology::Quads) {
|
||||
const auto patched = indirect_quads_pass.Assemble(
|
||||
static_cast<u32>(params.max_draw_counts), command_stride, command_buffer,
|
||||
static_cast<u32>(offset));
|
||||
command_buffer = patched.first;
|
||||
command_offset = patched.second;
|
||||
command_stride = IndirectQuadsPass::COMMAND_WORDS * static_cast<u32>(sizeof(u32));
|
||||
}
|
||||
if (params.is_byte_count) {
|
||||
scheduler.Record([buffer_obj = buffer->Handle(), offset,
|
||||
stride = params.stride](vk::CommandBuffer cmdbuf) {
|
||||
@@ -326,29 +340,32 @@ void RasterizerVulkan::DrawIndirect() {
|
||||
const auto count = buffer_cache.GetDrawIndirectCount();
|
||||
const auto& draw_buffer = count.first;
|
||||
const auto& offset_base = count.second;
|
||||
scheduler.Record([draw_buffer_obj = draw_buffer->Handle(),
|
||||
buffer_obj = buffer->Handle(), offset_base, offset,
|
||||
scheduler.Record([draw_buffer_obj = draw_buffer->Handle(), command_buffer,
|
||||
offset_base, command_offset, command_stride,
|
||||
params](vk::CommandBuffer cmdbuf) {
|
||||
if (params.is_indexed) {
|
||||
cmdbuf.DrawIndexedIndirectCount(
|
||||
buffer_obj, offset, draw_buffer_obj, offset_base,
|
||||
static_cast<u32>(params.max_draw_counts), static_cast<u32>(params.stride));
|
||||
cmdbuf.DrawIndexedIndirectCount(command_buffer, command_offset, draw_buffer_obj,
|
||||
offset_base,
|
||||
static_cast<u32>(params.max_draw_counts),
|
||||
command_stride);
|
||||
} else {
|
||||
cmdbuf.DrawIndirectCount(buffer_obj, offset, draw_buffer_obj, offset_base,
|
||||
cmdbuf.DrawIndirectCount(command_buffer, command_offset, draw_buffer_obj,
|
||||
offset_base,
|
||||
static_cast<u32>(params.max_draw_counts),
|
||||
static_cast<u32>(params.stride));
|
||||
command_stride);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
scheduler.Record([buffer_obj = buffer->Handle(), offset, params](vk::CommandBuffer cmdbuf) {
|
||||
scheduler.Record([command_buffer, command_offset, command_stride,
|
||||
params](vk::CommandBuffer cmdbuf) {
|
||||
if (params.is_indexed) {
|
||||
cmdbuf.DrawIndexedIndirect(buffer_obj, offset,
|
||||
cmdbuf.DrawIndexedIndirect(command_buffer, command_offset,
|
||||
static_cast<u32>(params.max_draw_counts),
|
||||
static_cast<u32>(params.stride));
|
||||
command_stride);
|
||||
} else {
|
||||
cmdbuf.DrawIndirect(buffer_obj, offset, static_cast<u32>(params.max_draw_counts),
|
||||
static_cast<u32>(params.stride));
|
||||
cmdbuf.DrawIndirect(command_buffer, command_offset,
|
||||
static_cast<u32>(params.max_draw_counts), command_stride);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "video_core/rasterizer_interface.h"
|
||||
#include "video_core/renderer_vulkan/blit_image.h"
|
||||
#include "video_core/renderer_vulkan/vk_buffer_cache.h"
|
||||
#include "video_core/renderer_vulkan/vk_compute_pass.h"
|
||||
#include "video_core/renderer_vulkan/vk_descriptor_buffer.h"
|
||||
#include "video_core/renderer_vulkan/vk_descriptor_pool.h"
|
||||
#include "video_core/renderer_vulkan/vk_fence_manager.h"
|
||||
@@ -211,6 +212,7 @@ private:
|
||||
DescriptorBufferRing descriptor_buffer_ring;
|
||||
BlitImageHelper blit_image;
|
||||
RenderPassCache render_pass_cache;
|
||||
IndirectQuadsPass indirect_quads_pass;
|
||||
|
||||
TextureCacheRuntime texture_cache_runtime;
|
||||
TextureCache texture_cache;
|
||||
|
||||
@@ -211,7 +211,8 @@ StagingBufferRef StagingBufferPool::CreateStagingBuffer(size_t size, MemoryUsage
|
||||
.size = 1ULL << log2_size,
|
||||
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
|
||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
|
||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
|
||||
VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.queueFamilyIndexCount = 0,
|
||||
.pQueueFamilyIndices = nullptr,
|
||||
|
||||
Reference in New Issue
Block a user