Fix OOM issue

Fixes an issue where there was a chance that an exception would be
thrown when out of memory rather than returning an
appropriate VkResult code.

Additionally introduces a noncopyable utility class that can be used to
mark classes that should not have copy semantics

Change-Id: I1f84dc9bb1ea96db2a88a90d56adbee78b17c5e3
Signed-off-by: Normunds Rieksts <normunds.rieksts@arm.com>
This commit is contained in:
Normunds Rieksts 2021-11-08 17:53:12 +00:00 committed by Matteo Franchin
parent a7a53ef092
commit 86fa15a8a2
10 changed files with 36 additions and 35 deletions

View file

@ -30,6 +30,8 @@
#include <vulkan/vulkan.h>
#include "helpers.hpp"
#pragma once
namespace util
@ -280,7 +282,7 @@ util::unique_ptr<T> allocator::make_unique(Args &&...args) const noexcept
* vector.
*/
template <typename T>
class vector : public std::vector<T, custom_allocator<T>>
class vector : public std::vector<T, custom_allocator<T>>, private noncopyable
{
public:
using base = std::vector<T, custom_allocator<T>>;

View file

@ -23,7 +23,8 @@
*/
#pragma once
#include "util/custom_allocator.hpp"
#include "custom_allocator.hpp"
#include "helpers.hpp"
#include <vector>
#include <algorithm>
@ -38,14 +39,11 @@ namespace util
*
* @note This class does not store the extension versions.
*/
class extension_list
class extension_list : private noncopyable
{
public:
extension_list(const util::allocator& allocator);
extension_list(const extension_list &rhs) = delete;
const extension_list &operator=(const extension_list &rhs) = delete;
/**
* @brief Get the allocator used to manage the memory of this object.
*/

View file

@ -33,13 +33,15 @@
#include <unistd.h>
#include <utility>
#include "helpers.hpp"
namespace util
{
/**
* Manages a POSIX file descriptor.
*/
class fd_owner
class fd_owner : private noncopyable
{
public:
@ -49,9 +51,6 @@ public:
{
}
fd_owner(const fd_owner &) = delete;
fd_owner &operator=(const fd_owner &) = delete;
fd_owner(fd_owner &&rhs)
{
*this = std::move(rhs);

View file

@ -44,4 +44,15 @@ const T *find_extension(VkStructureType sType, const void *pNext)
}
return reinterpret_cast<const T *>(entry);
}
class noncopyable
{
protected:
noncopyable() = default;
~noncopyable() = default;
private:
noncopyable(const noncopyable &) = delete;
noncopyable& operator=(const noncopyable &) = delete;
};
} // namespace util

View file

@ -24,18 +24,16 @@
#pragma once
#include <cassert>
#include "helpers.hpp"
namespace util
{
template <typename T>
class optional
class optional : private noncopyable
{
public:
using value_type = T;
optional(const optional &) = delete;
optional &operator=(const optional &) = delete;
/**
* @brief Construct an empty optional object.
*/

View file

@ -45,6 +45,7 @@ extern "C"
}
#include <vulkan/vulkan.h>
#include "helpers.hpp"
namespace util
{
@ -61,13 +62,9 @@ namespace util
*
* This code does not use the C++ standard library to avoid exceptions.
*/
class timed_semaphore
class timed_semaphore : private noncopyable
{
public:
/* copying not implemented */
timed_semaphore &operator=(const timed_semaphore &) = delete;
timed_semaphore(const timed_semaphore &) = delete;
~timed_semaphore();
timed_semaphore()
: initialized(false){};

View file

@ -26,6 +26,7 @@
#include <unordered_map>
#include "custom_allocator.hpp"
#include "optional.hpp"
#include "helpers.hpp"
namespace util
{
@ -39,7 +40,7 @@ template <typename Key, typename Value,
typename Hash = std::hash<Key>,
typename Comparator = std::equal_to<Key>,
typename Allocator = util::custom_allocator<std::pair<const Key, Value>>>
class unordered_map : public std::unordered_map<Key, Value, Hash, Comparator, Allocator>
class unordered_map : public std::unordered_map<Key, Value, Hash, Comparator, Allocator>, private noncopyable
{
using base = std::unordered_map<Key, Value, Hash, Comparator, Allocator>;
using size_type = typename base::size_type;
@ -52,9 +53,6 @@ public:
Value &operator[](const Key &key) = delete;
Value &operator[](Key &&key) = delete;
unordered_map(const unordered_map &) = delete;
unordered_map &operator=(const unordered_map &) = delete;
void insert() = delete;
void emplace() = delete;
void emplace_hint() = delete;

View file

@ -26,6 +26,7 @@
#include <unordered_set>
#include "custom_allocator.hpp"
#include "optional.hpp"
#include "helpers.hpp"
namespace util
{
@ -39,7 +40,7 @@ template <typename Key,
typename Hash = std::hash<Key>,
typename Comparator = std::equal_to<Key>,
typename Allocator = util::custom_allocator<Key>>
class unordered_set : public std::unordered_set<Key, Hash, Comparator, Allocator>
class unordered_set : public std::unordered_set<Key, Hash, Comparator, Allocator>, private noncopyable
{
using value_type = Key;
using base = std::unordered_set<Key, Hash, Comparator, Allocator>;
@ -50,9 +51,6 @@ public:
/**
* Delete all member functions that can cause allocation failure by throwing std::bad_alloc.
*/
unordered_set(const unordered_set &) = delete;
unordered_set &operator=(const unordered_set &) = delete;
void insert() = delete;
void emplace() = delete;
void emplace_hint() = delete;

View file

@ -399,8 +399,8 @@ VkResult swapchain::create_aliased_image_handle(const VkImageCreateInfo *image_c
get_allocation_callbacks(), image);
}
VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, wayland_image_data *image_data,
util::vector<wsialloc_format> importable_formats,
VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, wayland_image_data &image_data,
util::vector<wsialloc_format> &importable_formats,
wsialloc_format *allocated_format)
{
bool is_protected_memory = (image_create_info.flags & VK_IMAGE_CREATE_PROTECTED_BIT) != 0;
@ -408,8 +408,8 @@ VkResult swapchain::allocate_wsialloc(VkImageCreateInfo &image_create_info, wayl
wsialloc_allocate_info alloc_info = { importable_formats.data(), static_cast<unsigned>(importable_formats.size()),
image_create_info.extent.width, image_create_info.extent.height,
allocation_flags };
const auto res = wsialloc_alloc(m_wsi_allocator, &alloc_info, allocated_format, image_data->stride,
image_data->buffer_fd, image_data->offset);
const auto res = wsialloc_alloc(m_wsi_allocator, &alloc_info, allocated_format, image_data.stride,
image_data.buffer_fd, image_data.offset);
if (res != WSIALLOC_ERROR_NONE)
{
WSI_LOG_ERROR("Failed allocation of DMA Buffer. WSI error: %d", static_cast<int>(res));
@ -443,7 +443,7 @@ VkResult swapchain::allocate_image(VkImageCreateInfo &image_create_info, wayland
{
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
VkResult result = allocate_wsialloc(m_image_create_info, image_data, importable_formats, &m_allocated_format);
VkResult result = allocate_wsialloc(m_image_create_info, *image_data, importable_formats, &m_allocated_format);
if (result != VK_SUCCESS)
{
return result;
@ -474,7 +474,7 @@ VkResult swapchain::allocate_image(VkImageCreateInfo &image_create_info, wayland
}
wsialloc_format allocated_format = { 0 };
result = allocate_wsialloc(image_create_info, image_data, importable_formats, &allocated_format);
result = allocate_wsialloc(image_create_info, *image_data, importable_formats, &allocated_format);
if (result != VK_SUCCESS)
{
return result;

View file

@ -163,8 +163,8 @@ private:
struct wayland_image_data;
VkResult allocate_image(VkImageCreateInfo &image_create_info, wayland_image_data *image_data, VkImage *image);
VkResult allocate_wsialloc(VkImageCreateInfo &image_create_info, wayland_image_data *image_data,
util::vector<wsialloc_format> importable_formats, wsialloc_format *allocated_format);
VkResult allocate_wsialloc(VkImageCreateInfo &image_create_info, wayland_image_data &image_data,
util::vector<wsialloc_format> &importable_formats, wsialloc_format *allocated_format);
VkResult internal_bind_swapchain_image(VkDevice &device, wayland_image_data *swapchain_image,
const VkImage &image);