зеркало из https://github.com/AvaloniaUI/angle.git
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:
Родитель
4868e5a700
Коммит
ce3c0fe901
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче