Browse Source

Vk: Add NoCreate constructors, remove .vk*() methods, avoid some vectors

Signed-off-by: Squareys <squareys@googlemail.com>
pull/202/head
Squareys 10 years ago committed by Squareys
parent
commit
ac3db521ba
  1. 42
      src/Magnum/Vk/Buffer.cpp
  2. 40
      src/Magnum/Vk/Buffer.h
  3. 10
      src/Magnum/Vk/Command.h
  4. 4
      src/Magnum/Vk/CommandBuffer.cpp
  5. 16
      src/Magnum/Vk/CommandBuffer.h
  6. 5
      src/Magnum/Vk/Device.cpp
  7. 3
      src/Magnum/Vk/Device.h
  8. 4
      src/Magnum/Vk/DeviceMemory.cpp
  9. 6
      src/Magnum/Vk/DeviceMemory.h
  10. 6
      src/Magnum/Vk/PhysicalDevice.h
  11. 18
      src/Magnum/Vk/Queue.cpp
  12. 15
      src/Magnum/Vk/Queue.h
  13. 5
      src/Magnum/Vk/Semaphore.h
  14. 4
      src/Magnum/Vk/Shader.cpp
  15. 17
      src/Magnum/Vk/Shader.h
  16. 2
      src/Magnum/Vk/Swapchain.cpp
  17. 2
      src/Magnum/Vk/Swapchain.h

42
src/Magnum/Vk/Buffer.cpp

@ -24,13 +24,53 @@
DEALINGS IN THE SOFTWARE.
*/
#include <cstring>
#include "Buffer.h"
#include "Magnum/Vk/Command.h"
#include "Magnum/Vk/CommandPool.h"
#include "Magnum/Vk/Queue.h"
namespace Magnum { namespace Vk {
Buffer::~Buffer() {
vkDestroyBuffer(_device, _buffer, nullptr);
if(_device != nullptr) {
vkDestroyBuffer(*_device, _buffer, nullptr);
}
}
Buffer& Buffer::update(Queue& queue, CommandPool& pool, const void* sourceData, UnsignedLong size, UnsignedLong destOffset) {
// TODO: Do not use staging if the memory bound to this buffer is host visible.
/* command buffer needs to be destroyed before memory */
std::unique_ptr<Vk::CommandBuffer> copyToDeviceCmds = pool.allocateCommandBuffer(Vk::CommandBuffer::Level::Primary);
/* plane vertices */
Buffer stagingBuffer{*_device, size, Vk::BufferUsage::TransferSrc};
std::unique_ptr<DeviceMemory> stagingMemory = stagingBuffer.allocateDeviceMemory(Vk::MemoryProperty::HostVisible);
Containers::ArrayView<char> data = stagingMemory->map(destOffset, size);
std::memcpy(data, sourceData, stagingBuffer.size());
stagingMemory->unmap();
*copyToDeviceCmds << Vk::Cmd::begin()
<< stagingBuffer.cmdFullCopyTo(*this)
<< Vk::Cmd::end();
queue.submit(*copyToDeviceCmds).waitIdle();
return *this;
}
std::unique_ptr<DeviceMemory> Buffer::allocateDeviceMemory(Vk::MemoryProperty memProperty) {
VkMemoryRequirements memReqs = getMemoryRequirements();
UnsignedInt memoryTypeIndex = _device->physicalDevice().getMemoryType(memReqs.memoryTypeBits, memProperty);
std::unique_ptr<DeviceMemory> memory(new Vk::DeviceMemory{*_device, memReqs.size, memoryTypeIndex});
bindBufferMemory(*memory);
return memory;
}
}}

40
src/Magnum/Vk/Buffer.h

