Vulkan: Workaround ARM bug with stencil write mask

Bug: angleproject:7556
Change-Id: I0aa17c178071cc15d8ee15f700b0c4932819c72a
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3821367
Reviewed-by: Ian Elliott <ianelliott@google.com>
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Cody Northrop <cnorthrop@google.com>
This commit is contained in:
Shahbaz Youssefi 2022-08-09 14:57:24 -04:00 коммит произвёл Angle LUCI CQ
Родитель dc82ff15ee
Коммит 493b5aff70
23 изменённых файлов: 143 добавлений и 27 удалений

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

@ -26,7 +26,7 @@
// Version number for shader translation API.
// It is incremented every time the API changes.
#define ANGLE_SH_VERSION 300
#define ANGLE_SH_VERSION 301
enum ShShaderSpec
{
@ -805,6 +805,7 @@ unsigned int GetImage2DRegisterIndex(const ShHandle handle);
// handle: Specifies the compiler
const std::set<std::string> *GetUsedImage2DFunctionNames(const ShHandle handle);
bool HasDiscardInFragmentShader(const ShHandle handle);
bool HasValidGeometryShaderInputPrimitiveType(const ShHandle handle);
bool HasValidGeometryShaderOutputPrimitiveType(const ShHandle handle);
bool HasValidGeometryShaderMaxVertices(const ShHandle handle);

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

@ -670,6 +670,12 @@ struct FeaturesVk : FeatureSetBase
"VkDevice supports VK_ANDROID_render_to_external_format and VK_EXT_ycbcr_attachment",
&members,
};
FeatureInfo useNonZeroStencilWriteMaskStaticState = {
"useNonZeroStencilWriteMaskStaticState", FeatureCategory::VulkanWorkarounds,
"Work around a driver bug where 0 in stencil write mask static state would make the"
"corresponding dynamic state malfunction in the presence of discard or alpha to coverage",
&members, "http://anglebug.com/7556"};
};
inline FeaturesVk::FeaturesVk() = default;

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

@ -900,6 +900,15 @@
"description": [
"VkDevice supports VK_ANDROID_render_to_external_format and VK_EXT_ycbcr_attachment"
]
},
{
"name": "use_non_zero_stencil_write_mask_static_state",
"category": "Workarounds",
"description": [
"Work around a driver bug where 0 in stencil write mask static state would make the",
"corresponding dynamic state malfunction in the presence of discard or alpha to coverage"
],
"issue": "http://anglebug.com/7556"
}
]
}

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

@ -6,7 +6,7 @@
"include/platform/FeaturesMtl_autogen.h":
"6b6d49c35bc9246361f8dac0a5445a02",
"include/platform/FeaturesVk_autogen.h":
"ab5ace9dfe770836cc0532cb44a0d689",
"858c952c9988cfdb448ebf5ac24d3433",
"include/platform/FrontendFeatures_autogen.h":
"1781e4fa6efb552bca2ce5a5164eb374",
"include/platform/d3d_features.json":
@ -20,9 +20,9 @@
"include/platform/mtl_features.json":
"1fabfe4d5c2eb3683a5b567ab60ad83c",
"include/platform/vk_features.json":
"712395bb25e2492ea13fba1c8131f481",
"584d2949c0cc9e59f479748e583af9ef",
"util/angle_features_autogen.cpp":
"adf8f4a7e32d3229aa42bb7a96842d5b",
"e5742cc5b6a78cfed2345067f2a247b2",
"util/angle_features_autogen.h":
"92d40c02e5b2741b33bcc88aa759cfde"
"9bbae74bf2e9816ebe2f9002dd8f2fd2"
}

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

@ -553,6 +553,8 @@ void TCompiler::setASTMetadata(const TParseContext &parseContext)
mEarlyFragmentTestsSpecified = parseContext.isEarlyFragmentTestsSpecified();
mHasDiscard = parseContext.hasDiscard();
mEnablesPerSampleShading = parseContext.isSampleQualifierSpecified();
mComputeShaderLocalSizeDeclared = parseContext.isComputeShaderLocalSizeDeclared();

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

