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() { 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)); MAGNUM_VK_INTERNAL_ASSERT_SUCCESS((**_device).EndCommandBuffer(_handle));
} }

19
src/Magnum/Vk/CommandBuffer.h

@ -31,6 +31,7 @@
*/ */
#include <initializer_list> #include <initializer_list>
#include <Corrade/Containers/BigEnumSet.h>
#include <Corrade/Containers/EnumSet.h> #include <Corrade/Containers/EnumSet.h>
#include "Magnum/Tags.h" #include "Magnum/Tags.h"
@ -259,6 +260,17 @@ class MAGNUM_VK_EXPORT CommandBuffer {
/** @brief Handle flags */ /** @brief Handle flags */
HandleFlags handleFlags() const { return _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 * @brief Reset the command buffer
* *
@ -361,8 +373,10 @@ class MAGNUM_VK_EXPORT CommandBuffer {
* @brief Bind a pipeline * @brief Bind a pipeline
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Can be called both inside and outside a render pass. See * Can be called both inside and outside a render pass. If the pipeline
* @ref Vk-Pipeline-usage for a usage example. * 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} * @see @fn_vk_keyword{CmdBindPipeline}
*/ */
CommandBuffer& bindPipeline(Pipeline& pipeline); CommandBuffer& bindPipeline(Pipeline& pipeline);
@ -765,6 +779,7 @@ class MAGNUM_VK_EXPORT CommandBuffer {
VkCommandPool _pool; /* Used only for vkFreeCommandBuffers() */ VkCommandPool _pool; /* Used only for vkFreeCommandBuffers() */
VkCommandBuffer _handle; VkCommandBuffer _handle;
HandleFlags _flags; HandleFlags _flags;
DynamicRasterizationStates _dynamicRasterizationStates;
}; };
}} }}

4
src/Magnum/Vk/Pipeline.cpp

@ -412,6 +412,10 @@ ImageMemoryBarrier::ImageMemoryBarrier(const VkImageMemoryBarrier& barrier):
_barrier(barrier) {} _barrier(barrier) {}
CommandBuffer& CommandBuffer::bindPipeline(Pipeline& pipeline) { 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); (**_device).CmdBindPipeline(_handle, VkPipelineBindPoint(pipeline.bindPoint()), pipeline);
return *this; return *this;
} }

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

@ -67,7 +67,8 @@ struct PipelineVkTest: VulkanTester {
void dynamicRasterizationStatesNotRasterization(); void dynamicRasterizationStatesNotRasterization();
void cmdBind(); void cmdBindRasterization();
void cmdBindCompute();
void cmdBarrier(); void cmdBarrier();
void cmdBarrierExecutionOnly(); void cmdBarrierExecutionOnly();
@ -89,7 +90,8 @@ PipelineVkTest::PipelineVkTest() {
&PipelineVkTest::dynamicRasterizationStatesNotRasterization, &PipelineVkTest::dynamicRasterizationStatesNotRasterization,
&PipelineVkTest::cmdBind, &PipelineVkTest::cmdBindRasterization,
&PipelineVkTest::cmdBindCompute,
&PipelineVkTest::cmdBarrier, &PipelineVkTest::cmdBarrier,
&PipelineVkTest::cmdBarrierExecutionOnly, &PipelineVkTest::cmdBarrierExecutionOnly,
@ -447,7 +449,64 @@ void PipelineVkTest::dynamicRasterizationStatesNotRasterization() {
CORRADE_COMPARE(out.str(), "Vk::Pipeline::dynamicRasterizationStates(): not a rasterization pipeline\n"); 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{ CommandPool pool{device(), CommandPoolCreateInfo{
/* This might blow up if queue() isn't the one matching this family */ /* This might blow up if queue() isn't the one matching this family */
device().properties().pickQueueFamily(QueueFlag::Graphics|QueueFlag::Compute)}}; device().properties().pickQueueFamily(QueueFlag::Graphics|QueueFlag::Compute)}};

Loading…
Cancel
Save