object: fill out object instantiation routines

This commit is contained in:
Danny Robson 2017-05-26 16:32:31 +10:00
parent b3f9668c6b
commit 7850699178
9 changed files with 279 additions and 23 deletions

View File

@ -24,6 +24,63 @@ using cruft::vk::error;
using cruft::vk::error_code; using cruft::vk::error_code;
///////////////////////////////////////////////////////////////////////////////
#define VK_RESULT_MAP(FUNC)\
MAP(FUNC, \
VK_SUCCESS, \
VK_NOT_READY, \
VK_TIMEOUT, \
VK_EVENT_SET, \
VK_EVENT_RESET, \
VK_INCOMPLETE, \
VK_ERROR_OUT_OF_HOST_MEMORY, \
VK_ERROR_OUT_OF_DEVICE_MEMORY, \
VK_ERROR_INITIALIZATION_FAILED, \
VK_ERROR_DEVICE_LOST, \
VK_ERROR_MEMORY_MAP_FAILED, \
VK_ERROR_LAYER_NOT_PRESENT, \
VK_ERROR_EXTENSION_NOT_PRESENT, \
VK_ERROR_FEATURE_NOT_PRESENT, \
VK_ERROR_INCOMPATIBLE_DRIVER, \
VK_ERROR_TOO_MANY_OBJECTS, \
VK_ERROR_FORMAT_NOT_SUPPORTED, \
VK_ERROR_FRAGMENTED_POOL)
///////////////////////////////////////////////////////////////////////////////
static constexpr
const char*
to_string (VkResult res)
{
switch (res) {
case VK_SUCCESS: return "success";
// partial successes
case VK_NOT_READY: return "not ready";
case VK_TIMEOUT: return "timeout";
case VK_EVENT_SET: return "event set";
case VK_EVENT_RESET: return "event reset";
case VK_INCOMPLETE: return "incomplete";
// errors
case VK_ERROR_OUT_OF_HOST_MEMORY: return "out of host memory";
case VK_ERROR_OUT_OF_DEVICE_MEMORY: return "out of device memory";
case VK_ERROR_INITIALIZATION_FAILED: return "initialization failed";
case VK_ERROR_DEVICE_LOST: return "device lost";
case VK_ERROR_MEMORY_MAP_FAILED: return "memory map failed";
case VK_ERROR_LAYER_NOT_PRESENT: return "layer not present";
case VK_ERROR_EXTENSION_NOT_PRESENT: return "extension not present";
case VK_ERROR_FEATURE_NOT_PRESENT: return "feature not present";
case VK_ERROR_INCOMPATIBLE_DRIVER: return "incompatible driver";
case VK_ERROR_TOO_MANY_OBJECTS: return "too many objects";
case VK_ERROR_FORMAT_NOT_SUPPORTED: return "format not supported";
case VK_ERROR_FRAGMENTED_POOL: return "fragmented pool";
}
unreachable ();
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
void void
error::try_code (VkResult res) error::try_code (VkResult res)
@ -39,29 +96,25 @@ error::try_code (VkResult res)
void void
error::throw_code (VkResult res) error::throw_code (VkResult res)
{ {
#define THROW_CODE(C) case C: throw error_code<C> ();
switch (res) { switch (res) {
case VK_SUCCESS: throw error_code<VK_SUCCESS> (); VK_RESULT_MAP (THROW_CODE)
// partial successes
case VK_NOT_READY: throw error_code<VK_NOT_READY> ();
case VK_TIMEOUT: throw error_code<VK_TIMEOUT> ();
case VK_EVENT_SET: throw error_code<VK_EVENT_SET> ();
case VK_EVENT_RESET: throw error_code<VK_EVENT_RESET> ();
case VK_INCOMPLETE: throw error_code<VK_INCOMPLETE> ();
// errors
case VK_ERROR_OUT_OF_HOST_MEMORY: throw error_code<VK_ERROR_OUT_OF_HOST_MEMORY> ();
case VK_ERROR_OUT_OF_DEVICE_MEMORY: throw error_code<VK_ERROR_OUT_OF_DEVICE_MEMORY> ();
case VK_ERROR_INITIALIZATION_FAILED: throw error_code<VK_ERROR_INITIALIZATION_FAILED> ();
case VK_ERROR_DEVICE_LOST: throw error_code<VK_ERROR_DEVICE_LOST> ();
case VK_ERROR_MEMORY_MAP_FAILED: throw error_code<VK_ERROR_MEMORY_MAP_FAILED> ();
case VK_ERROR_LAYER_NOT_PRESENT: throw error_code<VK_ERROR_LAYER_NOT_PRESENT> ();
case VK_ERROR_EXTENSION_NOT_PRESENT: throw error_code<VK_ERROR_EXTENSION_NOT_PRESENT> ();
case VK_ERROR_FEATURE_NOT_PRESENT: throw error_code<VK_ERROR_FEATURE_NOT_PRESENT> ();
case VK_ERROR_INCOMPATIBLE_DRIVER: throw error_code<VK_ERROR_INCOMPATIBLE_DRIVER> ();
case VK_ERROR_TOO_MANY_OBJECTS: throw error_code<VK_ERROR_TOO_MANY_OBJECTS> ();
case VK_ERROR_FORMAT_NOT_SUPPORTED: throw error_code<VK_ERROR_FORMAT_NOT_SUPPORTED> ();
} }
#undef THROW_CODE
unreachable (); unreachable ();
} }
///////////////////////////////////////////////////////////////////////////////
template <VkResult res>
const char*
error_code<res>::what (void) const noexcept
{
return to_string (res);
}
///////////////////////////////////////////////////////////////////////////////
#define ERROR_CODE(R) template class cruft::vk::error_code<R>;
VK_RESULT_MAP(ERROR_CODE)

16
fwd.hpp
View File

@ -20,6 +20,9 @@
#include "./vk.hpp" #include "./vk.hpp"
#include <cruft/util/preprocessor.hpp>
namespace cruft::vk { namespace cruft::vk {
template <typename T> struct instantiated; template <typename T> struct instantiated;
template <typename T> struct enumerated; template <typename T> struct enumerated;
@ -45,6 +48,19 @@ namespace cruft::vk {
class error; class error;
template <VkResult> class error_code; template <VkResult> class error_code;
#define VK_ENUMERATED_TYPE_MAP(FUNC) \
MAP(FUNC, \
physical_device)
#define VK_INSTANTIATED_TYPE_MAP(FUNC) \
MAP(FUNC, \
device, \
instance)
#define VK_TYPE_MAP(FUNC) \
VK_ENUMERATED_TYPE_MAP(FUNC) \
VK_INSTANTIATED_TYPE_MAP(FUNC)
} }
#endif #endif

View File

@ -21,6 +21,41 @@ using cruft::vk::instance;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
instance::create_info::create_info ()
{
sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
pNext = nullptr;
flags = 0;
pApplicationInfo = nullptr;
enabledLayerCount = 0;
ppEnabledLayerNames = nullptr;
enabledExtensionCount = 0;
ppEnabledExtensionNames = nullptr;
}
//-----------------------------------------------------------------------------
instance::instance (const VkInstanceCreateInfo &info): instance::instance (const VkInstanceCreateInfo &info):
instantiated (&info, nullptr) instantiated (&info, nullptr)
{ ; } { ; }
///////////////////////////////////////////////////////////////////////////////
std::set<std::string>
instance::extensions (void) const
{
uint32_t expected = 0;
error::try_code (vkEnumerateInstanceExtensionProperties (nullptr, &expected, nullptr));
VkExtensionProperties props[expected];
uint32_t found = expected;
error::try_code (vkEnumerateInstanceExtensionProperties (nullptr, &found, props));
std::set<std::string> ext;
for (const auto &i: props)
ext.insert (i.extensionName);
return ext;
}

View File

@ -23,9 +23,18 @@
#include "./vk.hpp" #include "./vk.hpp"
#include "./traits.hpp" #include "./traits.hpp"
#include <set>
#include <string>
namespace cruft::vk { namespace cruft::vk {
struct instance : public instantiated<instance> { struct instance : public instantiated<instance> {
struct create_info : public VkInstanceCreateInfo {
create_info ();
};
instance (const VkInstanceCreateInfo &info); instance (const VkInstanceCreateInfo &info);
std::set<std::string> extensions (void) const;
}; };
} }

View File

@ -17,5 +17,77 @@
#include "./object.hpp" #include "./object.hpp"
#include "./instance.hpp"
#include "./physical_device.hpp"
#include <cruft/util/debug.hpp>
using cruft::vk::object; using cruft::vk::object;
using cruft::vk::enumerated; using cruft::vk::enumerated;
///////////////////////////////////////////////////////////////////////////////
template <typename T>
object<T>::object (id_t _id):
m_id (_id)
{
CHECK_NEQ (m_id, VK_NULL_HANDLE);
}
//-----------------------------------------------------------------------------
template <typename T>
object<T>::object (object &&rhs):
m_id (VK_NULL_HANDLE)
{
std::swap (m_id, rhs.m_id);
}
//-----------------------------------------------------------------------------
template <typename T>
const typename object<T>::id_t&
object<T>::id (void) const&
{
return m_id;
}
//-----------------------------------------------------------------------------
template <typename T>
typename object<T>::id_t&
object<T>::id (void) &
{
return m_id;
}
//-----------------------------------------------------------------------------
#define OBJECT(T) template struct cruft::vk::object<cruft::vk::T>;
VK_TYPE_MAP (OBJECT)
///////////////////////////////////////////////////////////////////////////////
#define INSTANTIATED(T) template struct cruft::vk::instantiated<cruft::vk::T>;
VK_INSTANTIATED_TYPE_MAP (INSTANTIATED)
///////////////////////////////////////////////////////////////////////////////
template <typename T>
std::vector<T>
cruft::vk::enumerated<T>::find (const instance &inst) {
uint32_t expected = 0;
error::try_code (enum_traits<T>::enumerate (inst.id (), &expected, nullptr));
uint32_t found = expected;
typename T::id_t handles[expected];
error::try_code (enum_traits<T>::enumerate (inst.id (), &found, handles));
return std::vector<T> (handles, handles + found);
}
//-----------------------------------------------------------------------------
#define ENUMERATED(T) template struct cruft::vk::enumerated<cruft::vk::T>;
VK_ENUMERATED_TYPE_MAP (ENUMERATED)

View File

@ -22,6 +22,7 @@
#include "./except.hpp" #include "./except.hpp"
#include <utility> #include <utility>
#include <vector>
namespace cruft::vk { namespace cruft::vk {
template <typename T> template <typename T>
@ -29,8 +30,11 @@ namespace cruft::vk {
using id_t = typename id_traits<T>::id_t; using id_t = typename id_traits<T>::id_t;
object (id_t); object (id_t);
object (object&&);
object (const object&) = delete;
id_t& id (void) const&; const id_t& id (void) const&;
id_t& id (void) &;
private: private:
id_t m_id; id_t m_id;
@ -64,7 +68,11 @@ namespace cruft::vk {
}; };
template <typename T> template <typename T>
struct enumerated : public object<T> { }; struct enumerated : public object<T> {
using object<T>::object;
static std::vector<T> find (const instance&);
};
template <typename T, typename O> template <typename T, typename O>
struct owned : public object<T> { }; struct owned : public object<T> { };

View File

@ -19,4 +19,49 @@
#include "./except.hpp" #include "./except.hpp"
using cruft::vk::physical_device;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
std::set<std::string>
physical_device::extensions (void) const
{
uint32_t expected = 0;
error::try_code (vkEnumerateDeviceExtensionProperties (id (), nullptr, &expected, nullptr));
VkExtensionProperties props[expected];
uint32_t found = expected;
error::try_code (vkEnumerateDeviceExtensionProperties (id (), nullptr, &found, props));
std::set<std::string> ext;
for (const auto &i: props)
ext.insert (i.extensionName);
return ext;
}
///////////////////////////////////////////////////////////////////////////////
VkPhysicalDeviceProperties
physical_device::properties (void) const
{
VkPhysicalDeviceProperties props;
vkGetPhysicalDeviceProperties (id (), &props);
return props;
}
//-----------------------------------------------------------------------------
VkPhysicalDeviceFeatures
physical_device::features (void) const
{
VkPhysicalDeviceFeatures feat;
vkGetPhysicalDeviceFeatures (id (), &feat);
return feat;
}
///////////////////////////////////////////////////////////////////////////////
std::string
physical_device::name (void) const
{
return properties ().deviceName;
}

View File

@ -22,8 +22,19 @@
#include "./vk.hpp" #include "./vk.hpp"
#include <set>
#include <string>
namespace cruft::vk { namespace cruft::vk {
struct physical_device : public enumerated<physical_device> { struct physical_device : public enumerated<physical_device> {
using enumerated::enumerated;
std::set<std::string> extensions (void) const;
VkPhysicalDeviceProperties properties (void) const;
VkPhysicalDeviceFeatures features (void) const;
std::string name (void) const;
}; };
} }

View File

@ -126,7 +126,14 @@ namespace cruft::vk {
template <> struct life_traits<buffer_view> { template <> struct life_traits<buffer_view> {
static constexpr auto create = vkCreateBufferView; static constexpr auto create = vkCreateBufferView;
};
///////////////////////////////////////////////////////////////////////////
template <typename T> struct enum_traits { };
template <> struct enum_traits<physical_device> {
static constexpr auto enumerate = vkEnumeratePhysicalDevices;
}; };
} }