Commit 633d5e69 by Jamie Madill Committed by Commit Bot

Vulkan: Put viewport and scissor back in pipeline desc.

Turns out this is much faster than using dynamic state. When we support multiple viewports it might be easier to use dynamic state since we won't need to make an overly large pipeline description. We could support both methods using a flag to indicate the viewport and/or scissor regions are invalid. Until then we can remove the pipeline and scissor dirty bits. Improves perf by about 15% in the Vulkan VBO state change test. Bug: angleproject:3013 Change-Id: I4572250626a9a0f0ca3451b17e8f0de186416cae Reviewed-on: https://chromium-review.googlesource.com/c/1390359 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 5bca4fed
......@@ -121,9 +121,7 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk
mDriverUniformsBuffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, sizeof(DriverUniforms) * 16, true),
mDriverUniformsDescriptorSet(VK_NULL_HANDLE),
mDefaultAttribBuffers{{INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT,
INIT, INIT, INIT, INIT}},
mViewport{},
mScissor{}
INIT, INIT, INIT, INIT}}
{
TRACE_EVENT0("gpu.angle", "ContextVk::ContextVk");
memset(&mClearColorValue, 0, sizeof(mClearColorValue));
......@@ -139,8 +137,6 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk
mNewCommandBufferDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
mNewCommandBufferDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
mNewCommandBufferDirtyBits.set(DIRTY_BIT_DESCRIPTOR_SETS);
mNewCommandBufferDirtyBits.set(DIRTY_BIT_VIEWPORT);
mNewCommandBufferDirtyBits.set(DIRTY_BIT_SCISSOR);
mDirtyBitHandlers[DIRTY_BIT_DEFAULT_ATTRIBS] = &ContextVk::handleDirtyDefaultAttribs;
mDirtyBitHandlers[DIRTY_BIT_PIPELINE] = &ContextVk::handleDirtyPipeline;
......@@ -149,8 +145,6 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk
mDirtyBitHandlers[DIRTY_BIT_INDEX_BUFFER] = &ContextVk::handleDirtyIndexBuffer;
mDirtyBitHandlers[DIRTY_BIT_DRIVER_UNIFORMS] = &ContextVk::handleDirtyDriverUniforms;
mDirtyBitHandlers[DIRTY_BIT_DESCRIPTOR_SETS] = &ContextVk::handleDirtyDescriptorSets;
mDirtyBitHandlers[DIRTY_BIT_VIEWPORT] = &ContextVk::handleDirtyViewport;
mDirtyBitHandlers[DIRTY_BIT_SCISSOR] = &ContextVk::handleDirtyScissor;
mDirtyBits = mNewCommandBufferDirtyBits;
}
......@@ -465,20 +459,6 @@ angle::Result ContextVk::handleDirtyDescriptorSets(const gl::Context *context,
return angle::Result::Continue;
}
angle::Result ContextVk::handleDirtyViewport(const gl::Context *context,
vk::CommandBuffer *commandBuffer)
{
commandBuffer->setViewport(0, 1, &mViewport);
return angle::Result::Continue;
}
angle::Result ContextVk::handleDirtyScissor(const gl::Context *context,
vk::CommandBuffer *commandBuffer)
{
commandBuffer->setScissor(0, 1, &mScissor);
return angle::Result::Continue;
}
angle::Result ContextVk::drawArrays(const gl::Context *context,
gl::PrimitiveMode mode,
GLint first,
......@@ -655,20 +635,17 @@ void ContextVk::updateViewport(FramebufferVk *framebufferVk,
float farPlane,
bool invertViewport)
{
VkViewport vkViewport;
gl_vk::GetViewport(viewport, nearPlane, farPlane, invertViewport,
framebufferVk->getState().getDimensions().height, &mViewport);
framebufferVk->getState().getDimensions().height, &vkViewport);
mGraphicsPipelineDesc->updateViewport(&mGraphicsPipelineTransition, vkViewport);
invalidateDriverUniforms();
mDirtyBits.set(DIRTY_BIT_VIEWPORT);
}
void ContextVk::updateDepthRange(float nearPlane, float farPlane)
{
// GLES2.0 Section 2.12.1: Each of n and f are clamped to lie within [0, 1], as are all
// arguments of type clampf.
mViewport.minDepth = gl::clamp01(nearPlane);
mViewport.maxDepth = gl::clamp01(farPlane);
invalidateDriverUniforms();
mDirtyBits.set(DIRTY_BIT_VIEWPORT);
mGraphicsPipelineDesc->updateDepthRange(&mGraphicsPipelineTransition, nearPlane, farPlane);
}
void ContextVk::updateScissor(const gl::State &glState)
......@@ -677,8 +654,9 @@ void ContextVk::updateScissor(const gl::State &glState)
gl::Box dimensions = framebufferVk->getState().getDimensions();
gl::Rectangle renderArea(0, 0, dimensions.width, dimensions.height);
gl_vk::GetScissor(glState, isViewportFlipEnabledForDrawFBO(), renderArea, &mScissor);
mDirtyBits.set(DIRTY_BIT_SCISSOR);
VkRect2D scissor;
gl_vk::GetScissor(glState, isViewportFlipEnabledForDrawFBO(), renderArea, &scissor);
mGraphicsPipelineDesc->updateScissor(&mGraphicsPipelineTransition, scissor);
}
angle::Result ContextVk::syncState(const gl::Context *context,
......
......@@ -194,7 +194,6 @@ class ContextVk : public ContextImpl, public vk::Context
const VkClearValue &getClearColorValue() const;
const VkClearValue &getClearDepthStencilValue() const;
VkColorComponentFlags getClearColorMask() const;
const VkRect2D &getScissor() const { return mScissor; }
angle::Result getIncompleteTexture(const gl::Context *context,
gl::TextureType type,
gl::Texture **textureOut);
......@@ -219,8 +218,6 @@ class ContextVk : public ContextImpl, public vk::Context
DIRTY_BIT_INDEX_BUFFER,
DIRTY_BIT_DRIVER_UNIFORMS,
DIRTY_BIT_DESCRIPTOR_SETS,
DIRTY_BIT_VIEWPORT,
DIRTY_BIT_SCISSOR,
DIRTY_BIT_MAX,
};
......@@ -266,12 +263,7 @@ class ContextVk : public ContextImpl, public vk::Context
angle::Result updateActiveTextures(const gl::Context *context);
angle::Result updateDefaultAttribute(size_t attribIndex);
ANGLE_INLINE void invalidateCurrentPipeline()
{
mDirtyBits.set(DIRTY_BIT_PIPELINE);
mDirtyBits.set(DIRTY_BIT_VIEWPORT);
mDirtyBits.set(DIRTY_BIT_SCISSOR);
}
ANGLE_INLINE void invalidateCurrentPipeline() { mDirtyBits.set(DIRTY_BIT_PIPELINE); }
void invalidateCurrentTextures();
void invalidateDriverUniforms();
......@@ -288,8 +280,6 @@ class ContextVk : public ContextImpl, public vk::Context
vk::CommandBuffer *commandBuffer);
angle::Result handleDirtyDescriptorSets(const gl::Context *context,
vk::CommandBuffer *commandBuffer);
angle::Result handleDirtyViewport(const gl::Context *context, vk::CommandBuffer *commandBuffer);
angle::Result handleDirtyScissor(const gl::Context *context, vk::CommandBuffer *commandBuffer);
vk::PipelineHelper *mCurrentPipeline;
gl::PrimitiveMode mCurrentDrawMode;
......@@ -361,10 +351,6 @@ class ContextVk : public ContextImpl, public vk::Context
// "Current Value" aka default vertex attribute state.
gl::AttributesMask mDirtyDefaultAttribsMask;
gl::AttribArray<vk::DynamicBuffer> mDefaultAttribBuffers;
// Viewport and scissor are handled as dynamic state.
VkViewport mViewport;
VkRect2D mScissor;
};
} // namespace rx
......
......@@ -627,6 +627,18 @@ angle::Result UtilsVk::clearImage(ContextVk *contextVk,
pipelineDesc.setColorWriteMask(params.colorMaskFlags, *params.alphaMask);
pipelineDesc.setRenderPassDesc(*params.renderPassDesc);
const gl::Rectangle &renderArea = framebuffer->getFramebuffer()->getRenderPassRenderArea();
bool invertViewport = contextVk->isViewportFlipEnabledForDrawFBO();
VkViewport viewport;
gl_vk::GetViewport(renderArea, 0.0f, 1.0f, invertViewport, params.renderAreaHeight, &viewport);
pipelineDesc.setViewport(viewport);
VkRect2D scissor;
const gl::State &glState = contextVk->getState();
gl_vk::GetScissor(glState, invertViewport, renderArea, &scissor);
pipelineDesc.setScissor(scissor);
vk::ShaderLibrary &shaderLibrary = renderer->getShaderLibrary();
vk::RefCounted<vk::ShaderAndSerial> *vertexShader = nullptr;
vk::RefCounted<vk::ShaderAndSerial> *fragmentShader = nullptr;
......@@ -637,17 +649,6 @@ angle::Result UtilsVk::clearImage(ContextVk *contextVk,
&mImageClearProgram, &pipelineDesc, VK_NULL_HANDLE, &shaderParams,
sizeof(shaderParams), commandBuffer));
VkViewport viewport;
const gl::Rectangle &renderArea = framebuffer->getFramebuffer()->getRenderPassRenderArea();
bool invertViewport = contextVk->isViewportFlipEnabledForDrawFBO();
gl_vk::GetViewport(renderArea, 0.0f, 1.0f, invertViewport, params.renderAreaHeight, &viewport);
VkRect2D scissor;
const gl::State &glState = contextVk->getState();
gl_vk::GetScissor(glState, invertViewport, renderArea, &scissor);
commandBuffer->setViewport(0, 1, &viewport);
commandBuffer->setScissor(0, 1, &scissor);
commandBuffer->draw(6, 1, 0, 0);
return angle::Result::Continue;
......@@ -720,6 +721,13 @@ angle::Result UtilsVk::copyImage(vk::Context *context,
renderArea.width = params.srcExtents[0];
renderArea.height = params.srcExtents[1];
VkViewport viewport;
gl_vk::GetViewport(renderArea, 0.0f, 1.0f, false, dest->getExtents().height, &viewport);
pipelineDesc.setViewport(viewport);
VkRect2D scissor = gl_vk::GetRect(renderArea);
pipelineDesc.setScissor(scissor);
// Change source layout outside render pass
if (src->getCurrentLayout() != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
{
......@@ -771,13 +779,6 @@ angle::Result UtilsVk::copyImage(vk::Context *context,
&mImageCopyPrograms[flags], &pipelineDesc, descriptorSet, &shaderParams,
sizeof(shaderParams), commandBuffer));
VkViewport viewport;
gl_vk::GetViewport(renderArea, 0.0f, 1.0f, false, dest->getExtents().height, &viewport);
VkRect2D scissor = gl_vk::GetRect(renderArea);
commandBuffer->setViewport(0, 1, &viewport);
commandBuffer->setScissor(0, 1, &scissor);
commandBuffer->draw(6, 1, 0, 0);
descriptorPoolBinding.reset();
......
......@@ -606,9 +606,9 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
viewportState.flags = 0;
viewportState.viewportCount = 1;
viewportState.pViewports = nullptr;
viewportState.pViewports = &mViewport;
viewportState.scissorCount = 1;
viewportState.pScissors = nullptr;
viewportState.pScissors = &mScissor;
const PackedRasterizationAndMultisampleStateInfo &rasterAndMS =
mRasterizationAndMultisampleStateInfo;
......@@ -689,13 +689,7 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
UnpackBlendAttachmentState(inputAndBlend.attachments[colorIndex], &state);
}
std::array<VkDynamicState, 2> dynamicStates = {
{VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_VIEWPORT}};
VkPipelineDynamicStateCreateInfo dynamicState = {};
dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
dynamicState.dynamicStateCount = static_cast<uint32_t>(dynamicStates.size());
dynamicState.pDynamicStates = dynamicStates.data();
// We would define dynamic state here if it were to be used.
createInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
createInfo.flags = 0;
......@@ -709,7 +703,7 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
createInfo.pMultisampleState = &multisampleState;
createInfo.pDepthStencilState = &depthStencilState;
createInfo.pColorBlendState = &blendState;
createInfo.pDynamicState = &dynamicState;
createInfo.pDynamicState = nullptr;
createInfo.layout = pipelineLayout.getHandle();
createInfo.renderPass = compatibleRenderPass.getHandle();
createInfo.subpass = 0;
......@@ -1006,6 +1000,50 @@ void GraphicsPipelineDesc::setRenderPassDesc(const RenderPassDesc &renderPassDes
mRenderPassDesc = renderPassDesc;
}
void GraphicsPipelineDesc::setViewport(const VkViewport &viewport)
{
mViewport = viewport;
}
void GraphicsPipelineDesc::updateViewport(GraphicsPipelineTransitionBits *transition,
const VkViewport &viewport)
{
mViewport = viewport;
transition->set(ANGLE_GET_TRANSITION_BIT(mViewport, x));
transition->set(ANGLE_GET_TRANSITION_BIT(mViewport, y));
transition->set(ANGLE_GET_TRANSITION_BIT(mViewport, width));
transition->set(ANGLE_GET_TRANSITION_BIT(mViewport, height));
transition->set(ANGLE_GET_TRANSITION_BIT(mViewport, minDepth));
transition->set(ANGLE_GET_TRANSITION_BIT(mViewport, maxDepth));
}
void GraphicsPipelineDesc::updateDepthRange(GraphicsPipelineTransitionBits *transition,
float nearPlane,
float farPlane)
{
// GLES2.0 Section 2.12.1: Each of n and f are clamped to lie within [0, 1], as are all
// arguments of type clampf.
mViewport.minDepth = gl::clamp01(nearPlane);
mViewport.maxDepth = gl::clamp01(farPlane);
transition->set(ANGLE_GET_TRANSITION_BIT(mViewport, minDepth));
transition->set(ANGLE_GET_TRANSITION_BIT(mViewport, maxDepth));
}
void GraphicsPipelineDesc::setScissor(const VkRect2D &scissor)
{
mScissor = scissor;
}
void GraphicsPipelineDesc::updateScissor(GraphicsPipelineTransitionBits *transition,
const VkRect2D &scissor)
{
mScissor = scissor;
transition->set(ANGLE_GET_TRANSITION_BIT(mScissor, offset.x));
transition->set(ANGLE_GET_TRANSITION_BIT(mScissor, offset.y));
transition->set(ANGLE_GET_TRANSITION_BIT(mScissor, extent.width));
transition->set(ANGLE_GET_TRANSITION_BIT(mScissor, extent.height));
}
void GraphicsPipelineDesc::updateRenderPassDesc(GraphicsPipelineTransitionBits *transition,
const RenderPassDesc &renderPassDesc)
{
......
......@@ -281,7 +281,7 @@ static_assert(kPackedInputAssemblyAndColorBlendStateSize == 56, "Size check fail
constexpr size_t kGraphicsPipelineDescSumOfSizes =
kVertexInputAttributesSize + kPackedInputAssemblyAndColorBlendStateSize +
kPackedRasterizationAndMultisampleStateSize + kPackedDepthStencilStateSize +
kRenderPassDescSize;
kRenderPassDescSize + sizeof(VkViewport) + sizeof(VkRect2D);
// Number of dirty bits in the dirty bit set.
constexpr size_t kGraphicsPipelineDirtyBitBytes = 4;
......@@ -402,13 +402,23 @@ class GraphicsPipelineDesc final
void updatePolygonOffset(GraphicsPipelineTransitionBits *transition,
const gl::RasterizerState &rasterState);
// Viewport and scissor.
void setViewport(const VkViewport &viewport);
void updateViewport(GraphicsPipelineTransitionBits *transition, const VkViewport &viewport);
void updateDepthRange(GraphicsPipelineTransitionBits *transition,
float nearPlane,
float farPlane);
void setScissor(const VkRect2D &scissor);
void updateScissor(GraphicsPipelineTransitionBits *transition, const VkRect2D &scissor);
private:
VertexInputAttributes mVertexInputAttribs;
RenderPassDesc mRenderPassDesc;
PackedRasterizationAndMultisampleStateInfo mRasterizationAndMultisampleStateInfo;
PackedDepthStencilStateInfo mDepthStencilStateInfo;
PackedInputAssemblyAndColorBlendStateInfo mInputAssemblyAndColorBlendStateInfo;
// Viewport and scissor are applied as dynamic state.
VkViewport mViewport;
VkRect2D mScissor;
};
// Verify the packed pipeline description has no gaps in the packing.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment