Commit b22f8e8e by Charlie Lao Committed by Commit Bot

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: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarIan Elliott <ianelliott@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 9d65420c
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
// Version number for shader translation API. // Version number for shader translation API.
// It is incremented every time the API changes. // It is incremented every time the API changes.
#define ANGLE_SH_VERSION 238 #define ANGLE_SH_VERSION 239
enum ShShaderSpec enum ShShaderSpec
{ {
...@@ -774,9 +774,10 @@ namespace vk ...@@ -774,9 +774,10 @@ namespace vk
enum class SpecializationConstantId : uint32_t enum class SpecializationConstantId : uint32_t
{ {
LineRasterEmulation = 0, LineRasterEmulation = 0,
SurfaceRotation = 1,
InvalidEnum = 1, InvalidEnum = 2,
EnumCount = 1, EnumCount = InvalidEnum,
}; };
// Interface block name containing the aggregate default uniforms // Interface block name containing the aggregate default uniforms
......
...@@ -3126,6 +3126,15 @@ void ContextVk::updateSurfaceRotationDrawFramebuffer(const gl::State &glState) ...@@ -3126,6 +3126,15 @@ void ContextVk::updateSurfaceRotationDrawFramebuffer(const gl::State &glState)
gl::Framebuffer *drawFramebuffer = glState.getDrawFramebuffer(); gl::Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
mCurrentRotationDrawFramebuffer = mCurrentRotationDrawFramebuffer =
DetermineSurfaceRotation(drawFramebuffer, mCurrentWindowSurface); 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) void ContextVk::updateSurfaceRotationReadFramebuffer(const gl::State &glState)
......
...@@ -136,7 +136,7 @@ ProgramInfo::~ProgramInfo() = default; ...@@ -136,7 +136,7 @@ ProgramInfo::~ProgramInfo() = default;
angle::Result ProgramInfo::initProgram(ContextVk *contextVk, angle::Result ProgramInfo::initProgram(ContextVk *contextVk,
const gl::ShaderType shaderType, const gl::ShaderType shaderType,
const ShaderInfo &shaderInfo, const ShaderInfo &shaderInfo,
ProgramTransformOptionBits optionBits, ProgramTransformOptions optionBits,
ProgramExecutableVk *executableVk) ProgramExecutableVk *executableVk)
{ {
const ShaderMapInterfaceVariableInfoMap &variableInfoMap = const ShaderMapInterfaceVariableInfoMap &variableInfoMap =
...@@ -144,8 +144,7 @@ angle::Result ProgramInfo::initProgram(ContextVk *contextVk, ...@@ -144,8 +144,7 @@ angle::Result ProgramInfo::initProgram(ContextVk *contextVk,
const gl::ShaderMap<SpirvBlob> &originalSpirvBlobs = shaderInfo.getSpirvBlobs(); const gl::ShaderMap<SpirvBlob> &originalSpirvBlobs = shaderInfo.getSpirvBlobs();
const SpirvBlob &originalSpirvBlob = originalSpirvBlobs[shaderType]; const SpirvBlob &originalSpirvBlob = originalSpirvBlobs[shaderType];
bool removeEarlyFragmentTestsOptimization = bool removeEarlyFragmentTestsOptimization =
(shaderType == gl::ShaderType::Fragment && (shaderType == gl::ShaderType::Fragment && optionBits.removeEarlyFragmentTestsOptimization);
optionBits[ProgramTransformOption::RemoveEarlyFragmentTestsOptimization]);
gl::ShaderMap<SpirvBlob> transformedSpirvBlobs; gl::ShaderMap<SpirvBlob> transformedSpirvBlobs;
SpirvBlob &transformedSpirvBlob = transformedSpirvBlobs[shaderType]; SpirvBlob &transformedSpirvBlob = transformedSpirvBlobs[shaderType];
...@@ -158,11 +157,10 @@ angle::Result ProgramInfo::initProgram(ContextVk *contextVk, ...@@ -158,11 +157,10 @@ angle::Result ProgramInfo::initProgram(ContextVk *contextVk,
mProgramHelper.setShader(shaderType, &mShaders[shaderType]); mProgramHelper.setShader(shaderType, &mShaders[shaderType]);
if (optionBits[ProgramTransformOption::EnableLineRasterEmulation]) mProgramHelper.setSpecializationConstant(sh::vk::SpecializationConstantId::LineRasterEmulation,
{ optionBits.enableLineRasterEmulation);
mProgramHelper.enableSpecializationConstant( mProgramHelper.setSpecializationConstant(sh::vk::SpecializationConstantId::SurfaceRotation,
sh::vk::SpecializationConstantId::LineRasterEmulation); optionBits.surfaceRotation);
}
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -202,7 +200,7 @@ void ProgramExecutableVk::reset(ContextVk *contextVk) ...@@ -202,7 +200,7 @@ void ProgramExecutableVk::reset(ContextVk *contextVk)
mDescriptorSets.fill(VK_NULL_HANDLE); mDescriptorSets.fill(VK_NULL_HANDLE);
mEmptyDescriptorSets.fill(VK_NULL_HANDLE); mEmptyDescriptorSets.fill(VK_NULL_HANDLE);
mNumDefaultUniformDescriptors = 0; mNumDefaultUniformDescriptors = 0;
mTransformOptionBits.reset(); mTransformOptions = {};
for (vk::RefCountedDescriptorPoolBinding &binding : mDescriptorPoolBindings) for (vk::RefCountedDescriptorPoolBinding &binding : mDescriptorPoolBindings)
{ {
...@@ -655,14 +653,13 @@ void ProgramExecutableVk::updateEarlyFragmentTestsOptimization(ContextVk *contex ...@@ -655,14 +653,13 @@ void ProgramExecutableVk::updateEarlyFragmentTestsOptimization(ContextVk *contex
{ {
const gl::State &glState = contextVk->getState(); const gl::State &glState = contextVk->getState();
mTransformOptionBits[ProgramTransformOption::RemoveEarlyFragmentTestsOptimization] = false; mTransformOptions.removeEarlyFragmentTestsOptimization = false;
if (!glState.canEnableEarlyFragmentTestsOptimization()) if (!glState.canEnableEarlyFragmentTestsOptimization())
{ {
ProgramVk *programVk = getShaderProgram(glState, gl::ShaderType::Fragment); ProgramVk *programVk = getShaderProgram(glState, gl::ShaderType::Fragment);
if (programVk && programVk->getState().hasEarlyFragmentTestsOptimization()) if (programVk && programVk->getState().hasEarlyFragmentTestsOptimization())
{ {
mTransformOptionBits[ProgramTransformOption::RemoveEarlyFragmentTestsOptimization] = mTransformOptions.removeEarlyFragmentTestsOptimization = true;
true;
} }
} }
} }
...@@ -675,23 +672,25 @@ angle::Result ProgramExecutableVk::getGraphicsPipeline( ...@@ -675,23 +672,25 @@ angle::Result ProgramExecutableVk::getGraphicsPipeline(
const vk::GraphicsPipelineDesc **descPtrOut, const vk::GraphicsPipelineDesc **descPtrOut,
vk::PipelineHelper **pipelineOut) vk::PipelineHelper **pipelineOut)
{ {
const gl::State &glState = contextVk->getState(); const gl::State &glState = contextVk->getState();
mTransformOptionBits[ProgramTransformOption::EnableLineRasterEmulation] = RendererVk *renderer = contextVk->getRenderer();
contextVk->isBresenhamEmulationEnabled(mode); vk::PipelineCache *pipelineCache = nullptr;
ProgramInfo &programInfo = getGraphicsProgramInfo(mTransformOptionBits);
RendererVk *renderer = contextVk->getRenderer();
vk::PipelineCache *pipelineCache = nullptr;
const gl::ProgramExecutable *glExecutable = glState.getProgramExecutable(); const gl::ProgramExecutable *glExecutable = glState.getProgramExecutable();
ASSERT(glExecutable && !glExecutable->isCompute()); 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()) for (const gl::ShaderType shaderType : glExecutable->getLinkedShaderStages())
{ {
ProgramVk *programVk = getShaderProgram(glState, shaderType); ProgramVk *programVk = getShaderProgram(glState, shaderType);
if (programVk) if (programVk)
{ {
ANGLE_TRY(programVk->initGraphicsShaderProgram( ANGLE_TRY(programVk->initGraphicsShaderProgram(contextVk, shaderType, mTransformOptions,
contextVk, shaderType, mTransformOptionBits, &programInfo, this)); &programInfo, this));
} }
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#define LIBANGLE_RENDERER_VULKAN_PROGRAMEXECUTABLEVK_H_ #define LIBANGLE_RENDERER_VULKAN_PROGRAMEXECUTABLEVK_H_
#include "common/bitset_utils.h" #include "common/bitset_utils.h"
#include "common/mathutil.h"
#include "common/utilities.h" #include "common/utilities.h"
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/InfoLog.h" #include "libANGLE/InfoLog.h"
...@@ -47,14 +48,16 @@ class ShaderInfo final : angle::NonCopyable ...@@ -47,14 +48,16 @@ class ShaderInfo final : angle::NonCopyable
bool mIsInitialized = false; bool mIsInitialized = false;
}; };
enum class ProgramTransformOption : uint8_t struct ProgramTransformOptions final
{ {
EnableLineRasterEmulation = 0, uint8_t enableLineRasterEmulation : 1;
RemoveEarlyFragmentTestsOptimization = 1, uint8_t removeEarlyFragmentTestsOptimization : 1;
EnumCount = 2, uint8_t surfaceRotation : 3;
PermutationCount = 4, 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 class ProgramInfo final : angle::NonCopyable
{ {
...@@ -65,7 +68,7 @@ class ProgramInfo final : angle::NonCopyable ...@@ -65,7 +68,7 @@ class ProgramInfo final : angle::NonCopyable
angle::Result initProgram(ContextVk *contextVk, angle::Result initProgram(ContextVk *contextVk,
const gl::ShaderType shaderType, const gl::ShaderType shaderType,
const ShaderInfo &shaderInfo, const ShaderInfo &shaderInfo,
ProgramTransformOptionBits optionBits, ProgramTransformOptions optionBits,
ProgramExecutableVk *executableVk); ProgramExecutableVk *executableVk);
void release(ContextVk *contextVk); void release(ContextVk *contextVk);
...@@ -119,9 +122,10 @@ class ProgramExecutableVk ...@@ -119,9 +122,10 @@ class ProgramExecutableVk
const gl::ProgramExecutable &getGlExecutable(); const gl::ProgramExecutable &getGlExecutable();
ProgramInfo &getGraphicsDefaultProgramInfo() { return mGraphicsProgramInfos[0]; } 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; } ProgramInfo &getComputeProgramInfo() { return mComputeProgramInfo; }
vk::BufferSerial getCurrentDefaultUniformBufferSerial() const vk::BufferSerial getCurrentDefaultUniformBufferSerial() const
...@@ -264,10 +268,12 @@ class ProgramExecutableVk ...@@ -264,10 +268,12 @@ class ProgramExecutableVk
// since that's slow to calculate. // since that's slow to calculate.
ShaderMapInterfaceVariableInfoMap mVariableInfoMap; 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; ProgramInfo mComputeProgramInfo;
ProgramTransformOptionBits mTransformOptionBits; ProgramTransformOptions mTransformOptions;
ProgramVk *mProgram; ProgramVk *mProgram;
ProgramPipelineVk *mProgramPipeline; ProgramPipelineVk *mProgramPipeline;
......
...@@ -147,7 +147,7 @@ class ProgramVk : public ProgramImpl ...@@ -147,7 +147,7 @@ class ProgramVk : public ProgramImpl
ANGLE_INLINE angle::Result initGraphicsShaderProgram(ContextVk *contextVk, ANGLE_INLINE angle::Result initGraphicsShaderProgram(ContextVk *contextVk,
const gl::ShaderType shaderType, const gl::ShaderType shaderType,
ProgramTransformOptionBits optionBits, ProgramTransformOptions optionBits,
ProgramInfo *programInfo, ProgramInfo *programInfo,
ProgramExecutableVk *executableVk) ProgramExecutableVk *executableVk)
{ {
...@@ -158,7 +158,7 @@ class ProgramVk : public ProgramImpl ...@@ -158,7 +158,7 @@ class ProgramVk : public ProgramImpl
ProgramInfo *programInfo, ProgramInfo *programInfo,
ProgramExecutableVk *executableVk) ProgramExecutableVk *executableVk)
{ {
ProgramTransformOptionBits optionBits; ProgramTransformOptions optionBits = {};
return initProgram(contextVk, gl::ShaderType::Compute, optionBits, programInfo, return initProgram(contextVk, gl::ShaderType::Compute, optionBits, programInfo,
executableVk); executableVk);
} }
...@@ -192,7 +192,7 @@ class ProgramVk : public ProgramImpl ...@@ -192,7 +192,7 @@ class ProgramVk : public ProgramImpl
ANGLE_INLINE angle::Result initProgram(ContextVk *contextVk, ANGLE_INLINE angle::Result initProgram(ContextVk *contextVk,
const gl::ShaderType shaderType, const gl::ShaderType shaderType,
ProgramTransformOptionBits optionBits, ProgramTransformOptions optionBits,
ProgramInfo *programInfo, ProgramInfo *programInfo,
ProgramExecutableVk *executableVk) ProgramExecutableVk *executableVk)
{ {
......
...@@ -1184,26 +1184,37 @@ void GetRenderPassAndUpdateCounters(ContextVk *contextVk, ...@@ -1184,26 +1184,37 @@ void GetRenderPassAndUpdateCounters(ContextVk *contextVk,
} }
void InitializeSpecializationInfo( void InitializeSpecializationInfo(
vk::SpecializationConstantBitSet specConsts, const vk::SpecializationConstants &specConsts,
vk::SpecializationConstantMap<VkSpecializationMapEntry> *specializationEntriesOut, vk::SpecializationConstantMap<VkSpecializationMapEntry> *specializationEntriesOut,
vk::SpecializationConstantMap<VkBool32> *specializationValuesOut,
VkSpecializationInfo *specializationInfoOut) VkSpecializationInfo *specializationInfoOut)
{ {
// Collect specialization constants. // Collect specialization constants.
for (const sh::vk::SpecializationConstantId id : for (const sh::vk::SpecializationConstantId id :
angle::AllEnums<sh::vk::SpecializationConstantId>()) angle::AllEnums<sh::vk::SpecializationConstantId>())
{ {
const uint32_t offset = static_cast<uint32_t>(id); (*specializationEntriesOut)[id].constantID = static_cast<uint32_t>(id);
(*specializationValuesOut)[id] = specConsts.test(id); switch (id)
(*specializationEntriesOut)[id].constantID = offset; {
(*specializationEntriesOut)[id].offset = offset; case sh::vk::SpecializationConstantId::LineRasterEmulation:
(*specializationEntriesOut)[id].size = sizeof(VkBool32); (*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->mapEntryCount = static_cast<uint32_t>(specializationEntriesOut->size());
specializationInfoOut->pMapEntries = specializationEntriesOut->data(); specializationInfoOut->pMapEntries = specializationEntriesOut->data();
specializationInfoOut->dataSize = specializationEntriesOut->size() * sizeof(VkBool32); specializationInfoOut->dataSize = sizeof(specConsts);
specializationInfoOut->pData = specializationValuesOut->data(); specializationInfoOut->pData = &specConsts;
} }
// Utility for setting a value on a packed 4-bit integer array. // Utility for setting a value on a packed 4-bit integer array.
...@@ -1520,7 +1531,8 @@ void GraphicsPipelineDesc::initDefaults() ...@@ -1520,7 +1531,8 @@ void GraphicsPipelineDesc::initDefaults()
mDepthStencilStateInfo.enable.depthTest = 0; mDepthStencilStateInfo.enable.depthTest = 0;
mDepthStencilStateInfo.enable.depthWrite = 1; 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.depthBoundsTest = 0;
mDepthStencilStateInfo.enable.stencilTest = 0; mDepthStencilStateInfo.enable.stencilTest = 0;
mDepthStencilStateInfo.minDepthBounds = 0.0f; mDepthStencilStateInfo.minDepthBounds = 0.0f;
...@@ -1540,6 +1552,9 @@ void GraphicsPipelineDesc::initDefaults() ...@@ -1540,6 +1552,9 @@ void GraphicsPipelineDesc::initDefaults()
SetBitField(mDepthStencilStateInfo.back.writeMask, 0xFF); SetBitField(mDepthStencilStateInfo.back.writeMask, 0xFF);
mDepthStencilStateInfo.backStencilReference = 0; mDepthStencilStateInfo.backStencilReference = 0;
mDepthStencilStateInfo.depthCompareOpAndSurfaceRotation.surfaceRotation =
static_cast<uint8_t>(SurfaceRotation::Identity);
PackedInputAssemblyAndColorBlendStateInfo &inputAndBlend = mInputAssemblyAndColorBlendStateInfo; PackedInputAssemblyAndColorBlendStateInfo &inputAndBlend = mInputAssemblyAndColorBlendStateInfo;
inputAndBlend.logic.opEnable = 0; inputAndBlend.logic.opEnable = 0;
inputAndBlend.logic.op = static_cast<uint32_t>(VK_LOGIC_OP_CLEAR); inputAndBlend.logic.op = static_cast<uint32_t>(VK_LOGIC_OP_CLEAR);
...@@ -1597,7 +1612,7 @@ angle::Result GraphicsPipelineDesc::initializePipeline( ...@@ -1597,7 +1612,7 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
const ShaderModule *vertexModule, const ShaderModule *vertexModule,
const ShaderModule *fragmentModule, const ShaderModule *fragmentModule,
const ShaderModule *geometryModule, const ShaderModule *geometryModule,
vk::SpecializationConstantBitSet specConsts, const vk::SpecializationConstants specConsts,
Pipeline *pipelineOut) const Pipeline *pipelineOut) const
{ {
angle::FixedVector<VkPipelineShaderStageCreateInfo, 3> shaderStages; angle::FixedVector<VkPipelineShaderStageCreateInfo, 3> shaderStages;
...@@ -1613,9 +1628,7 @@ angle::Result GraphicsPipelineDesc::initializePipeline( ...@@ -1613,9 +1628,7 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
VkGraphicsPipelineCreateInfo createInfo = {}; VkGraphicsPipelineCreateInfo createInfo = {};
vk::SpecializationConstantMap<VkSpecializationMapEntry> specializationEntries; vk::SpecializationConstantMap<VkSpecializationMapEntry> specializationEntries;
vk::SpecializationConstantMap<VkBool32> specializationValues; InitializeSpecializationInfo(specConsts, &specializationEntries, &specializationInfo);
InitializeSpecializationInfo(specConsts, &specializationEntries, &specializationValues,
&specializationInfo);
// Vertex shader is always expected to be present. // Vertex shader is always expected to be present.
ASSERT(vertexModule != nullptr); ASSERT(vertexModule != nullptr);
...@@ -1829,8 +1842,8 @@ angle::Result GraphicsPipelineDesc::initializePipeline( ...@@ -1829,8 +1842,8 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
static_cast<VkBool32>(mDepthStencilStateInfo.enable.depthTest); static_cast<VkBool32>(mDepthStencilStateInfo.enable.depthTest);
depthStencilState.depthWriteEnable = depthStencilState.depthWriteEnable =
static_cast<VkBool32>(mDepthStencilStateInfo.enable.depthWrite); static_cast<VkBool32>(mDepthStencilStateInfo.enable.depthWrite);
depthStencilState.depthCompareOp = depthStencilState.depthCompareOp = static_cast<VkCompareOp>(
static_cast<VkCompareOp>(mDepthStencilStateInfo.depthCompareOp); mDepthStencilStateInfo.depthCompareOpAndSurfaceRotation.depthCompareOp);
depthStencilState.depthBoundsTestEnable = depthStencilState.depthBoundsTestEnable =
static_cast<VkBool32>(mDepthStencilStateInfo.enable.depthBoundsTest); static_cast<VkBool32>(mDepthStencilStateInfo.enable.depthBoundsTest);
depthStencilState.stencilTestEnable = depthStencilState.stencilTestEnable =
...@@ -2196,7 +2209,7 @@ void GraphicsPipelineDesc::setDepthWriteEnabled(bool enabled) ...@@ -2196,7 +2209,7 @@ void GraphicsPipelineDesc::setDepthWriteEnabled(bool enabled)
void GraphicsPipelineDesc::setDepthFunc(VkCompareOp op) void GraphicsPipelineDesc::setDepthFunc(VkCompareOp op)
{ {
SetBitField(mDepthStencilStateInfo.depthCompareOp, op); SetBitField(mDepthStencilStateInfo.depthCompareOpAndSurfaceRotation.depthCompareOp, op);
} }
void GraphicsPipelineDesc::setDepthClampEnabled(bool enabled) void GraphicsPipelineDesc::setDepthClampEnabled(bool enabled)
...@@ -2269,7 +2282,17 @@ void GraphicsPipelineDesc::updateDepthFunc(GraphicsPipelineTransitionBits *trans ...@@ -2269,7 +2282,17 @@ void GraphicsPipelineDesc::updateDepthFunc(GraphicsPipelineTransitionBits *trans
const gl::DepthStencilState &depthStencilState) const gl::DepthStencilState &depthStencilState)
{ {
setDepthFunc(PackGLCompareFunc(depthStencilState.depthFunc)); 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, void GraphicsPipelineDesc::updateDepthWriteEnabled(GraphicsPipelineTransitionBits *transition,
...@@ -3250,7 +3273,7 @@ angle::Result GraphicsPipelineCache::insertPipeline( ...@@ -3250,7 +3273,7 @@ angle::Result GraphicsPipelineCache::insertPipeline(
const vk::ShaderModule *vertexModule, const vk::ShaderModule *vertexModule,
const vk::ShaderModule *fragmentModule, const vk::ShaderModule *fragmentModule,
const vk::ShaderModule *geometryModule, const vk::ShaderModule *geometryModule,
vk::SpecializationConstantBitSet specConsts, const vk::SpecializationConstants specConsts,
const vk::GraphicsPipelineDesc &desc, const vk::GraphicsPipelineDesc &desc,
const vk::GraphicsPipelineDesc **descPtrOut, const vk::GraphicsPipelineDesc **descPtrOut,
vk::PipelineHelper **pipelineOut) vk::PipelineHelper **pipelineOut)
......
...@@ -458,12 +458,24 @@ struct DepthStencilEnableFlags final ...@@ -458,12 +458,24 @@ struct DepthStencilEnableFlags final
constexpr size_t kDepthStencilEnableFlagsSize = sizeof(DepthStencilEnableFlags); constexpr size_t kDepthStencilEnableFlagsSize = sizeof(DepthStencilEnableFlags);
static_assert(kDepthStencilEnableFlagsSize == 1, "Size check failed"); 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 struct PackedDepthStencilStateInfo final
{ {
DepthStencilEnableFlags enable; DepthStencilEnableFlags enable;
uint8_t frontStencilReference; uint8_t frontStencilReference;
uint8_t backStencilReference; uint8_t backStencilReference;
uint8_t depthCompareOp; // only needs 4 bits. extra used as padding. DepthCompareOpAndSurfaceRotation depthCompareOpAndSurfaceRotation;
float minDepthBounds; float minDepthBounds;
float maxDepthBounds; float maxDepthBounds;
PackedStencilOpState front; PackedStencilOpState front;
...@@ -472,6 +484,7 @@ struct PackedDepthStencilStateInfo final ...@@ -472,6 +484,7 @@ struct PackedDepthStencilStateInfo final
constexpr size_t kPackedDepthStencilStateSize = sizeof(PackedDepthStencilStateInfo); constexpr size_t kPackedDepthStencilStateSize = sizeof(PackedDepthStencilStateInfo);
static_assert(kPackedDepthStencilStateSize == 20, "Size check failed"); static_assert(kPackedDepthStencilStateSize == 20, "Size check failed");
static_assert(static_cast<int>(SurfaceRotation::EnumCount) <= 8, "Size check failed");
struct LogicOpState final struct LogicOpState final
{ {
...@@ -569,7 +582,7 @@ class GraphicsPipelineDesc final ...@@ -569,7 +582,7 @@ class GraphicsPipelineDesc final
const ShaderModule *vertexModule, const ShaderModule *vertexModule,
const ShaderModule *fragmentModule, const ShaderModule *fragmentModule,
const ShaderModule *geometryModule, const ShaderModule *geometryModule,
vk::SpecializationConstantBitSet specConsts, const vk::SpecializationConstants specConsts,
Pipeline *pipelineOut) const; Pipeline *pipelineOut) const;
// Vertex input state. For ES 3.1 this should be separated into binding and attribute. // Vertex input state. For ES 3.1 this should be separated into binding and attribute.
...@@ -695,6 +708,14 @@ class GraphicsPipelineDesc final ...@@ -695,6 +708,14 @@ class GraphicsPipelineDesc final
void setSubpass(uint32_t subpass); void setSubpass(uint32_t subpass);
uint32_t getSubpass() const; uint32_t getSubpass() const;
void updateSurfaceRotation(GraphicsPipelineTransitionBits *transition,
const SurfaceRotation surfaceRotation);
SurfaceRotation getSurfaceRotation() const
{
return static_cast<SurfaceRotation>(
mDepthStencilStateInfo.depthCompareOpAndSurfaceRotation.surfaceRotation);
}
private: private:
void updateSubpass(GraphicsPipelineTransitionBits *transition, uint32_t subpass); void updateSubpass(GraphicsPipelineTransitionBits *transition, uint32_t subpass);
...@@ -1334,7 +1355,7 @@ class GraphicsPipelineCache final : angle::NonCopyable ...@@ -1334,7 +1355,7 @@ class GraphicsPipelineCache final : angle::NonCopyable
const vk::ShaderModule *vertexModule, const vk::ShaderModule *vertexModule,
const vk::ShaderModule *fragmentModule, const vk::ShaderModule *fragmentModule,
const vk::ShaderModule *geometryModule, const vk::ShaderModule *geometryModule,
vk::SpecializationConstantBitSet specConsts, const vk::SpecializationConstants specConsts,
const vk::GraphicsPipelineDesc &desc, const vk::GraphicsPipelineDesc &desc,
const vk::GraphicsPipelineDesc **descPtrOut, const vk::GraphicsPipelineDesc **descPtrOut,
vk::PipelineHelper **pipelineOut) vk::PipelineHelper **pipelineOut)
...@@ -1363,7 +1384,7 @@ class GraphicsPipelineCache final : angle::NonCopyable ...@@ -1363,7 +1384,7 @@ class GraphicsPipelineCache final : angle::NonCopyable
const vk::ShaderModule *vertexModule, const vk::ShaderModule *vertexModule,
const vk::ShaderModule *fragmentModule, const vk::ShaderModule *fragmentModule,
const vk::ShaderModule *geometryModule, const vk::ShaderModule *geometryModule,
vk::SpecializationConstantBitSet specConsts, const vk::SpecializationConstants specConsts,
const vk::GraphicsPipelineDesc &desc, const vk::GraphicsPipelineDesc &desc,
const vk::GraphicsPipelineDesc **descPtrOut, const vk::GraphicsPipelineDesc **descPtrOut,
vk::PipelineHelper **pipelineOut); vk::PipelineHelper **pipelineOut);
......
...@@ -6509,7 +6509,7 @@ ImageViewSubresourceSerial ImageViewHelper::getSubresourceSerial( ...@@ -6509,7 +6509,7 @@ ImageViewSubresourceSerial ImageViewHelper::getSubresourceSerial(
} }
// ShaderProgramHelper implementation. // ShaderProgramHelper implementation.
ShaderProgramHelper::ShaderProgramHelper() = default; ShaderProgramHelper::ShaderProgramHelper() : mSpecializationConstants{} {}
ShaderProgramHelper::~ShaderProgramHelper() = default; ShaderProgramHelper::~ShaderProgramHelper() = default;
...@@ -6543,11 +6543,22 @@ void ShaderProgramHelper::setShader(gl::ShaderType shaderType, RefCounted<Shader ...@@ -6543,11 +6543,22 @@ void ShaderProgramHelper::setShader(gl::ShaderType shaderType, RefCounted<Shader
mShaders[shaderType].set(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); ASSERT(id < sh::vk::SpecializationConstantId::EnumCount);
switch (id)
mSpecializationConstants.set(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, angle::Result ShaderProgramHelper::getComputePipeline(Context *context,
......
...@@ -2167,7 +2167,7 @@ class ShaderProgramHelper : angle::NonCopyable ...@@ -2167,7 +2167,7 @@ class ShaderProgramHelper : angle::NonCopyable
ShaderAndSerial &getShader(gl::ShaderType shaderType) { return mShaders[shaderType].get(); } ShaderAndSerial &getShader(gl::ShaderType shaderType) { return mShaders[shaderType].get(); }
void setShader(gl::ShaderType shaderType, RefCounted<ShaderAndSerial> *shader); 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. // For getting a Pipeline and from the pipeline cache.
ANGLE_INLINE angle::Result getGraphicsPipeline( ANGLE_INLINE angle::Result getGraphicsPipeline(
...@@ -2212,7 +2212,7 @@ class ShaderProgramHelper : angle::NonCopyable ...@@ -2212,7 +2212,7 @@ class ShaderProgramHelper : angle::NonCopyable
PipelineAndSerial mComputePipeline; PipelineAndSerial mComputePipeline;
// Specialization constants, currently only used by the graphics queue. // 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. // Tracks current handle allocation counts in the back-end. Useful for debugging and profiling.
......
...@@ -677,9 +677,13 @@ class Recycler final : angle::NonCopyable ...@@ -677,9 +677,13 @@ class Recycler final : angle::NonCopyable
std::vector<T> mObjectFreeList; std::vector<T> mObjectFreeList;
}; };
using SpecializationConstantBitSet = ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
angle::PackedEnumBitSet<sh::vk::SpecializationConstantId, uint32_t>; struct SpecializationConstants final
static_assert(sizeof(SpecializationConstantBitSet) == sizeof(uint32_t), "Unexpected size"); {
VkBool32 lineRasterEmulation;
uint32_t surfaceRotation;
};
ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
template <typename T> template <typename T>
using SpecializationConstantMap = angle::PackedEnumMap<sh::vk::SpecializationConstantId, T>; using SpecializationConstantMap = angle::PackedEnumMap<sh::vk::SpecializationConstantId, T>;
......
...@@ -88,7 +88,7 @@ void VulkanPipelineCachePerfTest::step() ...@@ -88,7 +88,7 @@ void VulkanPipelineCachePerfTest::step()
gl::AttributesMask am; gl::AttributesMask am;
gl::ComponentTypeMask ctm; gl::ComponentTypeMask ctm;
vk::SpecializationConstantBitSet defaultSpecConsts; vk::SpecializationConstants defaultSpecConsts{};
for (unsigned int iteration = 0; iteration < kIterationsPerStep; ++iteration) for (unsigned int iteration = 0; iteration < kIterationsPerStep; ++iteration)
{ {
......
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