Commit 130597e1 by Charlie Lao Committed by Commit Bot

Vulkan: Use PackedScissor struct to reduce GraphicsPipelineDesc size

We are running out of space in GraphicsPipelineDesc. According to gpuinfo, the max reported viewport size is 32768. This CL changes scissor's x/y/w/h from uint32_t to uint16_t, which saves two uint32_t for other usages. Bug: b/173800146 Change-Id: Icf2d8ba8ea8a8c412ecef2059401a8d831c410e4 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2557218 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 3efa290d
......@@ -31,12 +31,9 @@ namespace vk
namespace
{
constexpr int32_t kDynamicScissorSentinel = std::numeric_limits<int32_t>::min();
bool IsScissorStateDynamic(const VkRect2D &scissor)
bool IsScissorStateDynamic(const PackedScissor &scissor)
{
return scissor.offset.x == kDynamicScissorSentinel;
return scissor.x == kDynamicScissorSentinel;
}
uint8_t PackGLBlendOp(GLenum blendOp)
......@@ -1596,10 +1593,10 @@ void GraphicsPipelineDesc::initDefaults()
mViewport.minDepth = 0.0f;
mViewport.maxDepth = 1.0f;
mScissor.offset.x = 0;
mScissor.offset.y = 0;
mScissor.extent.width = 0;
mScissor.extent.height = 0;
mScissor.x = 0;
mScissor.y = 0;
mScissor.width = 0;
mScissor.height = 0;
}
angle::Result GraphicsPipelineDesc::initializePipeline(
......@@ -1771,8 +1768,21 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
viewportState.flags = 0;
viewportState.viewportCount = 1;
viewportState.pViewports = &viewport;
viewportState.scissorCount = 1;
viewportState.pScissors = IsScissorStateDynamic(mScissor) ? nullptr : &mScissor;
viewportState.scissorCount = 1;
VkRect2D scissor;
if (IsScissorStateDynamic(mScissor))
{
viewportState.pScissors = nullptr;
}
else
{
viewportState.pScissors = &scissor;
scissor.offset.x = mScissor.x;
scissor.offset.y = mScissor.y;
scissor.extent.width = mScissor.width;
scissor.extent.height = mScissor.height;
}
const PackedRasterizationAndMultisampleStateInfo &rasterAndMS =
mRasterizationAndMultisampleStateInfo;
......@@ -2433,25 +2443,32 @@ void GraphicsPipelineDesc::updateDepthRange(GraphicsPipelineTransitionBits *tran
void GraphicsPipelineDesc::setDynamicScissor()
{
mScissor.offset.x = kDynamicScissorSentinel;
mScissor.offset.y = 0;
mScissor.extent.width = 0;
mScissor.extent.height = 0;
mScissor.x = kDynamicScissorSentinel;
mScissor.y = 0;
mScissor.width = 0;
mScissor.height = 0;
}
void GraphicsPipelineDesc::setScissor(const VkRect2D &scissor)
{
mScissor = scissor;
ASSERT(scissor.offset.x < kDynamicScissorSentinel &&
scissor.offset.y < kDynamicScissorSentinel &&
scissor.extent.width < kDynamicScissorSentinel &&
scissor.extent.height < kDynamicScissorSentinel);
SetBitField(mScissor.x, scissor.offset.x);
SetBitField(mScissor.y, scissor.offset.y);
SetBitField(mScissor.width, scissor.extent.width);
SetBitField(mScissor.height, scissor.extent.height);
}
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));
setScissor(scissor);
transition->set(ANGLE_GET_TRANSITION_BIT(mScissor, x));
transition->set(ANGLE_GET_TRANSITION_BIT(mScissor, y));
transition->set(ANGLE_GET_TRANSITION_BIT(mScissor, width));
transition->set(ANGLE_GET_TRANSITION_BIT(mScissor, height));
}
void GraphicsPipelineDesc::updateSubpass(GraphicsPipelineTransitionBits *transition,
......
......@@ -527,6 +527,16 @@ struct PackedInputAssemblyAndColorBlendStateInfo final
PrimitiveState primitive;
};
struct PackedScissor final
{
uint16_t x;
uint16_t y;
uint16_t width;
uint16_t height;
};
// This is invalid value for PackedScissor.x. It is used to indicate scissor is a dynamic state
constexpr int32_t kDynamicScissorSentinel = std::numeric_limits<decltype(PackedScissor::x)>::max();
constexpr size_t kPackedInputAssemblyAndColorBlendStateSize =
sizeof(PackedInputAssemblyAndColorBlendStateInfo);
static_assert(kPackedInputAssemblyAndColorBlendStateSize == 56, "Size check failed");
......@@ -534,7 +544,7 @@ static_assert(kPackedInputAssemblyAndColorBlendStateSize == 56, "Size check fail
constexpr size_t kGraphicsPipelineDescSumOfSizes =
kVertexInputAttributesSize + kRenderPassDescSize + kPackedRasterizationAndMultisampleStateSize +
kPackedDepthStencilStateSize + kPackedInputAssemblyAndColorBlendStateSize + sizeof(VkViewport) +
sizeof(VkRect2D);
sizeof(PackedScissor);
// Number of dirty bits in the dirty bit set.
constexpr size_t kGraphicsPipelineDirtyBitBytes = 4;
......@@ -727,7 +737,7 @@ class GraphicsPipelineDesc final
VkViewport mViewport;
// The special value of .offset.x == INT_MIN for scissor implies dynamic scissor that needs to
// be set through vkCmdSetScissor.
VkRect2D mScissor;
PackedScissor mScissor;
};
// Verify the packed pipeline description has no gaps in the packing.
......
......@@ -17,6 +17,7 @@
#include "libANGLE/renderer/driver_utils.h"
#include "libANGLE/renderer/vulkan/DisplayVk.h"
#include "libANGLE/renderer/vulkan/RendererVk.h"
#include "libANGLE/renderer/vulkan/vk_cache_utils.h"
#include "vk_format_utils.h"
namespace
......@@ -278,6 +279,19 @@ GLint LimitToInt(const LargerInt physicalDeviceValue)
physicalDeviceValue, static_cast<LargerInt>(std::numeric_limits<int32_t>::max() / 2)));
}
template <typename LargerInt>
uint16_t LimitToDynamicScissorSentinelMinusOne(const LargerInt physicalDeviceValue)
{
static_assert(sizeof(LargerInt) >= sizeof(int32_t),
"Incorrect usage of LimitToDynamicScissorSentinelMinusOne");
// Limit to kDynamicScissorSentinel-1. This is used to pack drawable offset/dimension to
// uint16_t for space conservation. The UINT16_MAX is reserved for special value like
// kDynamicScissorSentinel.
return static_cast<uint16_t>(
std::min<int32_t>(physicalDeviceValue, vk::kDynamicScissorSentinel - 1));
}
void RendererVk::ensureCapsInitialized() const
{
if (mCapsInitialized)
......@@ -520,12 +534,16 @@ void RendererVk::ensureCapsInitialized() const
mNativeCaps.maxDrawBuffers =
std::min(limitsVk.maxColorAttachments, limitsVk.maxFragmentOutputAttachments);
mNativeCaps.maxFramebufferWidth = LimitToInt(limitsVk.maxFramebufferWidth);
mNativeCaps.maxFramebufferHeight = LimitToInt(limitsVk.maxFramebufferHeight);
mNativeCaps.maxColorAttachments = LimitToInt(limitsVk.maxColorAttachments);
mNativeCaps.maxViewportWidth = LimitToInt(limitsVk.maxViewportDimensions[0]);
mNativeCaps.maxViewportHeight = LimitToInt(limitsVk.maxViewportDimensions[1]);
mNativeCaps.maxSampleMaskWords = LimitToInt(limitsVk.maxSampleMaskWords);
mNativeCaps.maxFramebufferWidth =
LimitToDynamicScissorSentinelMinusOne(limitsVk.maxFramebufferWidth);
mNativeCaps.maxFramebufferHeight =
LimitToDynamicScissorSentinelMinusOne(limitsVk.maxFramebufferHeight);
mNativeCaps.maxColorAttachments = LimitToInt(limitsVk.maxColorAttachments);
mNativeCaps.maxViewportWidth =
LimitToDynamicScissorSentinelMinusOne(limitsVk.maxViewportDimensions[0]);
mNativeCaps.maxViewportHeight =
LimitToDynamicScissorSentinelMinusOne(limitsVk.maxViewportDimensions[1]);
mNativeCaps.maxSampleMaskWords = LimitToInt(limitsVk.maxSampleMaskWords);
mNativeCaps.maxColorTextureSamples =
limitsVk.sampledImageColorSampleCounts & vk_gl::kSupportedSampleCounts;
mNativeCaps.maxDepthTextureSamples =
......
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