Browse Source

Vk: Wrap many Vulkan types

* Buffer
 * Command
 * CommandBuffer
 * Device & PhysicalDevice
 * DeviceMemory
 * Framebuffer
 * Image & ImageView
 * Shader
 * Semaphore
 * Swapchain
 * RenderPass
 * Queue

Signed-off-by: Squareys <Squareys@googlemail.com>
pull/202/head
Squareys 10 years ago
parent
commit
c585d60da1
  1. 4
      src/Magnum/Platform/GlfwApplication.cpp
  2. 7
      src/Magnum/Platform/GlfwApplication.h
  3. 36
      src/Magnum/Vk/Buffer.cpp
  4. 143
      src/Magnum/Vk/Buffer.h
  5. 44
      src/Magnum/Vk/CMakeLists.txt
  6. 96
      src/Magnum/Vk/Command.h
  7. 38
      src/Magnum/Vk/CommandBuffer.cpp
  8. 130
      src/Magnum/Vk/CommandBuffer.h
  9. 49
      src/Magnum/Vk/CommandPool.cpp
  10. 93
      src/Magnum/Vk/CommandPool.h
  11. 82
      src/Magnum/Vk/Context.cpp
  12. 59
      src/Magnum/Vk/Device.cpp
  13. 106
      src/Magnum/Vk/Device.h
  14. 36
      src/Magnum/Vk/DeviceMemory.cpp
  15. 109
      src/Magnum/Vk/DeviceMemory.h
  16. 36
      src/Magnum/Vk/Framebuffer.cpp
  17. 98
      src/Magnum/Vk/Framebuffer.h
  18. 36
      src/Magnum/Vk/Image.cpp
  19. 188
      src/Magnum/Vk/Image.h
  20. 36
      src/Magnum/Vk/ImageView.cpp
  21. 110
      src/Magnum/Vk/ImageView.h
  22. 53
      src/Magnum/Vk/Math.h
  23. 98
      src/Magnum/Vk/PhysicalDevice.cpp
  24. 107
      src/Magnum/Vk/PhysicalDevice.h
  25. 100
      src/Magnum/Vk/Pipeline.cpp
  26. 364
      src/Magnum/Vk/Pipeline.h
  27. 83
      src/Magnum/Vk/Queue.cpp
  28. 90
      src/Magnum/Vk/Queue.h
  29. 37
      src/Magnum/Vk/RenderPass.cpp
  30. 139
      src/Magnum/Vk/RenderPass.h
  31. 34
      src/Magnum/Vk/Semaphore.cpp
  32. 94
      src/Magnum/Vk/Semaphore.h
  33. 36
      src/Magnum/Vk/Shader.cpp
  34. 88
      src/Magnum/Vk/Shader.h
  35. 316
      src/Magnum/Vk/Swapchain.cpp
  36. 155
      src/Magnum/Vk/Swapchain.h
  37. 59
      src/Magnum/Vk/Test/CommandTest.cpp
  38. 76
      src/Magnum/Vk/Test/ContextVkTest.cpp

4
src/Magnum/Platform/GlfwApplication.cpp

