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.
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) {
const VkBuffer source = _buffer;
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 descriptor;
descriptor.buffer = _buffer;

44
src/Magnum/Vk/DescriptorSet.h

@ -30,12 +30,16 @@
* @brief Class @ref Magnum::Vk::DescriptorSet
*/
#include <vector>
#include <Corrade/Containers/Array.h>
#include "Magnum/Magnum.h"
#include "Magnum/Vk/Buffer.h"
#include "Magnum/Vk/Device.h"
#include "Magnum/Vk/visibility.h"
#include "Magnum/Vk/ShaderStage.h"
#include "Magnum/Vk/Texture.h"
#include "vulkan.h"
@ -124,7 +128,6 @@ class MAGNUM_VK_EXPORT DescriptorSetLayout {
class MAGNUM_VK_EXPORT DescriptorSet {
public:
DescriptorSet(Device& device, DescriptorPool& pool, VkDescriptorSet vkDescriptorSet):
_device{device},
_pool{pool},
@ -161,6 +164,45 @@ class MAGNUM_VK_EXPORT 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

1
src/Magnum/Vk/Device.h

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

44
src/Magnum/Vk/Image.cpp

@ -1,4 +1,4 @@
/*
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016
@ -25,14 +25,52 @@
*/
#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 {
Image::~Image() {
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/Math/Vector3.h"
#include "Magnum/Vk/Device.h"
#include "Magnum/Vk/Format.h"
#include "Magnum/Vk/DeviceMemory.h"
#include "Magnum/Vk/Math.h"
#include "Magnum/Vk/visibility.h"
@ -108,28 +109,29 @@ class MAGNUM_VK_EXPORT Image {
public:
Image(Device& device, VkImage vkImage):
_device{device},
_device{&device},
_image{vkImage},
_flags{}
{}
Image(Device& device, Vector3ui extent, VkFormat format, ImageUsageFlags usage):
_device{device}, _flags{ObjectFlag::DeleteOnDestruction}
Image(Device& device, const Vector3ui& extent, Vk::Format format, ImageUsageFlags usage):
_device{&device}, _flags{ObjectFlag::DeleteOnDestruction}, _extent(extent)
{
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.format = VkFormat(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);
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);
}
@ -158,29 +160,53 @@ class MAGNUM_VK_EXPORT Image {
VkMemoryRequirements getMemoryRequirements() {
VkMemoryRequirements memReqs;
vkGetImageMemoryRequirements(_device, _image, &memReqs);
vkGetImageMemoryRequirements(*_device, _image, &memReqs);
return memReqs;
}
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);
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.
*/
Device& device() {
return _device;
return *_device;
}
private:
Device& _device;
Device* _device;
VkImage _image;
ObjectFlags _flags;
Vector3ui _extent;
};
struct ImageMemoryBarrier {

5
src/Magnum/Vk/ImageView.h

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

5
src/Magnum/Vk/RenderPass.h

@ -33,6 +33,7 @@
#include "Magnum/Magnum.h"
#include "Magnum/Vk/Device.h"
#include "Magnum/Vk/visibility.h"
#include "Magnum/Vk/Format.h"
#include "vulkan.h"
@ -44,7 +45,7 @@ class MAGNUM_VK_EXPORT RenderPass {
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;
VkAttachmentDescription attachments[2];
@ -57,7 +58,7 @@ class MAGNUM_VK_EXPORT RenderPass {
attachments[0].initialLayout = 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].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE;

10
src/Magnum/Vk/Swapchain.cpp

@ -27,7 +27,7 @@
#include "Swapchain.h"
#include "Magnum/Vk/Queue.h"
#include "Magnum/Vk/Format.h"
#include "Magnum/Vk/ImageView.h"
namespace Magnum { namespace Vk {
@ -127,16 +127,16 @@ Swapchain::Swapchain(Device& device, CommandBuffer& cb, VkSurfaceKHR surface):
MAGNUM_VK_ASSERT_ERROR(err);
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)) {
/* no preferred format */
colorFormat = VK_FORMAT_B8G8R8A8_UNORM;
colorFormat = Vk::Format(VK_FORMAT_R8G8B8A8_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;
colorFormat = Format(surfaceFormats[0].format);
}
// Get physical device surface properties and formats
@ -197,7 +197,7 @@ Swapchain::Swapchain(Device& device, CommandBuffer& cb, VkSurfaceKHR surface):
swapchainCI.flags = 0;
swapchainCI.surface = _surface;
swapchainCI.imageFormat = colorFormat;
swapchainCI.imageFormat = VkFormat(colorFormat);
swapchainCI.imageColorSpace = colorSpace;
swapchainCI.imageExtent = swapchainExtent;
swapchainCI.minImageCount = desiredNumberOfSwapchainImages;

35
src/Magnum/Vk/Texture.h

@ -40,10 +40,20 @@
namespace Magnum { namespace Vk {
/**
@brief Texture
A Sampler combined with an Image.
*/
class MAGNUM_VK_EXPORT Texture {
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;
VkSamplerCreateInfo sampler{VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, nullptr, 0};
sampler.magFilter = VK_FILTER_LINEAR;
@ -85,12 +95,33 @@ class MAGNUM_VK_EXPORT Texture {
/** @brief Move assignment is not allowed */
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:
Device& _device;
VkSampler _sampler;
std::unique_ptr<Vk::ImageView> _imageView;
VkImageLayout _imageLayout;
UnsignedInt _mipLevels;
Int _mipLevels;
};
}}

Loading…
Cancel
Save