Browse Source

More code...

pull/202/head
Squareys 10 years ago
parent
commit
7416e3ddde
  1. 2
      src/Magnum/Vk/Buffer.cpp
  2. 21
      src/Magnum/Vk/Buffer.h
  3. 44
      src/Magnum/Vk/DescriptorSet.h
  4. 1
      src/Magnum/Vk/Device.h
  5. 44
      src/Magnum/Vk/Image.cpp
  6. 44
      src/Magnum/Vk/Image.h
  7. 5
      src/Magnum/Vk/ImageView.h
  8. 5
      src/Magnum/Vk/RenderPass.h
  9. 10
      src/Magnum/Vk/Swapchain.cpp
  10. 35
      src/Magnum/Vk/Texture.h

2
src/Magnum/Vk/Buffer.cpp

@ -1,4 +1,4 @@
/* /*
This file is part of Magnum. This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016 Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016

21
src/Magnum/Vk/Buffer.h

@ -132,6 +132,13 @@ class MAGNUM_VK_EXPORT Buffer {
}; };
} }
auto cmdCopyTo(Image& dest, std::initializer_list<VkBufferImageCopy> regions) {
const VkBuffer source = _buffer;
return [source, &dest, &regions](VkCommandBuffer cmdBuffer){
vkCmdCopyBufferToImage(cmdBuffer, source, dest, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, UnsignedInt(regions.size()), std::vector<VkBufferImageCopy>(regions).data());
};
}
auto cmdFullCopyTo(Buffer& dest) { auto cmdFullCopyTo(Buffer& dest) {
const VkBuffer source = _buffer; const VkBuffer source = _buffer;
const UnsignedInt size = _size; const UnsignedInt size = _size;
@ -141,6 +148,20 @@ class MAGNUM_VK_EXPORT Buffer {
}; };
} }
auto cmdFullCopyTo(Image& dest) {
const VkBuffer source = _buffer;
const UnsignedInt size = _size;
return [source, &dest, size](VkCommandBuffer cmdBuffer){
VkBufferImageCopy copy;
copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy.imageSubresource.mipLevel = 0;
copy.imageSubresource.baseArrayLayer = 0;
copy.imageSubresource.layerCount = 1;
copy.imageExtent = VkExtent3D(dest.extent());
vkCmdCopyBufferToImage(cmdBuffer, source, dest, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy);
};
}
VkDescriptorBufferInfo getDescriptor() { VkDescriptorBufferInfo getDescriptor() {
VkDescriptorBufferInfo descriptor; VkDescriptorBufferInfo descriptor;
descriptor.buffer = _buffer; descriptor.buffer = _buffer;

44
src/Magnum/Vk/DescriptorSet.h

@ -30,12 +30,16 @@
* @brief Class @ref Magnum::Vk::DescriptorSet * @brief Class @ref Magnum::Vk::DescriptorSet
*/ */
#include <vector>
#include <Corrade/Containers/Array.h> #include <Corrade/Containers/Array.h>
#include "Magnum/Magnum.h" #include "Magnum/Magnum.h"
#include "Magnum/Vk/Buffer.h"
#include "Magnum/Vk/Device.h" #include "Magnum/Vk/Device.h"
#include "Magnum/Vk/visibility.h" #include "Magnum/Vk/visibility.h"
#include "Magnum/Vk/ShaderStage.h" #include "Magnum/Vk/ShaderStage.h"
#include "Magnum/Vk/Texture.h"
#include "vulkan.h" #include "vulkan.h"
@ -124,7 +128,6 @@ class MAGNUM_VK_EXPORT DescriptorSetLayout {
class MAGNUM_VK_EXPORT DescriptorSet { class MAGNUM_VK_EXPORT DescriptorSet {
public: public:
DescriptorSet(Device& device, DescriptorPool& pool, VkDescriptorSet vkDescriptorSet): DescriptorSet(Device& device, DescriptorPool& pool, VkDescriptorSet vkDescriptorSet):
_device{device}, _device{device},
_pool{pool}, _pool{pool},
@ -161,6 +164,45 @@ class MAGNUM_VK_EXPORT DescriptorSet {
VkDescriptorSet _descriptorSet; VkDescriptorSet _descriptorSet;
}; };
class MAGNUM_VK_EXPORT DescriptorSetUpdate {
public:
void run(Device& device) {
if(_writes.empty()) {
return;
}
// TODO: Error check?
vkUpdateDescriptorSets(device, UnsignedInt(_writes.size()), _writes.data(), 0, NULL);
}
DescriptorSetUpdate& useDescriptorSet(DescriptorSet& ds) {
_descriptorSet = &ds;
return *this;
}
DescriptorSetUpdate& bindUniformBuffer(Buffer& buffer, UnsignedInt dstBinding, UnsignedInt dstArrayElement=0) {
_buffers.push_back(buffer.getDescriptor());
_writes.push_back(VkWriteDescriptorSet{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, nullptr, *_descriptorSet,
dstBinding, dstArrayElement, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, nullptr, &_buffers.back(), nullptr});
return *this;
}
DescriptorSetUpdate& bindTexture(Vk::Texture& texture, UnsignedInt dstBinding, UnsignedInt dstArrayElement=0) {
_images.push_back(texture.getDescriptor());
_writes.push_back(VkWriteDescriptorSet{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, nullptr, *_descriptorSet,
dstBinding, dstArrayElement, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &_images.back(), nullptr, nullptr});
return *this;
}
private:
std::vector<VkDescriptorImageInfo> _images;
std::vector<VkDescriptorBufferInfo> _buffers;
std::vector<VkBufferView> _bufferViews;
std::vector<VkWriteDescriptorSet> _writes;
// TODO copies
DescriptorSet* _descriptorSet;
};
}} }}
#endif #endif

