Vulkan: Add specialization constants for surface rotation

This plumbing through the specialization constant for surface rotation
from ContextVk to pipeline program creation. It has not been used yet,
so expecting no real functional change. This CL also converts
lineRasterEmulation to use the same specialization constant path as
surface rotation.

Bug: b/171750979
Change-Id: Ic08c4f8bb576424d1752015e874d0977a58d78bb
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2508837
Commit-Queue: Charlie Lao <cclao@google.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Tim Van Patten <timvp@google.com>
Reviewed-by: Ian Elliott <ianelliott@google.com>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
This commit is contained in:
Charlie Lao 2020-10-29 15:50:39 -07:00 коммит произвёл Commit Bot
Родитель 9d65420c49
Коммит b22f8e8e6a
11 изменённых файлов: 145 добавлений и 71 удалений

Просмотреть файл

@ -26,7 +26,7 @@
// Version number for shader translation API.
// It is incremented every time the API changes.
#define ANGLE_SH_VERSION 238
#define ANGLE_SH_VERSION 239
enum ShShaderSpec
{
@ -774,9 +774,10 @@ namespace vk
enum class SpecializationConstantId : uint32_t
{
LineRasterEmulation = 0,
SurfaceRotation = 1,
InvalidEnum = 1,
EnumCount = 1,
InvalidEnum = 2,
EnumCount = InvalidEnum,
};
// Interface block name containing the aggregate default uniforms

Просмотреть файл

@ -3126,6 +3126,15 @@ void ContextVk::updateSurfaceRotationDrawFramebuffer(const gl::State &glState)
gl::Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
mCurrentRotationDrawFramebuffer =
DetermineSurfaceRotation(drawFramebuffer, mCurrentWindowSurface);
if (mCurrentRotationDrawFramebuffer != mGraphicsPipelineDesc->getSurfaceRotation())
{
// surface rotation are specialization constants, which affects program compilation. When
// rotation changes, we need to update GraphicsPipelineDesc so that the correct pipeline
// program object will be retrieved.
mGraphicsPipelineDesc->updateSurfaceRotation(&mGraphicsPipelineTransition,
mCurrentRotationDrawFramebuffer);
}
}
void ContextVk::updateSurfaceRotationReadFramebuffer(const gl::State &glState)

Просмотреть файл