@ -112,6 +112,7 @@ class TCompiler : public TShHandleBase
TInfoSink &getInfoSink() { return mInfoSink; }
bool isEarlyFragmentTestsSpecified() const { return mEarlyFragmentTestsSpecified; }
bool hasDiscard() const { return mHasDiscard; }
bool enablesPerSampleShading() const { return mEnablesPerSampleShading; }
SpecConstUsageBits getSpecConstUsageBits() const { return mSpecConstUsageBits; }
@ -317,9 +318,12 @@ class TCompiler : public TShHandleBase
TDiagnostics mDiagnostics;
const char *mSourcePath; // Path of source file or NULL
// fragment shader early fragment tests
// Fragment shader early fragment tests
bool mEarlyFragmentTestsSpecified;
// Fragment shader has the discard instruction
bool mHasDiscard;
// Whether per-sample shading is enabled by the shader. In OpenGL, this keyword should
// implicitly trigger per-sample shading without the API enabling it.
bool mEnablesPerSampleShading;

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

@ -210,6 +210,7 @@ TParseContext::TParseContext(TSymbolTable &symt,
mChecksPrecisionErrors(checksPrecErrors),
mFragmentPrecisionHighOnESSL1(false),
mEarlyFragmentTestsSpecified(false),
mHasDiscard(false),
mSampleQualifierSpecified(false),
mDefaultUniformMatrixPacking(EmpColumnMajor),
mDefaultUniformBlockStorage(sh::IsWebGLBasedSpec(spec) ? EbsStd140 : EbsShared),
@ -6810,6 +6811,7 @@ TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc)
{
errorIfPLSDeclared(loc, PLSIllegalOperations::Discard);
}
mHasDiscard = true;
break;
default:
UNREACHABLE();

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

@ -76,6 +76,7 @@ class TParseContext : angle::NonCopyable
}
bool isEarlyFragmentTestsSpecified() const { return mEarlyFragmentTestsSpecified; }
bool hasDiscard() const { return mHasDiscard; }
bool isSampleQualifierSpecified() const { return mSampleQualifierSpecified; }
void setLoopNestingLevel(int loopNestintLevel) { mLoopNestingLevel = loopNestintLevel; }
@ -731,8 +732,9 @@ class TParseContext : angle::NonCopyable
// without precision, explicit or implicit.
bool mFragmentPrecisionHighOnESSL1; // true if highp precision is supported when compiling
// ESSL1.
bool mEarlyFragmentTestsSpecified; // true if layout(early_fragment_tests) in; is specified.
bool mSampleQualifierSpecified; // true if the |sample| qualifier is used
bool mEarlyFragmentTestsSpecified; // true if |layout(early_fragment_tests) in| is specified.
bool mHasDiscard; // true if |discard| is encountered in the shader.
bool mSampleQualifierSpecified; // true if the |sample| qualifier is used.
TLayoutMatrixPacking mDefaultUniformMatrixPacking;
TLayoutBlockStorage mDefaultUniformBlockStorage;
TLayoutMatrixPacking mDefaultBufferMatrixPacking;

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

@ -736,6 +736,17 @@ const std::set<std::string> *GetUsedImage2DFunctionNames(const ShHandle handle)
#endif // ANGLE_ENABLE_HLSL
}
bool HasDiscardInFragmentShader(const ShHandle handle)
{
ASSERT(handle);
TShHandleBase *base = static_cast<TShHandleBase *>(handle);
TCompiler *compiler = base->getAsCompiler();
ASSERT(compiler);
return compiler->getShaderType() == GL_FRAGMENT_SHADER && compiler->hasDiscard();
}
bool HasValidGeometryShaderInputPrimitiveType(const ShHandle handle)
{
ASSERT(handle);

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

@ -1347,6 +1347,7 @@ angle::Result Program::linkImpl(const Context *context)
return angle::Result::Continue;
}
mState.mExecutable->mHasDiscard = fragmentShader->hasDiscard();
mState.mExecutable->mEnablesPerSampleShading =
fragmentShader->enablesPerSampleShading();
mState.mExecutable->mAdvancedBlendEquations =

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

