Commit bc5834cd by Jamie Madill Committed by Commit Bot

Vulkan: Use dynamic state for Viewport and Scissor.

This reduces the size of the pipeline cache descriptor under 256 bytes. Further improves the speed of cache query. Has the minor cost of needing more state application during a new command buffer or render pass. Bug: angleproject:2522 Change-Id: I3d71e457a36084ac4748d04fe3c9bab4caad503c Reviewed-on: https://chromium-review.googlesource.com/c/1316888 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 77b2436e
...@@ -89,11 +89,6 @@ void BindNonNullVertexBufferRanges(vk::CommandBuffer *commandBuffer, ...@@ -89,11 +89,6 @@ void BindNonNullVertexBufferRanges(vk::CommandBuffer *commandBuffer,
} }
} }
constexpr gl::Rectangle kMaxSizedScissor(0,
0,
std::numeric_limits<int>::max(),
std::numeric_limits<int>::max());
constexpr VkColorComponentFlags kAllColorChannelsMask = constexpr VkColorComponentFlags kAllColorChannelsMask =
(VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT |
VK_COLOR_COMPONENT_A_BIT); VK_COLOR_COMPONENT_A_BIT);
...@@ -123,7 +118,9 @@ ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer) ...@@ -123,7 +118,9 @@ ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer)
mDriverUniformsBuffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, sizeof(DriverUniforms) * 16), mDriverUniformsBuffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, sizeof(DriverUniforms) * 16),
mDriverUniformsDescriptorSet(VK_NULL_HANDLE), mDriverUniformsDescriptorSet(VK_NULL_HANDLE),
mDefaultAttribBuffers{{INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, mDefaultAttribBuffers{{INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT,
INIT, INIT, INIT, INIT}} INIT, INIT, INIT, INIT}},
mViewport{},
mScissor{}
{ {
memset(&mClearColorValue, 0, sizeof(mClearColorValue)); memset(&mClearColorValue, 0, sizeof(mClearColorValue));
memset(&mClearDepthStencilValue, 0, sizeof(mClearDepthStencilValue)); memset(&mClearDepthStencilValue, 0, sizeof(mClearDepthStencilValue));
...@@ -138,6 +135,8 @@ ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer) ...@@ -138,6 +135,8 @@ ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer)
mNewCommandBufferDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS); mNewCommandBufferDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
mNewCommandBufferDirtyBits.set(DIRTY_BIT_INDEX_BUFFER); mNewCommandBufferDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
mNewCommandBufferDirtyBits.set(DIRTY_BIT_DESCRIPTOR_SETS); 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_DEFAULT_ATTRIBS] = &ContextVk::handleDirtyDefaultAttribs;
mDirtyBitHandlers[DIRTY_BIT_PIPELINE] = &ContextVk::handleDirtyPipeline; mDirtyBitHandlers[DIRTY_BIT_PIPELINE] = &ContextVk::handleDirtyPipeline;
...@@ -146,6 +145,8 @@ ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer) ...@@ -146,6 +145,8 @@ ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer)
mDirtyBitHandlers[DIRTY_BIT_INDEX_BUFFER] = &ContextVk::handleDirtyIndexBuffer; mDirtyBitHandlers[DIRTY_BIT_INDEX_BUFFER] = &ContextVk::handleDirtyIndexBuffer;
mDirtyBitHandlers[DIRTY_BIT_DRIVER_UNIFORMS] = &ContextVk::handleDirtyDriverUniforms; mDirtyBitHandlers[DIRTY_BIT_DRIVER_UNIFORMS] = &ContextVk::handleDirtyDriverUniforms;
mDirtyBitHandlers[DIRTY_BIT_DESCRIPTOR_SETS] = &ContextVk::handleDirtyDescriptorSets; mDirtyBitHandlers[DIRTY_BIT_DESCRIPTOR_SETS] = &ContextVk::handleDirtyDescriptorSets;
mDirtyBitHandlers[DIRTY_BIT_VIEWPORT] = &ContextVk::handleDirtyViewport;
mDirtyBitHandlers[DIRTY_BIT_SCISSOR] = &ContextVk::handleDirtyScissor;
mDirtyBits = mNewCommandBufferDirtyBits; mDirtyBits = mNewCommandBufferDirtyBits;
} }
...@@ -276,8 +277,7 @@ angle::Result ContextVk::setupDraw(const gl::Context *context, ...@@ -276,8 +277,7 @@ angle::Result ContextVk::setupDraw(const gl::Context *context,
// Set any dirty bits that depend on draw call parameters or other objects. // Set any dirty bits that depend on draw call parameters or other objects.
if (mode != mCurrentDrawMode) if (mode != mCurrentDrawMode)
{ {
mCurrentPipeline = nullptr; invalidateCurrentPipeline();
mDirtyBits.set(DIRTY_BIT_PIPELINE);
mCurrentDrawMode = mode; mCurrentDrawMode = mode;
} }
...@@ -467,6 +467,20 @@ angle::Result ContextVk::handleDirtyDescriptorSets(const gl::Context *context, ...@@ -467,6 +467,20 @@ angle::Result ContextVk::handleDirtyDescriptorSets(const gl::Context *context,
return angle::Result::Continue(); 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, angle::Result ContextVk::drawArrays(const gl::Context *context,
gl::PrimitiveMode mode, gl::PrimitiveMode mode,
GLint first, GLint first,
...@@ -636,25 +650,36 @@ void ContextVk::updateColorMask(const gl::BlendState &blendState) ...@@ -636,25 +650,36 @@ void ContextVk::updateColorMask(const gl::BlendState &blendState)
framebufferVk->getEmulatedAlphaAttachmentMask()); framebufferVk->getEmulatedAlphaAttachmentMask());
} }
void ContextVk::updateScissor(const gl::State &glState) const void ContextVk::updateViewport(FramebufferVk *framebufferVk,
const gl::Rectangle &viewport,
float nearPlane,
float farPlane,
bool invertViewport)
{
gl_vk::GetViewport(viewport, nearPlane, farPlane, invertViewport,
framebufferVk->getState().getDimensions().height, &mViewport);
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);
}
void ContextVk::updateScissor(const gl::State &glState)
{ {
FramebufferVk *framebufferVk = vk::GetImpl(glState.getDrawFramebuffer()); FramebufferVk *framebufferVk = vk::GetImpl(glState.getDrawFramebuffer());
gl::Box dimensions = framebufferVk->getState().getDimensions(); gl::Box dimensions = framebufferVk->getState().getDimensions();
gl::Rectangle renderArea(0, 0, dimensions.width, dimensions.height); gl::Rectangle renderArea(0, 0, dimensions.width, dimensions.height);
if (glState.isScissorTestEnabled()) gl_vk::GetScissor(glState, isViewportFlipEnabledForDrawFBO(), renderArea, &mScissor);
{ mDirtyBits.set(DIRTY_BIT_SCISSOR);
mPipelineDesc->updateScissor(glState.getScissor(), isViewportFlipEnabledForDrawFBO(),
renderArea);
}
else
{
// If the scissor test isn't enabled, we can simply use a really big scissor that's
// certainly larger than the current surface using the maximum size of a 2D texture
// for the width and height.
mPipelineDesc->updateScissor(kMaxSizedScissor, isViewportFlipEnabledForDrawFBO(),
renderArea);
}
} }
angle::Result ContextVk::syncState(const gl::Context *context, angle::Result ContextVk::syncState(const gl::Context *context,
...@@ -663,7 +688,7 @@ angle::Result ContextVk::syncState(const gl::Context *context, ...@@ -663,7 +688,7 @@ angle::Result ContextVk::syncState(const gl::Context *context,
{ {
if (dirtyBits.any()) if (dirtyBits.any())
{ {
invalidateCurrentPipeline(); invalidateVertexAndIndexBuffers();
} }
const gl::State &glState = context->getGLState(); const gl::State &glState = context->getGLState();
...@@ -679,15 +704,12 @@ angle::Result ContextVk::syncState(const gl::Context *context, ...@@ -679,15 +704,12 @@ angle::Result ContextVk::syncState(const gl::Context *context,
case gl::State::DIRTY_BIT_VIEWPORT: case gl::State::DIRTY_BIT_VIEWPORT:
{ {
FramebufferVk *framebufferVk = vk::GetImpl(glState.getDrawFramebuffer()); FramebufferVk *framebufferVk = vk::GetImpl(glState.getDrawFramebuffer());
mPipelineDesc->updateViewport(framebufferVk, glState.getViewport(), updateViewport(framebufferVk, glState.getViewport(), glState.getNearPlane(),
glState.getNearPlane(), glState.getFarPlane(), glState.getFarPlane(), isViewportFlipEnabledForDrawFBO());
isViewportFlipEnabledForDrawFBO());
invalidateDriverUniforms();
break; break;
} }
case gl::State::DIRTY_BIT_DEPTH_RANGE: case gl::State::DIRTY_BIT_DEPTH_RANGE:
mPipelineDesc->updateDepthRange(glState.getNearPlane(), glState.getFarPlane()); updateDepthRange(glState.getNearPlane(), glState.getFarPlane());
invalidateDriverUniforms();
break; break;
case gl::State::DIRTY_BIT_BLEND_ENABLED: case gl::State::DIRTY_BIT_BLEND_ENABLED:
mPipelineDesc->updateBlendEnabled(glState.isBlendEnabled()); mPipelineDesc->updateBlendEnabled(glState.isBlendEnabled());
...@@ -810,9 +832,8 @@ angle::Result ContextVk::syncState(const gl::Context *context, ...@@ -810,9 +832,8 @@ angle::Result ContextVk::syncState(const gl::Context *context,
{ {
mDrawFramebuffer = vk::GetImpl(glState.getDrawFramebuffer()); mDrawFramebuffer = vk::GetImpl(glState.getDrawFramebuffer());
updateFlipViewportDrawFramebuffer(glState); updateFlipViewportDrawFramebuffer(glState);
mPipelineDesc->updateViewport(mDrawFramebuffer, glState.getViewport(), updateViewport(mDrawFramebuffer, glState.getViewport(), glState.getNearPlane(),
glState.getNearPlane(), glState.getFarPlane(), glState.getFarPlane(), isViewportFlipEnabledForDrawFBO());
isViewportFlipEnabledForDrawFBO());
updateColorMask(glState.getBlendState()); updateColorMask(glState.getBlendState());
mPipelineDesc->updateCullMode(glState.getRasterizerState()); mPipelineDesc->updateCullMode(glState.getRasterizerState());
updateScissor(glState); updateScissor(glState);
...@@ -826,7 +847,6 @@ angle::Result ContextVk::syncState(const gl::Context *context, ...@@ -826,7 +847,6 @@ angle::Result ContextVk::syncState(const gl::Context *context,
glState.getDrawFramebuffer()); glState.getDrawFramebuffer());
mPipelineDesc->updateStencilBackWriteMask(glState.getDepthStencilState(), mPipelineDesc->updateStencilBackWriteMask(glState.getDepthStencilState(),
glState.getDrawFramebuffer()); glState.getDrawFramebuffer());
invalidateDriverUniforms();
break; break;
} }
case gl::State::DIRTY_BIT_RENDERBUFFER_BINDING: case gl::State::DIRTY_BIT_RENDERBUFFER_BINDING:
...@@ -1035,11 +1055,18 @@ std::vector<PathImpl *> ContextVk::createPaths(GLsizei) ...@@ -1035,11 +1055,18 @@ std::vector<PathImpl *> ContextVk::createPaths(GLsizei)
return std::vector<PathImpl *>(); return std::vector<PathImpl *>();
} }
void ContextVk::invalidateCurrentPipeline() void ContextVk::invalidateVertexAndIndexBuffers()
{ {
mDirtyBits.set(DIRTY_BIT_PIPELINE); invalidateCurrentPipeline();
mDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS); mDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
mDirtyBits.set(DIRTY_BIT_INDEX_BUFFER); mDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
}
void ContextVk::invalidateCurrentPipeline()
{
mDirtyBits.set(DIRTY_BIT_PIPELINE);
mDirtyBits.set(DIRTY_BIT_VIEWPORT);
mDirtyBits.set(DIRTY_BIT_SCISSOR);
mCurrentPipeline = nullptr; mCurrentPipeline = nullptr;
} }
......
...@@ -159,7 +159,7 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -159,7 +159,7 @@ class ContextVk : public ContextImpl, public vk::Context
VkDevice getDevice() const; VkDevice getDevice() const;
const FeaturesVk &getFeatures() const; const FeaturesVk &getFeatures() const;
void invalidateCurrentPipeline(); void invalidateVertexAndIndexBuffers();
void invalidateDefaultAttribute(size_t attribIndex); void invalidateDefaultAttribute(size_t attribIndex);
void invalidateDefaultAttributes(const gl::AttributesMask &dirtyMask); void invalidateDefaultAttributes(const gl::AttributesMask &dirtyMask);
...@@ -169,7 +169,7 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -169,7 +169,7 @@ class ContextVk : public ContextImpl, public vk::Context
const VkClearValue &getClearColorValue() const; const VkClearValue &getClearColorValue() const;
const VkClearValue &getClearDepthStencilValue() const; const VkClearValue &getClearDepthStencilValue() const;
VkColorComponentFlags getClearColorMask() const; VkColorComponentFlags getClearColorMask() const;
const VkRect2D &getScissor() const { return mPipelineDesc->getScissor(); } const VkRect2D &getScissor() const { return mScissor; }
gl::Error getIncompleteTexture(const gl::Context *context, gl::Error getIncompleteTexture(const gl::Context *context,
gl::TextureType type, gl::TextureType type,
gl::Texture **textureOut); gl::Texture **textureOut);
...@@ -191,6 +191,8 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -191,6 +191,8 @@ class ContextVk : public ContextImpl, public vk::Context
DIRTY_BIT_INDEX_BUFFER, DIRTY_BIT_INDEX_BUFFER,
DIRTY_BIT_DRIVER_UNIFORMS, DIRTY_BIT_DRIVER_UNIFORMS,
DIRTY_BIT_DESCRIPTOR_SETS, DIRTY_BIT_DESCRIPTOR_SETS,
DIRTY_BIT_VIEWPORT,
DIRTY_BIT_SCISSOR,
DIRTY_BIT_MAX, DIRTY_BIT_MAX,
}; };
...@@ -224,13 +226,20 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -224,13 +226,20 @@ class ContextVk : public ContextImpl, public vk::Context
const void *indices, const void *indices,
vk::CommandBuffer **commandBufferOut); vk::CommandBuffer **commandBufferOut);
void updateScissor(const gl::State &glState) const; void updateViewport(FramebufferVk *framebufferVk,
const gl::Rectangle &viewport,
float nearPlane,
float farPlane,
bool invertViewport);
void updateDepthRange(float nearPlane, float farPlane);
void updateScissor(const gl::State &glState);
void updateFlipViewportDrawFramebuffer(const gl::State &glState); void updateFlipViewportDrawFramebuffer(const gl::State &glState);
void updateFlipViewportReadFramebuffer(const gl::State &glState); void updateFlipViewportReadFramebuffer(const gl::State &glState);
angle::Result updateActiveTextures(const gl::Context *context); angle::Result updateActiveTextures(const gl::Context *context);
angle::Result updateDefaultAttribute(size_t attribIndex); angle::Result updateDefaultAttribute(size_t attribIndex);
void invalidateCurrentPipeline();
void invalidateCurrentTextures(); void invalidateCurrentTextures();
void invalidateDriverUniforms(); void invalidateDriverUniforms();
...@@ -246,6 +255,8 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -246,6 +255,8 @@ class ContextVk : public ContextImpl, public vk::Context
vk::CommandBuffer *commandBuffer); vk::CommandBuffer *commandBuffer);
angle::Result handleDirtyDescriptorSets(const gl::Context *context, angle::Result handleDirtyDescriptorSets(const gl::Context *context,
vk::CommandBuffer *commandBuffer); vk::CommandBuffer *commandBuffer);
angle::Result handleDirtyViewport(const gl::Context *context, vk::CommandBuffer *commandBuffer);
angle::Result handleDirtyScissor(const gl::Context *context, vk::CommandBuffer *commandBuffer);
vk::PipelineAndSerial *mCurrentPipeline; vk::PipelineAndSerial *mCurrentPipeline;
gl::PrimitiveMode mCurrentDrawMode; gl::PrimitiveMode mCurrentDrawMode;
...@@ -316,6 +327,10 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -316,6 +327,10 @@ class ContextVk : public ContextImpl, public vk::Context
// "Current Value" aka default vertex attribute state. // "Current Value" aka default vertex attribute state.
gl::AttributesMask mDirtyDefaultAttribsMask; gl::AttributesMask mDirtyDefaultAttribsMask;
gl::AttribArray<vk::DynamicBuffer> mDefaultAttribBuffers; gl::AttribArray<vk::DynamicBuffer> mDefaultAttribBuffers;
// Viewport and scissor are handled as dynamic state.
VkViewport mViewport;
VkRect2D mScissor;
}; };
} // namespace rx } // namespace rx
......
...@@ -776,7 +776,7 @@ angle::Result FramebufferVk::syncState(const gl::Context *context, ...@@ -776,7 +776,7 @@ angle::Result FramebufferVk::syncState(const gl::Context *context,
// create a new entry in the command graph. // create a new entry in the command graph.
mFramebuffer.finishCurrentCommands(renderer); mFramebuffer.finishCurrentCommands(renderer);
contextVk->invalidateCurrentPipeline(); // No need to notify the ContextVk. A new command buffer will be started automatically.
return angle::Result::Continue(); return angle::Result::Continue();
} }
...@@ -1027,23 +1027,6 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk, ...@@ -1027,23 +1027,6 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
pipelineDesc.updateColorWriteMask(colorMaskFlags, getEmulatedAlphaAttachmentMask()); pipelineDesc.updateColorWriteMask(colorMaskFlags, getEmulatedAlphaAttachmentMask());
pipelineDesc.updateRenderPassDesc(getRenderPassDesc()); pipelineDesc.updateRenderPassDesc(getRenderPassDesc());
pipelineDesc.updateShaders(fullScreenQuad->getSerial(), pushConstantColor->getSerial()); pipelineDesc.updateShaders(fullScreenQuad->getSerial(), pushConstantColor->getSerial());
pipelineDesc.updateViewport(this, renderArea, 0.0f, 1.0f, invertViewport);
const gl::State &glState = contextVk->getGLState();
if (glState.isScissorTestEnabled())
{
gl::Rectangle intersection;
if (!gl::ClipRectangle(glState.getScissor(), renderArea, &intersection))
{
return angle::Result::Continue();
}
pipelineDesc.updateScissor(intersection, invertViewport, renderArea);
}
else
{
pipelineDesc.updateScissor(renderArea, invertViewport, renderArea);
}
vk::PipelineAndSerial *pipeline = nullptr; vk::PipelineAndSerial *pipeline = nullptr;
ANGLE_TRY(renderer->getPipeline(contextVk, *fullScreenQuad, *pushConstantColor, ANGLE_TRY(renderer->getPipeline(contextVk, *fullScreenQuad, *pushConstantColor,
...@@ -1072,6 +1055,18 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk, ...@@ -1072,6 +1055,18 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
// TODO(jmadill): Masked combined color and depth/stencil clear. http://anglebug.com/2455 // TODO(jmadill): Masked combined color and depth/stencil clear. http://anglebug.com/2455
// Any active queries submitted by the user should also be paused here. // Any active queries submitted by the user should also be paused here.
drawCommands->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->get()); drawCommands->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->get());
GLint renderAreaHeight = mState.getDimensions().height;
VkViewport viewport;
gl_vk::GetViewport(renderArea, 0.0f, 1.0f, invertViewport, renderAreaHeight, &viewport);
drawCommands->setViewport(0, 1, &viewport);
VkRect2D scissor;
const gl::State &glState = contextVk->getGLState();
gl_vk::GetScissor(glState, invertViewport, renderArea, &scissor);
drawCommands->setScissor(0, 1, &scissor);
drawCommands->draw(6, 1, 0, 0); drawCommands->draw(6, 1, 0, 0);
return angle::Result::Continue(); return angle::Result::Continue();
......
...@@ -212,14 +212,14 @@ void VertexArrayVk::ensureConversionReleased(RendererVk *renderer, size_t attrib ...@@ -212,14 +212,14 @@ void VertexArrayVk::ensureConversionReleased(RendererVk *renderer, size_t attrib
case gl::VertexArray::DIRTY_BIT_ATTRIB_0 + INDEX: \ case gl::VertexArray::DIRTY_BIT_ATTRIB_0 + INDEX: \
ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \ ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
bindings[attribs[INDEX].bindingIndex], INDEX)); \ bindings[attribs[INDEX].bindingIndex], INDEX)); \
invalidatePipeline = true; \ invalidateContext = true; \
break; break;
#define ANGLE_VERTEX_DIRTY_BINDING_FUNC(INDEX) \ #define ANGLE_VERTEX_DIRTY_BINDING_FUNC(INDEX) \
case gl::VertexArray::DIRTY_BIT_BINDING_0 + INDEX: \ case gl::VertexArray::DIRTY_BIT_BINDING_0 + INDEX: \
ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \ ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
bindings[attribs[INDEX].bindingIndex], INDEX)); \ bindings[attribs[INDEX].bindingIndex], INDEX)); \
invalidatePipeline = true; \ invalidateContext = true; \
break; break;
#define ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC(INDEX) \ #define ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC(INDEX) \
...@@ -235,7 +235,7 @@ angle::Result VertexArrayVk::syncState(const gl::Context *context, ...@@ -235,7 +235,7 @@ angle::Result VertexArrayVk::syncState(const gl::Context *context,
{ {
ASSERT(dirtyBits.any()); ASSERT(dirtyBits.any());
bool invalidatePipeline = false; bool invalidateContext = false;
ContextVk *contextVk = vk::GetImpl(context); ContextVk *contextVk = vk::GetImpl(context);
...@@ -288,9 +288,9 @@ angle::Result VertexArrayVk::syncState(const gl::Context *context, ...@@ -288,9 +288,9 @@ angle::Result VertexArrayVk::syncState(const gl::Context *context,
} }
} }
if (invalidatePipeline) if (invalidateContext)
{ {
contextVk->invalidateCurrentPipeline(); contextVk->invalidateVertexAndIndexBuffers();
} }
return angle::Result::Continue(); return angle::Result::Continue();
......
...@@ -558,9 +558,9 @@ angle::Result PipelineDesc::initializePipeline(vk::Context *context, ...@@ -558,9 +558,9 @@ angle::Result PipelineDesc::initializePipeline(vk::Context *context,
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
viewportState.flags = 0; viewportState.flags = 0;
viewportState.viewportCount = 1; viewportState.viewportCount = 1;
viewportState.pViewports = &mViewport; viewportState.pViewports = nullptr;
viewportState.scissorCount = 1; viewportState.scissorCount = 1;
viewportState.pScissors = &mScissor; viewportState.pScissors = nullptr;
const PackedRasterizationAndMultisampleStateInfo &rasterAndMS = const PackedRasterizationAndMultisampleStateInfo &rasterAndMS =
mRasterizationAndMultisampleStateInfo; mRasterizationAndMultisampleStateInfo;
...@@ -639,7 +639,13 @@ angle::Result PipelineDesc::initializePipeline(vk::Context *context, ...@@ -639,7 +639,13 @@ angle::Result PipelineDesc::initializePipeline(vk::Context *context,
UnpackBlendAttachmentState(inputAndBlend.attachments[colorIndex], &state); UnpackBlendAttachmentState(inputAndBlend.attachments[colorIndex], &state);
} }
// TODO(jmadill): Dynamic 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();
createInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
createInfo.flags = 0; createInfo.flags = 0;
...@@ -653,7 +659,7 @@ angle::Result PipelineDesc::initializePipeline(vk::Context *context, ...@@ -653,7 +659,7 @@ angle::Result PipelineDesc::initializePipeline(vk::Context *context,
createInfo.pMultisampleState = &multisampleState; createInfo.pMultisampleState = &multisampleState;
createInfo.pDepthStencilState = &depthStencilState; createInfo.pDepthStencilState = &depthStencilState;
createInfo.pColorBlendState = &blendState; createInfo.pColorBlendState = &blendState;
createInfo.pDynamicState = nullptr; createInfo.pDynamicState = &dynamicState;
createInfo.layout = pipelineLayout.getHandle(); createInfo.layout = pipelineLayout.getHandle();
createInfo.renderPass = compatibleRenderPass.getHandle(); createInfo.renderPass = compatibleRenderPass.getHandle();
createInfo.subpass = 0; createInfo.subpass = 0;
...@@ -680,35 +686,6 @@ void PipelineDesc::updateShaders(Serial vertexSerial, Serial fragmentSerial) ...@@ -680,35 +686,6 @@ void PipelineDesc::updateShaders(Serial vertexSerial, Serial fragmentSerial)
static_cast<uint32_t>(fragmentSerial.getValue()); static_cast<uint32_t>(fragmentSerial.getValue());
} }
void PipelineDesc::updateViewport(FramebufferVk *framebufferVk,
const gl::Rectangle &viewport,
float nearPlane,
float farPlane,
bool invertViewport)
{
mViewport.x = static_cast<float>(viewport.x);
mViewport.y = static_cast<float>(viewport.y);
mViewport.width = static_cast<float>(viewport.width);
mViewport.height = static_cast<float>(viewport.height);
if (invertViewport)
{
gl::Box dimensions = framebufferVk->getState().getDimensions();
gl::Rectangle renderArea = gl::Rectangle(0, 0, dimensions.width, dimensions.height);
mViewport.y = static_cast<float>(renderArea.height - viewport.y);
mViewport.height = -mViewport.height;
}
updateDepthRange(nearPlane, farPlane);
}
void PipelineDesc::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);
}
void PipelineDesc::updateVertexInputInfo(const VertexInputBindings &bindings, void PipelineDesc::updateVertexInputInfo(const VertexInputBindings &bindings,
const VertexInputAttributes &attribs) const VertexInputAttributes &attribs)
{ {
...@@ -893,17 +870,6 @@ void PipelineDesc::updateRenderPassDesc(const RenderPassDesc &renderPassDesc) ...@@ -893,17 +870,6 @@ void PipelineDesc::updateRenderPassDesc(const RenderPassDesc &renderPassDesc)
mRenderPassDesc = renderPassDesc; mRenderPassDesc = renderPassDesc;
} }
void PipelineDesc::updateScissor(const gl::Rectangle &rect,
bool invertScissor,
const gl::Rectangle &renderArea)
{
mScissor = gl_vk::GetRect(rect);
if (invertScissor)
{
mScissor.offset.y = renderArea.height - mScissor.offset.y - mScissor.extent.height;
}
}
// AttachmentOpsArray implementation. // AttachmentOpsArray implementation.
AttachmentOpsArray::AttachmentOpsArray() AttachmentOpsArray::AttachmentOpsArray()
{ {
......
...@@ -269,13 +269,6 @@ class PipelineDesc final ...@@ -269,13 +269,6 @@ class PipelineDesc final
const ShaderModule &fragmentModule, const ShaderModule &fragmentModule,
Pipeline *pipelineOut) const; Pipeline *pipelineOut) const;
void updateViewport(FramebufferVk *framebufferVk,
const gl::Rectangle &viewport,
float nearPlane,
float farPlane,
bool invertViewport);
void updateDepthRange(float nearPlane, float farPlane);
// Shader stage info // Shader stage info
const ShaderStageInfo &getShaderStageInfo() const; const ShaderStageInfo &getShaderStageInfo() const;
void updateShaders(Serial vertexSerial, Serial fragmentSerial); void updateShaders(Serial vertexSerial, Serial fragmentSerial);
...@@ -296,12 +289,6 @@ class PipelineDesc final ...@@ -296,12 +289,6 @@ class PipelineDesc final
const RenderPassDesc &getRenderPassDesc() const; const RenderPassDesc &getRenderPassDesc() const;
void updateRenderPassDesc(const RenderPassDesc &renderPassDesc); void updateRenderPassDesc(const RenderPassDesc &renderPassDesc);
// Scissor support
const VkRect2D &getScissor() const { return mScissor; }
void updateScissor(const gl::Rectangle &rect,
bool invertScissor,
const gl::Rectangle &renderArea);
// Blend states // Blend states
void updateBlendEnabled(bool isBlendEnabled); void updateBlendEnabled(bool isBlendEnabled);
void updateBlendColor(const gl::ColorF &color); void updateBlendColor(const gl::ColorF &color);
...@@ -332,7 +319,7 @@ class PipelineDesc final ...@@ -332,7 +319,7 @@ class PipelineDesc final
void updatePolygonOffset(const gl::RasterizerState &rasterState); void updatePolygonOffset(const gl::RasterizerState &rasterState);
private: private:
// TODO(jmadill): Use gl::ShaderMap when we can pack into fewer bits. http://anglebug.com/2522 // We can consider storing the shader stage info
ShaderStageInfo mShaderStageInfo; ShaderStageInfo mShaderStageInfo;
VertexInputBindings mVertexInputBindings; VertexInputBindings mVertexInputBindings;
VertexInputAttributes mVertexInputAttribs; VertexInputAttributes mVertexInputAttribs;
...@@ -340,11 +327,7 @@ class PipelineDesc final ...@@ -340,11 +327,7 @@ class PipelineDesc final
PackedRasterizationAndMultisampleStateInfo mRasterizationAndMultisampleStateInfo; PackedRasterizationAndMultisampleStateInfo mRasterizationAndMultisampleStateInfo;
PackedDepthStencilStateInfo mDepthStencilStateInfo; PackedDepthStencilStateInfo mDepthStencilStateInfo;
PackedInputAssemblyAndColorBlendStateInfo mInputAssembltyAndColorBlendStateInfo; PackedInputAssemblyAndColorBlendStateInfo mInputAssembltyAndColorBlendStateInfo;
// TODO(jmadill): Consider using dynamic state for viewport/scissor. // Viewport and scissor are applied as dynamic state.
VkViewport mViewport;
VkRect2D mScissor;
// TODO(jmadill): Dynamic state.
// TODO(jmadill): Pipeline layout
}; };
// Verify the packed pipeline description has no gaps in the packing. // Verify the packed pipeline description has no gaps in the packing.
...@@ -353,9 +336,8 @@ class PipelineDesc final ...@@ -353,9 +336,8 @@ class PipelineDesc final
// into uninitialized memory regions. // into uninitialized memory regions.
constexpr size_t kPipelineDescSumOfSizes = constexpr size_t kPipelineDescSumOfSizes =
kShaderStageInfoSize + kVertexInputBindingsSize + kVertexInputAttributesSize + kShaderStageInfoSize + kVertexInputBindingsSize + kVertexInputAttributesSize +
kPackedInputAssemblyAndColorBlendStateSize + sizeof(VkViewport) + sizeof(VkRect2D) + kPackedInputAssemblyAndColorBlendStateSize + kPackedRasterizationAndMultisampleStateSize +
kPackedRasterizationAndMultisampleStateSize + kPackedDepthStencilStateSize + kPackedDepthStencilStateSize + kRenderPassDescSize;
kRenderPassDescSize;
static constexpr size_t kPipelineDescSize = sizeof(PipelineDesc); static constexpr size_t kPipelineDescSize = sizeof(PipelineDesc);
static_assert(kPipelineDescSize == kPipelineDescSumOfSizes, "Size mismatch"); static_assert(kPipelineDescSize == kPipelineDescSumOfSizes, "Size mismatch");
......
...@@ -33,6 +33,11 @@ VkImageUsageFlags GetStagingBufferUsageFlags(rx::vk::StagingUsage usage) ...@@ -33,6 +33,11 @@ VkImageUsageFlags GetStagingBufferUsageFlags(rx::vk::StagingUsage usage)
return 0; return 0;
} }
} }
constexpr gl::Rectangle kMaxSizedScissor(0,
0,
std::numeric_limits<int>::max(),
std::numeric_limits<int>::max());
} // anonymous namespace } // anonymous namespace
namespace angle namespace angle
...@@ -620,6 +625,22 @@ void CommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage, ...@@ -620,6 +625,22 @@ void CommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage,
vkCmdWriteTimestamp(mHandle, pipelineStage, queryPool, query); vkCmdWriteTimestamp(mHandle, pipelineStage, queryPool, query);
} }
void CommandBuffer::setViewport(uint32_t firstViewport,
uint32_t viewportCount,
const VkViewport *viewports)
{
ASSERT(valid());
vkCmdSetViewport(mHandle, firstViewport, viewportCount, viewports);
}
void CommandBuffer::setScissor(uint32_t firstScissor,
uint32_t scissorCount,
const VkRect2D *scissors)
{
ASSERT(valid());
vkCmdSetScissor(mHandle, firstScissor, scissorCount, scissors);
}
// Image implementation. // Image implementation.
Image::Image() Image::Image()
{ {
...@@ -1574,5 +1595,57 @@ VkColorComponentFlags GetColorComponentFlags(bool red, bool green, bool blue, bo ...@@ -1574,5 +1595,57 @@ VkColorComponentFlags GetColorComponentFlags(bool red, bool green, bool blue, bo
return (red ? VK_COLOR_COMPONENT_R_BIT : 0) | (green ? VK_COLOR_COMPONENT_G_BIT : 0) | return (red ? VK_COLOR_COMPONENT_R_BIT : 0) | (green ? VK_COLOR_COMPONENT_G_BIT : 0) |
(blue ? VK_COLOR_COMPONENT_B_BIT : 0) | (alpha ? VK_COLOR_COMPONENT_A_BIT : 0); (blue ? VK_COLOR_COMPONENT_B_BIT : 0) | (alpha ? VK_COLOR_COMPONENT_A_BIT : 0);
} }
void GetViewport(const gl::Rectangle &viewport,
float nearPlane,
float farPlane,
bool invertViewport,
GLint renderAreaHeight,
VkViewport *viewportOut)
{
viewportOut->x = static_cast<float>(viewport.x);
viewportOut->y = static_cast<float>(viewport.y);
viewportOut->width = static_cast<float>(viewport.width);
viewportOut->height = static_cast<float>(viewport.height);
viewportOut->minDepth = gl::clamp01(nearPlane);
viewportOut->maxDepth = gl::clamp01(farPlane);
if (invertViewport)
{
viewportOut->y = static_cast<float>(renderAreaHeight - viewport.y);
viewportOut->height = -viewportOut->height;
}
}
void GetScissor(const gl::State &glState,
bool invertViewport,
const gl::Rectangle &renderArea,
VkRect2D *scissorOut)
{
if (glState.isScissorTestEnabled())
{
gl::Rectangle clippedRect;
if (!gl::ClipRectangle(glState.getScissor(), renderArea, &clippedRect))
{
memset(scissorOut, 0, sizeof(VkRect2D));
return;
}
*scissorOut = gl_vk::GetRect(clippedRect);
if (invertViewport)
{
scissorOut->offset.y =
renderArea.height - scissorOut->offset.y - scissorOut->extent.height;
}
}
else
{
// If the scissor test isn't enabled, we can simply use a really big scissor that's
// certainly larger than the current surface using the maximum size of a 2D texture
// for the width and height.
*scissorOut = gl_vk::GetRect(kMaxSizedScissor);
}
}
} // namespace gl_vk } // namespace gl_vk
} // namespace rx } // namespace rx
...@@ -42,6 +42,7 @@ struct Box; ...@@ -42,6 +42,7 @@ struct Box;
struct Extents; struct Extents;
struct RasterizerState; struct RasterizerState;
struct Rectangle; struct Rectangle;
class State;
struct SwizzleState; struct SwizzleState;
struct VertexAttribute; struct VertexAttribute;
class VertexBinding; class VertexBinding;
...@@ -441,6 +442,9 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer> ...@@ -441,6 +442,9 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
void writeTimestamp(VkPipelineStageFlagBits pipelineStage, void writeTimestamp(VkPipelineStageFlagBits pipelineStage,
VkQueryPool queryPool, VkQueryPool queryPool,
uint32_t query); uint32_t query);
void setViewport(uint32_t firstViewport, uint32_t viewportCount, const VkViewport *viewports);
void setScissor(uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *scissors);
}; };
class Image final : public WrappedObject<Image, VkImage> class Image final : public WrappedObject<Image, VkImage>
...@@ -862,8 +866,6 @@ class BindingPointer final : angle::NonCopyable ...@@ -862,8 +866,6 @@ class BindingPointer final : angle::NonCopyable
private: private:
RefCounted<T> *mRefCounted; RefCounted<T> *mRefCounted;
}; };
using SharedDescriptorPool = RefCounted<DescriptorPool>;
} // namespace vk } // namespace vk
namespace gl_vk namespace gl_vk
...@@ -883,6 +885,17 @@ void GetExtent(const gl::Extents &glExtent, VkExtent3D *vkExtent); ...@@ -883,6 +885,17 @@ void GetExtent(const gl::Extents &glExtent, VkExtent3D *vkExtent);
VkImageType GetImageType(gl::TextureType textureType); VkImageType GetImageType(gl::TextureType textureType);
VkImageViewType GetImageViewType(gl::TextureType textureType); VkImageViewType GetImageViewType(gl::TextureType textureType);
VkColorComponentFlags GetColorComponentFlags(bool red, bool green, bool blue, bool alpha); VkColorComponentFlags GetColorComponentFlags(bool red, bool green, bool blue, bool alpha);
void GetViewport(const gl::Rectangle &viewport,
float nearPlane,
float farPlane,
bool invertViewport,
GLint renderAreaHeight,
VkViewport *viewportOut);
void GetScissor(const gl::State &glState,
bool invertViewport,
const gl::Rectangle &renderArea,
VkRect2D *scissorOut);
} // namespace gl_vk } // namespace gl_vk
} // namespace rx } // namespace rx
......
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