VK refactoring Part 2 (#9542)

This commit is contained in:
Megamouse 2021-01-05 08:49:03 +01:00 committed by GitHub
parent 65f81aca0f
commit 11db3151ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 474 additions and 375 deletions

View File

@ -435,11 +435,14 @@ target_sources(rpcs3_emu PRIVATE
if(TARGET 3rdparty_vulkan)
target_sources(rpcs3_emu PRIVATE
RSX/VK/vkutils/buffer_view.cpp
RSX/VK/vkutils/chip_class.cpp
RSX/VK/vkutils/command_pool.cpp
RSX/VK/vkutils/fence.cpp
RSX/VK/vkutils/mem_allocator.cpp
RSX/VK/vkutils/memory_block.cpp
RSX/VK/vkutils/physical_device.cpp
RSX/VK/vkutils/render_device.cpp
RSX/VK/vkutils/sampler.cpp
RSX/VK/vkutils/shared.cpp
RSX/VK/VKCommandStream.cpp

View File

@ -2,6 +2,7 @@
#include "../Common/BufferUtils.h"
#include "../rsx_methods.h"
#include "VKGSRender.h"
#include "vkutils/buffer_view.h"
namespace vk
{

View File

@ -7,6 +7,7 @@
#include "VKRenderPass.h"
#include "VKResourceManager.h"
#include "VKCommandStream.h"
#include "vkutils/buffer_view.h"
#include "Emu/RSX/rsx_methods.h"
#include "Emu/Memory/vm_locking.h"

View File

@ -53,6 +53,8 @@ extern u64 get_system_time();
namespace vk
{
struct buffer_view;
struct command_buffer_chunk: public vk::command_buffer
{
vk::fence* submit_fence = nullptr;

View File

@ -21,12 +21,11 @@
#include "../Common/TextureUtils.h"
#include "../display.h"
#include "../rsx_utils.h"
#include "vkutils/chip_class.h"
#include "vkutils/command_pool.h"
#include "vkutils/fence.h"
#include "vkutils/mem_allocator.h"
#include "vkutils/memory_block.h"
#include "vkutils/physical_device.h"
#include "vkutils/pipeline_binding_table.h"
#include "vkutils/render_device.h"
#include "vkutils/shared.h"
#include "vkutils/supported_extensions.h"
@ -45,11 +44,6 @@
//using enum rsx::format_class;
using namespace ::rsx::format_class_;
namespace rsx
{
class fragment_texture;
}
namespace vk
{
VKAPI_ATTR void *VKAPI_CALL mem_realloc(void *pUserData, void *pOriginal, usz size, usz alignment, VkSystemAllocationScope allocationScope);
@ -77,7 +71,6 @@ namespace vk
class context;
class render_device;
class swap_chain_image;
class command_buffer;
class image;
struct image_view;
@ -192,325 +185,6 @@ namespace vk
// TODO: Move queries out of the renderer!
void do_query_cleanup(vk::command_buffer& cmd);
class render_device
{
physical_device *pgpu = nullptr;
memory_type_mapping memory_map{};
gpu_formats_support m_formats_support{};
pipeline_binding_table m_pipeline_binding_table{};
std::unique_ptr<mem_allocator_base> m_allocator;
VkDevice dev = VK_NULL_HANDLE;
public:
// Exported device endpoints
PFN_vkCmdBeginConditionalRenderingEXT cmdBeginConditionalRenderingEXT = nullptr;
PFN_vkCmdEndConditionalRenderingEXT cmdEndConditionalRenderingEXT = nullptr;
public:
render_device() = default;
~render_device() = default;
void create(vk::physical_device &pdev, u32 graphics_queue_idx)
{
float queue_priorities[1] = { 0.f };
pgpu = &pdev;
VkDeviceQueueCreateInfo queue = {};
queue.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue.pNext = NULL;
queue.queueFamilyIndex = graphics_queue_idx;
queue.queueCount = 1;
queue.pQueuePriorities = queue_priorities;
// Set up instance information
std::vector<const char *>requested_extensions =
{
VK_KHR_SWAPCHAIN_EXTENSION_NAME
};
// Enable hardware features manually
// Currently we require:
// 1. Anisotropic sampling
// 2. DXT support
// 3. Indexable storage buffers
VkPhysicalDeviceFeatures enabled_features{};
if (pgpu->shader_types_support.allow_float16)
{
requested_extensions.push_back(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME);
}
if (pgpu->conditional_render_support)
{
requested_extensions.push_back(VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME);
}
if (pgpu->unrestricted_depth_range_support)
{
requested_extensions.push_back(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME);
}
enabled_features.robustBufferAccess = VK_TRUE;
enabled_features.fullDrawIndexUint32 = VK_TRUE;
enabled_features.independentBlend = VK_TRUE;
enabled_features.logicOp = VK_TRUE;
enabled_features.depthClamp = VK_TRUE;
enabled_features.depthBounds = VK_TRUE;
enabled_features.wideLines = VK_TRUE;
enabled_features.largePoints = VK_TRUE;
enabled_features.shaderFloat64 = VK_TRUE;
if (g_cfg.video.antialiasing_level != msaa_level::none)
{
// MSAA features
if (!pgpu->features.shaderStorageImageMultisample ||
!pgpu->features.shaderStorageImageWriteWithoutFormat)
{
// TODO: Slow fallback to emulate this
// Just warn and let the driver decide whether to crash or not
rsx_log.fatal("Your GPU driver does not support some required MSAA features. Expect problems.");
}
enabled_features.sampleRateShading = VK_TRUE;
enabled_features.alphaToOne = VK_TRUE;
enabled_features.shaderStorageImageMultisample = VK_TRUE;
// enabled_features.shaderStorageImageReadWithoutFormat = VK_TRUE; // Unused currently, may be needed soon
enabled_features.shaderStorageImageWriteWithoutFormat = VK_TRUE;
}
// enabled_features.shaderSampledImageArrayDynamicIndexing = TRUE; // Unused currently but will be needed soon
enabled_features.shaderClipDistance = VK_TRUE;
// enabled_features.shaderCullDistance = VK_TRUE; // Alt notation of clip distance
enabled_features.samplerAnisotropy = VK_TRUE;
enabled_features.textureCompressionBC = VK_TRUE;
enabled_features.shaderStorageBufferArrayDynamicIndexing = VK_TRUE;
// Optionally disable unsupported stuff
if (!pgpu->features.shaderFloat64)
{
rsx_log.error("Your GPU does not support double precision floats in shaders. Graphics may not work correctly.");
enabled_features.shaderFloat64 = VK_FALSE;
}
if (!pgpu->features.depthBounds)
{
rsx_log.error("Your GPU does not support depth bounds testing. Graphics may not work correctly.");
enabled_features.depthBounds = VK_FALSE;
}
if (!pgpu->features.sampleRateShading && enabled_features.sampleRateShading)
{
rsx_log.error("Your GPU does not support sample rate shading for multisampling. Graphics may be inaccurate when MSAA is enabled.");
enabled_features.sampleRateShading = VK_FALSE;
}
if (!pgpu->features.alphaToOne && enabled_features.alphaToOne)
{
// AMD proprietary drivers do not expose alphaToOne support
rsx_log.error("Your GPU does not support alpha-to-one for multisampling. Graphics may be inaccurate when MSAA is enabled.");
enabled_features.alphaToOne = VK_FALSE;
}
VkDeviceCreateInfo device = {};
device.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
device.pNext = nullptr;
device.queueCreateInfoCount = 1;
device.pQueueCreateInfos = &queue;
device.enabledLayerCount = 0;
device.ppEnabledLayerNames = nullptr; // Deprecated
device.enabledExtensionCount = ::size32(requested_extensions);
device.ppEnabledExtensionNames = requested_extensions.data();
device.pEnabledFeatures = &enabled_features;
VkPhysicalDeviceFloat16Int8FeaturesKHR shader_support_info{};
if (pgpu->shader_types_support.allow_float16)
{
// Allow use of f16 type in shaders if possible
shader_support_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR;
shader_support_info.shaderFloat16 = VK_TRUE;
device.pNext = &shader_support_info;
rsx_log.notice("GPU/driver supports float16 data types natively. Using native float16_t variables if possible.");
}
else
{
rsx_log.notice("GPU/driver lacks support for float16 data types. All float16_t arithmetic will be emulated with float32_t.");
}
CHECK_RESULT(vkCreateDevice(*pgpu, &device, nullptr, &dev));
// Import optional function endpoints
if (pgpu->conditional_render_support)
{
cmdBeginConditionalRenderingEXT = reinterpret_cast<PFN_vkCmdBeginConditionalRenderingEXT>(vkGetDeviceProcAddr(dev, "vkCmdBeginConditionalRenderingEXT"));
cmdEndConditionalRenderingEXT = reinterpret_cast<PFN_vkCmdEndConditionalRenderingEXT>(vkGetDeviceProcAddr(dev, "vkCmdEndConditionalRenderingEXT"));
}
memory_map = vk::get_memory_mapping(pdev);
m_formats_support = vk::get_optimal_tiling_supported_formats(pdev);
m_pipeline_binding_table = vk::get_pipeline_binding_table(pdev);
if (g_cfg.video.disable_vulkan_mem_allocator)
m_allocator = std::make_unique<vk::mem_allocator_vk>(dev, pdev);
else
m_allocator = std::make_unique<vk::mem_allocator_vma>(dev, pdev);
}
void destroy()
{
if (dev && pgpu)
{
if (m_allocator)
{
m_allocator->destroy();
m_allocator.reset();
}
vkDestroyDevice(dev, nullptr);
dev = nullptr;
memory_map = {};
m_formats_support = {};
}
}
const VkFormatProperties get_format_properties(VkFormat format)
{
auto found = pgpu->format_properties.find(format);
if (found != pgpu->format_properties.end())
{
return found->second;
}
auto& props = pgpu->format_properties[format];
vkGetPhysicalDeviceFormatProperties(*pgpu, format, &props);
return props;
}
bool get_compatible_memory_type(u32 typeBits, u32 desired_mask, u32 *type_index) const
{
VkPhysicalDeviceMemoryProperties mem_infos = pgpu->get_memory_properties();
for (u32 i = 0; i < 32; i++)
{
if ((typeBits & 1) == 1)
{
if ((mem_infos.memoryTypes[i].propertyFlags & desired_mask) == desired_mask)
{
if (type_index)
{
*type_index = i;
}
return true;
}
}
typeBits >>= 1;
}
return false;
}
const physical_device& gpu() const
{
return *pgpu;
}
const memory_type_mapping& get_memory_mapping() const
{
return memory_map;
}
const gpu_formats_support& get_formats_support() const
{
return m_formats_support;
}
const pipeline_binding_table& get_pipeline_binding_table() const
{
return m_pipeline_binding_table;
}
const gpu_shader_types_support& get_shader_types_support() const
{
return pgpu->shader_types_support;
}
bool get_shader_stencil_export_support() const
{
return pgpu->stencil_export_support;
}
bool get_depth_bounds_support() const
{
return pgpu->features.depthBounds != VK_FALSE;
}
bool get_alpha_to_one_support() const
{
return pgpu->features.alphaToOne != VK_FALSE;
}
bool get_conditional_render_support() const
{
return pgpu->conditional_render_support;
}
bool get_unrestricted_depth_range_support() const
{
return pgpu->unrestricted_depth_range_support;
}
mem_allocator_base* get_allocator() const
{
return m_allocator.get();
}
operator VkDevice() const
{
return dev;
}
};
class command_pool
{
vk::render_device *owner = nullptr;
VkCommandPool pool = nullptr;
public:
command_pool() = default;
~command_pool() = default;
void create(vk::render_device &dev)
{
owner = &dev;
VkCommandPoolCreateInfo infos = {};
infos.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
infos.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
CHECK_RESULT(vkCreateCommandPool(dev, &infos, nullptr, &pool));
}
void destroy()
{
if (!pool)
return;
vkDestroyCommandPool((*owner), pool, nullptr);
pool = nullptr;
}
vk::render_device& get_owner()
{
return (*owner);
}
operator VkCommandPool()
{
return pool;
}
};
class command_buffer
{
private:
@ -1125,53 +799,6 @@ namespace vk
VkDevice m_device;
};
struct buffer_view
{
VkBufferView value;
VkBufferViewCreateInfo info = {};
buffer_view(VkDevice dev, VkBuffer buffer, VkFormat format, VkDeviceSize offset, VkDeviceSize size)
: m_device(dev)
{
info.buffer = buffer;
info.format = format;
info.offset = offset;
info.range = size;
info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
CHECK_RESULT(vkCreateBufferView(m_device, &info, nullptr, &value));
}
~buffer_view()
{
vkDestroyBufferView(m_device, value, nullptr);
}
buffer_view(const buffer_view&) = delete;
buffer_view(buffer_view&&) = delete;
bool in_range(u32 address, u32 size, u32& offset) const
{
if (address < info.offset)
return false;
const u32 _offset = address - static_cast<u32>(info.offset);
if (info.range < _offset)
return false;
const auto remaining = info.range - _offset;
if (size <= remaining)
{
offset = _offset;
return true;
}
return false;
}
private:
VkDevice m_device;
};
class event
{
VkDevice m_device = VK_NULL_HANDLE;

View File

@ -1,5 +1,6 @@
#include "stdafx.h"
#include "VKGSRender.h"
#include "vkutils/buffer_view.h"
#include "Emu/Cell/Modules/cellVideoOut.h"
#include "util/asm.hpp"

View File

@ -2,6 +2,7 @@
#include "VKGSRender.h"
#include "../Common/BufferUtils.h"
#include "../rsx_methods.h"
#include "vkutils/buffer_view.h"
namespace vk
{

View File

@ -0,0 +1,40 @@
#include "buffer_view.h"
#include "shared.h"
namespace vk
{
buffer_view::buffer_view(VkDevice dev, VkBuffer buffer, VkFormat format, VkDeviceSize offset, VkDeviceSize size)
: m_device(dev)
{
info.buffer = buffer;
info.format = format;
info.offset = offset;
info.range = size;
info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
CHECK_RESULT(vkCreateBufferView(m_device, &info, nullptr, &value));
}
buffer_view::~buffer_view()
{
vkDestroyBufferView(m_device, value, nullptr);
}
bool buffer_view::in_range(u32 address, u32 size, u32& offset) const
{
if (address < info.offset)
return false;
const u32 _offset = address - static_cast<u32>(info.offset);
if (info.range < _offset)
return false;
const auto remaining = info.range - _offset;
if (size <= remaining)
{
offset = _offset;
return true;
}
return false;
}
}

View File

@ -0,0 +1,23 @@
#pragma once
#include "../VulkanAPI.h"
namespace vk
{
struct buffer_view
{
VkBufferView value;
VkBufferViewCreateInfo info = {};
buffer_view(VkDevice dev, VkBuffer buffer, VkFormat format, VkDeviceSize offset, VkDeviceSize size);
~buffer_view();
buffer_view(const buffer_view&) = delete;
buffer_view(buffer_view&&) = delete;
bool in_range(u32 address, u32 size, u32& offset) const;
private:
VkDevice m_device;
};
}

View File

@ -0,0 +1,35 @@
#include "command_pool.h"
#include "render_device.h"
#include "shared.h"
namespace vk
{
void command_pool::create(vk::render_device& dev)
{
owner = &dev;
VkCommandPoolCreateInfo infos = {};
infos.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
infos.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
CHECK_RESULT(vkCreateCommandPool(dev, &infos, nullptr, &pool));
}
void command_pool::destroy()
{
if (!pool)
return;
vkDestroyCommandPool((*owner), pool, nullptr);
pool = nullptr;
}
vk::render_device& command_pool::get_owner()
{
return (*owner);
}
command_pool::operator VkCommandPool()
{
return pool;
}
}

View File

@ -0,0 +1,25 @@
#pragma once
#include "../VulkanAPI.h"
namespace vk
{
class render_device;
class command_pool
{
vk::render_device* owner = nullptr;
VkCommandPool pool = nullptr;
public:
command_pool() = default;
~command_pool() = default;
void create(vk::render_device& dev);
void destroy();
vk::render_device& get_owner();
operator VkCommandPool();
};
}

View File

@ -0,0 +1,265 @@
#include "render_device.h"
#include "mem_allocator.h"
#include "shared.h"
#include "Emu/system_config.h"
namespace vk
{
void render_device::create(vk::physical_device& pdev, u32 graphics_queue_idx)
{
float queue_priorities[1] = {0.f};
pgpu = &pdev;
VkDeviceQueueCreateInfo queue = {};
queue.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue.pNext = NULL;
queue.queueFamilyIndex = graphics_queue_idx;
queue.queueCount = 1;
queue.pQueuePriorities = queue_priorities;
// Set up instance information
std::vector<const char*> requested_extensions = {VK_KHR_SWAPCHAIN_EXTENSION_NAME};
// Enable hardware features manually
// Currently we require:
// 1. Anisotropic sampling
// 2. DXT support
// 3. Indexable storage buffers
VkPhysicalDeviceFeatures enabled_features{};
if (pgpu->shader_types_support.allow_float16)
{
requested_extensions.push_back(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME);
}
if (pgpu->conditional_render_support)
{
requested_extensions.push_back(VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME);
}
if (pgpu->unrestricted_depth_range_support)
{
requested_extensions.push_back(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME);
}
enabled_features.robustBufferAccess = VK_TRUE;
enabled_features.fullDrawIndexUint32 = VK_TRUE;
enabled_features.independentBlend = VK_TRUE;
enabled_features.logicOp = VK_TRUE;
enabled_features.depthClamp = VK_TRUE;
enabled_features.depthBounds = VK_TRUE;
enabled_features.wideLines = VK_TRUE;
enabled_features.largePoints = VK_TRUE;
enabled_features.shaderFloat64 = VK_TRUE;
if (g_cfg.video.antialiasing_level != msaa_level::none)
{
// MSAA features
if (!pgpu->features.shaderStorageImageMultisample || !pgpu->features.shaderStorageImageWriteWithoutFormat)
{
// TODO: Slow fallback to emulate this
// Just warn and let the driver decide whether to crash or not
rsx_log.fatal("Your GPU driver does not support some required MSAA features. Expect problems.");
}
enabled_features.sampleRateShading = VK_TRUE;
enabled_features.alphaToOne = VK_TRUE;
enabled_features.shaderStorageImageMultisample = VK_TRUE;
// enabled_features.shaderStorageImageReadWithoutFormat = VK_TRUE; // Unused currently, may be needed soon
enabled_features.shaderStorageImageWriteWithoutFormat = VK_TRUE;
}
// enabled_features.shaderSampledImageArrayDynamicIndexing = TRUE; // Unused currently but will be needed soon
enabled_features.shaderClipDistance = VK_TRUE;
// enabled_features.shaderCullDistance = VK_TRUE; // Alt notation of clip distance
enabled_features.samplerAnisotropy = VK_TRUE;
enabled_features.textureCompressionBC = VK_TRUE;
enabled_features.shaderStorageBufferArrayDynamicIndexing = VK_TRUE;
// Optionally disable unsupported stuff
if (!pgpu->features.shaderFloat64)
{
rsx_log.error("Your GPU does not support double precision floats in shaders. Graphics may not work correctly.");
enabled_features.shaderFloat64 = VK_FALSE;
}
if (!pgpu->features.depthBounds)
{
rsx_log.error("Your GPU does not support depth bounds testing. Graphics may not work correctly.");
enabled_features.depthBounds = VK_FALSE;
}
if (!pgpu->features.sampleRateShading && enabled_features.sampleRateShading)
{
rsx_log.error("Your GPU does not support sample rate shading for multisampling. Graphics may be inaccurate when MSAA is enabled.");
enabled_features.sampleRateShading = VK_FALSE;
}
if (!pgpu->features.alphaToOne && enabled_features.alphaToOne)
{
// AMD proprietary drivers do not expose alphaToOne support
rsx_log.error("Your GPU does not support alpha-to-one for multisampling. Graphics may be inaccurate when MSAA is enabled.");
enabled_features.alphaToOne = VK_FALSE;
}
VkDeviceCreateInfo device = {};
device.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
device.pNext = nullptr;
device.queueCreateInfoCount = 1;
device.pQueueCreateInfos = &queue;
device.enabledLayerCount = 0;
device.ppEnabledLayerNames = nullptr; // Deprecated
device.enabledExtensionCount = ::size32(requested_extensions);
device.ppEnabledExtensionNames = requested_extensions.data();
device.pEnabledFeatures = &enabled_features;
VkPhysicalDeviceFloat16Int8FeaturesKHR shader_support_info{};
if (pgpu->shader_types_support.allow_float16)
{
// Allow use of f16 type in shaders if possible
shader_support_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR;
shader_support_info.shaderFloat16 = VK_TRUE;
device.pNext = &shader_support_info;
rsx_log.notice("GPU/driver supports float16 data types natively. Using native float16_t variables if possible.");
}
else
{
rsx_log.notice("GPU/driver lacks support for float16 data types. All float16_t arithmetic will be emulated with float32_t.");
}
CHECK_RESULT(vkCreateDevice(*pgpu, &device, nullptr, &dev));
// Import optional function endpoints
if (pgpu->conditional_render_support)
{
cmdBeginConditionalRenderingEXT = reinterpret_cast<PFN_vkCmdBeginConditionalRenderingEXT>(vkGetDeviceProcAddr(dev, "vkCmdBeginConditionalRenderingEXT"));
cmdEndConditionalRenderingEXT = reinterpret_cast<PFN_vkCmdEndConditionalRenderingEXT>(vkGetDeviceProcAddr(dev, "vkCmdEndConditionalRenderingEXT"));
}
memory_map = vk::get_memory_mapping(pdev);
m_formats_support = vk::get_optimal_tiling_supported_formats(pdev);
m_pipeline_binding_table = vk::get_pipeline_binding_table(pdev);
if (g_cfg.video.disable_vulkan_mem_allocator)
m_allocator = std::make_unique<vk::mem_allocator_vk>(dev, pdev);
else
m_allocator = std::make_unique<vk::mem_allocator_vma>(dev, pdev);
}
void render_device::destroy()
{
if (dev && pgpu)
{
if (m_allocator)
{
m_allocator->destroy();
m_allocator.reset();
}
vkDestroyDevice(dev, nullptr);
dev = nullptr;
memory_map = {};
m_formats_support = {};
}
}
const VkFormatProperties render_device::get_format_properties(VkFormat format)
{
auto found = pgpu->format_properties.find(format);
if (found != pgpu->format_properties.end())
{
return found->second;
}
auto& props = pgpu->format_properties[format];
vkGetPhysicalDeviceFormatProperties(*pgpu, format, &props);
return props;
}
bool render_device::get_compatible_memory_type(u32 typeBits, u32 desired_mask, u32* type_index) const
{
VkPhysicalDeviceMemoryProperties mem_infos = pgpu->get_memory_properties();
for (u32 i = 0; i < 32; i++)
{
if ((typeBits & 1) == 1)
{
if ((mem_infos.memoryTypes[i].propertyFlags & desired_mask) == desired_mask)
{
if (type_index)
{
*type_index = i;
}
return true;
}
}
typeBits >>= 1;
}
return false;
}
const physical_device& render_device::gpu() const
{
return *pgpu;
}
const memory_type_mapping& render_device::get_memory_mapping() const
{
return memory_map;
}
const gpu_formats_support& render_device::get_formats_support() const
{
return m_formats_support;
}
const pipeline_binding_table& render_device::get_pipeline_binding_table() const
{
return m_pipeline_binding_table;
}
const gpu_shader_types_support& render_device::get_shader_types_support() const
{
return pgpu->shader_types_support;
}
bool render_device::get_shader_stencil_export_support() const
{
return pgpu->stencil_export_support;
}
bool render_device::get_depth_bounds_support() const
{
return pgpu->features.depthBounds != VK_FALSE;
}
bool render_device::get_alpha_to_one_support() const
{
return pgpu->features.alphaToOne != VK_FALSE;
}
bool render_device::get_conditional_render_support() const
{
return pgpu->conditional_render_support;
}
bool render_device::get_unrestricted_depth_range_support() const
{
return pgpu->unrestricted_depth_range_support;
}
mem_allocator_base* render_device::get_allocator() const
{
return m_allocator.get();
}
render_device::operator VkDevice() const
{
return dev;
}
}

View File

@ -0,0 +1,51 @@
#pragma once
#include "physical_device.h"
#include <memory>
namespace vk
{
class mem_allocator_base;
class render_device
{
physical_device* pgpu = nullptr;
memory_type_mapping memory_map{};
gpu_formats_support m_formats_support{};
pipeline_binding_table m_pipeline_binding_table{};
std::unique_ptr<mem_allocator_base> m_allocator;
VkDevice dev = VK_NULL_HANDLE;
public:
// Exported device endpoints
PFN_vkCmdBeginConditionalRenderingEXT cmdBeginConditionalRenderingEXT = nullptr;
PFN_vkCmdEndConditionalRenderingEXT cmdEndConditionalRenderingEXT = nullptr;
public:
render_device() = default;
~render_device() = default;
void create(vk::physical_device& pdev, u32 graphics_queue_idx);
void destroy();
const VkFormatProperties get_format_properties(VkFormat format);
bool get_compatible_memory_type(u32 typeBits, u32 desired_mask, u32* type_index) const;
const physical_device& gpu() const;
const memory_type_mapping& get_memory_mapping() const;
const gpu_formats_support& get_formats_support() const;
const pipeline_binding_table& get_pipeline_binding_table() const;
const gpu_shader_types_support& get_shader_types_support() const;
bool get_shader_stencil_export_support() const;
bool get_depth_bounds_support() const;
bool get_alpha_to_one_support() const;
bool get_conditional_render_support() const;
bool get_unrestricted_depth_range_support() const;
mem_allocator_base* get_allocator() const;
operator VkDevice() const;
};
}

View File

@ -40,7 +40,9 @@
<ClInclude Include="Emu\RSX\VK\VKShaderInterpreter.h" />
<ClInclude Include="Emu\RSX\VK\VKTextOut.h" />
<ClInclude Include="Emu\RSX\VK\VKTextureCache.h" />
<ClInclude Include="Emu\RSX\VK\vkutils\buffer_view.h" />
<ClInclude Include="Emu\RSX\VK\vkutils\chip_class.h" />
<ClInclude Include="Emu\RSX\VK\vkutils\command_pool.h" />
<ClInclude Include="Emu\RSX\VK\vkutils\fence.h" />
<ClInclude Include="Emu\RSX\VK\vkutils\graphics_pipeline_state.h" />
<ClInclude Include="Emu\RSX\VK\vkutils\memory_block.h" />
@ -48,6 +50,7 @@
<ClInclude Include="Emu\RSX\VK\vkutils\physical_device.h" />
<ClInclude Include="Emu\RSX\VK\vkutils\pipeline_binding_table.h" />
<ClInclude Include="Emu\RSX\VK\vkutils\query_pool.h" />
<ClInclude Include="Emu\RSX\VK\vkutils\render_device.h" />
<ClInclude Include="Emu\RSX\VK\vkutils\sampler.h" />
<ClInclude Include="Emu\RSX\VK\vkutils\shared.h" />
<ClInclude Include="Emu\RSX\VK\vkutils\supported_extensions.h" />
@ -73,11 +76,14 @@
<ClCompile Include="Emu\RSX\VK\VKResourceManager.cpp" />
<ClCompile Include="Emu\RSX\VK\VKShaderInterpreter.cpp" />
<ClCompile Include="Emu\RSX\VK\VKTexture.cpp" />
<ClCompile Include="Emu\RSX\VK\vkutils\buffer_view.cpp" />
<ClCompile Include="Emu\RSX\VK\vkutils\chip_class.cpp" />
<ClCompile Include="Emu\RSX\VK\vkutils\command_pool.cpp" />
<ClCompile Include="Emu\RSX\VK\vkutils\fence.cpp" />
<ClCompile Include="Emu\RSX\VK\vkutils\memory_block.cpp" />
<ClCompile Include="Emu\RSX\VK\vkutils\mem_allocator.cpp" />
<ClCompile Include="Emu\RSX\VK\vkutils\physical_device.cpp" />
<ClCompile Include="Emu\RSX\VK\vkutils\render_device.cpp" />
<ClCompile Include="Emu\RSX\VK\vkutils\sampler.cpp" />
<ClCompile Include="Emu\RSX\VK\vkutils\shared.cpp" />
<ClCompile Include="Emu\RSX\VK\VKVertexBuffers.cpp" />

View File

@ -44,6 +44,15 @@
<ClCompile Include="Emu\RSX\VK\vkutils\shared.cpp">
<Filter>vkutils</Filter>
</ClCompile>
<ClCompile Include="Emu\RSX\VK\vkutils\buffer_view.cpp">
<Filter>vkutils</Filter>
</ClCompile>
<ClCompile Include="Emu\RSX\VK\vkutils\render_device.cpp">
<Filter>vkutils</Filter>
</ClCompile>
<ClCompile Include="Emu\RSX\VK\vkutils\command_pool.cpp">
<Filter>vkutils</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Emu\RSX\VK\VKCommonDecompiler.h" />
@ -102,6 +111,15 @@
<ClInclude Include="Emu\RSX\VK\vkutils\supported_extensions.h">
<Filter>vkutils</Filter>
</ClInclude>
<ClInclude Include="Emu\RSX\VK\vkutils\buffer_view.h">
<Filter>vkutils</Filter>
</ClInclude>
<ClInclude Include="Emu\RSX\VK\vkutils\render_device.h">
<Filter>vkutils</Filter>
</ClInclude>
<ClInclude Include="Emu\RSX\VK\vkutils\command_pool.h">
<Filter>vkutils</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="vkutils">