Pack booleans inside struct LinkedUniform into bitfields

Right now every bool is load/stored as integer, which itself is a
memcpy. This CL moves them into a bitfield and load/store with one
uint32_t, thus improves efficiency of cache load/save.

Bug: b/275102061
Bug: angleproject:8223
Change-Id: Id8e8e8861c8fcbd75dbef6056e4ff6c8ad2fc4a1
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4740292
Commit-Queue: Charlie Lao <cclao@google.com>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Roman Lavrov <romanl@google.com>
This commit is contained in:
Charlie Lao
2023-08-01 12:10:44 -07:00
committed by Angle LUCI CQ
parent 0581a81c8f
commit 7bb132261a
5 changed files with 55 additions and 77 deletions

View File

@@ -374,18 +374,11 @@ void ProgramExecutable::load(bool isSeparable, gl::BinaryInputStream *stream)
stream->readString(&uniform.name);
stream->readString(&uniform.mappedName);
stream->readIntVector<unsigned int>(&uniform.arraySizes);
uniform.staticUse = stream->readBool();
uniform.active = stream->readBool();
uniform.isStruct = stream->readBool();
uniform.location = stream->readInt<int>();
uniform.binding = stream->readInt<int>();
uniform.imageUnitFormat = stream->readInt<GLenum>();
uniform.offset = stream->readInt<int>();
uniform.rasterOrdered = stream->readBool();
uniform.readonly = stream->readBool();
uniform.writeonly = stream->readBool();
uniform.isFragmentInOut = stream->readBool();
uniform.texelFetchStaticUse = stream->readBool();
uniform.flagBitsAsUInt = stream->readInt<unsigned int>();
uniform.location = stream->readInt<int>();
uniform.binding = stream->readInt<int>();
uniform.imageUnitFormat = stream->readInt<GLenum>();
uniform.offset = stream->readInt<int>();
uniform.setParentArrayIndex(stream->readInt<int>());
uniform.id = stream->readInt<uint32_t>();
@@ -625,18 +618,11 @@ void ProgramExecutable::save(bool isSeparable, gl::BinaryOutputStream *stream) c
stream->writeString(uniform.name);
stream->writeString(uniform.mappedName);
stream->writeIntVector(uniform.arraySizes);
stream->writeBool(uniform.staticUse);
stream->writeBool(uniform.active);
stream->writeBool(uniform.isStruct);
stream->writeInt(uniform.flagBitsAsUInt);
stream->writeInt(uniform.location);
stream->writeInt(uniform.binding);
stream->writeInt(uniform.imageUnitFormat);
stream->writeInt(uniform.offset);
stream->writeBool(uniform.rasterOrdered);
stream->writeBool(uniform.readonly);
stream->writeBool(uniform.writeonly);
stream->writeBool(uniform.isFragmentInOut);
stream->writeBool(uniform.texelFetchStaticUse);
stream->writeInt(uniform.getFlattenedOffsetInParentArrays());
stream->writeInt(uniform.id);
@@ -1620,9 +1606,9 @@ void ProgramExecutable::linkSamplerAndImageBindings(GLuint *combinedImageUniform
// Note that uniform block uniforms are not yet appended to this list.
ASSERT(mUniforms.empty() || highIter->isAtomicCounter() || highIter->isImage() ||
highIter->isSampler() || highIter->isInDefaultBlock() || highIter->isFragmentInOut);
highIter->isSampler() || highIter->isInDefaultBlock() || highIter->isFragmentInOut());
for (; lowIter != mUniforms.rend() && lowIter->isFragmentInOut; ++lowIter)
for (; lowIter != mUniforms.rend() && lowIter->isFragmentInOut(); ++lowIter)
{
--low;
}

View File

