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,
}
}
constexpr gl::Rectangle kMaxSizedScissor(0,
0,
std::numeric_limits<int>::max(),
std::numeric_limits<int>::max());
constexpr VkColorComponentFlags kAllColorChannelsMask =
(VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT |
VK_COLOR_COMPONENT_A_BIT);
......@@ -123,7 +118,9 @@ ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer)
mDriverUniformsBuffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, sizeof(DriverUniforms) * 16),
mDriverUniformsDescriptorSet(VK_NULL_HANDLE),
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(&mClearDepthStencilValue, 0, sizeof(mClearDepthStencilValue));
......@@ -138,6 +135,8 @@ ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer)
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;
......@@ -146,6 +145,8 @@ ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer)
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;
}
......@@ -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.
if (mode != mCurrentDrawMode)
{
mCurrentPipeline = nullptr;
mDirtyBits.set(DIRTY_BIT_PIPELINE);
invalidateCurrentPipeline();
mCurrentDrawMode = mode;
}
......@@ -467,6 +467,20 @@ 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,
......@@ -636,25 +650,36 @@ void ContextVk::updateColorMask(const gl::BlendState &blendState)
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());
gl::Box dimensions = framebufferVk->getState().getDimensions();
gl::Rectangle renderArea(0, 0, dimensions.width, dimensions.height);
if (glState.isScissorTestEnabled())
{
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);
}
gl_vk::GetScissor(glState, isViewportFlipEnabledForDrawFBO(), renderArea, &mScissor);
mDirtyBits.set(DIRTY_BIT_SCISSOR);
}
angle::Result ContextVk::syncState(const gl::Context *context,
......@@ -663,7 +688,7 @@ angle::Result ContextVk::syncState(const gl::Context *context,
{
if (dirtyBits.any())
{
invalidateCurrentPipeline();
invalidateVertexAndIndexBuffers();
}
const gl::State &glState = context->getGLState();
......@@ -679,15 +704,12 @@ angle::Result ContextVk::syncState(const gl::Context *context,
case gl::State::DIRTY_BIT_VIEWPORT:
{
FramebufferVk *framebufferVk = vk::GetImpl(glState.getDrawFramebuffer());
mPipelineDesc->updateViewport(framebufferVk, glState.getViewport(),
glState.getNearPlane(), glState.getFarPlane(),
isViewportFlipEnabledForDrawFBO());
invalidateDriverUniforms();
updateViewport(framebufferVk, glState.getViewport(), glState.getNearPlane(),
glState.getFarPlane(), isViewportFlipEnabledForDrawFBO());
break;
}
case gl::State::DIRTY_BIT_DEPTH_RANGE:
mPipelineDesc->updateDepthRange(glState.getNearPlane(), glState.getFarPlane());
invalidateDriverUniforms();
updateDepthRange(glState.getNearPlane(), glState.getFarPlane());
break;
case gl::State::DIRTY_BIT_BLEND_ENABLED:
mPipelineDesc->updateBlendEnabled(glState.isBlendEnabled());
......@@ -810,9 +832,8 @@ angle::Result ContextVk::syncState(const gl::Context *context,
{
mDrawFramebuffer = vk::GetImpl(glState.getDrawFramebuffer());
updateFlipViewportDrawFramebuffer(glState);
mPipelineDesc->updateViewport(mDrawFramebuffer, glState.getViewport(),
glState.getNearPlane(), glState.getFarPlane(),
isViewportFlipEnabledForDrawFBO());
updateViewport(mDrawFramebuffer, glState.getViewport(), glState.getNearPlane(),
glState.getFarPlane(), isViewportFlipEnabledForDrawFBO());
updateColorMask(glState.getBlendState());
mPipelineDesc->updateCullMode(glState.getRasterizerState());
updateScissor(glState);
......@@ -826,7 +847,6 @@ angle::Result ContextVk::syncState(const gl::Context *context,
glState.getDrawFramebuffer());
mPipelineDesc->updateStencilBackWriteMask(glState.getDepthStencilState(),
glState.getDrawFramebuffer());
invalidateDriverUniforms();
break;
}
case gl::State::DIRTY_BIT_RENDERBUFFER_BINDING:
......@@ -1035,11 +1055,18 @@ std::vector<PathImpl *> ContextVk::createPaths(GLsizei)
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_INDEX_BUFFER);
}
void ContextVk::invalidateCurrentPipeline()
{
mDirtyBits.set(DIRTY_BIT_PIPELINE);
mDirtyBits.set(DIRTY_BIT_VIEWPORT);
mDirtyBits.set(DIRTY_BIT_SCISSOR);
mCurrentPipeline = nullptr;
}
......
......@@ -159,7 +159,7 @@ class ContextVk : public ContextImpl, public vk::Context
VkDevice getDevice() const;
const FeaturesVk &getFeatures() const;
void invalidateCurrentPipeline();
void invalidateVertexAndIndexBuffers();
void invalidateDefaultAttribute(size_t attribIndex);
void invalidateDefaultAttributes(const gl::AttributesMask &dirtyMask);
......@@ -169,7 +169,7 @@ class ContextVk : public ContextImpl, public vk::Context
const VkClearValue &getClearColorValue() const;
const VkClearValue &getClearDepthStencilValue() 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::TextureType type,
gl::Texture **textureOut);
......@@ -191,6 +191,8 @@ 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,
};
......@@ -224,13 +226,20 @@ class ContextVk : public ContextImpl, public vk::Context
const void *indices,
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 updateFlipViewportReadFramebuffer(const gl::State &glState);
angle::Result updateActiveTextures(const gl::Context *context);
angle::Result updateDefaultAttribute(size_t attribIndex);
void invalidateCurrentPipeline();
void invalidateCurrentTextures();
void invalidateDriverUniforms();
......@@ -246,6 +255,8 @@ 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::PipelineAndSerial *mCurrentPipeline;
gl::PrimitiveMode mCurrentDrawMode;
......@@ -316,6 +327,10 @@ 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
......
......@@ -776,7 +776,7 @@ angle::Result FramebufferVk::syncState(const gl::Context *context,
// create a new entry in the command graph.
mFramebuffer.finishCurrentCommands(renderer);
contextVk->invalidateCurrentPipeline();
// No need to notify the ContextVk. A new command buffer will be started automatically.
return angle::Result::Continue();
}
......@@ -1027,23 +1027,6 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
pipelineDesc.updateColorWriteMask(colorMaskFlags, getEmulatedAlphaAttachmentMask());
pipelineDesc.updateRenderPassDesc(getRenderPassDesc());
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;
ANGLE_TRY(renderer->getPipeline(contextVk, *fullScreenQuad, *pushConstantColor,
......@@ -1072,6 +1055,18 @@ angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
// 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.
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);
return angle::Result::Continue();
......
......@@ -212,14 +212,14 @@ void VertexArrayVk::ensureConversionReleased(RendererVk *renderer, size_t attrib
case gl::VertexArray::DIRTY_BIT_ATTRIB_0 + INDEX: \
ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
bindings[attribs[INDEX].bindingIndex], INDEX)); \
invalidatePipeline = true; \
invalidateContext = true; \
break;
#define ANGLE_VERTEX_DIRTY_BINDING_FUNC(INDEX) \
case gl::VertexArray::DIRTY_BIT_BINDING_0 + INDEX: \
ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
bindings[attribs[INDEX].bindingIndex], INDEX)); \
invalidatePipeline = true; \
invalidateContext = true; \
break;
#define ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC(INDEX) \
......@@ -235,7 +235,7 @@ angle::Result VertexArrayVk::syncState(const gl::Context *context,
{
ASSERT(dirtyBits.any());
bool invalidatePipeline = false;
bool invalidateContext = false;
ContextVk *contextVk = vk::GetImpl(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();
......
......@@ -558,9 +558,9 @@ angle::Result PipelineDesc::initializePipeline(vk::Context *context,
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
viewportState.flags = 0;
viewportState.viewportCount = 1;
viewportState.pViewports = &mViewport;
viewportState.pViewports = nullptr;
viewportState.scissorCount = 1;
viewportState.pScissors = &mScissor;
viewportState.pScissors = nullptr;
const PackedRasterizationAndMultisampleStateInfo &rasterAndMS =
mRasterizationAndMultisampleStateInfo;
......@@ -639,7 +639,13 @@ angle::Result PipelineDesc::initializePipeline(vk::Context *context,
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.flags = 0;
......@@ -653,7 +659,7 @@ angle::Result PipelineDesc::initializePipeline(vk::Context *context,
createInfo.pMultisampleState = &multisampleState;
createInfo.pDepthStencilState = &depthStencilState;
createInfo.pColorBlendState = &blendState;
createInfo.pDynamicState = nullptr;
createInfo.pDynamicState = &dynamicState;
createInfo.layout = pipelineLayout.getHandle();
createInfo.renderPass = compatibleRenderPass.getHandle();
createInfo.subpass = 0;
......@@ -680,35 +686,6 @@ void PipelineDesc::updateShaders(Serial vertexSerial, Serial fragmentSerial)
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,
const VertexInputAttributes &attribs)
{
......@@ -893,17 +870,6 @@ void PipelineDesc::updateRenderPassDesc(const RenderPassDesc &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::AttachmentOpsArray()
{
......
......@@ -269,13 +269,6 @@ class PipelineDesc final
const ShaderModule &fragmentModule,
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
const ShaderStageInfo &getShaderStageInfo() const;
void updateShaders(Serial vertexSerial, Serial fragmentSerial);
......@@ -296,12 +289,6 @@ class PipelineDesc final
const RenderPassDesc &getRenderPassDesc() const;
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
void updateBlendEnabled(bool isBlendEnabled);
void updateBlendColor(const gl::ColorF &color);
......@@ -332,7 +319,7 @@ class PipelineDesc final
void updatePolygonOffset(const gl::RasterizerState &rasterState);
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;
VertexInputBindings mVertexInputBindings;
VertexInputAttributes mVertexInputAttribs;
......@@ -340,11 +327,7 @@ class PipelineDesc final
PackedRasterizationAndMultisampleStateInfo mRasterizationAndMultisampleStateInfo;
PackedDepthStencilStateInfo mDepthStencilStateInfo;
PackedInputAssemblyAndColorBlendStateInfo mInputAssembltyAndColorBlendStateInfo;
// TODO(jmadill): Consider using dynamic state for viewport/scissor.
VkViewport mViewport;
VkRect2D mScissor;
// TODO(jmadill): Dynamic state.
// TODO(jmadill): Pipeline layout
// Viewport and scissor are applied as dynamic state.
};
// Verify the packed pipeline description has no gaps in the packing.
......@@ -353,9 +336,8 @@ class PipelineDesc final
// into uninitialized memory regions.
constexpr size_t kPipelineDescSumOfSizes =
kShaderStageInfoSize + kVertexInputBindingsSize + kVertexInputAttributesSize +
kPackedInputAssemblyAndColorBlendStateSize + sizeof(VkViewport) + sizeof(VkRect2D) +
kPackedRasterizationAndMultisampleStateSize + kPackedDepthStencilStateSize +
kRenderPassDescSize;
kPackedInputAssemblyAndColorBlendStateSize + kPackedRasterizationAndMultisampleStateSize +
kPackedDepthStencilStateSize + kRenderPassDescSize;
static constexpr size_t kPipelineDescSize = sizeof(PipelineDesc);
static_assert(kPipelineDescSize == kPipelineDescSumOfSizes, "Size mismatch");
......
......@@ -33,6 +33,11 @@ VkImageUsageFlags GetStagingBufferUsageFlags(rx::vk::StagingUsage usage)
return 0;
}
}
constexpr gl::Rectangle kMaxSizedScissor(0,
0,
std::numeric_limits<int>::max(),
std::numeric_limits<int>::max());
} // anonymous namespace
namespace angle
......@@ -620,6 +625,22 @@ void CommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage,
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::Image()
{
......@@ -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) |
(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 rx
......@@ -42,6 +42,7 @@ struct Box;
struct Extents;
struct RasterizerState;
struct Rectangle;
class State;
struct SwizzleState;
struct VertexAttribute;
class VertexBinding;
......@@ -441,6 +442,9 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
void writeTimestamp(VkPipelineStageFlagBits pipelineStage,
VkQueryPool queryPool,
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>
......@@ -862,8 +866,6 @@ class BindingPointer final : angle::NonCopyable
private:
RefCounted<T> *mRefCounted;
};
using SharedDescriptorPool = RefCounted<DescriptorPool>;
} // namespace vk
namespace gl_vk
......@@ -883,6 +885,17 @@ void GetExtent(const gl::Extents &glExtent, VkExtent3D *vkExtent);
VkImageType GetImageType(gl::TextureType textureType);
VkImageViewType GetImageViewType(gl::TextureType textureType);
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 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