@ -94,6 +94,7 @@ bool GlfwApplication::tryCreateContext(const Configuration& configuration) {
glfwWindowHint(GLFW_ICONIFIED, flags >= Configuration::WindowFlag::Minimized); glfwWindowHint(GLFW_ICONIFIED, flags >= Configuration::WindowFlag::Minimized);
glfwWindowHint(GLFW_FLOATING, flags >= Configuration::WindowFlag::Floating); glfwWindowHint(GLFW_FLOATING, flags >= Configuration::WindowFlag::Floating);
} }
glfwWindowHint(GLFW_FOCUSED, configuration.windowFlags() >= Configuration::WindowFlag::Focused); glfwWindowHint(GLFW_FOCUSED, configuration.windowFlags() >= Configuration::WindowFlag::Focused);
/* Context window hints */ /* Context window hints */
@ -125,6 +126,7 @@ bool GlfwApplication::tryCreateContext(const Configuration& configuration) {
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
#endif #endif
} }
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
/* Set context flags */ /* Set context flags */
_window = glfwCreateWindow(configuration.size().x(), configuration.size().y(), configuration.title().c_str(), monitor, nullptr); _window = glfwCreateWindow(configuration.size().x(), configuration.size().y(), configuration.title().c_str(), monitor, nullptr);
@ -144,7 +146,7 @@ bool GlfwApplication::tryCreateContext(const Configuration& configuration) {
glfwMakeContextCurrent(_window); glfwMakeContextCurrent(_window);
/* Return true if the initialization succeeds */ /* Return true if the initialization succeeds */
return _context->tryCreate(); return true; //_context->tryCreate();
} }
GlfwApplication::~GlfwApplication() { GlfwApplication::~GlfwApplication() {

7
src/Magnum/Platform/GlfwApplication.h

@ -45,6 +45,8 @@
#endif #endif
#include <glfw3.h> #include <glfw3.h>
#define GLFW_EXPOSE_NATIVE_WIN32
#include <glfw3native.h>
namespace Magnum { namespace Platform { namespace Magnum { namespace Platform {
@ -223,6 +225,11 @@ class GlfwApplication {
#ifdef MAGNUM_TARGET_VULKAN #ifdef MAGNUM_TARGET_VULKAN
VkSurfaceKHR createVkSurface(); VkSurfaceKHR createVkSurface();
HWND getPlatformWindow() {
return glfwGetWin32Window(_window);
}
#endif #endif
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT

36
src/Magnum/Vk/Buffer.cpp

@ -0,0 +1,36 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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"
namespace Magnum { namespace Vk {
Buffer::~Buffer() {
vkDestroyBuffer(_device, _buffer, nullptr);
}
}}

143
src/Magnum/Vk/Buffer.h

@ -0,0 +1,143 @@
#ifndef Magnum_Vk_Buffer_h
#define Magnum_Vk_Buffer_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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::Buffer
*/
#include <Corrade/Containers/EnumSet.h>
#include "Magnum/Magnum.h"
#include "Magnum/Vk/CommandBuffer.h"
#include "Magnum/Vk/Device.h"
#include "Magnum/Vk/DeviceMemory.h"
#include "Magnum/Vk/visibility.h"
#include "vulkan.h"
namespace Magnum { namespace Vk {
enum class BufferUsage: UnsignedInt {
TransferSrc = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
TransferDst = 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,
};
typedef Containers::EnumSet<BufferUsage> BufferUsageFlags;
CORRADE_ENUMSET_OPERATORS(BufferUsageFlags)
class MAGNUM_VK_EXPORT Buffer {
public:
Buffer(Device& device, UnsignedInt size, BufferUsageFlags usage):
_device{device},
_size{size}
{
VkBufferCreateInfo bufferInfo = {};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.pNext = nullptr;
bufferInfo.size = size;
bufferInfo.usage = VkBufferUsageFlags(usage);
VkResult err = vkCreateBuffer(_device, &bufferInfo, nullptr, &_buffer);
MAGNUM_VK_ASSERT_ERROR(err);
}
/** @brief Copying is not allowed */
Buffer(const Buffer&) = delete;
/** @brief Move constructor */
Buffer(Buffer&& other);
/**
* @brief Destructor
*
* @see @fn_vk{DestroyBuffer}
*/
~Buffer();
/** @brief Copying is not allowed */
Buffer& operator=(const Buffer&) = delete;
/** @brief Move assignment is not allowed */
Buffer& operator=(Buffer&&) = delete;
operator VkBuffer() const {
return _buffer;
}
VkMemoryRequirements getMemoryRequirements() const {
VkMemoryRequirements memReqs;
vkGetBufferMemoryRequirements(_device, _buffer, &memReqs);
return memReqs;
}
UnsignedInt size() const {
return _size;
}
Buffer& bindBufferMemory(const DeviceMemory& deviceMemory, UnsignedLong offset=0) {
VkResult err = vkBindBufferMemory(_device, _buffer, deviceMemory, offset);
MAGNUM_VK_ASSERT_ERROR(err);
return *this;
}
auto cmdCopyTo(Buffer& dest, std::initializer_list<VkBufferCopy> regions) {
const VkBuffer source = _buffer;
return [source, &dest, &regions](VkCommandBuffer cmdBuffer){
vkCmdCopyBuffer(cmdBuffer, source, dest, regions.size(), std::vector<VkBufferCopy>(regions).data());
};
}
auto cmdFullCopyTo(Buffer& dest) {
const VkBuffer source = _buffer;
const UnsignedInt size = _size;
return [source, &dest, size](VkCommandBuffer cmdBuffer){
VkBufferCopy bufferCopy = {0, 0, size};
vkCmdCopyBuffer(cmdBuffer, source, dest, 1, &bufferCopy);
};
}
private:
Device& _device;
VkBuffer _buffer;
UnsignedInt _size;
};
}}
#endif

44
src/Magnum/Vk/CMakeLists.txt

@ -28,10 +28,42 @@
find_package(Vulkan REQUIRED) find_package(Vulkan REQUIRED)
set(MagnumVk_SRCS set(MagnumVk_SRCS
Context.cpp) Buffer.cpp
CommandBuffer.cpp
CommandPool.cpp
Context.cpp
Device.cpp
DeviceMemory.cpp
Framebuffer.cpp
Image.cpp
ImageView.cpp
PhysicalDevice.cpp
Pipeline.cpp
Queue.cpp
RenderPass.cpp
Semaphore.cpp
Shader.cpp
Swapchain.cpp)
set(MagnumVk_HEADERS set(MagnumVk_HEADERS
Buffer.h
Command.h
CommandBuffer.h
CommandPool.h
Context.h Context.h
Device.h
DeviceMemory.h
Framebuffer.h
Image.h
ImageView.h
Math.h
PhysicalDevice.h
Pipeline.h
Queue.h
RenderPass.h
Semaphore.h
Shader.h
Swapchain.h
visibility.h) visibility.h)
@ -45,6 +77,8 @@ set(MagnumVk_PRIVATE_HEADERS "")
add_library(MagnumVk ${SHARED_OR_STATIC} add_library(MagnumVk ${SHARED_OR_STATIC}
${MagnumVk_SRCS} ${MagnumVk_SRCS}
${MagnumVk_HEADERS} ${MagnumVk_HEADERS}
${MagnumVkTest_HEADERS}
${MagnumVk_PRIVATE_HEADERS}) ${MagnumVk_PRIVATE_HEADERS})
set_target_properties(MagnumVk PROPERTIES DEBUG_POSTFIX "-d") set_target_properties(MagnumVk PROPERTIES DEBUG_POSTFIX "-d")
if(BUILD_STATIC_PIC) if(BUILD_STATIC_PIC)
@ -52,13 +86,21 @@ if(BUILD_STATIC_PIC)
endif() endif()
target_link_libraries(MagnumVk Magnum Vulkan::Vulkan) target_link_libraries(MagnumVk Magnum Vulkan::Vulkan)
set_target_properties(MagnumVk PROPERTIES
CORRADE_CXX_STANDARD 14
INTERFACE_CORRADE_CXX_STANDARD 14)
install(TARGETS MagnumVk install(TARGETS MagnumVk
RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR}
LIBRARY DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR} LIBRARY DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}
ARCHIVE DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) ARCHIVE DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR})
install(FILES ${MagnumVkTest_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Vk/Test)
install(FILES ${MagnumVk_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Vk) install(FILES ${MagnumVk_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Vk)
if(BUILD_TESTS) if(BUILD_TESTS)
set(VK_TEST_LIBRARIES MagnumVk)
add_subdirectory(Test) add_subdirectory(Test)
endif() endif()

96
src/Magnum/Vk/Command.h

@ -0,0 +1,96 @@
#ifndef Magnum_Vk_Command_h
#define Magnum_Vk_Command_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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 Namespace @ref Magnum::Vk::Cmd
*/
#include "vulkan.h"
#include <Corrade/Containers/Array.h>
#include <Corrade/Utility/Debug.h>
#include "Magnum/Tags.h"
#include "Magnum/Magnum.h"
#include "Magnum/Math/Range.h"
#include "Magnum/Vk/CommandBuffer.h"
#include "Magnum/Vk/Pipeline.h"
#include "Magnum/Vk/visibility.h"
#include "Magnum/Vk/Image.h"
namespace Magnum { namespace Vk {
template<typename Lambda>
CommandBuffer& operator << (CommandBuffer& cmdBuffer, const Lambda& lambda) {
lambda(cmdBuffer);
return cmdBuffer;
}
namespace Cmd {
auto setScissor(UnsignedInt firstScissor, const std::initializer_list<Range2Di>& ranges) {
return [firstScissor, &ranges](VkCommandBuffer cmdBuffer){
Corrade::Containers::Array<VkRect2D> vkRects(ranges.size());
UnsignedInt i = 0;
for(auto& range: ranges) {
vkRects[i] = {{range.left(), range.bottom()}, {range.sizeX(), range.sizeY()}};
++i;
}
vkCmdSetScissor(cmdBuffer, firstScissor, vkRects.size(), vkRects.data());
};
}
auto setViewport(UnsignedInt firstViewport, const std::vector<VkViewport>& viewports) {
return [firstViewport, &viewports](VkCommandBuffer cmdBuffer){
vkCmdSetViewport(cmdBuffer, firstViewport, viewports.size(), viewports.data());
};
}
auto pipelineBarrier(PipelineStageFlags srcStageMask,
PipelineStageFlags dstStageMask,
const std::vector<VkMemoryBarrier>& memoryBarriers,
const std::vector<VkBufferMemoryBarrier>& bufferMemoryBarriers,
const std::vector<ImageMemoryBarrier>& imageMemoryBarriers) {
return [&memoryBarriers, &bufferMemoryBarriers, &imageMemoryBarriers](VkCommandBuffer cmdBuffer){
vkCmdPipelineBarrier(cmdBuffer,
VkPipelineStageFlags(srcStageFlags), VkPipelineStageFlags(dstStageMask),
0, memoryBarriers.size(),
Containers::StaticArrayView<VkMemoryBarrier>(memoryBarriers),
bufferMemoryBarriers.size(),
Containers::StaticArrayView<VkBufferMemoryBarrier>(bufferMemoryBarriers),
imageMemoryBarriers.size(),
Containers::StaticArrayView<VkImageMemoryBarrier>(imageMemoryBarriers)
);
}
}
}}}
#endif

38
src/Magnum/Vk/CommandBuffer.cpp

@ -0,0 +1,38 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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 "CommandBuffer.h"
#include "CommandPool.h"
namespace Magnum { namespace Vk {
CommandBuffer::~CommandBuffer() {
_pool.freeCommandBuffer(this);
}
}}

130
src/Magnum/Vk/CommandBuffer.h

@ -0,0 +1,130 @@
#ifndef Magnum_Vk_CommandBuffer_h
#define Magnum_Vk_CommandBuffer_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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::CommandBuffer
*/
#include "Magnum/Magnum.h"
#include "Magnum/Math/Range.h"
#include "Magnum/Vk/Context.h"
#include "Magnum/Vk/visibility.h"
#include "vulkan.h"
namespace Magnum { namespace Vk {
class CommandPool;
class MAGNUM_VK_EXPORT CommandBuffer {
public:
enum class Level: Int {
Primary = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
Secondary = VK_COMMAND_BUFFER_LEVEL_SECONDARY
};
enum class SubpassContents: UnsignedInt {
Inline = VK_SUBPASS_CONTENTS_INLINE,
SecondaryCommandBuffers = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS,
};
CommandBuffer(VkCommandBuffer buffer, CommandPool& commandPool):
_cmdBuffer{buffer},
_pool{commandPool}
{
}
/** @brief Copying is not allowed */
CommandBuffer(const CommandBuffer&) = delete;
/** @brief Move constructor */
CommandBuffer(CommandBuffer&& other);
/**
* @brief Destructor
*
* @see @fn_vk{DestroyCommandBuffer}
*/
~CommandBuffer();
/** @brief Copying is not allowed */
CommandBuffer& operator=(const CommandBuffer&) = delete;
/** @brief Move assignment is not allowed */
CommandBuffer& operator=(CommandBuffer&&) = delete;
operator VkCommandBuffer() const {
return _cmdBuffer;
}
CommandBuffer& begin() {
VkCommandBufferBeginInfo cmdBufInfo = {};
cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
vkBeginCommandBuffer(_cmdBuffer, &cmdBufInfo);
return *this;
}
CommandBuffer& end() {
VkResult err = vkEndCommandBuffer(_cmdBuffer);
MAGNUM_VK_ASSERT_ERROR(err);
return *this;
}
CommandBuffer& beginRenderPass(SubpassContents subpassContents, VkRenderPass renderPass,
VkFramebuffer framebuffer, Range2Di renderArea,
const std::vector<VkClearValue>& clearValues) {
VkRenderPassBeginInfo renderPassBeginInfo {
VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
nullptr,
renderPass,
framebuffer,
VkRect2D{{renderArea.left(), renderArea.bottom()}, {renderArea.sizeX(), renderArea.sizeY()}},
clearValues.size(),
clearValues.data()};
vkCmdBeginRenderPass(_cmdBuffer, &renderPassBeginInfo, VkSubpassContents(subpassContents));
return *this;
}
CommandBuffer& endRenderPass() {
vkCmdEndRenderPass(_cmdBuffer);
return *this;
}
private:
VkCommandBuffer _cmdBuffer;
CommandPool& _pool;
};
}}
#endif

49
src/Magnum/Vk/CommandPool.cpp

@ -0,0 +1,49 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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 "CommandPool.h"
namespace Magnum { namespace Vk {
CommandPool::~CommandPool() {
vkDestroyCommandPool(_device.vkDevice(), _pool, nullptr);
}
std::unique_ptr<CommandBuffer> CommandPool::allocateCommandBuffer(CommandBuffer::Level level) {
VkCommandBuffer cmdBuffer;
VkCommandBufferAllocateInfo commandBufferAllocateInfo = {};
commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
commandBufferAllocateInfo.commandPool = _pool;
commandBufferAllocateInfo.level = VkCommandBufferLevel(level);
commandBufferAllocateInfo.commandBufferCount = 1;
vkAllocateCommandBuffers(_device.vkDevice(), &commandBufferAllocateInfo, &cmdBuffer);
return std::unique_ptr<CommandBuffer>{new CommandBuffer{cmdBuffer, *this}};
}
}}

93
src/Magnum/Vk/CommandPool.h

@ -0,0 +1,93 @@
#ifndef Magnum_Vk_CommandPool_h
#define Magnum_Vk_CommandPool_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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::CommandPool
*/
#include "Magnum/Magnum.h"
#include "Magnum/Vk/CommandBuffer.h"
#include "Magnum/Vk/Device.h"
#include "Magnum/Vk/PhysicalDevice.h"
#include "Magnum/Vk/visibility.h"
#include "vulkan.h"
namespace Magnum { namespace Vk {
class MAGNUM_VK_EXPORT CommandPool {
friend class CommandBuffer;
public:
/** @brief Copying is not allowed */
CommandPool(const Context&) = delete;
/** @brief Move constructor */
CommandPool(CommandPool&& other);
CommandPool(Device& device, QueueFamily family): _device{device} {
const VkCommandPoolCreateInfo cmdPoolInfo = {
VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, nullptr,
VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
_device.physicalDevice().getQueueFamilyIndex(family)};
vkCreateCommandPool(_device, &cmdPoolInfo, nullptr, &_pool);
}
/**
* @brief Destructor
*
* @see @fn_vk{DestroyCommandPool}
*/
~CommandPool();
/** @brief Copying is not allowed */
CommandPool& operator=(const CommandPool&) = delete;
/** @brief Move assignment is not allowed */
CommandPool& operator=(CommandPool&&) = delete;
VkCommandPool vkCommandPool() {
return _pool;
}
std::unique_ptr<CommandBuffer> allocateCommandBuffer(CommandBuffer::Level level);
private:
VkCommandPool _pool;
Device& _device;
void freeCommandBuffer(CommandBuffer* buffer) {
VkCommandBuffer buffers = *buffer;
vkFreeCommandBuffers(_device.vkDevice(), _pool, 1, &buffers);
}
};
}}
#endif

82
src/Magnum/Vk/Context.cpp

@ -30,20 +30,16 @@
#include <Corrade/Utility/String.h> #include <Corrade/Utility/String.h>
#include "vulkan.h" #include "vulkan.h"
PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallback;
PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallback;
PFN_vkDebugReportMessageEXT dbgBreakCallback;
VkDebugReportCallbackEXT msgCallback;
namespace Magnum { namespace Vk { namespace Magnum { namespace Vk {
unsigned int layerCount = 2;
const char *validationLayerNames[] = const char *validationLayerNames[] =
{ {
// This is a meta layer that enables all of the standard // This is a meta layer that enables all of the standard
// validation layers in the correct order : // validation layers in the correct order :
// threading, parameter_validation, device_limits, object_tracker, image, core_validation, swapchain, and unique_objects // threading, parameter_validation, device_limits, object_tracker, image, core_validation, swapchain, and unique_objects
"VK_LAYER_LUNARG_standard_validation" "VK_LAYER_LUNARG_standard_validation",
"VK_LAYER_LUNARG_api_dump"
}; };
Context* Context::_current = nullptr; Context* Context::_current = nullptr;
@ -79,7 +75,7 @@ Context::~Context() {
} }
if (_flags >= Flag::EnableValidation) { if (_flags >= Flag::EnableValidation) {
DestroyDebugReportCallback(_instance, msgCallback, nullptr); //DestroyDebugReportCallback(_instance, msgCallback, nullptr);
} }
vkDestroyInstance(_instance, nullptr); vkDestroyInstance(_instance, nullptr);
} }
@ -89,16 +85,18 @@ void Context::create() {
if(!tryCreate()) std::exit(1); if(!tryCreate()) std::exit(1);
} }
VkBool32 messageCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, VKAPI_ATTR VkBool32 VKAPI_CALL MyDebugReportCallback(
uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void* pUserData) { VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objectType,
if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { uint64_t object,
Error() << "[" << pLayerPrefix << "] Code" << msgCode << ":" << pMsg; size_t location,
} else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { int32_t messageCode,
Warning() << "[" << pLayerPrefix << "] Code" << msgCode << ":" << pMsg; const char* pLayerPrefix,
} const char* pMessage,
void* pUserData)
return false; {
Error() << pMessage;
return VK_FALSE;
} }
bool Context::tryCreate() { bool Context::tryCreate() {
@ -108,7 +106,7 @@ bool Context::tryCreate() {
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "Vulkan Example"; appInfo.pApplicationName = "Vulkan Example";
appInfo.pEngineName = "Magnum"; appInfo.pEngineName = "Magnum";
appInfo.apiVersion = UnsignedInt(_version); appInfo.apiVersion = VK_API_VERSION_1_0;
std::vector<const char*> enabledExtensions = {VK_KHR_SURFACE_EXTENSION_NAME, "VK_KHR_win32_surface"}; std::vector<const char*> enabledExtensions = {VK_KHR_SURFACE_EXTENSION_NAME, "VK_KHR_win32_surface"};
@ -120,11 +118,13 @@ bool Context::tryCreate() {
instanceCreateInfo.pNext = nullptr; instanceCreateInfo.pNext = nullptr;
instanceCreateInfo.pApplicationInfo = &appInfo; instanceCreateInfo.pApplicationInfo = &appInfo;
if (_flags >= Flag::EnableValidation) { if (_flags >= Flag::EnableValidation) {
Debug() << "Enabling Validation";
enabledExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); enabledExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
instanceCreateInfo.enabledLayerCount = 1; instanceCreateInfo.enabledLayerCount = layerCount;
instanceCreateInfo.ppEnabledLayerNames = validationLayerNames; instanceCreateInfo.ppEnabledLayerNames = validationLayerNames;
} }
if (!enabledExtensions.empty()) { if (!enabledExtensions.empty()) {
instanceCreateInfo.enabledExtensionCount = enabledExtensions.size(); instanceCreateInfo.enabledExtensionCount = enabledExtensions.size();
instanceCreateInfo.ppEnabledExtensionNames = enabledExtensions.data(); instanceCreateInfo.ppEnabledExtensionNames = enabledExtensions.data();
@ -140,21 +140,33 @@ bool Context::tryCreate() {
/* setup debugging */ /* setup debugging */
if (_flags >= Flag::EnableValidation) { if (_flags >= Flag::EnableValidation) {
CreateDebugReportCallback = PFN_vkCreateDebugReportCallbackEXT(vkGetInstanceProcAddr(_instance, "vkCreateDebugReportCallbackEXT")); /* Load VK_EXT_debug_report entry points in debug builds */
DestroyDebugReportCallback = PFN_vkDestroyDebugReportCallbackEXT(vkGetInstanceProcAddr(_instance, "vkDestroyDebugReportCallbackEXT")); PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT =
dbgBreakCallback = PFN_vkDebugReportMessageEXT(vkGetInstanceProcAddr(_instance, "vkDebugReportMessageEXT")); reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>
(vkGetInstanceProcAddr(_instance, "vkCreateDebugReportCallbackEXT"));
VkDebugReportCallbackCreateInfoEXT dbgCreateInfo = {}; PFN_vkDebugReportMessageEXT vkDebugReportMessageEXT =
dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; reinterpret_cast<PFN_vkDebugReportMessageEXT>
dbgCreateInfo.pfnCallback = PFN_vkDebugReportCallbackEXT(messageCallback); (vkGetInstanceProcAddr(_instance, "vkDebugReportMessageEXT"));
dbgCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT; PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT =
reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>
VkResult err = CreateDebugReportCallback( (vkGetInstanceProcAddr(_instance, "vkDestroyDebugReportCallbackEXT"));
_instance,
&dbgCreateInfo, /* Setup callback creation information */
nullptr, VkDebugReportCallbackCreateInfoEXT callbackCreateInfo;
&msgCallback); callbackCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
assert(!err); callbackCreateInfo.pNext = nullptr;
callbackCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT |
VK_DEBUG_REPORT_WARNING_BIT_EXT |
VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
callbackCreateInfo.pfnCallback = &MyDebugReportCallback;
callbackCreateInfo.pUserData = nullptr;
/* Register the callback */
VkDebugReportCallbackEXT callback;
VkResult err = vkCreateDebugReportCallbackEXT(_instance, &callbackCreateInfo, nullptr, &callback);
if (err != VK_SUCCESS) {
Error() << "Could not setup Debug callback";
}
} }
return true; return true;
} }

59
src/Magnum/Vk/Device.cpp

@ -0,0 +1,59 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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 "Device.h"
#include "Magnum/Vk/CommandPool.h"
#include "Magnum/Vk/Queue.h"
namespace Magnum { namespace Vk {
Device::Device(PhysicalDevice& physicalDevice, VkDeviceQueueCreateInfo& requestedQueues):
_physicalDevice(physicalDevice)
{
constexpr const char* enabledExtensions[]{VK_KHR_SWAPCHAIN_EXTENSION_NAME};
constexpr const char* validationLayerNames[] = {"VK_LAYER_LUNARG_standard_validation"};
// TODO: Allow disabling validation layers
VkDeviceCreateInfo deviceCreateInfo = {
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
nullptr,
0, /* flags */
1, &requestedQueues,
1, validationLayerNames,
1, enabledExtensions,
nullptr};
vkCreateDevice(physicalDevice.vkPhysicalDevice(), &deviceCreateInfo, nullptr, &_device);
}
Device::~Device() {
vkDestroyDevice(_device, nullptr);
}
}}

106
src/Magnum/Vk/Device.h

@ -0,0 +1,106 @@
#ifndef Magnum_Vk_Device_h
#define Magnum_Vk_Device_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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::Device
*/
#include <memory>
#include "Magnum/Magnum.h"
#include "Magnum/Vk/Context.h"
#include "Magnum/Vk/PhysicalDevice.h"
#include "Magnum/Vk/visibility.h"
#include "vulkan.h"
namespace Magnum { namespace Vk {
class CommandPool;
class Queue;
class MAGNUM_VK_EXPORT Device {
public:
/** @brief Copying is not allowed */
Device(const Device&) = delete;
/** @brief Move constructor */
Device(Device&& other);
Device(PhysicalDevice& physicalDevice, VkDeviceQueueCreateInfo& requestedQueues);
/**
* @brief Destructor
*
* @see @fn_vk{DestroyDevice}
*/
~Device();
/** @brief Copying is not allowed */
Device& operator=(const Device&) = delete;
/** @brief Move assignment is not allowed */
Device& operator=(Device&&) = delete;
/**
* @brief Return the underlying VkDevice handle
*/
VkDevice vkDevice() {
return _device;
}
/**
* @return Reference to the PhysicalDevice this Device was created from
*/
PhysicalDevice& physicalDevice() {
return _physicalDevice;
}
/**
* @brief Wait until the device is idle
* @return Reference to self (for method chaining)
*/
Device& waitIdle() {
VkResult err = vkDeviceWaitIdle(_device);
MAGNUM_VK_ASSERT_ERROR(err);
return *this;
}
operator VkDevice() const {
return _device;
}
private:
VkDevice _device;
PhysicalDevice& _physicalDevice;
};
}}
#endif

36
src/Magnum/Vk/DeviceMemory.cpp

@ -0,0 +1,36 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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 "DeviceMemory.h"
namespace Magnum { namespace Vk {
DeviceMemory::~DeviceMemory() {
vkFreeMemory(_device, _deviceMemory, nullptr);
}
}}

109
src/Magnum/Vk/DeviceMemory.h

@ -0,0 +1,109 @@
#ifndef Magnum_Vk_DeviceMemory_h
#define Magnum_Vk_DeviceMemory_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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::DeviceMemory
*/
#include <Corrade/Containers/Array.h>
#include "Magnum/Magnum.h"
#include "Magnum/Vk/Device.h"
#include "Magnum/Vk/visibility.h"
#include "vulkan.h"
namespace Magnum { namespace Vk {
class MAGNUM_VK_EXPORT DeviceMemory {
public:
DeviceMemory(Device& device, UnsignedLong size, UnsignedInt memoryTypeIndex):
_device{device}
{
_memAlloc = {
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
nullptr,
size,
memoryTypeIndex
};
VkResult err = vkAllocateMemory(_device, &_memAlloc, nullptr, &_deviceMemory);
MAGNUM_VK_ASSERT_ERROR(err);
}
/** @brief Copying is not allowed */
DeviceMemory(const DeviceMemory&) = delete;
/** @brief Move constructor */
DeviceMemory(DeviceMemory&& other);
/**
* @brief Destructor
*
* @see @fn_vk{DestroyDeviceMemory}
*/
~DeviceMemory();
/** @brief Copying is not allowed */
DeviceMemory& operator=(const DeviceMemory&) = delete;
/** @brief Move assignment is not allowed */
DeviceMemory& operator=(DeviceMemory&&) = delete;
operator VkDeviceMemory() const {
return _deviceMemory;
}
Containers::Array<char> map() {
return map(0, _memAlloc.allocationSize);
}
Containers::Array<char> map(UnsignedInt offset, UnsignedInt size) {
// TODO: Memory map flags (== 0)
void* data;
VkResult err = vkMapMemory(_device, _deviceMemory, offset, size, 0, &data);
MAGNUM_VK_ASSERT_ERROR(err);
return Containers::Array<char>(static_cast<char*>(data), size);
}
DeviceMemory& unmap() {
vkUnmapMemory(_device, _deviceMemory);
return *this;
}
private:
Device& _device;
VkDeviceMemory _deviceMemory;
VkMemoryAllocateInfo _memAlloc;
};
}}
#endif

36
src/Magnum/Vk/Framebuffer.cpp

@ -0,0 +1,36 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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 "Framebuffer.h"
namespace Magnum { namespace Vk {
Framebuffer::~Framebuffer() {
vkDestroyFramebuffer(_device, _framebuffer, nullptr);
}
}}

98
src/Magnum/Vk/Framebuffer.h

@ -0,0 +1,98 @@
#ifndef Magnum_Vk_Framebuffer_h
#define Magnum_Vk_Framebuffer_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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::Framebuffer
*/
#include "Magnum/Magnum.h"
#include "Magnum/Vk/visibility.h"
#include "Magnum/Vk/Device.h"
#include "Magnum/Vk/RenderPass.h"
#include "Magnum/Vk/ImageView.h"
#include "vulkan.h"
namespace Magnum { namespace Vk {
class MAGNUM_VK_EXPORT Framebuffer {
public:
Framebuffer(Device& device, RenderPass& renderPass, Vector2ui size, std::initializer_list<Vk::ImageView>& attachments):
_device{device}
{
std::vector<VkImageView> vkAttachments;
vkAttachments.reserve(attachments.size());
for (auto& imageView : attachments) {
vkAttachments.push_back(imageView);
}
VkFramebufferCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
createInfo.pNext = nullptr;
createInfo.renderPass = renderPass;
createInfo.attachmentCount = attachments.size();
createInfo.pAttachments = vkAttachments.data();
createInfo.width = size.x();
createInfo.height = size.y();
createInfo.layers = 1;
vkCreateFramebuffer(_device, &createInfo, nullptr, &_framebuffer);
}
/** @brief Copying is not allowed */
Framebuffer(const Framebuffer&) = delete;
/** @brief Move constructor */
Framebuffer(Framebuffer&& other);
/**
* @brief Destructor
*
* @see @fn_vk{DestroyFramebuffer}
*/
~Framebuffer();
/** @brief Copying is not allowed */
Framebuffer& operator=(const Framebuffer&) = delete;
/** @brief Move assignment is not allowed */
Framebuffer& operator=(Framebuffer&&) = delete;
operator VkFramebuffer() const {
return _framebuffer;
}
private:
Device& _device;
VkFramebuffer _framebuffer;
};
}}
#endif

36
src/Magnum/Vk/Image.cpp

@ -0,0 +1,36 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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 "Image.h"
namespace Magnum { namespace Vk {
Image::~Image() {
vkDestroyImage(_device, _image, nullptr);
}
}}

188
src/Magnum/Vk/Image.h

@ -0,0 +1,188 @@
#ifndef Magnum_Vk_Image_h
#define Magnum_Vk_Image_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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::Image
*/
#include <Corrade/Containers/EnumSet.h>
#include "Magnum/Magnum.h"
#include "Magnum/Math/Vector3.h"
#include "Magnum/Vk/Device.h"
#include "Magnum/Vk/Math.h"
#include "Magnum/Vk/visibility.h"
#include "vulkan.h"
namespace Magnum { namespace Vk {
class Image;
enum class ImageUsageFlag: UnsignedInt {
TransferSrc = VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
TransferDst = VK_IMAGE_USAGE_TRANSFER_DST_BIT,
Sampled = VK_IMAGE_USAGE_SAMPLED_BIT,
Storage = VK_IMAGE_USAGE_STORAGE_BIT,
ColorAttachment = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
StencilAttachment = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
TransientAttachment = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
};
typedef Corrade::Containers::EnumSet<ImageUsageFlag> ImageUsageFlags;
CORRADE_ENUMSET_OPERATORS(ImageUsageFlags)
enum class Access: UnsignedInt {
IndirectCommandRead = VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
IndexRead = VK_ACCESS_INDEX_READ_BIT,
VertexAttributeRead = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
UniformRead = VK_ACCESS_UNIFORM_READ_BIT,
InputAttachmentRead = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
ShaderRead = VK_ACCESS_SHADER_READ_BIT,
ShaderWrite = VK_ACCESS_SHADER_WRITE_BIT,
ColorAttachmentRead = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
ColorAttachmentWrite = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
DepthStencilAttachmentRead = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
DepthStencilAttachmentWrite = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
TransferRead = VK_ACCESS_TRANSFER_READ_BIT,
TransferWrite = VK_ACCESS_TRANSFER_WRITE_BIT,
HostRead = VK_ACCESS_HOST_READ_BIT,
HostWrite = VK_ACCESS_HOST_WRITE_BIT,
MemoryRead = VK_ACCESS_MEMORY_READ_BIT,
MemoryWrite = VK_ACCESS_MEMORY_WRITE_BIT,
};
typedef Containers::EnumSet<Access> AccessFlags;
CORRADE_ENUMSET_OPERATORS(AccessFlags)
enum class ImageLayout: UnsignedInt {
Undefined = VK_IMAGE_LAYOUT_UNDEFINED,
General = VK_IMAGE_LAYOUT_GENERAL,
ColorAttachmentOptimal = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
DepthStencilAttachmentOptimal = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
DepthStencilReadOnlyOptimal = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
ShaderReadOnlyOptimal = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
TransferSrcOptimal = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
TransferDstOptimal = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
Preinitialized = VK_IMAGE_LAYOUT_PREINITIALIZED,
PresentSrc = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
};
class MAGNUM_VK_EXPORT Image {
public:
Image(Device& device, VkImage vkImage):
_device{device},
_image{vkImage}
{}
Image(Device& device, Vector3ui extent, VkFormat format, ImageUsageFlags usage): _device{device} {
VkImageCreateInfo image = {};
image.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
image.flags = 0;
image.pNext = nullptr;
image.imageType = VK_IMAGE_TYPE_2D;
image.format = format;
image.extent = VkExtent3D(extent);
image.samples = VK_SAMPLE_COUNT_1_BIT;
image.mipLevels = 1;
image.arrayLayers = 1;
image.tiling = VK_IMAGE_TILING_OPTIMAL;
image.usage = UnsignedInt(usage);
VkResult err = vkCreateImage(_device, &image, nullptr, &_image);
MAGNUM_VK_ASSERT_ERROR(err);
}
/** @brief Copying is not allowed */
Image(const Image&) = delete;
/** @brief Move constructor */
Image(Image&& other);
/**
* @brief Destructor
*
* @see @fn_vk{DestroyImage}
*/
~Image();
/** @brief Copying is not allowed */
Image& operator=(const Image&) = delete;
/** @brief Move assignment is not allowed */
Image& operator=(Image&&) = delete;
operator VkImage() const {
return _image;
}
VkMemoryRequirements getMemoryRequirements() {
VkMemoryRequirements memReqs;
vkGetImageMemoryRequirements(_device, _image, &memReqs);
return memReqs;
}
private:
Device& _device;
VkImage _image;
};
struct ImageMemoryBarrier {
ImageMemoryBarrier(const Image& image, ImageLayout src, ImageLayout dst,
VkImageSubresourceRange range,
AccessFlags srcAccessMask = {},
AccessFlags destAccessMask = {}):
_imageMemoryBarrier{
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
nullptr,
VkAccessFlags(srcAccessMask),
VkAccessFlags(destAccessMask),
VkImageLayout(src),
VkImageLayout(dst),
VK_QUEUE_FAMILY_IGNORED,
VK_QUEUE_FAMILY_IGNORED,
image,
range
}
{}
operator VkImageMemoryBarrier() const {
return _imageMemoryBarrier;
}
private:
VkImageMemoryBarrier _imageMemoryBarrier;
};
}}
#endif

36
src/Magnum/Vk/ImageView.cpp

@ -0,0 +1,36 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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 "ImageView.h"
namespace Magnum { namespace Vk {
ImageView::~ImageView() {
vkDestroyImageView(_device, _imageView, nullptr);
}
}}

110
src/Magnum/Vk/ImageView.h

@ -0,0 +1,110 @@
#ifndef Magnum_Vk_ImageView_h
#define Magnum_Vk_ImageView_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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::ImageView
*/
#include "Magnum/Magnum.h"
#include "Magnum/Vk/visibility.h"
#include "Magnum/Vk/Image.h"
#include "vulkan.h"
namespace Magnum { namespace Vk {
enum class ImageAspect: UnsignedInt {
Color = VK_IMAGE_ASPECT_COLOR_BIT,
Depth = VK_IMAGE_ASPECT_DEPTH_BIT,
Stencil = VK_IMAGE_ASPECT_STENCIL_BIT,
Metadata = VK_IMAGE_ASPECT_METADATA_BIT,
};
typedef Containers::EnumSet<ImageAspect> ImageAspects;
CORRADE_ENUMSET_OPERATORS(ImageAspects)
class MAGNUM_VK_EXPORT ImageView {
public:
ImageView(Device& device, Image& image, VkFormat format,
VkImageViewType type, ImageAspects aspects,
VkComponentMapping components = {}):
_device{device}
{
VkImageViewCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.viewType = type;
createInfo.format = format;
createInfo.subresourceRange = {
VkImageAspectFlags(aspects),
0, /* base mip level */
1, /* layer count */
0, /* base array layer */
1, /* layer count */
};
createInfo.image = image;
createInfo.components = components;
VkResult err = vkCreateImageView(_device, &createInfo, nullptr, &_imageView);
MAGNUM_VK_ASSERT_ERROR(err);
}
/** @brief Copying is not allowed */
ImageView(const ImageView&) = delete;
/** @brief Move constructor */
ImageView(ImageView&& other);
/**
* @brief Destructor
*
* @see @fn_vk{DestroyImageView}
*/
~ImageView();
/** @brief Copying is not allowed */
ImageView& operator=(const ImageView&) = delete;
/** @brief Move assignment is not allowed */
ImageView& operator=(ImageView&&) = delete;
operator VkImageView() const {
return _imageView;
}
private:
Device& _device;
VkImageView _imageView;
};
}}
#endif

53
src/Magnum/Vk/Math.h

@ -0,0 +1,53 @@
#ifndef Magnum_Vk_Math_h
#define Magnum_Vk_Math_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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
*/
#include <Magnum/Magnum.h>
#include <Magnum/Math/Range.h>
#include <Magnum/Math/Vector.h>
#include "vulkan.h"
namespace Magnum { namespace Math { namespace Implementation {
/* VkExtent3D */
template<> struct VectorConverter<3, UnsignedInt, VkExtent3D> {
static Vector<3, UnsignedInt> from(const VkExtent3D& other) {
return {other.width, other.height, other.depth};
}
static VkExtent3D to(const Vector<3, UnsignedInt>& other) {
return {other[0], other[1], other[2]};
}
};
}}}
#endif

98
src/Magnum/Vk/PhysicalDevice.cpp

@ -0,0 +1,98 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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 "PhysicalDevice.h"
#include <vector>
#include <Corrade/Utility/Assert.h>
#include <Corrade/Utility/Debug.h>
namespace Magnum { namespace Vk {
PhysicalDevice::~PhysicalDevice() {
}
VkFormat PhysicalDevice::getSupportedDepthFormat() {
// Since all depth formats may be optional, we need to find a suitable depth format to use
// Start with the highest precision packed format
std::vector<VkFormat> depthFormats = {
VK_FORMAT_D32_SFLOAT_S8_UINT,
VK_FORMAT_D32_SFLOAT,
VK_FORMAT_D24_UNORM_S8_UINT,
VK_FORMAT_D16_UNORM_S8_UINT,
VK_FORMAT_D16_UNORM
};
VkFormatProperties formatProps;
for(auto& format : depthFormats) {
vkGetPhysicalDeviceFormatProperties(_physicalDevice, format, &formatProps);
// Format must support depth stencil attachment for optimal tiling
if (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
return format;
}
}
return VK_FORMAT_UNDEFINED;
}
UnsignedInt PhysicalDevice::getQueueFamilyIndex(QueueFamily family) {
// Find a queue that supports graphics
UnsignedInt queueCount;
vkGetPhysicalDeviceQueueFamilyProperties(_physicalDevice, &queueCount, nullptr);
if(queueCount <= 0) { // TODO I belive there allways is at least one queue of a certain specified type, lookup in spec
Error() << "Physical Device does not provide queues"; // TODO
}
std::vector<VkQueueFamilyProperties> queueProps; // TODO Use NoInit Containers::Array
queueProps.resize(queueCount);
vkGetPhysicalDeviceQueueFamilyProperties(_physicalDevice, &queueCount, queueProps.data());
for(UnsignedInt i = 0; i < queueCount; ++i) {
if(queueProps[i].queueFlags & VkQueueFlags(family)) {
return i;
}
}
CORRADE_ASSERT(false, "The device does not support the given queue family.", -1); // TODO
}
UnsignedInt PhysicalDevice::getMemoryType(UnsignedInt typeBits, VkFlags properties) {
for (uint32_t i = 0; i < 32; i++) {
if((typeBits & 1) != 0) {
if((_deviceMemoryProperties.memoryTypes[i].propertyFlags & properties) == properties) {
return i;
}
}
typeBits >>= 1;
}
CORRADE_ASSERT(false, "Physical devices does not support memory with given properties.", -1); // TODO
}
}}

107
src/Magnum/Vk/PhysicalDevice.h

@ -0,0 +1,107 @@
#ifndef Magnum_Vk_PhysicalDevice_h
#define Magnum_Vk_PhysicalDevice_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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::PhysicalDevice
*/
#include "Magnum/Magnum.h"
#include "Magnum/Vk/visibility.h"
#include "vulkan.h"
namespace Magnum { namespace Vk {
enum class QueueFamily: UnsignedInt {
Graphics = VK_QUEUE_GRAPHICS_BIT,
Compute = VK_QUEUE_COMPUTE_BIT,
Transfer = VK_QUEUE_TRANSFER_BIT,
};
enum class QueueFlag: UnsignedInt {
SparseBinding = VK_QUEUE_SPARSE_BINDING_BIT,
};
class MAGNUM_VK_EXPORT PhysicalDevice {
public:
/** @brief Copying is not allowed */
PhysicalDevice(const PhysicalDevice&) = delete;
/** @brief Move constructor */
PhysicalDevice(PhysicalDevice&& other);
/**
* @brief Construct from VkPhysicalDevice
*/
PhysicalDevice(const VkPhysicalDevice& device):
_physicalDevice(device)
{
// Gather physical device memory properties
vkGetPhysicalDeviceMemoryProperties(_physicalDevice, &_deviceMemoryProperties);
}
/** @brief Destructor */
~PhysicalDevice();
/** @brief Copying is not allowed */
PhysicalDevice& operator=(const PhysicalDevice&) = delete;
/** @brief Move assignment is not allowed */
PhysicalDevice& operator=(PhysicalDevice&&) = delete;
/**
* @brief Get the underlying VkPhysicalDevice handle
*/
VkPhysicalDevice vkPhysicalDevice() {
return _physicalDevice;
}
VkFormat getSupportedDepthFormat();
UnsignedInt getQueueFamilyIndex(QueueFamily family);
VkPhysicalDeviceProperties getProperties() {
VkPhysicalDeviceProperties deviceProperties;
vkGetPhysicalDeviceProperties(_physicalDevice, &deviceProperties);
return deviceProperties;
}
UnsignedInt getMemoryType(UnsignedInt typeBits, VkFlags properties);
private:
VkPhysicalDevice _physicalDevice;
VkPhysicalDeviceMemoryProperties _deviceMemoryProperties;
};
}}
#endif

100
src/Magnum/Vk/Pipeline.cpp

@ -0,0 +1,100 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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 "Pipeline.h"
namespace Magnum { namespace Vk {
Pipeline::~Pipeline() {
vkDestroyPipeline(_device, _pipeline, nullptr);
vkDestroyPipelineLayout(_device, _layout, nullptr);
vkDestroyPipelineCache(_device, _cache, nullptr);
}
std::unique_ptr<Pipeline> GraphicsPipelineFactory::create() {
VkPipeline pipeline;
VkPipelineCache cache;
VkPipelineLayout layout;
/* create pipeline layout */
VkPipelineLayoutCreateInfo plInfo = {
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
nullptr,
0,
_setLayouts.size(),
_setLayouts.data(),
_pushConstantRanges.size(),
_pushConstantRanges.data()
};
VkResult err = vkCreatePipelineLayout(_device, &plInfo, nullptr, &layout);
MAGNUM_VK_ASSERT_ERROR(err);
/* create pipeline cache */
VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {
VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
nullptr,
0,
0, /* initial data size */
nullptr /* initial data */
};
err = vkCreatePipelineCache(_device, &pipelineCacheCreateInfo, nullptr, &cache);
MAGNUM_VK_ASSERT_ERROR(err);
/* create pipeline itself */
VkPipelineDynamicStateCreateInfo dynamicState = {
VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
nullptr,
0,
_dynamicStates.size(),
reinterpret_cast<VkDynamicState*>(_dynamicStates.data())
};
VkGraphicsPipelineCreateInfo pipelineInfo = {};
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
pipelineInfo.pNext = nullptr;
pipelineInfo.layout = layout;
pipelineInfo.renderPass = *_renderPass;
pipelineInfo.pInputAssemblyState = &_inputAssemblyState;
pipelineInfo.pVertexInputState = &_vertexInputState;
pipelineInfo.pRasterizationState = &_rasterizationState;
pipelineInfo.pColorBlendState = &_colorBlendState;
pipelineInfo.pMultisampleState = &_multisampleState;
pipelineInfo.pViewportState = &_viewportState;
pipelineInfo.pDepthStencilState = &_depthStencilState;
pipelineInfo.stageCount = _shaderStages.size();
pipelineInfo.pStages = _shaderStages.data();
pipelineInfo.pDynamicState = &dynamicState;
err = vkCreateGraphicsPipelines(_device, cache, 1, &pipelineInfo, nullptr, &pipeline);
MAGNUM_VK_ASSERT_ERROR(err);
return std::unique_ptr<Pipeline>{new Pipeline{_device, pipeline, cache, layout}};
}
}}

364
src/Magnum/Vk/Pipeline.h

@ -0,0 +1,364 @@
#ifndef Magnum_Vk_GraphicsPipeline_h
#define Magnum_Vk_GraphicsPipeline_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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::GraphicsPipeline
*/
#include "Magnum/Magnum.h"
#include "Magnum/Vk/visibility.h"
#include "Magnum/Vk/Device.h"
#include "Magnum/Vk/RenderPass.h"
#include "Magnum/Vk/Shader.h"
#include "Magnum/Math/Vector3.h" // TEMPORARY!!!
#include <Corrade/Containers/Array.h>
#include "vulkan.h"
namespace Magnum { namespace Vk {
enum class ShaderStage: UnsignedInt {
Vertex = VK_SHADER_STAGE_VERTEX_BIT,
TesslationControl = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
TesslationEvaluation = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
Geometry = VK_SHADER_STAGE_GEOMETRY_BIT,
Fragment = VK_SHADER_STAGE_FRAGMENT_BIT,
Compute = VK_SHADER_STAGE_COMPUTE_BIT,
AllGraphics = VK_SHADER_STAGE_ALL_GRAPHICS,
All = VK_SHADER_STAGE_ALL,
};
enum class DynamicState: UnsignedInt {
Viewport = VK_DYNAMIC_STATE_VIEWPORT,
Scissor = VK_DYNAMIC_STATE_SCISSOR,
LineWidth = VK_DYNAMIC_STATE_LINE_WIDTH,
DepthBias = VK_DYNAMIC_STATE_DEPTH_BIAS,
BlendConstant = VK_DYNAMIC_STATE_BLEND_CONSTANTS,
DepthBounds = VK_DYNAMIC_STATE_DEPTH_BOUNDS,
CompareMask = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
WriteMask = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
StencilReference = VK_DYNAMIC_STATE_STENCIL_REFERENCE,
};
enum class Topology: UnsignedInt {
PointList = VK_PRIMITIVE_TOPOLOGY_POINT_LIST,
LineList = VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
LineStrip = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
TriangleList = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
TriangleStrip = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
TriangleFan = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,
LineListWithAdjacency = VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY,
LineStripWithAdjacency = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY,
TriangleListWithAdjacency = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY,
TriangleStripWithAdjacency = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY,
PatchList = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,
};
enum class PipelineStage: UnsignedInt {
TopOfThePipe = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
DrawIndirect = VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
VertexInput = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
VertexShader = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
TesslationControlShader = VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT,
TesslationEvaluationShader = VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT,
GeometryShader = VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT,
FragmentShader = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
EarlyFragmentTest = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
LateFragmentTests = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
ColorAttachmentOutput = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
ComputeShader = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
StageTransfer = VK_PIPELINE_STAGE_TRANSFER_BIT,
BottomOfPipe = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
Host = VK_PIPELINE_STAGE_HOST_BIT,
AllGraphics = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
AllCommands = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT
};
typedef Containers::EnumSet<PipelineStage> PipelineStageFlags;
enum class BindPoint: UnsignedInt {
Graphics = VK_PIPELINE_BIND_POINT_GRAPHICS,
Compute = VK_PIPELINE_BIND_POINT_COMPUTE,
};
class MAGNUM_VK_EXPORT Pipeline {
public:
Pipeline(Device& device, VkPipeline pipeline, VkPipelineCache cache, VkPipelineLayout layout):
_device{device},
_pipeline{pipeline},
_cache{cache},
_layout{layout}
{}
/** @brief Copying is not allowed */
Pipeline(const Pipeline&) = delete;
/** @brief Move constructor */
Pipeline(Pipeline&& other);
/**
* @brief Destructor
*
* @see @fn_vk{DestroyPipeline}
*/
~Pipeline();
/** @brief Copying is not allowed */
Pipeline& operator=(const Pipeline&) = delete;
/** @brief Move assignment is not allowed */
Pipeline& operator=(Pipeline&&) = delete;
operator VkPipeline() const {
return _pipeline;
}
VkPipelineLayout layout() {
return _layout;
}
auto bind(BindPoint bindPoint, std::initializer_list<VkDescriptorSet> descriptorSets) {
const VkPipelineLayout pl = _layout;
return [bindPoint, &descriptorSets, pl](VkCommandBuffer cmdBuffer){
vkCmdBindDescriptorSets(cmdBuffer,
VkPipelineBindPoint(bindPoint),
pl, 0,
descriptorSets.size(), std::vector<VkDescriptorSet>(descriptorSets).data(),
0, nullptr);
};
}
private:
Device& _device;
VkPipeline _pipeline;
VkPipelineCache _cache;
VkPipelineLayout _layout;
};
class MAGNUM_VK_EXPORT GraphicsPipelineFactory {
public:
GraphicsPipelineFactory(Device& device):
_device{device} {
_inputAssemblyState = {
VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
nullptr,
0,
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
0 /* primitive restart enable */
};
_multisampleState = {
VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, nullptr, 0,
VK_SAMPLE_COUNT_1_BIT,
VK_FALSE,
0.0f,
nullptr,
VK_FALSE,
VK_FALSE
};
_depthStencilState = {
VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
nullptr,
0,
VK_TRUE, /* depth test enable */
VK_TRUE, /* depth write enable */
VK_COMPARE_OP_LESS_OR_EQUAL, /* depth compare op */
VK_FALSE, /* depth bounds test enable */
VK_FALSE, /* stencil test enable */
VkStencilOpState{VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_NEVER, 0, 0, 0}, /* front */
VkStencilOpState{VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_NEVER, 0, 0, 0}, /* back */
0.0f, 0.0f /* depth bounds */
};
_rasterizationState = {
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
nullptr,
0,
VK_FALSE, /* depth clamp enable */
VK_FALSE, /* rasterizer discard enable */
VK_POLYGON_MODE_FILL, /* poygon mode */
VK_CULL_MODE_NONE, /* cull mode */
VK_FRONT_FACE_COUNTER_CLOCKWISE, /* front face */
VK_FALSE, /* depth bias enable */
0.0f, 0.0f, 0.0f, 0.0f
};
VkPipelineColorBlendAttachmentState blendAttachmentState = {
VK_FALSE,
VK_BLEND_FACTOR_ZERO,
VK_BLEND_FACTOR_ZERO,
VK_BLEND_OP_ADD,
VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ZERO,
VK_BLEND_OP_ADD,
0xf
};
_blendAttachments.push_back(blendAttachmentState);
_colorBlendState = {
VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
nullptr,
0,
VK_FALSE,
VK_LOGIC_OP_CLEAR,
_blendAttachments.size(),
_blendAttachments.data(),
{0.0f, 0.0f, 0.0f, 0.0f}
};
_viewportState = {
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
nullptr,
0,
1,
nullptr, // TODO currently expecting dynamic state here...
1,
nullptr
};
VkVertexInputBindingDescription bindingDesc;
bindingDesc.binding = 0;
bindingDesc.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
bindingDesc.stride = sizeof(Vector3)*2;
_vertexInputBindings.push_back(bindingDesc);
VkVertexInputAttributeDescription attributeDesc[2];
attributeDesc[0].binding = 0;
attributeDesc[0].location = 0;
attributeDesc[0].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDesc[0].offset = 0;
_vertexInputAttrbutes.push_back(attributeDesc[0]);
// Color
attributeDesc[1].binding = 0;
attributeDesc[1].location = 1;
attributeDesc[1].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDesc[1].offset = sizeof(Vector3);
_vertexInputAttrbutes.push_back(attributeDesc[1]);
_vertexInputState = {
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
nullptr,
0,
_vertexInputBindings.size(),
_vertexInputBindings.data(),
_vertexInputAttrbutes.size(),
_vertexInputAttrbutes.data(),
};
}
/** @brief Copying is not allowed */
GraphicsPipelineFactory(const GraphicsPipelineFactory&) = delete;
/** @brief Move constructor */
GraphicsPipelineFactory(GraphicsPipelineFactory&& other);
/**
* @brief Destructor
*
* @see @fn_vk{DestroyPipeline}
*/
~GraphicsPipelineFactory() {
}
/** @brief Copying is not allowed */
GraphicsPipelineFactory& operator=(const GraphicsPipelineFactory&) = delete;
/** @brief Move assignment is not allowed */
GraphicsPipelineFactory& operator=(GraphicsPipelineFactory&&) = delete;
GraphicsPipelineFactory& addShader(ShaderStage stage, Shader& shader) {
VkPipelineShaderStageCreateInfo shaderStage = {
VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
nullptr,
0,
VkShaderStageFlagBits(stage),
shader.vkShaderModule(),
"main",
nullptr // TODO: SpecializationInfo?
};
_shaderStages.push_back(shaderStage);
return *this;
}
std::unique_ptr<Pipeline> create();
GraphicsPipelineFactory& setRenderPass(RenderPass& renderPass) {
_renderPass = &renderPass;
return *this;
}
GraphicsPipelineFactory& setTopology(Topology topology) {
_inputAssemblyState.topology = VkPrimitiveTopology(topology);
return *this;
}
GraphicsPipelineFactory& setDynamicStates(std::initializer_list<DynamicState> states) {
_dynamicStates = std::vector<DynamicState>(states);
return *this;
}
GraphicsPipelineFactory& addDescriptorSetLayout(const VkDescriptorSetLayout& layout) {
_setLayouts.push_back(layout);
return *this;
}
private:
Device& _device;
VkGraphicsPipelineCreateInfo _createInfo;
VkPipelineInputAssemblyStateCreateInfo _inputAssemblyState;
VkPipelineVertexInputStateCreateInfo _vertexInputState;
VkPipelineRasterizationStateCreateInfo _rasterizationState;
VkPipelineColorBlendStateCreateInfo _colorBlendState;
VkPipelineMultisampleStateCreateInfo _multisampleState;
VkPipelineViewportStateCreateInfo _viewportState;
VkPipelineDepthStencilStateCreateInfo _depthStencilState;
std::vector<DynamicState> _dynamicStates;
std::vector<VkPipelineColorBlendAttachmentState> _blendAttachments;
std::vector<VkDescriptorSetLayout> _setLayouts;
std::vector<VkVertexInputBindingDescription> _vertexInputBindings;
std::vector<VkVertexInputAttributeDescription> _vertexInputAttrbutes;
std::vector<VkPushConstantRange> _pushConstantRanges;
RenderPass* _renderPass;
std::vector<VkPipelineShaderStageCreateInfo> _shaderStages;
};
}}
#endif

83
src/Magnum/Vk/Queue.cpp

@ -0,0 +1,83 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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 "Queue.h"
namespace Magnum { namespace Vk {
Queue::~Queue() {
}
Queue& Queue::submit(const CommandBuffer& cmdBuffer) {
const VkCommandBuffer cb = cmdBuffer;
VkSubmitInfo submitInfo = {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &cb;
VkResult err = vkQueueSubmit(_queue, 1, &submitInfo, VK_NULL_HANDLE);
MAGNUM_VK_ASSERT_ERROR(err);
return *this;
}
Queue& Queue::submit(const CommandBuffer& cmdBuffer,
std::vector<std::reference_wrapper<Semaphore>> waitSemaphores,
std::vector<std::reference_wrapper<Semaphore>> signalSemaphores) {
const VkCommandBuffer cb = cmdBuffer;
VkPipelineStageFlags pipelineDstStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; // TODO: Expose
VkSubmitInfo submitInfo = {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.pWaitDstStageMask = &pipelineDstStage;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &cb;
std::vector<VkSemaphore> waitSems;
waitSems.reserve(waitSemaphores.size());
for(Semaphore& sem : waitSemaphores) {
waitSems.push_back(sem.vkSemaphore());
}
std::vector<VkSemaphore> sigSems;
sigSems.reserve(waitSemaphores.size());
for(Semaphore& sem : signalSemaphores) {
sigSems.push_back(sem.vkSemaphore());
}
submitInfo.waitSemaphoreCount = waitSemaphores.size();
submitInfo.pWaitSemaphores = waitSems.data();
submitInfo.signalSemaphoreCount = signalSemaphores.size();
submitInfo.pSignalSemaphores = sigSems.data();
VkResult err = vkQueueSubmit(_queue, 1, &submitInfo, VK_NULL_HANDLE);
MAGNUM_VK_ASSERT_ERROR(err);
return *this;
}
}}

90
src/Magnum/Vk/Queue.h

@ -0,0 +1,90 @@
#ifndef Magnum_Vk_Queue_h
#define Magnum_Vk_Queue_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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::Queue
*/
#include "Magnum/Magnum.h"
#include "Magnum/Vk/CommandBuffer.h"
#include "Magnum/Vk/Context.h"
#include "Magnum/Vk/Device.h"
#include "Magnum/Vk/Semaphore.h"
#include "Magnum/Vk/visibility.h"
namespace Magnum { namespace Vk {
class MAGNUM_VK_EXPORT Queue {
public:
/** @brief Copying is not allowed */
Queue(const Context&) = delete;
/** @brief Move constructor */
Queue(Queue&& other);
Queue(Device& device, UnsignedInt familyIndex, UnsignedInt queueIndex): _device{device} {
vkGetDeviceQueue(_device, familyIndex, queueIndex, &_queue);
}
/**
* @brief Destructor
*
* @see @fn_vk{DestroyQueue}
*/
~Queue();
/** @brief Copying is not allowed */
Queue& operator=(const Queue&) = delete;
/** @brief Move assignment is not allowed */
Queue& operator=(Queue&&) = delete;
VkQueue vkQueue() {
return _queue;
}
Queue& waitIdle() {
VkResult err = vkQueueWaitIdle(_queue);
MAGNUM_VK_ASSERT_ERROR(err);
return *this;
}
Queue& submit(const CommandBuffer& cmdBuffer);
Queue& submit(const CommandBuffer& cmdBuffer, std::vector<std::reference_wrapper<Semaphore>> waitSemaphores, std::vector<std::reference_wrapper<Semaphore>> signalSemaphores);
private:
VkQueue _queue;
Device& _device;
};
}}
#endif

37
src/Magnum/Vk/RenderPass.cpp

@ -0,0 +1,37 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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 "RenderPass.h"
namespace Magnum { namespace Vk {
RenderPass::~RenderPass() {
if (_device != nullptr)
vkDestroyRenderPass(*_device, _renderPass, nullptr);
}
}}

139
src/Magnum/Vk/RenderPass.h

@ -0,0 +1,139 @@
#ifndef Magnum_Vk_RenderPass_h
#define Magnum_Vk_RenderPass_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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::RenderPass
*/
#include "Magnum/Magnum.h"
#include "Magnum/Vk/Device.h"
#include "Magnum/Vk/visibility.h"
#include "vulkan.h"
namespace Magnum { namespace Vk {
class MAGNUM_VK_EXPORT RenderPass {
public:
RenderPass(NoCreateT) noexcept: _device{nullptr} {
}
RenderPass(Device& device, VkFormat depthFormat): _device{&device} {
VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
VkAttachmentDescription attachments[2];
attachments[0].format = VK_FORMAT_B8G8R8A8_UNORM;
attachments[0].samples = sampleCount;
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachments[1].format = depthFormat;
attachments[1].samples = sampleCount;
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachments[1].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkAttachmentReference colorReference = {};
colorReference.attachment = 0;
colorReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentReference depthReference = {};
depthReference.attachment = 1;
depthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkSubpassDescription subpass = {};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.flags = 0;
subpass.inputAttachmentCount = 0;
subpass.pInputAttachments = nullptr;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &colorReference;
subpass.pResolveAttachments = nullptr;
subpass.pDepthStencilAttachment = &depthReference;
subpass.preserveAttachmentCount = 0;
subpass.pPreserveAttachments = nullptr;
VkRenderPassCreateInfo renderPassInfo = {};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassInfo.pNext = nullptr;
renderPassInfo.attachmentCount = 2;
renderPassInfo.pAttachments = attachments;
renderPassInfo.subpassCount = 1;
renderPassInfo.pSubpasses = &subpass;
renderPassInfo.dependencyCount = 0;
renderPassInfo.pDependencies = nullptr;
VkResult err = vkCreateRenderPass(*_device, &renderPassInfo, nullptr, &_renderPass);
MAGNUM_VK_ASSERT_ERROR(err);
}
/** @brief Copying is not allowed */
RenderPass(const RenderPass&) = delete;
/** @brief Move constructor */
RenderPass(RenderPass&& other): _device{other._device}, _renderPass{other._renderPass}{
other._renderPass = VK_NULL_HANDLE;
}
/**
* @brief Destructor
*
* @see @fn_vk{DestroyRenderPass}
*/
~RenderPass();
/** @brief Copying is not allowed */
RenderPass& operator=(const RenderPass&) = delete;
RenderPass& operator=(RenderPass&& sem) noexcept {
std::swap(_renderPass, sem._renderPass);
std::swap(_device, sem._device);
return *this;
}
operator VkRenderPass() const {
return _renderPass;
}
private:
Device* _device;
VkRenderPass _renderPass;
};
}}
#endif

34
src/Magnum/Vk/Semaphore.cpp

@ -0,0 +1,34 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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 "Semaphore.h"
namespace Magnum { namespace Vk {
Semaphore::Semaphore(NoCreateT) noexcept: _semaphore(VK_NULL_HANDLE), _device{nullptr} {}
}}

94
src/Magnum/Vk/Semaphore.h

@ -0,0 +1,94 @@
#ifndef Magnum_Vk_Semaphore_h
#define Magnum_Vk_Semaphore_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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::Semaphore
*/
#include "Magnum/Magnum.h"
#include "Magnum/Vk/Device.h"
namespace Magnum { namespace Vk {
class MAGNUM_VK_EXPORT Semaphore {
public:
explicit Semaphore(NoCreateT) noexcept;
/** @brief Constructor */
explicit Semaphore(Device& device):
_semaphore(VK_NULL_HANDLE),
_device(&device)
{
constexpr VkSemaphoreCreateInfo semaphoreCreateInfo{VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
VkResult err = vkCreateSemaphore(_device->vkDevice(), &semaphoreCreateInfo, nullptr, &_semaphore);
MAGNUM_VK_ASSERT_ERROR(err);
}
/**
* @brief Destructor
*
* @see @fn_vk{DestroySemaphore}
*/
~Semaphore() {
/* NoCreate constructor initializes _device with nullptr */
if (_device != nullptr) {
vkDestroySemaphore(_device->vkDevice(), _semaphore, nullptr);
}
}
/** @brief Copying is not allowed */
Semaphore(const Semaphore& sem) = delete;
/** @brief Move assignment */
Semaphore& operator=(Semaphore&& sem) noexcept {
std::swap(_semaphore, sem._semaphore);
std::swap(_device, sem._device);
return *this;
}
/** @brief Move constructor */
Semaphore(Semaphore&& sem): _semaphore{sem.vkSemaphore()}, _device{sem._device} {
sem._semaphore = VK_NULL_HANDLE;
}
/** @brief Get the underlying VkSemaphore handle */
VkSemaphore& vkSemaphore() {
return _semaphore;
}
private:
VkSemaphore _semaphore;
Device* _device;
};
}}
#endif

36
src/Magnum/Vk/Shader.cpp

@ -0,0 +1,36 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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 "Shader.h"
namespace Magnum { namespace Vk {
Shader::~Shader() {
vkDestroyShaderModule(_device, _shaderModule, nullptr);
}
}}

88
src/Magnum/Vk/Shader.h

@ -0,0 +1,88 @@
#ifndef Magnum_Vk_Shader_h
#define Magnum_Vk_Shader_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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::Shader
*/
#include <Corrade/Containers/Array.h>
#include "Magnum/Magnum.h"
#include "Magnum/Vk/visibility.h"
#include "Magnum/Vk/Device.h"
#include <vulkan.h>
namespace Magnum { namespace Vk {
class MAGNUM_VK_EXPORT Shader {
public:
Shader(Device& device, const Containers::Array<char>& shaderCode): _device{device} {
VkShaderModuleCreateInfo moduleCreateInfo;
moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
moduleCreateInfo.pNext = nullptr;
moduleCreateInfo.codeSize = shaderCode.size();
moduleCreateInfo.pCode = reinterpret_cast<const uint32_t*>(shaderCode.data());
moduleCreateInfo.flags = 0;
const VkResult err = vkCreateShaderModule(device.vkDevice(), &moduleCreateInfo, nullptr, &_shaderModule);
MAGNUM_VK_ASSERT_ERROR(err);
}
/** @brief Copying is not allowed */
Shader(const Shader&) = delete;
/** @brief Move constructor */
Shader(Shader&& other);
/**
* @brief Destructor
*
* @see @fn_vk{DestroyShader}
*/
~Shader();
/** @brief Copying is not allowed */
Shader& operator=(const Shader&) = delete;
/** @brief Move assignment is not allowed */
Shader& operator=(Shader&&) = delete;
VkShaderModule vkShaderModule() {
return _shaderModule;
}
private:
VkShaderModule _shaderModule;
Device& _device;
};
}}
#endif

316
src/Magnum/Vk/Swapchain.cpp

@ -0,0 +1,316 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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 "Swapchain.h"
#include "Magnum/Vk/Queue.h"
#include "Magnum/Vk/ImageView.h"
namespace Magnum { namespace Vk {
// TODO Wrap surface
Swapchain::Swapchain(Device& device, CommandBuffer& cb, VkSurfaceKHR surface):
_device{device},
_surface{surface},
_swapchain{VK_NULL_HANDLE},
_currentIndex{0}
{
VkDevice vkDevice = _device.vkDevice();
VkPhysicalDevice vkPhysicalDevice = _device.physicalDevice().vkPhysicalDevice();
#define GET_INSTANCE_PROC_ADDR(entrypoint) vk##entrypoint = PFN_vk##entrypoint(vkGetInstanceProcAddr(Vk::Context::current().vkInstance(), "vk"#entrypoint)); do{if(vk##entrypoint == nullptr) { Error() << "Failed to get function pointer.";} }while(false)
#define GET_DEVICE_PROC_ADDR(entrypoint) vk##entrypoint = PFN_vk##entrypoint(vkGetDeviceProcAddr(vkDevice, "vk"#entrypoint)); do{ if(vk##entrypoint == nullptr) { Error() << "Failed to get function pointer.";} }while(false)
GET_INSTANCE_PROC_ADDR(GetPhysicalDeviceSurfaceSupportKHR);
GET_INSTANCE_PROC_ADDR(GetPhysicalDeviceSurfaceCapabilitiesKHR);
GET_INSTANCE_PROC_ADDR(GetPhysicalDeviceSurfaceFormatsKHR);
GET_INSTANCE_PROC_ADDR(GetPhysicalDeviceSurfacePresentModesKHR);
GET_DEVICE_PROC_ADDR(CreateSwapchainKHR);
GET_DEVICE_PROC_ADDR(DestroySwapchainKHR);
GET_DEVICE_PROC_ADDR(GetSwapchainImagesKHR);
GET_DEVICE_PROC_ADDR(AcquireNextImageKHR);
GET_DEVICE_PROC_ADDR(QueuePresentKHR);
#undef GET_INSTANCE_PROC_ADDR
#undef GET_DEVICE_PROC_ADDR
VkResult err;
// Get available queue family properties
uint32_t queueCount;
vkGetPhysicalDeviceQueueFamilyProperties(vkPhysicalDevice,
&queueCount, nullptr);
assert(queueCount >= 1);
std::vector<VkQueueFamilyProperties> queueProps(queueCount);
vkGetPhysicalDeviceQueueFamilyProperties(vkPhysicalDevice,
&queueCount, queueProps.data());
std::vector<VkBool32> supportsPresent(queueCount);
for (uint32_t i = 0; i < queueCount; i++) {
vkGetPhysicalDeviceSurfaceSupportKHR(vkPhysicalDevice,
i, surface, &supportsPresent[i]);
}
// Search for a graphics and a present queue in the array of queue
// families, try to find one that supports both
uint32_t graphicsQueueNodeIndex = UINT32_MAX;
uint32_t presentQueueNodeIndex = UINT32_MAX;
for (uint32_t i = 0; i < queueCount; i++) {
if ((queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0) {
if (graphicsQueueNodeIndex == UINT32_MAX) {
graphicsQueueNodeIndex = i;
}
if (supportsPresent[i] == VK_TRUE) {
graphicsQueueNodeIndex = i;
presentQueueNodeIndex = i;
break;
} else {
Warning() << "Queue" << i << "does not support present.";
}
}
}
if (presentQueueNodeIndex == UINT32_MAX) {
// If there's no queue that supports both present and graphics
// try to find a separate present queue
for (uint32_t i = 0; i < queueCount; ++i) {
if (supportsPresent[i] == VK_TRUE) {
presentQueueNodeIndex = i;
break;
}
}
}
// Exit if either a graphics or a presenting queue hasn't been found
if (graphicsQueueNodeIndex == UINT32_MAX || presentQueueNodeIndex == UINT32_MAX) {
return; // fatal
}
// todo : Add support for separate graphics and presenting queue
if (graphicsQueueNodeIndex != presentQueueNodeIndex) {
Error() << "I am unsure about this error in Swapchain.cpp#L" << __LINE__;
return; // fatal
}
// Get list of supported surface formats
UnsignedInt formatCount;
err = vkGetPhysicalDeviceSurfaceFormatsKHR(vkPhysicalDevice, surface, &formatCount, nullptr);
MAGNUM_VK_ASSERT_ERROR(err);
if(formatCount < 1) {
Error() << "The device does not support any surface formats."; // TODO: Can this even happen?
return;
}
std::vector<VkSurfaceFormatKHR> surfaceFormats(formatCount);
err = vkGetPhysicalDeviceSurfaceFormatsKHR(vkPhysicalDevice,
_surface, &formatCount,
surfaceFormats.data());
MAGNUM_VK_ASSERT_ERROR(err);
VkColorSpaceKHR colorSpace = surfaceFormats[0].colorSpace;
VkFormat colorFormat = VK_FORMAT_B8G8R8A8_UNORM;
if ((formatCount == 1) && (surfaceFormats[0].format == VK_FORMAT_UNDEFINED)) {
/* no preferred format */
colorFormat = VK_FORMAT_B8G8R8A8_UNORM;
} else {
// Always select the first available color format
// If you need a specific format (e.g. SRGB) you'd need to
// iterate over the list of available surface format and
// check for it's presence
colorFormat = surfaceFormats[0].format;
}
// Get physical device surface properties and formats
VkSurfaceCapabilitiesKHR surfCaps;
err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vkPhysicalDevice,
surface, &surfCaps);
MAGNUM_VK_ASSERT_ERROR(err);
// Get available present modes
UnsignedInt presentModeCount;
err = vkGetPhysicalDeviceSurfacePresentModesKHR(vkPhysicalDevice,
surface, &presentModeCount, nullptr);
MAGNUM_VK_ASSERT_ERROR(err);
if (presentModeCount < 1) {
Error() << "The device does not support any surface present mode."; // TODO: Can this even happen?
}
std::vector<VkPresentModeKHR> presentModes(presentModeCount);
err = vkGetPhysicalDeviceSurfacePresentModesKHR(vkPhysicalDevice,
surface, &presentModeCount,
presentModes.data());
MAGNUM_VK_ASSERT_ERROR(err);
VkExtent2D swapchainExtent = surfCaps.currentExtent;
if (surfCaps.currentExtent.width == UnsignedInt(-1)) {
Error() << "The surface has undefined extents.";
return;
}
VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
for (auto presentMode : presentModes) {
if (presentMode == VK_PRESENT_MODE_MAILBOX_KHR) {
swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
break;
}
if ((swapchainPresentMode != VK_PRESENT_MODE_MAILBOX_KHR) && (presentMode == VK_PRESENT_MODE_IMMEDIATE_KHR)) {
swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
}
}
UnsignedInt desiredNumberOfSwapchainImages = surfCaps.minImageCount + 1;
if ((surfCaps.maxImageCount > 0) && (desiredNumberOfSwapchainImages > surfCaps.maxImageCount)) {
desiredNumberOfSwapchainImages = surfCaps.maxImageCount;
}
VkSurfaceTransformFlagsKHR preTransform;
if (surfCaps.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
} else {
preTransform = surfCaps.currentTransform;
}
VkSwapchainKHR oldSwapchain = _swapchain;
VkSwapchainCreateInfoKHR swapchainCI = {};
swapchainCI.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
swapchainCI.pNext = nullptr;
swapchainCI.flags = 0;
swapchainCI.surface = _surface;
swapchainCI.imageFormat = colorFormat;
swapchainCI.imageColorSpace = colorSpace;
swapchainCI.imageExtent = swapchainExtent;
swapchainCI.minImageCount = desiredNumberOfSwapchainImages;
swapchainCI.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
swapchainCI.preTransform = VkSurfaceTransformFlagBitsKHR(preTransform);
swapchainCI.imageArrayLayers = 1;
swapchainCI.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
swapchainCI.queueFamilyIndexCount = 0;
swapchainCI.pQueueFamilyIndices = nullptr;
swapchainCI.presentMode = swapchainPresentMode;
swapchainCI.oldSwapchain = VK_NULL_HANDLE;
swapchainCI.clipped = VK_TRUE;
swapchainCI.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
err = vkCreateSwapchainKHR(vkDevice, &swapchainCI, nullptr, &_swapchain);
MAGNUM_VK_ASSERT_ERROR(err);
// If an existing sawp chain is re-created, destroy the old swap chain
// This also cleans up all the presentable images
if (oldSwapchain != VK_NULL_HANDLE) {
vkDestroySwapchainKHR(vkDevice, oldSwapchain, nullptr);
}
UnsignedInt imageCount = 0;
err = vkGetSwapchainImagesKHR(vkDevice, _swapchain, &imageCount, nullptr);
MAGNUM_VK_ASSERT_ERROR(err);
std::vector<VkImage> images;
images.resize(imageCount);
err = vkGetSwapchainImagesKHR(vkDevice, _swapchain, &imageCount, images.data());
MAGNUM_VK_ASSERT_ERROR(err);
_buffers.resize(imageCount);
for (uint32_t i = 0; i < imageCount; i++) {
_buffers[i].image.reset(new Vk::Image(_device, images[i]));
// Create an image barrier object
VkImageMemoryBarrier imageMemoryBarrier = {
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
nullptr,
0, /* src access mask */
0, /* dst access mask */
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
VK_QUEUE_FAMILY_IGNORED,
VK_QUEUE_FAMILY_IGNORED,
*_buffers[i].image,
VkImageSubresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}
};
vkCmdPipelineBarrier(
cb,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
0,
0, nullptr,
0, nullptr,
1, &imageMemoryBarrier);
_buffers[i].view.reset(
new Vk::ImageView(_device, *_buffers[i].image, colorFormat,
VK_IMAGE_VIEW_TYPE_2D, ImageAspect::Color,
VkComponentMapping{
VK_COMPONENT_SWIZZLE_R,
VK_COMPONENT_SWIZZLE_G,
VK_COMPONENT_SWIZZLE_B,
VK_COMPONENT_SWIZZLE_A
}
)
);
}
}
Swapchain::~Swapchain() {
vkDestroySwapchainKHR(_device, _swapchain, nullptr);
vkDestroySurfaceKHR(Vk::Context::current().vkInstance(), _surface, nullptr);
}
Swapchain& Swapchain::queuePresent(VkQueue queue, UnsignedInt currentBuffer) {
VkPresentInfoKHR presentInfo = {};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.pNext = nullptr;
presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = &_swapchain;
presentInfo.pImageIndices = &currentBuffer;
VkResult err = vkQueuePresentKHR(queue, &presentInfo);
MAGNUM_VK_ASSERT_ERROR(err);
return *this;
}
Swapchain& Swapchain::queuePresent(Queue& queue, UnsignedInt currentBuffer, Semaphore& waitSemaphore) {
VkSemaphore sem = waitSemaphore.vkSemaphore();
VkPresentInfoKHR presentInfo = {};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.pNext = nullptr;
presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = &_swapchain;
presentInfo.pImageIndices = &currentBuffer;
presentInfo.pWaitSemaphores = &sem;
presentInfo.waitSemaphoreCount = 1;
VkResult err = vkQueuePresentKHR(queue.vkQueue(), &presentInfo);
MAGNUM_VK_ASSERT_ERROR(err);
return *this;
}
}}

155
src/Magnum/Vk/Swapchain.h

@ -0,0 +1,155 @@
#ifndef Magnum_Vk_Swapchain_h
#define Magnum_Vk_Swapchain_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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::Swapchain
*/
#include "Magnum/Magnum.h"
#include "Magnum/Vk/CommandBuffer.h"
#include "Magnum/Vk/Context.h"
#include "Magnum/Vk/Device.h"
#include "Magnum/Vk/ImageView.h"
#include "Magnum/Vk/Semaphore.h"
#include "Magnum/Vk/visibility.h"
namespace Magnum { namespace Vk {
typedef struct {
std::unique_ptr<Image> image;
std::unique_ptr<ImageView> view;
} SwapchainBuffer;
class MAGNUM_VK_EXPORT Swapchain {
public:
Swapchain(Device& device, CommandBuffer& cb, VkSurfaceKHR surface);
/** @brief Copying is not allowed */
Swapchain(const Swapchain&) = delete;
/** @brief Move constructor */
Swapchain(Swapchain&& other);
/**
* @brief Destructor
*
* @see @fn_vk{DestroySwapchain}
*/
~Swapchain();
/** @brief Copying is not allowed */
Swapchain& operator=(const Swapchain&) = delete;
/** @brief Move assignment is not allowed */
Swapchain& operator=(Swapchain&&) = delete;
VkSwapchainKHR vkSwapchain() {
return _swapchain;
}
Swapchain& acquireNextImage(Semaphore& presentCompleteSemaphore) {
VkResult err = vkAcquireNextImageKHR(_device.vkDevice(),
_swapchain, UINT64_MAX,
presentCompleteSemaphore.vkSemaphore(),
VkFence(nullptr), &_currentIndex);
MAGNUM_VK_ASSERT_ERROR(err);
return *this;
}
Swapchain& queuePresent(VkQueue queue, UnsignedInt currentBuffer);
/**
* Present the current image to the given
* TODO
* @brief queuePresent
* @param queue
* @param currentBuffer
* @param waitSemaphore
* @return Reference to self (for method chaining)
*/
Swapchain& queuePresent(Queue& queue, UnsignedInt currentBuffer, Semaphore& waitSemaphore);
/**
* @brief Number of images in the swapchain
*/
UnsignedInt imageCount() const {
return _buffers.size();
}
/**
* @brief Index of current buffer in swapchain
*/
UnsignedInt currentIndex() const {
return _currentIndex;
}
/**
* @brief VkImageView at current index
*/
Image& image() {
return *_buffers[_currentIndex].image;
}
/**
* @brief VkImageView at the given index
*/
Image& image(UnsignedInt index) {
return *_buffers[index].image;
}
/**
* @brief VkImageView at the given index
*/
Vk::ImageView& imageView(UnsignedInt index) {
return *_buffers[index].view;
}
private:
PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR;
PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
PFN_vkQueuePresentKHR vkQueuePresentKHR;
Device& _device;
VkSurfaceKHR _surface;
VkSwapchainKHR _swapchain;
std::vector<SwapchainBuffer> _buffers;
UnsignedInt _currentIndex;
};
}}
#endif

59
src/Magnum/Vk/Test/CommandTest.cpp

@ -0,0 +1,59 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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 <sstream>
#include <algorithm>
#include "Magnum/Vk/Command.h"
#include "Magnum/Vk/Context.h"
#include "Magnum/Vk/Device.h"
#include "Magnum/Vk/PhysicalDevice.h"
#include "AbstractVulkanTester.h"
namespace Magnum { namespace Vk { namespace Test {
struct CommandVkTest: AbstractVulkanTester {
explicit CommandVkTest();
void doTheLambdasWork();
};
CommandVkTest::CommandVkTest() {
addTests({&CommandVkTest::doTheLambdasWork});
}
void CommandVkTest::doTheLambdasWork() {
Vk::Context context{};
//CommandBuffer buffer;
//buffer << Cmd::setScissor(0, {Range2Di{{0, 0}, {0, 0}});
}
}}}
MAGNUM_VK_TEST_MAIN(Magnum::Vk::Test::CommandVkTest)

76
src/Magnum/Vk/Test/ContextVkTest.cpp

@ -0,0 +1,76 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
Vladimír Vondruš <mosra@centrum.cz>
Copyright © 2016 Jonathan Hale <squareys@googlemail.com>
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 <sstream>
#include <algorithm>
#include "Magnum/Vk/Context.h"
#include "AbstractVulkanTester.h"
namespace Magnum { namespace Vk { namespace Test {
struct ContextVkTest: AbstractVulkanTester {
explicit ContextVkTest();
void constructCopyMove();
void createInstance();
void createWithValidation();
};
ContextVkTest::ContextVkTest() {
addTests({&ContextVkTest::constructCopyMove,
&ContextVkTest::createInstance,
&ContextVkTest::createWithValidation});
}
void ContextVkTest::constructCopyMove() {
/* Only move-construction allowed */
CORRADE_VERIFY(!(std::is_constructible<Context, const Context&>{}));
CORRADE_VERIFY((std::is_constructible<Context, Context&&>{}));
CORRADE_VERIFY(!(std::is_assignable<Context, const Context&>{}));
CORRADE_VERIFY(!(std::is_assignable<Context, Context&&>{}));
}
void ContextVkTest::createInstance() {
Vk::Context context;
CORRADE_VERIFY(&Vk::Context::current() != nullptr);
CORRADE_VERIFY(Vk::Context::hasCurrent());
CORRADE_COMPARE(context.version(), Vk::Version::Vulkan_1_0);
}
void ContextVkTest::createWithValidation() {
Vk::Context context{Vk::Context::Flag::EnableValidation};
CORRADE_VERIFY(Vk::Context::hasCurrent());
CORRADE_COMPARE(context.version(), Vk::Version::Vulkan_1_0);
}
}}}
MAGNUM_VK_TEST_MAIN(Magnum::Vk::Test::ContextVkTest)
Loading…
Cancel
Save