|
|
|
@ -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);
|
|
|
|
|
|
|
|
|
|