Vulkan: Make depth-correction uniform controlled

This change makes sure SPIR-V transformations are not required for depth
correction, having the number of potential pipelines.

Bug: angleproject:5881
Change-Id: If3f66b34bdd1127ae588cbc822ea7cf01fa8621f
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3691801
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Charlie Lao <cclao@google.com>
This commit is contained in:
Shahbaz Youssefi 2022-06-06 12:09:45 -04:00 коммит произвёл Angle LUCI CQ
Родитель 4868e5a700
Коммит ce3c0fe901
16 изменённых файлов: 149 добавлений и 179 удалений

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

@ -26,7 +26,7 @@
// Version number for shader translation API.
// It is incremented every time the API changes.
#define ANGLE_SH_VERSION 277
#define ANGLE_SH_VERSION 279
enum ShShaderSpec
{
@ -321,7 +321,9 @@ const ShCompileOptions SH_REWRITE_ROW_MAJOR_MATRICES = UINT64_C(1) << 49;
// Drop any explicit precision qualifiers from shader.
const ShCompileOptions SH_IGNORE_PRECISION_QUALIFIERS = UINT64_C(1) << 50;
// Bit 51 is unused.
// Ask compiler to generate code for depth correction to conform to the Vulkan clip space. If
// VK_EXT_depth_clip_control is supported, this code is not generated, saving a uniform look up.
const ShCompileOptions SH_ADD_VULKAN_DEPTH_CORRECTION = UINT64_C(1) << 51;
// Note: bit 52 is unused
@ -875,7 +877,8 @@ extern const char kDriverUniformsVarName[];
// - 5 bits for advanced blend equation
// - 6 bits for sample count
// - 8 bits for enabled clip planes
// - 12 bits unused
// - 1 bit for whether depth should be transformed to Vulkan clip space
// - 11 bits unused
constexpr uint32_t kDriverUniformsMiscSwapXYMask = 0x1;
constexpr uint32_t kDriverUniformsMiscAdvancedBlendEquationOffset = 1;
constexpr uint32_t kDriverUniformsMiscAdvancedBlendEquationMask = 0x1F;
@ -883,6 +886,8 @@ constexpr uint32_t kDriverUniformsMiscSampleCountOffset = 6;
constexpr uint32_t kDriverUniformsMiscSampleCountMask = 0x3F;
constexpr uint32_t kDriverUniformsMiscEnabledClipPlanesOffset = 12;
constexpr uint32_t kDriverUniformsMiscEnabledClipPlanesMask = 0xFF;
constexpr uint32_t kDriverUniformsMiscTransformDepthOffset = 20;
constexpr uint32_t kDriverUniformsMiscTransformDepthMask = 0x1;
// Interface block array name used for atomic counter emulation
extern const char kAtomicCountersBlockName[];
@ -901,7 +906,7 @@ extern const char kXfbEmulationBufferFieldName[];
extern const char kXfbExtensionPositionOutName[];
// Pre-rotation support
extern const char kPreRotationRotatePositionFunctionName[];
extern const char kTransformPositionFunctionName[];
// EXT_shader_framebuffer_fetch and EXT_shader_framebuffer_fetch_non_coherent
extern const char kInputAttachmentName[];

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

@ -984,7 +984,7 @@ const char kXfbEmulationBufferBlockName[] = "ANGLEXfbBuffer";
const char kXfbEmulationBufferName[] = "ANGLEXfb";
const char kXfbEmulationBufferFieldName[] = "xfbOut";
const char kPreRotationRotatePositionFunctionName[] = "ANGLEPreRotatePositionXY";
const char kTransformPositionFunctionName[] = "ANGLETransformPosition";
const char kXfbExtensionPositionOutName[] = "ANGLEXfbPosition";

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

@ -193,13 +193,13 @@ bool TranslatorMetal::transformDepthBeforeCorrection(TIntermBlock *root,
TVector<int> swizzleOffsetZ = {2};
TIntermSwizzle *positionZ = new TIntermSwizzle(positionRef, swizzleOffsetZ);
// Create a ref to "depthRange.reserved"
// Create a ref to "zscale"
TIntermTyped *viewportZScale = driverUniforms->getViewportZScale();
// Create the expression "gl_Position.z * depthRange.reserved".
// Create the expression "gl_Position.z * zscale".
TIntermBinary *zScale = new TIntermBinary(EOpMul, positionZ->deepCopy(), viewportZScale);
// Create the assignment "gl_Position.z = gl_Position.z * depthRange.reserved"
// Create the assignment "gl_Position.z = gl_Position.z * zscale"
TIntermTyped *positionZLHS = positionZ->deepCopy();
TIntermBinary *assignment = new TIntermBinary(TOperator::EOpAssign, positionZLHS, zScale);

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

@ -506,14 +506,15 @@ ANGLE_NO_DISCARD bool TranslatorMetalDirect::insertRasterizationDiscardLogic(TIn
TIntermSymbol *positionRef = new TIntermSymbol(position);
// Create vec4(-3, -3, -3, 1):
auto vec4Type = new TType(EbtFloat, 4);
TIntermSequence *vec4Args = new TIntermSequence();
vec4Args->push_back(CreateFloatNode(-3.0f, EbpMedium));
vec4Args->push_back(CreateFloatNode(-3.0f, EbpMedium));
vec4Args->push_back(CreateFloatNode(-3.0f, EbpMedium));
vec4Args->push_back(CreateFloatNode(1.0f, EbpMedium));
auto vec4Type = new TType(EbtFloat, 4);
TIntermSequence vec4Args = {
CreateFloatNode(-3.0f, EbpMedium),
CreateFloatNode(-3.0f, EbpMedium),
CreateFloatNode(-3.0f, EbpMedium),
CreateFloatNode(1.0f, EbpMedium),
};
TIntermAggregate *constVarConstructor =
TIntermAggregate::CreateConstructor(*vec4Type, vec4Args);
TIntermAggregate::CreateConstructor(*vec4Type, &vec4Args);
// Create the assignment "gl_Position = vec4(-3, -3, -3, 1)"
TIntermBinary *assignment =
@ -542,13 +543,13 @@ bool TranslatorMetalDirect::transformDepthBeforeCorrection(TIntermBlock *root,
TVector<int> swizzleOffsetZ = {2};
TIntermSwizzle *positionZ = new TIntermSwizzle(positionRef, swizzleOffsetZ);
// Create a ref to "depthRange.reserved"
// Create a ref to "zscale"
TIntermTyped *viewportZScale = driverUniforms->getViewportZScale();
// Create the expression "gl_Position.z * depthRange.reserved".
// Create the expression "gl_Position.z * zscale".
TIntermBinary *zScale = new TIntermBinary(EOpMul, positionZ->deepCopy(), viewportZScale);
// Create the assignment "gl_Position.z = gl_Position.z * depthRange.reserved"
// Create the assignment "gl_Position.z = gl_Position.z * zscale"
TIntermTyped *positionZLHS = positionZ->deepCopy();
TIntermBinary *assignment = new TIntermBinary(TOperator::EOpAssign, positionZLHS, zScale);

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

@ -619,23 +619,33 @@ ANGLE_NO_DISCARD bool AddXfbExtensionSupport(TCompiler *compiler,
return compiler->validateAST(root);
}
ANGLE_NO_DISCARD bool AddVertexPreRotationSupport(TCompiler *compiler,
ShCompileOptions compileOptions,
TIntermBlock *root,
TSymbolTable *symbolTable,
SpecConst *specConst,
const DriverUniform *driverUniforms)
ANGLE_NO_DISCARD bool AddVertexTransformationSupport(TCompiler *compiler,
ShCompileOptions compileOptions,
TIntermBlock *root,
TSymbolTable *symbolTable,
SpecConst *specConst,
const DriverUniform *driverUniforms)
{
// Generate the following function and place it before main(). This function takes
// gl_Position.xy and rotates it.
// In GL the viewport transformation is slightly different - see the GL 2.0 spec section "2.12.1
// Controlling the Viewport". In Vulkan the corresponding spec section is currently "23.4.
// Coordinate Transformations". The following transformation needs to be done:
//
// vec2 ANGLEPreRotatePositionXY(vec2 position)
// z_vk = 0.5 * (w_gl + z_gl)
//
// where z_vk is the depth output of a Vulkan geometry-stage shader and z_gl is the same for GL.
//
// Generate the following function and place it before main(). This function takes
// gl_Position and rotates xy, and adjusts z (if necessary).
//
// vec4 ANGLETransformPosition(vec4 position)
// {
// return (swapXY ? position.yx : position) * flipXY;
// return vec4((swapXY ? position.yx : position.xy) * flipXY,
// transformDepth ? (gl_Position.z + gl_Position.w) / 2 : gl_Position.z,
// gl_Postion.w);
// }
const TType *vec2Type = StaticType::GetBasic<EbtFloat, EbpHigh, 2>();
TType *positionType = new TType(*vec2Type);
const TType *vec4Type = StaticType::GetBasic<EbtFloat, EbpHigh, 4>();
TType *positionType = new TType(*vec4Type);
positionType->setQualifier(EvqParamConst);
// Create the parameter variable.
@ -643,46 +653,71 @@ ANGLE_NO_DISCARD bool AddVertexPreRotationSupport(TCompiler *compiler,
SymbolType::AngleInternal);
TIntermSymbol *positionSymbol = new TIntermSymbol(positionVar);
// swapXY ? position.yx : position
// swapXY ? position.yx : position.xy
TIntermTyped *swapXY = specConst->getSwapXY();
if (swapXY == nullptr)
{
swapXY = driverUniforms->getSwapXY();
}
TIntermTyped *swapped = new TIntermSwizzle(positionSymbol, {1, 0});
TIntermTyped *rotatedXY = new TIntermTernary(swapXY, swapped, positionSymbol->deepCopy());
TIntermTyped *xy = new TIntermSwizzle(positionSymbol, {0, 1});
TIntermTyped *swappedXY = new TIntermSwizzle(positionSymbol->deepCopy(), {1, 0});
TIntermTyped *rotatedXY = new TIntermTernary(swapXY, swappedXY, xy);
// (swapXY ? position.yx : position) * flipXY
// (swapXY ? position.yx : position.xy) * flipXY
TIntermTyped *flipXY = driverUniforms->getFlipXY(symbolTable, DriverUniformFlip::PreFragment);
TIntermTyped *rotatedFlippedXY = new TIntermBinary(EOpMul, rotatedXY, flipXY);
// (gl_Position.z + gl_Position.w) / 2
TIntermTyped *z = new TIntermSwizzle(positionSymbol->deepCopy(), {2});
TIntermTyped *w = new TIntermSwizzle(positionSymbol->deepCopy(), {3});
TIntermTyped *transformedDepth = z;
if ((compileOptions & SH_ADD_VULKAN_DEPTH_CORRECTION) != 0)
{
TIntermBinary *zPlusW = new TIntermBinary(EOpAdd, z, w->deepCopy());
TIntermBinary *halfZPlusW =
new TIntermBinary(EOpMul, zPlusW, CreateFloatNode(0.5, EbpMedium));
// transformDepth ? (gl_Position.z + gl_Position.w) / 2 : gl_Position.z,
TIntermTyped *transformDepth = driverUniforms->getTransformDepth();
transformedDepth = new TIntermTernary(transformDepth, halfZPlusW, z->deepCopy());
}
// vec4(...);
TIntermSequence args = {
rotatedFlippedXY,
transformedDepth,
w,
};
TIntermTyped *transformedPosition = TIntermAggregate::CreateConstructor(*vec4Type, &args);
// Create the function body, which has a single return statement.
TIntermBlock *body = new TIntermBlock;
body->appendStatement(new TIntermBranch(EOpReturn, rotatedFlippedXY));
body->appendStatement(new TIntermBranch(EOpReturn, transformedPosition));
// Declare the function
TFunction *rotatePositionFunction =
new TFunction(symbolTable, ImmutableString(vk::kPreRotationRotatePositionFunctionName),
SymbolType::AngleInternal, vec2Type, true);
rotatePositionFunction->addParameter(positionVar);
TFunction *transformPositionFunction =
new TFunction(symbolTable, ImmutableString(vk::kTransformPositionFunctionName),
SymbolType::AngleInternal, vec4Type, true);
transformPositionFunction->addParameter(positionVar);
TIntermFunctionDefinition *functionDef =
CreateInternalFunctionDefinitionNode(*rotatePositionFunction, body);
CreateInternalFunctionDefinitionNode(*transformPositionFunction, body);
// Insert the function declaration before main().
const size_t mainIndex = FindMainIndex(root);
root->insertChildNodes(mainIndex, {functionDef});
// Create a call to ANGLEPreRotatePositionXY, for the sole purpose of preventing it from being
// Create a call to ANGLETransformPosition, for the sole purpose of preventing it from being
// culled as unused by glslang.
if ((compileOptions & SH_GENERATE_SPIRV_THROUGH_GLSLANG) != 0)
{
TIntermSequence vec2Zero;
vec2Zero.push_back(CreateZeroNode(*vec2Type));
TIntermAggregate *rotateCall =
TIntermAggregate::CreateFunctionCall(*rotatePositionFunction, &vec2Zero);
if (!RunAtTheBeginningOfShader(compiler, root, rotateCall))
TIntermSequence vec4Zero;
vec4Zero.push_back(CreateZeroNode(*vec4Type));
TIntermAggregate *transformCall =
TIntermAggregate::CreateFunctionCall(*transformPositionFunction, &vec4Zero);
if (!RunAtTheBeginningOfShader(compiler, root, transformCall))
{
return false;
}
@ -1096,9 +1131,9 @@ bool TranslatorVulkan::translateImpl(TInfoSinkBase &sink,
}
}
// Add support code for pre-rotation in the vertex processing stages.
if (!AddVertexPreRotationSupport(this, compileOptions, root, &getSymbolTable(), specConst,
driverUniforms))
// Add support code for pre-rotation and depth correction in the vertex processing stages.
if (!AddVertexTransformationSupport(this, compileOptions, root, &getSymbolTable(),
specConst, driverUniforms))
{
return false;
}

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

@ -354,6 +354,21 @@ TIntermTyped *DriverUniform::getClipDistancesEnabled() const
return enabledMask;
}
TIntermTyped *DriverUniform::getTransformDepth() const
{
TIntermTyped *miscRef = createDriverUniformRef(kMisc);
TIntermTyped *transformDepth = new TIntermBinary(
EOpBitShiftRight, miscRef, CreateUIntNode(vk::kDriverUniformsMiscTransformDepthOffset));
transformDepth = new TIntermBinary(EOpBitwiseAnd, transformDepth,
CreateUIntNode(vk::kDriverUniformsMiscTransformDepthMask));
TIntermSequence args = {
transformDepth,
};
return TIntermAggregate::CreateConstructor(*StaticType::GetBasic<EbtBool, EbpUndefined>(),
&args);
}
//
// Class DriverUniformExtended
//

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

@ -66,6 +66,7 @@ class DriverUniform
TIntermTyped *getAdvancedBlendEquation() const;
TIntermTyped *getNumSamples() const;
TIntermTyped *getClipDistancesEnabled() const;
TIntermTyped *getTransformDepth() const;
virtual TIntermTyped *getViewport() const { return nullptr; }
virtual TIntermTyped *getXfbBufferOffsets() const { return nullptr; }

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

@ -1123,7 +1123,6 @@ class SpirvIDDiscoverer final : angle::NonCopyable
}
spirv::IdRef floatId() const { return mFloatId; }
spirv::IdRef vec2Id() const { return mVec2Id; }
spirv::IdRef vec4Id() const { return mVec4Id; }
spirv::IdRef vec4OutTypePointerId() const { return mVec4OutTypePointerId; }
spirv::IdRef intId() const { return mIntId; }
@ -1167,7 +1166,6 @@ class SpirvIDDiscoverer final : angle::NonCopyable
// and swizzles.
//
// - mFloatId: id of OpTypeFloat 32
// - mVec2Id: id of OpTypeVector %mFloatId 2
// - mVec4Id: id of OpTypeVector %mFloatId 4
// - mVec4OutTypePointerId: id of OpTypePointer Output %mVec4Id
// - mIntId: id of OpTypeInt 32 1
@ -1179,7 +1177,6 @@ class SpirvIDDiscoverer final : angle::NonCopyable
// - mOutputPerVertexId: id of OpVariable %mOutputPerVertexTypePointerId Output
//
spirv::IdRef mFloatId;
spirv::IdRef mVec2Id;
spirv::IdRef mVec4Id;
spirv::IdRef mVec4OutTypePointerId;
spirv::IdRef mIntId;
@ -1371,12 +1368,7 @@ void SpirvIDDiscoverer::visitTypeVector(spirv::IdResult id,
spirv::IdRef componentId,
spirv::LiteralInteger componentCount)
{
// Only interested in OpTypeVector %mFloatId 2/4 and OpTypeVector %mIntId 4
if (componentId == mFloatId && componentCount == 2)
{
ASSERT(!mVec2Id.valid());
mVec2Id = id;
}
// Only interested in OpTypeVector %mFloatId 4 and OpTypeVector %mIntId 4
if (componentId == mFloatId && componentCount == 4)
{
ASSERT(!mVec4Id.valid());
@ -1447,12 +1439,6 @@ void SpirvIDDiscoverer::writePendingDeclarations(spirv::Blob *blobOut)
spirv::WriteTypeFloat(blobOut, mFloatId, spirv::LiteralInteger(32));
}
if (!mVec2Id.valid())
{
mVec2Id = SpirvTransformerBase::GetNewId(blobOut);
spirv::WriteTypeVector(blobOut, mVec2Id, mFloatId, spirv::LiteralInteger(2));
}
if (!mVec4Id.valid())
{
mVec4Id = SpirvTransformerBase::GetNewId(blobOut);
@ -2777,28 +2763,17 @@ class SpirvPositionTransformer final : angle::NonCopyable
spirv::Blob *blobOut);
private:
void preRotateXY(const SpirvIDDiscoverer &ids,
spirv::IdRef vec2Id,
spirv::IdRef xyId,
spirv::IdRef rotatedXYId,
spirv::Blob *blobOut);
void transformZToVulkanClipSpace(const SpirvIDDiscoverer &ids,
spirv::IdRef zId,
spirv::IdRef wId,
spirv::IdRef *correctedZIdOut,
spirv::Blob *blobOut);
GlslangSpirvOptions mOptions;
spirv::IdRef mPreRotatePositionFuncId;
spirv::IdRef mTransformPositionFuncId;
};
void SpirvPositionTransformer::visitName(spirv::IdRef id, const spirv::LiteralString &name)
{
if (angle::BeginsWith(name, sh::vk::kPreRotationRotatePositionFunctionName))
if (angle::BeginsWith(name, sh::vk::kTransformPositionFunctionName))
{
ASSERT(!mPreRotatePositionFuncId.valid());
mPreRotatePositionFuncId = id;
ASSERT(!mTransformPositionFuncId.valid());
mTransformPositionFuncId = id;
}
}
@ -2807,86 +2782,20 @@ void SpirvPositionTransformer::writePositionTransformation(const SpirvIDDiscover
spirv::IdRef positionId,
spirv::Blob *blobOut)
{
// In GL the viewport transformation is slightly different - see the GL 2.0 spec section "2.12.1
// Controlling the Viewport". In Vulkan the corresponding spec section is currently "23.4.
// Coordinate Transformations". The following transformation needs to be done:
//
// z_vk = 0.5 * (w_gl + z_gl)
//
// where z_vk is the depth output of a Vulkan geometry-stage shader and z_gl is the same for GL.
// Generate the following SPIR-V for prerotation and depth transformation:
//
// // Create gl_Position.x and gl_Position.y for transformation, as well as gl_Position.z
// // and gl_Position.w for later.
// %xy = OpVectorShuffle %mVec2Id %Position %position 0 1
// %z = OpCompositeExtract %mFloatId %Position 2
// %w = OpCompositeExtract %mFloatId %Position 3
//
// // Transform %xy based on pre-rotation by making a call to the ANGLEPreRotatePositionXY
// // Transform position based on uniforms by making a call to the ANGLETransformPosition
// // function that the translator has already provided.
// %transformed = OpFunctionCall %mVec4Id %mTransformPositionFuncId %position
//
// // Transform %z if necessary, based on the above formula.
// %zPlusW = OpFAdd %mFloatId %z %w
// %correctedZ = OpFMul %mFloatId %zPlusW %mFloatHalfId
//
// // Create the rotated gl_Position from the rotated xy and corrected z components.
// %RotatedPosition = OpCompositeConstruct %mVec4Id %rotatedXY %correctedZ %w
// // Store the results back in gl_Position
// OpStore %PositionPointer %RotatedPosition
// OpStore %PositionPointer %transformedPosition
//
const spirv::IdRef xyId(SpirvTransformerBase::GetNewId(blobOut));
const spirv::IdRef zId(SpirvTransformerBase::GetNewId(blobOut));
const spirv::IdRef wId(SpirvTransformerBase::GetNewId(blobOut));
const spirv::IdRef rotatedXYId(SpirvTransformerBase::GetNewId(blobOut));
const spirv::IdRef rotatedPositionId(SpirvTransformerBase::GetNewId(blobOut));
const spirv::IdRef transformedPositionId(SpirvTransformerBase::GetNewId(blobOut));
spirv::WriteVectorShuffle(blobOut, ids.vec2Id(), xyId, positionId, positionId,
{spirv::LiteralInteger{0}, spirv::LiteralInteger{1}});
spirv::WriteCompositeExtract(blobOut, ids.floatId(), zId, positionId,
{spirv::LiteralInteger{2}});
spirv::WriteCompositeExtract(blobOut, ids.floatId(), wId, positionId,
{spirv::LiteralInteger{3}});
preRotateXY(ids, ids.vec2Id(), xyId, rotatedXYId, blobOut);
spirv::IdRef correctedZId;
transformZToVulkanClipSpace(ids, zId, wId, &correctedZId, blobOut);
spirv::WriteCompositeConstruct(blobOut, ids.vec4Id(), rotatedPositionId,
{rotatedXYId, correctedZId, wId});
spirv::WriteStore(blobOut, positionPointerId, rotatedPositionId, nullptr);
}
void SpirvPositionTransformer::preRotateXY(const SpirvIDDiscoverer &ids,
spirv::IdRef vec2Id,
spirv::IdRef xyId,
spirv::IdRef rotatedXYId,
spirv::Blob *blobOut)
{
spirv::WriteFunctionCall(blobOut, vec2Id, rotatedXYId, mPreRotatePositionFuncId, {xyId});
}
void SpirvPositionTransformer::transformZToVulkanClipSpace(const SpirvIDDiscoverer &ids,
spirv::IdRef zId,
spirv::IdRef wId,
spirv::IdRef *correctedZIdOut,
spirv::Blob *blobOut)
{
if (!mOptions.transformPositionToVulkanClipSpace)
{
*correctedZIdOut = zId;
return;
}
const spirv::IdRef zPlusWId(SpirvTransformerBase::GetNewId(blobOut));
*correctedZIdOut = SpirvTransformerBase::GetNewId(blobOut);
// %zPlusW = OpFAdd %mFloatId %z %w
spirv::WriteFAdd(blobOut, ids.floatId(), zPlusWId, zId, wId);
// %correctedZ = OpFMul %mFloatId %zPlusW %mFloatHalfId
spirv::WriteFMul(blobOut, ids.floatId(), *correctedZIdOut, zPlusWId, ids.floatHalfId());
spirv::WriteFunctionCall(blobOut, ids.vec4Id(), transformedPositionId, mTransformPositionFuncId,
{positionId});
spirv::WriteStore(blobOut, positionPointerId, transformedPositionId, nullptr);
}
// A SPIR-V transformer. It walks the instructions and modifies them as necessary, for example to

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

@ -54,13 +54,12 @@ struct GlslangSourceOptions
struct GlslangSpirvOptions
{
gl::ShaderType shaderType = gl::ShaderType::InvalidEnum;
bool negativeViewportSupported = false;
bool transformPositionToVulkanClipSpace = false;
bool removeDebugInfo = false;
bool isLastPreFragmentStage = false;
bool isTransformFeedbackStage = false;
bool isTransformFeedbackEmulated = false;
gl::ShaderType shaderType = gl::ShaderType::InvalidEnum;
bool negativeViewportSupported = false;
bool removeDebugInfo = false;
bool isLastPreFragmentStage = false;
bool isTransformFeedbackStage = false;
bool isTransformFeedbackEmulated = false;
};
struct UniformBindingInfo final

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

@ -127,6 +127,7 @@ std::shared_ptr<WaitableCompileEvent> ShaderMtl::compile(const gl::Context *cont
}
// If compiling through SPIR-V
compileOptions |= SH_ADD_VULKAN_XFB_EMULATION_SUPPORT_CODE;
compileOptions |= SH_ADD_VULKAN_DEPTH_CORRECTION;
// If compiling through SPIR-V. This path outputs text, so cannot use the direct SPIR-V gen
// path unless fixed.
compileOptions |= SH_GENERATE_SPIRV_THROUGH_GLSLANG;

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

@ -419,8 +419,7 @@ angle::Result GlslangTransformSpirvCode(const gl::ShaderBitSet &linkedShaderStag
for (const gl::ShaderType shaderType : linkedShaderStages)
{
GlslangSpirvOptions options;
options.shaderType = shaderType;
options.transformPositionToVulkanClipSpace = true;
options.shaderType = shaderType;
options.isTransformFeedbackStage =
shaderType == gl::ShaderType::Vertex && isTransformFeedbackEnabled;
options.isTransformFeedbackEmulated = true;

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

@ -84,6 +84,7 @@ struct GraphicsDriverUniforms
// - Advanced blend equation
// - Sample count
// - Enabled clip planes
// - Depth transformation
uint32_t misc;
};
static_assert(sizeof(GraphicsDriverUniforms) % (sizeof(uint32_t) * 4) == 0,
@ -5130,6 +5131,10 @@ angle::Result ContextVk::syncState(const gl::Context *context,
&mGraphicsPipelineTransition,
!glState.isClipControlDepthZeroToOne());
}
else
{
invalidateGraphicsDriverUniforms();
}
break;
case gl::State::ExtendedDirtyBitType::EXTENDED_DIRTY_BIT_CLIP_DISTANCES:
invalidateGraphicsDriverUniforms();
@ -6177,6 +6182,8 @@ angle::Result ContextVk::handleDirtyGraphicsDriverUniforms(DirtyBits::Iterator *
const uint32_t swapXY = IsRotatedAspectRatio(mCurrentRotationDrawFramebuffer);
const uint32_t enabledClipDistances = mState.getEnabledClipDistances().bits();
const uint32_t transformDepth =
getFeatures().supportsDepthClipControl.enabled ? 0 : !mState.isClipControlDepthZeroToOne();
static_assert(angle::BitMask<uint32_t>(gl::IMPLEMENTATION_MAX_CLIP_DISTANCES) <=
sh::vk::kDriverUniformsMiscEnabledClipPlanesMask,
@ -6186,11 +6193,13 @@ angle::Result ContextVk::handleDirtyGraphicsDriverUniforms(DirtyBits::Iterator *
ASSERT((advancedBlendEquation & ~sh::vk::kDriverUniformsMiscAdvancedBlendEquationMask) == 0);
ASSERT((numSamples & ~sh::vk::kDriverUniformsMiscSampleCountMask) == 0);
ASSERT((enabledClipDistances & ~sh::vk::kDriverUniformsMiscEnabledClipPlanesMask) == 0);
ASSERT((transformDepth & ~sh::vk::kDriverUniformsMiscTransformDepthMask) == 0);
const uint32_t misc =
swapXY | advancedBlendEquation << sh::vk::kDriverUniformsMiscAdvancedBlendEquationOffset |
numSamples << sh::vk::kDriverUniformsMiscSampleCountOffset |
enabledClipDistances << sh::vk::kDriverUniformsMiscEnabledClipPlanesOffset;
enabledClipDistances << sh::vk::kDriverUniformsMiscEnabledClipPlanesOffset |
transformDepth << sh::vk::kDriverUniformsMiscTransformDepthOffset;
// Copy and flush to the device.
*driverUniforms = {

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

@ -69,12 +69,11 @@ bool ValidateTransformedSpirV(const gl::ShaderBitSet &linkedShaderStages,
for (gl::ShaderType shaderType : linkedShaderStages)
{
GlslangSpirvOptions options;
options.shaderType = shaderType;
options.negativeViewportSupported = false;
options.transformPositionToVulkanClipSpace = true;
options.removeDebugInfo = true;
options.isLastPreFragmentStage = shaderType == lastPreFragmentStage;
options.isTransformFeedbackStage = shaderType == lastPreFragmentStage;
options.shaderType = shaderType;
options.negativeViewportSupported = false;
options.removeDebugInfo = true;
options.isLastPreFragmentStage = shaderType == lastPreFragmentStage;
options.isTransformFeedbackStage = shaderType == lastPreFragmentStage;
angle::spirv::Blob transformed;
if (GlslangWrapperVk::TransformSpirV(options, variableInfoMap, spirvBlobs[shaderType],
@ -190,13 +189,6 @@ angle::Result ProgramInfo::initProgram(ContextVk *contextVk,
options.isTransformFeedbackEmulated = contextVk->getFeatures().emulateTransformFeedback.enabled;
options.negativeViewportSupported = contextVk->getFeatures().supportsNegativeViewport.enabled;
if (isLastPreFragmentStage)
{
options.transformPositionToVulkanClipSpace =
optionBits.enableDepthCorrection &&
!contextVk->getFeatures().supportsDepthClipControl.enabled;
}
ANGLE_TRY(GlslangWrapperVk::TransformSpirV(options, variableInfoMap, originalSpirvBlob,
&transformedSpirvBlob));
ANGLE_TRY(vk::InitShaderAndSerial(contextVk, &mShaders[shaderType].get(),
@ -750,7 +742,6 @@ angle::Result ProgramExecutableVk::getGraphicsPipeline(ContextVk *contextVk,
mTransformOptions.enableLineRasterEmulation = contextVk->isBresenhamEmulationEnabled(mode);
mTransformOptions.surfaceRotation = desc.getSurfaceRotation();
mTransformOptions.enableDepthCorrection = !glState.isClipControlDepthZeroToOne();
mTransformOptions.removeTransformFeedbackEmulation =
contextVk->getFeatures().emulateTransformFeedback.enabled &&
!glState.isTransformFeedbackActiveUnpaused();

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

@ -53,10 +53,9 @@ struct ProgramTransformOptions final
{
uint8_t enableLineRasterEmulation : 1;
uint8_t surfaceRotation : 1;
uint8_t enableDepthCorrection : 1;
uint8_t removeTransformFeedbackEmulation : 1;
uint8_t reserved : 4; // must initialize to zero
static constexpr uint32_t kPermutationCount = 0x1 << 4;
uint8_t reserved : 5; // must initialize to zero
static constexpr uint32_t kPermutationCount = 0x1 << 3;
};
static_assert(sizeof(ProgramTransformOptions) == 1, "Size check failed");
static_assert(static_cast<int>(SurfaceRotation::EnumCount) <= 8, "Size check failed");

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

@ -81,6 +81,11 @@ std::shared_ptr<WaitableCompileEvent> ShaderVk::compile(const gl::Context *conte
compileOptions |= SH_USE_SPECIALIZATION_CONSTANT;
}
if (!contextVk->getFeatures().supportsDepthClipControl.enabled)
{
compileOptions |= SH_ADD_VULKAN_DEPTH_CORRECTION;
}
if (contextVk->getFeatures().supportsTransformFeedbackExtension.enabled)
{
compileOptions |= SH_ADD_VULKAN_XFB_EXTENSION_SUPPORT_CODE;

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

@ -268,5 +268,6 @@
6678 TSAN : dEQP-EGL.functional.multithread.* = SKIP
6678 TSAN : dEQP-EGL.functional.sharing.gles2.multithread.* = SKIP
7327 TSAN : dEQP-EGL.functional.color_clears.multi_thread.gles3.rgba8888_window = SKIP
7327 TSAN : dEQP-EGL.functional.render.multi_thread.gles3.rgba8888_window = SKIP
6678 UBSAN : dEQP-EGL.functional.sharing.gles2.multithread.* = SKIP