build: expanded API coverage

This commit is contained in:
Danny Robson 2017-09-05 17:20:17 +10:00
parent 116ed2044d
commit 2224b781f2
15 changed files with 224 additions and 39 deletions

View File

@ -7,14 +7,9 @@ include (nc)
############################################################################### ###############################################################################
include (FindVulkan) find_package (Vulkan REQUIRED)
if (NOT Vulkan_FOUND)
message (FATAL_ERROR "Vulkan client library not found")
endif ()
##-----------------------------------------------------------------------------
find_package (PythonInterp 3 REQUIRED) find_package (PythonInterp 3 REQUIRED)
find_package (glfw3 REQUIRED)
############################################################################### ###############################################################################
@ -99,7 +94,7 @@ endif ()
############################################################################### ###############################################################################
foreach (t info) foreach (t info hello)
add_executable (vk_${t} "tools/${t}.cpp") add_executable (vk_${t} "tools/${t}.cpp")
set_target_properties(vk_${t} PROPERTIES set_target_properties(vk_${t} PROPERTIES
OUTPUT_NAME OUTPUT_NAME
@ -107,7 +102,7 @@ foreach (t info)
set_target_properties(vk_${t} PROPERTIES set_target_properties(vk_${t} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/tools") "${CMAKE_CURRENT_BINARY_DIR}/tools")
target_link_libraries (vk_${t} cruft-vk) target_link_libraries (vk_${t} cruft-vk glfw)
endforeach () endforeach ()
############################################################################### ###############################################################################

View File

@ -18,6 +18,7 @@
#include "./device.hpp" #include "./device.hpp"
#include "./physical_device.hpp" #include "./physical_device.hpp"
#include "./queue.hpp"
#include <cruft/util/cast.hpp> #include <cruft/util/cast.hpp>
#include <cruft/util/debug.hpp> #include <cruft/util/debug.hpp>
@ -28,7 +29,7 @@ using cruft::vk::device;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
device::device (const physical_device &phys, device::device (const physical_device &phys,
const VkDeviceCreateInfo &info): const VkDeviceCreateInfo &info):
instantiated (phys.id (), &info, nullptr) descendant (phys, &info, nullptr)
{ ; } { ; }
@ -42,6 +43,14 @@ device::physical_properties (void) const
} }
///////////////////////////////////////////////////////////////////////////////
cruft::vk::queue
device::queue (uint32_t id)
{
return ::cruft::vk::queue (*this, id, 0);
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
void void
device::flush (const VkMappedMemoryRange *first, device::flush (const VkMappedMemoryRange *first,

View File

@ -23,13 +23,15 @@
#include "./fwd.hpp" #include "./fwd.hpp"
namespace cruft::vk { namespace cruft::vk {
struct device : public instantiated<device> { struct device : public descendant<device> {
device (const physical_device&, device (const physical_device&,
const VkDeviceCreateInfo&); const VkDeviceCreateInfo&);
VkPhysicalDeviceMemoryProperties VkPhysicalDeviceMemoryProperties
physical_properties (void) const; physical_properties (void) const;
struct queue queue (uint32_t id);
void flush (const VkMappedMemoryRange *first, void flush (const VkMappedMemoryRange *first,
const VkMappedMemoryRange *last); const VkMappedMemoryRange *last);

View File

@ -43,8 +43,7 @@ using cruft::vk::error_code;
VK_ERROR_FEATURE_NOT_PRESENT, \ VK_ERROR_FEATURE_NOT_PRESENT, \
VK_ERROR_INCOMPATIBLE_DRIVER, \ VK_ERROR_INCOMPATIBLE_DRIVER, \
VK_ERROR_TOO_MANY_OBJECTS, \ VK_ERROR_TOO_MANY_OBJECTS, \
VK_ERROR_FORMAT_NOT_SUPPORTED, \ VK_ERROR_FORMAT_NOT_SUPPORTED)
VK_ERROR_FRAGMENTED_POOL)
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -74,7 +73,6 @@ to_string (VkResult res)
case VK_ERROR_INCOMPATIBLE_DRIVER: return "incompatible driver"; case VK_ERROR_INCOMPATIBLE_DRIVER: return "incompatible driver";
case VK_ERROR_TOO_MANY_OBJECTS: return "too many objects"; case VK_ERROR_TOO_MANY_OBJECTS: return "too many objects";
case VK_ERROR_FORMAT_NOT_SUPPORTED: return "format not supported"; case VK_ERROR_FORMAT_NOT_SUPPORTED: return "format not supported";
case VK_ERROR_FRAGMENTED_POOL: return "fragmented pool";
} }
unreachable (); unreachable ();

View File

@ -30,6 +30,23 @@ namespace cruft::vk {
}; };
class invalid_argument : public error {
public:
invalid_argument (const char *_what) noexcept:
m_what (_what)
{ ; }
const char*
what (void) const noexcept override
{
return m_what;
}
private:
const char *m_what;
};
template <VkResult> template <VkResult>
class error_code : public error { class error_code : public error {
public: public:

15
fwd.hpp
View File

@ -24,7 +24,7 @@
namespace cruft::vk { namespace cruft::vk {
template <typename T> struct instantiated; template <typename T> struct descendant;
template <typename T> struct enumerated; template <typename T> struct enumerated;
template <typename T, typename O> struct owned; template <typename T, typename O> struct owned;
@ -53,14 +53,19 @@ namespace cruft::vk {
MAP(FUNC, \ MAP(FUNC, \
physical_device) physical_device)
#define VK_INSTANTIATED_TYPE_MAP(FUNC) \ #define VK_DESCENDANT_TYPE_MAP(FUNC) \
MAP(FUNC, \ MAP(FUNC, \
device, \ device)
instance)
#define VK_OWNED_TYPE_MAP(FUNC) \
MAP(FUNC, \
queue)
#define VK_TYPE_MAP(FUNC) \ #define VK_TYPE_MAP(FUNC) \
MAP(FUNC,instance) \
VK_ENUMERATED_TYPE_MAP(FUNC) \ VK_ENUMERATED_TYPE_MAP(FUNC) \
VK_INSTANTIATED_TYPE_MAP(FUNC) VK_DESCENDANT_TYPE_MAP(FUNC) \
VK_OWNED_TYPE_MAP(FUNC)
} }
#endif #endif

View File

@ -57,11 +57,28 @@ instance::instance ():
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
instance::instance (const create_info_t &info): instance::instance (const util::view<const char **> layers,
instantiated (&info, nullptr) const util::view<const char **> extensions):
instance (VkInstanceCreateInfo {
.sType = cruft::vk::structure_type_v<VkInstanceCreateInfo>,
.pNext = nullptr,
.flags = {},
.pApplicationInfo = nullptr,
.enabledLayerCount = static_cast<uint32_t> (layers.size ()),
.ppEnabledLayerNames = layers.data (),
.enabledExtensionCount = static_cast<uint32_t> (extensions.size ()),
.ppEnabledExtensionNames = extensions.data ()
})
{ ; } { ; }
//-----------------------------------------------------------------------------
instance::instance (const create_info_t &info):
root (&info, nullptr)
{ ; }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
std::set<std::string> std::set<std::string>
instance::extensions (void) const instance::extensions (void) const
@ -78,3 +95,17 @@ instance::extensions (void) const
ext.insert (i.extensionName); ext.insert (i.extensionName);
return ext; return ext;
} }
///////////////////////////////////////////////////////////////////////////////
std::vector<VkLayerProperties>
instance::available_layers (void)
{
uint32_t count;
vk::error::try_code (vkEnumerateInstanceLayerProperties (&count, nullptr));
std::vector<VkLayerProperties> layers (count);
vk::error::try_code (vkEnumerateInstanceLayerProperties (&count, layers.data ()));
return layers;
}

View File

@ -22,12 +22,15 @@
#include "./vk.hpp" #include "./vk.hpp"
#include "./traits.hpp" #include "./traits.hpp"
#include "./except.hpp"
#include <cruft/util/view.hpp>
#include <set> #include <set>
#include <string> #include <string>
namespace cruft::vk { namespace cruft::vk {
struct instance : public instantiated<instance> { struct instance : public root<instance> {
struct create_info_t : public VkInstanceCreateInfo { struct create_info_t : public VkInstanceCreateInfo {
create_info_t (); create_info_t ();
create_info_t (const VkInstanceCreateInfo&); create_info_t (const VkInstanceCreateInfo&);
@ -39,9 +42,24 @@ namespace cruft::vk {
}; };
instance (); instance ();
instance (util::view<const char**> layers,
util::view<const char**> extensions);
instance (const create_info_t &info); instance (const create_info_t &info);
template <typename T>
T
proc (const char *name)
{
auto ret = vkGetInstanceProcAddr (id (), name);
if (!ret)
throw vk::invalid_argument ("invalid procedure name");
return reinterpret_cast<T> (ret);
}
std::set<std::string> extensions (void) const; std::set<std::string> extensions (void) const;
static std::vector<VkLayerProperties> available_layers (void);
}; };
} }

View File

@ -69,8 +69,8 @@ VK_TYPE_MAP (OBJECT)
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define INSTANTIATED(T) template struct cruft::vk::instantiated<cruft::vk::T>; #define DESCENDANT(T) template struct cruft::vk::descendant<cruft::vk::T>;
VK_INSTANTIATED_TYPE_MAP (INSTANTIATED) VK_DESCENDANT_TYPE_MAP (DESCENDANT)
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -43,30 +43,57 @@ namespace cruft::vk {
}; };
template <typename SelfT>
struct root : public object<SelfT> {
using id_t = typename object<SelfT>::id_t;
template <typename ...Args>
root (Args &&...args):
object<SelfT> (make (std::forward<Args> (args)...))
{ ; }
~root ()
{
life_traits<SelfT>::destroy (this->id (), nullptr);
}
private:
template <typename ...Args>
static id_t
make (Args &&...args)
{
id_t id;
auto res = life_traits<SelfT>::create (std::forward<Args> (args)..., &id);
error::try_code (res);
return id;
}
};
/// a vulkan object that must be directly instantiated through /// a vulkan object that must be directly instantiated through
/// constructor arguments, rather than being enumerated and owned by /// constructor arguments, rather than being enumerated and owned by
/// another object. /// another object.
template <typename T> template <typename T>
struct instantiated : public object<T> { struct descendant : public object<T> {
using id_t = typename object<T>::id_t; using id_t = typename object<T>::id_t;
template <typename ...Args> template <typename ...Args>
instantiated (Args &&...args): descendant (Args &&...args):
object<T> (make (std::forward<Args> (args)...)) object<T> (make (std::forward<Args> (args)...))
{ ; } { ; }
~instantiated () ~descendant ()
{ {
life_traits<T>::destroy (this->id (), nullptr); life_traits<T>::destroy (this->id (), nullptr);
} }
private: private:
template <typename ...Args> template <typename Base, typename ...Args>
static static
id_t make (Args &&...args) id_t make (Base &&base, Args &&...args)
{ {
id_t id; id_t id;
auto res = life_traits<T>::create (std::forward<Args> (args)..., &id); auto res = life_traits<T>::create (base.id (), std::forward<Args> (args)..., &id);
error::try_code (res); error::try_code (res);
return id; return id;
} }
@ -86,8 +113,26 @@ namespace cruft::vk {
/// ///
/// typically implies that this object must be freed using a reference to /// typically implies that this object must be freed using a reference to
/// the parent object. /// the parent object.
template <typename T, typename O> template <typename SelfT, typename OwnerT>
struct owned : public object<T> { }; struct owned : public object<SelfT> {
using id_t = typename object<SelfT>::id_t;
using object<SelfT>::object;
template <typename ...Args>
owned (Args &&...args):
object<SelfT> (make (std::forward<Args> (args)...))
{ ; }
private:
template <typename ...Args>
static
id_t make (OwnerT &owner, Args &&...args)
{
id_t id;
life_traits<SelfT>::get (owner.id (), std::forward<Args> (args)..., &id);
return id;
}
};
} }
#endif #endif

View File

@ -93,6 +93,18 @@ cruft::vk::operator<< (std::ostream &os, const instance &i)
} }
///////////////////////////////////////////////////////////////////////////////
std::ostream&
operator<< (std::ostream &os, const VkLayerProperties &val)
{
return os << "{ name: '" << val.layerName << "'"
<< ", specVersion: " << val.specVersion
<< ", implementationVersion: " << val.implementationVersion
<< ", description: '" << val.description << "'"
<< " }";
};
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
std::ostream& std::ostream&
operator<< (std::ostream &os, VkPhysicalDeviceType t) operator<< (std::ostream &os, VkPhysicalDeviceType t)

View File

@ -33,10 +33,13 @@ std::ostream& operator<< (std::ostream&, VkPhysicalDeviceType);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
std::ostream& operator<< (std::ostream&, const VkQueueFamilyProperties&); std::ostream& operator<< (std::ostream&, const VkLayerProperties&);
std::ostream& operator<< (std::ostream&, const VkPhysicalDeviceLimits&); std::ostream& operator<< (std::ostream&, const VkPhysicalDeviceLimits&);
std::ostream& operator<< (std::ostream&, const VkPhysicalDeviceProperties&); std::ostream& operator<< (std::ostream&, const VkPhysicalDeviceProperties&);
std::ostream& operator<< (std::ostream&, const VkQueueFamilyProperties&);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
namespace cruft::vk { namespace cruft::vk {

View File

@ -23,6 +23,8 @@
namespace cruft::vk { namespace cruft::vk {
struct queue : public owned<queue,device> { struct queue : public owned<queue,device> {
using owned<queue,device>::owned;
void wait_idle (void); void wait_idle (void);
template <typename T> template <typename T>

View File

@ -15,16 +15,23 @@
* 2017, Danny Robson <danny@nerdcruft.net> * 2017, Danny Robson <danny@nerdcruft.net>
*/ */
#include <cruft/util/iterator.hpp>
#include <cruft/vk/instance.hpp> #include <cruft/vk/instance.hpp>
#include <cruft/vk/physical_device.hpp> #include <cruft/vk/physical_device.hpp>
#include <cruft/vk/ostream.hpp> #include <cruft/vk/ostream.hpp>
#include <iostream> #include <iostream>
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
int int
main (int, char**) main (int, char**)
{ {
std::cout << "available_layers: [ "
<< util::make_infix (cruft::vk::instance::available_layers ())
<< " ]\n";
cruft::vk::instance instance; cruft::vk::instance instance;
std::cout << "instance: " << instance << '\n'; std::cout << "instance: " << instance << '\n';

View File

@ -34,10 +34,20 @@ namespace cruft::vk {
#define DEFINE_STRUCTURE_TYPE(KLASS,VALUE) \ #define DEFINE_STRUCTURE_TYPE(KLASS,VALUE) \
template <> \ template <> \
struct structure_type<KLASS> : \ struct structure_type<KLASS> : \
public std::integral_constant<VkStructureType, VALUE> \ public std::integral_constant< \
VkStructureType, \
PASTE(VK_STRUCTURE_TYPE_,VALUE) \
> \
{ } { }
DEFINE_STRUCTURE_TYPE (VkInstanceCreateInfo, VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO); DEFINE_STRUCTURE_TYPE (VkInstanceCreateInfo, INSTANCE_CREATE_INFO);
DEFINE_STRUCTURE_TYPE (VkApplicationInfo, APPLICATION_INFO);
DEFINE_STRUCTURE_TYPE (VkDeviceQueueCreateInfo, DEVICE_QUEUE_CREATE_INFO);
DEFINE_STRUCTURE_TYPE (VkDeviceCreateInfo, DEVICE_CREATE_INFO);
DEFINE_STRUCTURE_TYPE (VkSwapchainCreateInfoKHR, SWAPCHAIN_CREATE_INFO_KHR);
DEFINE_STRUCTURE_TYPE (VkImageViewCreateInfo, IMAGE_VIEW_CREATE_INFO);
DEFINE_STRUCTURE_TYPE (VkShaderModuleCreateInfo, SHADER_MODULE_CREATE_INFO);
DEFINE_STRUCTURE_TYPE (VkPipelineShaderStageCreateInfo, PIPELINE_SHADER_STAGE_CREATE_INFO);
#undef DEFINE_STRUCTURE_TYPE #undef DEFINE_STRUCTURE_TYPE
@ -47,6 +57,28 @@ namespace cruft::vk {
constexpr auto structure_type_v = structure_type<T>::value; constexpr auto structure_type_v = structure_type<T>::value;
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct create_info { };
//-------------------------------------------------------------------------
#define DEFINE_CREATE_INFO(TARGET,INFO) \
template <> \
struct create_info<TARGET> \
{ using type = INFO; }
DEFINE_CREATE_INFO (VkImageViewCreateInfo, VkImageViewCreateInfo);
DEFINE_CREATE_INFO (VkShaderModule, VkShaderModuleCreateInfo);
#undef DEFINE_CREATE_INFO
//-------------------------------------------------------------------------
template <typename T>
using create_info_t = typename create_info<T>::type;
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template <typename T> struct id_traits { }; template <typename T> struct id_traits { };
@ -117,6 +149,11 @@ namespace cruft::vk {
static constexpr auto destroy = vkDestroyShaderModule; static constexpr auto destroy = vkDestroyShaderModule;
}; };
template <>
struct life_traits<queue> {
static constexpr auto get = vkGetDeviceQueue;
};
template <VkPipelineBindPoint> struct create_traits { }; template <VkPipelineBindPoint> struct create_traits { };
template <> struct create_traits<VK_PIPELINE_BIND_POINT_COMPUTE> { template <> struct create_traits<VK_PIPELINE_BIND_POINT_COMPUTE> {
static constexpr auto func = vkCreateComputePipelines; static constexpr auto func = vkCreateComputePipelines;
@ -160,6 +197,10 @@ namespace cruft::vk {
template <> struct enum_traits<physical_device> { template <> struct enum_traits<physical_device> {
static constexpr auto enumerate = vkEnumeratePhysicalDevices; static constexpr auto enumerate = vkEnumeratePhysicalDevices;
}; };
///////////////////////////////////////////////////////////////////////////
template <typename T> struct format_traits {};
} }
#endif #endif