1
src/Magnum/Vk/Device.h

@ -114,6 +114,7 @@ public:
DeviceFeatures(const std::initializer_list<DeviceFeature>& features) { DeviceFeatures(const std::initializer_list<DeviceFeature>& features) {
VkBool32* enabled = reinterpret_cast<VkBool32*>(&_features); VkBool32* enabled = reinterpret_cast<VkBool32*>(&_features);
std::memset(enabled, 0, sizeof(VkPhysicalDeviceFeatures));
for(DeviceFeature f : features) { for(DeviceFeature f : features) {
enabled[UnsignedInt(f)] = VK_TRUE; enabled[UnsignedInt(f)] = VK_TRUE;
} }

44
src/Magnum/Vk/Image.cpp

@ -1,4 +1,4 @@
/* /*
This file is part of Magnum. This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016 Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
@ -25,14 +25,52 @@
*/ */
#include "Image.h" #include "Image.h"
#include "Magnum/Vk/Buffer.h"
#include "Magnum/Vk/Command.h"
#include "Magnum/Vk/CommandBuffer.h"
#include "Magnum/Vk/CommandPool.h"
#include "Magnum/Vk/DeviceMemory.h"
#include "Magnum/Vk/Queue.h"
namespace Magnum { namespace Vk { namespace Magnum { namespace Vk {
Image::~Image() { Image::~Image() {
if(_flags >= ObjectFlag::DeleteOnDestruction) { if(_flags >= ObjectFlag::DeleteOnDestruction) {
vkDestroyImage(_device, _image, nullptr); vkDestroyImage(*_device, _image, nullptr);
} }
} }
std::unique_ptr<DeviceMemory> Image::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});
bindImageMemory(*memory);
return std::unique_ptr<DeviceMemory>{};
}
Image& Image::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, UnsignedInt(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()
<< Vk::Cmd::imageMemoryk
<< stagingBuffer.cmdFullCopyTo(*this)
<< Vk::Cmd::end();
queue.submit(*copyToDeviceCmds).waitIdle();
return *this;
}
}} }}

