Revert "Revert "added support for sk_Dimensions to SkSL""

This reverts commit e6ab998bc2.

Bug: skia:
Change-Id: I19451f924d514dadac9d2c326bcc8404a1b501e9
Reviewed-on: https://skia-review.googlesource.com/149239
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
Ethan Nicholas 2018-08-24 16:43:57 -04:00 committed by Skia Commit-Bot
parent 9402c7dc37
commit cd700e9ab7
17 changed files with 135 additions and 28 deletions

View File

@ -133,7 +133,11 @@ void GrGLProgram::setFragmentData(const GrPipeline& pipeline, int* nextTexSample
void GrGLProgram::setRenderTargetState(const GrPrimitiveProcessor& primProc,
const GrRenderTargetProxy* proxy) {
GrRenderTarget* rt = proxy->peekRenderTarget();
// Load the RT height uniform if it is needed to y-flip gl_FragCoord.
// Load the RT size uniforms if they are needed
if (fBuiltinUniformHandles.fRTWidthUni.isValid() &&
fRenderTargetState.fRenderTargetSize.fWidth != rt->width()) {
fProgramDataManager.set1f(fBuiltinUniformHandles.fRTWidthUni, SkIntToScalar(rt->width()));
}
if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height()));

View File

@ -159,6 +159,15 @@ void GrGLProgramBuilder::computeCountsAndStrides(GrGLuint programID,
SkASSERT(fInstanceStride == primProc.debugOnly_instanceStride());
}
void GrGLProgramBuilder::addInputVars(const SkSL::Program::Inputs& inputs) {
if (inputs.fRTWidth) {
this->addRTWidthUniform(SKSL_RTWIDTH_NAME);
}
if (inputs.fRTHeight) {
this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
}
}
GrGLProgram* GrGLProgramBuilder::finalize() {
TRACE_EVENT0("skia", TRACE_FUNC);
@ -204,9 +213,7 @@ GrGLProgram* GrGLProgramBuilder::finalize() {
if (GR_GL_GET_ERROR(this->gpu()->glInterface()) == GR_GL_NO_ERROR) {
cached = this->checkLinkStatus(programID);
if (cached) {
if (inputs.fRTHeight) {
this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
}
this->addInputVars(inputs);
this->computeCountsAndStrides(programID, primProc, false);
}
} else {
@ -231,9 +238,7 @@ GrGLProgram* GrGLProgramBuilder::finalize() {
return nullptr;
}
inputs = fs->fInputs;
if (inputs.fRTHeight) {
this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
}
this->addInputVars(inputs);
if (!this->compileAndAttachShaders(glsl.c_str(), glsl.size(), programID,
GR_GL_FRAGMENT_SHADER, &shadersToDelete, settings,
inputs)) {

View File

@ -48,6 +48,7 @@ private:
GrGLProgramBuilder(GrGLGpu*, const GrPipeline&, const GrPrimitiveProcessor&,
GrProgramDesc*);
void addInputVars(const SkSL::Program::Inputs& inputs);
bool compileAndAttachShaders(const char* glsl,
int length,
GrGLuint programId,

View File

@ -371,6 +371,15 @@ void GrGLSLProgramBuilder::appendUniformDecls(GrShaderFlags visibility, SkString
this->uniformHandler()->appendUniformDecls(visibility, out);
}
void GrGLSLProgramBuilder::addRTWidthUniform(const char* name) {
SkASSERT(!fUniformHandles.fRTWidthUni.isValid());
GrGLSLUniformHandler* uniformHandler = this->uniformHandler();
fUniformHandles.fRTWidthUni =
uniformHandler->internalAddUniformArray(kFragment_GrShaderFlag,
kHalf_GrSLType, kDefault_GrSLPrecision,
name, false, 0, nullptr);
}
void GrGLSLProgramBuilder::addRTHeightUniform(const char* name) {
SkASSERT(!fUniformHandles.fRTHeightUni.isValid());
GrGLSLUniformHandler* uniformHandler = this->uniformHandler();

View File

@ -49,8 +49,12 @@ public:
return this->uniformHandler()->samplerSwizzle(handle);
}
// Used to add a uniform for the RenderTarget height (used for frag position) without mangling
// Used to add a uniform for the RenderTarget width (used for sk_Width) without mangling
// the name of the uniform inside of a stage.
void addRTWidthUniform(const char* name);
// Used to add a uniform for the RenderTarget height (used for sk_Height and frag position)
// without mangling the name of the uniform inside of a stage.
void addRTHeightUniform(const char* name);
// Generates a name for a variable. The generated string will be name prefixed by the prefix

View File

@ -20,7 +20,9 @@ class GrGLSLProgramBuilder;
// Handles for program uniforms (other than per-effect uniforms)
struct GrGLSLBuiltinUniformHandles {
GrGLSLProgramDataManager::UniformHandle fRTAdjustmentUni;
// We use the render target height to provide a y-down frag coord when specifying
// Render target width, used to implement sk_Width
GrGLSLProgramDataManager::UniformHandle fRTWidthUni;
// Render target height, used to implement sk_Height and to calculate sk_FragCoord when
// origin_upper_left is not supported.
GrGLSLProgramDataManager::UniformHandle fRTHeightUni;
};

View File

@ -57,6 +57,7 @@ Differences from GLSL
Use swizzles instead.
* Use texture() instead of textureProj(), e.g. texture(sampler2D, float3) is
equivalent to GLSL's textureProj(sampler2D, float3)
* Render target width and height are available via sk_Width and sk_Height
* some built-in functions and one or two rarely-used language features are not
yet supported (sorry!)

View File

@ -246,6 +246,12 @@ void CPPCodeGenerator::writeVariableReference(const VariableReference& ref) {
this->write("%s");
fFormatArgs.push_back(String("args.fOutputColor"));
break;
case SK_WIDTH_BUILTIN:
this->write("sk_Width");
break;
case SK_HEIGHT_BUILTIN:
this->write("sk_Height");
break;
default:
if (ref.fVariable.fType.kind() == Type::kSampler_Kind) {
this->write("%s");
@ -446,6 +452,9 @@ void CPPCodeGenerator::addUniform(const Variable& var) {
}
}
void CPPCodeGenerator::writeInputVars() {
}
void CPPCodeGenerator::writePrivateVars() {
for (const auto& p : fProgram) {
if (ProgramElement::kVar_Kind == p.fKind) {

View File

@ -68,6 +68,8 @@ private:
void writeVarInitializer(const Variable& var, const Expression& value) override;
void writeInputVars() override;
void writePrivateVars();
void writePrivateVarValues();

View File

@ -28,6 +28,8 @@
#define SK_LASTFRAGCOLOR_BUILTIN 10008
#define SK_MAIN_X_BUILTIN 10009
#define SK_MAIN_Y_BUILTIN 10010
#define SK_WIDTH_BUILTIN 10011
#define SK_HEIGHT_BUILTIN 10012
#define SK_FRAGCOORD_BUILTIN 15
#define SK_CLOCKWISE_BUILTIN 17
#define SK_VERTEXID_BUILTIN 42

View File

@ -730,7 +730,7 @@ void GLSLCodeGenerator::writeFragCoord() {
if (!fProgram.fSettings.fFlipY) {
this->write("gl_FragCoord");
} else if (const char* extension =
fProgram.fSettings.fCaps->fragCoordConventionsExtensionString()) {
fProgram.fSettings.fCaps->fragCoordConventionsExtensionString()) {
if (!fSetupFragPositionGlobal) {
if (fProgram.fSettings.fCaps->generation() < k150_GrGLSLGeneration) {
this->writeExtension(extension);
@ -740,19 +740,12 @@ void GLSLCodeGenerator::writeFragCoord() {
}
this->write("gl_FragCoord");
} else {
if (!fSetupFragPositionGlobal) {
if (!fSetupFragPositionLocal) {
// The Adreno compiler seems to be very touchy about access to "gl_FragCoord".
// Accessing glFragCoord.zw can cause a program to fail to link. Additionally,
// depending on the surrounding code, accessing .xy with a uniform involved can
// do the same thing. Copying gl_FragCoord.xy into a temp float2 beforehand
// (and only accessing .xy) seems to "fix" things.
const char* precision = usesPrecisionModifiers() ? "highp " : "";
fGlobals.writeText("uniform ");
fGlobals.writeText(precision);
fGlobals.writeText("float " SKSL_RTHEIGHT_NAME ";\n");
fSetupFragPositionGlobal = true;
}
if (!fSetupFragPositionLocal) {
const char* precision = usesPrecisionModifiers() ? "highp " : "";
fFunctionHeader += precision;
fFunctionHeader += " vec2 _sktmpCoord = gl_FragCoord.xy;\n";
@ -777,6 +770,12 @@ void GLSLCodeGenerator::writeVariableReference(const VariableReference& ref) {
case SK_FRAGCOORD_BUILTIN:
this->writeFragCoord();
break;
case SK_WIDTH_BUILTIN:
this->write("u_skRTWidth");
break;
case SK_HEIGHT_BUILTIN:
this->write("u_skRTHeight");
break;
case SK_CLOCKWISE_BUILTIN:
this->write(fProgram.fSettings.fFlipY ? "(!gl_FrontFacing)" : "gl_FrontFacing");
break;
@ -1494,6 +1493,21 @@ void GLSLCodeGenerator::writeProgramElement(const ProgramElement& e) {
}
}
void GLSLCodeGenerator::writeInputVars() {
if (fProgram.fInputs.fRTWidth) {
const char* precision = usesPrecisionModifiers() ? "highp " : "";
fGlobals.writeText("uniform ");
fGlobals.writeText(precision);
fGlobals.writeText("float " SKSL_RTWIDTH_NAME ";\n");
}
if (fProgram.fInputs.fRTHeight) {
const char* precision = usesPrecisionModifiers() ? "highp " : "";
fGlobals.writeText("uniform ");
fGlobals.writeText(precision);
fGlobals.writeText("float " SKSL_RTHEIGHT_NAME ";\n");
}
}
bool GLSLCodeGenerator::generateCode() {
fProgramKind = fProgram.fKind;
if (fProgramKind != Program::kPipelineStage_Kind) {
@ -1512,6 +1526,7 @@ bool GLSLCodeGenerator::generateCode() {
fOut = rawOut;
write_stringstream(fExtensions, *rawOut);
this->writeInputVars();
write_stringstream(fGlobals, *rawOut);
if (!fProgram.fSettings.fCaps->canUseFragCoord()) {

View File

@ -118,7 +118,7 @@ protected:
void writeModifiers(const Modifiers& modifiers, bool globalContext);
void writeGlobalVars(const VarDeclaration& vs);
virtual void writeInputVars();
virtual void writeVarInitializer(const Variable& var, const Expression& value);

View File

@ -1025,16 +1025,25 @@ std::unique_ptr<Expression> IRGenerator::convertIdentifier(const ASTIdentifier&
}
case Symbol::kVariable_Kind: {
const Variable* var = (const Variable*) result;
#ifndef SKSL_STANDALONE
if (var->fModifiers.fLayout.fBuiltin == SK_FRAGCOORD_BUILTIN) {
fInputs.fFlipY = true;
if (fSettings->fFlipY &&
(!fSettings->fCaps ||
!fSettings->fCaps->fragCoordConventionsExtensionString())) {
switch (var->fModifiers.fLayout.fBuiltin) {
case SK_WIDTH_BUILTIN:
fInputs.fRTWidth = true;
break;
case SK_HEIGHT_BUILTIN:
fInputs.fRTHeight = true;
}
}
break;
#ifndef SKSL_STANDALONE
case SK_FRAGCOORD_BUILTIN:
if (var->fModifiers.fLayout.fBuiltin == SK_FRAGCOORD_BUILTIN) {
fInputs.fFlipY = true;
if (fSettings->fFlipY &&
(!fSettings->fCaps ||
!fSettings->fCaps->fragCoordConventionsExtensionString())) {
fInputs.fRTHeight = true;
}
}
#endif
}
// default to kRead_RefKind; this will be corrected later if the variable is written to
return std::unique_ptr<VariableReference>(new VariableReference(
identifier.fOffset,

View File

@ -18,6 +18,9 @@
#include "SkSLProgramElement.h"
#include "SkSLSymbolTable.h"
// name of the render target width uniform
#define SKSL_RTWIDTH_NAME "u_skRTWidth"
// name of the render target height uniform
#define SKSL_RTHEIGHT_NAME "u_skRTHeight"
@ -88,6 +91,9 @@ struct Program {
};
struct Inputs {
// if true, this program requires the render target width uniform to be defined
bool fRTWidth;
// if true, this program requires the render target height uniform to be defined
bool fRTHeight;
@ -96,12 +102,13 @@ struct Program {
bool fFlipY;
void reset() {
fRTWidth = false;
fRTHeight = false;
fFlipY = false;
}
bool isEmpty() {
return !fRTHeight && !fFlipY;
return !fRTWidth && !fRTHeight && !fFlipY;
}
};

View File

@ -20,6 +20,9 @@ layout(builtin=10003) half4 sk_InColor;
layout(builtin=10004) out half4 sk_OutColor;
layout(builtin=10005) float2[] sk_TransformedCoords2D;
layout(builtin=10006) sampler2D[] sk_TextureSamplers;
layout(builtin=10011) half sk_Width;
layout(builtin=10012) half sk_Height;
half4 process(fragmentProcessor fp);
)

View File

@ -17,5 +17,7 @@ layout(builtin=9999) out half4 gl_SecondaryFragColorEXT;
layout(location=0,index=0,builtin=10001) out half4 sk_FragColor;
layout(builtin=10008) half4 sk_LastFragColor;
layout(builtin=10011) half sk_Width;
layout(builtin=10012) half sk_Height;
)

View File

@ -1154,6 +1154,38 @@ DEF_TEST(SkSLFragCoord, r) {
"}\n");
}
DEF_TEST(SkSLWidthAndHeight, r) {
SkSL::Program::Settings settings;
sk_sp<GrShaderCaps> caps = SkSL::ShaderCapsFactory::Default();
settings.fCaps = caps.get();
SkSL::Program::Inputs inputs;
test(r,
"void main() { sk_FragColor.r = sk_FragCoord.x / sk_Width; }",
settings,
"#version 400\n"
"uniform float u_skRTWidth;\n"
"out vec4 sk_FragColor;\n"
"void main() {\n"
" sk_FragColor.x = gl_FragCoord.x / u_skRTWidth;\n"
"}\n",
&inputs);
REPORTER_ASSERT(r, inputs.fRTWidth);
REPORTER_ASSERT(r, !inputs.fRTHeight);
test(r,
"void main() { sk_FragColor.r = sk_FragCoord.y / sk_Height; }",
settings,
"#version 400\n"
"uniform float u_skRTHeight;\n"
"out vec4 sk_FragColor;\n"
"void main() {\n"
" sk_FragColor.x = gl_FragCoord.y / u_skRTHeight;\n"
"}\n",
&inputs);
REPORTER_ASSERT(r, !inputs.fRTWidth);
REPORTER_ASSERT(r, inputs.fRTHeight);
}
DEF_TEST(SkSLClockwise, r) {
test(r,
"void main() { sk_FragColor = half4(sk_Clockwise ? +1 : -1); }",