Browse Source

Vk: save current dynamic state on a pipeline bind.

Will be used for the draw() command.
pull/495/head
Vladimír Vondruš 5 years ago
parent
commit
14389c99d5
  1. 6
      src/Magnum/Vk/CommandBuffer.cpp
  2. 19
      src/Magnum/Vk/CommandBuffer.h
  3. 4
      src/Magnum/Vk/Pipeline.cpp
  4. 65
      src/Magnum/Vk/Test/PipelineVkTest.cpp

6
src/Magnum/Vk/CommandBuffer.cpp

@ -84,6 +84,12 @@ CommandBuffer& CommandBuffer::begin(const CommandBufferBeginInfo& info) {
}
void CommandBuffer::end() {
/* Clear everything that is valid only for the duration of this command
buffer recording -- so when the user calls reset() and begin() again,
the old values are not preserved */
/** @todo do this on begin() too? */
_dynamicRasterizationStates = {};
MAGNUM_VK_INTERNAL_ASSERT_SUCCESS((**_device).EndCommandBuffer(_handle));
}

19
src/Magnum/Vk/CommandBuffer.h

@ -31,6 +31,7 @@
*/
#include <initializer_list>
#include <Corrade/Containers/BigEnumSet.h>
#include <Corrade/Containers/EnumSet.h>
#include "Magnum/Tags.h"
@ -259,6 +260,17 @@ class MAGNUM_VK_EXPORT CommandBuffer {
/** @brief Handle flags */
HandleFlags handleFlags() const { return _flags; }
/**
* @brief Dynamic states used by currently bound rasterization pipeline
*
* If no rasterization pipeline is bound or there are no dynamic states
* on the currently bound one, returns an empty set.
* @see @ref bindPipeline()
*/
DynamicRasterizationStates dynamicRasterizationStates() const {
return _dynamicRasterizationStates;
}
/**
* @brief Reset the command buffer
*
@ -361,8 +373,10 @@ class MAGNUM_VK_EXPORT CommandBuffer {
* @brief Bind a pipeline
* @return Reference to self (for method chaining)
*
* Can be called both inside and outside a render pass. See
* @ref Vk-Pipeline-usage for a usage example.
* Can be called both inside and outside a render pass. If the pipeline
* is a rasterization pipeline, the set of its dynamic states is stored
* in @ref dynamicRasterizationStates() for use by drawing and other
* commands. See @ref Vk-Pipeline-usage for a usage example.
* @see @fn_vk_keyword{CmdBindPipeline}
*/
CommandBuffer& bindPipeline(Pipeline& pipeline);
@ -765,6 +779,7 @@ class MAGNUM_VK_EXPORT CommandBuffer {
VkCommandPool _pool; /* Used only for vkFreeCommandBuffers() */
VkCommandBuffer _handle;
HandleFlags _flags;
DynamicRasterizationStates _dynamicRasterizationStates;
};
}}

4
src/Magnum/Vk/Pipeline.cpp

@ -412,6 +412,10 @@ ImageMemoryBarrier::ImageMemoryBarrier(const VkImageMemoryBarrier& barrier):
_barrier(barrier) {}
CommandBuffer& CommandBuffer::bindPipeline(Pipeline& pipeline) {
/* Save the set of dynamic states for future use */
if(pipeline.bindPoint() == PipelineBindPoint::Rasterization)
_dynamicRasterizationStates = pipeline.dynamicRasterizationStates();
(**_device).CmdBindPipeline(_handle, VkPipelineBindPoint(pipeline.bindPoint()), pipeline);
return *this;
}

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

@ -67,7 +67,8 @@ struct PipelineVkTest: VulkanTester {
void dynamicRasterizationStatesNotRasterization();
void cmdBind();
void cmdBindRasterization();
void cmdBindCompute();
void cmdBarrier();
void cmdBarrierExecutionOnly();
@ -89,7 +90,8 @@ PipelineVkTest::PipelineVkTest() {
&PipelineVkTest::dynamicRasterizationStatesNotRasterization,
&PipelineVkTest::cmdBind,
&PipelineVkTest::cmdBindRasterization,
&PipelineVkTest::cmdBindCompute,
&PipelineVkTest::cmdBarrier,
&PipelineVkTest::cmdBarrierExecutionOnly,
@ -447,7 +449,64 @@ void PipelineVkTest::dynamicRasterizationStatesNotRasterization() {
CORRADE_COMPARE(out.str(), "Vk::Pipeline::dynamicRasterizationStates(): not a rasterization pipeline\n");
}
void PipelineVkTest::cmdBind() {
void PipelineVkTest::cmdBindRasterization() {
CommandPool pool{device(), CommandPoolCreateInfo{
/* This might blow up if queue() isn't the one matching this family */
device().properties().pickQueueFamily(QueueFlag::Graphics|QueueFlag::Compute)}};
RenderPass renderPass{device(), RenderPassCreateInfo{}
.setAttachments({
AttachmentDescription{PixelFormat::RGBA8Unorm,
AttachmentLoadOperation::Clear,
AttachmentStoreOperation::Store,
ImageLayout::Undefined,
ImageLayout::ColorAttachment}
})
.addSubpass(SubpassDescription{}.setColorAttachments({
AttachmentReference{0, ImageLayout::ColorAttachment}
}))
};
/* Not sure if this is really needed, but the shader needs those inputs so
playing it safe */
MeshLayout meshLayout{MeshPrimitive::Triangles};
meshLayout
.addBinding(0, 2*4*4)
.addAttribute(0, 0, Vk::VertexFormat::Vector4, 0)
.addAttribute(1, 0, Vk::VertexFormat::Vector4, 4*4);
PipelineLayout pipelineLayout{device(), PipelineLayoutCreateInfo{}};
Shader shader{device(), ShaderCreateInfo{
Utility::Directory::read(Utility::Directory::join(VK_TEST_DIR, "triangle-shaders.spv"))
}};
ShaderSet shaderSet;
shaderSet
.addShader(ShaderStage::Vertex, shader, "ver"_s)
.addShader(ShaderStage::Fragment, shader, "fra"_s);
Pipeline pipeline{device(), RasterizationPipelineCreateInfo{
shaderSet, meshLayout, pipelineLayout, renderPass, 0, 1}
.setViewport({{}, {200, 200}})
.setDynamicStates(DynamicRasterizationState::LineWidth|DynamicRasterizationState::DepthBias)
};
CommandBuffer cmd = pool.allocate();
cmd.begin();
CORRADE_COMPARE(cmd.dynamicRasterizationStates(), DynamicRasterizationStates{});
cmd.bindPipeline(pipeline);
CORRADE_COMPARE(cmd.dynamicRasterizationStates(), DynamicRasterizationState::LineWidth|DynamicRasterizationState::DepthBias);
/* Should be reset again on end() so if it's reset() and begun again it
doesn't show a no-longer-true value */
cmd.end();
CORRADE_COMPARE(cmd.dynamicRasterizationStates(), DynamicRasterizationStates{});
}
void PipelineVkTest::cmdBindCompute() {
CommandPool pool{device(), CommandPoolCreateInfo{
/* This might blow up if queue() isn't the one matching this family */
device().properties().pickQueueFamily(QueueFlag::Graphics|QueueFlag::Compute)}};

Loading…
Cancel
Save