diff --git a/doc/vulkan-mapping.dox b/doc/vulkan-mapping.dox index f3453b144..afe1d23e8 100644 --- a/doc/vulkan-mapping.dox +++ b/doc/vulkan-mapping.dox @@ -121,7 +121,7 @@ Vulkan function | Matching API @fn_vk{CmdUpdateBuffer} | | @fn_vk{CmdWaitEvents} | | @fn_vk{CmdWriteTimestamp} | | -@fn_vk{CreateBuffer}, \n @fn_vk{DestroyBuffer} | | +@fn_vk{CreateBuffer}, \n @fn_vk{DestroyBuffer} | @ref Buffer constructor and destructor @fn_vk{CreateBufferView}, \n @fn_vk{DestroyBufferView} | | @fn_vk{CreateCommandPool}, \n @fn_vk{DestroyCommandPool} | @ref CommandPool constructor and destructor @fn_vk{CreateComputePipelines}, \n @fn_vk{DestroyComputePipelines} | | @@ -304,6 +304,14 @@ Vulkan structure | Matching API --------------------------------------- | ------------ @type_vk{ApplicationInfo} | @ref InstanceCreateInfo +@subsection vulkan-mapping-structures-b B + +@m_class{m-fullwidth} + +Vulkan structure | Matching API +--------------------------------------- | ------------ +@type_vk{BufferCreateInfo} | @ref BufferCreateInfo + @subsection vulkan-mapping-structures-c C @m_class{m-fullwidth} diff --git a/src/Magnum/Vk/Buffer.cpp b/src/Magnum/Vk/Buffer.cpp new file mode 100644 index 000000000..d8ab43676 --- /dev/null +++ b/src/Magnum/Vk/Buffer.cpp @@ -0,0 +1,88 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "Buffer.h" + +#include "Magnum/Vk/Assert.h" +#include "Magnum/Vk/Device.h" +#include "Magnum/Vk/Handle.h" + +namespace Magnum { namespace Vk { + +BufferCreateInfo::BufferCreateInfo(const BufferUsages usages, const UnsignedLong size, const Flags flags): _info{} { + _info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + _info.flags = VkBufferCreateFlags(flags); + _info.size = size; + _info.usage = VkBufferUsageFlags(usages); + /* _info.sharingMode is implicitly VK_SHARING_MODE_EXCLUSIVE; + _info.queueFamilyIndexCount and _info.pQueueFamilyIndices should be + filled only for VK_SHARING_MODE_CONCURRENT */ +} + +BufferCreateInfo::BufferCreateInfo(NoInitT) noexcept {} + +BufferCreateInfo::BufferCreateInfo(const VkBufferCreateInfo& info): + /* Can't use {} with GCC 4.8 here because it tries to initialize the first + member instead of doing a copy */ + _info(info) {} + +Buffer Buffer::wrap(Device& device, const VkBuffer handle, const HandleFlags flags) { + Buffer out{NoCreate}; + out._device = &device; + out._handle = handle; + out._flags = flags; + return out; +} + +Buffer::Buffer(Device& device, const BufferCreateInfo& info, NoAllocateT): _device{&device}, _flags{HandleFlag::DestroyOnDestruction} { + MAGNUM_VK_INTERNAL_ASSERT_SUCCESS(device->CreateBuffer(device, info, nullptr, &_handle)); +} + +Buffer::Buffer(NoCreateT): _device{}, _handle{} {} + +Buffer::Buffer(Buffer&& other) noexcept: _device{other._device}, _handle{other._handle}, _flags{other._flags} { + other._handle = {}; +} + +Buffer::~Buffer() { + if(_handle && (_flags & HandleFlag::DestroyOnDestruction)) + (**_device).DestroyBuffer(*_device, _handle, nullptr); +} + +Buffer& Buffer::operator=(Buffer&& other) noexcept { + using std::swap; + swap(other._device, _device); + swap(other._handle, _handle); + swap(other._flags, _flags); + return *this; +} + +VkBuffer Buffer::release() { + const VkBuffer handle = _handle; + _handle = {}; + return handle; +} + +}} diff --git a/src/Magnum/Vk/Buffer.h b/src/Magnum/Vk/Buffer.h new file mode 100644 index 000000000..377698064 --- /dev/null +++ b/src/Magnum/Vk/Buffer.h @@ -0,0 +1,245 @@ +#ifndef Magnum_Vk_Buffer_h +#define Magnum_Vk_Buffer_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Class @ref Magnum::Vk::BufferCreateInfo, @ref Magnum::Vk::Buffer, enum @ref Magnum::Vk::BufferUsage, enum set @ref Magnum::Vk::BufferUsages + * @m_since_latest + */ + +#include + +#include "Magnum/Magnum.h" +#include "Magnum/Tags.h" +#include "Magnum/Vk/Vk.h" +#include "Magnum/Vk/Vulkan.h" +#include "Magnum/Vk/visibility.h" + +namespace Magnum { namespace Vk { + +/** +@brief Buffer usage +@m_since_latest + +Wraps a @type_vk_keyword{BufferUsageFlagBits}. +@see @ref BufferUsages, @ref BufferCreateInfo +@m_enum_values_as_keywords +*/ +enum class BufferUsage: UnsignedInt { + TransferSource = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + TransferDestination = VK_BUFFER_USAGE_TRANSFER_DST_BIT, + UniformTexelBuffer = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, + StorageTexelBuffer = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, + UniformBuffer = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + StorageBuffer = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, + IndexBuffer = VK_BUFFER_USAGE_INDEX_BUFFER_BIT, + VertexBuffer = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, + IndirectBuffer = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, + + /** @todo VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, 1.2 */ +}; + +/** +@brief Buffer usages +@m_since_latest + +Type-safe wrapper for @type_vk_keyword{BufferUsageFlags}. +@see @ref BufferCreateInfo +*/ +typedef Containers::EnumSet BufferUsages; + +CORRADE_ENUMSET_OPERATORS(BufferUsages) + +/** +@brief Buffer creation info +@m_since_latest + +Wraps a @type_vk_keyword{BufferCreateInfo}. See @ref Buffer for usage +information. +*/ +class MAGNUM_VK_EXPORT BufferCreateInfo { + public: + /** + * @brief Buffer creation flag + * + * Wraps @type_vk_keyword{BufferCreateFlagBits}. + * @see @ref Flags, @ref BufferCreateInfo() + * @m_enum_values_as_keywords + */ + enum class Flag: UnsignedInt { + /** @todo sparse binding, protected ... */ + }; + + /** + * @brief Buffer creation flags + * + * Type-safe wrapper for @type_vk_keyword{BufferCreateFlags}. + * @see @ref BufferCreateInfo() + */ + typedef Containers::EnumSet Flags; + + /** + * @brief Constructor + * @param usages Desired buffer usage. At least one flag is + * required. + * @param size Buffer size + * @param flags Buffer creation flags + * + * The following @type_vk{BufferCreateInfo} fields are pre-filled in + * addition to `sType`, everything else is zero-filled: + * + * - `flags` + * - `size` + * - `usage` to @p usages + * - `sharingMode` to @val_vk{SHARING_MODE_EXCLUSIVE,SharingMode} + */ + explicit BufferCreateInfo(BufferUsages usages, UnsignedLong size, Flags flags = {}); + + /** + * @brief Construct without initializing the contents + * + * Note that not even the `sType` field is set --- the structure has to + * be fully initialized afterwards in order to be usable. + */ + explicit BufferCreateInfo(NoInitT) noexcept; + + /** + * @brief Construct from existing data + * + * Copies the existing values verbatim, pointers are kept unchanged + * without taking over the ownership. Modifying the newly created + * instance will not modify the original data nor the pointed-to data. + */ + explicit BufferCreateInfo(const VkBufferCreateInfo& info); + + /** @brief Underlying @type_vk{BufferCreateInfo} structure */ + VkBufferCreateInfo& operator*() { return _info; } + /** @overload */ + const VkBufferCreateInfo& operator*() const { return _info; } + /** @overload */ + VkBufferCreateInfo* operator->() { return &_info; } + /** @overload */ + const VkBufferCreateInfo* operator->() const { return &_info; } + /** @overload */ + operator const VkBufferCreateInfo*() const { return &_info; } + + private: + VkBufferCreateInfo _info; +}; + +CORRADE_ENUMSET_OPERATORS(BufferCreateInfo::Flags) + +/** +@brief Buffer +@m_since_latest + +Wraps a @type_vk_keyword{Buffer}. +*/ +class MAGNUM_VK_EXPORT Buffer { + public: + /** + * @brief Wrap existing Vulkan handle + * @param device Vulkan device the buffer is created on + * @param handle The @type_vk{Buffer} handle + * @param flags Handle flags + * + * The @p handle is expected to be originating from @p device. Unlike + * a buffer created using a constructor, the Vulkan buffer is by + * default not deleted on destruction, use @p flags for different + * behavior. + * @see @ref release() + */ + static Buffer wrap(Device& device, VkBuffer handle, HandleFlags flags = {}); + + /** + * @brief Construct a buffer without allocating + * @param device Vulkan device to create the buffer on + * @param info Buffer creation info + * + * @see @fn_vk_keyword{CreateBuffer} + */ + explicit Buffer(Device& device, const BufferCreateInfo& info, NoAllocateT); + + /** + * @brief Construct without creating the buffer + * + * The constructed instance is equivalent to moved-from state. Useful + * in cases where you will overwrite the instance later anyway. Move + * another object over it to make it useful. + */ + explicit Buffer(NoCreateT); + + /** @brief Copying is not allowed */ + Buffer(const Buffer&) = delete; + + /** @brief Move constructor */ + Buffer(Buffer&& other) noexcept; + + /** + * @brief Destructor + * + * Destroys associated @type_vk{Buffer} handle, unless the instance was + * created using @ref wrap() without + * @ref HandleFlag::DestroyOnDestruction specified. + * @see @fn_vk_keyword{DestroyBuffer}, @ref release() + */ + ~Buffer(); + + /** @brief Copying is not allowed */ + Buffer& operator=(const Buffer&) = delete; + + /** @brief Move assignment */ + Buffer& operator=(Buffer&& other) noexcept; + + /** @brief Underlying @type_vk{Buffer} handle */ + VkBuffer handle() { return _handle; } + /** @overload */ + operator VkBuffer() { return _handle; } + + /** @brief Handle flags */ + HandleFlags handleFlags() const { return _flags; } + + /** + * @brief Release the underlying Vulkan buffer + * + * Releases ownership of the Vulkan buffer and returns its handle so + * @fn_vk{DestroyBuffer} is not called on destruction. The internal + * state is then equivalent to moved-from state. + * @see @ref wrap() + */ + VkBuffer release(); + + private: + /* Can't be a reference because of the NoCreate constructor */ + Device* _device; + + VkBuffer _handle; + HandleFlags _flags; +}; + +}} + +#endif diff --git a/src/Magnum/Vk/CMakeLists.txt b/src/Magnum/Vk/CMakeLists.txt index c7a6f0d84..21150bf0e 100644 --- a/src/Magnum/Vk/CMakeLists.txt +++ b/src/Magnum/Vk/CMakeLists.txt @@ -27,6 +27,7 @@ find_package(Vulkan REQUIRED) set(MagnumVk_SRCS + Buffer.cpp CommandBuffer.cpp CommandPool.cpp Extensions.cpp @@ -50,6 +51,7 @@ set(MagnumVk_GracefulAssert_SRCS set(MagnumVk_HEADERS Assert.h + Buffer.h CommandBuffer.h CommandPool.h Device.h diff --git a/src/Magnum/Vk/Test/BufferTest.cpp b/src/Magnum/Vk/Test/BufferTest.cpp new file mode 100644 index 000000000..5281937db --- /dev/null +++ b/src/Magnum/Vk/Test/BufferTest.cpp @@ -0,0 +1,98 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include +#include + +#include "Magnum/Vk/Buffer.h" + +namespace Magnum { namespace Vk { namespace Test { namespace { + +struct BufferTest: TestSuite::Tester { + explicit BufferTest(); + + void createInfoConstruct(); + void createInfoConstructNoInit(); + void createInfoConstructFromVk(); + + void constructNoCreate(); + void constructCopy(); +}; + +BufferTest::BufferTest() { + addTests({&BufferTest::createInfoConstruct, + &BufferTest::createInfoConstructNoInit, + &BufferTest::createInfoConstructFromVk, + + &BufferTest::constructNoCreate, + &BufferTest::constructCopy}); +} + +void BufferTest::createInfoConstruct() { + /** @todo use a real flag once at least one is exposed */ + BufferCreateInfo info{BufferUsage::UniformBuffer, 1024, BufferCreateInfo::Flag(VK_BUFFER_CREATE_PROTECTED_BIT)}; + CORRADE_COMPARE(info->flags, VK_BUFFER_CREATE_PROTECTED_BIT); + CORRADE_COMPARE(info->size, 1024); + CORRADE_COMPARE(info->usage, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); +} + +void BufferTest::createInfoConstructNoInit() { + BufferCreateInfo info{NoInit}; + info->sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; + new(&info) BufferCreateInfo{NoInit}; + CORRADE_COMPARE(info->sType, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2); + + CORRADE_VERIFY((std::is_nothrow_constructible::value)); + + /* Implicit construction is not allowed */ + CORRADE_VERIFY(!(std::is_convertible::value)); +} + +void BufferTest::createInfoConstructFromVk() { + VkBufferCreateInfo vkInfo; + vkInfo.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; + + BufferCreateInfo info{vkInfo}; + CORRADE_COMPARE(info->sType, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2); +} + +void BufferTest::constructNoCreate() { + { + Buffer buffer{NoCreate}; + CORRADE_VERIFY(!buffer.handle()); + } + + /* Implicit construction is not allowed */ + CORRADE_VERIFY(!(std::is_convertible::value)); +} + +void BufferTest::constructCopy() { + CORRADE_VERIFY(!(std::is_constructible{})); + CORRADE_VERIFY(!(std::is_assignable{})); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Vk::Test::BufferTest) diff --git a/src/Magnum/Vk/Test/BufferVkTest.cpp b/src/Magnum/Vk/Test/BufferVkTest.cpp new file mode 100644 index 000000000..065b3202c --- /dev/null +++ b/src/Magnum/Vk/Test/BufferVkTest.cpp @@ -0,0 +1,97 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "Magnum/Vk/Buffer.h" +#include "Magnum/Vk/Handle.h" +#include "Magnum/Vk/Result.h" +#include "Magnum/Vk/VulkanTester.h" + +namespace Magnum { namespace Vk { namespace Test { namespace { + +struct BufferVkTest: VulkanTester { + explicit BufferVkTest(); + + void construct(); + void constructMove(); + + void wrap(); +}; + +BufferVkTest::BufferVkTest() { + addTests({&BufferVkTest::construct, + &BufferVkTest::constructMove, + + &BufferVkTest::wrap}); +} + +void BufferVkTest::construct() { + { + Buffer buffer{device(), BufferCreateInfo{BufferUsage::StorageBuffer, 1024}, NoAllocate}; + CORRADE_VERIFY(buffer.handle()); + CORRADE_COMPARE(buffer.handleFlags(), HandleFlag::DestroyOnDestruction); + } + + /* Shouldn't crash or anything */ + CORRADE_VERIFY(true); +} + +void BufferVkTest::constructMove() { + Buffer a{device(), BufferCreateInfo{BufferUsage::StorageBuffer, 1024}, NoAllocate}; + VkBuffer handle = a.handle(); + + Buffer b = std::move(a); + CORRADE_VERIFY(!a.handle()); + CORRADE_COMPARE(b.handle(), handle); + CORRADE_COMPARE(b.handleFlags(), HandleFlag::DestroyOnDestruction); + + Buffer c{NoCreate}; + c = std::move(b); + CORRADE_VERIFY(!b.handle()); + CORRADE_COMPARE(b.handleFlags(), HandleFlags{}); + CORRADE_COMPARE(c.handle(), handle); + CORRADE_COMPARE(c.handleFlags(), HandleFlag::DestroyOnDestruction); + + CORRADE_VERIFY(std::is_nothrow_move_constructible::value); + CORRADE_VERIFY(std::is_nothrow_move_assignable::value); +} + +void BufferVkTest::wrap() { + VkBuffer buffer{}; + CORRADE_COMPARE(Result(device()->CreateBuffer(device(), + BufferCreateInfo{BufferUsage::StorageTexelBuffer, 4096}, + nullptr, &buffer)), Result::Success); + + auto wrapped = Buffer::wrap(device(), buffer, HandleFlag::DestroyOnDestruction); + CORRADE_COMPARE(wrapped.handle(), buffer); + + /* Release the handle again, destroy by hand */ + CORRADE_COMPARE(wrapped.release(), buffer); + CORRADE_VERIFY(!wrapped.handle()); + device()->DestroyBuffer(device(), buffer, nullptr); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Vk::Test::BufferVkTest) diff --git a/src/Magnum/Vk/Test/CMakeLists.txt b/src/Magnum/Vk/Test/CMakeLists.txt index af459e963..5ac6b9727 100644 --- a/src/Magnum/Vk/Test/CMakeLists.txt +++ b/src/Magnum/Vk/Test/CMakeLists.txt @@ -24,6 +24,7 @@ # DEALINGS IN THE SOFTWARE. # +corrade_add_test(VkBufferTest BufferTest.cpp LIBRARIES MagnumVk) corrade_add_test(VkCommandBufferTest CommandBufferTest.cpp LIBRARIES MagnumVk) corrade_add_test(VkCommandPoolTest CommandPoolTest.cpp LIBRARIES MagnumVk) corrade_add_test(VkDeviceTest DeviceTest.cpp LIBRARIES MagnumVk) @@ -94,6 +95,7 @@ target_compile_definitions(VkAssertStandardDisabledTest PRIVATE corrade_add_test(VkVersionTest VersionTest.cpp LIBRARIES MagnumVk) if(BUILD_VK_TESTS) + corrade_add_test(VkBufferVkTest BufferVkTest.cpp LIBRARIES MagnumVulkanTester) corrade_add_test(VkCommandBufferVkTest CommandBufferVkTest.cpp LIBRARIES MagnumVulkanTester) corrade_add_test(VkCommandPoolVkTest CommandPoolVkTest.cpp LIBRARIES MagnumVulkanTester) corrade_add_test(VkDeviceVkTest DeviceVkTest.cpp LIBRARIES MagnumVkTestLib MagnumVulkanTester) diff --git a/src/Magnum/Vk/Vk.h b/src/Magnum/Vk/Vk.h index cef370bf5..7878da264 100644 --- a/src/Magnum/Vk/Vk.h +++ b/src/Magnum/Vk/Vk.h @@ -36,6 +36,7 @@ namespace Magnum { namespace Vk { #ifndef DOXYGEN_GENERATING_OUTPUT +class Buffer; class CommandBuffer; class CommandPool; class Device;