Program::link() and callees do not access mPixelHLSL, mVertexHLSL, mFragmentShader, mVertexShader, mAttributeBinding.
mPixelHLSL and mVertexHLSL are deleted because they are only used during linking.
Review URL: https://codereview.appspot.com/6306047
git-svn-id: https://angleproject.googlecode.com/svn/trunk@1141 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Program.cpp b/src/libGLESv2/Program.cpp
index beb0fae..e0fe8d7 100644
--- a/src/libGLESv2/Program.cpp
+++ b/src/libGLESv2/Program.cpp
@@ -33,6 +33,14 @@
return buffer;
}
+AttributeBindings::AttributeBindings()
+{
+}
+
+AttributeBindings::~AttributeBindings()
+{
+}
+
Uniform::Uniform(GLenum type, const std::string &_name, unsigned int arraySize)
: type(type), _name(_name), name(Program::undecorateUniform(_name)), arraySize(arraySize)
{
@@ -162,17 +170,22 @@
return mVertexExecutable;
}
+void AttributeBindings::bindAttributeLocation(GLuint index, const char *name)
+{
+ if (index < MAX_VERTEX_ATTRIBS)
+ {
+ for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ {
+ mAttributeBinding[i].erase(name);
+ }
+
+ mAttributeBinding[index].insert(name);
+ }
+}
+
void Program::bindAttributeLocation(GLuint index, const char *name)
{
- if (index < MAX_VERTEX_ATTRIBS)
- {
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- mAttributeBinding[i].erase(name);
- }
-
- mAttributeBinding[index].insert(name);
- }
+ mAttributeBindings.bindAttributeLocation(index, name);
}
GLuint Program::getAttributeLocation(const char *name)
@@ -1140,12 +1153,12 @@
// Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
// Returns the number of used varying registers, or -1 if unsuccesful
-int Program::packVaryings(const Varying *packing[][4])
+int Program::packVaryings(const Varying *packing[][4], FragmentShader *fragmentShader)
{
Context *context = getContext();
const int maxVaryingVectors = context->getMaximumVaryingVectors();
- for (VaryingList::iterator varying = mFragmentShader->mVaryings.begin(); varying != mFragmentShader->mVaryings.end(); varying++)
+ for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++)
{
int n = VariableRowCount(varying->type) * varying->size;
int m = VariableColumnCount(varying->type);
@@ -1288,21 +1301,21 @@
return registers;
}
-bool Program::linkVaryings()
+bool Program::linkVaryings(std::string& pixelHLSL, std::string& vertexHLSL, FragmentShader *fragmentShader, VertexShader *vertexShader)
{
- if (mPixelHLSL.empty() || mVertexHLSL.empty())
+ if (pixelHLSL.empty() || vertexHLSL.empty())
{
return false;
}
// Reset the varying register assignments
- for (VaryingList::iterator fragVar = mFragmentShader->mVaryings.begin(); fragVar != mFragmentShader->mVaryings.end(); fragVar++)
+ for (VaryingList::iterator fragVar = fragmentShader->mVaryings.begin(); fragVar != fragmentShader->mVaryings.end(); fragVar++)
{
fragVar->reg = -1;
fragVar->col = -1;
}
- for (VaryingList::iterator vtxVar = mVertexShader->mVaryings.begin(); vtxVar != mVertexShader->mVaryings.end(); vtxVar++)
+ for (VaryingList::iterator vtxVar = vertexShader->mVaryings.begin(); vtxVar != vertexShader->mVaryings.end(); vtxVar++)
{
vtxVar->reg = -1;
vtxVar->col = -1;
@@ -1310,7 +1323,7 @@
// Map the varyings to the register file
const Varying *packing[MAX_VARYING_VECTORS_SM3][4] = {NULL};
- int registers = packVaryings(packing);
+ int registers = packVaryings(packing, fragmentShader);
if (registers < 0)
{
@@ -1322,18 +1335,18 @@
const bool sm3 = context->supportsShaderModel3();
const int maxVaryingVectors = context->getMaximumVaryingVectors();
- if (registers == maxVaryingVectors && mFragmentShader->mUsesFragCoord)
+ if (registers == maxVaryingVectors && fragmentShader->mUsesFragCoord)
{
appendToInfoLog("No varying registers left to support gl_FragCoord");
return false;
}
- for (VaryingList::iterator input = mFragmentShader->mVaryings.begin(); input != mFragmentShader->mVaryings.end(); input++)
+ for (VaryingList::iterator input = fragmentShader->mVaryings.begin(); input != fragmentShader->mVaryings.end(); input++)
{
bool matched = false;
- for (VaryingList::iterator output = mVertexShader->mVaryings.begin(); output != mVertexShader->mVaryings.end(); output++)
+ for (VaryingList::iterator output = vertexShader->mVaryings.begin(); output != vertexShader->mVaryings.end(); output++)
{
if (output->name == input->name)
{
@@ -1362,30 +1375,30 @@
std::string varyingSemantic = (sm3 ? "COLOR" : "TEXCOORD");
- mVertexHLSL += "struct VS_INPUT\n"
+ vertexHLSL += "struct VS_INPUT\n"
"{\n";
int semanticIndex = 0;
- for (AttributeArray::iterator attribute = mVertexShader->mAttributes.begin(); attribute != mVertexShader->mAttributes.end(); attribute++)
+ for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
{
switch (attribute->type)
{
- case GL_FLOAT: mVertexHLSL += " float "; break;
- case GL_FLOAT_VEC2: mVertexHLSL += " float2 "; break;
- case GL_FLOAT_VEC3: mVertexHLSL += " float3 "; break;
- case GL_FLOAT_VEC4: mVertexHLSL += " float4 "; break;
- case GL_FLOAT_MAT2: mVertexHLSL += " float2x2 "; break;
- case GL_FLOAT_MAT3: mVertexHLSL += " float3x3 "; break;
- case GL_FLOAT_MAT4: mVertexHLSL += " float4x4 "; break;
+ case GL_FLOAT: vertexHLSL += " float "; break;
+ case GL_FLOAT_VEC2: vertexHLSL += " float2 "; break;
+ case GL_FLOAT_VEC3: vertexHLSL += " float3 "; break;
+ case GL_FLOAT_VEC4: vertexHLSL += " float4 "; break;
+ case GL_FLOAT_MAT2: vertexHLSL += " float2x2 "; break;
+ case GL_FLOAT_MAT3: vertexHLSL += " float3x3 "; break;
+ case GL_FLOAT_MAT4: vertexHLSL += " float4x4 "; break;
default: UNREACHABLE();
}
- mVertexHLSL += decorateAttribute(attribute->name) + " : TEXCOORD" + str(semanticIndex) + ";\n";
+ vertexHLSL += decorateAttribute(attribute->name) + " : TEXCOORD" + str(semanticIndex) + ";\n";
semanticIndex += VariableRowCount(attribute->type);
}
- mVertexHLSL += "};\n"
+ vertexHLSL += "};\n"
"\n"
"struct VS_OUTPUT\n"
"{\n"
@@ -1395,37 +1408,37 @@
{
int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1));
- mVertexHLSL += " float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n";
+ vertexHLSL += " float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n";
}
- if (mFragmentShader->mUsesFragCoord)
+ if (fragmentShader->mUsesFragCoord)
{
- mVertexHLSL += " float4 gl_FragCoord : " + varyingSemantic + str(registers) + ";\n";
+ vertexHLSL += " float4 gl_FragCoord : " + varyingSemantic + str(registers) + ";\n";
}
- if (mVertexShader->mUsesPointSize && sm3)
+ if (vertexShader->mUsesPointSize && sm3)
{
- mVertexHLSL += " float gl_PointSize : PSIZE;\n";
+ vertexHLSL += " float gl_PointSize : PSIZE;\n";
}
- mVertexHLSL += "};\n"
+ vertexHLSL += "};\n"
"\n"
"VS_OUTPUT main(VS_INPUT input)\n"
"{\n";
- for (AttributeArray::iterator attribute = mVertexShader->mAttributes.begin(); attribute != mVertexShader->mAttributes.end(); attribute++)
+ for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
{
- mVertexHLSL += " " + decorateAttribute(attribute->name) + " = ";
+ vertexHLSL += " " + decorateAttribute(attribute->name) + " = ";
if (VariableRowCount(attribute->type) > 1) // Matrix
{
- mVertexHLSL += "transpose";
+ vertexHLSL += "transpose";
}
- mVertexHLSL += "(input." + decorateAttribute(attribute->name) + ");\n";
+ vertexHLSL += "(input." + decorateAttribute(attribute->name) + ");\n";
}
- mVertexHLSL += "\n"
+ vertexHLSL += "\n"
" gl_main();\n"
"\n"
" VS_OUTPUT output;\n"
@@ -1434,17 +1447,17 @@
" output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
" output.gl_Position.w = gl_Position.w;\n";
- if (mVertexShader->mUsesPointSize && sm3)
+ if (vertexShader->mUsesPointSize && sm3)
{
- mVertexHLSL += " output.gl_PointSize = clamp(gl_PointSize, 1.0, " + str((int)ALIASED_POINT_SIZE_RANGE_MAX_SM3) + ");\n";
+ vertexHLSL += " output.gl_PointSize = clamp(gl_PointSize, 1.0, " + str((int)ALIASED_POINT_SIZE_RANGE_MAX_SM3) + ");\n";
}
- if (mFragmentShader->mUsesFragCoord)
+ if (fragmentShader->mUsesFragCoord)
{
- mVertexHLSL += " output.gl_FragCoord = gl_Position;\n";
+ vertexHLSL += " output.gl_FragCoord = gl_Position;\n";
}
- for (VaryingList::iterator varying = mVertexShader->mVaryings.begin(); varying != mVertexShader->mVaryings.end(); varying++)
+ for (VaryingList::iterator varying = vertexShader->mVaryings.begin(); varying != vertexShader->mVaryings.end(); varying++)
{
if (varying->reg >= 0)
{
@@ -1455,7 +1468,7 @@
for (int j = 0; j < rows; j++)
{
int r = varying->reg + i * rows + j;
- mVertexHLSL += " output.v" + str(r);
+ vertexHLSL += " output.v" + str(r);
bool sharedRegister = false; // Register used by multiple varyings
@@ -1470,7 +1483,7 @@
if(sharedRegister)
{
- mVertexHLSL += ".";
+ vertexHLSL += ".";
for (int x = 0; x < 4; x++)
{
@@ -1478,41 +1491,41 @@
{
switch(x)
{
- case 0: mVertexHLSL += "x"; break;
- case 1: mVertexHLSL += "y"; break;
- case 2: mVertexHLSL += "z"; break;
- case 3: mVertexHLSL += "w"; break;
+ case 0: vertexHLSL += "x"; break;
+ case 1: vertexHLSL += "y"; break;
+ case 2: vertexHLSL += "z"; break;
+ case 3: vertexHLSL += "w"; break;
}
}
}
}
- mVertexHLSL += " = " + varying->name;
+ vertexHLSL += " = " + varying->name;
if (varying->array)
{
- mVertexHLSL += "[" + str(i) + "]";
+ vertexHLSL += "[" + str(i) + "]";
}
if (rows > 1)
{
- mVertexHLSL += "[" + str(j) + "]";
+ vertexHLSL += "[" + str(j) + "]";
}
- mVertexHLSL += ";\n";
+ vertexHLSL += ";\n";
}
}
}
}
- mVertexHLSL += "\n"
+ vertexHLSL += "\n"
" return output;\n"
"}\n";
- mPixelHLSL += "struct PS_INPUT\n"
+ pixelHLSL += "struct PS_INPUT\n"
"{\n";
- for (VaryingList::iterator varying = mFragmentShader->mVaryings.begin(); varying != mFragmentShader->mVaryings.end(); varying++)
+ for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++)
{
if (varying->reg >= 0)
{
@@ -1522,32 +1535,32 @@
for (int j = 0; j < rows; j++)
{
std::string n = str(varying->reg + i * rows + j);
- mPixelHLSL += " float4 v" + n + " : " + varyingSemantic + n + ";\n";
+ pixelHLSL += " float4 v" + n + " : " + varyingSemantic + n + ";\n";
}
}
}
else UNREACHABLE();
}
- if (mFragmentShader->mUsesFragCoord)
+ if (fragmentShader->mUsesFragCoord)
{
- mPixelHLSL += " float4 gl_FragCoord : " + varyingSemantic + str(registers) + ";\n";
+ pixelHLSL += " float4 gl_FragCoord : " + varyingSemantic + str(registers) + ";\n";
if (sm3) {
- mPixelHLSL += " float2 dx_VPos : VPOS;\n";
+ pixelHLSL += " float2 dx_VPos : VPOS;\n";
}
}
- if (mFragmentShader->mUsesPointCoord && sm3)
+ if (fragmentShader->mUsesPointCoord && sm3)
{
- mPixelHLSL += " float2 gl_PointCoord : TEXCOORD0;\n";
+ pixelHLSL += " float2 gl_PointCoord : TEXCOORD0;\n";
}
- if (mFragmentShader->mUsesFrontFacing)
+ if (fragmentShader->mUsesFrontFacing)
{
- mPixelHLSL += " float vFace : VFACE;\n";
+ pixelHLSL += " float vFace : VFACE;\n";
}
- mPixelHLSL += "};\n"
+ pixelHLSL += "};\n"
"\n"
"struct PS_OUTPUT\n"
"{\n"
@@ -1557,38 +1570,38 @@
"PS_OUTPUT main(PS_INPUT input)\n"
"{\n";
- if (mFragmentShader->mUsesFragCoord)
+ if (fragmentShader->mUsesFragCoord)
{
- mPixelHLSL += " float rhw = 1.0 / input.gl_FragCoord.w;\n";
+ pixelHLSL += " float rhw = 1.0 / input.gl_FragCoord.w;\n";
if (sm3)
{
// dx_Coord.y contains the render target height. See Context::applyRenderTarget()
- mPixelHLSL += " gl_FragCoord.x = input.dx_VPos.x + 0.5;\n"
+ pixelHLSL += " gl_FragCoord.x = input.dx_VPos.x + 0.5;\n"
" gl_FragCoord.y = dx_Coord.y - input.dx_VPos.y - 0.5;\n";
}
else
{
// dx_Coord contains the viewport width/2, height/2, center.x and center.y. See Context::applyRenderTarget()
- mPixelHLSL += " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Coord.x + dx_Coord.z;\n"
+ pixelHLSL += " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Coord.x + dx_Coord.z;\n"
" gl_FragCoord.y = -(input.gl_FragCoord.y * rhw) * dx_Coord.y + dx_Coord.w;\n";
}
- mPixelHLSL += " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n"
+ pixelHLSL += " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n"
" gl_FragCoord.w = rhw;\n";
}
- if (mFragmentShader->mUsesPointCoord && sm3)
+ if (fragmentShader->mUsesPointCoord && sm3)
{
- mPixelHLSL += " gl_PointCoord = input.gl_PointCoord;\n";
+ pixelHLSL += " gl_PointCoord = input.gl_PointCoord;\n";
}
- if (mFragmentShader->mUsesFrontFacing)
+ if (fragmentShader->mUsesFrontFacing)
{
- mPixelHLSL += " gl_FrontFacing = dx_PointsOrLines || (dx_FrontCCW ? (input.vFace >= 0.0) : (input.vFace <= 0.0));\n";
+ pixelHLSL += " gl_FrontFacing = dx_PointsOrLines || (dx_FrontCCW ? (input.vFace >= 0.0) : (input.vFace <= 0.0));\n";
}
- for (VaryingList::iterator varying = mFragmentShader->mVaryings.begin(); varying != mFragmentShader->mVaryings.end(); varying++)
+ for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++)
{
if (varying->reg >= 0)
{
@@ -1598,26 +1611,26 @@
for (int j = 0; j < rows; j++)
{
std::string n = str(varying->reg + i * rows + j);
- mPixelHLSL += " " + varying->name;
+ pixelHLSL += " " + varying->name;
if (varying->array)
{
- mPixelHLSL += "[" + str(i) + "]";
+ pixelHLSL += "[" + str(i) + "]";
}
if (rows > 1)
{
- mPixelHLSL += "[" + str(j) + "]";
+ pixelHLSL += "[" + str(j) + "]";
}
- mPixelHLSL += " = input.v" + n + ";\n";
+ pixelHLSL += " = input.v" + n + ";\n";
}
}
}
else UNREACHABLE();
}
- mPixelHLSL += "\n"
+ pixelHLSL += "\n"
" gl_main();\n"
"\n"
" PS_OUTPUT output;\n"
@@ -1632,24 +1645,29 @@
// Links the HLSL code of the vertex and pixel shader by matching up their varyings,
// compiling them into binaries, determining the attribute mappings, and collecting
// a list of uniforms
-void Program::link()
+void Program::link()
+{
+ link(mAttributeBindings, mFragmentShader, mVertexShader);
+}
+
+void Program::link(const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader)
{
unlink();
- if (!mFragmentShader || !mFragmentShader->isCompiled())
+ if (!fragmentShader || !fragmentShader->isCompiled())
{
return;
}
- if (!mVertexShader || !mVertexShader->isCompiled())
+ if (!vertexShader || !vertexShader->isCompiled())
{
return;
}
- mPixelHLSL = mFragmentShader->getHLSL();
- mVertexHLSL = mVertexShader->getHLSL();
+ std::string pixelHLSL = fragmentShader->getHLSL();
+ std::string vertexHLSL = vertexShader->getHLSL();
- if (!linkVaryings())
+ if (!linkVaryings(pixelHLSL, vertexHLSL, fragmentShader, vertexShader))
{
return;
}
@@ -1658,8 +1676,8 @@
const char *vertexProfile = context->supportsShaderModel3() ? "vs_3_0" : "vs_2_0";
const char *pixelProfile = context->supportsShaderModel3() ? "ps_3_0" : "ps_2_0";
- ID3D10Blob *vertexBinary = compileToBinary(mVertexHLSL.c_str(), vertexProfile, &mConstantTableVS);
- ID3D10Blob *pixelBinary = compileToBinary(mPixelHLSL.c_str(), pixelProfile, &mConstantTablePS);
+ ID3D10Blob *vertexBinary = compileToBinary(vertexHLSL.c_str(), vertexProfile, &mConstantTableVS);
+ ID3D10Blob *pixelBinary = compileToBinary(pixelHLSL.c_str(), pixelProfile, &mConstantTablePS);
if (vertexBinary && pixelBinary)
{
@@ -1680,7 +1698,7 @@
if (mVertexExecutable && mPixelExecutable)
{
- if (!linkAttributes())
+ if (!linkAttributes(attributeBindings, fragmentShader, vertexShader))
{
return;
}
@@ -1712,14 +1730,14 @@
}
// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
-bool Program::linkAttributes()
+bool Program::linkAttributes(const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader)
{
unsigned int usedLocations = 0;
// Link attributes that have a binding location
for (AttributeArray::iterator attribute = mVertexShader->mAttributes.begin(); attribute != mVertexShader->mAttributes.end(); attribute++)
{
- int location = getAttributeBinding(attribute->name);
+ int location = attributeBindings.getAttributeBinding(attribute->name);
if (location != -1) // Set by glBindAttribLocation
{
@@ -1749,7 +1767,7 @@
// Link attributes that don't have a binding location
for (AttributeArray::iterator attribute = mVertexShader->mAttributes.begin(); attribute != mVertexShader->mAttributes.end(); attribute++)
{
- int location = getAttributeBinding(attribute->name);
+ int location = attributeBindings.getAttributeBinding(attribute->name);
if (location == -1) // Not set by glBindAttribLocation
{
@@ -1781,7 +1799,7 @@
return true;
}
-int Program::getAttributeBinding(const std::string &name)
+int AttributeBindings::getAttributeBinding(const std::string &name) const
{
for (int location = 0; location < MAX_VERTEX_ATTRIBS; location++)
{
@@ -2391,9 +2409,6 @@
mUniformIndex.clear();
- mPixelHLSL.clear();
- mVertexHLSL.clear();
-
delete[] mInfoLog;
mInfoLog = NULL;