Make GrGLShaderVar objects aware of whether they are uniform, varying, or
attribute varibles. Extract GLSL generation enum and utility function into new GrGLSL header. git-svn-id: http://skia.googlecode.com/svn/trunk@2827 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
88ca1b4102
commit
086e5354fe
@ -210,6 +210,8 @@
|
||||
'../src/gpu/GrGLRenderTarget.cpp',
|
||||
'../src/gpu/GrGLRenderTarget.h',
|
||||
'../src/gpu/GrGLShaderVar.h',
|
||||
'../src/gpu/GrGLSL.cpp',
|
||||
'../src/gpu/GrGLSL.h',
|
||||
'../src/gpu/GrGLStencilBuffer.cpp',
|
||||
'../src/gpu/GrGLStencilBuffer.h',
|
||||
'../src/gpu/GrGLTexture.cpp',
|
||||
|
@ -369,9 +369,9 @@ static void addColorFilter(GrStringBuilder* fsCode, const char * outputVar,
|
||||
namespace {
|
||||
|
||||
const char* glsl_version_string(const GrGLInterface* gl,
|
||||
GrGLProgram::GLSLVersion v) {
|
||||
GrGLSLGeneration v) {
|
||||
switch (v) {
|
||||
case GrGLProgram::k110_GLSLVersion:
|
||||
case k110_GLSLGeneration:
|
||||
if (gl->supportsES2()) {
|
||||
// ES2s shader language is based on version 1.20 but is version
|
||||
// 1.00 of the ES language.
|
||||
@ -379,10 +379,10 @@ const char* glsl_version_string(const GrGLInterface* gl,
|
||||
} else {
|
||||
return "#version 110\n";
|
||||
}
|
||||
case GrGLProgram::k130_GLSLVersion:
|
||||
case k130_GLSLGeneration:
|
||||
GrAssert(!gl->supportsES2());
|
||||
return "#version 130\n";
|
||||
case GrGLProgram::k150_GLSLVersion:
|
||||
case k150_GLSLGeneration:
|
||||
GrAssert(!gl->supportsES2());
|
||||
return "#version 150\n";
|
||||
default:
|
||||
@ -400,6 +400,8 @@ void append_varying(GrGLShaderVar::Type type,
|
||||
const char** fsInName = NULL) {
|
||||
segments->fVSOutputs.push_back();
|
||||
segments->fVSOutputs.back().setType(type);
|
||||
segments->fVSOutputs.back().setTypeModifier(
|
||||
GrGLShaderVar::kOut_TypeModifier);
|
||||
segments->fVSOutputs.back().accessName()->printf("v%s", name);
|
||||
if (vsOutName) {
|
||||
*vsOutName = segments->fVSOutputs.back().getName().c_str();
|
||||
@ -411,11 +413,15 @@ void append_varying(GrGLShaderVar::Type type,
|
||||
// and output as non-array.
|
||||
segments->fGSInputs.push_back();
|
||||
segments->fGSInputs.back().setType(type);
|
||||
segments->fGSInputs.back().setTypeModifier(
|
||||
GrGLShaderVar::kIn_TypeModifier);
|
||||
segments->fGSInputs.back().setUnsizedArray();
|
||||
*segments->fGSInputs.back().accessName() =
|
||||
segments->fVSOutputs.back().getName();
|
||||
segments->fGSOutputs.push_back();
|
||||
segments->fGSOutputs.back().setType(type);
|
||||
segments->fGSOutputs.back().setTypeModifier(
|
||||
GrGLShaderVar::kOut_TypeModifier);
|
||||
segments->fGSOutputs.back().accessName()->printf("g%s", name);
|
||||
fsName = segments->fGSOutputs.back().accessName();
|
||||
} else {
|
||||
@ -423,6 +429,8 @@ void append_varying(GrGLShaderVar::Type type,
|
||||
}
|
||||
segments->fFSInputs.push_back();
|
||||
segments->fFSInputs.back().setType(type);
|
||||
segments->fFSInputs.back().setTypeModifier(
|
||||
GrGLShaderVar::kIn_TypeModifier);
|
||||
segments->fFSInputs.back().setName(*fsName);
|
||||
if (fsInName) {
|
||||
*fsInName = fsName->c_str();
|
||||
@ -450,6 +458,7 @@ void GrGLProgram::genEdgeCoverage(const GrGLInterface* gl,
|
||||
ShaderCodeSegments* segments) const {
|
||||
if (fProgramDesc.fEdgeAANumEdges > 0) {
|
||||
segments->fFSUnis.push_back().set(GrGLShaderVar::kVec3f_Type,
|
||||
GrGLShaderVar::kUniform_TypeModifier,
|
||||
EDGES_UNI_NAME,
|
||||
fProgramDesc.fEdgeAANumEdges);
|
||||
programData->fUniLocations.fEdgesUni = kUseUniform;
|
||||
@ -499,8 +508,10 @@ void GrGLProgram::genEdgeCoverage(const GrGLInterface* gl,
|
||||
*coverageVar = "edgeAlpha";
|
||||
} else if (layout & GrDrawTarget::kEdge_VertexLayoutBit) {
|
||||
const char *vsName, *fsName;
|
||||
append_varying(GrGLShaderVar::kVec4f_Type, "Edge", segments, &vsName, &fsName);
|
||||
segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type, EDGE_ATTR_NAME);
|
||||
append_varying(GrGLShaderVar::kVec4f_Type, "Edge", segments,
|
||||
&vsName, &fsName);
|
||||
segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type,
|
||||
GrGLShaderVar::kAttribute_TypeModifier, EDGE_ATTR_NAME);
|
||||
segments->fVSCode.appendf("\t%s = " EDGE_ATTR_NAME ";\n", vsName);
|
||||
if (GrDrawState::kHairLine_EdgeType == fProgramDesc.fVertexEdgeType) {
|
||||
segments->fFSCode.appendf("\tfloat edgeAlpha = abs(dot(vec3(gl_FragCoord.xy,1), %s.xyz));\n", fsName);
|
||||
@ -528,18 +539,19 @@ void GrGLProgram::genEdgeCoverage(const GrGLInterface* gl,
|
||||
namespace {
|
||||
|
||||
// returns true if the color output was explicitly declared or not.
|
||||
bool decl_and_get_fs_color_output(GrGLProgram::GLSLVersion v,
|
||||
bool decl_and_get_fs_color_output(GrGLSLGeneration v,
|
||||
VarArray* fsOutputs,
|
||||
const char** name) {
|
||||
switch (v) {
|
||||
case GrGLProgram::k110_GLSLVersion:
|
||||
case k110_GLSLGeneration:
|
||||
*name = "gl_FragColor";
|
||||
return false;
|
||||
break;
|
||||
case GrGLProgram::k130_GLSLVersion: // fallthru
|
||||
case GrGLProgram::k150_GLSLVersion:
|
||||
case k130_GLSLGeneration: // fallthru
|
||||
case k150_GLSLGeneration:
|
||||
*name = declared_color_output_name();
|
||||
fsOutputs->push_back().set(GrGLShaderVar::kVec4f_Type,
|
||||
GrGLShaderVar::kOut_TypeModifier,
|
||||
declared_color_output_name());
|
||||
return true;
|
||||
break;
|
||||
@ -556,7 +568,8 @@ void genInputColor(GrGLProgram::ProgramDesc::ColorInput colorInput,
|
||||
switch (colorInput) {
|
||||
case GrGLProgram::ProgramDesc::kAttribute_ColorInput: {
|
||||
segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type,
|
||||
COL_ATTR_NAME);
|
||||
GrGLShaderVar::kAttribute_TypeModifier,
|
||||
COL_ATTR_NAME);
|
||||
const char *vsName, *fsName;
|
||||
append_varying(GrGLShaderVar::kVec4f_Type, "Color", segments, &vsName, &fsName);
|
||||
segments->fVSCode.appendf("\t%s = " COL_ATTR_NAME ";\n", vsName);
|
||||
@ -564,7 +577,8 @@ void genInputColor(GrGLProgram::ProgramDesc::ColorInput colorInput,
|
||||
} break;
|
||||
case GrGLProgram::ProgramDesc::kUniform_ColorInput:
|
||||
segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
|
||||
COL_UNI_NAME);
|
||||
GrGLShaderVar::kUniform_TypeModifier,
|
||||
COL_UNI_NAME);
|
||||
programData->fUniLocations.fColorUni = kUseUniform;
|
||||
*inColor = COL_UNI_NAME;
|
||||
break;
|
||||
@ -582,6 +596,7 @@ void genInputColor(GrGLProgram::ProgramDesc::ColorInput colorInput,
|
||||
void genPerVertexCoverage(ShaderCodeSegments* segments,
|
||||
GrStringBuilder* inCoverage) {
|
||||
segments->fVSAttrs.push_back().set(GrGLShaderVar::kFloat_Type,
|
||||
GrGLShaderVar::kAttribute_TypeModifier,
|
||||
COV_ATTR_NAME);
|
||||
const char *vsName, *fsName;
|
||||
append_varying(GrGLShaderVar::kFloat_Type, "Coverage",
|
||||
@ -599,11 +614,11 @@ void genPerVertexCoverage(ShaderCodeSegments* segments,
|
||||
}
|
||||
|
||||
void GrGLProgram::genGeometryShader(const GrGLInterface* gl,
|
||||
GLSLVersion glslVersion,
|
||||
GrGLSLGeneration glslGeneration,
|
||||
ShaderCodeSegments* segments) const {
|
||||
#if GR_GL_EXPERIMENTAL_GS
|
||||
if (fProgramDesc.fExperimentalGS) {
|
||||
GrAssert(glslVersion >= k150_GLSLVersion);
|
||||
GrAssert(glslGeneration >= k150_GLSLGeneration);
|
||||
segments->fGSHeader.append("layout(triangles) in;\n"
|
||||
"layout(triangle_strip, max_vertices = 6) out;\n");
|
||||
segments->fGSCode.append("void main() {\n"
|
||||
@ -628,7 +643,7 @@ void GrGLProgram::genGeometryShader(const GrGLInterface* gl,
|
||||
}
|
||||
|
||||
bool GrGLProgram::genProgram(const GrGLInterface* gl,
|
||||
GLSLVersion glslVersion,
|
||||
GrGLSLGeneration glslGeneration,
|
||||
GrGLProgram::CachedData* programData) const {
|
||||
|
||||
ShaderCodeSegments segments;
|
||||
@ -676,19 +691,22 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
|
||||
// declare an output, which is incompatible with gl_FragColor/gl_FragData.
|
||||
const char* fsColorOutput = NULL;
|
||||
bool dualSourceOutputWritten = false;
|
||||
segments.fHeader.printf(glsl_version_string(gl, glslVersion));
|
||||
bool isColorDeclared = decl_and_get_fs_color_output(glslVersion,
|
||||
segments.fHeader.printf(glsl_version_string(gl, glslGeneration));
|
||||
bool isColorDeclared = decl_and_get_fs_color_output(glslGeneration,
|
||||
&segments.fFSOutputs,
|
||||
&fsColorOutput);
|
||||
|
||||
#if GR_GL_ATTRIBUTE_MATRICES
|
||||
segments.fVSAttrs.push_back().set(GrGLShaderVar::kMat33f_Type, VIEW_MATRIX_NAME);
|
||||
segments.fVSAttrs.push_back().set(GrGLShaderVar::kMat33f_Type,
|
||||
GrGLShaderVar::kAttribute_TypeModifier, VIEW_MATRIX_NAME);
|
||||
programData->fUniLocations.fViewMatrixUni = kSetAsAttribute;
|
||||
#else
|
||||
segments.fVSUnis.push_back().set(GrGLShaderVar::kMat33f_Type, VIEW_MATRIX_NAME);
|
||||
segments.fVSUnis.push_back().set(GrGLShaderVar::kMat33f_Type,
|
||||
GrGLShaderVar::kUniform_TypeModifier, VIEW_MATRIX_NAME);
|
||||
programData->fUniLocations.fViewMatrixUni = kUseUniform;
|
||||
#endif
|
||||
segments.fVSAttrs.push_back().set(GrGLShaderVar::kVec2f_Type, POS_ATTR_NAME);
|
||||
segments.fVSAttrs.push_back().set(GrGLShaderVar::kVec2f_Type,
|
||||
GrGLShaderVar::kAttribute_TypeModifier, POS_ATTR_NAME);
|
||||
|
||||
segments.fVSCode.append(
|
||||
"void main() {\n"
|
||||
@ -716,7 +734,8 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
|
||||
if (GrDrawTarget::VertexUsesTexCoordIdx(t, layout)) {
|
||||
tex_attr_name(t, texCoordAttrs + t);
|
||||
segments.fVSAttrs.push_back().set(GrGLShaderVar::kVec2f_Type,
|
||||
texCoordAttrs[t].c_str());
|
||||
GrGLShaderVar::kAttribute_TypeModifier,
|
||||
texCoordAttrs[t].c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -775,6 +794,7 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
|
||||
}
|
||||
if (needColorFilterUniform) {
|
||||
segments.fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
|
||||
GrGLShaderVar::kUniform_TypeModifier,
|
||||
COL_FILTER_UNI_NAME);
|
||||
programData->fUniLocations.fColorFilterUni = kUseUniform;
|
||||
}
|
||||
@ -854,7 +874,8 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
|
||||
}
|
||||
if (ProgramDesc::kNone_DualSrcOutput != fProgramDesc.fDualSrcOutput) {
|
||||
segments.fFSOutputs.push_back().set(GrGLShaderVar::kVec4f_Type,
|
||||
dual_source_output_name());
|
||||
GrGLShaderVar::kOut_TypeModifier,
|
||||
dual_source_output_name());
|
||||
bool outputIsZero = false;
|
||||
GrStringBuilder coeff;
|
||||
if (ProgramDesc::kCoverage_DualSrcOutput !=
|
||||
@ -908,13 +929,13 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// insert GS
|
||||
#if GR_DEBUG
|
||||
this->genGeometryShader(gl, glslVersion, &segments);
|
||||
this->genGeometryShader(gl, glslGeneration, &segments);
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// compile and setup attribs and unis
|
||||
|
||||
if (!CompileShaders(gl, glslVersion, segments, programData)) {
|
||||
if (!CompileShaders(gl, glslGeneration, segments, programData)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -934,14 +955,11 @@ namespace {
|
||||
|
||||
inline void expand_decls(const VarArray& vars,
|
||||
const GrGLInterface* gl,
|
||||
const char* prefix,
|
||||
GrStringBuilder* string) {
|
||||
GrStringBuilder* string,
|
||||
GrGLSLGeneration gen) {
|
||||
const int count = vars.count();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
string->append(prefix);
|
||||
string->append(" ");
|
||||
vars[i].appendDecl(gl, string);
|
||||
string->append(";\n");
|
||||
vars[i].appendDecl(gl, string, gen);
|
||||
}
|
||||
}
|
||||
|
||||
@ -980,18 +998,18 @@ inline void append_string(const GrStringBuilder& str,
|
||||
|
||||
inline void append_decls(const VarArray& vars,
|
||||
const GrGLInterface* gl,
|
||||
const char* prefix,
|
||||
StrArray* strings,
|
||||
LengthArray* lengths,
|
||||
TempArray* temp) {
|
||||
expand_decls(vars, gl, prefix, &temp->push_back());
|
||||
TempArray* temp,
|
||||
GrGLSLGeneration gen) {
|
||||
expand_decls(vars, gl, &temp->push_back(), gen);
|
||||
append_string(temp->back(), strings, lengths);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool GrGLProgram::CompileShaders(const GrGLInterface* gl,
|
||||
GLSLVersion glslVersion,
|
||||
GrGLSLGeneration glslGeneration,
|
||||
const ShaderCodeSegments& segments,
|
||||
CachedData* programData) {
|
||||
enum { kPreAllocStringCnt = 8 };
|
||||
@ -1004,19 +1022,12 @@ bool GrGLProgram::CompileShaders(const GrGLInterface* gl,
|
||||
GrStringBuilder inputs;
|
||||
GrStringBuilder outputs;
|
||||
|
||||
static const char* gVaryingPrefixes[2][2] = {{"varying", "varying"},
|
||||
{"out", "in"}};
|
||||
const char** varyingPrefixes = k110_GLSLVersion == glslVersion ?
|
||||
gVaryingPrefixes[0] :
|
||||
gVaryingPrefixes[1];
|
||||
const char* attributePrefix = k110_GLSLVersion == glslVersion ?
|
||||
"attribute" :
|
||||
"in";
|
||||
|
||||
append_string(segments.fHeader, &strs, &lengths);
|
||||
append_decls(segments.fVSUnis, gl, "uniform", &strs, &lengths, &temps);
|
||||
append_decls(segments.fVSAttrs, gl, attributePrefix, &strs, &lengths, &temps);
|
||||
append_decls(segments.fVSOutputs, gl, varyingPrefixes[0], &strs, &lengths, &temps);
|
||||
append_decls(segments.fVSUnis, gl, &strs, &lengths, &temps, glslGeneration);
|
||||
append_decls(segments.fVSAttrs, gl, &strs, &lengths,
|
||||
&temps, glslGeneration);
|
||||
append_decls(segments.fVSOutputs, gl, &strs, &lengths,
|
||||
&temps, glslGeneration);
|
||||
append_string(segments.fVSCode, &strs, &lengths);
|
||||
|
||||
#if PRINT_SHADERS
|
||||
@ -1037,8 +1048,10 @@ bool GrGLProgram::CompileShaders(const GrGLInterface* gl,
|
||||
temps.reset();
|
||||
append_string(segments.fHeader, &strs, &lengths);
|
||||
append_string(segments.fGSHeader, &strs, &lengths);
|
||||
append_decls(segments.fGSInputs, gl, "in", &strs, &lengths, &temps);
|
||||
append_decls(segments.fGSOutputs, gl, "out", &strs, &lengths, &temps);
|
||||
append_decls(segments.fGSInputs, gl, &strs, &lengths,
|
||||
&temps, glslGeneration);
|
||||
append_decls(segments.fGSOutputs, gl, &strs, &lengths,
|
||||
&temps, glslGeneration);
|
||||
append_string(segments.fGSCode, &strs, &lengths);
|
||||
#if PRINT_SHADERS
|
||||
print_shader(strs.count(), &strs[0], &lengths[0]);
|
||||
@ -1058,11 +1071,14 @@ bool GrGLProgram::CompileShaders(const GrGLInterface* gl,
|
||||
append_string(segments.fHeader, &strs, &lengths);
|
||||
GrStringBuilder precisionStr(GrShaderPrecision(gl));
|
||||
append_string(precisionStr, &strs, &lengths);
|
||||
append_decls(segments.fFSUnis, gl, "uniform", &strs, &lengths, &temps);
|
||||
append_decls(segments.fFSInputs, gl, varyingPrefixes[1], &strs, &lengths, &temps);
|
||||
append_decls(segments.fFSUnis, gl, &strs, &lengths, &temps, glslGeneration);
|
||||
append_decls(segments.fFSInputs, gl, &strs, &lengths,
|
||||
&temps, glslGeneration);
|
||||
// We shouldn't have declared outputs on 1.10
|
||||
GrAssert(k110_GLSLVersion != glslVersion || segments.fFSOutputs.empty());
|
||||
append_decls(segments.fFSOutputs, gl, "out", &strs, &lengths, &temps);
|
||||
GrAssert(k110_GLSLGeneration != glslGeneration ||
|
||||
segments.fFSOutputs.empty());
|
||||
append_decls(segments.fFSOutputs, gl, &strs, &lengths,
|
||||
&temps, glslGeneration);
|
||||
append_string(segments.fFSFunctions, &strs, &lengths);
|
||||
append_string(segments.fFSCode, &strs, &lengths);
|
||||
|
||||
@ -1334,6 +1350,7 @@ GrGLShaderVar* genRadialVS(int stageNum,
|
||||
|
||||
GrGLShaderVar* radial2FSParams = &segments->fFSUnis.push_back();
|
||||
radial2FSParams->setType(GrGLShaderVar::kFloat_Type);
|
||||
radial2FSParams->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
|
||||
radial2FSParams->setArrayCount(6);
|
||||
radial2_param_name(stageNum, radial2FSParams->accessName());
|
||||
segments->fVSUnis.push_back(*radial2FSParams).setEmitPrecision(true);
|
||||
@ -1523,9 +1540,11 @@ void genConvolutionVS(int stageNum,
|
||||
//GrGLShaderVar* kernel = &segments->fFSUnis.push_back();
|
||||
*kernel = &segments->fFSUnis.push_back();
|
||||
(*kernel)->setType(GrGLShaderVar::kFloat_Type);
|
||||
(*kernel)->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
|
||||
(*kernel)->setArrayCount(desc.fKernelWidth);
|
||||
GrGLShaderVar* imgInc = &segments->fFSUnis.push_back();
|
||||
imgInc->setType(GrGLShaderVar::kVec2f_Type);
|
||||
imgInc->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
|
||||
|
||||
convolve_param_names(stageNum,
|
||||
(*kernel)->accessName(),
|
||||
@ -1612,9 +1631,11 @@ void GrGLProgram::genStageCode(const GrGLInterface* gl,
|
||||
GrGLShaderVar* mat;
|
||||
#if GR_GL_ATTRIBUTE_MATRICES
|
||||
mat = &segments->fVSAttrs.push_back();
|
||||
mat->setTypeModifier(GrGLShaderVar::kAttribute_TypeModifier);
|
||||
locations->fTextureMatrixUni = kSetAsAttribute;
|
||||
#else
|
||||
mat = &segments->fVSUnis.push_back();
|
||||
mat->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
|
||||
locations->fTextureMatrixUni = kUseUniform;
|
||||
#endif
|
||||
tex_matrix_name(stageNum, mat->accessName());
|
||||
@ -1628,14 +1649,16 @@ void GrGLProgram::genStageCode(const GrGLInterface* gl,
|
||||
}
|
||||
}
|
||||
|
||||
segments->fFSUnis.push_back().setType(GrGLShaderVar::kSampler2D_Type);
|
||||
segments->fFSUnis.push_back().set(GrGLShaderVar::kSampler2D_Type,
|
||||
GrGLShaderVar::kUniform_TypeModifier, "");
|
||||
sampler_name(stageNum, segments->fFSUnis.back().accessName());
|
||||
locations->fSamplerUni = kUseUniform;
|
||||
const char* samplerName = segments->fFSUnis.back().getName().c_str();
|
||||
|
||||
const char* texelSizeName = NULL;
|
||||
if (StageDesc::k2x2_FetchMode == desc.fFetchMode) {
|
||||
segments->fFSUnis.push_back().setType(GrGLShaderVar::kVec2f_Type);
|
||||
segments->fFSUnis.push_back().set(GrGLShaderVar::kVec2f_Type,
|
||||
GrGLShaderVar::kUniform_TypeModifier, "");
|
||||
normalized_texel_size_name(stageNum, segments->fFSUnis.back().accessName());
|
||||
texelSizeName = segments->fFSUnis.back().getName().c_str();
|
||||
}
|
||||
@ -1758,7 +1781,8 @@ void GrGLProgram::genStageCode(const GrGLInterface* gl,
|
||||
StageDesc::kCustomTextureDomain_OptFlagBit) {
|
||||
GrStringBuilder texDomainName;
|
||||
tex_domain_name(stageNum, &texDomainName);
|
||||
segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type, texDomainName);
|
||||
segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
|
||||
GrGLShaderVar::kUniform_TypeModifier, texDomainName);
|
||||
GrStringBuilder coordVar("clampCoord");
|
||||
segments->fFSCode.appendf("\t%s %s = clamp(%s, %s.xy, %s.zw);\n",
|
||||
float_vector_type_str(coordDims),
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "GrDrawState.h"
|
||||
#include "GrGLInterface.h"
|
||||
#include "GrGLSL.h"
|
||||
#include "GrStringBuilder.h"
|
||||
#include "GrGpu.h"
|
||||
|
||||
@ -36,22 +37,6 @@ struct ShaderCodeSegments;
|
||||
*/
|
||||
class GrGLProgram {
|
||||
public:
|
||||
// Limited set of GLSL versions we build shaders for. Caller should round
|
||||
// down the GLSL version to one of these enums.
|
||||
enum GLSLVersion {
|
||||
/**
|
||||
* Desktop GLSL 1.10 and ES2 shading lang (based on desktop GLSL 1.20)
|
||||
*/
|
||||
k110_GLSLVersion,
|
||||
/**
|
||||
* Desktop GLSL 1.30
|
||||
*/
|
||||
k130_GLSLVersion,
|
||||
/**
|
||||
* Dekstop GLSL 1.50
|
||||
*/
|
||||
k150_GLSLVersion,
|
||||
};
|
||||
|
||||
class CachedData;
|
||||
|
||||
@ -64,7 +49,7 @@ public:
|
||||
* but in a separate cacheable container.
|
||||
*/
|
||||
bool genProgram(const GrGLInterface* gl,
|
||||
GLSLVersion glslVersion,
|
||||
GrGLSLGeneration glslVersion,
|
||||
CachedData* programData) const;
|
||||
|
||||
/**
|
||||
@ -353,7 +338,7 @@ private:
|
||||
StageUniLocations* locations) const;
|
||||
|
||||
void genGeometryShader(const GrGLInterface* gl,
|
||||
GLSLVersion glslVersion,
|
||||
GrGLSLGeneration glslVersion,
|
||||
ShaderCodeSegments* segments) const;
|
||||
|
||||
// generates code to compute coverage based on edge AA.
|
||||
@ -364,7 +349,7 @@ private:
|
||||
ShaderCodeSegments* segments) const;
|
||||
|
||||
static bool CompileShaders(const GrGLInterface* gl,
|
||||
GLSLVersion glslVersion,
|
||||
GrGLSLGeneration glslVersion,
|
||||
const ShaderCodeSegments& segments,
|
||||
CachedData* programData);
|
||||
|
||||
|
32
src/gpu/GrGLSL.cpp
Normal file
32
src/gpu/GrGLSL.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "GrGLSL.h"
|
||||
|
||||
GrGLSLGeneration GetGLSLGeneration(GrGLBinding binding,
|
||||
const GrGLInterface* gl) {
|
||||
GrGLSLVersion ver = GrGLGetGLSLVersion(gl);
|
||||
switch (binding) {
|
||||
case kDesktop_GrGLBinding:
|
||||
GrAssert(ver >= GR_GLSL_VER(1,10));
|
||||
if (ver >= GR_GLSL_VER(1,50)) {
|
||||
return k150_GLSLGeneration;
|
||||
} else if (ver >= GR_GLSL_VER(1,30)) {
|
||||
return k130_GLSLGeneration;
|
||||
} else {
|
||||
return k110_GLSLGeneration;
|
||||
}
|
||||
case kES2_GrGLBinding:
|
||||
// version 1.00 of ES GLSL based on ver 1.20 of desktop GLSL
|
||||
GrAssert(ver >= GR_GL_VER(1,00));
|
||||
return k110_GLSLGeneration;
|
||||
default:
|
||||
GrCrash("Unknown GL Binding");
|
||||
return k110_GLSLGeneration; // suppress warning
|
||||
}
|
||||
}
|
||||
|
34
src/gpu/GrGLSL.h
Normal file
34
src/gpu/GrGLSL.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrGLSL_DEFINED
|
||||
#define GrGLSL_DEFINED
|
||||
|
||||
#include "GrGLInterface.h"
|
||||
|
||||
// Limited set of GLSL versions we build shaders for. Caller should round
|
||||
// down the GLSL version to one of these enums.
|
||||
enum GrGLSLGeneration {
|
||||
/**
|
||||
* Desktop GLSL 1.10 and ES2 shading lang (based on desktop GLSL 1.20)
|
||||
*/
|
||||
k110_GLSLGeneration,
|
||||
/**
|
||||
* Desktop GLSL 1.30
|
||||
*/
|
||||
k130_GLSLGeneration,
|
||||
/**
|
||||
* Dekstop GLSL 1.50
|
||||
*/
|
||||
k150_GLSLGeneration,
|
||||
};
|
||||
|
||||
GrGLSLGeneration GetGLSLGeneration(GrGLBinding binding,
|
||||
const GrGLInterface* gl);
|
||||
|
||||
#endif
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define GrGLShaderVar_DEFINED
|
||||
|
||||
#include "GrGLInterface.h"
|
||||
#include "GrGLSL.h"
|
||||
#include "GrStringBuilder.h"
|
||||
|
||||
#define USE_UNIFORM_FLOAT_ARRAYS true
|
||||
@ -29,11 +30,25 @@ public:
|
||||
kSampler2D_Type,
|
||||
};
|
||||
|
||||
/**
|
||||
* Early versions of GLSL have Varying and Attribute; those are later
|
||||
* deprecated, but we still need to know whether a Varying variable
|
||||
* should be treated as In or Out.
|
||||
*/
|
||||
enum TypeModifier {
|
||||
kNone_TypeModifier,
|
||||
kOut_TypeModifier,
|
||||
kIn_TypeModifier,
|
||||
kUniform_TypeModifier,
|
||||
kAttribute_TypeModifier
|
||||
};
|
||||
|
||||
/**
|
||||
* Defaults to a float with no precision specifier
|
||||
*/
|
||||
GrGLShaderVar() {
|
||||
fType = kFloat_Type;
|
||||
fTypeModifier = kNone_TypeModifier;
|
||||
fCount = kNonArray;
|
||||
fEmitPrecision = false;
|
||||
fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
|
||||
@ -41,6 +56,7 @@ public:
|
||||
|
||||
GrGLShaderVar(const GrGLShaderVar& var)
|
||||
: fType(var.fType)
|
||||
, fTypeModifier(var.fTypeModifier)
|
||||
, fName(var.fName)
|
||||
, fCount(var.fCount)
|
||||
, fEmitPrecision(var.fEmitPrecision)
|
||||
@ -58,10 +74,12 @@ public:
|
||||
* Sets as a non-array.
|
||||
*/
|
||||
void set(Type type,
|
||||
TypeModifier typeModifier,
|
||||
const GrStringBuilder& name,
|
||||
bool emitPrecision = false,
|
||||
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
|
||||
fType = type;
|
||||
fTypeModifier = typeModifier;
|
||||
fName = name;
|
||||
fCount = kNonArray;
|
||||
fEmitPrecision = emitPrecision;
|
||||
@ -72,10 +90,12 @@ public:
|
||||
* Sets as a non-array.
|
||||
*/
|
||||
void set(Type type,
|
||||
TypeModifier typeModifier,
|
||||
const char* name,
|
||||
bool specifyPrecision = false,
|
||||
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
|
||||
fType = type;
|
||||
fTypeModifier = typeModifier;
|
||||
fName = name;
|
||||
fCount = kNonArray;
|
||||
fEmitPrecision = specifyPrecision;
|
||||
@ -86,11 +106,13 @@ public:
|
||||
* Set all var options
|
||||
*/
|
||||
void set(Type type,
|
||||
TypeModifier typeModifier,
|
||||
const GrStringBuilder& name,
|
||||
int count,
|
||||
bool specifyPrecision = false,
|
||||
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
|
||||
fType = type;
|
||||
fTypeModifier = typeModifier;
|
||||
fName = name;
|
||||
fCount = count;
|
||||
fEmitPrecision = specifyPrecision;
|
||||
@ -101,11 +123,13 @@ public:
|
||||
* Set all var options
|
||||
*/
|
||||
void set(Type type,
|
||||
TypeModifier typeModifier,
|
||||
const char* name,
|
||||
int count,
|
||||
bool specifyPrecision = false,
|
||||
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
|
||||
fType = type;
|
||||
fTypeModifier = typeModifier;
|
||||
fName = name;
|
||||
fCount = count;
|
||||
fEmitPrecision = specifyPrecision;
|
||||
@ -160,6 +184,9 @@ public:
|
||||
*/
|
||||
void setType(Type type) { fType = type; }
|
||||
|
||||
TypeModifier getTypeModifier() const { return fTypeModifier; }
|
||||
void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
|
||||
|
||||
/**
|
||||
* Must the variable declaration emit a precision specifier
|
||||
*/
|
||||
@ -172,7 +199,12 @@ public:
|
||||
/**
|
||||
* Write a declaration of this variable to out.
|
||||
*/
|
||||
void appendDecl(const GrGLInterface* gl, GrStringBuilder* out) const {
|
||||
void appendDecl(const GrGLInterface* gl, GrStringBuilder* out,
|
||||
GrGLSLGeneration gen) const {
|
||||
if (this->getTypeModifier() != kNone_TypeModifier) {
|
||||
out->append(TypeModifierString(this->getTypeModifier(), gen));
|
||||
out->append(" ");
|
||||
}
|
||||
if (this->emitsPrecision()) {
|
||||
out->append(PrecisionString(gl));
|
||||
out->append(" ");
|
||||
@ -195,6 +227,7 @@ public:
|
||||
TypeString(effectiveType),
|
||||
this->getName().c_str());
|
||||
}
|
||||
out->append(";\n");
|
||||
}
|
||||
|
||||
static const char* TypeString(Type t) {
|
||||
@ -236,7 +269,27 @@ private:
|
||||
return gl->supportsDesktop() ? "" : "mediump";
|
||||
}
|
||||
|
||||
static const char* TypeModifierString(TypeModifier t,
|
||||
GrGLSLGeneration gen) {
|
||||
switch (t) {
|
||||
case kNone_TypeModifier:
|
||||
return "";
|
||||
case kOut_TypeModifier:
|
||||
return k110_GLSLGeneration == gen ? "varying" : "out";
|
||||
case kIn_TypeModifier:
|
||||
return k110_GLSLGeneration == gen ? "varying" : "in";
|
||||
case kUniform_TypeModifier:
|
||||
return "uniform";
|
||||
case kAttribute_TypeModifier:
|
||||
return k110_GLSLGeneration == gen ? "attribute" : "in";
|
||||
default:
|
||||
GrCrash("Unknown shader variable type modifier.");
|
||||
return ""; // suppress warning
|
||||
}
|
||||
}
|
||||
|
||||
Type fType;
|
||||
TypeModifier fTypeModifier;
|
||||
GrStringBuilder fName;
|
||||
int fCount;
|
||||
bool fEmitPrecision;
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "GrBinHashKey.h"
|
||||
#include "GrGLProgram.h"
|
||||
#include "GrGLSL.h"
|
||||
#include "GrGpuGLShaders.h"
|
||||
#include "GrGpuVertex.h"
|
||||
#include "GrNoncopyable.h"
|
||||
@ -55,15 +56,15 @@ private:
|
||||
int fCount;
|
||||
unsigned int fCurrLRUStamp;
|
||||
const GrGLInterface* fGL;
|
||||
GrGLProgram::GLSLVersion fGLSLVersion;
|
||||
GrGLSLGeneration fGLSLGeneration;
|
||||
|
||||
public:
|
||||
ProgramCache(const GrGLInterface* gl,
|
||||
GrGLProgram::GLSLVersion glslVersion)
|
||||
GrGLSLGeneration glslGeneration)
|
||||
: fCount(0)
|
||||
, fCurrLRUStamp(0)
|
||||
, fGL(gl)
|
||||
, fGLSLVersion(glslVersion) {
|
||||
, fGLSLGeneration(glslGeneration) {
|
||||
}
|
||||
|
||||
~ProgramCache() {
|
||||
@ -89,7 +90,8 @@ public:
|
||||
|
||||
Entry* entry = fHashCache.find(newEntry.fKey);
|
||||
if (NULL == entry) {
|
||||
if (!desc.genProgram(fGL, fGLSLVersion, &newEntry.fProgramData)) {
|
||||
if (!desc.genProgram(fGL, fGLSLGeneration,
|
||||
&newEntry.fProgramData)) {
|
||||
return NULL;
|
||||
}
|
||||
if (fCount < kMaxEntries) {
|
||||
@ -144,29 +146,6 @@ void GrGpuGLShaders::DeleteProgram(const GrGLInterface* gl,
|
||||
|
||||
namespace {
|
||||
|
||||
GrGLProgram::GLSLVersion get_glsl_version(GrGLBinding binding,
|
||||
const GrGLInterface* gl) {
|
||||
GrGLSLVersion ver = GrGLGetGLSLVersion(gl);
|
||||
switch (binding) {
|
||||
case kDesktop_GrGLBinding:
|
||||
GrAssert(ver >= GR_GLSL_VER(1,10));
|
||||
if (ver >= GR_GLSL_VER(1,50)) {
|
||||
return GrGLProgram::k150_GLSLVersion;
|
||||
} else if (ver >= GR_GLSL_VER(1,30)) {
|
||||
return GrGLProgram::k130_GLSLVersion;
|
||||
} else {
|
||||
return GrGLProgram::k110_GLSLVersion;
|
||||
}
|
||||
case kES2_GrGLBinding:
|
||||
// version 1.00 of ES GLSL based on ver 1.20 of desktop GLSL
|
||||
GrAssert(ver >= GR_GL_VER(1,00));
|
||||
return GrGLProgram::k110_GLSLVersion;
|
||||
default:
|
||||
GrCrash("Unknown GL Binding");
|
||||
return GrGLProgram::k110_GLSLVersion; // suppress warning
|
||||
}
|
||||
}
|
||||
|
||||
// GrRandoms nextU() values have patterns in the low bits
|
||||
// So using nextU() % array_count might never take some values.
|
||||
int random_int(GrRandom* r, int count) {
|
||||
@ -186,8 +165,8 @@ bool random_bool(GrRandom* r) {
|
||||
|
||||
bool GrGpuGLShaders::programUnitTest() {
|
||||
|
||||
GrGLProgram::GLSLVersion glslVersion =
|
||||
get_glsl_version(this->glBinding(), this->glInterface());
|
||||
GrGLSLGeneration glslGeneration =
|
||||
GetGLSLGeneration(this->glBinding(), this->glInterface());
|
||||
static const int STAGE_OPTS[] = {
|
||||
0,
|
||||
StageDesc::kNoPerspective_OptFlagBit,
|
||||
@ -302,7 +281,7 @@ bool GrGpuGLShaders::programUnitTest() {
|
||||
}
|
||||
CachedData cachedData;
|
||||
if (!program.genProgram(this->glInterface(),
|
||||
glslVersion,
|
||||
glslGeneration,
|
||||
&cachedData)) {
|
||||
return false;
|
||||
}
|
||||
@ -325,8 +304,8 @@ GrGLBinding get_binding_in_use(const GrGLInterface* gl) {
|
||||
GrGpuGLShaders::GrGpuGLShaders(const GrGLInterface* gl)
|
||||
: GrGpuGL(gl, get_binding_in_use(gl)) {
|
||||
|
||||
GrGLProgram::GLSLVersion glslVersion =
|
||||
get_glsl_version(this->glBinding(), gl);
|
||||
GrGLSLGeneration glslGeneration =
|
||||
GetGLSLGeneration(this->glBinding(), gl);
|
||||
|
||||
// Enable supported shader-releated caps
|
||||
fCaps.fShaderSupport = true;
|
||||
@ -339,7 +318,7 @@ GrGpuGLShaders::GrGpuGLShaders(const GrGLInterface* gl)
|
||||
// we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS
|
||||
fCaps.fGeometryShaderSupport =
|
||||
this->glVersion() >= GR_GL_VER(3,2) &&
|
||||
glslVersion >= GrGLProgram::k150_GLSLVersion;
|
||||
glslGeneration >= k150_GLSLGeneration;
|
||||
} else {
|
||||
fCaps.fShaderDerivativeSupport =
|
||||
this->hasExtension("GL_OES_standard_derivatives");
|
||||
@ -348,7 +327,7 @@ GrGpuGLShaders::GrGpuGLShaders(const GrGLInterface* gl)
|
||||
GR_GL_GetIntegerv(gl, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttribs);
|
||||
|
||||
fProgramData = NULL;
|
||||
fProgramCache = new ProgramCache(gl, glslVersion);
|
||||
fProgramCache = new ProgramCache(gl, glslGeneration);
|
||||
|
||||
#if 0
|
||||
this->programUnitTest();
|
||||
|
Loading…
Reference in New Issue
Block a user