44
src/Magnum/Vk/Image.h

@ -34,6 +34,7 @@
#include "Magnum/Magnum.h" #include "Magnum/Magnum.h"
#include "Magnum/Math/Vector3.h" #include "Magnum/Math/Vector3.h"
#include "Magnum/Vk/Device.h" #include "Magnum/Vk/Device.h"
#include "Magnum/Vk/Format.h"
#include "Magnum/Vk/DeviceMemory.h" #include "Magnum/Vk/DeviceMemory.h"
#include "Magnum/Vk/Math.h" #include "Magnum/Vk/Math.h"
#include "Magnum/Vk/visibility.h" #include "Magnum/Vk/visibility.h"
@ -108,28 +109,29 @@ class MAGNUM_VK_EXPORT Image {
public: public:
Image(Device& device, VkImage vkImage): Image(Device& device, VkImage vkImage):
_device{device}, _device{&device},
_image{vkImage}, _image{vkImage},
_flags{} _flags{}
{} {}
Image(Device& device, Vector3ui extent, VkFormat format, ImageUsageFlags usage): Image(Device& device, const Vector3ui& extent, Vk::Format format, ImageUsageFlags usage):
_device{device}, _flags{ObjectFlag::DeleteOnDestruction} _device{&device}, _flags{ObjectFlag::DeleteOnDestruction}, _extent(extent)
{ {
VkImageCreateInfo image = {}; VkImageCreateInfo image = {};
image.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; image.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
image.flags = 0; image.flags = 0;
image.pNext = nullptr; image.pNext = nullptr;
image.imageType = VK_IMAGE_TYPE_2D; image.imageType = VK_IMAGE_TYPE_2D;
image.format = format; image.format = VkFormat(format);
image.extent = VkExtent3D(extent); image.extent = VkExtent3D(extent);
image.samples = VK_SAMPLE_COUNT_1_BIT; image.samples = VK_SAMPLE_COUNT_1_BIT;
image.mipLevels = 1; image.mipLevels = 1;
image.arrayLayers = 1; image.arrayLayers = 1;
image.tiling = VK_IMAGE_TILING_OPTIMAL; image.tiling = VK_IMAGE_TILING_OPTIMAL;
image.usage = UnsignedInt(usage); image.usage = UnsignedInt(usage);
image.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
VkResult err = vkCreateImage(_device, &image, nullptr, &_image); VkResult err = vkCreateImage(*_device, &image, nullptr, &_image);
MAGNUM_VK_ASSERT_ERROR(err); MAGNUM_VK_ASSERT_ERROR(err);
} }
@ -158,29 +160,53 @@ class MAGNUM_VK_EXPORT Image {
VkMemoryRequirements getMemoryRequirements() { VkMemoryRequirements getMemoryRequirements() {
VkMemoryRequirements memReqs; VkMemoryRequirements memReqs;
vkGetImageMemoryRequirements(_device, _image, &memReqs); vkGetImageMemoryRequirements(*_device, _image, &memReqs);
return memReqs; return memReqs;
} }
Image& bindImageMemory(DeviceMemory& memory, UnsignedLong memoryOffset=0) { Image& bindImageMemory(DeviceMemory& memory, UnsignedLong memoryOffset=0) {
VkResult err = vkBindImageMemory(_device, _image, memory, memoryOffset); VkResult err = vkBindImageMemory(*_device, _image, memory, memoryOffset);
MAGNUM_VK_ASSERT_ERROR(err); MAGNUM_VK_ASSERT_ERROR(err);
return *this; return *this;
} }
/**
* @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.
*/
Image& 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);
Vector3ui extent() const {
return _extent;
}
/** /**
* @brief The device this image was created for. * @brief The device this image was created for.
*/ */
Device& device() { Device& device() {
return _device; return *_device;
} }
private: private:
Device& _device; Device* _device;
VkImage _image; VkImage _image;
ObjectFlags _flags; ObjectFlags _flags;
Vector3ui _extent;
}; };
struct ImageMemoryBarrier { struct ImageMemoryBarrier {

5
src/Magnum/Vk/ImageView.h

@ -33,6 +33,7 @@
#include "Magnum/Magnum.h" #include "Magnum/Magnum.h"
#include "Magnum/Vk/visibility.h" #include "Magnum/Vk/visibility.h"
#include "Magnum/Vk/Image.h" #include "Magnum/Vk/Image.h"
#include "Magnum/Vk/Format.h"
#include "vulkan.h" #include "vulkan.h"
@ -52,7 +53,7 @@ CORRADE_ENUMSET_OPERATORS(ImageAspects)
class MAGNUM_VK_EXPORT ImageView { class MAGNUM_VK_EXPORT ImageView {
public: public:
ImageView(Device& device, Image& image, VkFormat format, ImageView(Device& device, Image& image, Vk::Format format,
VkImageViewType type, ImageAspects aspects, VkImageViewType type, ImageAspects aspects,
VkComponentMapping components = {}): VkComponentMapping components = {}):
_device{device} _device{device}
@ -62,7 +63,7 @@ class MAGNUM_VK_EXPORT ImageView {
createInfo.pNext = nullptr; createInfo.pNext = nullptr;
createInfo.flags = 0; createInfo.flags = 0;
createInfo.viewType = type; createInfo.viewType = type;
createInfo.format = format; createInfo.format = VkFormat(format);
createInfo.subresourceRange = { createInfo.subresourceRange = {
VkImageAspectFlags(aspects), VkImageAspectFlags(aspects),
0, /* base mip level */ 0, /* base mip level */

5
src/Magnum/Vk/RenderPass.h

@ -33,6 +33,7 @@
#include "Magnum/Magnum.h" #include "Magnum/Magnum.h"
#include "Magnum/Vk/Device.h" #include "Magnum/Vk/Device.h"
#include "Magnum/Vk/visibility.h" #include "Magnum/Vk/visibility.h"
#include "Magnum/Vk/Format.h"
#include "vulkan.h" #include "vulkan.h"
@ -44,7 +45,7 @@ class MAGNUM_VK_EXPORT RenderPass {
RenderPass(NoCreateT) noexcept: _device{nullptr} { RenderPass(NoCreateT) noexcept: _device{nullptr} {
} }
RenderPass(Device& device, VkFormat depthFormat): _device{&device} { RenderPass(Device& device, Vk::Format depthFormat): _device{&device} {
VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT; VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
VkAttachmentDescription attachments[2]; VkAttachmentDescription attachments[2];
@ -57,7 +58,7 @@ class MAGNUM_VK_EXPORT RenderPass {
attachments[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; attachments[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachments[1].format = depthFormat; attachments[1].format = VkFormat(depthFormat);
attachments[1].samples = sampleCount; attachments[1].samples = sampleCount;
attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;

10
src/Magnum/Vk/Swapchain.cpp

@ -27,7 +27,7 @@
#include "Swapchain.h" #include "Swapchain.h"
#include "Magnum/Vk/Queue.h" #include "Magnum/Vk/Queue.h"
#include "Magnum/Vk/Format.h"
#include "Magnum/Vk/ImageView.h" #include "Magnum/Vk/ImageView.h"
namespace Magnum { namespace Vk { namespace Magnum { namespace Vk {
@ -127,16 +127,16 @@ Swapchain::Swapchain(Device& device, CommandBuffer& cb, VkSurfaceKHR surface):
MAGNUM_VK_ASSERT_ERROR(err); MAGNUM_VK_ASSERT_ERROR(err);
VkColorSpaceKHR colorSpace = surfaceFormats[0].colorSpace; VkColorSpaceKHR colorSpace = surfaceFormats[0].colorSpace;
VkFormat colorFormat = VK_FORMAT_B8G8R8A8_UNORM; Format colorFormat = Vk::Format(VK_FORMAT_R8G8B8A8_UNORM);
if ((formatCount == 1) && (surfaceFormats[0].format == VK_FORMAT_UNDEFINED)) { if ((formatCount == 1) && (surfaceFormats[0].format == VK_FORMAT_UNDEFINED)) {
/* no preferred format */ /* no preferred format */
colorFormat = VK_FORMAT_B8G8R8A8_UNORM; colorFormat = Vk::Format(VK_FORMAT_R8G8B8A8_UNORM);
} else { } else {
// Always select the first available color format // Always select the first available color format
// If you need a specific format (e.g. SRGB) you'd need to // If you need a specific format (e.g. SRGB) you'd need to
// iterate over the list of available surface format and // iterate over the list of available surface format and
// check for it's presence // check for it's presence
colorFormat = surfaceFormats[0].format; colorFormat = Format(surfaceFormats[0].format);
} }
// Get physical device surface properties and formats // Get physical device surface properties and formats
@ -197,7 +197,7 @@ Swapchain::Swapchain(Device& device, CommandBuffer& cb, VkSurfaceKHR surface):
swapchainCI.flags = 0; swapchainCI.flags = 0;
swapchainCI.surface = _surface; swapchainCI.surface = _surface;
swapchainCI.imageFormat = colorFormat; swapchainCI.imageFormat = VkFormat(colorFormat);
swapchainCI.imageColorSpace = colorSpace; swapchainCI.imageColorSpace = colorSpace;
swapchainCI.imageExtent = swapchainExtent; swapchainCI.imageExtent = swapchainExtent;
swapchainCI.minImageCount = desiredNumberOfSwapchainImages; swapchainCI.minImageCount = desiredNumberOfSwapchainImages;

35
src/Magnum/Vk/Texture.h

@ -40,10 +40,20 @@
namespace Magnum { namespace Vk { namespace Magnum { namespace Vk {
/**
@brief Texture
A Sampler combined with an Image.
*/
class MAGNUM_VK_EXPORT Texture { class MAGNUM_VK_EXPORT Texture {
public: public:
Texture(Device& device): _device{device} { Texture(Device& device, std::unique_ptr<ImageView>&& imageView, ImageLayout layout, Int numMipLevels):
_device{device},
_imageView{std::move(imageView)},
_imageLayout{VkImageLayout(layout)},
_mipLevels{numMipLevels}
{
int mipLevels = 0; int mipLevels = 0;
VkSamplerCreateInfo sampler{VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, nullptr, 0}; VkSamplerCreateInfo sampler{VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, nullptr, 0};
sampler.magFilter = VK_FILTER_LINEAR; sampler.magFilter = VK_FILTER_LINEAR;
@ -85,12 +95,33 @@ class MAGNUM_VK_EXPORT Texture {
/** @brief Move assignment is not allowed */ /** @brief Move assignment is not allowed */
Texture& operator=(Texture&&) = delete; Texture& operator=(Texture&&) = delete;
ImageView& imageView() {
return *_imageView;
}
operator VkSampler() const {
return _sampler;
}
UnsignedInt mipLevels() const {
return _mipLevels;
}
VkImageLayout imageLayout() const {
return _imageLayout;
}
VkDescriptorImageInfo getDescriptor() const {
return VkDescriptorImageInfo{_sampler, *_imageView, _imageLayout};
}
private: private:
Device& _device; Device& _device;
VkSampler _sampler; VkSampler _sampler;
std::unique_ptr<Vk::ImageView> _imageView;
VkImageLayout _imageLayout; VkImageLayout _imageLayout;
UnsignedInt _mipLevels; Int _mipLevels;
}; };
}} }}

Loading…
Cancel
Save