@ -136,7 +136,7 @@ ProgramInfo::~ProgramInfo() = default;
angle::Result ProgramInfo::initProgram(ContextVk *contextVk,
const gl::ShaderType shaderType,
const ShaderInfo &shaderInfo,
ProgramTransformOptionBits optionBits,
ProgramTransformOptions optionBits,
ProgramExecutableVk *executableVk)
{
const ShaderMapInterfaceVariableInfoMap &variableInfoMap =
@ -144,8 +144,7 @@ angle::Result ProgramInfo::initProgram(ContextVk *contextVk,
const gl::ShaderMap<SpirvBlob> &originalSpirvBlobs = shaderInfo.getSpirvBlobs();
const SpirvBlob &originalSpirvBlob = originalSpirvBlobs[shaderType];
bool removeEarlyFragmentTestsOptimization =
(shaderType == gl::ShaderType::Fragment &&
optionBits[ProgramTransformOption::RemoveEarlyFragmentTestsOptimization]);
(shaderType == gl::ShaderType::Fragment && optionBits.removeEarlyFragmentTestsOptimization);
gl::ShaderMap<SpirvBlob> transformedSpirvBlobs;
SpirvBlob &transformedSpirvBlob = transformedSpirvBlobs[shaderType];
@ -158,11 +157,10 @@ angle::Result ProgramInfo::initProgram(ContextVk *contextVk,
mProgramHelper.setShader(shaderType, &mShaders[shaderType]);
if (optionBits[ProgramTransformOption::EnableLineRasterEmulation])
{
mProgramHelper.enableSpecializationConstant(
sh::vk::SpecializationConstantId::LineRasterEmulation);
}
mProgramHelper.setSpecializationConstant(sh::vk::SpecializationConstantId::LineRasterEmulation,
optionBits.enableLineRasterEmulation);
mProgramHelper.setSpecializationConstant(sh::vk::SpecializationConstantId::SurfaceRotation,
optionBits.surfaceRotation);
return angle::Result::Continue;
}
@ -202,7 +200,7 @@ void ProgramExecutableVk::reset(ContextVk *contextVk)
mDescriptorSets.fill(VK_NULL_HANDLE);
mEmptyDescriptorSets.fill(VK_NULL_HANDLE);
mNumDefaultUniformDescriptors = 0;
mTransformOptionBits.reset();
mTransformOptions = {};
for (vk::RefCountedDescriptorPoolBinding &binding : mDescriptorPoolBindings)
{
@ -655,14 +653,13 @@ void ProgramExecutableVk::updateEarlyFragmentTestsOptimization(ContextVk *contex
{
const gl::State &glState = contextVk->getState();
mTransformOptionBits[ProgramTransformOption::RemoveEarlyFragmentTestsOptimization] = false;
mTransformOptions.removeEarlyFragmentTestsOptimization = false;
if (!glState.canEnableEarlyFragmentTestsOptimization())
{
ProgramVk *programVk = getShaderProgram(glState, gl::ShaderType::Fragment);
if (programVk && programVk->getState().hasEarlyFragmentTestsOptimization())
{
mTransformOptionBits[ProgramTransformOption::RemoveEarlyFragmentTestsOptimization] =
true;
mTransformOptions.removeEarlyFragmentTestsOptimization = true;
}
}
}
@ -675,23 +672,25 @@ angle::Result ProgramExecutableVk::getGraphicsPipeline(
const vk::GraphicsPipelineDesc **descPtrOut,
vk::PipelineHelper **pipelineOut)
{
const gl::State &glState = contextVk->getState();
mTransformOptionBits[ProgramTransformOption::EnableLineRasterEmulation] =
contextVk->isBresenhamEmulationEnabled(mode);
ProgramInfo &programInfo = getGraphicsProgramInfo(mTransformOptionBits);
RendererVk *renderer = contextVk->getRenderer();
vk::PipelineCache *pipelineCache = nullptr;
const gl::State &glState = contextVk->getState();
RendererVk *renderer = contextVk->getRenderer();
vk::PipelineCache *pipelineCache = nullptr;
const gl::ProgramExecutable *glExecutable = glState.getProgramExecutable();
ASSERT(glExecutable && !glExecutable->isCompute());
mTransformOptions.enableLineRasterEmulation = contextVk->isBresenhamEmulationEnabled(mode);
mTransformOptions.surfaceRotation = static_cast<uint8_t>(desc.getSurfaceRotation());
// This must be called after mTransformOptions have been set.
ProgramInfo &programInfo = getGraphicsProgramInfo(mTransformOptions);
for (const gl::ShaderType shaderType : glExecutable->getLinkedShaderStages())
{
ProgramVk *programVk = getShaderProgram(glState, shaderType);
if (programVk)
{
ANGLE_TRY(programVk->initGraphicsShaderProgram(
contextVk, shaderType, mTransformOptionBits, &programInfo, this));
ANGLE_TRY(programVk->initGraphicsShaderProgram(contextVk, shaderType, mTransformOptions,
&programInfo, this));
}
}

Просмотреть файл

@ -11,6 +11,7 @@
#define LIBANGLE_RENDERER_VULKAN_PROGRAMEXECUTABLEVK_H_
#include "common/bitset_utils.h"
#include "common/mathutil.h"
#include "common/utilities.h"
#include "libANGLE/Context.h"
#include "libANGLE/InfoLog.h"
@ -47,14 +48,16 @@ class ShaderInfo final : angle::NonCopyable
bool mIsInitialized = false;
};
enum class ProgramTransformOption : uint8_t
struct ProgramTransformOptions final
{
EnableLineRasterEmulation = 0,
RemoveEarlyFragmentTestsOptimization = 1,
EnumCount = 2,
PermutationCount = 4,
uint8_t enableLineRasterEmulation : 1;
uint8_t removeEarlyFragmentTestsOptimization : 1;
uint8_t surfaceRotation : 3;
uint8_t reserved : 3; // must initialize to zero
static constexpr uint32_t kPermutationCount = 0x1 << 5;
};
using ProgramTransformOptionBits = angle::PackedEnumBitSet<ProgramTransformOption, uint8_t>;
static_assert(sizeof(ProgramTransformOptions) == 1, "Size check failed");
static_assert(static_cast<int>(SurfaceRotation::EnumCount) <= 8, "Size check failed");
class ProgramInfo final : angle::NonCopyable
{
@ -65,7 +68,7 @@ class ProgramInfo final : angle::NonCopyable
angle::Result initProgram(ContextVk *contextVk,
const gl::ShaderType shaderType,
const ShaderInfo &shaderInfo,
ProgramTransformOptionBits optionBits,
ProgramTransformOptions optionBits,
ProgramExecutableVk *executableVk);
void release(ContextVk *contextVk);
@ -119,9 +122,10 @@ class ProgramExecutableVk
const gl::ProgramExecutable &getGlExecutable();
ProgramInfo &getGraphicsDefaultProgramInfo() { return mGraphicsProgramInfos[0]; }
ProgramInfo &getGraphicsProgramInfo(ProgramTransformOptionBits optionBits)
ProgramInfo &getGraphicsProgramInfo(ProgramTransformOptions option)
{
return mGraphicsProgramInfos[optionBits.to_ulong()];
uint8_t index = gl::bitCast<uint8_t, ProgramTransformOptions>(option);
return mGraphicsProgramInfos[index];
}
ProgramInfo &getComputeProgramInfo() { return mComputeProgramInfo; }
vk::BufferSerial getCurrentDefaultUniformBufferSerial() const
@ -264,10 +268,12 @@ class ProgramExecutableVk
// since that's slow to calculate.
ShaderMapInterfaceVariableInfoMap mVariableInfoMap;
ProgramInfo mGraphicsProgramInfos[static_cast<int>(ProgramTransformOption::PermutationCount)];
// We store all permutations of surface rotation and transformed SPIR-V programs here. We may
// need some LRU algorithm to free least used programs to reduce the number of programs.
ProgramInfo mGraphicsProgramInfos[ProgramTransformOptions::kPermutationCount];
ProgramInfo mComputeProgramInfo;
ProgramTransformOptionBits mTransformOptionBits;
ProgramTransformOptions mTransformOptions;
ProgramVk *mProgram;
ProgramPipelineVk *mProgramPipeline;

Просмотреть файл

@ -147,7 +147,7 @@ class ProgramVk : public ProgramImpl
ANGLE_INLINE angle::Result initGraphicsShaderProgram(ContextVk *contextVk,
const gl::ShaderType shaderType,
ProgramTransformOptionBits optionBits,
ProgramTransformOptions optionBits,
ProgramInfo *programInfo,
ProgramExecutableVk *executableVk)
{
@ -158,7 +158,7 @@ class ProgramVk : public ProgramImpl
ProgramInfo *programInfo,
ProgramExecutableVk *executableVk)
{
ProgramTransformOptionBits optionBits;
ProgramTransformOptions optionBits = {};
return initProgram(contextVk, gl::ShaderType::Compute, optionBits, programInfo,
executableVk);
}
@ -192,7 +192,7 @@ class ProgramVk : public ProgramImpl
ANGLE_INLINE angle::Result initProgram(ContextVk *contextVk,
const gl::ShaderType shaderType,
ProgramTransformOptionBits optionBits,
ProgramTransformOptions optionBits,
ProgramInfo *programInfo,
ProgramExecutableVk *executableVk)
{

Просмотреть файл

@ -1184,26 +1184,37 @@ void GetRenderPassAndUpdateCounters(ContextVk *contextVk,
}
void InitializeSpecializationInfo(
vk::SpecializationConstantBitSet specConsts,
const vk::SpecializationConstants &specConsts,
vk::SpecializationConstantMap<VkSpecializationMapEntry> *specializationEntriesOut,
vk::SpecializationConstantMap<VkBool32> *specializationValuesOut,
VkSpecializationInfo *specializationInfoOut)
{
// Collect specialization constants.
for (const sh::vk::SpecializationConstantId id :
angle::AllEnums<sh::vk::SpecializationConstantId>())
{
const uint32_t offset = static_cast<uint32_t>(id);
(*specializationValuesOut)[id] = specConsts.test(id);
(*specializationEntriesOut)[id].constantID = offset;
(*specializationEntriesOut)[id].offset = offset;
(*specializationEntriesOut)[id].size = sizeof(VkBool32);
(*specializationEntriesOut)[id].constantID = static_cast<uint32_t>(id);
switch (id)
{
case sh::vk::SpecializationConstantId::LineRasterEmulation:
(*specializationEntriesOut)[id].offset =
offsetof(vk::SpecializationConstants, lineRasterEmulation);
(*specializationEntriesOut)[id].size = sizeof(specConsts.lineRasterEmulation);
break;
case sh::vk::SpecializationConstantId::SurfaceRotation:
(*specializationEntriesOut)[id].offset =
offsetof(vk::SpecializationConstants, surfaceRotation);
(*specializationEntriesOut)[id].size = sizeof(specConsts.surfaceRotation);
break;
default:
UNREACHABLE();
break;
}
}
specializationInfoOut->mapEntryCount = static_cast<uint32_t>(specializationEntriesOut->size());
specializationInfoOut->pMapEntries = specializationEntriesOut->data();
specializationInfoOut->dataSize = specializationEntriesOut->size() * sizeof(VkBool32);
specializationInfoOut->pData = specializationValuesOut->data();
specializationInfoOut->dataSize = sizeof(specConsts);
specializationInfoOut->pData = &specConsts;
}
// Utility for setting a value on a packed 4-bit integer array.
@ -1520,7 +1531,8 @@ void GraphicsPipelineDesc::initDefaults()
mDepthStencilStateInfo.enable.depthTest = 0;
mDepthStencilStateInfo.enable.depthWrite = 1;
SetBitField(mDepthStencilStateInfo.depthCompareOp, VK_COMPARE_OP_LESS);
SetBitField(mDepthStencilStateInfo.depthCompareOpAndSurfaceRotation.depthCompareOp,
VK_COMPARE_OP_LESS);
mDepthStencilStateInfo.enable.depthBoundsTest = 0;
mDepthStencilStateInfo.enable.stencilTest = 0;
mDepthStencilStateInfo.minDepthBounds = 0.0f;
@ -1540,6 +1552,9 @@ void GraphicsPipelineDesc::initDefaults()
SetBitField(mDepthStencilStateInfo.back.writeMask, 0xFF);
mDepthStencilStateInfo.backStencilReference = 0;
mDepthStencilStateInfo.depthCompareOpAndSurfaceRotation.surfaceRotation =
static_cast<uint8_t>(SurfaceRotation::Identity);
PackedInputAssemblyAndColorBlendStateInfo &inputAndBlend = mInputAssemblyAndColorBlendStateInfo;
inputAndBlend.logic.opEnable = 0;
inputAndBlend.logic.op = static_cast<uint32_t>(VK_LOGIC_OP_CLEAR);
@ -1597,7 +1612,7 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
const ShaderModule *vertexModule,
const ShaderModule *fragmentModule,
const ShaderModule *geometryModule,
vk::SpecializationConstantBitSet specConsts,
const vk::SpecializationConstants specConsts,
Pipeline *pipelineOut) const
{
angle::FixedVector<VkPipelineShaderStageCreateInfo, 3> shaderStages;
@ -1613,9 +1628,7 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
VkGraphicsPipelineCreateInfo createInfo = {};
vk::SpecializationConstantMap<VkSpecializationMapEntry> specializationEntries;
vk::SpecializationConstantMap<VkBool32> specializationValues;
InitializeSpecializationInfo(specConsts, &specializationEntries, &specializationValues,
&specializationInfo);
InitializeSpecializationInfo(specConsts, &specializationEntries, &specializationInfo);
// Vertex shader is always expected to be present.
ASSERT(vertexModule != nullptr);
@ -1829,8 +1842,8 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
static_cast<VkBool32>(mDepthStencilStateInfo.enable.depthTest);
depthStencilState.depthWriteEnable =
static_cast<VkBool32>(mDepthStencilStateInfo.enable.depthWrite);
depthStencilState.depthCompareOp =
static_cast<VkCompareOp>(mDepthStencilStateInfo.depthCompareOp);
depthStencilState.depthCompareOp = static_cast<VkCompareOp>(
mDepthStencilStateInfo.depthCompareOpAndSurfaceRotation.depthCompareOp);
depthStencilState.depthBoundsTestEnable =
static_cast<VkBool32>(mDepthStencilStateInfo.enable.depthBoundsTest);
depthStencilState.stencilTestEnable =
@ -2196,7 +2209,7 @@ void GraphicsPipelineDesc::setDepthWriteEnabled(bool enabled)
void GraphicsPipelineDesc::setDepthFunc(VkCompareOp op)
{
SetBitField(mDepthStencilStateInfo.depthCompareOp, op);
SetBitField(mDepthStencilStateInfo.depthCompareOpAndSurfaceRotation.depthCompareOp, op);
}
void GraphicsPipelineDesc::setDepthClampEnabled(bool enabled)
@ -2269,7 +2282,17 @@ void GraphicsPipelineDesc::updateDepthFunc(GraphicsPipelineTransitionBits *trans
const gl::DepthStencilState &depthStencilState)
{
setDepthFunc(PackGLCompareFunc(depthStencilState.depthFunc));
transition->set(ANGLE_GET_TRANSITION_BIT(mDepthStencilStateInfo, depthCompareOp));
transition->set(
ANGLE_GET_TRANSITION_BIT(mDepthStencilStateInfo, depthCompareOpAndSurfaceRotation));
}
void GraphicsPipelineDesc::updateSurfaceRotation(GraphicsPipelineTransitionBits *transition,
const SurfaceRotation surfaceRotation)
{
SetBitField(mDepthStencilStateInfo.depthCompareOpAndSurfaceRotation.surfaceRotation,
surfaceRotation);
transition->set(
ANGLE_GET_TRANSITION_BIT(mDepthStencilStateInfo, depthCompareOpAndSurfaceRotation));
}
void GraphicsPipelineDesc::updateDepthWriteEnabled(GraphicsPipelineTransitionBits *transition,
@ -3250,7 +3273,7 @@ angle::Result GraphicsPipelineCache::insertPipeline(
const vk::ShaderModule *vertexModule,
const vk::ShaderModule *fragmentModule,
const vk::ShaderModule *geometryModule,
vk::SpecializationConstantBitSet specConsts,
const vk::SpecializationConstants specConsts,
const vk::GraphicsPipelineDesc &desc,
const vk::GraphicsPipelineDesc **descPtrOut,
vk::PipelineHelper **pipelineOut)

Просмотреть файл

@ -458,12 +458,24 @@ struct DepthStencilEnableFlags final
constexpr size_t kDepthStencilEnableFlagsSize = sizeof(DepthStencilEnableFlags);
static_assert(kDepthStencilEnableFlagsSize == 1, "Size check failed");
// We are borrowing three bits here for surface rotation, even though it has nothing to do with
// depth stencil.
struct DepthCompareOpAndSurfaceRotation final
{
uint8_t depthCompareOp : 4;
uint8_t surfaceRotation : 3;
uint8_t padding : 1;
};
constexpr size_t kDepthCompareOpAndSurfaceRotationSize = sizeof(DepthCompareOpAndSurfaceRotation);
static_assert(kDepthCompareOpAndSurfaceRotationSize == 1, "Size check failed");
struct PackedDepthStencilStateInfo final
{
DepthStencilEnableFlags enable;
uint8_t frontStencilReference;
uint8_t backStencilReference;
uint8_t depthCompareOp; // only needs 4 bits. extra used as padding.
DepthCompareOpAndSurfaceRotation depthCompareOpAndSurfaceRotation;
float minDepthBounds;
float maxDepthBounds;
PackedStencilOpState front;
@ -472,6 +484,7 @@ struct PackedDepthStencilStateInfo final
constexpr size_t kPackedDepthStencilStateSize = sizeof(PackedDepthStencilStateInfo);
static_assert(kPackedDepthStencilStateSize == 20, "Size check failed");
static_assert(static_cast<int>(SurfaceRotation::EnumCount) <= 8, "Size check failed");
struct LogicOpState final
{
@ -569,7 +582,7 @@ class GraphicsPipelineDesc final
const ShaderModule *vertexModule,
const ShaderModule *fragmentModule,
const ShaderModule *geometryModule,
vk::SpecializationConstantBitSet specConsts,
const vk::SpecializationConstants specConsts,
Pipeline *pipelineOut) const;
// Vertex input state. For ES 3.1 this should be separated into binding and attribute.
@ -695,6 +708,14 @@ class GraphicsPipelineDesc final
void setSubpass(uint32_t subpass);
uint32_t getSubpass() const;
void updateSurfaceRotation(GraphicsPipelineTransitionBits *transition,
const SurfaceRotation surfaceRotation);
SurfaceRotation getSurfaceRotation() const
{
return static_cast<SurfaceRotation>(
mDepthStencilStateInfo.depthCompareOpAndSurfaceRotation.surfaceRotation);
}
private:
void updateSubpass(GraphicsPipelineTransitionBits *transition, uint32_t subpass);
@ -1334,7 +1355,7 @@ class GraphicsPipelineCache final : angle::NonCopyable
const vk::ShaderModule *vertexModule,
const vk::ShaderModule *fragmentModule,
const vk::ShaderModule *geometryModule,
vk::SpecializationConstantBitSet specConsts,
const vk::SpecializationConstants specConsts,
const vk::GraphicsPipelineDesc &desc,
const vk::GraphicsPipelineDesc **descPtrOut,
vk::PipelineHelper **pipelineOut)
@ -1363,7 +1384,7 @@ class GraphicsPipelineCache final : angle::NonCopyable
const vk::ShaderModule *vertexModule,
const vk::ShaderModule *fragmentModule,
const vk::ShaderModule *geometryModule,
vk::SpecializationConstantBitSet specConsts,
const vk::SpecializationConstants specConsts,
const vk::GraphicsPipelineDesc &desc,
const vk::GraphicsPipelineDesc **descPtrOut,
vk::PipelineHelper **pipelineOut);

Просмотреть файл

@ -6509,7 +6509,7 @@ ImageViewSubresourceSerial ImageViewHelper::getSubresourceSerial(
}
// ShaderProgramHelper implementation.
ShaderProgramHelper::ShaderProgramHelper() = default;
ShaderProgramHelper::ShaderProgramHelper() : mSpecializationConstants{} {}
ShaderProgramHelper::~ShaderProgramHelper() = default;
@ -6543,11 +6543,22 @@ void ShaderProgramHelper::setShader(gl::ShaderType shaderType, RefCounted<Shader
mShaders[shaderType].set(shader);
}
void ShaderProgramHelper::enableSpecializationConstant(sh::vk::SpecializationConstantId id)
void ShaderProgramHelper::setSpecializationConstant(sh::vk::SpecializationConstantId id,
uint32_t value)
{
ASSERT(id < sh::vk::SpecializationConstantId::EnumCount);
mSpecializationConstants.set(id);
switch (id)
{
case sh::vk::SpecializationConstantId::LineRasterEmulation:
mSpecializationConstants.lineRasterEmulation = value;
break;
case sh::vk::SpecializationConstantId::SurfaceRotation:
mSpecializationConstants.surfaceRotation = value;
break;
default:
UNREACHABLE();
break;
}
}
angle::Result ShaderProgramHelper::getComputePipeline(Context *context,

Просмотреть файл

@ -2167,7 +2167,7 @@ class ShaderProgramHelper : angle::NonCopyable
ShaderAndSerial &getShader(gl::ShaderType shaderType) { return mShaders[shaderType].get(); }
void setShader(gl::ShaderType shaderType, RefCounted<ShaderAndSerial> *shader);
void enableSpecializationConstant(sh::vk::SpecializationConstantId id);
void setSpecializationConstant(sh::vk::SpecializationConstantId id, uint32_t value);
// For getting a Pipeline and from the pipeline cache.
ANGLE_INLINE angle::Result getGraphicsPipeline(
@ -2212,7 +2212,7 @@ class ShaderProgramHelper : angle::NonCopyable
PipelineAndSerial mComputePipeline;
// Specialization constants, currently only used by the graphics queue.
SpecializationConstantBitSet mSpecializationConstants;
SpecializationConstants mSpecializationConstants;
};
// Tracks current handle allocation counts in the back-end. Useful for debugging and profiling.

Просмотреть файл

@ -677,9 +677,13 @@ class Recycler final : angle::NonCopyable
std::vector<T> mObjectFreeList;
};
using SpecializationConstantBitSet =
angle::PackedEnumBitSet<sh::vk::SpecializationConstantId, uint32_t>;
static_assert(sizeof(SpecializationConstantBitSet) == sizeof(uint32_t), "Unexpected size");
ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
struct SpecializationConstants final
{
VkBool32 lineRasterEmulation;
uint32_t surfaceRotation;
};
ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
template <typename T>
using SpecializationConstantMap = angle::PackedEnumMap<sh::vk::SpecializationConstantId, T>;

Просмотреть файл

@ -88,7 +88,7 @@ void VulkanPipelineCachePerfTest::step()
gl::AttributesMask am;
gl::ComponentTypeMask ctm;
vk::SpecializationConstantBitSet defaultSpecConsts;
vk::SpecializationConstants defaultSpecConsts{};
for (unsigned int iteration = 0; iteration < kIterationsPerStep; ++iteration)
{