Browse Source

Vk: rethink render pass creation to make it clearer (but more verbose).

Originally I wanted to save people typing and provide "reasonable
defaults" for the image layout, however shortly after I realized I can't
express even the simplest case in the Vulkan Triangle example with
those.

Furthermore the case of having default load/store operations are so
rare that it isn't worth an extra API which tricks the user into
thinking the clear/discard operations are meant to be done somewhere
else. I realized this because it was actually harder to explain these in
a second step than introducing them right from the beginning.

Finally, because there's so many different structures to fill, the
implicit constructors weren't a good idea either, as it again tricked
users to think just PixelFormat or just an index is the parameter, with
nothing else, and then left them wondering where all the other important
params go. Same with {} used instead AttachmentLoadOperation::Load /
AttachmentStoreOperation::Store, unnecessary confusion there so don't
even suggest that.
pull/494/head
Vladimír Vondruš 5 years ago
parent
commit
0825db39ab
  1. 61
      doc/snippets/MagnumVk.cpp
  2. 12
      src/Magnum/Vk/Image.h
  3. 12
      src/Magnum/Vk/RenderPass.cpp
  4. 66
      src/Magnum/Vk/RenderPass.h
  5. 92
      src/Magnum/Vk/RenderPassCreateInfo.h
  6. 44
      src/Magnum/Vk/Test/FramebufferVkTest.cpp
  7. 169
      src/Magnum/Vk/Test/RenderPassTest.cpp
  8. 54
      src/Magnum/Vk/Test/RenderPassVkTest.cpp

61
doc/snippets/MagnumVk.cpp

