Browse Source

Vk: compute pipeline creation.

Because I needed something simple to test pipeline binding with. Also,
my first handwritten SPIR-V compute shader! It does absolutely nothing,
yay.
pull/494/head
Vladimír Vondruš 5 years ago
parent
commit
45c4fa20f7
  1. 18
      doc/snippets/MagnumVk.cpp
  2. 4
      doc/vulkan-mapping.dox
  3. 1
      src/Magnum/Vk/CMakeLists.txt
  4. 154
      src/Magnum/Vk/ComputePipelineCreateInfo.h
  5. 22
      src/Magnum/Vk/Pipeline.cpp
  6. 17
      src/Magnum/Vk/Pipeline.h
  7. 1
      src/Magnum/Vk/RasterizationPipelineCreateInfo.h
  8. 4
      src/Magnum/Vk/Test/CMakeLists.txt
  9. 77
      src/Magnum/Vk/Test/PipelineTest.cpp
  10. 25
      src/Magnum/Vk/Test/PipelineVkTest.cpp
  11. BIN
      src/Magnum/Vk/Test/compute-noop.spv
  12. 1
      src/Magnum/Vk/Vk.h

18
doc/snippets/MagnumVk.cpp

@ -37,6 +37,7 @@
#include "Magnum/Vk/BufferCreateInfo.h" #include "Magnum/Vk/BufferCreateInfo.h"
#include "Magnum/Vk/CommandBuffer.h" #include "Magnum/Vk/CommandBuffer.h"
#include "Magnum/Vk/CommandPoolCreateInfo.h" #include "Magnum/Vk/CommandPoolCreateInfo.h"
#include "Magnum/Vk/ComputePipelineCreateInfo.h"
#include "Magnum/Vk/DeviceCreateInfo.h" #include "Magnum/Vk/DeviceCreateInfo.h"
#include "Magnum/Vk/DeviceFeatures.h" #include "Magnum/Vk/DeviceFeatures.h"
#include "Magnum/Vk/DeviceProperties.h" #include "Magnum/Vk/DeviceProperties.h"
@ -812,6 +813,23 @@ Vk::Pipeline pipeline{device, Vk::RasterizationPipelineCreateInfo{
/* [Pipeline-creation-rasterization] */ /* [Pipeline-creation-rasterization] */
} }
{
Vk::Device device{NoCreate};
/* The include should be a no-op here since it was already included above */
/* [Pipeline-creation-compute] */
#include <Magnum/Vk/ComputePipelineCreateInfo.h>
DOXYGEN_IGNORE()
Vk::ShaderSet shaderSet{DOXYGEN_IGNORE()};
Vk::PipelineLayout pipelineLayout{DOXYGEN_IGNORE(NoCreate)};
Vk::Pipeline pipeline{device, Vk::ComputePipelineCreateInfo{
shaderSet, pipelineLayout
}};
/* [Pipeline-creation-compute] */
}
{ {
Vk::Device device{NoCreate}; Vk::Device device{NoCreate};
/* The include should be a no-op here since it was already included above */ /* The include should be a no-op here since it was already included above */

4
doc/vulkan-mapping.dox

@ -434,7 +434,7 @@ Vulkan structure | Matching API
@type_vk{CommandBufferInheritanceInfo} | | @type_vk{CommandBufferInheritanceInfo} | |
@type_vk{CommandPoolCreateInfo} | @ref CommandPoolCreateInfo @type_vk{CommandPoolCreateInfo} | @ref CommandPoolCreateInfo
@type_vk{ComponentMapping} | | @type_vk{ComponentMapping} | |
@type_vk{ComputePipelineCreateInfo} | | @type_vk{ComputePipelineCreateInfo} | @ref ComputePipelineCreateInfo
@type_vk{ConformanceVersion} | | @type_vk{ConformanceVersion} | |
@type_vk{CopyBufferInfo2KHR} @m_class{m-label m-flat m-warning} **KHR** | @ref CopyBufferInfo @type_vk{CopyBufferInfo2KHR} @m_class{m-label m-flat m-warning} **KHR** | @ref CopyBufferInfo
@type_vk{CopyBufferToImageInfo2KHR} @m_class{m-label m-flat m-warning} **KHR** | @ref CopyBufferToImageInfo @type_vk{CopyBufferToImageInfo2KHR} @m_class{m-label m-flat m-warning} **KHR** | @ref CopyBufferToImageInfo
@ -919,7 +919,7 @@ Vulkan enum | Matching API
@type_vk{PipelineCacheCreateFlagBits}, \n @type_vk{PipelineCacheCreateFlags} | | @type_vk{PipelineCacheCreateFlagBits}, \n @type_vk{PipelineCacheCreateFlags} | |
@type_vk{PipelineCacheHeaderVersion} | | @type_vk{PipelineCacheHeaderVersion} | |
@type_vk{PipelineCacheCreateFlagBits}, \n @type_vk{PipelineCacheCreateFlags} | | @type_vk{PipelineCacheCreateFlagBits}, \n @type_vk{PipelineCacheCreateFlags} | |
@type_vk{PipelineCreateFlagBits}, \n @type_vk{PipelineCreateFlags} | @ref RasterizationPipelineCreateInfo::Flag, \n @ref RasterizationPipelineCreateInfo::Flags @type_vk{PipelineCreateFlagBits}, \n @type_vk{PipelineCreateFlags} | @ref RasterizationPipelineCreateInfo::Flag, \n @ref RasterizationPipelineCreateInfo::Flags, \n @ref ComputePipelineCreateInfo::Flag, \n @ref ComputePipelineCreateInfo::Flags
@type_vk{PipelineShaderStageCreateFlagBits}, \n @type_vk{PipelineShaderStageCreateFlags} | | @type_vk{PipelineShaderStageCreateFlagBits}, \n @type_vk{PipelineShaderStageCreateFlags} | |
@type_vk{PipelineStageFlagBits}, \n @type_vk{PipelineStageFlags} | @ref PipelineStage, \n @ref PipelineStages @type_vk{PipelineStageFlagBits}, \n @type_vk{PipelineStageFlags} | @ref PipelineStage, \n @ref PipelineStages
@type_vk{PointClippingBehavior} @m_class{m-label m-flat m-success} **KHR, 1.1** | | @type_vk{PointClippingBehavior} @m_class{m-label m-flat m-success} **KHR, 1.1** | |

1
src/Magnum/Vk/CMakeLists.txt

@ -70,6 +70,7 @@ set(MagnumVk_HEADERS
CommandBuffer.h CommandBuffer.h
CommandPool.h CommandPool.h
CommandPoolCreateInfo.h CommandPoolCreateInfo.h
ComputePipelineCreateInfo.h
Device.h Device.h
DeviceCreateInfo.h DeviceCreateInfo.h
DeviceFeatures.h DeviceFeatures.h

154
src/Magnum/Vk/ComputePipelineCreateInfo.h

@ -0,0 +1,154 @@
#ifndef Magnum_Vk_ComputePipelineCreateInfo_h
#define Magnum_Vk_ComputePipelineCreateInfo_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
2020, 2021 Vladimír Vondruš <mosra@centrum.cz>
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::ComputePipelineCreateInfo
* @m_since_latest
*/
#include <Corrade/Containers/EnumSet.h>
#include "Magnum/Tags.h"
#include "Magnum/Vk/Vk.h"
#include "Magnum/Vk/Vulkan.h"
#include "Magnum/Vk/visibility.h"
namespace Magnum { namespace Vk {
/**
@brief Compute pipeline creation info
@m_since_latest
Wraps a @type_vk_keyword{ComputePipelineCreateInfo}. See
@ref Vk-Pipeline-creation-compute "Compute pipeline creation" for usage
information.
@see @ref RasterizationPipelineCreateInfo
*/
class MAGNUM_VK_EXPORT ComputePipelineCreateInfo {
public:
/**
* @brief Compute pipeline creation flag
*
* Wraps the compute-related subset of
* @type_vk_keyword{PipelineCreateFlagBits}.
* @see @ref Flags, @ref ComputePipelineCreateInfo(const ShaderSet&, VkPipelineLayout, Flags)
* @m_enum_values_as_keywords
*/
enum class Flag: UnsignedInt {
/**
* Create the pipeline without optimization.
*
* @m_class{m-note m-success}
*
* @par
* Setting this flag on single-use pipelines might help
* drivers pick a better tradeoff between CPU time spent
* optimizing the pipeline and GPU time spent executing it.
*/
DisableOptimization = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT,
/**
* Allow derivatives to be subsequently created from this pipeline.
*/
AllowDerivatives = VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT,
/** Derivative of a pipeline created earlier. */
Derivative = VK_PIPELINE_CREATE_DERIVATIVE_BIT
};
/**
* @brief Compite pipeline creation flags
*
* Type-safe wrapper for the compute-related subset of
* @type_vk_keyword{PipelineCreateFlags}.
* @see @ref ComputePipelineCreateInfo(const ShaderSet&, VkPipelineLayout, Flags)
*/
typedef Containers::EnumSet<Flag> Flags;
/**
* @brief Constructor
* @param shaderSet Shader to use for this pipeline. Expected
* to have just one entry.
* @param pipelineLayout A @ref PipelineLayout or a raw Vulkan
* pipeline layout handle
* @param flags Compute pipeline creation flags
*
* Note that the @p shaderSet structure internals are referenced, not
* copied, and thus have to stay in scope until the @ref Pipeline
* object is created.
*
* The following @type_vk{ComputePipelineCreateInfo} fields are
* pre-filled in addition to `sType`, everything else is zero-filled:
*
* - `flags`
* - `stage` to @p shaderSet
* - `layout` to @p pipelineLayout
*/
explicit ComputePipelineCreateInfo(const ShaderSet& shaderSet, VkPipelineLayout pipelineLayout, Flags flags = {});
/**
* @brief Construct without initializing the contents
*
* Note that not even the `sType` field nor the nested structure
* pointers are set --- the structure has to be fully initialized
* afterwards in order to be usable.
*/
explicit ComputePipelineCreateInfo(NoInitT) noexcept;
/**
* @brief Construct from existing data
*
* Copies the existing values verbatim, pointers are kept unchanged
* without taking over the ownership. Modifying the newly created
* instance will not modify the original data nor the pointed-to data.
*/
explicit ComputePipelineCreateInfo(const VkComputePipelineCreateInfo& info);
/** @brief Underlying @type_vk{GraphicsPipelineCreateInfo} structure */
VkComputePipelineCreateInfo& operator*() { return _info; }
/** @overload */
const VkComputePipelineCreateInfo& operator*() const { return _info; }
/** @overload */
VkComputePipelineCreateInfo* operator->() { return &_info; }
/** @overload */
const VkComputePipelineCreateInfo* operator->() const { return &_info; }
/** @overload */
operator const VkComputePipelineCreateInfo*() const { return &_info; }
private:
VkComputePipelineCreateInfo _info;
};
CORRADE_ENUMSET_OPERATORS(ComputePipelineCreateInfo::Flags)
}}
/* Make the definition complete -- it doesn't make sense to have a CreateInfo
without the corresponding object anyway. */
#include "Magnum/Vk/Pipeline.h"
#endif

22
src/Magnum/Vk/Pipeline.cpp

@ -25,6 +25,7 @@
#include "Pipeline.h" #include "Pipeline.h"
#include "RasterizationPipelineCreateInfo.h" #include "RasterizationPipelineCreateInfo.h"
#include "ComputePipelineCreateInfo.h"
#include "CommandBuffer.h" #include "CommandBuffer.h"
#include <Corrade/Containers/Array.h> #include <Corrade/Containers/Array.h>
@ -259,6 +260,23 @@ RasterizationPipelineCreateInfo& RasterizationPipelineCreateInfo::setDynamicStat
return *this; return *this;
} }
ComputePipelineCreateInfo::ComputePipelineCreateInfo(const ShaderSet& shaderSet, const VkPipelineLayout pipelineLayout, const Flags flags): _info{} {
CORRADE_ASSERT(shaderSet.stages().size() == 1,
"Vk::ComputePipelineCreateInfo: the shader set has to contain exactly one shader, got" << shaderSet.stages().size(), );
_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
_info.flags = VkPipelineCreateFlags(flags);
_info.stage = shaderSet.stages()[0];
_info.layout = pipelineLayout;
}
ComputePipelineCreateInfo::ComputePipelineCreateInfo(NoInitT) noexcept {}
ComputePipelineCreateInfo::ComputePipelineCreateInfo(const VkComputePipelineCreateInfo& info):
/* Can't use {} with GCC 4.8 here because it tries to initialize the first
member instead of doing a copy */
_info(info) {}
Pipeline Pipeline::wrap(Device& device, const VkPipeline handle, const HandleFlags flags) { Pipeline Pipeline::wrap(Device& device, const VkPipeline handle, const HandleFlags flags) {
Pipeline out{NoCreate}; Pipeline out{NoCreate};
out._device = &device; out._device = &device;
@ -283,6 +301,10 @@ Pipeline::Pipeline(Device& device, const RasterizationPipelineCreateInfo& info):
MAGNUM_VK_INTERNAL_ASSERT_SUCCESS(device->CreateGraphicsPipelines(device, {}, 1, info, nullptr, &_handle)); MAGNUM_VK_INTERNAL_ASSERT_SUCCESS(device->CreateGraphicsPipelines(device, {}, 1, info, nullptr, &_handle));
} }
Pipeline::Pipeline(Device& device, const ComputePipelineCreateInfo& info): _device{&device}, _flags{HandleFlag::DestroyOnDestruction} {
MAGNUM_VK_INTERNAL_ASSERT_SUCCESS(device->CreateComputePipelines(device, {}, 1, info, nullptr, &_handle));
}
Pipeline::Pipeline(NoCreateT): _device{}, _handle{} {} Pipeline::Pipeline(NoCreateT): _device{}, _handle{} {}
Pipeline::Pipeline(Pipeline&& other) noexcept: _device{other._device}, _handle{other._handle}, _flags{other._flags} { Pipeline::Pipeline(Pipeline&& other) noexcept: _device{other._device}, _handle{other._handle}, _flags{other._flags} {

17
src/Magnum/Vk/Pipeline.h

@ -60,6 +60,14 @@ Certain aspects of the pipeline can be set as dynamic using
@relativeref{RasterizationPipelineCreateInfo,setDynamicStates()} --- in that @relativeref{RasterizationPipelineCreateInfo,setDynamicStates()} --- in that
case a subset of the values passed to the constructor will be ignored. See the case a subset of the values passed to the constructor will be ignored. See the
particular @ref DynamicRasterizationState values for more information. particular @ref DynamicRasterizationState values for more information.
@section Vk-Pipeline-creation-compute Compute pipeline creation
Compared to a rasterization pipeline, @ref ComputePipelineCreateInfo only takes
a @ref ShaderSet containing a single @ref ShaderStage::Compute shader and a
@link PipelineLayout @endlink:
@snippet MagnumVk.cpp Pipeline-creation-compute
*/ */
class MAGNUM_VK_EXPORT Pipeline { class MAGNUM_VK_EXPORT Pipeline {
public: public:
@ -86,6 +94,15 @@ class MAGNUM_VK_EXPORT Pipeline {
*/ */
explicit Pipeline(Device& device, const RasterizationPipelineCreateInfo& info); explicit Pipeline(Device& device, const RasterizationPipelineCreateInfo& info);
/**
* @brief Construct a compute pipeline
* @param device Vulkan device to create the pipeline on
* @param info Compite pipeline creation info
*
* @see @fn_vk_keyword{CreateComputePipelines}
*/
explicit Pipeline(Device& device, const ComputePipelineCreateInfo& info);
/** /**
* @brief Construct without creating the pipeline layout * @brief Construct without creating the pipeline layout
* *

1
src/Magnum/Vk/RasterizationPipelineCreateInfo.h

@ -291,6 +291,7 @@ Wraps a @type_vk_keyword{GraphicsPipelineCreateInfo}, along with
See @ref Vk-Pipeline-creation-rasterization "Rasterization pipeline creation" See @ref Vk-Pipeline-creation-rasterization "Rasterization pipeline creation"
for usage information. for usage information.
@see @ref ComputePipelineCreateInfo
*/ */
class MAGNUM_VK_EXPORT RasterizationPipelineCreateInfo { class MAGNUM_VK_EXPORT RasterizationPipelineCreateInfo {
public: public:

4
src/Magnum/Vk/Test/CMakeLists.txt

@ -43,7 +43,7 @@ corrade_add_test(VkIntegrationTest IntegrationTest.cpp LIBRARIES MagnumVk)
corrade_add_test(VkLayerPropertiesTest LayerPropertiesTest.cpp LIBRARIES MagnumVk) corrade_add_test(VkLayerPropertiesTest LayerPropertiesTest.cpp LIBRARIES MagnumVk)
corrade_add_test(VkMemoryTest MemoryTest.cpp LIBRARIES MagnumVkTestLib) corrade_add_test(VkMemoryTest MemoryTest.cpp LIBRARIES MagnumVkTestLib)
corrade_add_test(VkMeshLayoutTest MeshLayoutTest.cpp LIBRARIES MagnumVkTestLib) corrade_add_test(VkMeshLayoutTest MeshLayoutTest.cpp LIBRARIES MagnumVkTestLib)
corrade_add_test(VkPipelineTest PipelineTest.cpp LIBRARIES MagnumVk) corrade_add_test(VkPipelineTest PipelineTest.cpp LIBRARIES MagnumVkTestLib)
corrade_add_test(VkPipelineLayoutTest PipelineLayoutTest.cpp LIBRARIES MagnumVk) corrade_add_test(VkPipelineLayoutTest PipelineLayoutTest.cpp LIBRARIES MagnumVk)
corrade_add_test(VkPixelFormatTest PixelFormatTest.cpp LIBRARIES MagnumVkTestLib) corrade_add_test(VkPixelFormatTest PixelFormatTest.cpp LIBRARIES MagnumVkTestLib)
corrade_add_test(VkQueueTest QueueTest.cpp LIBRARIES MagnumVk) corrade_add_test(VkQueueTest QueueTest.cpp LIBRARIES MagnumVk)
@ -178,7 +178,7 @@ if(BUILD_VK_TESTS)
corrade_add_test(VkMemoryVkTest MemoryVkTest.cpp LIBRARIES MagnumVk MagnumVulkanTester) corrade_add_test(VkMemoryVkTest MemoryVkTest.cpp LIBRARIES MagnumVk MagnumVulkanTester)
corrade_add_test(VkPipelineVkTest PipelineVkTest.cpp corrade_add_test(VkPipelineVkTest PipelineVkTest.cpp
LIBRARIES MagnumVkTestLib MagnumVulkanTester LIBRARIES MagnumVkTestLib MagnumVulkanTester
FILES triangle-shaders.spv) FILES triangle-shaders.spv compute-noop.spv)
target_include_directories(VkPipelineVkTest PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_include_directories(VkPipelineVkTest PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
corrade_add_test(VkPipelineLayoutVkTest PipelineLayoutVkTest.cpp LIBRARIES MagnumVk MagnumVulkanTester) corrade_add_test(VkPipelineLayoutVkTest PipelineLayoutVkTest.cpp LIBRARIES MagnumVk MagnumVulkanTester)
corrade_add_test(VkQueueVkTest QueueVkTest.cpp LIBRARIES MagnumVk MagnumVulkanTester) corrade_add_test(VkQueueVkTest QueueVkTest.cpp LIBRARIES MagnumVk MagnumVulkanTester)

77
src/Magnum/Vk/Test/PipelineTest.cpp

@ -24,17 +24,21 @@
*/ */
#include <new> #include <new>
#include <sstream>
#include <Corrade/Containers/ArrayView.h> #include <Corrade/Containers/ArrayView.h>
#include <Corrade/Containers/StringView.h> #include <Corrade/Containers/StringView.h>
#include <Corrade/TestSuite/Tester.h> #include <Corrade/TestSuite/Tester.h>
#include <Corrade/Utility/DebugStl.h>
#include "Magnum/Math/Range.h" #include "Magnum/Math/Range.h"
#include "Magnum/Vk/ComputePipelineCreateInfo.h"
#include "Magnum/Vk/Device.h" #include "Magnum/Vk/Device.h"
#include "Magnum/Vk/Image.h" #include "Magnum/Vk/Image.h"
#include "Magnum/Vk/MeshLayout.h" #include "Magnum/Vk/MeshLayout.h"
#include "Magnum/Vk/Pipeline.h" #include "Magnum/Vk/Pipeline.h"
#include "Magnum/Vk/PixelFormat.h" #include "Magnum/Vk/PixelFormat.h"
#include "Magnum/Vk/RasterizationPipelineCreateInfo.h" #include "Magnum/Vk/RasterizationPipelineCreateInfo.h"
#include "Magnum/Vk/Shader.h"
#include "Magnum/Vk/ShaderSet.h" #include "Magnum/Vk/ShaderSet.h"
namespace Magnum { namespace Vk { namespace Test { namespace { namespace Magnum { namespace Vk { namespace Test { namespace {
@ -57,6 +61,12 @@ struct PipelineTest: TestSuite::Tester {
void rasterizationCreateInfoViewport2DImplicitScissor(); void rasterizationCreateInfoViewport2DImplicitScissor();
void rasterizationCreateInfoDynamicState(); void rasterizationCreateInfoDynamicState();
void computeCreateInfoConstruct();
void computeCreateInfoConstructOwnedEntrypoint();
void computeCreateInfoConstructNotSingleShader();
void computeCreateInfoConstructNoInit();
void computeCreateInfoConstructFromVk();
void constructNoCreate(); void constructNoCreate();
void constructCopy(); void constructCopy();
@ -90,6 +100,12 @@ PipelineTest::PipelineTest() {
&PipelineTest::rasterizationCreateInfoViewport2DImplicitScissor, &PipelineTest::rasterizationCreateInfoViewport2DImplicitScissor,
&PipelineTest::rasterizationCreateInfoDynamicState, &PipelineTest::rasterizationCreateInfoDynamicState,
&PipelineTest::computeCreateInfoConstruct,
&PipelineTest::computeCreateInfoConstructOwnedEntrypoint,
&PipelineTest::computeCreateInfoConstructNotSingleShader,
&PipelineTest::computeCreateInfoConstructNoInit,
&PipelineTest::computeCreateInfoConstructFromVk,
&PipelineTest::constructNoCreate, &PipelineTest::constructNoCreate,
&PipelineTest::constructCopy, &PipelineTest::constructCopy,
@ -107,6 +123,8 @@ PipelineTest::PipelineTest() {
&PipelineTest::imageMemoryBarrierConstructFromVk}); &PipelineTest::imageMemoryBarrierConstructFromVk});
} }
using namespace Containers::Literals;
void PipelineTest::dynamicRasterizationStateMapping() { void PipelineTest::dynamicRasterizationStateMapping() {
/* Same table is in Pipeline.cpp, here just to have something to test the /* Same table is in Pipeline.cpp, here just to have something to test the
order with -- without this, correct order can't be verified */ order with -- without this, correct order can't be verified */
@ -510,6 +528,65 @@ void PipelineTest::rasterizationCreateInfoDynamicState() {
CORRADE_COMPARE(info->pDynamicState->pDynamicStates[2], VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT); CORRADE_COMPARE(info->pDynamicState->pDynamicStates[2], VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT);
} }
void PipelineTest::computeCreateInfoConstruct() {
ShaderSet shaderSet;
Containers::StringView name = "dead"_s;
/* Yes, I know Fragment is wrong, it's just for testing */
shaderSet.addShader(ShaderStage::Fragment, reinterpret_cast<VkShaderModule>(0xbeef), name);
ComputePipelineCreateInfo info{shaderSet, reinterpret_cast<VkPipelineLayout>(0xdead), ComputePipelineCreateInfo::Flag::DisableOptimization|ComputePipelineCreateInfo::Flag::AllowDerivatives};
CORRADE_COMPARE(info->flags, VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT|VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT);
CORRADE_COMPARE(info->stage.stage, VK_SHADER_STAGE_FRAGMENT_BIT);
CORRADE_COMPARE(info->stage.module, reinterpret_cast<VkShaderModule>(0xbeef));
CORRADE_COMPARE(info->stage.pName, name.data());
CORRADE_COMPARE(info->layout, reinterpret_cast<VkPipelineLayout>(0xdead));
}
void PipelineTest::computeCreateInfoConstructOwnedEntrypoint() {
ShaderSet shaderSet;
shaderSet.addShader({}, {}, "dead!"_s.except(1));
ComputePipelineCreateInfo info{shaderSet, {}};
CORRADE_COMPARE(info->stage.pName, "dead"_s);
{
CORRADE_EXPECT_FAIL("ComputePipelineCreateInfo currently expects the ShaderSet to stay in scope, referencing its internals.");
CORRADE_VERIFY(info->stage.pName != shaderSet.stages()[0].pName);
}
}
void PipelineTest::computeCreateInfoConstructNotSingleShader() {
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
ShaderSet shaderSet;
std::ostringstream out;
Error redirectError{&out};
ComputePipelineCreateInfo info{shaderSet, {}};
CORRADE_COMPARE(out.str(), "Vk::ComputePipelineCreateInfo: the shader set has to contain exactly one shader, got 0\n");
}
void PipelineTest::computeCreateInfoConstructNoInit() {
ComputePipelineCreateInfo info{NoInit};
info->sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
new(&info) ComputePipelineCreateInfo{NoInit};
CORRADE_COMPARE(info->sType, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2);
CORRADE_VERIFY((std::is_nothrow_constructible<ComputePipelineCreateInfo, NoInitT>::value));
/* Implicit construction is not allowed */
CORRADE_VERIFY(!(std::is_convertible<NoInitT, ComputePipelineCreateInfo>::value));
}
void PipelineTest::computeCreateInfoConstructFromVk() {
VkComputePipelineCreateInfo vkInfo;
vkInfo.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
ComputePipelineCreateInfo info{vkInfo};
CORRADE_COMPARE(info->sType, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2);
}
void PipelineTest::constructNoCreate() { void PipelineTest::constructNoCreate() {
{ {
Pipeline pipeline{NoCreate}; Pipeline pipeline{NoCreate};

25
src/Magnum/Vk/Test/PipelineVkTest.cpp

@ -33,6 +33,7 @@
#include "Magnum/Vk/BufferCreateInfo.h" #include "Magnum/Vk/BufferCreateInfo.h"
#include "Magnum/Vk/CommandBuffer.h" #include "Magnum/Vk/CommandBuffer.h"
#include "Magnum/Vk/CommandPoolCreateInfo.h" #include "Magnum/Vk/CommandPoolCreateInfo.h"
#include "Magnum/Vk/ComputePipelineCreateInfo.h"
#include "Magnum/Vk/DeviceProperties.h" #include "Magnum/Vk/DeviceProperties.h"
#include "Magnum/Vk/ImageCreateInfo.h" #include "Magnum/Vk/ImageCreateInfo.h"
#include "Magnum/Vk/MeshLayout.h" #include "Magnum/Vk/MeshLayout.h"
@ -58,6 +59,7 @@ struct PipelineVkTest: VulkanTester {
void constructRasterizationViewportNotSet(); void constructRasterizationViewportNotSet();
void constructRasterizationViewportNotSetDiscardEnabled(); void constructRasterizationViewportNotSetDiscardEnabled();
void constructRasterizationViewportNotSetDynamic(); void constructRasterizationViewportNotSetDynamic();
void constructCompute();
void constructMove(); void constructMove();
void wrap(); void wrap();
@ -74,6 +76,7 @@ PipelineVkTest::PipelineVkTest() {
&PipelineVkTest::constructRasterizationViewportNotSet, &PipelineVkTest::constructRasterizationViewportNotSet,
&PipelineVkTest::constructRasterizationViewportNotSetDiscardEnabled, &PipelineVkTest::constructRasterizationViewportNotSetDiscardEnabled,
&PipelineVkTest::constructRasterizationViewportNotSetDynamic, &PipelineVkTest::constructRasterizationViewportNotSetDynamic,
&PipelineVkTest::constructCompute,
&PipelineVkTest::constructMove, &PipelineVkTest::constructMove,
&PipelineVkTest::wrap, &PipelineVkTest::wrap,
@ -245,6 +248,28 @@ void PipelineVkTest::constructRasterizationViewportNotSetDynamic() {
CORRADE_VERIFY(pipeline.handle()); CORRADE_VERIFY(pipeline.handle());
} }
void PipelineVkTest::constructCompute() {
{
PipelineLayout pipelineLayout{device(), PipelineLayoutCreateInfo{}};
Shader shader{device(), ShaderCreateInfo{
Utility::Directory::read(Utility::Directory::join(VK_TEST_DIR, "compute-noop.spv"))
}};
ShaderSet shaderSet;
shaderSet.addShader(ShaderStage::Compute, shader, "main"_s);
Pipeline pipeline{device(), ComputePipelineCreateInfo{
shaderSet, pipelineLayout
}};
CORRADE_VERIFY(pipeline.handle());
CORRADE_COMPARE(pipeline.handleFlags(), HandleFlag::DestroyOnDestruction);
}
/* Shouldn't crash or anything */
CORRADE_VERIFY(true);
}
void PipelineVkTest::constructMove() { void PipelineVkTest::constructMove() {
RenderPass renderPass{device(), RenderPassCreateInfo{} RenderPass renderPass{device(), RenderPassCreateInfo{}
.setAttachments({ .setAttachments({

BIN
src/Magnum/Vk/Test/compute-noop.spv

Binary file not shown.

1
src/Magnum/Vk/Vk.h

@ -45,6 +45,7 @@ class CommandBuffer;
/* CommandBufferBeginInfo is useful only in combination with CommandBuffer */ /* CommandBufferBeginInfo is useful only in combination with CommandBuffer */
class CommandPool; class CommandPool;
class CommandPoolCreateInfo; class CommandPoolCreateInfo;
class ComputePipelineCreateInfo;
/* BufferCopy used only directly inside CopyBufferInfo */ /* BufferCopy used only directly inside CopyBufferInfo */
class CopyBufferInfo; class CopyBufferInfo;
/* ImageCopy used only directly inside CopyImageInfo */ /* ImageCopy used only directly inside CopyImageInfo */

Loading…
Cancel
Save