mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-14 15:40:17 +00:00
Refactoring
- Make the memory allocator a unique child of the render device. Fixes object lifetime issues with swapchain management due to cyclic dependencies
This commit is contained in:
parent
c9e367befd
commit
63f803b68a
@ -547,18 +547,6 @@ VKGSRender::VKGSRender() : GSRender()
|
||||
vk::set_current_thread_ctx(m_thread_context);
|
||||
vk::set_current_renderer(m_swapchain->get_device());
|
||||
|
||||
// Choose memory allocator (device memory)
|
||||
if (g_cfg.video.disable_vulkan_mem_allocator)
|
||||
{
|
||||
m_mem_allocator = std::make_shared<vk::mem_allocator_vk>(*m_device, m_device->gpu());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mem_allocator = std::make_shared<vk::mem_allocator_vma>(*m_device, m_device->gpu());
|
||||
}
|
||||
|
||||
vk::set_current_mem_allocator(m_mem_allocator);
|
||||
|
||||
m_client_width = m_frame->client_width();
|
||||
m_client_height = m_frame->client_height();
|
||||
if (!m_swapchain->init(m_client_width, m_client_height))
|
||||
@ -782,7 +770,6 @@ VKGSRender::~VKGSRender()
|
||||
|
||||
//Device handles/contexts
|
||||
m_swapchain->destroy();
|
||||
m_mem_allocator->destroy();
|
||||
m_thread_context.close();
|
||||
|
||||
#if !defined(_WIN32) && defined(HAVE_VULKAN)
|
||||
|
@ -287,8 +287,6 @@ public:
|
||||
std::unique_ptr<vk::vertex_cache> m_vertex_cache;
|
||||
std::unique_ptr<vk::shader_cache> m_shaders_cache;
|
||||
|
||||
std::shared_ptr<vk::mem_allocator_base> m_mem_allocator;
|
||||
|
||||
private:
|
||||
std::unique_ptr<VKProgramBuffer> m_prog_buffer;
|
||||
|
||||
|
@ -4,20 +4,19 @@
|
||||
|
||||
namespace vk
|
||||
{
|
||||
context* g_current_vulkan_ctx = nullptr;
|
||||
render_device g_current_renderer;
|
||||
driver_vendor g_driver_vendor = driver_vendor::unknown;
|
||||
std::shared_ptr<vk::mem_allocator_base> g_mem_allocator = nullptr;
|
||||
const context* g_current_vulkan_ctx = nullptr;
|
||||
const render_device* g_current_renderer;
|
||||
|
||||
std::unique_ptr<image> g_null_texture;
|
||||
std::unique_ptr<image_view> g_null_image_view;
|
||||
std::unordered_map<VkFormat, std::unique_ptr<image>> g_typeless_textures;
|
||||
std::unordered_map<u32, std::unique_ptr<image>> g_typeless_textures;
|
||||
|
||||
VkSampler g_null_sampler = nullptr;
|
||||
|
||||
atomic_t<bool> g_cb_no_interrupt_flag { false };
|
||||
|
||||
//Driver compatibility workarounds
|
||||
driver_vendor g_driver_vendor = driver_vendor::unknown;
|
||||
bool g_drv_no_primitive_restart_flag = false;
|
||||
bool g_drv_sanitize_fp_values = false;
|
||||
bool g_drv_disable_fence_reset = false;
|
||||
@ -141,7 +140,7 @@ namespace vk
|
||||
sampler_info.compareOp = VK_COMPARE_OP_NEVER;
|
||||
sampler_info.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
|
||||
|
||||
vkCreateSampler(g_current_renderer, &sampler_info, nullptr, &g_null_sampler);
|
||||
vkCreateSampler(*g_current_renderer, &sampler_info, nullptr, &g_null_sampler);
|
||||
return g_null_sampler;
|
||||
}
|
||||
|
||||
@ -150,11 +149,11 @@ namespace vk
|
||||
if (g_null_image_view)
|
||||
return g_null_image_view->value;
|
||||
|
||||
g_null_texture.reset(new image(g_current_renderer, g_current_renderer.get_memory_mapping().device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
g_null_texture.reset(new image(*g_current_renderer, g_current_renderer->get_memory_mapping().device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
VK_IMAGE_TYPE_2D, VK_FORMAT_B8G8R8A8_UNORM, 4, 4, 1, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 0));
|
||||
|
||||
g_null_image_view.reset(new image_view(g_current_renderer, g_null_texture->value, VK_IMAGE_VIEW_TYPE_2D,
|
||||
g_null_image_view.reset(new image_view(*g_current_renderer, g_null_texture->value, VK_IMAGE_VIEW_TYPE_2D,
|
||||
VK_FORMAT_B8G8R8A8_UNORM, {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
|
||||
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}));
|
||||
|
||||
@ -173,12 +172,12 @@ namespace vk
|
||||
{
|
||||
auto create_texture = [&]()
|
||||
{
|
||||
return new vk::image(g_current_renderer, g_current_renderer.get_memory_mapping().device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
return new vk::image(*g_current_renderer, g_current_renderer->get_memory_mapping().device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
VK_IMAGE_TYPE_2D, format, 4096, 4096, 1, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0);
|
||||
};
|
||||
|
||||
auto &ptr = g_typeless_textures[format];
|
||||
auto &ptr = g_typeless_textures[(u32)format];
|
||||
if (!ptr)
|
||||
{
|
||||
auto _img = create_texture();
|
||||
@ -206,39 +205,35 @@ namespace vk
|
||||
g_typeless_textures.clear();
|
||||
|
||||
if (g_null_sampler)
|
||||
vkDestroySampler(g_current_renderer, g_null_sampler, nullptr);
|
||||
vkDestroySampler(*g_current_renderer, g_null_sampler, nullptr);
|
||||
|
||||
g_null_sampler = nullptr;
|
||||
}
|
||||
|
||||
void set_current_mem_allocator(std::shared_ptr<vk::mem_allocator_base> mem_allocator)
|
||||
vk::mem_allocator_base* get_current_mem_allocator()
|
||||
{
|
||||
g_mem_allocator = mem_allocator;
|
||||
}
|
||||
|
||||
std::shared_ptr<vk::mem_allocator_base> get_current_mem_allocator()
|
||||
{
|
||||
return g_mem_allocator;
|
||||
verify (HERE, g_current_renderer);
|
||||
return g_current_renderer->get_allocator();
|
||||
}
|
||||
|
||||
void set_current_thread_ctx(const vk::context &ctx)
|
||||
{
|
||||
g_current_vulkan_ctx = (vk::context *)&ctx;
|
||||
g_current_vulkan_ctx = &ctx;
|
||||
}
|
||||
|
||||
context *get_current_thread_ctx()
|
||||
const context *get_current_thread_ctx()
|
||||
{
|
||||
return g_current_vulkan_ctx;
|
||||
}
|
||||
|
||||
vk::render_device *get_current_renderer()
|
||||
const vk::render_device *get_current_renderer()
|
||||
{
|
||||
return &g_current_renderer;
|
||||
return g_current_renderer;
|
||||
}
|
||||
|
||||
void set_current_renderer(const vk::render_device &device)
|
||||
{
|
||||
g_current_renderer = device;
|
||||
g_current_renderer = &device;
|
||||
g_cb_no_interrupt_flag.store(false);
|
||||
g_drv_no_primitive_restart_flag = false;
|
||||
g_drv_sanitize_fp_values = false;
|
||||
@ -247,7 +242,7 @@ namespace vk
|
||||
g_num_total_frames = 0;
|
||||
g_driver_vendor = driver_vendor::unknown;
|
||||
|
||||
const auto gpu_name = g_current_renderer.gpu().name();
|
||||
const auto gpu_name = g_current_renderer->gpu().name();
|
||||
|
||||
//Radeon fails to properly handle degenerate primitives if primitive restart is enabled
|
||||
//One has to choose between using degenerate primitives or primitive restart to break up lists but not both
|
||||
@ -488,15 +483,15 @@ namespace vk
|
||||
{
|
||||
if (g_drv_disable_fence_reset)
|
||||
{
|
||||
vkDestroyFence(g_current_renderer, *pFence, nullptr);
|
||||
vkDestroyFence(*g_current_renderer, *pFence, nullptr);
|
||||
|
||||
VkFenceCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
CHECK_RESULT(vkCreateFence(g_current_renderer, &info, nullptr, pFence));
|
||||
CHECK_RESULT(vkCreateFence(*g_current_renderer, &info, nullptr, pFence));
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_RESULT(vkResetFences(g_current_renderer, 1, pFence));
|
||||
CHECK_RESULT(vkResetFences(*g_current_renderer, 1, pFence));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,14 +77,13 @@ namespace vk
|
||||
struct memory_type_mapping;
|
||||
struct gpu_formats_support;
|
||||
|
||||
vk::context *get_current_thread_ctx();
|
||||
const vk::context *get_current_thread_ctx();
|
||||
void set_current_thread_ctx(const vk::context &ctx);
|
||||
|
||||
vk::render_device *get_current_renderer();
|
||||
const vk::render_device *get_current_renderer();
|
||||
void set_current_renderer(const vk::render_device &device);
|
||||
|
||||
void set_current_mem_allocator(std::shared_ptr<vk::mem_allocator_base> mem_allocator);
|
||||
std::shared_ptr<vk::mem_allocator_base> get_current_mem_allocator();
|
||||
mem_allocator_base *get_current_mem_allocator();
|
||||
|
||||
//Compatibility workarounds
|
||||
bool emulate_primitive_restart(rsx::primitive_type type);
|
||||
@ -167,178 +166,6 @@ namespace vk
|
||||
bool d32_sfloat_s8;
|
||||
};
|
||||
|
||||
class physical_device
|
||||
{
|
||||
VkPhysicalDevice dev = nullptr;
|
||||
VkPhysicalDeviceProperties props;
|
||||
VkPhysicalDeviceMemoryProperties memory_properties;
|
||||
std::vector<VkQueueFamilyProperties> queue_props;
|
||||
|
||||
public:
|
||||
|
||||
physical_device() {}
|
||||
~physical_device() {}
|
||||
|
||||
void set_device(VkPhysicalDevice pdev)
|
||||
{
|
||||
dev = pdev;
|
||||
vkGetPhysicalDeviceProperties(pdev, &props);
|
||||
vkGetPhysicalDeviceMemoryProperties(pdev, &memory_properties);
|
||||
}
|
||||
|
||||
std::string name() const
|
||||
{
|
||||
return props.deviceName;
|
||||
}
|
||||
|
||||
uint32_t get_queue_count() const
|
||||
{
|
||||
if (queue_props.size())
|
||||
return (u32)queue_props.size();
|
||||
|
||||
uint32_t count = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(dev, &count, nullptr);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
VkQueueFamilyProperties get_queue_properties(uint32_t queue)
|
||||
{
|
||||
if (!queue_props.size())
|
||||
{
|
||||
uint32_t count = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(dev, &count, nullptr);
|
||||
|
||||
queue_props.resize(count);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(dev, &count, queue_props.data());
|
||||
}
|
||||
|
||||
if (queue >= queue_props.size()) fmt::throw_exception("Bad queue index passed to get_queue_properties (%u)" HERE, queue);
|
||||
return queue_props[queue];
|
||||
}
|
||||
|
||||
VkPhysicalDeviceMemoryProperties get_memory_properties() const
|
||||
{
|
||||
return memory_properties;
|
||||
}
|
||||
|
||||
operator VkPhysicalDevice() const
|
||||
{
|
||||
return dev;
|
||||
}
|
||||
};
|
||||
|
||||
class render_device
|
||||
{
|
||||
physical_device *pgpu = nullptr;
|
||||
memory_type_mapping memory_map{};
|
||||
gpu_formats_support m_formats_support{};
|
||||
VkDevice dev = VK_NULL_HANDLE;
|
||||
|
||||
public:
|
||||
render_device()
|
||||
{}
|
||||
|
||||
render_device(vk::physical_device &pdev, uint32_t 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
|
||||
const char *requested_extensions[] =
|
||||
{
|
||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
||||
};
|
||||
|
||||
//Enable hardware features manually
|
||||
//Currently we require:
|
||||
//1. Anisotropic sampling
|
||||
//2. DXT support
|
||||
VkPhysicalDeviceFeatures available_features;
|
||||
vkGetPhysicalDeviceFeatures(*pgpu, &available_features);
|
||||
|
||||
available_features.samplerAnisotropy = VK_TRUE;
|
||||
available_features.textureCompressionBC = VK_TRUE;
|
||||
|
||||
VkDeviceCreateInfo device = {};
|
||||
device.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||
device.pNext = NULL;
|
||||
device.queueCreateInfoCount = 1;
|
||||
device.pQueueCreateInfos = &queue;
|
||||
device.enabledLayerCount = 0;
|
||||
device.ppEnabledLayerNames = nullptr; // Deprecated
|
||||
device.enabledExtensionCount = 1;
|
||||
device.ppEnabledExtensionNames = requested_extensions;
|
||||
device.pEnabledFeatures = &available_features;
|
||||
|
||||
CHECK_RESULT(vkCreateDevice(*pgpu, &device, nullptr, &dev));
|
||||
|
||||
memory_map = vk::get_memory_mapping(pdev);
|
||||
m_formats_support = vk::get_optimal_tiling_supported_formats(pdev);
|
||||
}
|
||||
|
||||
~render_device()
|
||||
{
|
||||
}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
if (dev && pgpu)
|
||||
{
|
||||
vkDestroyDevice(dev, nullptr);
|
||||
dev = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool get_compatible_memory_type(u32 typeBits, u32 desired_mask, u32 *type_index)
|
||||
{
|
||||
VkPhysicalDeviceMemoryProperties mem_infos = pgpu->get_memory_properties();
|
||||
|
||||
for (uint32_t i = 0; i < 32; i++)
|
||||
{
|
||||
if ((typeBits & 1) == 1)
|
||||
{
|
||||
if ((mem_infos.memoryTypes[i].propertyFlags & desired_mask) == desired_mask)
|
||||
{
|
||||
*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;
|
||||
}
|
||||
|
||||
operator VkDevice&()
|
||||
{
|
||||
return dev;
|
||||
}
|
||||
};
|
||||
|
||||
// Memory Allocator - base class
|
||||
|
||||
class mem_allocator_base
|
||||
@ -530,10 +357,200 @@ namespace vk
|
||||
|
||||
private:
|
||||
VkDevice m_device;
|
||||
std::shared_ptr<vk::mem_allocator_base> m_mem_allocator;
|
||||
vk::mem_allocator_base* m_mem_allocator;
|
||||
mem_allocator_base::mem_handle_t m_mem_handle;
|
||||
};
|
||||
|
||||
class physical_device
|
||||
{
|
||||
VkPhysicalDevice dev = nullptr;
|
||||
VkPhysicalDeviceProperties props;
|
||||
VkPhysicalDeviceMemoryProperties memory_properties;
|
||||
std::vector<VkQueueFamilyProperties> queue_props;
|
||||
|
||||
public:
|
||||
|
||||
physical_device() {}
|
||||
~physical_device() {}
|
||||
|
||||
void set_device(VkPhysicalDevice pdev)
|
||||
{
|
||||
dev = pdev;
|
||||
vkGetPhysicalDeviceProperties(pdev, &props);
|
||||
vkGetPhysicalDeviceMemoryProperties(pdev, &memory_properties);
|
||||
}
|
||||
|
||||
std::string name() const
|
||||
{
|
||||
return props.deviceName;
|
||||
}
|
||||
|
||||
uint32_t get_queue_count() const
|
||||
{
|
||||
if (queue_props.size())
|
||||
return (u32)queue_props.size();
|
||||
|
||||
uint32_t count = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(dev, &count, nullptr);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
VkQueueFamilyProperties get_queue_properties(uint32_t queue)
|
||||
{
|
||||
if (!queue_props.size())
|
||||
{
|
||||
uint32_t count = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(dev, &count, nullptr);
|
||||
|
||||
queue_props.resize(count);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(dev, &count, queue_props.data());
|
||||
}
|
||||
|
||||
if (queue >= queue_props.size()) fmt::throw_exception("Bad queue index passed to get_queue_properties (%u)" HERE, queue);
|
||||
return queue_props[queue];
|
||||
}
|
||||
|
||||
VkPhysicalDeviceMemoryProperties get_memory_properties() const
|
||||
{
|
||||
return memory_properties;
|
||||
}
|
||||
|
||||
operator VkPhysicalDevice() const
|
||||
{
|
||||
return dev;
|
||||
}
|
||||
};
|
||||
|
||||
class render_device
|
||||
{
|
||||
physical_device *pgpu = nullptr;
|
||||
memory_type_mapping memory_map{};
|
||||
gpu_formats_support m_formats_support{};
|
||||
std::unique_ptr<mem_allocator_base> m_allocator;
|
||||
VkDevice dev = VK_NULL_HANDLE;
|
||||
|
||||
public:
|
||||
render_device()
|
||||
{}
|
||||
|
||||
~render_device()
|
||||
{}
|
||||
|
||||
void create(vk::physical_device &pdev, uint32_t 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
|
||||
const char *requested_extensions[] =
|
||||
{
|
||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
||||
};
|
||||
|
||||
//Enable hardware features manually
|
||||
//Currently we require:
|
||||
//1. Anisotropic sampling
|
||||
//2. DXT support
|
||||
VkPhysicalDeviceFeatures available_features;
|
||||
vkGetPhysicalDeviceFeatures(*pgpu, &available_features);
|
||||
|
||||
available_features.samplerAnisotropy = VK_TRUE;
|
||||
available_features.textureCompressionBC = VK_TRUE;
|
||||
|
||||
VkDeviceCreateInfo device = {};
|
||||
device.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||
device.pNext = NULL;
|
||||
device.queueCreateInfoCount = 1;
|
||||
device.pQueueCreateInfos = &queue;
|
||||
device.enabledLayerCount = 0;
|
||||
device.ppEnabledLayerNames = nullptr; // Deprecated
|
||||
device.enabledExtensionCount = 1;
|
||||
device.ppEnabledExtensionNames = requested_extensions;
|
||||
device.pEnabledFeatures = &available_features;
|
||||
|
||||
CHECK_RESULT(vkCreateDevice(*pgpu, &device, nullptr, &dev));
|
||||
|
||||
memory_map = vk::get_memory_mapping(pdev);
|
||||
m_formats_support = vk::get_optimal_tiling_supported_formats(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 = {};
|
||||
}
|
||||
}
|
||||
|
||||
bool get_compatible_memory_type(u32 typeBits, u32 desired_mask, u32 *type_index) const
|
||||
{
|
||||
VkPhysicalDeviceMemoryProperties mem_infos = pgpu->get_memory_properties();
|
||||
|
||||
for (uint32_t i = 0; i < 32; i++)
|
||||
{
|
||||
if ((typeBits & 1) == 1)
|
||||
{
|
||||
if ((mem_infos.memoryTypes[i].propertyFlags & desired_mask) == desired_mask)
|
||||
{
|
||||
*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;
|
||||
}
|
||||
|
||||
mem_allocator_base* get_allocator() const
|
||||
{
|
||||
return m_allocator.get();
|
||||
}
|
||||
|
||||
operator VkDevice() const
|
||||
{
|
||||
return dev;
|
||||
}
|
||||
};
|
||||
|
||||
struct image
|
||||
{
|
||||
VkImage value = VK_NULL_HANDLE;
|
||||
@ -542,7 +559,7 @@ namespace vk
|
||||
VkImageCreateInfo info = {};
|
||||
std::shared_ptr<vk::memory_block> memory;
|
||||
|
||||
image(vk::render_device &dev,
|
||||
image(const vk::render_device &dev,
|
||||
uint32_t memory_type_index,
|
||||
uint32_t access_flags,
|
||||
VkImageType image_type,
|
||||
@ -1179,7 +1196,7 @@ public:
|
||||
public:
|
||||
swapchain_base(physical_device &gpu, uint32_t _present_queue, uint32_t _graphics_queue, VkFormat format = VK_FORMAT_B8G8R8A8_UNORM)
|
||||
{
|
||||
dev = render_device(gpu, _graphics_queue);
|
||||
dev.create(gpu, _graphics_queue);
|
||||
|
||||
if (_graphics_queue < UINT32_MAX) vkGetDeviceQueue(dev, _graphics_queue, 0, &vk_graphics_queue);
|
||||
if (_present_queue < UINT32_MAX) vkGetDeviceQueue(dev, _present_queue, 0, &vk_present_queue);
|
||||
|
Loading…
x
Reference in New Issue
Block a user