Allow FPs to elevate default precision for the entire fragment program
Currently, GrConfigConversionEffect is able to round-trip on many
mobile GPUs because it uses highp for all intermediate variables
(including the texture fetch result). Separating the texture sample
into a different processor breaks that.
This is a blunt instrument, not to be used lightly.
This reverts commit dffe9827b1
.
Bug: skia:
Change-Id: I940af3256c47e6672a008d516db9e55669672ca3
Reviewed-on: https://skia-review.googlesource.com/11345
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
bf17eecf46
commit
33aa2c7b5c
@ -133,7 +133,7 @@ GrGLuint GLCpuPosInstancedArraysBench::setupShader(const GrGLContext* ctx) {
|
||||
// setup fragment shader
|
||||
GrShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_TypeModifier);
|
||||
SkString fshaderTxt(version);
|
||||
GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, *shaderCaps, &fshaderTxt);
|
||||
GrGLSLAppendDefaultFloatPrecisionDeclaration(kMedium_GrSLPrecision, *shaderCaps, &fshaderTxt);
|
||||
oColor.setTypeModifier(GrShaderVar::kIn_TypeModifier);
|
||||
oColor.appendDecl(shaderCaps, &fshaderTxt);
|
||||
fshaderTxt.append(";\n");
|
||||
|
@ -131,7 +131,7 @@ GrGLuint GLVec4ScalarBench::setupShader(const GrGLContext* ctx) {
|
||||
// next stage.
|
||||
GrShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_TypeModifier);
|
||||
SkString fshaderTxt(version);
|
||||
GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, *shaderCaps, &fshaderTxt);
|
||||
GrGLSLAppendDefaultFloatPrecisionDeclaration(kMedium_GrSLPrecision, *shaderCaps, &fshaderTxt);
|
||||
oPosition.setTypeModifier(GrShaderVar::kIn_TypeModifier);
|
||||
oPosition.appendDecl(shaderCaps, &fshaderTxt);
|
||||
fshaderTxt.append(";\n");
|
||||
|
@ -117,7 +117,7 @@ GrGLuint GLVertexAttributesBench::setupShader(const GrGLContext* ctx, uint32_t a
|
||||
// setup fragment shader
|
||||
GrShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_TypeModifier);
|
||||
SkString fshaderTxt(version);
|
||||
GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, *shaderCaps, &fshaderTxt);
|
||||
GrGLSLAppendDefaultFloatPrecisionDeclaration(kMedium_GrSLPrecision, *shaderCaps, &fshaderTxt);
|
||||
|
||||
const char* fsOutName;
|
||||
if (shaderCaps->mustDeclareFragmentShaderOutput()) {
|
||||
|
@ -116,11 +116,14 @@ enum GrSLPrecision {
|
||||
kMedium_GrSLPrecision,
|
||||
kHigh_GrSLPrecision,
|
||||
|
||||
// Default precision is medium. This is because on OpenGL ES 2 highp support is not
|
||||
// guaranteed. On (non-ES) OpenGL the specifiers have no effect on precision.
|
||||
kDefault_GrSLPrecision = kMedium_GrSLPrecision,
|
||||
// Default precision is a special tag that means "whatever the default for the program/type
|
||||
// combination is". In other words, it maps to the empty string in shader code. There are some
|
||||
// scenarios where kDefault is not allowed (as the default precision for a program, or for
|
||||
// varyings, for example).
|
||||
kDefault_GrSLPrecision,
|
||||
|
||||
kLast_GrSLPrecision = kHigh_GrSLPrecision
|
||||
// We only consider the "real" precisions here
|
||||
kLast_GrSLPrecision = kHigh_GrSLPrecision,
|
||||
};
|
||||
|
||||
static const int kGrSLPrecisionCount = kLast_GrSLPrecision + 1;
|
||||
|
@ -74,6 +74,8 @@ static inline const char* GrGLSLPrecisionString(GrSLPrecision p) {
|
||||
return "mediump";
|
||||
case kHigh_GrSLPrecision:
|
||||
return "highp";
|
||||
case kDefault_GrSLPrecision:
|
||||
return "";
|
||||
default:
|
||||
SkFAIL("Unexpected precision type.");
|
||||
return "";
|
||||
|
@ -51,6 +51,7 @@ protected:
|
||||
*/
|
||||
const Attribute& addVertexAttrib(const char* name, GrVertexAttribType type,
|
||||
GrSLPrecision precision = kDefault_GrSLPrecision) {
|
||||
precision = (kDefault_GrSLPrecision == precision) ? kMedium_GrSLPrecision : precision;
|
||||
fAttribs.emplace_back(name, type, precision);
|
||||
fVertexStride += fAttribs.back().fOffset;
|
||||
return fAttribs.back();
|
||||
|
@ -32,8 +32,10 @@ static const char* precision_to_string(GrSLPrecision p) {
|
||||
return "medium";
|
||||
case kHigh_GrSLPrecision:
|
||||
return "high";
|
||||
default:
|
||||
SkFAIL("Unexpected precision type.");
|
||||
return "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
GrShaderCaps::GrShaderCaps(const GrContextOptions& options) {
|
||||
@ -201,7 +203,7 @@ void GrShaderCaps::initSamplerPrecisionTable() {
|
||||
}
|
||||
|
||||
uint8_t* table = fSamplerPrecisions[visibility];
|
||||
table[kUnknown_GrPixelConfig] = kDefault_GrSLPrecision;
|
||||
table[kUnknown_GrPixelConfig] = lowp;
|
||||
table[kAlpha_8_GrPixelConfig] = lowp;
|
||||
table[kGray_8_GrPixelConfig] = lowp;
|
||||
table[kRGB_565_GrPixelConfig] = lowp;
|
||||
|
@ -1257,9 +1257,10 @@ static GrGLenum precision_to_gl_float_type(GrSLPrecision p) {
|
||||
return GR_GL_MEDIUM_FLOAT;
|
||||
case kHigh_GrSLPrecision:
|
||||
return GR_GL_HIGH_FLOAT;
|
||||
default:
|
||||
SkFAIL("Unexpected precision type.");
|
||||
return -1;
|
||||
}
|
||||
SkFAIL("Unknown precision.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static GrGLenum shader_type_to_gl_shader(GrShaderType type) {
|
||||
|
@ -3578,7 +3578,7 @@ bool GrGLGpu::createCopyProgram(GrTexture* srcTex) {
|
||||
fshaderTxt.appendf("#extension %s : require\n",
|
||||
shaderCaps->externalTextureExtensionString());
|
||||
}
|
||||
GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, *shaderCaps,
|
||||
GrGLSLAppendDefaultFloatPrecisionDeclaration(kMedium_GrSLPrecision, *shaderCaps,
|
||||
&fshaderTxt);
|
||||
vTexCoord.setTypeModifier(GrShaderVar::kIn_TypeModifier);
|
||||
vTexCoord.appendDecl(shaderCaps, &fshaderTxt);
|
||||
@ -3716,7 +3716,7 @@ bool GrGLGpu::createMipmapProgram(int progIdx) {
|
||||
fshaderTxt.appendf("#extension %s : require\n", extension);
|
||||
}
|
||||
}
|
||||
GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, *shaderCaps,
|
||||
GrGLSLAppendDefaultFloatPrecisionDeclaration(kMedium_GrSLPrecision, *shaderCaps,
|
||||
&fshaderTxt);
|
||||
for (int i = 0; i < numTaps; ++i) {
|
||||
vTexCoords[i].setTypeModifier(GrShaderVar::kIn_TypeModifier);
|
||||
@ -3831,7 +3831,7 @@ bool GrGLGpu::createWireRectProgram() {
|
||||
GrShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_TypeModifier);
|
||||
|
||||
SkString fshaderTxt(version);
|
||||
GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision,
|
||||
GrGLSLAppendDefaultFloatPrecisionDeclaration(kMedium_GrSLPrecision,
|
||||
*this->caps()->shaderCaps(),
|
||||
&fshaderTxt);
|
||||
uColor.appendDecl(this->caps()->shaderCaps(), &fshaderTxt);
|
||||
|
@ -85,7 +85,8 @@ GrGLSLFragmentShaderBuilder::GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* p
|
||||
, fCustomColorOutputIndex(-1)
|
||||
, fHasSecondaryOutput(false)
|
||||
, fUsedSampleOffsetArrays(0)
|
||||
, fHasInitializedSampleMask(false) {
|
||||
, fHasInitializedSampleMask(false)
|
||||
, fDefaultPrecision(kMedium_GrSLPrecision) {
|
||||
fSubstageIndices.push_back(0);
|
||||
#ifdef SK_DEBUG
|
||||
fUsedProcessorFeatures = GrProcessor::kNone_RequiredFeatures;
|
||||
@ -178,6 +179,10 @@ void GrGLSLFragmentShaderBuilder::overrideSampleCoverage(const char* mask) {
|
||||
fHasInitializedSampleMask = true;
|
||||
}
|
||||
|
||||
void GrGLSLFragmentShaderBuilder::elevateDefaultPrecision(GrSLPrecision precision) {
|
||||
fDefaultPrecision = SkTMax(fDefaultPrecision, precision);
|
||||
}
|
||||
|
||||
const char* GrGLSLFragmentShaderBuilder::dstColor() {
|
||||
SkDEBUGCODE(fHasReadDstColor = true;)
|
||||
|
||||
@ -279,7 +284,7 @@ GrSurfaceOrigin GrGLSLFragmentShaderBuilder::getSurfaceOrigin() const {
|
||||
|
||||
void GrGLSLFragmentShaderBuilder::onFinalize() {
|
||||
fProgramBuilder->varyingHandler()->getFragDecls(&this->inputs(), &this->outputs());
|
||||
GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision,
|
||||
GrGLSLAppendDefaultFloatPrecisionDeclaration(fDefaultPrecision,
|
||||
*fProgramBuilder->shaderCaps(),
|
||||
&this->precisionQualifier());
|
||||
if (fUsedSampleOffsetArrays & (1 << kSkiaDevice_Coordinates)) {
|
||||
|
@ -93,6 +93,13 @@ public:
|
||||
space coordinates. */
|
||||
virtual const char* distanceVectorName() const = 0;
|
||||
|
||||
/**
|
||||
* Overrides the default precision for the entire fragment program. Processors that require
|
||||
* high precision input (eg from incoming texture samples) may use this. For calculations that
|
||||
* are limited to a single processor's code, it is better to annotate individual declarations.
|
||||
*/
|
||||
virtual void elevateDefaultPrecision(GrSLPrecision) = 0;
|
||||
|
||||
/**
|
||||
* Fragment procs with child procs should call these functions before/after calling emitCode
|
||||
* on a child proc.
|
||||
@ -167,6 +174,7 @@ public:
|
||||
void appendOffsetToSample(const char* sampleIdx, Coordinates) override;
|
||||
void maskSampleCoverage(const char* mask, bool invert = false) override;
|
||||
void overrideSampleCoverage(const char* mask) override;
|
||||
void elevateDefaultPrecision(GrSLPrecision) override;
|
||||
const SkString& getMangleString() const override { return fMangleString; }
|
||||
void onBeforeChildProcEmitCode() override;
|
||||
void onAfterChildProcEmitCode() override;
|
||||
@ -225,13 +233,14 @@ private:
|
||||
*/
|
||||
SkString fMangleString;
|
||||
|
||||
bool fSetupFragPosition;
|
||||
bool fHasCustomColorOutput;
|
||||
int fCustomColorOutputIndex;
|
||||
bool fHasSecondaryOutput;
|
||||
uint8_t fUsedSampleOffsetArrays;
|
||||
bool fHasInitializedSampleMask;
|
||||
SkString fDistanceVectorOutput;
|
||||
bool fSetupFragPosition;
|
||||
bool fHasCustomColorOutput;
|
||||
int fCustomColorOutputIndex;
|
||||
bool fHasSecondaryOutput;
|
||||
uint8_t fUsedSampleOffsetArrays;
|
||||
bool fHasInitializedSampleMask;
|
||||
SkString fDistanceVectorOutput;
|
||||
GrSLPrecision fDefaultPrecision;
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
// some state to verify shaders and effects are consistent, this is reset between effects by
|
||||
|
@ -42,7 +42,7 @@ void GrGLSLVaryingHandler::internalAddVarying(const char* name,
|
||||
|
||||
SkASSERT(varying);
|
||||
v.fType = varying->fType;
|
||||
v.fPrecision = precision;
|
||||
v.fPrecision = (kDefault_GrSLPrecision == precision) ? kMedium_GrSLPrecision : precision;
|
||||
v.fIsFlat = flat;
|
||||
fProgramBuilder->nameVariable(&v.fVsOut, 'v', name);
|
||||
v.fVisibility = kNone_GrShaderFlags;
|
||||
|
Loading…
Reference in New Issue
Block a user