From 55f67e78b29e560dc8b82fd8a00cd8d58a5dcbe4 Mon Sep 17 00:00:00 2001 From: Squareys Date: Mon, 31 Oct 2016 09:30:15 +0100 Subject: [PATCH] More fixes and code Signed-off-by: Squareys --- src/Magnum/Vk/Buffer.cpp | 12 +++++-- src/Magnum/Vk/Buffer.h | 19 +++++------ src/Magnum/Vk/Command.h | 7 ++++ src/Magnum/Vk/CommandBuffer.h | 5 ++- src/Magnum/Vk/Device.h | 44 ++++++++++++++++++++++++- src/Magnum/Vk/DeviceMemory.h | 37 +++++++++++++++++++++ src/Magnum/Vk/Image.cpp | 11 +++++-- src/Magnum/Vk/Image.h | 22 +++++++------ src/Magnum/Vk/Instance.cpp | 59 +++++++++++++++++----------------- src/Magnum/Vk/Math.h | 2 +- src/Magnum/Vk/PhysicalDevice.h | 2 +- src/Magnum/Vk/Pipeline.cpp | 11 +++++-- src/Magnum/Vk/Pipeline.h | 46 ++++++++++++++++++++------ src/Magnum/Vk/Texture.h | 24 ++++++++++---- 14 files changed, 227 insertions(+), 74 deletions(-) diff --git a/src/Magnum/Vk/Buffer.cpp b/src/Magnum/Vk/Buffer.cpp index 5f060d792..d1e6077a5 100644 --- a/src/Magnum/Vk/Buffer.cpp +++ b/src/Magnum/Vk/Buffer.cpp @@ -30,6 +30,7 @@ #include "Magnum/Vk/Command.h" #include "Magnum/Vk/CommandPool.h" +#include "Magnum/Vk/DeviceMemory.h" #include "Magnum/Vk/Queue.h" @@ -41,6 +42,13 @@ Buffer::~Buffer() { } } +Buffer& Buffer::bindBufferMemory(DeviceMemory& deviceMemory, const UnsignedLong offset) { + VkResult err = vkBindBufferMemory(*_device, _buffer, deviceMemory, offset); + MAGNUM_VK_ASSERT_ERROR(err); + + return *this; +} + 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. @@ -63,11 +71,11 @@ Buffer& Buffer::update(Queue& queue, CommandPool& pool, const void* sourceData, return *this; } -std::unique_ptr Buffer::allocateDeviceMemory(Vk::MemoryProperty memProperty) { +std::unique_ptr Buffer::allocateDeviceMemory(Vk::MemoryProperties memProperty) { VkMemoryRequirements memReqs = getMemoryRequirements(); UnsignedInt memoryTypeIndex = _device->physicalDevice().getMemoryType(memReqs.memoryTypeBits, memProperty); - std::unique_ptr memory(new Vk::DeviceMemory{*_device, memReqs.size, memoryTypeIndex}); + std::unique_ptr memory(new Vk::DeviceMemory{*_device, memReqs.size, memoryTypeIndex, *this}); bindBufferMemory(*memory); return memory; diff --git a/src/Magnum/Vk/Buffer.h b/src/Magnum/Vk/Buffer.h index 1483b5242..7e7281825 100644 --- a/src/Magnum/Vk/Buffer.h +++ b/src/Magnum/Vk/Buffer.h @@ -35,13 +35,14 @@ #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 { +class DeviceMemory; + enum class BufferUsage: UnsignedInt { TransferSrc = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, TransferDst = VK_BUFFER_USAGE_TRANSFER_DST_BIT, @@ -65,9 +66,14 @@ class MAGNUM_VK_EXPORT Buffer { _device{&device}, _size{size} { + VkDedicatedAllocationImageCreateInfoNV dedicatedInfo{ + VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV, + nullptr, VK_TRUE + }; + VkBufferCreateInfo bufferInfo = {}; bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - bufferInfo.pNext = nullptr; + bufferInfo.pNext = &dedicatedInfo; bufferInfo.size = size; bufferInfo.usage = VkBufferUsageFlags(usage); @@ -123,12 +129,7 @@ class MAGNUM_VK_EXPORT Buffer { return _size; } - Buffer& bindBufferMemory(const DeviceMemory& deviceMemory, UnsignedLong offset=0) { - VkResult err = vkBindBufferMemory(*_device, _buffer, deviceMemory, offset); - MAGNUM_VK_ASSERT_ERROR(err); - - return *this; - } + Buffer& bindBufferMemory(DeviceMemory& deviceMemory, UnsignedLong offset=0); auto cmdCopyTo(Buffer& dest, std::initializer_list regions) { const VkBuffer source = _buffer; @@ -192,7 +193,7 @@ class MAGNUM_VK_EXPORT Buffer { * @param memProperty property for the allocated memory * @return the allocated and bound memory */ - std::unique_ptr allocateDeviceMemory(Vk::MemoryProperty memProperty); + std::unique_ptr allocateDeviceMemory(Vk::MemoryProperties memProperty); private: Device* _device; diff --git a/src/Magnum/Vk/Command.h b/src/Magnum/Vk/Command.h index ef183a62c..f1560f0aa 100644 --- a/src/Magnum/Vk/Command.h +++ b/src/Magnum/Vk/Command.h @@ -32,6 +32,7 @@ #include "vulkan.h" #include +#include #include #include "Magnum/Tags.h" @@ -100,6 +101,12 @@ inline auto pipelineBarrier(PipelineStageFlags srcStageMask, }; } +inline auto pushConstants(VkPipelineLayout layout, ShaderStage shaderStage, Containers::ArrayView data, UnsignedInt offset = 0) { + return [shaderStage, data, offset, layout](VkCommandBuffer cmdBuffer){ + vkCmdPushConstants(cmdBuffer, layout, VkShaderStageFlagBits(shaderStage), offset, data.size(), data.data()); + }; +} + }}} #endif diff --git a/src/Magnum/Vk/CommandBuffer.h b/src/Magnum/Vk/CommandBuffer.h index c269221cf..c4f263c71 100644 --- a/src/Magnum/Vk/CommandBuffer.h +++ b/src/Magnum/Vk/CommandBuffer.h @@ -90,7 +90,10 @@ class MAGNUM_VK_EXPORT CommandBuffer { CommandBuffer(const CommandBuffer&) = delete; /** @brief Move constructor */ - CommandBuffer(CommandBuffer&& other); + CommandBuffer(CommandBuffer&& other) { + std::swap(_cmdBuffer, other._cmdBuffer); + std::swap(_pool, other._pool); + } /** * @brief Destructor diff --git a/src/Magnum/Vk/Device.h b/src/Magnum/Vk/Device.h index 306599d7d..637d83b3a 100644 --- a/src/Magnum/Vk/Device.h +++ b/src/Magnum/Vk/Device.h @@ -41,7 +41,49 @@ #include "vulkan.h" -namespace Magnum { namespace Vk { +namespace Magnum { namespace Extensions { +/* +#ifndef DOXYGEN_GENERATING_OUTPUT +#define _extension(vendor, extension, _requiredVersion, _coreVersion) \ + struct extension { \ + enum: std::size_t { Index = __LINE__-1 }; \ + constexpr static Version requiredVersion() { return Version::_requiredVersion; } \ + constexpr static Version coreVersion() { return Version::_coreVersion; } \ + constexpr static const char* string() { return "VK_" #vendor "_" #extension; } \ + }; + + // TODO: Encode Device/Instance level into extension structure +namespace Device { namespace Vk { + namespace AMD { + _extension(AMD,negative_viewport_height, Vulkan_1_0, None) + } namespace EXT { + _extension(EXT,debug_marker, Vulkan_1_0, None) + _extension(EXT,debug_reporter, Vulkan_1_0, None) + } namespace KHR { + _extension(KHR,android_surface, Vulkan_1_0, None) + _extension(KHR,display, Vulkan_1_0, None) + _extension(KHR,display_swapchain, Vulkan_1_0, None) + _extension(KHR,mir_surface, Vulkan_1_0, None) + _extension(KHR,sampler_mirror_clamp_to_edge, Vulkan_1_0, None) + _extension(KHR,swapchain, Vulkan_1_0, None) + _extension(KHR,wayland_surface, Vulkan_1_0, None) + _extension(KHR,win32_surface, Vulkan_1_0, None) + _extension(KHR,xcb_surface, Vulkan_1_0, None) + _extension(KHR,xlib_surface, Vulkan_1_0, None) + } namespace NV { + _extension(NV,dedicated_allocation, Vulkan_1_0, None) + _extension(NV,glsl_shader, Vulkan_1_0, None) + } +}} + +namespace Instance { namespace Vk { + namespace KHR { + _extension(KHR,surface, Vulkan_1_0, None) + } +}} +*/ +} +namespace Vk { constexpr UnsignedInt deviceFeaturesCount = sizeof(VkPhysicalDeviceFeatures) / 4; diff --git a/src/Magnum/Vk/DeviceMemory.h b/src/Magnum/Vk/DeviceMemory.h index 21f996367..e521571c6 100644 --- a/src/Magnum/Vk/DeviceMemory.h +++ b/src/Magnum/Vk/DeviceMemory.h @@ -33,7 +33,9 @@ #include #include "Magnum/Magnum.h" +#include "Magnum/Vk/Buffer.h" #include "Magnum/Vk/Device.h" +#include "Magnum/Vk/Image.h" #include "Magnum/Vk/visibility.h" #include "vulkan.h" @@ -57,6 +59,41 @@ class MAGNUM_VK_EXPORT DeviceMemory { MAGNUM_VK_ASSERT_ERROR(err); } + DeviceMemory(Device& device, UnsignedLong size, UnsignedInt memoryTypeIndex, Vk::Buffer& buffer): + _device{device} + { + VkDedicatedAllocationMemoryAllocateInfoNV dedicatedInfo{ + VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV, + nullptr, VK_NULL_HANDLE, buffer + }; + _memAlloc = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + &dedicatedInfo, + size, + memoryTypeIndex + }; + + VkResult err = vkAllocateMemory(_device, &_memAlloc, nullptr, &_deviceMemory); + MAGNUM_VK_ASSERT_ERROR(err); + } + + DeviceMemory(Device& device, UnsignedLong size, UnsignedInt memoryTypeIndex, Vk::Image& image): + _device{device} + { + VkDedicatedAllocationMemoryAllocateInfoNV dedicatedInfo{ + VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV, + nullptr, image, VK_NULL_HANDLE + }; + _memAlloc = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + &dedicatedInfo, + size, + memoryTypeIndex + }; + + VkResult err = vkAllocateMemory(_device, &_memAlloc, nullptr, &_deviceMemory); + MAGNUM_VK_ASSERT_ERROR(err); + } /** @brief Copying is not allowed */ DeviceMemory(const DeviceMemory&) = delete; diff --git a/src/Magnum/Vk/Image.cpp b/src/Magnum/Vk/Image.cpp index 7faa8202e..11793234a 100644 --- a/src/Magnum/Vk/Image.cpp +++ b/src/Magnum/Vk/Image.cpp @@ -41,16 +41,23 @@ Image::~Image() { } } -std::unique_ptr Image::allocateDeviceMemory(Vk::MemoryProperty memProperty) { +std::unique_ptr Image::allocateDeviceMemory(Vk::MemoryProperties memProperty) { VkMemoryRequirements memReqs = getMemoryRequirements(); UnsignedInt memoryTypeIndex = _device->physicalDevice().getMemoryType(memReqs.memoryTypeBits, memProperty); - std::unique_ptr memory(new Vk::DeviceMemory{*_device, memReqs.size, memoryTypeIndex}); + std::unique_ptr memory(new Vk::DeviceMemory{*_device, memReqs.size, memoryTypeIndex, *this}); bindImageMemory(*memory); return memory; } +Image& Image::bindImageMemory(const DeviceMemory& memory, const UnsignedLong memoryOffset) { + VkResult err = vkBindImageMemory(*_device, _image, memory, memoryOffset); + MAGNUM_VK_ASSERT_ERROR(err); + + return *this; +} + 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. diff --git a/src/Magnum/Vk/Image.h b/src/Magnum/Vk/Image.h index efcb33e8e..45d1074f7 100644 --- a/src/Magnum/Vk/Image.h +++ b/src/Magnum/Vk/Image.h @@ -35,7 +35,6 @@ #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" @@ -44,6 +43,7 @@ namespace Magnum { namespace Vk { class Image; +class DeviceMemory; enum class ImageUsageFlag: UnsignedInt { TransferSrc = VK_IMAGE_USAGE_TRANSFER_SRC_BIT, @@ -117,10 +117,19 @@ class MAGNUM_VK_EXPORT Image { Image(Device& device, const Vector3ui& extent, Vk::Format format, ImageUsageFlags usage): _device{&device}, _flags{ObjectFlag::DeleteOnDestruction}, _extent(extent) { + VkDedicatedAllocationImageCreateInfoNV dedicatedInfo{ + VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV, + nullptr, VK_TRUE + }; + VkImageCreateInfo image = {}; image.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; image.flags = 0; - image.pNext = nullptr; + if(true) { // FIXME: If VK_NV_dedicated_allocation is enabled + image.pNext = &dedicatedInfo; + } else { + image.pNext = nullptr; + } image.imageType = VK_IMAGE_TYPE_2D; image.format = VkFormat(format); image.extent = VkExtent3D(extent); @@ -166,12 +175,7 @@ class MAGNUM_VK_EXPORT Image { return memReqs; } - Image& bindImageMemory(DeviceMemory& memory, UnsignedLong memoryOffset=0) { - VkResult err = vkBindImageMemory(*_device, _image, memory, memoryOffset); - MAGNUM_VK_ASSERT_ERROR(err); - - return *this; - } + Image& bindImageMemory(const DeviceMemory& memory, UnsignedLong memoryOffset=0); /** * @brief Update contents of device memory. @@ -190,7 +194,7 @@ class MAGNUM_VK_EXPORT Image { * @param memProperty property for the allocated memory * @return the allocated and bound memory */ - std::unique_ptr allocateDeviceMemory(Vk::MemoryProperty memProperty); + std::unique_ptr allocateDeviceMemory(Vk::MemoryProperties memProperty); Vector3ui extent() const { return _extent; diff --git a/src/Magnum/Vk/Instance.cpp b/src/Magnum/Vk/Instance.cpp index a03e109d7..3d0b917d6 100644 --- a/src/Magnum/Vk/Instance.cpp +++ b/src/Magnum/Vk/Instance.cpp @@ -106,7 +106,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL MyDebugReportCallback( } else if(flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) { Warning() << "[Perf Warning][" << pLayerPrefix << "]" << pMessage; } - + return VK_FALSE; } @@ -128,9 +128,10 @@ bool Instance::tryCreate() { instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; instanceCreateInfo.pNext = nullptr; instanceCreateInfo.pApplicationInfo = &appInfo; + enabledExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); + if (_flags >= Flag::EnableValidation) { Debug() << "Enabling Validation"; - enabledExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); instanceCreateInfo.enabledLayerCount = layerCount; instanceCreateInfo.ppEnabledLayerNames = validationLayerNames; @@ -150,34 +151,32 @@ bool Instance::tryCreate() { _current = this; /* setup debugging */ - if (_flags >= Flag::EnableValidation) { - /* Load VK_EXT_debug_report entry points in debug builds */ - vkCreateDebugReportCallbackEXT = - reinterpret_cast - (vkGetInstanceProcAddr(_instance, "vkCreateDebugReportCallbackEXT")); - vkDebugReportMessageEXT = - reinterpret_cast - (vkGetInstanceProcAddr(_instance, "vkDebugReportMessageEXT")); - vkDestroyDebugReportCallbackEXT = - reinterpret_cast - (vkGetInstanceProcAddr(_instance, "vkDestroyDebugReportCallbackEXT")); - - /* Setup callback creation information */ - VkDebugReportCallbackCreateInfoEXT callbackCreateInfo; - callbackCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; - 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 */ - VkResult err = vkCreateDebugReportCallbackEXT(_instance, &callbackCreateInfo, nullptr, &_callback); - - if (err != VK_SUCCESS) { - Error() << "Could not setup Debug callback"; - } + /* Load VK_EXT_debug_report entry points in debug builds */ + vkCreateDebugReportCallbackEXT = + reinterpret_cast + (vkGetInstanceProcAddr(_instance, "vkCreateDebugReportCallbackEXT")); + vkDebugReportMessageEXT = + reinterpret_cast + (vkGetInstanceProcAddr(_instance, "vkDebugReportMessageEXT")); + vkDestroyDebugReportCallbackEXT = + reinterpret_cast + (vkGetInstanceProcAddr(_instance, "vkDestroyDebugReportCallbackEXT")); + + /* Setup callback creation information */ + VkDebugReportCallbackCreateInfoEXT callbackCreateInfo; + callbackCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; + 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 */ + VkResult err = vkCreateDebugReportCallbackEXT(_instance, &callbackCreateInfo, nullptr, &_callback); + + if (err != VK_SUCCESS) { + Error() << "Could not setup Debug callback"; } return true; } diff --git a/src/Magnum/Vk/Math.h b/src/Magnum/Vk/Math.h index f3ddf5180..50971f57c 100644 --- a/src/Magnum/Vk/Math.h +++ b/src/Magnum/Vk/Math.h @@ -68,7 +68,7 @@ template Matrix4 perspectiveProjectionZeroToOne(const Vector2& si T zScale = T(1.0)/(near-far); return {{xyScale.x(), T(0), T(0), T(0)}, - { T(0), xyScale.y(), T(0), T(0)}, + { T(0),-xyScale.y(), T(0), T(0)}, { T(0), T(0), far*zScale, T(-1)}, // difference in [2][2] { T(0), T(0), far*near*zScale, T(0)}};// difference in [3][2] } diff --git a/src/Magnum/Vk/PhysicalDevice.h b/src/Magnum/Vk/PhysicalDevice.h index 4664f89dd..a2633b515 100644 --- a/src/Magnum/Vk/PhysicalDevice.h +++ b/src/Magnum/Vk/PhysicalDevice.h @@ -43,7 +43,7 @@ namespace Magnum { namespace Vk { enum class MemoryProperty: UnsignedInt { DeviceLocal = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, HostVisible = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, - Coherent = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + HostCoherent = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, HostCached = VK_MEMORY_PROPERTY_HOST_CACHED_BIT, LazilyAllocated = VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, }; diff --git a/src/Magnum/Vk/Pipeline.cpp b/src/Magnum/Vk/Pipeline.cpp index 5ad22ba07..c6481d807 100644 --- a/src/Magnum/Vk/Pipeline.cpp +++ b/src/Magnum/Vk/Pipeline.cpp @@ -37,8 +37,8 @@ Pipeline::~Pipeline() { std::unique_ptr GraphicsPipelineBuilder::build() { VkPipeline pipeline; - VkPipelineCache cache; VkPipelineLayout layout; + VkPipelineCache cache; /* create pipeline layout */ VkPipelineLayoutCreateInfo plInfo = { @@ -93,6 +93,13 @@ std::unique_ptr GraphicsPipelineBuilder::build() { UnsignedInt(_dynamicStates.size()), reinterpret_cast(_dynamicStates.data()) }; + VkPipelineViewportStateCreateInfo viewportState{ + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, nullptr, 0, + UnsignedInt(_viewports.size()), + _viewports.data(), + UnsignedInt(_scissors.size()), + _scissors.data() + }; VkGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; @@ -104,7 +111,7 @@ std::unique_ptr GraphicsPipelineBuilder::build() { pipelineInfo.pRasterizationState = &_rasterizationState; pipelineInfo.pColorBlendState = &_colorBlendState; pipelineInfo.pMultisampleState = &_multisampleState; - pipelineInfo.pViewportState = &_viewportState; + pipelineInfo.pViewportState = &viewportState; pipelineInfo.pDepthStencilState = &_depthStencilState; pipelineInfo.stageCount = UnsignedInt(_shaderStages.size()); pipelineInfo.pStages = _shaderStages.data(); diff --git a/src/Magnum/Vk/Pipeline.h b/src/Magnum/Vk/Pipeline.h index b9373198b..60eab503d 100644 --- a/src/Magnum/Vk/Pipeline.h +++ b/src/Magnum/Vk/Pipeline.h @@ -269,14 +269,6 @@ class MAGNUM_VK_EXPORT GraphicsPipelineBuilder { {0.0f, 0.0f, 0.0f, 0.0f} }; - _viewportState = { - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, nullptr, 0, - 1, - nullptr, // TODO currently allways expecting dynamic state here... - 1, - nullptr - }; - } /** @brief Copying is not allowed */ @@ -371,11 +363,46 @@ class MAGNUM_VK_EXPORT GraphicsPipelineBuilder { return *this; } + GraphicsPipelineBuilder& addPushConstantRange(ShaderStage stage, UnsignedInt size, UnsignedInt offset = 0) { + VkPushConstantRange range{VkShaderStageFlags(stage), offset, size}; + _pushConstantRanges.push_back(range); + return *this; + } + GraphicsPipelineBuilder& setPrimitiveTopology(PrimitiveTopology topology) { _primitiveTopology = topology; return *this; } + GraphicsPipelineBuilder& addViewport(const Range2D& viewport) { + VkViewport vp{ + viewport.min().x(), viewport.min().y(), + viewport.size().x(), viewport.size().y(), + 0.0f, 1.0f + }; + _viewports.push_back(vp); + return *this; + } + + GraphicsPipelineBuilder& addScissor(const Range2Di& sc) { + VkRect2D scissor{ + VkOffset2D{sc.min().x(), sc.min().y()}, + VkExtent2D{UnsignedInt(sc.size().x()), UnsignedInt(sc.size().y())} + }; + _scissors.push_back(scissor); + return *this; + } + + GraphicsPipelineBuilder& clear() { + _vertexInputAttrbutes.clear(); + _dynamicStates.clear(); + _setLayouts.clear(); + _vertexInputBindings.clear(); + _pushConstantRanges.clear(); + // do not clear _blendAttachments + return *this; + } + private: Device& _device; VkGraphicsPipelineCreateInfo _createInfo; @@ -384,7 +411,6 @@ class MAGNUM_VK_EXPORT GraphicsPipelineBuilder { VkPipelineRasterizationStateCreateInfo _rasterizationState; VkPipelineColorBlendStateCreateInfo _colorBlendState; VkPipelineMultisampleStateCreateInfo _multisampleState; - VkPipelineViewportStateCreateInfo _viewportState; VkPipelineDepthStencilStateCreateInfo _depthStencilState; std::vector _dynamicStates; @@ -393,6 +419,8 @@ class MAGNUM_VK_EXPORT GraphicsPipelineBuilder { std::vector _vertexInputBindings; std::vector _vertexInputAttrbutes; std::vector _pushConstantRanges; + std::vector _viewports; + std::vector _scissors; PrimitiveTopology _primitiveTopology; RenderPass* _renderPass; diff --git a/src/Magnum/Vk/Texture.h b/src/Magnum/Vk/Texture.h index 927fdb087..e0c0a56ee 100644 --- a/src/Magnum/Vk/Texture.h +++ b/src/Magnum/Vk/Texture.h @@ -40,6 +40,15 @@ namespace Magnum { namespace Vk { +enum class SamplerAddressMode: UnsignedInt { + Repeat = VK_SAMPLER_ADDRESS_MODE_REPEAT, + MirroredRepeat = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, + ClampToEdge = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + ClampToBorder = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, + MirrorClampToEdge = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, +}; + + /** @brief Texture @@ -48,7 +57,7 @@ namespace Magnum { namespace Vk { class MAGNUM_VK_EXPORT Texture { public: - Texture(Device& device, std::unique_ptr&& imageView, ImageLayout layout, Int numMipLevels): + Texture(Device& device, std::unique_ptr&& imageView, ImageLayout layout, Int numMipLevels, SamplerAddressMode samplerAddressMode = SamplerAddressMode::Repeat): _device{device}, _imageView{std::move(imageView)}, _imageLayout{layout}, @@ -58,16 +67,17 @@ class MAGNUM_VK_EXPORT Texture { VkSamplerCreateInfo sampler{VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, nullptr, 0}; sampler.magFilter = VK_FILTER_LINEAR; sampler.minFilter = VK_FILTER_LINEAR; - sampler.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; - sampler.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; - sampler.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; + sampler.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + sampler.addressModeU = VkSamplerAddressMode(samplerAddressMode); + sampler.addressModeV = VkSamplerAddressMode(samplerAddressMode); + sampler.addressModeW = VkSamplerAddressMode(samplerAddressMode); sampler.mipLodBias = 0.0f; + sampler.compareEnable = VK_FALSE; sampler.compareOp = VK_COMPARE_OP_NEVER; sampler.minLod = 0.0f; sampler.maxLod = float(mipLevels); - sampler.maxAnisotropy = 8; - sampler.anisotropyEnable = VK_TRUE; + sampler.maxAnisotropy = 1; + sampler.anisotropyEnable = VK_FALSE; sampler.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; sampler.unnormalizedCoordinates = VK_FALSE;