@ -196,6 +196,7 @@ ProgramExecutable::ProgramExecutable()
mImageUniformRange(0, 0),
mAtomicCounterUniformRange(0, 0),
mFragmentInoutRange(0, 0),
mHasDiscard(false),
mEnablesPerSampleShading(false),
// [GL_EXT_geometry_shader] Table 20.22
mGeometryShaderInputPrimitiveType(PrimitiveMode::Triangles),
@ -244,6 +245,7 @@ ProgramExecutable::ProgramExecutable(const ProgramExecutable &other)
mAtomicCounterBuffers(other.mAtomicCounterBuffers),
mShaderStorageBlocks(other.mShaderStorageBlocks),
mFragmentInoutRange(other.mFragmentInoutRange),
mHasDiscard(other.mHasDiscard),
mEnablesPerSampleShading(other.mEnablesPerSampleShading),
mAdvancedBlendEquations(other.mAdvancedBlendEquations)
{
@ -293,6 +295,7 @@ void ProgramExecutable::reset(bool clearInfoLog)
mAtomicCounterUniformRange = RangeUI(0, 0);
mFragmentInoutRange = RangeUI(0, 0);
mHasDiscard = false;
mEnablesPerSampleShading = false;
mAdvancedBlendEquations.reset();
@ -325,6 +328,7 @@ void ProgramExecutable::load(bool isSeparable, gl::BinaryInputStream *stream)
unsigned int fragmentInoutRangeHigh = stream->readInt<uint32_t>();
mFragmentInoutRange = RangeUI(fragmentInoutRangeLow, fragmentInoutRangeHigh);
mHasDiscard = stream->readBool();
mEnablesPerSampleShading = stream->readBool();
static_assert(sizeof(mAdvancedBlendEquations.bits()) == sizeof(uint32_t));
@ -557,6 +561,7 @@ void ProgramExecutable::save(bool isSeparable, gl::BinaryOutputStream *stream) c
stream->writeInt(mFragmentInoutRange.low());
stream->writeInt(mFragmentInoutRange.high());
stream->writeBool(mHasDiscard);
stream->writeBool(mEnablesPerSampleShading);
stream->writeInt(mAdvancedBlendEquations.bits());

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

@ -231,6 +231,7 @@ class ProgramExecutable final : public angle::Subject
const RangeUI &getImageUniformRange() const { return mImageUniformRange; }
const RangeUI &getAtomicCounterUniformRange() const { return mAtomicCounterUniformRange; }
const RangeUI &getFragmentInoutRange() const { return mFragmentInoutRange; }
bool hasDiscard() const { return mHasDiscard; }
bool enablesPerSampleShading() const { return mEnablesPerSampleShading; }
BlendEquationBitSet getAdvancedBlendEquations() const { return mAdvancedBlendEquations; }
const std::vector<TransformFeedbackVarying> &getLinkedTransformFeedbackVaryings() const
@ -472,6 +473,7 @@ class ProgramExecutable final : public angle::Subject
std::vector<InterfaceBlock> mShaderStorageBlocks;
RangeUI mFragmentInoutRange;
bool mHasDiscard;
bool mEnablesPerSampleShading;
// KHR_blend_equation_advanced supported equation list

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

@ -371,6 +371,7 @@ void ProgramPipeline::updateFragmentInoutRangeAndEnablesPerSampleShading()
const ProgramExecutable &fragmentExecutable = fragmentProgram->getExecutable();
mState.mExecutable->mFragmentInoutRange = fragmentExecutable.mFragmentInoutRange;
mState.mExecutable->mHasDiscard = fragmentExecutable.mHasDiscard;
mState.mExecutable->mEnablesPerSampleShading = fragmentExecutable.mEnablesPerSampleShading;
}

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

