- use dynamic state for viewport and scissor

This commit is contained in:
Magnus Norddahl 2019-02-28 15:45:59 +01:00
parent 45061e8b44
commit e472050f36
4 changed files with 87 additions and 6 deletions

View file

@ -157,6 +157,16 @@ void VkRenderPassSetup::CreatePipeline()
builder.addVertexAttribute(5, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(FFlatVertex, x));
#endif
builder.addDynamicState(VK_DYNAMIC_STATE_VIEWPORT);
builder.addDynamicState(VK_DYNAMIC_STATE_SCISSOR);
// builder.addDynamicState(VK_DYNAMIC_STATE_LINE_WIDTH);
// builder.addDynamicState(VK_DYNAMIC_STATE_DEPTH_BIAS);
// builder.addDynamicState(VK_DYNAMIC_STATE_BLEND_CONSTANTS);
// builder.addDynamicState(VK_DYNAMIC_STATE_DEPTH_BOUNDS);
// builder.addDynamicState(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK);
// builder.addDynamicState(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK);
// builder.addDynamicState(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
builder.setViewport(0.0f, 0.0f, (float)SCREENWIDTH, (float)SCREENHEIGHT);
builder.setScissor(0, 0, SCREENWIDTH, SCREENHEIGHT);
builder.setAlphaBlendMode();

View file

@ -77,6 +77,9 @@ void VkRenderState::SetDepthFunc(int func)
void VkRenderState::SetDepthRange(float min, float max)
{
mViewportDepthMin = min;
mViewportDepthMax = max;
mViewportChanged = true;
}
void VkRenderState::SetColorMask(bool r, bool g, bool b, bool a)
@ -109,10 +112,20 @@ void VkRenderState::EnableStencil(bool on)
void VkRenderState::SetScissor(int x, int y, int w, int h)
{
mScissorX = x;
mScissorY = y;
mScissorWidth = w;
mScissorHeight = h;
mScissorChanged = true;
}
void VkRenderState::SetViewport(int x, int y, int w, int h)
{
mViewportX = x;
mViewportY = y;
mViewportWidth = w;
mViewportHeight = h;
mViewportChanged = true;
}
void VkRenderState::EnableDepthTest(bool on)
@ -139,6 +152,8 @@ void VkRenderState::Apply(int dt)
{
mCommandBuffer = fb->GetDrawCommands();
changingRenderPass = true;
mScissorChanged = true;
mViewportChanged = true;
}
else if (changingRenderPass)
{
@ -157,6 +172,50 @@ void VkRenderState::Apply(int dt)
mCommandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->Pipeline.get());
}
if (mScissorChanged)
{
VkRect2D scissor;
if (mScissorWidth >= 0)
{
scissor.offset.x = mScissorX;
scissor.offset.y = mScissorY;
scissor.extent.width = mScissorWidth;
scissor.extent.height = mScissorHeight;
}
else
{
scissor.offset.x = 0;
scissor.offset.y = 0;
scissor.extent.width = SCREENWIDTH;
scissor.extent.height = SCREENHEIGHT;
}
mCommandBuffer->setScissor(0, 1, &scissor);
mScissorChanged = false;
}
if (mViewportChanged)
{
VkViewport viewport;
if (mViewportWidth >= 0)
{
viewport.x = (float)mViewportX;
viewport.y = (float)mViewportY;
viewport.width = (float)mViewportWidth;
viewport.height = (float)mViewportHeight;
}
else
{
viewport.x = 0.0f;
viewport.y = 0.0f;
viewport.width = (float)SCREENWIDTH;
viewport.height = (float)SCREENHEIGHT;
}
viewport.minDepth = mViewportDepthMin;
viewport.maxDepth = mViewportDepthMax;
mCommandBuffer->setViewport(0, 1, &viewport);
mViewportChanged = false;
}
const float normScale = 1.0f / 255.0f;
//glVertexAttrib4fv(VATTR_COLOR, mColor.vec);

View file

@ -49,6 +49,12 @@ private:
VulkanCommandBuffer *mCommandBuffer = nullptr;
bool mDescriptorsChanged = true;
int mScissorX = 0, mScissorY = 0, mScissorWidth = -1, mScissorHeight = -1;
int mViewportX = 0, mViewportY = 0, mViewportWidth = -1, mViewportHeight = -1;
float mViewportDepthMin = 0.0f, mViewportDepthMax = 1.0f;
bool mScissorChanged = true;
bool mViewportChanged = true;
MatricesUBO mMatrices = {};
ColorsUBO mColors = {};
GlowingWallsUBO mGlowingWalls = {};

View file

@ -197,6 +197,8 @@ public:
void addVertexBufferBinding(int index, size_t stride);
void addVertexAttribute(int location, int binding, VkFormat format, size_t offset);
void addDynamicState(VkDynamicState state);
std::unique_ptr<VulkanPipeline> create(VulkanDevice *device);
private:
@ -211,11 +213,13 @@ private:
VkPipelineColorBlendAttachmentState colorBlendAttachment = { };
VkPipelineColorBlendStateCreateInfo colorBlending = { };
VkPipelineDepthStencilStateCreateInfo depthStencil = { };
VkPipelineDynamicStateCreateInfo dynamicState = {};
std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachments;
std::vector<VkVertexInputBindingDescription> vertexInputBindings;
std::vector<VkVertexInputAttributeDescription> vertexInputAttributes;
std::vector<VkDynamicState> dynamicStates;
};
class PipelineLayoutBuilder
@ -638,7 +642,7 @@ inline GraphicsPipelineBuilder::GraphicsPipelineBuilder()
pipelineInfo.pMultisampleState = &multisampling;
pipelineInfo.pDepthStencilState = nullptr;
pipelineInfo.pColorBlendState = &colorBlending;
pipelineInfo.pDynamicState = nullptr;
pipelineInfo.pDynamicState = &dynamicState;
pipelineInfo.subpass = 0;
pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
pipelineInfo.basePipelineIndex = -1;
@ -703,13 +707,8 @@ inline GraphicsPipelineBuilder::GraphicsPipelineBuilder()
colorBlending.blendConstants[2] = 0.0f;
colorBlending.blendConstants[3] = 0.0f;
/*
VkDynamicState dynamicStates[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_LINE_WIDTH };
VkPipelineDynamicStateCreateInfo dynamicState = {};
dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
dynamicState.dynamicStateCount = 2;
dynamicState.pDynamicStates = dynamicStates;
*/
}
inline void GraphicsPipelineBuilder::setSubpass(int subpass)
@ -845,6 +844,13 @@ inline void GraphicsPipelineBuilder::addVertexAttribute(int location, int bindin
vertexInputInfo.pVertexAttributeDescriptions = vertexInputAttributes.data();
}
inline void GraphicsPipelineBuilder::addDynamicState(VkDynamicState state)
{
dynamicStates.push_back(state);
dynamicState.dynamicStateCount = (uint32_t)dynamicStates.size();
dynamicState.pDynamicStates = dynamicStates.data();
}
inline std::unique_ptr<VulkanPipeline> GraphicsPipelineBuilder::create(VulkanDevice *device)
{
VkPipeline pipeline = 0;