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)
if (NOT Vulkan_FOUND)
message (FATAL_ERROR "Vulkan client library not found")
endif ()
##-----------------------------------------------------------------------------
find_package(PythonInterp 3 REQUIRED)
find_package (Vulkan 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")
set_target_properties(vk_${t} PROPERTIES
OUTPUT_NAME
@ -107,7 +102,7 @@ foreach (t info)
set_target_properties(vk_${t} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/tools")
target_link_libraries (vk_${t} cruft-vk)
target_link_libraries (vk_${t} cruft-vk glfw)
endforeach ()
###############################################################################

View File

@ -18,6 +18,7 @@
#include "./device.hpp"
#include "./physical_device.hpp"
#include "./queue.hpp"
#include <cruft/util/cast.hpp>
#include <cruft/util/debug.hpp>
@ -28,7 +29,7 @@ using cruft::vk::device;
///////////////////////////////////////////////////////////////////////////////
device::device (const physical_device &phys,
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
device::flush (const VkMappedMemoryRange *first,

View File

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

View File

@ -43,8 +43,7 @@ using cruft::vk::error_code;
VK_ERROR_FEATURE_NOT_PRESENT, \
VK_ERROR_INCOMPATIBLE_DRIVER, \
VK_ERROR_TOO_MANY_OBJECTS, \
VK_ERROR_FORMAT_NOT_SUPPORTED, \
VK_ERROR_FRAGMENTED_POOL)
VK_ERROR_FORMAT_NOT_SUPPORTED)
///////////////////////////////////////////////////////////////////////////////
@ -74,7 +73,6 @@ to_string (VkResult res)
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 ();

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>
class error_code : public error {
public:

15
fwd.hpp
View File

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

View File

@ -57,11 +57,28 @@ instance::instance ():
//-----------------------------------------------------------------------------
instance::instance (const create_info_t &info):
instantiated (&info, nullptr)
instance::instance (const util::view<const char **> layers,
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>
instance::extensions (void) const
@ -78,3 +95,17 @@ instance::extensions (void) const
ext.insert (i.extensionName);
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 "./traits.hpp"
#include "./except.hpp"
#include <cruft/util/view.hpp>
#include <set>
#include <string>
namespace cruft::vk {
struct instance : public instantiated<instance> {
struct instance : public root<instance> {
struct create_info_t : public VkInstanceCreateInfo {
create_info_t ();
create_info_t (const VkInstanceCreateInfo&);
@ -39,9 +42,24 @@ namespace cruft::vk {
};
instance ();
instance (util::view<const char**> layers,
util::view<const char**> extensions);
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;
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>;
VK_INSTANTIATED_TYPE_MAP (INSTANTIATED)
#define DESCENDANT(T) template struct cruft::vk::descendant<cruft::vk::T>;
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
/// constructor arguments, rather than being enumerated and owned by
/// another object.
template <typename T>
struct instantiated : public object<T> {
struct descendant : public object<T> {
using id_t = typename object<T>::id_t;
template <typename ...Args>
instantiated (Args &&...args):
descendant (Args &&...args):
object<T> (make (std::forward<Args> (args)...))
{ ; }
~instantiated ()
~descendant ()
{
life_traits<T>::destroy (this->id (), nullptr);
}
private:
template <typename ...Args>
template <typename Base, typename ...Args>
static
id_t make (Args &&...args)
id_t make (Base &&base, Args &&...args)
{
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);
return id;
}
@ -86,8 +113,26 @@ namespace cruft::vk {
///
/// typically implies that this object must be freed using a reference to
/// the parent object.
template <typename T, typename O>
struct owned : public object<T> { };
template <typename SelfT, typename OwnerT>
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

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&
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 VkPhysicalDeviceProperties&);
std::ostream& operator<< (std::ostream&, const VkQueueFamilyProperties&);
///////////////////////////////////////////////////////////////////////////////
namespace cruft::vk {

View File

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

View File

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

View File

@ -34,10 +34,20 @@ namespace cruft::vk {
#define DEFINE_STRUCTURE_TYPE(KLASS,VALUE) \
template <> \
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
@ -47,6 +57,28 @@ namespace cruft::vk {
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 { };
@ -117,6 +149,11 @@ namespace cruft::vk {
static constexpr auto destroy = vkDestroyShaderModule;
};
template <>
struct life_traits<queue> {
static constexpr auto get = vkGetDeviceQueue;
};
template <VkPipelineBindPoint> struct create_traits { };
template <> struct create_traits<VK_PIPELINE_BIND_POINT_COMPUTE> {
static constexpr auto func = vkCreateComputePipelines;
@ -160,6 +197,10 @@ namespace cruft::vk {
template <> struct enum_traits<physical_device> {
static constexpr auto enumerate = vkEnumeratePhysicalDevices;
};
///////////////////////////////////////////////////////////////////////////
template <typename T> struct format_traits {};
}
#endif