@ -343,6 +343,7 @@ void Shader::compile(const Context *context)
mState.mTessGenVertexOrder = 0;
mState.mTessGenPointMode = 0;
mState.mAdvancedBlendEquations.reset();
mState.mHasDiscard = false;
mState.mEnablesPerSampleShading = false;
mState.mSpecConstUsageBits.reset();
@ -544,6 +545,7 @@ void Shader::resolveCompile()
std::sort(mState.mInputVaryings.begin(), mState.mInputVaryings.end(), CompareShaderVar);
mState.mActiveOutputVariables =
GetActiveShaderVariables(sh::GetOutputVariables(compilerHandle));
mState.mHasDiscard = sh::HasDiscardInFragmentShader(compilerHandle);
mState.mEnablesPerSampleShading = sh::EnablesPerSampleShading(compilerHandle);
mState.mAdvancedBlendEquations =
BlendEquationBitSet(sh::GetAdvancedBlendEquations(compilerHandle));

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

@ -91,6 +91,7 @@ class ShaderState final : angle::NonCopyable
const sh::WorkGroupSize &getLocalSize() const { return mLocalSize; }
bool hasDiscard() const { return mHasDiscard; }
bool enablesPerSampleShading() const { return mEnablesPerSampleShading; }
rx::SpecConstUsageBits getSpecConstUsageBits() const { return mSpecConstUsageBits; }
@ -134,6 +135,7 @@ class ShaderState final : angle::NonCopyable
std::vector<sh::ShaderVariable> mActiveAttributes;
std::vector<sh::ShaderVariable> mActiveOutputVariables;
bool mHasDiscard;
bool mEnablesPerSampleShading;
BlendEquationBitSet mAdvancedBlendEquations;
rx::SpecConstUsageBits mSpecConstUsageBits;
@ -200,6 +202,7 @@ class Shader final : angle::NonCopyable, public LabeledObject
unsigned int getRefCount() const;
bool isFlaggedForDeletion() const;
void flagForDeletion();
bool hasDiscard() const { return mState.mHasDiscard; }
bool enablesPerSampleShading() const { return mState.mEnablesPerSampleShading; }
BlendEquationBitSet getAdvancedBlendEquations() const { return mState.mAdvancedBlendEquations; }
rx::SpecConstUsageBits getSpecConstUsageBits() const { return mState.mSpecConstUsageBits; }

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

