Commit 18ddd131 by Shahbaz Youssefi Committed by Angle LUCI CQ

Vulkan: SPIR-V Gen: Support mediump/lowp

The mediump and lowp precisions translate to a RelaxedPrecision decoration in SPIR-V. This change implements this decoration and enables SPIR-V generation when emulating Bresenham lines. Prior to this change, Bresenham line emulation resulted in a validation error due to the vertex shader output being without RelaxedPrecision but the fragment shader input (translated by glslang) with it. The function that produces a new id is given a list of decorations to apply, which itself is automatically deriven from the TType where applicable, to minimize the risk of any id missing this decoration. Bug: angleproject:4889 Change-Id: I30cc5a278634c5d83d63cd65b057336f9f573baa Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2946113 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent 33aa7ef0
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#ifndef COMPILER_TRANSLATOR_BUILDSPIRV_H_ #ifndef COMPILER_TRANSLATOR_BUILDSPIRV_H_
#define COMPILER_TRANSLATOR_BUILDSPIRV_H_ #define COMPILER_TRANSLATOR_BUILDSPIRV_H_
#include "common/FixedVector.h"
#include "common/hash_utils.h" #include "common/hash_utils.h"
#include "common/spirv/spirv_instruction_builder_autogen.h" #include "common/spirv/spirv_instruction_builder_autogen.h"
#include "compiler/translator/Compiler.h" #include "compiler/translator/Compiler.h"
...@@ -156,6 +157,16 @@ struct SpirvTypeData ...@@ -156,6 +157,16 @@ struct SpirvTypeData
uint32_t matrixStride; uint32_t matrixStride;
}; };
// Decorations to be applied to variable or intermediate ids which are not part of the SPIR-V type
// and are not specific enough (like DescriptorSet) to be handled automatically. Currently, these
// are:
//
// RelaxedPrecision: used to implement |lowp| and |mediump|
// NoContraction: used to implement |precise|. TODO: support this. It requires the precise
// property to be promoted through the nodes in the AST, which currently isn't.
// http://anglebug.com/4889
using SpirvDecorations = angle::FixedVector<spv::Decoration, 2>;
// A block of code. SPIR-V produces forward references to blocks, such as OpBranchConditional // A block of code. SPIR-V produces forward references to blocks, such as OpBranchConditional
// specifying the id of the if and else blocks, each of those referencing the id of the block after // specifying the id of the if and else blocks, each of those referencing the id of the block after
// the else. Additionally, local variable declarations are accumulated at the top of the first // the else. Additionally, local variable declarations are accumulated at the top of the first
...@@ -213,11 +224,13 @@ class SPIRVBuilder : angle::NonCopyable ...@@ -213,11 +224,13 @@ class SPIRVBuilder : angle::NonCopyable
public: public:
SPIRVBuilder(TCompiler *compiler, SPIRVBuilder(TCompiler *compiler,
ShCompileOptions compileOptions, ShCompileOptions compileOptions,
bool forceHighp,
ShHashFunction64 hashFunction, ShHashFunction64 hashFunction,
NameMap &nameMap) NameMap &nameMap)
: mCompiler(compiler), : mCompiler(compiler),
mCompileOptions(compileOptions), mCompileOptions(compileOptions),
mShaderType(gl::FromGLenum<gl::ShaderType>(compiler->getShaderType())), mShaderType(gl::FromGLenum<gl::ShaderType>(compiler->getShaderType())),
mDisableRelaxedPrecision(forceHighp),
mNextAvailableId(1), mNextAvailableId(1),
mHashFunction(hashFunction), mHashFunction(hashFunction),
mNameMap(nameMap), mNameMap(nameMap),
...@@ -226,13 +239,16 @@ class SPIRVBuilder : angle::NonCopyable ...@@ -226,13 +239,16 @@ class SPIRVBuilder : angle::NonCopyable
mNextUnusedOutputLocation(0) mNextUnusedOutputLocation(0)
{} {}
spirv::IdRef getNewId(); spirv::IdRef getNewId(const SpirvDecorations &decorations);
SpirvType getSpirvType(const TType &type, TLayoutBlockStorage blockStorage) const; SpirvType getSpirvType(const TType &type, TLayoutBlockStorage blockStorage) const;
const SpirvTypeData &getTypeData(const TType &type, TLayoutBlockStorage blockStorage); const SpirvTypeData &getTypeData(const TType &type, TLayoutBlockStorage blockStorage);
const SpirvTypeData &getSpirvTypeData(const SpirvType &type, const char *blockName); const SpirvTypeData &getSpirvTypeData(const SpirvType &type, const char *blockName);
spirv::IdRef getTypePointerId(spirv::IdRef typeId, spv::StorageClass storageClass); spirv::IdRef getTypePointerId(spirv::IdRef typeId, spv::StorageClass storageClass);
spirv::IdRef getFunctionTypeId(spirv::IdRef returnTypeId, const spirv::IdRefList &paramTypeIds); spirv::IdRef getFunctionTypeId(spirv::IdRef returnTypeId, const spirv::IdRefList &paramTypeIds);
// Decorations that may apply to intermediate instructions (in addition to variables).
SpirvDecorations getDecorations(const TType &type);
spirv::Blob *getSpirvDebug() { return &mSpirvDebug; } spirv::Blob *getSpirvDebug() { return &mSpirvDebug; }
spirv::Blob *getSpirvDecorations() { return &mSpirvDecorations; } spirv::Blob *getSpirvDecorations() { return &mSpirvDecorations; }
spirv::Blob *getSpirvTypeAndConstantDecls() { return &mSpirvTypeAndConstantDecls; } spirv::Blob *getSpirvTypeAndConstantDecls() { return &mSpirvTypeAndConstantDecls; }
...@@ -264,11 +280,6 @@ class SPIRVBuilder : angle::NonCopyable ...@@ -264,11 +280,6 @@ class SPIRVBuilder : angle::NonCopyable
void writePerVertexBuiltIns(const TType &type, spirv::IdRef typeId); void writePerVertexBuiltIns(const TType &type, spirv::IdRef typeId);
void writeInterfaceVariableDecorations(const TType &type, spirv::IdRef variableId); void writeInterfaceVariableDecorations(const TType &type, spirv::IdRef variableId);
uint32_t calculateBaseAlignmentAndSize(const SpirvType &type,
uint32_t *sizeInStorageBlockOut,
uint32_t *matrixStrideOut);
uint32_t calculateSizeAndWriteOffsetDecorations(const SpirvType &type, spirv::IdRef typeId);
spirv::IdRef getBoolConstant(bool value); spirv::IdRef getBoolConstant(bool value);
spirv::IdRef getUintConstant(uint32_t value); spirv::IdRef getUintConstant(uint32_t value);
spirv::IdRef getIntConstant(int32_t value); spirv::IdRef getIntConstant(int32_t value);
...@@ -283,6 +294,7 @@ class SPIRVBuilder : angle::NonCopyable ...@@ -283,6 +294,7 @@ class SPIRVBuilder : angle::NonCopyable
// the current function. // the current function.
spirv::IdRef declareVariable(spirv::IdRef typeId, spirv::IdRef declareVariable(spirv::IdRef typeId,
spv::StorageClass storageClass, spv::StorageClass storageClass,
const SpirvDecorations &decorations,
spirv::IdRef *initializerId, spirv::IdRef *initializerId,
const char *name); const char *name);
// Helper to declare specialization constants. // Helper to declare specialization constants.
...@@ -308,6 +320,12 @@ class SPIRVBuilder : angle::NonCopyable ...@@ -308,6 +320,12 @@ class SPIRVBuilder : angle::NonCopyable
private: private:
SpirvTypeData declareType(const SpirvType &type, const char *blockName); SpirvTypeData declareType(const SpirvType &type, const char *blockName);
uint32_t calculateBaseAlignmentAndSize(const SpirvType &type,
uint32_t *sizeInStorageBlockOut,
uint32_t *matrixStrideOut);
uint32_t calculateSizeAndWriteOffsetDecorations(const SpirvType &type, spirv::IdRef typeId);
void writeMemberDecorations(const SpirvType &type, spirv::IdRef typeId);
// Helpers for type declaration. // Helpers for type declaration.
void getImageTypeParameters(TBasicType type, void getImageTypeParameters(TBasicType type,
spirv::IdRef *sampledTypeOut, spirv::IdRef *sampledTypeOut,
...@@ -329,8 +347,9 @@ class SPIRVBuilder : angle::NonCopyable ...@@ -329,8 +347,9 @@ class SPIRVBuilder : angle::NonCopyable
void generateExecutionModes(spirv::Blob *blob); void generateExecutionModes(spirv::Blob *blob);
ANGLE_MAYBE_UNUSED TCompiler *mCompiler; ANGLE_MAYBE_UNUSED TCompiler *mCompiler;
ANGLE_MAYBE_UNUSED ShCompileOptions mCompileOptions; ShCompileOptions mCompileOptions;
gl::ShaderType mShaderType; gl::ShaderType mShaderType;
const bool mDisableRelaxedPrecision;
// Capabilities the shader is using. Accumulated as the instructions are generated. The Shader // Capabilities the shader is using. Accumulated as the instructions are generated. The Shader
// capability is unconditionally generated, so it's not tracked. // capability is unconditionally generated, so it's not tracked.
......
...@@ -186,14 +186,6 @@ bool CanFoldAggregateBuiltInOp(TOperator op) ...@@ -186,14 +186,6 @@ bool CanFoldAggregateBuiltInOp(TOperator op)
TIntermExpression::TIntermExpression(const TType &t) : TIntermTyped(), mType(t) {} TIntermExpression::TIntermExpression(const TType &t) : TIntermTyped(), mType(t) {}
void TIntermExpression::setTypePreservePrecision(const TType &t)
{
TPrecision precision = getPrecision();
mType = t;
ASSERT(mType.getBasicType() != EbtBool || precision == EbpUndefined);
mType.setPrecision(precision);
}
#define REPLACE_IF_IS(node, type, original, replacement) \ #define REPLACE_IF_IS(node, type, original, replacement) \
do \ do \
{ \ { \
......
...@@ -170,6 +170,7 @@ class TIntermTyped : public TIntermNode ...@@ -170,6 +170,7 @@ class TIntermTyped : public TIntermNode
bool isVector() const { return getType().isVector(); } bool isVector() const { return getType().isVector(); }
bool isScalar() const { return getType().isScalar(); } bool isScalar() const { return getType().isScalar(); }
bool isScalarInt() const { return getType().isScalarInt(); } bool isScalarInt() const { return getType().isScalarInt(); }
bool isPrecise() const { return getType().isPrecise(); }
const char *getBasicString() const { return getType().getBasicString(); } const char *getBasicString() const { return getType().getBasicString(); }
unsigned int getOutermostArraySize() const { return getType().getOutermostArraySize(); } unsigned int getOutermostArraySize() const { return getType().getOutermostArraySize(); }
...@@ -303,7 +304,6 @@ class TIntermExpression : public TIntermTyped ...@@ -303,7 +304,6 @@ class TIntermExpression : public TIntermTyped
protected: protected:
TType *getTypePointer() { return &mType; } TType *getTypePointer() { return &mType; }
void setType(const TType &t) { mType = t; } void setType(const TType &t) { mType = t; }
void setTypePreservePrecision(const TType &t);
TIntermExpression(const TIntermExpression &node) = default; TIntermExpression(const TIntermExpression &node) = default;
......
...@@ -13,7 +13,10 @@ ...@@ -13,7 +13,10 @@
namespace sh namespace sh
{ {
bool OutputSPIRV(TCompiler *compiler, TIntermBlock *root, ShCompileOptions compileOptions); bool OutputSPIRV(TCompiler *compiler,
TIntermBlock *root,
ShCompileOptions compileOptions,
bool forceHighp);
} // namespace sh } // namespace sh
#endif // COMPILER_TRANSLATOR_OUTPUTSPIRV_H_ #endif // COMPILER_TRANSLATOR_OUTPUTSPIRV_H_
...@@ -1313,7 +1313,7 @@ bool TranslatorVulkan::translate(TIntermBlock *root, ...@@ -1313,7 +1313,7 @@ bool TranslatorVulkan::translate(TIntermBlock *root,
return false; return false;
} }
return OutputSPIRV(this, root, compileOptions); return OutputSPIRV(this, root, compileOptions, precisionEmulation);
} }
#endif #endif
......
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