@ -403,8 +403,8 @@ Vk::ImageView depthView{device, Vk::ImageViewCreateInfo2D{depth}};
Vk::RenderPass renderPass{device, Vk::RenderPassCreateInfo{} /* created before */ Vk::RenderPass renderPass{device, Vk::RenderPassCreateInfo{} /* created before */
.setAttachments({ .setAttachments({
color.format(), Vk::AttachmentDescription{color.format(), DOXYGEN_IGNORE({}, {}, {}, {})},
depth.format() Vk::AttachmentDescription{depth.format(), DOXYGEN_IGNORE({}, {}, {}, {})},
}) })
DOXYGEN_IGNORE() DOXYGEN_IGNORE()
}; };
@ -621,7 +621,7 @@ indices.bindMemory(memory, indicesOffset);
} }
{ {
Vk::Device device{DOXYGEN_IGNORE(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 */
/* [RenderPass-creation] */ /* [RenderPass-creation] */
#include <Magnum/Vk/RenderPassCreateInfo.h> #include <Magnum/Vk/RenderPassCreateInfo.h>
@ -630,52 +630,29 @@ DOXYGEN_IGNORE()
Vk::RenderPass renderPass{device, Vk::RenderPassCreateInfo{} Vk::RenderPass renderPass{device, Vk::RenderPassCreateInfo{}
.setAttachments({ .setAttachments({
Vk::PixelFormat::RGBA8Srgb, Vk::AttachmentDescription{Vk::PixelFormat::RGBA8Srgb,
Vk::PixelFormat::Depth24UnormStencil8UI Vk::AttachmentLoadOperation::Clear,
Vk::AttachmentStoreOperation::Store,
Vk::ImageLayout::Undefined,
Vk::ImageLayout::ColorAttachment},
Vk::AttachmentDescription{Vk::PixelFormat::Depth24UnormStencil8UI,
Vk::AttachmentLoadOperation::Clear,
Vk::AttachmentStoreOperation::DontCare,
Vk::ImageLayout::Undefined,
Vk::ImageLayout::DepthStencilAttachment}
}) })
.addSubpass(Vk::SubpassDescription{} .addSubpass(Vk::SubpassDescription{}
.setColorAttachments({0}) .setColorAttachments({
.setDepthStencilAttachment(1) Vk::AttachmentReference{0, Vk::ImageLayout::ColorAttachment}
})
.setDepthStencilAttachment(
Vk::AttachmentReference{1, Vk::ImageLayout::DepthStencilAttachment}
)
) )
}; };
/* [RenderPass-creation] */ /* [RenderPass-creation] */
} }
{
Vk::Device device{DOXYGEN_IGNORE(NoCreate)};
/* [RenderPass-creation-load-store] */
Vk::RenderPass renderPass{device, Vk::RenderPassCreateInfo{}
.setAttachments({
{Vk::PixelFormat::RGBA8Srgb, Vk::AttachmentLoadOperation::Clear, {}},
{Vk::PixelFormat::Depth24UnormStencil8UI, Vk::AttachmentLoadOperation::Clear, {}},
})
DOXYGEN_IGNORE()
};
/* [RenderPass-creation-load-store] */
}
{
Vk::Device device{DOXYGEN_IGNORE(NoCreate)};
/* [RenderPass-creation-layout] */
Vk::RenderPass renderPass{device, Vk::RenderPassCreateInfo{}
.setAttachments({
{Vk::PixelFormat::RGBA8Srgb,
Vk::AttachmentLoadOperation::Clear, {},
Vk::ImageLayout::ColorAttachment,
Vk::ImageLayout::ColorAttachment},
{Vk::PixelFormat::Depth24UnormStencil8UI,
Vk::AttachmentLoadOperation::Clear, {},
Vk::ImageLayout::DepthStencilAttachment,
Vk::ImageLayout::DepthStencilAttachment},
})
.addSubpass(Vk::SubpassDescription{}
.setColorAttachments({{0, Vk::ImageLayout::ColorAttachment}})
.setDepthStencilAttachment({1, Vk::ImageLayout::ColorAttachment})
)
};
/* [RenderPass-creation-layout] */
}
{ {
Vk::Device device{DOXYGEN_IGNORE(NoCreate)}; Vk::Device device{DOXYGEN_IGNORE(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 */

12
src/Magnum/Vk/Image.h

@ -49,9 +49,11 @@ namespace Implementation { struct DeviceState; }
*/ */
enum class ImageLayout: Int { enum class ImageLayout: Int {
/** /**
* Undefined. Can only be used as the initial layout in * Undefined. Can be used as the initial layout in @ref ImageCreateInfo
* @ref ImageCreateInfo structures (and there it's the default). Images in * structures (and there it's the default) and as the initial layout in
* this layout are not accessible by the device, the image has to be * render pass @ref AttachmentDescription (in which case it tells the
* driver that we don't care about the previous contents). Images in this
* layout are not accessible by the device, the image has to be
* transitioned to a defined layout such as @ref ImageLayout::General * transitioned to a defined layout such as @ref ImageLayout::General
* first; contents of the memory are not guaranteed to be preserved during * first; contents of the memory are not guaranteed to be preserved during
* the transition. * the transition.
@ -84,9 +86,7 @@ enum class ImageLayout: Int {
Preinitialized = VK_IMAGE_LAYOUT_PREINITIALIZED, Preinitialized = VK_IMAGE_LAYOUT_PREINITIALIZED,
/** /**
* General layout, supports all types of device access. This is the * General layout, supports all types of device access.
* conservative default used everywhere except the @ref ImageCreateInfo
* structures, which uses @ref ImageLayout::Undefined.
* *
* @m_class{m-note m-success} * @m_class{m-note m-success}
* *

12
src/Magnum/Vk/RenderPass.cpp

@ -57,12 +57,6 @@ AttachmentDescription::AttachmentDescription(const Magnum::PixelFormat format, c
AttachmentDescription::AttachmentDescription(const Magnum::CompressedPixelFormat format, const AttachmentLoadOperation loadOperation, const AttachmentStoreOperation storeOperation, const ImageLayout initialLayout, const ImageLayout finalLayout, const Int samples, const Flags flags): AttachmentDescription{pixelFormat(format), loadOperation, storeOperation, initialLayout, finalLayout, samples, flags} {} AttachmentDescription::AttachmentDescription(const Magnum::CompressedPixelFormat format, const AttachmentLoadOperation loadOperation, const AttachmentStoreOperation storeOperation, const ImageLayout initialLayout, const ImageLayout finalLayout, const Int samples, const Flags flags): AttachmentDescription{pixelFormat(format), loadOperation, storeOperation, initialLayout, finalLayout, samples, flags} {}
AttachmentDescription::AttachmentDescription(const PixelFormat format, const AttachmentLoadOperation loadOperation, const AttachmentStoreOperation storeOperation, const Int samples, const Flags flags): AttachmentDescription{format, loadOperation, storeOperation, ImageLayout::General, ImageLayout::General, samples, flags} {}
AttachmentDescription::AttachmentDescription(const Magnum::PixelFormat format, const AttachmentLoadOperation loadOperation, const AttachmentStoreOperation storeOperation, const Int samples, const Flags flags): AttachmentDescription{pixelFormat(format), loadOperation, storeOperation, samples, flags} {}
AttachmentDescription::AttachmentDescription(const Magnum::CompressedPixelFormat format, const AttachmentLoadOperation loadOperation, const AttachmentStoreOperation storeOperation, const Int samples, const Flags flags): AttachmentDescription{pixelFormat(format), loadOperation, storeOperation, samples, flags} {}
AttachmentDescription::AttachmentDescription(const PixelFormat format, const std::pair<AttachmentLoadOperation, AttachmentLoadOperation> depthStencilLoadOperation, const std::pair<AttachmentStoreOperation, AttachmentStoreOperation> depthStencilStoreOperation, const ImageLayout initialLayout, const ImageLayout finalLayout, const Int samples, const Flags flags): _description{} { AttachmentDescription::AttachmentDescription(const PixelFormat format, const std::pair<AttachmentLoadOperation, AttachmentLoadOperation> depthStencilLoadOperation, const std::pair<AttachmentStoreOperation, AttachmentStoreOperation> depthStencilStoreOperation, const ImageLayout initialLayout, const ImageLayout finalLayout, const Int samples, const Flags flags): _description{} {
_description.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2; _description.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2;
_description.flags = VkAttachmentDescriptionFlags(flags); _description.flags = VkAttachmentDescriptionFlags(flags);
@ -80,12 +74,6 @@ AttachmentDescription::AttachmentDescription(const Magnum::PixelFormat format, c
AttachmentDescription::AttachmentDescription(const Magnum::CompressedPixelFormat format, const std::pair<AttachmentLoadOperation, AttachmentLoadOperation> depthStencilLoadOperation, const std::pair<AttachmentStoreOperation, AttachmentStoreOperation> depthStencilStoreOperation, const ImageLayout initialLayout, const ImageLayout finalLayout, const Int samples, const Flags flags): AttachmentDescription{pixelFormat(format), depthStencilLoadOperation, depthStencilStoreOperation, initialLayout, finalLayout, samples, flags} {} AttachmentDescription::AttachmentDescription(const Magnum::CompressedPixelFormat format, const std::pair<AttachmentLoadOperation, AttachmentLoadOperation> depthStencilLoadOperation, const std::pair<AttachmentStoreOperation, AttachmentStoreOperation> depthStencilStoreOperation, const ImageLayout initialLayout, const ImageLayout finalLayout, const Int samples, const Flags flags): AttachmentDescription{pixelFormat(format), depthStencilLoadOperation, depthStencilStoreOperation, initialLayout, finalLayout, samples, flags} {}
AttachmentDescription::AttachmentDescription(const PixelFormat format, const std::pair<AttachmentLoadOperation, AttachmentLoadOperation> depthStencilLoadOperation, const std::pair<AttachmentStoreOperation, AttachmentStoreOperation> depthStencilStoreOperation, const Int samples, const Flags flags): AttachmentDescription{format, depthStencilLoadOperation, depthStencilStoreOperation, ImageLayout::General, ImageLayout::General, samples, flags} {}
AttachmentDescription::AttachmentDescription(const Magnum::PixelFormat format, const std::pair<AttachmentLoadOperation, AttachmentLoadOperation> depthStencilLoadOperation, const std::pair<AttachmentStoreOperation, AttachmentStoreOperation> depthStencilStoreOperation, const Int samples, const Flags flags): AttachmentDescription{pixelFormat(format), depthStencilLoadOperation, depthStencilStoreOperation, samples, flags} {}
AttachmentDescription::AttachmentDescription(const Magnum::CompressedPixelFormat format, const std::pair<AttachmentLoadOperation, AttachmentLoadOperation> depthStencilLoadOperation, const std::pair<AttachmentStoreOperation, AttachmentStoreOperation> depthStencilStoreOperation, const Int samples, const Flags flags): AttachmentDescription{pixelFormat(format), depthStencilLoadOperation, depthStencilStoreOperation, samples, flags} {}
AttachmentDescription::AttachmentDescription(NoInitT) noexcept {} AttachmentDescription::AttachmentDescription(NoInitT) noexcept {}
AttachmentDescription::AttachmentDescription(const VkAttachmentDescription2& description): AttachmentDescription::AttachmentDescription(const VkAttachmentDescription2& description):

66
src/Magnum/Vk/RenderPass.h

@ -53,45 +53,45 @@ connected together in a @ref Framebuffer.
@section Vk-RenderPass-creation Render pass creation @section Vk-RenderPass-creation Render pass creation
@ref RenderPassCreateInfo is a set of attachments, described by A @ref RenderPassCreateInfo consists of:
@ref AttachmentDescription instances, subpasses operating on those attachments,
described by a @ref SubpassDescription using @ref AttachmentReference - a set of attachments, described by @ref AttachmentDescription instances,
instances, and subpass dependencies, described by @ref SubpassDependency. - subpasses operating on those attachments, described by a
@ref SubpassDescription using @ref AttachmentReference instances,
- and subpass dependencies, described by @ref SubpassDependency.
A render pass has to have at least one subpass. It's common to have just one A render pass has to have at least one subpass. It's common to have just one
subpass but while the subpass isn't required to operate on any attachments, subpass, but while the subpass isn't required to operate on any attachments,
such case is rather rare. Following is a simple setup for one subpass operating such case is rather rare. Following is a simple setup for one subpass operating
on a color and a combined depth/stencil attachment. The main parameter an on a color and a combined depth/stencil attachment. Each
@ref AttachmentDescription needs is attachment format; the numbers passed to @ref AttachmentDescription describes a concrete attachment and particular
@ref SubpassDescription::setColorAttachments() and @ref SubpassDescription::setColorAttachments() /
@ref SubpassDescription::setDepthStencilAttachment() are indices into the @ref SubpassDescription::setDepthStencilAttachment() "setColorAttachments()"
@ref RenderPassCreateInfo::setAttachments() array, and it's actually then reference it by an index.
@ref AttachmentReference instances:
In addition to a format, each @ref AttachmentDescription has to specify an
@ref AttachmentLoadOperation that happens at the render pass begin --- whether
we want to preserve the contents, clear them or discard --- and similarly an
@ref AttachmentStoreOperation at the end. Then, the @ref ImageLayout parameters
specify what implicit layout transitions (if any) need to happen between start
of the render pass and the first subpass, between subpasses and between last
subpass and end of the render pass.
@snippet MagnumVk.cpp RenderPass-creation @snippet MagnumVk.cpp RenderPass-creation
The above again does a conservative estimate that you'd want to preserve the <b></b>
attachment contents between render passes. Usually you'd want to clear the
framebuffer first instead of reusing its previous contents, which is done by @m_class{m-note m-info}
passing appropriate @ref AttachmentLoadOperation /
@ref AttachmentStoreOperation to the @ref AttachmentDescription constructor. @par
@ref AttachmentLoadOperation::Load and @ref AttachmentStoreOperation::Store are @ref ImageLayout::Undefined also doubles as a way of saying "transition
conveniently the zero values, which means you can use @cpp {} @ce instead of from whatever layout is there" --- when we render to an attachment for the
typing them out in full: first time, it will most probably be in @ref ImageLayout::Undefined, but
subsequently it won't anymore and instead be
@snippet MagnumVk.cpp RenderPass-creation-load-store @ref ImageLayout::ColorAttachment,
@ref ImageLayout::DepthStencilAttachment "DepthStencilAttachment" or just
Vulkan makes heavy use of image layouts for optimal memory access any other. With @ref ImageLayout::Undefined we don't need to explicitly
and in all the cases above, @ref ImageLayout::General is used as an implicit handle that case.
conservative layout. It's guaranteed to work for all device access, but it
might not always be optimal. A complete description of image layouts and their
use is out of scope of this reference, but for example, if the attached images
would be always only used as a render target, the above setup could be made
more optimal by explicitly specifying both a concrete initial and final layout
in the @ref AttachmentDescription constructors and in
each @link AttachmentReference @endlink:
@snippet MagnumVk.cpp RenderPass-creation-layout
*/ */
class MAGNUM_VK_EXPORT RenderPass { class MAGNUM_VK_EXPORT RenderPass {
public: public:

92
src/Magnum/Vk/RenderPassCreateInfo.h

@ -52,14 +52,7 @@ subpass.
@m_enum_values_as_keywords @m_enum_values_as_keywords
*/ */
enum class AttachmentLoadOperation: Int { enum class AttachmentLoadOperation: Int {
/** /** Previous contents are preserved. */
* Previous contents are preserved. This is the conservative default when
* using the @ref AttachmentDescription::AttachmentDescription(PixelFormat, Int, Flags)
* constructor.
*
* This value is also guaranteed to be @cpp 0 @ce, which means you're
* encouraged to simply use @cpp {} @ce in function calls and elsewhere.
*/
Load = VK_ATTACHMENT_LOAD_OP_LOAD, Load = VK_ATTACHMENT_LOAD_OP_LOAD,
/** /**
@ -103,14 +96,7 @@ treated at the end of a subpass.
@m_enum_values_as_keywords @m_enum_values_as_keywords
*/ */
enum class AttachmentStoreOperation: Int { enum class AttachmentStoreOperation: Int {
/** /** Generated contents are written to memory. */
* Generated contents are written to memory. This is the conservative
* default when using the @ref AttachmentDescription::AttachmentDescription(PixelFormat, Int, Flags)
* constructor.
*
* This value is also guaranteed to be @cpp 0 @ce, which means you're
* encouraged to simply use @cpp {} @ce in function calls and elsewhere.
*/
Store = VK_ATTACHMENT_STORE_OP_STORE, Store = VK_ATTACHMENT_STORE_OP_STORE,
/** /**
@ -215,24 +201,13 @@ class MAGNUM_VK_EXPORT AttachmentDescription {
* See also @ref AttachmentDescription(PixelFormat, std::pair<AttachmentLoadOperation, AttachmentLoadOperation>, std::pair<AttachmentStoreOperation, AttachmentStoreOperation>, ImageLayout, ImageLayout, Int, Flags) * See also @ref AttachmentDescription(PixelFormat, std::pair<AttachmentLoadOperation, AttachmentLoadOperation>, std::pair<AttachmentStoreOperation, AttachmentStoreOperation>, ImageLayout, ImageLayout, Int, Flags)
* for a constructing a combined depth/stencil attachment description. * for a constructing a combined depth/stencil attachment description.
*/ */
/*implicit*/ AttachmentDescription(PixelFormat format, AttachmentLoadOperation loadOperation, AttachmentStoreOperation storeOperation, ImageLayout initialLayout, ImageLayout finalLayout, Int samples = 1, Flags flags = {}); /* These were implicit at first, but I realized code gets way too
confusing with all the {{}} so it's not anymore */
explicit AttachmentDescription(PixelFormat format, AttachmentLoadOperation loadOperation, AttachmentStoreOperation storeOperation, ImageLayout initialLayout, ImageLayout finalLayout, Int samples = 1, Flags flags = {});
/** @overload */ /** @overload */
/*implicit*/ AttachmentDescription(Magnum::PixelFormat format, AttachmentLoadOperation loadOperation, AttachmentStoreOperation storeOperation, ImageLayout initialLayout, ImageLayout finalLayout, Int samples = 1, Flags flags = {}); explicit AttachmentDescription(Magnum::PixelFormat format, AttachmentLoadOperation loadOperation, AttachmentStoreOperation storeOperation, ImageLayout initialLayout, ImageLayout finalLayout, Int samples = 1, Flags flags = {});
/** @overload */ /** @overload */
/*implicit*/ AttachmentDescription(Magnum::CompressedPixelFormat format, AttachmentLoadOperation loadOperation, AttachmentStoreOperation storeOperation, ImageLayout initialLayout, ImageLayout finalLayout, Int samples = 1, Flags flags = {}); explicit AttachmentDescription(Magnum::CompressedPixelFormat format, AttachmentLoadOperation loadOperation, AttachmentStoreOperation storeOperation, ImageLayout initialLayout, ImageLayout finalLayout, Int samples = 1, Flags flags = {});
/**
* @brief Construct with implicit conservative layout
*
* Equivalent to calling @ref AttachmentDescription(PixelFormat, AttachmentLoadOperation, AttachmentStoreOperation, ImageLayout, ImageLayout, Int, Flags)
* with both @p initialLayout and @p finalLayout set to
* @ref ImageLayout::General.
*/
/*implicit*/ AttachmentDescription(PixelFormat format, AttachmentLoadOperation loadOperation, AttachmentStoreOperation storeOperation, Int samples = 1, Flags flags = {});
/** @overload */
/*implicit*/ AttachmentDescription(Magnum::PixelFormat format, AttachmentLoadOperation loadOperation, AttachmentStoreOperation storeOperation, Int samples = 1, Flags flags = {});
/** @overload */
/*implicit*/ AttachmentDescription(Magnum::CompressedPixelFormat format, AttachmentLoadOperation loadOperation, AttachmentStoreOperation storeOperation, Int samples = 1, Flags flags = {});
/** /**
* @brief Construct for a combined depth/stencil attachment * @brief Construct for a combined depth/stencil attachment
@ -254,8 +229,10 @@ class MAGNUM_VK_EXPORT AttachmentDescription {
* @param samples Sample count * @param samples Sample count
* @param flags Attachment description flags * @param flags Attachment description flags
* *
* The following @type_vk{AttachmentDescription} fields are pre-filled * Compared to @ref AttachmentDescription(PixelFormat, AttachmentLoadOperation, AttachmentStoreOperation, ImageLayout, ImageLayout, Int, Flags)
* in addition to `sType`, everything else is zero-filled: * allows you to specify different load/store operation for depth and
* stencil. The following @type_vk{AttachmentDescription2} fields are
* pre-filled in addition to `sType`, everything else is zero-filled:
* *
* - `flags` * - `flags`
* - `format` * - `format`
@ -268,38 +245,13 @@ class MAGNUM_VK_EXPORT AttachmentDescription {
* @todo Implement @vk_extension{KHR,separate_depth_stencil_layouts} * @todo Implement @vk_extension{KHR,separate_depth_stencil_layouts}
* and provide a pair of layouts as well * and provide a pair of layouts as well
*/ */
/*implicit*/ AttachmentDescription(PixelFormat format, std::pair<AttachmentLoadOperation, AttachmentLoadOperation> depthStencilLoadOperation, std::pair<AttachmentStoreOperation, AttachmentStoreOperation> depthStencilStoreOperation, ImageLayout initialLayout, ImageLayout finalLayout, Int samples = 1, Flags flags = {}); /* These were implicit at first, but I realized code gets way too
/** @overload */ confusing with all the {{}} so it's not anymore */
/*implicit*/ AttachmentDescription(Magnum::PixelFormat format, std::pair<AttachmentLoadOperation, AttachmentLoadOperation> depthStencilLoadOperation, std::pair<AttachmentStoreOperation, AttachmentStoreOperation> depthStencilStoreOperation, ImageLayout initialLayout, ImageLayout finalLayout, Int samples = 1, Flags flags = {}); explicit AttachmentDescription(PixelFormat format, std::pair<AttachmentLoadOperation, AttachmentLoadOperation> depthStencilLoadOperation, std::pair<AttachmentStoreOperation, AttachmentStoreOperation> depthStencilStoreOperation, ImageLayout initialLayout, ImageLayout finalLayout, Int samples = 1, Flags flags = {});
/** @overload */
/*implicit*/ AttachmentDescription(Magnum::CompressedPixelFormat format, std::pair<AttachmentLoadOperation, AttachmentLoadOperation> depthStencilLoadOperation, std::pair<AttachmentStoreOperation, AttachmentStoreOperation> depthStencilStoreOperation, ImageLayout initialLayout, ImageLayout finalLayout, Int samples = 1, Flags flags = {});
/**
* @brief Construct for a combined depth/stencil attachment with implicit conservative layout
*
* Equivalent to calling @ref AttachmentDescription(PixelFormat, std::pair<AttachmentLoadOperation, AttachmentLoadOperation>, std::pair<AttachmentStoreOperation, AttachmentStoreOperation>, ImageLayout, ImageLayout, Int, Flags)
* with both @p initialLayout and @p finalLayout set to
* @ref ImageLayout::General.
*/
/*implicit*/ AttachmentDescription(PixelFormat format, std::pair<AttachmentLoadOperation, AttachmentLoadOperation> depthStencilLoadOperation, std::pair<AttachmentStoreOperation, AttachmentStoreOperation> depthStencilStoreOperation, Int samples = 1, Flags flags = {});
/** @overload */
/*implicit*/ AttachmentDescription(Magnum::PixelFormat format, std::pair<AttachmentLoadOperation, AttachmentLoadOperation> depthStencilLoadOperation, std::pair<AttachmentStoreOperation, AttachmentStoreOperation> depthStencilStoreOperation, Int samples = 1, Flags flags = {});
/** @overload */
/*implicit*/ AttachmentDescription(Magnum::CompressedPixelFormat format, std::pair<AttachmentLoadOperation, AttachmentLoadOperation> depthStencilLoadOperation, std::pair<AttachmentStoreOperation, AttachmentStoreOperation> depthStencilStoreOperation, Int samples = 1, Flags flags = {});
/**
* @brief Construct with implicit conservative load/store operation and layout
*
* Equivalent to calling @ref AttachmentDescription(PixelFormat, std::pair<AttachmentLoadOperation, AttachmentLoadOperation>, std::pair<AttachmentStoreOperation, AttachmentStoreOperation>, ImageLayout, ImageLayout, Int, Flags)
* with @ref AttachmentLoadOperation::Load and
* @ref AttachmentStoreOperation::Store and both @p initialLayout and
* @p finalLayout set to @ref ImageLayout::General.
*/
/*implicit*/ AttachmentDescription(PixelFormat format, Int samples = 1, Flags flags = {}): AttachmentDescription{format, AttachmentLoadOperation{}, AttachmentStoreOperation{}, samples, flags} {}
/** @overload */ /** @overload */
/*implicit*/ AttachmentDescription(Magnum::PixelFormat format, Int samples = 1, Flags flags = {}): AttachmentDescription{format, AttachmentLoadOperation{}, AttachmentStoreOperation{}, samples, flags} {} explicit AttachmentDescription(Magnum::PixelFormat format, std::pair<AttachmentLoadOperation, AttachmentLoadOperation> depthStencilLoadOperation, std::pair<AttachmentStoreOperation, AttachmentStoreOperation> depthStencilStoreOperation, ImageLayout initialLayout, ImageLayout finalLayout, Int samples = 1, Flags flags = {});
/** @overload */ /** @overload */
/*implicit*/ AttachmentDescription(Magnum::CompressedPixelFormat format, Int samples = 1, Flags flags = {}): AttachmentDescription{format, AttachmentLoadOperation{}, AttachmentStoreOperation{}, samples, flags} {} explicit AttachmentDescription(Magnum::CompressedPixelFormat format, std::pair<AttachmentLoadOperation, AttachmentLoadOperation> depthStencilLoadOperation, std::pair<AttachmentStoreOperation, AttachmentStoreOperation> depthStencilStoreOperation, ImageLayout initialLayout, ImageLayout finalLayout, Int samples = 1, Flags flags = {});
/** /**
* @brief Construct without initializing the contents * @brief Construct without initializing the contents
@ -412,14 +364,10 @@ class MAGNUM_VK_EXPORT AttachmentReference {
* - `attachment` * - `attachment`
* - `layout` * - `layout`
*/ */
/*implicit*/ AttachmentReference(UnsignedInt attachment, ImageLayout layout = /* This was implicit at first, but I realized code gets way too
#ifdef DOXYGEN_GENERATING_OUTPUT confusing with all the {{}} especially with setColorAttachments()
/* To avoid Image.h dependency */ that takes two lists so it's not anymore */
ImageLayout::General explicit AttachmentReference(UnsignedInt attachment, ImageLayout layout);
#else
ImageLayout(VK_IMAGE_LAYOUT_GENERAL)
#endif
);
/** /**
* @brief Construct with no attachment * @brief Construct with no attachment

44
src/Magnum/Vk/Test/FramebufferVkTest.cpp

@ -63,12 +63,24 @@ void FramebufferVkTest::construct() {
RenderPass renderPass{device(), RenderPassCreateInfo{} RenderPass renderPass{device(), RenderPassCreateInfo{}
.setAttachments({ .setAttachments({
color.format(), AttachmentDescription{color.format(),
depth.format() AttachmentLoadOperation::Clear,
AttachmentStoreOperation::Store,
ImageLayout::Undefined,
ImageLayout::ColorAttachment},
AttachmentDescription{depth.format(),
AttachmentLoadOperation::Clear,
AttachmentStoreOperation::Store,
ImageLayout::Undefined,
ImageLayout::DepthStencilAttachment}
}) })
.addSubpass(SubpassDescription{} .addSubpass(SubpassDescription{}
.setColorAttachments({0}) .setColorAttachments({
.setDepthStencilAttachment(1) AttachmentReference{0, ImageLayout::ColorAttachment}
})
.setDepthStencilAttachment(
AttachmentReference{1, ImageLayout::DepthStencilAttachment}
)
) )
}; };
@ -91,8 +103,16 @@ void FramebufferVkTest::constructMove() {
PixelFormat::RGBA8Unorm, {256, 256}, 1}, MemoryFlag::DeviceLocal}; PixelFormat::RGBA8Unorm, {256, 256}, 1}, MemoryFlag::DeviceLocal};
ImageView colorView{device(), ImageViewCreateInfo2D{color}}; ImageView colorView{device(), ImageViewCreateInfo2D{color}};
RenderPass renderPass{device(), RenderPassCreateInfo{} RenderPass renderPass{device(), RenderPassCreateInfo{}
.setAttachments({color.format()}) .setAttachments({
.addSubpass(SubpassDescription{}.setColorAttachments({0})) AttachmentDescription{color.format(),
AttachmentLoadOperation::Clear,
AttachmentStoreOperation::Store,
ImageLayout::Undefined,
ImageLayout::ColorAttachment}
})
.addSubpass(SubpassDescription{}.setColorAttachments({
AttachmentReference{0, ImageLayout::ColorAttachment}
}))
}; };
Framebuffer a{device(), FramebufferCreateInfo{renderPass, { Framebuffer a{device(), FramebufferCreateInfo{renderPass, {
@ -123,8 +143,16 @@ void FramebufferVkTest::wrap() {
PixelFormat::RGBA8Unorm, {256, 256}, 1}, MemoryFlag::DeviceLocal}; PixelFormat::RGBA8Unorm, {256, 256}, 1}, MemoryFlag::DeviceLocal};
ImageView colorView{device(), ImageViewCreateInfo2D{color}}; ImageView colorView{device(), ImageViewCreateInfo2D{color}};
RenderPass renderPass{device(), RenderPassCreateInfo{} RenderPass renderPass{device(), RenderPassCreateInfo{}
.setAttachments({color.format()}) .setAttachments({
.addSubpass(SubpassDescription{}.setColorAttachments({0})) AttachmentDescription{color.format(),
AttachmentLoadOperation::Load,
AttachmentStoreOperation::Store,
ImageLayout::Undefined,
ImageLayout::ColorAttachment}
})
.addSubpass(SubpassDescription{}.setColorAttachments({
AttachmentReference{0, ImageLayout::ColorAttachment}
}))
}; };
VkFramebuffer framebuffer{}; VkFramebuffer framebuffer{};

169
src/Magnum/Vk/Test/RenderPassTest.cpp

@ -52,10 +52,7 @@ struct RenderPassTest: TestSuite::Tester {
structures. */ structures. */
template<class T> void attachmentDescriptionConstruct(); template<class T> void attachmentDescriptionConstruct();
template<class T> void attachmentDescriptionConstructImplicitLayout();
template<class T> void attachmentDescriptionConstructDepthStencil(); template<class T> void attachmentDescriptionConstructDepthStencil();
template<class T> void attachmentDescriptionConstructDepthStencilImplicitLayout();
template<class T> void attachmentDescriptionConstructImplicitLoadStoreLayout();
void attachmentDescriptionConstructNoInit(); void attachmentDescriptionConstructNoInit();
template<class From, class To> void attachmentDescriptionConstructFromVk(); template<class From, class To> void attachmentDescriptionConstructFromVk();
template<class T> void attachmentDescriptionConvertToVk(); template<class T> void attachmentDescriptionConvertToVk();
@ -122,18 +119,9 @@ RenderPassTest::RenderPassTest() {
addTests({&RenderPassTest::attachmentDescriptionConstruct<PixelFormat>, addTests({&RenderPassTest::attachmentDescriptionConstruct<PixelFormat>,
&RenderPassTest::attachmentDescriptionConstruct<Magnum::PixelFormat>, &RenderPassTest::attachmentDescriptionConstruct<Magnum::PixelFormat>,
&RenderPassTest::attachmentDescriptionConstruct<Magnum::CompressedPixelFormat>, &RenderPassTest::attachmentDescriptionConstruct<Magnum::CompressedPixelFormat>,
&RenderPassTest::attachmentDescriptionConstructImplicitLayout<PixelFormat>,
&RenderPassTest::attachmentDescriptionConstructImplicitLayout<Magnum::PixelFormat>,
&RenderPassTest::attachmentDescriptionConstructImplicitLayout<Magnum::CompressedPixelFormat>,
&RenderPassTest::attachmentDescriptionConstructDepthStencil<PixelFormat>, &RenderPassTest::attachmentDescriptionConstructDepthStencil<PixelFormat>,
&RenderPassTest::attachmentDescriptionConstructDepthStencil<Magnum::PixelFormat>, &RenderPassTest::attachmentDescriptionConstructDepthStencil<Magnum::PixelFormat>,
&RenderPassTest::attachmentDescriptionConstructDepthStencil<Magnum::CompressedPixelFormat>, &RenderPassTest::attachmentDescriptionConstructDepthStencil<Magnum::CompressedPixelFormat>,
&RenderPassTest::attachmentDescriptionConstructDepthStencilImplicitLayout<PixelFormat>,
&RenderPassTest::attachmentDescriptionConstructDepthStencilImplicitLayout<Magnum::PixelFormat>,
&RenderPassTest::attachmentDescriptionConstructDepthStencilImplicitLayout<Magnum::CompressedPixelFormat>,
&RenderPassTest::attachmentDescriptionConstructImplicitLoadStoreLayout<PixelFormat>,
&RenderPassTest::attachmentDescriptionConstructImplicitLoadStoreLayout<Magnum::PixelFormat>,
&RenderPassTest::attachmentDescriptionConstructImplicitLoadStoreLayout<Magnum::CompressedPixelFormat>,
&RenderPassTest::attachmentDescriptionConstructNoInit, &RenderPassTest::attachmentDescriptionConstructNoInit,
&RenderPassTest::attachmentDescriptionConstructFromVk<VkAttachmentDescription2, VkAttachmentDescription2>, &RenderPassTest::attachmentDescriptionConstructFromVk<VkAttachmentDescription2, VkAttachmentDescription2>,
&RenderPassTest::attachmentDescriptionConstructFromVk<VkAttachmentDescription, VkAttachmentDescription2>, &RenderPassTest::attachmentDescriptionConstructFromVk<VkAttachmentDescription, VkAttachmentDescription2>,
@ -272,23 +260,6 @@ template<class T> void RenderPassTest::attachmentDescriptionConstruct() {
CORRADE_COMPARE(description->finalLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); CORRADE_COMPARE(description->finalLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
} }
template<class T> void RenderPassTest::attachmentDescriptionConstructImplicitLayout() {
setTestCaseTemplateName(PixelFormatTraits<T>::name());
AttachmentDescription description{PixelFormatTraits<T>::format(),
AttachmentLoadOperation::Clear, AttachmentStoreOperation::DontCare,
4, AttachmentDescription::Flag::MayAlias};
CORRADE_COMPARE(description->flags, VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT);
CORRADE_COMPARE(description->format, PixelFormatTraits<T>::expected());
CORRADE_COMPARE(description->samples, VK_SAMPLE_COUNT_4_BIT);
CORRADE_COMPARE(description->loadOp, VK_ATTACHMENT_LOAD_OP_CLEAR);
CORRADE_COMPARE(description->stencilLoadOp, VK_ATTACHMENT_LOAD_OP_LOAD);
CORRADE_COMPARE(description->storeOp, VK_ATTACHMENT_STORE_OP_DONT_CARE);
CORRADE_COMPARE(description->stencilStoreOp, VK_ATTACHMENT_STORE_OP_STORE);
CORRADE_COMPARE(description->initialLayout, VK_IMAGE_LAYOUT_GENERAL);
CORRADE_COMPARE(description->finalLayout, VK_IMAGE_LAYOUT_GENERAL);
}
template<class T> void RenderPassTest::attachmentDescriptionConstructDepthStencil() { template<class T> void RenderPassTest::attachmentDescriptionConstructDepthStencil() {
setTestCaseTemplateName(PixelFormatTraits<T>::name()); setTestCaseTemplateName(PixelFormatTraits<T>::name());
@ -308,40 +279,6 @@ template<class T> void RenderPassTest::attachmentDescriptionConstructDepthStenci
CORRADE_COMPARE(description->finalLayout, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); CORRADE_COMPARE(description->finalLayout, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
} }
template<class T> void RenderPassTest::attachmentDescriptionConstructDepthStencilImplicitLayout() {
setTestCaseTemplateName(PixelFormatTraits<T>::name());
AttachmentDescription description{PixelFormatTraits<T>::format(),
{AttachmentLoadOperation::Clear, AttachmentLoadOperation::DontCare},
{AttachmentStoreOperation::Store, AttachmentStoreOperation::DontCare},
4, AttachmentDescription::Flag::MayAlias};
CORRADE_COMPARE(description->flags, VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT);
CORRADE_COMPARE(description->format, PixelFormatTraits<T>::expected());
CORRADE_COMPARE(description->samples, VK_SAMPLE_COUNT_4_BIT);
CORRADE_COMPARE(description->loadOp, VK_ATTACHMENT_LOAD_OP_CLEAR);
CORRADE_COMPARE(description->stencilLoadOp, VK_ATTACHMENT_LOAD_OP_DONT_CARE);
CORRADE_COMPARE(description->storeOp, VK_ATTACHMENT_STORE_OP_STORE);
CORRADE_COMPARE(description->stencilStoreOp, VK_ATTACHMENT_STORE_OP_DONT_CARE);
CORRADE_COMPARE(description->initialLayout, VK_IMAGE_LAYOUT_GENERAL);
CORRADE_COMPARE(description->finalLayout, VK_IMAGE_LAYOUT_GENERAL);
}
template<class T> void RenderPassTest::attachmentDescriptionConstructImplicitLoadStoreLayout() {
setTestCaseTemplateName(PixelFormatTraits<T>::name());
AttachmentDescription description{PixelFormatTraits<T>::format(),
4, AttachmentDescription::Flag::MayAlias};
CORRADE_COMPARE(description->flags, VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT);
CORRADE_COMPARE(description->format, PixelFormatTraits<T>::expected());
CORRADE_COMPARE(description->samples, VK_SAMPLE_COUNT_4_BIT);
CORRADE_COMPARE(description->loadOp, VK_ATTACHMENT_LOAD_OP_LOAD);
CORRADE_COMPARE(description->stencilLoadOp, VK_ATTACHMENT_LOAD_OP_LOAD);
CORRADE_COMPARE(description->storeOp, VK_ATTACHMENT_STORE_OP_STORE);
CORRADE_COMPARE(description->stencilStoreOp, VK_ATTACHMENT_STORE_OP_STORE);
CORRADE_COMPARE(description->initialLayout, VK_IMAGE_LAYOUT_GENERAL);
CORRADE_COMPARE(description->finalLayout, VK_IMAGE_LAYOUT_GENERAL);
}
void RenderPassTest::attachmentDescriptionConstructNoInit() { void RenderPassTest::attachmentDescriptionConstructNoInit() {
AttachmentDescription description{NoInit}; AttachmentDescription description{NoInit};
description->sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; description->sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
@ -475,17 +412,25 @@ void RenderPassTest::subpassDescriptionConstructNoInit() {
void RenderPassTest::subpassDescriptionConstructInputAttachments() { void RenderPassTest::subpassDescriptionConstructInputAttachments() {
SubpassDescription description; SubpassDescription description;
description.setInputAttachments({15, {}, 2}); description.setInputAttachments({
AttachmentReference{15, ImageLayout::ShaderReadOnly},
{},
AttachmentReference{2, ImageLayout::ShaderReadOnly}
});
CORRADE_COMPARE(description->inputAttachmentCount, 3); CORRADE_COMPARE(description->inputAttachmentCount, 3);
CORRADE_VERIFY(description->pInputAttachments); CORRADE_VERIFY(description->pInputAttachments);
CORRADE_COMPARE(description->pInputAttachments[0].attachment, 15); CORRADE_COMPARE(description->pInputAttachments[0].attachment, 15);
CORRADE_COMPARE(description->pInputAttachments[0].layout, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
CORRADE_COMPARE(description->pInputAttachments[1].attachment, VK_ATTACHMENT_UNUSED); CORRADE_COMPARE(description->pInputAttachments[1].attachment, VK_ATTACHMENT_UNUSED);
CORRADE_COMPARE(description->pInputAttachments[2].attachment, 2); CORRADE_COMPARE(description->pInputAttachments[2].attachment, 2);
} }
void RenderPassTest::subpassDescriptionConstructColorAttachments() { void RenderPassTest::subpassDescriptionConstructColorAttachments() {
SubpassDescription description; SubpassDescription description;
description.setColorAttachments({{}, 23}); description.setColorAttachments({
{},
AttachmentReference{23, ImageLayout::ColorAttachment}
});
CORRADE_COMPARE(description->colorAttachmentCount, 2); CORRADE_COMPARE(description->colorAttachmentCount, 2);
CORRADE_VERIFY(description->pColorAttachments); CORRADE_VERIFY(description->pColorAttachments);
CORRADE_VERIFY(!description->pResolveAttachments); CORRADE_VERIFY(!description->pResolveAttachments);
@ -495,7 +440,13 @@ void RenderPassTest::subpassDescriptionConstructColorAttachments() {
void RenderPassTest::subpassDescriptionConstructColorResolveAttachments() { void RenderPassTest::subpassDescriptionConstructColorResolveAttachments() {
SubpassDescription description; SubpassDescription description;
description.setColorAttachments({{}, 23}, {1, 0}); description.setColorAttachments({
{},
AttachmentReference{23, ImageLayout::ColorAttachment}
}, {
AttachmentReference{1, ImageLayout::ColorAttachment},
AttachmentReference{0, ImageLayout::ColorAttachment}
});
CORRADE_COMPARE(description->colorAttachmentCount, 2); CORRADE_COMPARE(description->colorAttachmentCount, 2);
CORRADE_VERIFY(description->pColorAttachments); CORRADE_VERIFY(description->pColorAttachments);
@ -515,14 +466,16 @@ void RenderPassTest::subpassDescriptionConstructColorResolveAttachmentsWrongCoun
std::ostringstream out; std::ostringstream out;
Error redirectError{&out}; Error redirectError{&out};
description.setColorAttachments({0, 1}, {2, 3, 5}); description.setColorAttachments({{}, {}}, {{}, {}, {}});
CORRADE_COMPARE(out.str(), CORRADE_COMPARE(out.str(),
"Vk::SubpassDescription::setColorAttachments(): resolve attachments expected to be either empty or have a size of 2 but got 3\n"); "Vk::SubpassDescription::setColorAttachments(): resolve attachments expected to be either empty or have a size of 2 but got 3\n");
} }
void RenderPassTest::subpassDescriptionConstructDepthStencilAttachment() { void RenderPassTest::subpassDescriptionConstructDepthStencilAttachment() {
SubpassDescription description; SubpassDescription description;
description.setDepthStencilAttachment(11); description.setDepthStencilAttachment(
AttachmentReference{11, ImageLayout::DepthStencilAttachment}
);
CORRADE_VERIFY(description->pDepthStencilAttachment); CORRADE_VERIFY(description->pDepthStencilAttachment);
CORRADE_COMPARE(description->pDepthStencilAttachment->attachment, 11); CORRADE_COMPARE(description->pDepthStencilAttachment->attachment, 11);
} }
@ -633,7 +586,10 @@ void RenderPassTest::subpassDescriptionConstructCopy() {
void RenderPassTest::subpassDescriptionConstructMove() { void RenderPassTest::subpassDescriptionConstructMove() {
SubpassDescription a; SubpassDescription a;
a.setInputAttachments({24, 35}); a.setInputAttachments({
AttachmentReference{24, ImageLayout::ShaderReadOnly},
AttachmentReference{35, ImageLayout::ShaderReadOnly}
});
CORRADE_COMPARE(a->inputAttachmentCount, 2); CORRADE_COMPARE(a->inputAttachmentCount, 2);
CORRADE_COMPARE(a->pInputAttachments[1].attachment, 35); CORRADE_COMPARE(a->pInputAttachments[1].attachment, 35);
@ -659,10 +615,20 @@ template<class T> void RenderPassTest::subpassDescriptionConvertToVk() {
SubpassDescription description{}; SubpassDescription description{};
description.setInputAttachments({ description.setInputAttachments({
24, {35, ImageLayout::ShaderReadOnly}, 17 AttachmentReference{24, ImageLayout::ShaderReadOnly},
AttachmentReference{35, ImageLayout::ShaderReadOnly},
AttachmentReference{17, ImageLayout::ShaderReadOnly},
})
.setColorAttachments({
AttachmentReference{1, ImageLayout::ColorAttachment},
AttachmentReference{3, ImageLayout::ColorAttachment},
}, {
AttachmentReference{25, ImageLayout::ColorAttachment},
AttachmentReference{12, ImageLayout::ColorAttachment}
}) })
.setColorAttachments({1, 3}, {{25, ImageLayout::ColorAttachment}, 12}) .setDepthStencilAttachment(
.setDepthStencilAttachment({5, ImageLayout::DepthStencilAttachment}) AttachmentReference{5, ImageLayout::DepthStencilAttachment}
)
.setPreserveAttachments({0, 15, 23, 17}); .setPreserveAttachments({0, 15, 23, 17});
Containers::Array<T> array = Traits<T>::convert(description); Containers::Array<T> array = Traits<T>::convert(description);
@ -720,7 +686,10 @@ template<class T> void RenderPassTest::subpassDescriptionConvertToVkNoResolveAtt
setTestCaseTemplateName(Traits<T>::name()); setTestCaseTemplateName(Traits<T>::name());
SubpassDescription description{}; SubpassDescription description{};
description.setColorAttachments({1, 3}); description.setColorAttachments({
AttachmentReference{1, ImageLayout::ColorAttachment},
AttachmentReference{3, ImageLayout::ColorAttachment}
});
Containers::Array<T> array = Traits<T>::convert(description); Containers::Array<T> array = Traits<T>::convert(description);
const T& to = array[0]; const T& to = array[0];
@ -818,14 +787,23 @@ void RenderPassTest::createInfoConstructNoInit() {
void RenderPassTest::createInfoConstructAttachments() { void RenderPassTest::createInfoConstructAttachments() {
RenderPassCreateInfo info; RenderPassCreateInfo info;
info.setAttachments({ info.setAttachments({
{PixelFormat::RGBA16F, AttachmentLoadOperation::Clear, AttachmentStoreOperation::DontCare}, AttachmentDescription{PixelFormat::RGBA16F,
{PixelFormat::RGB8Snorm, 4} AttachmentLoadOperation::Clear,
AttachmentStoreOperation::Store,
ImageLayout::Undefined,
ImageLayout::ColorAttachment},
AttachmentDescription{PixelFormat::RGB8Snorm,
AttachmentLoadOperation::Clear,
AttachmentStoreOperation::Store,
ImageLayout::Undefined,
ImageLayout::General,
4}
}); });
CORRADE_COMPARE(info->attachmentCount, 2); CORRADE_COMPARE(info->attachmentCount, 2);
CORRADE_VERIFY(info->pAttachments); CORRADE_VERIFY(info->pAttachments);
CORRADE_COMPARE(info->pAttachments[0].format, VK_FORMAT_R16G16B16A16_SFLOAT); CORRADE_COMPARE(info->pAttachments[0].format, VK_FORMAT_R16G16B16A16_SFLOAT);
CORRADE_COMPARE(info->pAttachments[0].loadOp, VK_ATTACHMENT_LOAD_OP_CLEAR); CORRADE_COMPARE(info->pAttachments[0].initialLayout, VK_IMAGE_LAYOUT_UNDEFINED);
CORRADE_COMPARE(info->pAttachments[0].storeOp, VK_ATTACHMENT_STORE_OP_DONT_CARE); CORRADE_COMPARE(info->pAttachments[0].finalLayout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
CORRADE_COMPARE(info->pAttachments[1].format, VK_FORMAT_R8G8B8_SNORM); CORRADE_COMPARE(info->pAttachments[1].format, VK_FORMAT_R8G8B8_SNORM);
CORRADE_COMPARE(info->pAttachments[1].samples, VK_SAMPLE_COUNT_4_BIT); CORRADE_COMPARE(info->pAttachments[1].samples, VK_SAMPLE_COUNT_4_BIT);
} }
@ -833,12 +811,19 @@ void RenderPassTest::createInfoConstructAttachments() {
void RenderPassTest::createInfoConstructSubpasses() { void RenderPassTest::createInfoConstructSubpasses() {
RenderPassCreateInfo info; RenderPassCreateInfo info;
info.addSubpass(SubpassDescription{} info.addSubpass(SubpassDescription{}
.setColorAttachments({15, 34, 1}) .setColorAttachments({
AttachmentReference{15, ImageLayout::ColorAttachment},
AttachmentReference{34, ImageLayout::ColorAttachment},
AttachmentReference{1, ImageLayout::ColorAttachment}
})
.setPreserveAttachments({22}) .setPreserveAttachments({22})
); );
info.addSubpass(SubpassDescription{} info.addSubpass(SubpassDescription{}
.setInputAttachments({17, {}}) .setInputAttachments({
.setDepthStencilAttachment(1) AttachmentReference{17, ImageLayout::ShaderReadOnly},
{}
})
.setDepthStencilAttachment(AttachmentReference{1, ImageLayout::DepthStencilAttachment})
); );
CORRADE_COMPARE(info->subpassCount, 2); CORRADE_COMPARE(info->subpassCount, 2);
CORRADE_VERIFY(info->pSubpasses); CORRADE_VERIFY(info->pSubpasses);
@ -953,7 +938,14 @@ void RenderPassTest::createInfoConstructCopy() {
void RenderPassTest::createInfoConstructMove() { void RenderPassTest::createInfoConstructMove() {
RenderPassCreateInfo a; RenderPassCreateInfo a;
a.setAttachments({PixelFormat::Depth32F, PixelFormat::RGB8Snorm}); a.setAttachments({
AttachmentDescription{PixelFormat::Depth32F,
{}, {},
{}, {}},
AttachmentDescription{PixelFormat::RGB8Snorm,
{}, {},
{}, {}}
});
CORRADE_COMPARE(a->attachmentCount, 2); CORRADE_COMPARE(a->attachmentCount, 2);
CORRADE_COMPARE(a->pAttachments[1].format, VK_FORMAT_R8G8B8_SNORM); CORRADE_COMPARE(a->pAttachments[1].format, VK_FORMAT_R8G8B8_SNORM);
@ -980,11 +972,18 @@ template<class T> void RenderPassTest::createInfoConvertToVk() {
RenderPassCreateInfo info; RenderPassCreateInfo info;
info.setAttachments({ info.setAttachments({
AttachmentDescription{PixelFormat::RGB16UI}, AttachmentDescription{PixelFormat::RGB16UI,
AttachmentDescription{PixelFormat{}, {}, {AttachmentStoreOperation::Store, AttachmentStoreOperation::DontCare}} AttachmentLoadOperation{}, AttachmentStoreOperation{},
ImageLayout{}, ImageLayout{}},
AttachmentDescription{PixelFormat{}, {}, {AttachmentStoreOperation::Store, AttachmentStoreOperation::DontCare}, ImageLayout{}, ImageLayout{}}
}) })
.addSubpass(SubpassDescription{}.setColorAttachments({1, {15, ImageLayout::ShaderReadOnly}})) .addSubpass(SubpassDescription{}.setColorAttachments({
.addSubpass(SubpassDescription{}.setDepthStencilAttachment({15, ImageLayout::ShaderReadOnly})) AttachmentReference{1, ImageLayout{}},
AttachmentReference{15, ImageLayout::ShaderReadOnly}
}))
.addSubpass(SubpassDescription{}.setDepthStencilAttachment(
AttachmentReference{15, ImageLayout::ShaderReadOnly}
))
.addSubpass(SubpassDescription{}.setPreserveAttachments({57})) .addSubpass(SubpassDescription{}.setPreserveAttachments({57}))
.setDependencies({SubpassDependency{dependency}}); .setDependencies({SubpassDependency{dependency}});
Containers::Array<T> array = Traits<T>::convert(info); Containers::Array<T> array = Traits<T>::convert(info);

54
src/Magnum/Vk/Test/RenderPassVkTest.cpp

@ -70,8 +70,16 @@ RenderPassVkTest::RenderPassVkTest() {
void RenderPassVkTest::construct() { void RenderPassVkTest::construct() {
{ {
RenderPass renderPass{device(), RenderPassCreateInfo{} RenderPass renderPass{device(), RenderPassCreateInfo{}
.setAttachments({PixelFormat::RGBA8Unorm}) .setAttachments({
.addSubpass(SubpassDescription{}.setColorAttachments({0})) AttachmentDescription{PixelFormat::RGBA8Unorm,
AttachmentLoadOperation::Clear,
AttachmentStoreOperation::Store,
ImageLayout::Undefined,
ImageLayout::General}
})
.addSubpass(SubpassDescription{}.setColorAttachments({
AttachmentReference{0, ImageLayout::General}
}))
}; };
CORRADE_VERIFY(renderPass.handle()); CORRADE_VERIFY(renderPass.handle());
CORRADE_COMPARE(renderPass.handleFlags(), HandleFlag::DestroyOnDestruction); CORRADE_COMPARE(renderPass.handleFlags(), HandleFlag::DestroyOnDestruction);
@ -103,8 +111,16 @@ void RenderPassVkTest::constructSubpassNoAttachments() {
void RenderPassVkTest::constructMove() { void RenderPassVkTest::constructMove() {
RenderPass a{device(), RenderPassCreateInfo{} RenderPass a{device(), RenderPassCreateInfo{}
.setAttachments({PixelFormat::RGBA8Unorm}) .setAttachments({
.addSubpass(SubpassDescription{}.setColorAttachments({0})) AttachmentDescription{PixelFormat::RGBA8Unorm,
AttachmentLoadOperation::Clear,
AttachmentStoreOperation::Store,
ImageLayout::Undefined,
ImageLayout::ColorAttachment}
})
.addSubpass(SubpassDescription{}.setColorAttachments({
AttachmentReference{0, ImageLayout::ColorAttachment}
}))
}; };
VkRenderPass handle = a.handle(); VkRenderPass handle = a.handle();
@ -128,8 +144,16 @@ void RenderPassVkTest::wrap() {
VkRenderPass renderPass{}; VkRenderPass renderPass{};
CORRADE_COMPARE(Result(device()->CreateRenderPass(device(), CORRADE_COMPARE(Result(device()->CreateRenderPass(device(),
RenderPassCreateInfo{} RenderPassCreateInfo{}
.setAttachments({PixelFormat::RGBA8Unorm}) .setAttachments({
.addSubpass(SubpassDescription{}.setColorAttachments({0})) AttachmentDescription{PixelFormat::RGBA8Unorm,
AttachmentLoadOperation::Clear,
AttachmentStoreOperation::Store,
ImageLayout::Undefined,
ImageLayout::ColorAttachment}
})
.addSubpass(SubpassDescription{}.setColorAttachments({
AttachmentReference{0, ImageLayout::ColorAttachment}
}))
.vkRenderPassCreateInfo(), .vkRenderPassCreateInfo(),
nullptr, &renderPass)), Result::Success); nullptr, &renderPass)), Result::Success);
@ -160,12 +184,22 @@ void RenderPassVkTest::cmdBeginEnd() {
RenderPass renderPass{device(), RenderPassCreateInfo{} RenderPass renderPass{device(), RenderPassCreateInfo{}
.setAttachments({ .setAttachments({
{color.format(), AttachmentLoadOperation::Clear, {}}, AttachmentDescription{color.format(),
{depth.format(), AttachmentLoadOperation::Clear, {}}, AttachmentLoadOperation::Clear, {},
ImageLayout::Undefined,
ImageLayout::ColorAttachment},
AttachmentDescription{depth.format(),
AttachmentLoadOperation::Clear, {},
ImageLayout::Undefined,
ImageLayout::ColorAttachment},
}) })
.addSubpass(SubpassDescription{} .addSubpass(SubpassDescription{}
.setColorAttachments({0}) .setColorAttachments({
.setDepthStencilAttachment(1) AttachmentReference{0, ImageLayout::ColorAttachment}
})
.setDepthStencilAttachment(
AttachmentReference{1, ImageLayout::DepthStencilAttachment}
)
) )
/* Further subpasses with no attachments so we can test nextSubpass() /* Further subpasses with no attachments so we can test nextSubpass()
but don't need to specify subpass dependencies (which I have no idea but don't need to specify subpass dependencies (which I have no idea

Loading…
Cancel
Save