@@ -46,18 +46,11 @@ void ActiveVariable::unionReferencesWith(const ActiveVariable &other)
LinkedUniform::LinkedUniform()
: type(GL_NONE),
precision(0),
staticUse(false),
active(false),
isStruct(false),
flagBitsAsUInt(0),
location(-1),
binding(-1),
imageUnitFormat(GL_NONE),
offset(-1),
rasterOrdered(false),
readonly(false),
writeonly(false),
isFragmentInOut(false),
texelFetchStaticUse(false),
id(0),
flattenedOffsetInParentArrays(-1),
typeInfo(nullptr),
@@ -87,21 +80,14 @@ LinkedUniform::LinkedUniform(GLenum typeIn,
bufferIndex(bufferIndexIn),
blockInfo(blockInfoIn)
{
staticUse = false;
active = false;
isStruct = false;
rasterOrdered = false;
readonly = false;
writeonly = false;
isFragmentInOut = false;
texelFetchStaticUse = false;
flagBitsAsUInt = 0;
id = 0;
flattenedOffsetInParentArrays = -1;
outerArraySizeProduct = 1;
outerArrayOffset = 0;
imageUnitFormat = GL_NONE;
ASSERT(!isArrayOfArrays());
ASSERT(!isArray() || !isStruct);
ASSERT(!isArray() || !isStruct());
}
LinkedUniform::LinkedUniform(const LinkedUniform &other)
@@ -111,24 +97,26 @@ LinkedUniform::LinkedUniform(const LinkedUniform &other)
LinkedUniform::LinkedUniform(const UsedUniform &usedUniform)
{
type = usedUniform.type;
precision = usedUniform.precision;
name = usedUniform.name;
mappedName = usedUniform.mappedName;
arraySizes = usedUniform.arraySizes;
staticUse = usedUniform.staticUse;
active = usedUniform.active;
isStruct = usedUniform.isStruct();
type = usedUniform.type;
precision = usedUniform.precision;
name = usedUniform.name;
mappedName = usedUniform.mappedName;
arraySizes = usedUniform.arraySizes;
flagBits.staticUse = usedUniform.staticUse;
flagBits.active = usedUniform.active;
flagBits.isStruct = usedUniform.isStruct();
flagBits.rasterOrdered = usedUniform.rasterOrdered;
flagBits.readonly = usedUniform.readonly;
flagBits.writeonly = usedUniform.writeonly;
flagBits.isFragmentInOut = usedUniform.isFragmentInOut;
flagBits.texelFetchStaticUse = usedUniform.texelFetchStaticUse;
flattenedOffsetInParentArrays = usedUniform.getFlattenedOffsetInParentArrays();
location = usedUniform.location;
binding = usedUniform.binding;
imageUnitFormat = usedUniform.imageUnitFormat;
offset = usedUniform.offset;
rasterOrdered = usedUniform.rasterOrdered;
readonly = usedUniform.readonly;
writeonly = usedUniform.writeonly;
isFragmentInOut = usedUniform.isFragmentInOut;
texelFetchStaticUse = usedUniform.texelFetchStaticUse;
id = usedUniform.id;
activeVariable = usedUniform.activeVariable;
typeInfo = usedUniform.typeInfo;
@@ -145,20 +133,13 @@ LinkedUniform &LinkedUniform::operator=(const LinkedUniform &other)
name = other.name;
mappedName = other.mappedName;
arraySizes = other.arraySizes;
staticUse = other.staticUse;
active = other.active;
isStruct = other.isStruct;
flattenedOffsetInParentArrays = other.flattenedOffsetInParentArrays;
flagBitsAsUInt = other.flagBitsAsUInt;
location = other.location;
binding = other.binding;
imageUnitFormat = other.imageUnitFormat;
offset = other.offset;
rasterOrdered = other.rasterOrdered;
readonly = other.readonly;
writeonly = other.writeonly;
isFragmentInOut = other.isFragmentInOut;
texelFetchStaticUse = other.texelFetchStaticUse;
id = other.id;
flattenedOffsetInParentArrays = other.flattenedOffsetInParentArrays;
activeVariable = other.activeVariable;
typeInfo = other.typeInfo;
bufferIndex = other.bufferIndex;

View File

@@ -79,6 +79,10 @@ struct LinkedUniform
size_t getElementSize() const { return typeInfo->externalSize; }
size_t getElementComponents() const { return typeInfo->componentCount; }
bool isStruct() const { return flagBits.isStruct; }
bool isTexelFetchStaticUse() const { return flagBits.texelFetchStaticUse; }
bool isFragmentInOut() const { return flagBits.isFragmentInOut; }
bool isArrayOfArrays() const { return arraySizes.size() >= 2u; }
bool isArray() const { return !arraySizes.empty(); }
unsigned int getArraySizeProduct() const { return gl::ArraySizeProduct(arraySizes); }
@@ -86,7 +90,7 @@ struct LinkedUniform
unsigned int getBasicTypeElementCount() const
{
ASSERT(!isArrayOfArrays());
ASSERT(!isStruct || !isArray());
ASSERT(!isStruct() || !isArray());
if (isArray())
{
@@ -138,23 +142,29 @@ struct LinkedUniform
std::vector<unsigned int> arraySizes;
bool staticUse;
bool active;
union
{
struct
{
uint32_t staticUse : 1;
uint32_t active : 1;
uint32_t isStruct : 1;
uint32_t rasterOrdered : 1;
uint32_t readonly : 1;
uint32_t writeonly : 1;
uint32_t isFragmentInOut : 1;
uint32_t texelFetchStaticUse : 1;
uint32_t padding : 24;
} flagBits;
bool isStruct;
uint32_t flagBitsAsUInt;
};
int location;
int binding;
GLenum imageUnitFormat;
int offset;
bool rasterOrdered;
bool readonly;
bool writeonly;
bool isFragmentInOut;
bool texelFetchStaticUse;
uint32_t id;

View File

@@ -299,7 +299,7 @@ void ProgramVk::initDefaultUniformLayoutMapping(gl::ShaderMap<sh::BlockLayoutMap
{
const auto &uniform = uniforms[location.index];
if (uniform.isInDefaultBlock() && !uniform.isSampler() && !uniform.isImage() &&
!uniform.isFragmentInOut)
!uniform.isFragmentInOut())
{
std::string uniformName = uniform.name;
if (uniform.isArray())

View File

@@ -6017,15 +6017,16 @@ angle::Result DescriptorSetDescBuilder::updateFullActiveTextures(
// If emulating seamful cube mapping, use the fetch image view. This is
// basically the same image view as read, except it's a 2DArray view for
// cube maps.
const ImageView &imageView = textureVk->getFetchImageView(
context, samplerState.getSRGBDecode(), samplerUniform.texelFetchStaticUse);
const ImageView &imageView =
textureVk->getFetchImageView(context, samplerState.getSRGBDecode(),
samplerUniform.isTexelFetchStaticUse());
mHandles[infoIndex].imageView = imageView.getHandle();
}
else
{
const ImageView &imageView = textureVk->getReadImageView(
context, samplerState.getSRGBDecode(), samplerUniform.texelFetchStaticUse,
isSamplerExternalY2Y);
context, samplerState.getSRGBDecode(),
samplerUniform.isTexelFetchStaticUse(), isSamplerExternalY2Y);
mHandles[infoIndex].imageView = imageView.getHandle();
}
}