2020-12-05 13:08:24 +01:00
|
|
|
#include "stdafx.h"
|
2016-02-21 18:50:49 +03:00
|
|
|
#include "VKHelpers.h"
|
2019-06-28 21:35:43 +03:00
|
|
|
#include "VKGSRender.h"
|
2018-06-12 18:46:59 +03:00
|
|
|
#include "VKCompute.h"
|
2019-05-24 16:31:46 +03:00
|
|
|
#include "VKRenderPass.h"
|
2019-05-27 12:16:18 +03:00
|
|
|
#include "VKFramebuffer.h"
|
2019-05-30 18:38:18 +03:00
|
|
|
#include "VKResolveHelper.h"
|
2019-06-28 20:33:03 +03:00
|
|
|
#include "VKResourceManager.h"
|
2019-08-17 14:06:38 +03:00
|
|
|
#include "VKDMA.h"
|
2019-12-07 16:28:35 +03:00
|
|
|
#include "VKCommandStream.h"
|
2020-03-10 14:05:50 +03:00
|
|
|
#include "VKRenderPass.h"
|
2019-12-07 16:28:35 +03:00
|
|
|
|
2021-01-09 21:46:50 +03:00
|
|
|
#include "vkutils/scratch.h"
|
|
|
|
|
#include "vkutils/device.h"
|
2020-12-13 14:54:43 +03:00
|
|
|
#include "Emu/RSX/rsx_methods.h"
|
2020-12-22 18:04:08 +03:00
|
|
|
#include <unordered_map>
|
2017-12-28 20:07:43 +03:00
|
|
|
|
2016-02-21 18:50:49 +03:00
|
|
|
namespace vk
|
|
|
|
|
{
|
2020-12-24 11:49:08 +01:00
|
|
|
extern chip_class g_chip_class;
|
2019-09-26 14:06:37 +03:00
|
|
|
|
2018-06-12 18:46:59 +03:00
|
|
|
std::unordered_map<u32, std::unique_ptr<vk::compute_task>> g_compute_tasks;
|
2020-05-20 22:51:15 +03:00
|
|
|
std::unordered_map<u32, std::unique_ptr<vk::overlay_pass>> g_overlay_passes;
|
2016-02-21 18:50:49 +03:00
|
|
|
|
2019-11-09 16:31:12 +03:00
|
|
|
rsx::atomic_bitmask_t<runtime_state, u64> g_runtime_state;
|
2018-02-23 11:30:13 +03:00
|
|
|
|
2018-12-22 13:26:32 +03:00
|
|
|
// Driver compatibility workarounds
|
2018-08-23 21:56:06 +03:00
|
|
|
VkFlags g_heap_compatible_buffer_types = 0;
|
2018-06-06 20:34:55 +03:00
|
|
|
driver_vendor g_driver_vendor = driver_vendor::unknown;
|
2020-06-29 20:03:27 +03:00
|
|
|
bool g_drv_no_primitive_restart = false;
|
2018-02-23 11:30:13 +03:00
|
|
|
bool g_drv_sanitize_fp_values = false;
|
2018-03-26 14:40:23 +03:00
|
|
|
bool g_drv_disable_fence_reset = false;
|
2019-12-10 09:10:13 +03:00
|
|
|
bool g_drv_emulate_cond_render = false;
|
2017-04-23 17:17:05 +03:00
|
|
|
|
2017-09-22 20:29:12 +03:00
|
|
|
u64 g_num_processed_frames = 0;
|
|
|
|
|
u64 g_num_total_frames = 0;
|
|
|
|
|
|
2020-05-20 22:51:15 +03:00
|
|
|
void reset_overlay_passes()
|
|
|
|
|
{
|
|
|
|
|
for (const auto& p : g_overlay_passes)
|
|
|
|
|
{
|
|
|
|
|
p.second->free_resources();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-30 18:38:18 +03:00
|
|
|
void reset_global_resources()
|
|
|
|
|
{
|
2023-05-29 17:01:03 +03:00
|
|
|
// FIXME: These two shouldn't exist
|
2019-05-30 18:38:18 +03:00
|
|
|
vk::reset_resolve_resources();
|
2020-05-20 22:51:15 +03:00
|
|
|
vk::reset_overlay_passes();
|
2019-08-06 14:46:21 +03:00
|
|
|
|
2021-01-09 21:46:50 +03:00
|
|
|
get_upload_heap()->reset_allocation_stats();
|
2019-05-30 18:38:18 +03:00
|
|
|
}
|
|
|
|
|
|
2016-02-21 18:50:49 +03:00
|
|
|
void destroy_global_resources()
|
|
|
|
|
{
|
2021-01-09 21:46:50 +03:00
|
|
|
VkDevice dev = *g_render_device;
|
2019-05-24 16:31:46 +03:00
|
|
|
vk::clear_renderpass_cache(dev);
|
2019-05-27 12:16:18 +03:00
|
|
|
vk::clear_framebuffer_cache();
|
2019-05-30 18:38:18 +03:00
|
|
|
vk::clear_resolve_helpers();
|
2019-08-17 14:06:38 +03:00
|
|
|
vk::clear_dma_resources();
|
2021-01-09 21:46:50 +03:00
|
|
|
vk::clear_scratch_resources();
|
2019-05-24 16:31:46 +03:00
|
|
|
|
2021-01-09 21:46:50 +03:00
|
|
|
vk::get_upload_heap()->destroy();
|
2018-06-12 18:46:59 +03:00
|
|
|
|
|
|
|
|
g_compute_tasks.clear();
|
2020-05-20 22:51:15 +03:00
|
|
|
|
|
|
|
|
for (const auto& p : g_overlay_passes)
|
|
|
|
|
{
|
|
|
|
|
p.second->destroy();
|
|
|
|
|
}
|
|
|
|
|
g_overlay_passes.clear();
|
2021-01-19 00:40:56 +03:00
|
|
|
|
|
|
|
|
// This must be the last item destroyed
|
|
|
|
|
vk::get_resource_manager()->destroy();
|
2022-02-09 00:44:17 +03:00
|
|
|
|
|
|
|
|
// Statistics counter reset. Also verifies that everything was deleted.
|
|
|
|
|
vk::vmm_reset();
|
2016-02-21 18:50:49 +03:00
|
|
|
}
|
|
|
|
|
|
2018-06-06 20:34:55 +03:00
|
|
|
const vk::render_device *get_current_renderer()
|
2016-02-21 18:50:49 +03:00
|
|
|
{
|
2021-01-09 21:46:50 +03:00
|
|
|
return g_render_device;
|
2016-02-21 18:50:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void set_current_renderer(const vk::render_device &device)
|
|
|
|
|
{
|
2021-01-09 21:46:50 +03:00
|
|
|
g_render_device = &device;
|
2019-11-09 16:31:12 +03:00
|
|
|
g_runtime_state.clear();
|
2020-06-29 20:03:27 +03:00
|
|
|
g_drv_no_primitive_restart = false;
|
2018-05-10 14:50:32 +03:00
|
|
|
g_drv_sanitize_fp_values = false;
|
|
|
|
|
g_drv_disable_fence_reset = false;
|
2021-01-09 21:46:50 +03:00
|
|
|
g_drv_emulate_cond_render = (g_cfg.video.relaxed_zcull_sync && !g_render_device->get_conditional_render_support());
|
2018-05-10 14:50:32 +03:00
|
|
|
g_num_processed_frames = 0;
|
|
|
|
|
g_num_total_frames = 0;
|
2018-08-23 21:56:06 +03:00
|
|
|
g_heap_compatible_buffer_types = 0;
|
2018-05-10 14:50:32 +03:00
|
|
|
|
2021-01-09 21:46:50 +03:00
|
|
|
const auto& gpu = g_render_device->gpu();
|
2019-09-26 14:06:37 +03:00
|
|
|
const auto gpu_name = gpu.get_name();
|
|
|
|
|
|
|
|
|
|
g_driver_vendor = gpu.get_driver_vendor();
|
|
|
|
|
g_chip_class = gpu.get_chip_class();
|
|
|
|
|
|
|
|
|
|
switch (g_driver_vendor)
|
2017-10-17 01:02:43 +03:00
|
|
|
{
|
2018-08-29 15:49:19 +03:00
|
|
|
case driver_vendor::AMD:
|
2020-06-29 20:03:27 +03:00
|
|
|
// Primitive restart on older GCN is still broken
|
|
|
|
|
g_drv_no_primitive_restart = (g_chip_class == vk::chip_class::AMD_gcn_generic);
|
|
|
|
|
break;
|
2018-08-29 15:49:19 +03:00
|
|
|
case driver_vendor::RADV:
|
2019-07-08 21:46:09 +03:00
|
|
|
// Previous bugs with fence reset and primitive restart seem to have been fixed with newer drivers
|
2018-08-29 15:49:19 +03:00
|
|
|
break;
|
|
|
|
|
case driver_vendor::NVIDIA:
|
|
|
|
|
// Nvidia cards are easily susceptible to NaN poisoning
|
|
|
|
|
g_drv_sanitize_fp_values = true;
|
|
|
|
|
break;
|
2019-05-04 16:56:57 +03:00
|
|
|
case driver_vendor::INTEL:
|
2021-08-17 15:47:29 +03:00
|
|
|
case driver_vendor::ANV:
|
|
|
|
|
// INTEL vulkan drivers are mostly OK, workarounds are applied when creating the device
|
|
|
|
|
break;
|
2022-01-18 00:25:59 +01:00
|
|
|
case driver_vendor::MVK:
|
|
|
|
|
// Apple GPUs / moltenVK need more testing
|
|
|
|
|
break;
|
2018-08-29 15:49:19 +03:00
|
|
|
default:
|
2020-02-01 11:07:25 +03:00
|
|
|
rsx_log.warning("Unsupported device: %s", gpu_name);
|
2018-06-04 19:57:16 +03:00
|
|
|
}
|
2018-08-23 21:56:06 +03:00
|
|
|
|
2020-02-01 11:07:25 +03:00
|
|
|
rsx_log.notice("Vulkan: Renderer initialized on device '%s'", gpu_name);
|
2018-08-29 15:49:19 +03:00
|
|
|
|
2018-08-23 21:56:06 +03:00
|
|
|
{
|
|
|
|
|
// Buffer memory tests, only useful for portability on macOS
|
|
|
|
|
VkBufferUsageFlags types[] =
|
|
|
|
|
{
|
|
|
|
|
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
|
|
|
|
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
|
|
|
|
VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
|
|
|
|
|
VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
|
|
|
|
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
|
|
|
|
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkFlags memory_flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
|
|
|
|
|
|
|
|
|
VkBuffer tmp;
|
|
|
|
|
VkMemoryRequirements memory_reqs;
|
|
|
|
|
|
|
|
|
|
VkBufferCreateInfo info = {};
|
|
|
|
|
info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
|
|
|
|
info.size = 4096;
|
|
|
|
|
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
|
|
|
|
info.flags = 0;
|
|
|
|
|
|
|
|
|
|
for (const auto &usage : types)
|
|
|
|
|
{
|
|
|
|
|
info.usage = usage;
|
2021-01-09 21:46:50 +03:00
|
|
|
CHECK_RESULT(vkCreateBuffer(*g_render_device, &info, nullptr, &tmp));
|
2019-06-02 00:12:17 +03:00
|
|
|
|
2021-01-09 21:46:50 +03:00
|
|
|
vkGetBufferMemoryRequirements(*g_render_device, tmp, &memory_reqs);
|
|
|
|
|
if (g_render_device->get_compatible_memory_type(memory_reqs.memoryTypeBits, memory_flags, nullptr))
|
2018-08-23 21:56:06 +03:00
|
|
|
{
|
|
|
|
|
g_heap_compatible_buffer_types |= usage;
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-09 21:46:50 +03:00
|
|
|
vkDestroyBuffer(*g_render_device, tmp, nullptr);
|
2018-08-23 21:56:06 +03:00
|
|
|
}
|
|
|
|
|
}
|
2021-09-23 22:54:50 +03:00
|
|
|
|
|
|
|
|
descriptors::init();
|
2018-08-23 21:56:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkFlags get_heap_compatible_buffer_types()
|
|
|
|
|
{
|
|
|
|
|
return g_heap_compatible_buffer_types;
|
2018-06-04 19:57:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
driver_vendor get_driver_vendor()
|
|
|
|
|
{
|
|
|
|
|
return g_driver_vendor;
|
2017-10-17 01:02:43 +03:00
|
|
|
}
|
|
|
|
|
|
2018-04-21 18:02:17 +03:00
|
|
|
bool emulate_primitive_restart(rsx::primitive_type type)
|
2017-10-17 01:02:43 +03:00
|
|
|
{
|
2020-06-29 20:03:27 +03:00
|
|
|
if (g_drv_no_primitive_restart)
|
2018-04-21 18:02:17 +03:00
|
|
|
{
|
|
|
|
|
switch (type)
|
|
|
|
|
{
|
|
|
|
|
case rsx::primitive_type::triangle_strip:
|
|
|
|
|
case rsx::primitive_type::quad_strip:
|
|
|
|
|
return true;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-02-21 18:50:49 +03:00
|
|
|
|
2018-04-21 18:02:17 +03:00
|
|
|
return false;
|
2018-02-05 23:36:45 +03:00
|
|
|
}
|
|
|
|
|
|
2018-02-23 11:30:13 +03:00
|
|
|
bool sanitize_fp_values()
|
|
|
|
|
{
|
|
|
|
|
return g_drv_sanitize_fp_values;
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-26 14:40:23 +03:00
|
|
|
bool fence_reset_disabled()
|
|
|
|
|
{
|
|
|
|
|
return g_drv_disable_fence_reset;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-10 09:10:13 +03:00
|
|
|
bool emulate_conditional_rendering()
|
|
|
|
|
{
|
|
|
|
|
return g_drv_emulate_cond_render;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-09 16:31:12 +03:00
|
|
|
void raise_status_interrupt(runtime_state status)
|
|
|
|
|
{
|
|
|
|
|
g_runtime_state |= status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void clear_status_interrupt(runtime_state status)
|
|
|
|
|
{
|
|
|
|
|
g_runtime_state.clear(status);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool test_status_interrupt(runtime_state status)
|
|
|
|
|
{
|
|
|
|
|
return g_runtime_state & status;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-23 17:17:05 +03:00
|
|
|
void enter_uninterruptible()
|
|
|
|
|
{
|
2019-11-09 16:31:12 +03:00
|
|
|
raise_status_interrupt(runtime_state::uninterruptible);
|
2017-04-23 17:17:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void leave_uninterruptible()
|
|
|
|
|
{
|
2019-11-09 16:31:12 +03:00
|
|
|
clear_status_interrupt(runtime_state::uninterruptible);
|
2017-04-23 17:17:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool is_uninterruptible()
|
|
|
|
|
{
|
2019-11-09 16:31:12 +03:00
|
|
|
return test_status_interrupt(runtime_state::uninterruptible);
|
2017-04-23 17:17:05 +03:00
|
|
|
}
|
|
|
|
|
|
2017-09-22 20:29:12 +03:00
|
|
|
void advance_completed_frame_counter()
|
|
|
|
|
{
|
|
|
|
|
g_num_processed_frames++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void advance_frame_counter()
|
|
|
|
|
{
|
2020-12-09 10:47:45 +03:00
|
|
|
ensure(g_num_processed_frames <= g_num_total_frames);
|
2017-09-22 20:29:12 +03:00
|
|
|
g_num_total_frames++;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-07 18:49:42 +03:00
|
|
|
u64 get_current_frame_id()
|
2017-09-22 20:29:12 +03:00
|
|
|
{
|
|
|
|
|
return g_num_total_frames;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-07 18:49:42 +03:00
|
|
|
u64 get_last_completed_frame_id()
|
2017-09-22 20:29:12 +03:00
|
|
|
{
|
|
|
|
|
return (g_num_processed_frames > 0)? g_num_processed_frames - 1: 0;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-28 21:35:43 +03:00
|
|
|
void do_query_cleanup(vk::command_buffer& cmd)
|
|
|
|
|
{
|
|
|
|
|
auto renderer = dynamic_cast<VKGSRender*>(rsx::get_current_renderer());
|
2020-12-09 10:47:45 +03:00
|
|
|
ensure(renderer);
|
2019-06-28 21:35:43 +03:00
|
|
|
|
|
|
|
|
renderer->emergency_query_cleanup(&cmd);
|
|
|
|
|
}
|
2023-06-12 23:31:13 +03:00
|
|
|
|
2023-06-13 22:29:08 +03:00
|
|
|
void on_descriptor_pool_fragmentation(bool is_fatal)
|
2023-06-12 23:31:13 +03:00
|
|
|
{
|
|
|
|
|
if (auto vkthr = dynamic_cast<VKGSRender*>(rsx::get_current_renderer()))
|
|
|
|
|
{
|
2023-06-13 22:29:08 +03:00
|
|
|
vkthr->on_descriptor_pool_fragmentation(is_fatal);
|
2023-06-12 23:31:13 +03:00
|
|
|
}
|
|
|
|
|
}
|
2016-02-02 00:50:02 +03:00
|
|
|
}
|