@ -62,7 +62,7 @@ class MAGNUM_VK_EXPORT Buffer {
public:
Buffer(Device& device, UnsignedInt size, BufferUsageFlags usage):
_device{device},
_device{&device},
_size{size}
{
VkBufferCreateInfo bufferInfo = {};
@ -71,10 +71,13 @@ class MAGNUM_VK_EXPORT Buffer {
bufferInfo.size = size;
bufferInfo.usage = VkBufferUsageFlags(usage);
VkResult err = vkCreateBuffer(_device, &bufferInfo, nullptr, &_buffer);
VkResult err = vkCreateBuffer(*_device, &bufferInfo, nullptr, &_buffer);
MAGNUM_VK_ASSERT_ERROR(err);
}
Buffer(NoCreateT): _device{nullptr} {
}
/** @brief Copying is not allowed */
Buffer(const Buffer&) = delete;
@ -92,7 +95,13 @@ class MAGNUM_VK_EXPORT Buffer {
Buffer& operator=(const Buffer&) = delete;
/** @brief Move assignment is not allowed */
Buffer& operator=(Buffer&&) = delete;
Buffer& operator=(Buffer&& other) {
std::swap(_device, other._device);
std::swap(_buffer, other._buffer);
std::swap(_size, other._size);
return *this;
}
operator VkBuffer() const {
return _buffer;
@ -100,7 +109,7 @@ class MAGNUM_VK_EXPORT Buffer {
VkMemoryRequirements getMemoryRequirements() const {
VkMemoryRequirements memReqs;
vkGetBufferMemoryRequirements(_device, _buffer, &memReqs);
vkGetBufferMemoryRequirements(*_device, _buffer, &memReqs);
return memReqs;
}
@ -110,7 +119,7 @@ class MAGNUM_VK_EXPORT Buffer {
}
Buffer& bindBufferMemory(const DeviceMemory& deviceMemory, UnsignedLong offset=0) {
VkResult err = vkBindBufferMemory(_device, _buffer, deviceMemory, offset);
VkResult err = vkBindBufferMemory(*_device, _buffer, deviceMemory, offset);
MAGNUM_VK_ASSERT_ERROR(err);
return *this;
@ -141,8 +150,27 @@ class MAGNUM_VK_EXPORT Buffer {
return descriptor;
}
/**
* @brief Update contents of device memory.
* @return Reference to self (for method chaining)
*
* Will involve mapping and unmapping memory and possibly creating intermediate
* staging buffers if the memory is not visible by the host.
*
* At the end of the method, the queue will be waited for so that temporary buffers
* can be cleaned up.
*/
Buffer& update(Queue& queue, CommandPool& pool, const void* sourceData, UnsignedLong size, UnsignedLong destOffset=0);
/**
* @brief Allocate memory matching requirements of this buffer and bind it
* @param memProperty property for the allocated memory
* @return the allocated and bound memory
*/
std::unique_ptr<DeviceMemory> allocateDeviceMemory(Vk::MemoryProperty memProperty);
private:
Device& _device;
Device* _device;
VkBuffer _buffer;
UnsignedInt _size;
};

10
src/Magnum/Vk/Command.h

@ -53,19 +53,19 @@ CommandBuffer& operator << (CommandBuffer& cmdBuffer, const Lambda& lambda) {
namespace Cmd {
auto begin() {
inline auto begin() {
return [](CommandBuffer& cmdBuffer){
cmdBuffer.begin();
};
}
auto end() {
inline auto end() {
return [](CommandBuffer& cmdBuffer){
cmdBuffer.end();
};
}
auto setScissor(UnsignedInt firstScissor, const std::initializer_list<Range2Di>& ranges) {
inline auto setScissor(UnsignedInt firstScissor, const std::initializer_list<Range2Di>& ranges) {
return [firstScissor, &ranges](VkCommandBuffer cmdBuffer){
Corrade::Containers::Array<VkRect2D> vkRects(ranges.size());
@ -78,13 +78,13 @@ auto setScissor(UnsignedInt firstScissor, const std::initializer_list<Range2Di>&
};
}
auto setViewport(UnsignedInt firstViewport, const std::vector<VkViewport>& viewports) {
inline 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,
inline auto pipelineBarrier(PipelineStageFlags srcStageMask,
PipelineStageFlags dstStageMask,
const std::vector<VkMemoryBarrier>& memoryBarriers,
const std::vector<VkBufferMemoryBarrier>& bufferMemoryBarriers,

4
src/Magnum/Vk/CommandBuffer.cpp

@ -32,7 +32,9 @@
namespace Magnum { namespace Vk {
CommandBuffer::~CommandBuffer() {
_pool.freeCommandBuffer(this);
if(_cmdBuffer != VK_NULL_HANDLE) {
_pool->freeCommandBuffer(this);
}
}
}}

16
src/Magnum/Vk/CommandBuffer.h

@ -76,7 +76,13 @@ class MAGNUM_VK_EXPORT CommandBuffer {
*/
CommandBuffer(VkCommandBuffer buffer, CommandPool& commandPool):
_cmdBuffer{buffer},
_pool{commandPool}
_pool{&commandPool}
{
}
CommandBuffer(NoCreateT):
_cmdBuffer{VK_NULL_HANDLE},
_pool{nullptr}
{
}
@ -97,7 +103,11 @@ class MAGNUM_VK_EXPORT CommandBuffer {
CommandBuffer& operator=(const CommandBuffer&) = delete;
/** @brief Move assignment is not allowed */
CommandBuffer& operator=(CommandBuffer&&) = delete;
CommandBuffer& operator=(CommandBuffer&& other) {
std::swap(_cmdBuffer, other._cmdBuffer);
std::swap(_pool, other._pool);
return *this;
}
operator VkCommandBuffer() const {
return _cmdBuffer;
@ -162,7 +172,7 @@ class MAGNUM_VK_EXPORT CommandBuffer {
private:
VkCommandBuffer _cmdBuffer;
CommandPool& _pool;
CommandPool* _pool;
};
}}

5
src/Magnum/Vk/Device.cpp

@ -33,7 +33,8 @@
namespace Magnum { namespace Vk {
Device::Device(PhysicalDevice& physicalDevice, const std::vector<VkDeviceQueueCreateInfo>& requestedQueues,
const std::vector<const char*>& extensions, const std::vector<const char*>& validationLayers):
const std::vector<const char*>& extensions, const std::vector<const char*>& validationLayers,
const VkPhysicalDeviceFeatures& features):
_physicalDevice(physicalDevice)
{
VkDeviceCreateInfo deviceCreateInfo = {
@ -43,7 +44,7 @@ Device::Device(PhysicalDevice& physicalDevice, const std::vector<VkDeviceQueueCr
requestedQueues.size(), requestedQueues.data(),
validationLayers.size(), validationLayers.data(),
extensions.size(), extensions.data(),
nullptr};
&features};
vkCreateDevice(physicalDevice.vkPhysicalDevice(), &deviceCreateInfo, nullptr, &_device);

3
src/Magnum/Vk/Device.h

@ -56,7 +56,8 @@ class MAGNUM_VK_EXPORT Device {
Device(PhysicalDevice& physicalDevice,
const std::vector<VkDeviceQueueCreateInfo>& requestedQueues,
const std::vector<const char*>& extensions,
const std::vector<const char*>& validationLayers);
const std::vector<const char*>& validationLayers,
const VkPhysicalDeviceFeatures& features);
/**
* @brief Destructor

4
src/Magnum/Vk/DeviceMemory.cpp

@ -26,6 +26,10 @@
#include "DeviceMemory.h"
#include "Magnum/Vk/Buffer.h"
#include "Magnum/Vk/CommandBuffer.h"
#include "Magnum/Vk/CommandPool.h"
namespace Magnum { namespace Vk {

6
src/Magnum/Vk/DeviceMemory.h

@ -80,17 +80,17 @@ class MAGNUM_VK_EXPORT DeviceMemory {
return _deviceMemory;
}
Containers::Array<char> map() {
Containers::ArrayView<char> map() {
return map(0, _memAlloc.allocationSize);
}
Containers::Array<char> map(UnsignedInt offset, UnsignedInt size) {
Containers::ArrayView<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);
return Containers::ArrayView<char>(static_cast<char*>(data), size);
}
DeviceMemory& unmap() {

6
src/Magnum/Vk/PhysicalDevice.h

@ -129,6 +129,12 @@ class MAGNUM_VK_EXPORT PhysicalDevice {
*/
UnsignedInt getMemoryType(UnsignedInt supportedTypeBits, MemoryProperties properties);
VkPhysicalDeviceFeatures getFeatures() const {
VkPhysicalDeviceFeatures features;
vkGetPhysicalDeviceFeatures(_physicalDevice, &features);
return features;
}
private:
VkPhysicalDevice _physicalDevice;
VkPhysicalDeviceMemoryProperties _deviceMemoryProperties;

18
src/Magnum/Vk/Queue.cpp

@ -47,8 +47,8 @@ Queue& Queue::submit(const CommandBuffer& cmdBuffer) {
}
Queue& Queue::submit(const CommandBuffer& cmdBuffer,
std::vector<std::reference_wrapper<Semaphore>> waitSemaphores,
std::vector<std::reference_wrapper<Semaphore>> signalSemaphores) {
Containers::ArrayView<const std::reference_wrapper<Semaphore>> waitSemaphores,
Containers::ArrayView<const std::reference_wrapper<Semaphore>> signalSemaphores) {
const VkCommandBuffer cb = cmdBuffer;
VkPipelineStageFlags pipelineDstStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; // TODO: Expose
@ -58,16 +58,18 @@ Queue& Queue::submit(const CommandBuffer& cmdBuffer,
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &cb;
std::vector<VkSemaphore> waitSems;
waitSems.reserve(waitSemaphores.size());
Containers::Array<VkSemaphore> waitSems(Containers::NoInit, waitSemaphores.size());
int i = 0;
for(Semaphore& sem : waitSemaphores) {
waitSems.push_back(sem.vkSemaphore());
waitSems[i] = sem;
++i;
}
std::vector<VkSemaphore> sigSems;
sigSems.reserve(waitSemaphores.size());
Containers::Array<VkSemaphore> sigSems(Containers::NoInit, signalSemaphores.size());
i = 0;
for(Semaphore& sem : signalSemaphores) {
sigSems.push_back(sem.vkSemaphore());
sigSems[i] = sem;
++i;
}
submitInfo.waitSemaphoreCount = waitSemaphores.size();
submitInfo.pWaitSemaphores = waitSems.data();

15
src/Magnum/Vk/Queue.h

@ -77,8 +77,21 @@ class MAGNUM_VK_EXPORT Queue {
return *this;
}
typedef std::reference_wrapper<Semaphore> SemaphoreRef;
Queue& submit(const CommandBuffer& cmdBuffer);
Queue& submit(const CommandBuffer& cmdBuffer, std::vector<std::reference_wrapper<Semaphore>> waitSemaphores, std::vector<std::reference_wrapper<Semaphore>> signalSemaphores);
Queue& submit(const CommandBuffer& cmdBuffer,
const std::initializer_list<const SemaphoreRef> waitSemaphores,
const std::initializer_list<const SemaphoreRef> signalSemaphores) {
submit(cmdBuffer,
Containers::ArrayView<const SemaphoreRef>(waitSemaphores.begin(), waitSemaphores.size()),
Containers::ArrayView<const SemaphoreRef>(signalSemaphores.begin(), signalSemaphores.size()));
return *this;
}
Queue& submit(const CommandBuffer& cmdBuffer,
Containers::ArrayView<const SemaphoreRef> waitSemaphores,
Containers::ArrayView<const SemaphoreRef> signalSemaphores);
/**
* @brief The device this queue was created for.

5
src/Magnum/Vk/Semaphore.h

@ -75,12 +75,11 @@ class MAGNUM_VK_EXPORT Semaphore {
}
/** @brief Move constructor */
Semaphore(Semaphore&& sem): _semaphore{sem.vkSemaphore()}, _device{sem._device} {
Semaphore(Semaphore&& sem): _semaphore{sem}, _device{sem._device} {
sem._semaphore = VK_NULL_HANDLE;
}
/** @brief Get the underlying VkSemaphore handle */
VkSemaphore& vkSemaphore() {
operator VkSemaphore() const {
return _semaphore;
}

4
src/Magnum/Vk/Shader.cpp

@ -30,7 +30,9 @@
namespace Magnum { namespace Vk {
Shader::~Shader() {
vkDestroyShaderModule(_device, _shaderModule, nullptr);
if(_device != nullptr) {
vkDestroyShaderModule(*_device, _shaderModule, nullptr);
}
}
}}

17
src/Magnum/Vk/Shader.h

@ -43,7 +43,8 @@ namespace Magnum { namespace Vk {
class MAGNUM_VK_EXPORT Shader {
public:
Shader(Device& device, const Containers::Array<char>& shaderCode): _device{device} {
Shader(Device& device, const Containers::Array<char>& shaderCode):
_device{&device} {
VkShaderModuleCreateInfo moduleCreateInfo;
moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
moduleCreateInfo.pNext = nullptr;
@ -51,10 +52,13 @@ class MAGNUM_VK_EXPORT Shader {
moduleCreateInfo.pCode = reinterpret_cast<const uint32_t*>(shaderCode.data());
moduleCreateInfo.flags = 0;
const VkResult err = vkCreateShaderModule(device.vkDevice(), &moduleCreateInfo, nullptr, &_shaderModule);
const VkResult err = vkCreateShaderModule(*_device, &moduleCreateInfo, nullptr, &_shaderModule);
MAGNUM_VK_ASSERT_ERROR(err);
}
Shader(NoCreateT): _device{nullptr} {
}
/** @brief Copying is not allowed */
Shader(const Shader&) = delete;
@ -72,15 +76,20 @@ class MAGNUM_VK_EXPORT Shader {
Shader& operator=(const Shader&) = delete;
/** @brief Move assignment is not allowed */
Shader& operator=(Shader&&) = delete;
Shader& operator=(Shader&& other) {
std::swap(_device, other._device);
std::swap(_shaderModule, other._shaderModule);
return *this;
}
VkShaderModule vkShaderModule() {
return _shaderModule;
}
private:
Device* _device;
VkShaderModule _shaderModule;
Device& _device;
};
}}

2
src/Magnum/Vk/Swapchain.cpp

@ -298,7 +298,7 @@ Swapchain& Swapchain::queuePresent(VkQueue queue, UnsignedInt currentBuffer) {
}
Swapchain& Swapchain::queuePresent(Queue& queue, UnsignedInt currentBuffer, Semaphore& waitSemaphore) {
VkSemaphore sem = waitSemaphore.vkSemaphore();
VkSemaphore sem = waitSemaphore;
VkPresentInfoKHR presentInfo = {};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.pNext = nullptr;

2
src/Magnum/Vk/Swapchain.h

@ -76,7 +76,7 @@ class MAGNUM_VK_EXPORT Swapchain {
Swapchain& acquireNextImage(Semaphore& presentCompleteSemaphore) {
VkResult err = vkAcquireNextImageKHR(_device.vkDevice(),
_swapchain, UINT64_MAX,
presentCompleteSemaphore.vkSemaphore(),
presentCompleteSemaphore,
VkFence(nullptr), &_currentIndex);
MAGNUM_VK_ASSERT_ERROR(err);

Loading…
Cancel
Save