@ -920,8 +920,11 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk
mPipelineDirtyBitsMask.reset(gl::State::DIRTY_BIT_LINE_WIDTH);
mPipelineDirtyBitsMask.reset(gl::State::DIRTY_BIT_POLYGON_OFFSET);
mPipelineDirtyBitsMask.reset(gl::State::DIRTY_BIT_BLEND_COLOR);
mPipelineDirtyBitsMask.reset(gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
mPipelineDirtyBitsMask.reset(gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
if (!getFeatures().useNonZeroStencilWriteMaskStaticState.enabled)
{
mPipelineDirtyBitsMask.reset(gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
mPipelineDirtyBitsMask.reset(gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
}
// Dynamic state in VK_EXT_extended_dynamic_state:
if (getFeatures().supportsExtendedDynamicState.enabled)
@ -4626,6 +4629,24 @@ void ContextVk::updateDither()
}
}
void ContextVk::updateStencilWriteWorkaround()
{
if (!getFeatures().useNonZeroStencilWriteMaskStaticState.enabled)
{
return;
}
// On certain drivers, having a stencil write mask of 0 in static state enables optimizations
// that make the interaction of the stencil write mask dynamic state with discard and alpha to
// coverage broken. When the program has discard, or when alpha to coverage is enabled, these
// optimizations are disabled by specifying a non-zero static state for stencil write mask.
const bool programHasDiscard = mState.getProgramExecutable()->hasDiscard();
const bool isAlphaToCoverageEnabled = mState.isSampleAlphaToCoverageEnabled();
mGraphicsPipelineDesc->updateNonZeroStencilWriteMaskWorkaround(
&mGraphicsPipelineTransition, programHasDiscard || isAlphaToCoverageEnabled);
}
angle::Result ContextVk::invalidateProgramExecutableHelper(const gl::Context *context)
{
const gl::State &glState = context->getState();
@ -4661,6 +4682,8 @@ angle::Result ContextVk::invalidateProgramExecutableHelper(const gl::Context *co
// masked, so update their access.
onColorAccessChange();
}
updateStencilWriteWorkaround();
}
return angle::Result::Continue;
@ -4729,6 +4752,8 @@ angle::Result ContextVk::syncState(const gl::Context *context,
case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED:
mGraphicsPipelineDesc->updateAlphaToCoverageEnable(
&mGraphicsPipelineTransition, glState.isSampleAlphaToCoverageEnabled());
updateStencilWriteWorkaround();
static_assert(gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE >
gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED,
"Dirty bit order");

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

@ -1277,6 +1277,16 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText
void updateDither();
// When the useNonZeroStencilWriteMaskStaticState workaround is enabled, the static state for
// stencil should be non-zero despite the state being dynamic. This is done when:
//
// - The shader includes discard, or
// - Alpha-to-coverage is enabled.
//
// An alternative could have been to set the static state unconditionally to non-zero. This is
// avoided however, as on the affected driver that would disable certain optimizations.
void updateStencilWriteWorkaround();
SpecConstUsageBits getCurrentProgramSpecConstUsageBits() const;
void updateGraphicsPipelineDescWithSpecConstUsageBits(SpecConstUsageBits usageBits);

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

@ -3671,6 +3671,11 @@ void RendererVk::initFeatures(DisplayVk *displayVk,
!isARM && !isPowerVR && !isQualcommProprietary &&
!(IsLinux() && isIntel) && !(IsChromeOS() && isSwiftShader));
// On ARM, dynamic state for stencil write mask doesn't work correctly in the presence of
// discard or alpha to coverage, if the static state provided when creating the pipeline has a
// value of 0.
ANGLE_FEATURE_CONDITION(&mFeatures, useNonZeroStencilWriteMaskStaticState, isARM);
// On ARM, per-sample shading is not enabled despite the presence of a Sample decoration. As a
// workaround, per-sample shading is inferred by ANGLE and explicitly enabled by the API.
ANGLE_FEATURE_CONDITION(&mFeatures, explicitlyEnablePerSampleShading, isARM);

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

@ -257,14 +257,20 @@ void UnpackDepthStencilResolveAttachmentDesc(VkAttachmentDescription *desc,
desc->finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
}
void UnpackStencilState(const PackedStencilOpState &packedState, VkStencilOpState *stateOut)
void UnpackStencilState(const PackedStencilOpState &packedState,
VkStencilOpState *stateOut,
bool writeMaskWorkaround)
{
// Any non-zero value works for the purposes of the useNonZeroStencilWriteMaskStaticState driver
// bug workaround.
constexpr uint32_t kNonZeroWriteMaskForWorkaround = 1;
stateOut->failOp = static_cast<VkStencilOp>(packedState.ops.fail);
stateOut->passOp = static_cast<VkStencilOp>(packedState.ops.pass);
stateOut->depthFailOp = static_cast<VkStencilOp>(packedState.ops.depthFail);
stateOut->compareOp = static_cast<VkCompareOp>(packedState.ops.compare);
stateOut->compareMask = 0;
stateOut->writeMask = 0;
stateOut->writeMask = writeMaskWorkaround ? kNonZeroWriteMaskForWorkaround : 0;
stateOut->reference = 0;
}
@ -1637,7 +1643,7 @@ void UnpackPipelineState(const vk::GraphicsPipelineDesc &state, UnpackedPipeline
const PackedInputAssemblyAndRasterizationStateInfo &inputAndRaster =
state.getInputAssemblyAndRasterizationStateInfoForLog();
const PackedColorBlendStateInfo &colorBlend = state.getColorBlendStateInfoForLog();
const PackedDither &dither = state.getDitherForLog();
const PackedDitherAndWorkarounds &dither = state.getDitherForLog();
const PackedDynamicState &dynamicState = state.getDynamicStateForLog();
valuesOut->fill(0);
@ -2669,8 +2675,9 @@ void GraphicsPipelineDesc::initDefaults(const ContextVk *contextVk)
&mColorBlendStateInfo.attachments[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS],
blendAttachmentState);
mDither.emulatedDitherControl = 0;
mDither.unused = 0;
mDitherAndWorkarounds.emulatedDitherControl = 0;
mDitherAndWorkarounds.nonZeroStencilWriteMaskWorkaround = 0;
mDitherAndWorkarounds.unused = 0;
SetBitField(mDynamicState.ds1And2.cullMode, VK_CULL_MODE_NONE);
SetBitField(mDynamicState.ds1And2.frontFace, VK_FRONT_FACE_COUNTER_CLOCKWISE);
@ -3032,8 +3039,10 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
depthStencilState.depthBoundsTestEnable =
static_cast<VkBool32>(inputAndRaster.misc.depthBoundsTest);
depthStencilState.stencilTestEnable = static_cast<VkBool32>(mDynamicState.ds1And2.stencilTest);
UnpackStencilState(mDynamicState.ds1.front, &depthStencilState.front);
UnpackStencilState(mDynamicState.ds1.back, &depthStencilState.back);
UnpackStencilState(mDynamicState.ds1.front, &depthStencilState.front,
mDitherAndWorkarounds.nonZeroStencilWriteMaskWorkaround);
UnpackStencilState(mDynamicState.ds1.back, &depthStencilState.back,
mDitherAndWorkarounds.nonZeroStencilWriteMaskWorkaround);
depthStencilState.minDepthBounds = 0;
depthStencilState.maxDepthBounds = 0;
@ -3703,10 +3712,18 @@ void GraphicsPipelineDesc::updateEmulatedDitherControl(GraphicsPipelineTransitio
uint16_t value)
{
// Make sure we don't waste time resetting this to zero in the common no-dither case.
ASSERT(value != 0 || mDither.emulatedDitherControl != 0);
ASSERT(value != 0 || mDitherAndWorkarounds.emulatedDitherControl != 0);
mDither.emulatedDitherControl = value;
transition->set(ANGLE_GET_TRANSITION_BIT(mDither, emulatedDitherControl));
mDitherAndWorkarounds.emulatedDitherControl = value;
transition->set(ANGLE_GET_TRANSITION_BIT(mDitherAndWorkarounds, emulatedDitherControl));
}
void GraphicsPipelineDesc::updateNonZeroStencilWriteMaskWorkaround(
GraphicsPipelineTransitionBits *transition,
bool enabled)
{
mDitherAndWorkarounds.nonZeroStencilWriteMaskWorkaround = enabled;
transition->set(ANGLE_GET_TRANSITION_BIT(mDitherAndWorkarounds, emulatedDitherControl));
}
void GraphicsPipelineDesc::updateRenderPassDesc(GraphicsPipelineTransitionBits *transition,

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

@ -468,12 +468,13 @@ struct PackedColorBlendStateInfo final
constexpr size_t kPackedColorBlendStateSize = sizeof(PackedColorBlendStateInfo);
static_assert(kPackedColorBlendStateSize == 36, "Size check failed");
struct PackedDither final
struct PackedDitherAndWorkarounds final
{
static_assert(gl::IMPLEMENTATION_MAX_DRAW_BUFFERS <= 8,
"2 bits per draw buffer is needed for dither emulation");
uint16_t emulatedDitherControl;
uint16_t unused;
uint16_t nonZeroStencilWriteMaskWorkaround : 1;
uint16_t unused : 15;
};
// State that is dynamic in VK_EXT_extended_dynamic_state and 2. These are placed at the end of the
@ -537,7 +538,7 @@ static_assert(kPackedDynamicStateSize == 40, "Size check failed");
constexpr size_t kGraphicsPipelineDescSumOfSizes =
kVertexInputAttributesSize + kRenderPassDescSize +
kPackedInputAssemblyAndRasterizationStateSize + kPackedColorBlendStateSize +
sizeof(PackedDither) + kPackedDynamicStateSize;
sizeof(PackedDitherAndWorkarounds) + kPackedDynamicStateSize;
// Number of dirty bits in the dirty bit set.
constexpr size_t kGraphicsPipelineDirtyBitBytes = 4;
@ -720,7 +721,13 @@ class GraphicsPipelineDesc final
}
void updateEmulatedDitherControl(GraphicsPipelineTransitionBits *transition, uint16_t value);
uint32_t getEmulatedDitherControl() const { return mDither.emulatedDitherControl; }
uint32_t getEmulatedDitherControl() const
{
return mDitherAndWorkarounds.emulatedDitherControl;
}
void updateNonZeroStencilWriteMaskWorkaround(GraphicsPipelineTransitionBits *transition,
bool enabled);
void setSupportsDynamicStateForTest(bool supports)
{
@ -740,7 +747,7 @@ class GraphicsPipelineDesc final
{
return mColorBlendStateInfo;
}
const PackedDither &getDitherForLog() const { return mDither; }
const PackedDitherAndWorkarounds &getDitherForLog() const { return mDitherAndWorkarounds; }
const PackedDynamicState &getDynamicStateForLog() const { return mDynamicState; }
private:
@ -750,7 +757,7 @@ class GraphicsPipelineDesc final
RenderPassDesc mRenderPassDesc;
PackedInputAssemblyAndRasterizationStateInfo mInputAssemblyAndRasterizationStateInfo;
PackedColorBlendStateInfo mColorBlendStateInfo;
PackedDither mDither;
PackedDitherAndWorkarounds mDitherAndWorkarounds;
PackedDynamicState mDynamicState;
};

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

@ -538,7 +538,6 @@
7158 PIXEL6 VULKAN : ImageTestES3.SourceAHBMipTarget2DMip/* = SKIP
7158 PIXEL6 VULKAN : ImageTestES3.SourceAHBMipTarget2DMipGenerateMipmap/* = SKIP
7279 PIXEL6 VULKAN : PixelLocalStorageTest.EarlyFragmentTests/ES3_1_Vulkan_EmulatePixelLocalStorage* = SKIP
7556 PIXEL6 VULKAN : StateChangeTestES3.StencilWriteMaskVsDiscard/* = SKIP
// ARM drivers cannot support xfb emulation because they lack support for the
// vertexPipelineStoresAndAtomics Vulkan feature. The tests that force-enable this feature are

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

@ -285,6 +285,7 @@ constexpr PackedEnumMap<Feature, const char *> kFeatureNames = {{
{Feature::UploadTextureDataInChunks, "uploadTextureDataInChunks"},
{Feature::UseInstancedPointSpriteEmulation, "useInstancedPointSpriteEmulation"},
{Feature::UseMultipleDescriptorsForExternalFormats, "useMultipleDescriptorsForExternalFormats"},
{Feature::UseNonZeroStencilWriteMaskStaticState, "useNonZeroStencilWriteMaskStaticState"},
{Feature::UseSystemMemoryForConstantBuffers, "useSystemMemoryForConstantBuffers"},
{Feature::UseUnusedBlocksWithStandardOrSharedLayout,
"useUnusedBlocksWithStandardOrSharedLayout"},

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

@ -266,6 +266,7 @@ enum class Feature
UploadTextureDataInChunks,
UseInstancedPointSpriteEmulation,
UseMultipleDescriptorsForExternalFormats,
UseNonZeroStencilWriteMaskStaticState,
UseSystemMemoryForConstantBuffers,
UseUnusedBlocksWithStandardOrSharedLayout,
VertexIDDoesNotIncludeBaseVertex,